diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c87cdae7c3562ad2a90ce0b8cbcace2aec64b620..51ee7bcb1ef2a2d4c5d045bd77f142de712425f6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,59 +1,65 @@ +# .gitlab-ci.yml + + + stages: - test - build + - publish image: parity/rust:nightly variables: CI_SERVER_NAME: "GitLab CI" - CARGO_HOME: "${CI_PROJECT_DIR}/cargo" + CARGO_HOME: "${CI_PROJECT_DIR}/.cargo" + # have OS based build containers in the future + DOCKER_OS: "ubuntu:xenial" + ARCH: "x86_64" - BUILD_TARGET: ubuntu - BUILD_ARCH: amd64 - CARGO_TARGET: x86_64-unknown-linux-gnu -.releaseable_branches: # list of git refs for building GitLab artifacts (think "pre-release binaries") - only: &releaseable_branches - - master - - stable - - beta - - tags - - gitlab-next -.publishable_branches: # list of git refs for publishing builds to the "production" locations - only: &publishable_branches - - nightly # Our nightly builds from schedule, on `master` - - "v*" # Our version tags - - gitlab-next +cache: + key: "${CI_JOB_NAME}" + paths: + - ${CARGO_HOME} + - ./target .collect_artifacts: &collect_artifacts artifacts: name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}" when: on_success - expire_in: 1 mos + expire_in: 7 days paths: - - target/release/substrate + - artifacts/ + -.determine_version: &determine_version | - export VERSION=$(grep -m 1 "version =" Cargo.toml | awk '{print $3}' | tr -d '"' | tr -d "\n") - echo "Version" $VERSION #### stage: test + test:rust:stable: &test stage: test variables: RUST_TOOLCHAIN: stable + # Enable debug assertions since we are running optimized builds for testing + # but still want to have debug assertions. + RUSTFLAGS: -Cdebug-assertions=y TARGET: native - script: - - ./scripts/init.sh - - export PATH="${CI_PROJECT_DIR}/cargo/bin/:$PATH" - - export RUST_BACKTRACE=1 - - ./scripts/build.sh - - time cargo test --all --release --locked + only: + - triggers + - tags + - master + - schedules + - web + - /^pr-[0-9]+$/ + - /^[0-9]+$/ tags: - - rust-stable + - linux-docker + before_script: + - ./scripts/build.sh + script: + - time cargo test --all --release --verbose --locked .optional_test: &optional_test <<: *test @@ -61,21 +67,144 @@ test:rust:stable: &test only: - master + + + + +.build_only: &build_only + only: + - master + - tags + - web + + #### stage: build -build:linux:ubuntu:amd64: &build +build:rust:linux:release: &build stage: build - only: *releaseable_branches + <<: *collect_artifacts + <<: *build_only + tags: + - linux-docker + before_script: + - ./scripts/build.sh + script: + - time cargo build --release --verbose + - mkdir -p ./artifacts + - mv ./target/release/substrate ./artifacts/. + - echo -n "Substrate version = " + - ./artifacts/substrate --version | + sed -n -r 's/^substrate ([0-9.]+.*-[0-9a-f]{7,13})-.*$/\1/p' | + tee ./artifacts/VERSION + - sha256sum ./artifacts/substrate | tee ./artifacts/substrate.sha256 + + + +build:rust:doc:release: &build + stage: build + artifacts: + name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}-doc" + when: on_success + expire_in: 7 days + paths: + - ./crate-docs + only: + - master + - tags + - web + - publish-rustdoc + tags: + - linux-docker + script: + - time cargo doc --release --verbose + - cp -R ./target/doc ./crate-docs + - echo "" > ./crate-docs/index.html + + + + +#### stage: publish + +.publish_build: &publish_build + stage: publish + dependencies: + - build:rust:linux:release + cache: {} + <<: *build_only + + + +publish:docker:release: + <<: *publish_build + tags: + - shell variables: - CARGO_TARGET: x86_64-unknown-linux-gnu - TARGET: native - RUST_TOOLCHAIN: stable + GIT_STRATEGY: none + DOCKERFILE: scripts/docker/Dockerfile + CONTAINER_IMAGE: parity/substrate script: - - ./scripts/init.sh - - export PATH="${CI_PROJECT_DIR}/cargo/bin/:$PATH" - - ./scripts/build.sh - - cargo build --release - <<: *collect_artifacts + - VERSION="$(cat ./artifacts/VERSION)" + - test "$Docker_Hub_User_Parity" -a "$Docker_Hub_Pass_Parity" + || ( echo "no docker credentials provided"; exit 1 ) + - docker login -u "$Docker_Hub_User_Parity" -p "$Docker_Hub_Pass_Parity" + - docker info + - docker build --tag $CONTAINER_IMAGE:$VERSION --tag $CONTAINER_IMAGE:latest -f $DOCKERFILE ./artifacts/ + - docker push $CONTAINER_IMAGE:$VERSION + - docker push $CONTAINER_IMAGE:latest + after_script: + - docker logout + + +publish:s3:release: + <<: *publish_build + image: parity/awscli:latest + variables: + GIT_STRATEGY: none + BUCKET: "releases.parity.io" + PREFIX: "substrate/${ARCH}-${DOCKER_OS}" + script: + - aws s3 sync ./artifacts/ s3://${BUCKET}/${PREFIX}/$(cat ./artifacts/VERSION)/ + after_script: + - aws s3 ls s3://${BUCKET}/${PREFIX}/ tags: - - rust-stable - allow_failure: true + - linux-docker + + + +publish:s3:doc: + stage: publish + dependencies: + - build:rust:doc:release + cache: {} + only: + - master + - tags + - web + - publish-rustdoc + variables: + GIT_STRATEGY: none + BUCKET: "releases.parity.io" + PREFIX: "substrate-rustdoc" + before_script: + - mkdir -p ${HOME}/.aws + - | + cat > ${HOME}/.aws/config <" +"checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" +"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" "checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" +"checksum dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" "checksum ed25519-dalek 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cd66d8a16ef71c23cf5eeb2140d8d3cd293457c6c7fd6804b593397a933fcf1e" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88d4851b005ef16de812ea9acdb7bece2f0a40dd86c07b85631d7dafa54537bb" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" +"checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e" "checksum environmental 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db746025e3ea695bfa0ae744dbacd5fcfc8db51b9760cf8bd0ab69708bb93c49" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" -"checksum eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)" = "" "checksum etrace 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f17311e68ea07046ee809b8513f6c259518bc10173681d98c21f8c3926f56f40" -"checksum exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9aa7b56cef68c4182db7212dece19cc9f6e2916cf9412e57e6cea53ec02f316d" -"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9" -"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426" +"checksum exit-future 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "87559b08e99a81a92bbb867d237543e43495857749f688e0773390a20d56c61c" +"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" +"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" -"checksum finality-grandpa 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "20d8cf871510f0d57630e75f9e65f87cba29581ccab1f78666d8b2e422d0baa6" -"checksum fixed-hash 0.3.0-beta.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e71c99c903a9fe54baed1bc701b43daba8c6dc6d4aec89a32f667ab6b3094c4" +"checksum finality-grandpa 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a1dffe3c9d4c59d964f25cea31880e56c20414cdae7efe2269411238f850ad39" +"checksum fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a557e80084b05c32b455963ff565a9de6f2866da023d6671705c6aff6f65e01c" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" @@ -4400,31 +4995,38 @@ dependencies = [ "checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" +"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" -"checksum getopts 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7292d30132fb5424b354f5dc02512a86e4c516fe544bb7a25e7f266951b797" "checksum getset 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "54c7f36a235738bb25904d6a2b3dbb28f6f5736cd3918c4bf80d6bb236200782" +"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865" -"checksum h2 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd33bafe2e6370e6c8eb0cf1b8c5f93390b90acde7e9b03723f166b28b648ed" +"checksum h2 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1ac030ae20dee464c5d0f36544d8b914a6bc606da44a57e052d2b0f5dae129e0" +"checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd" "checksum hash-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" +"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4da5f0e01bd8a71a224a4eedecaacfcabda388dbb7a80faf04d3514287572d95" "checksum hex-literal-impl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d340b6514f232f6db1bd16db65302a5278a04fef9ce867cb932e7e5fa21130a" "checksum hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "733e1b3ac906631ca01ebb577e9bb0f5e37a454032b9036b5eaea4013ed6f99a" -"checksum http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "24f58e8c2d8e886055c3ead7b28793e1455270b5fb39650984c224bc538ba581" +"checksum http 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "02096a6d2c55e63f7fcb800690e4f889a25f6ec342e3adb4594e293b625215ab" "checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" -"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" -"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" -"checksum hyper 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)" = "4aca412c241a2dd53af261efc7adf7736fdebd67dc0d1cc1ffdbcb9407e0e810" +"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" +"checksum hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "df0caae6b71d266b91b4a83111a61d2b94ed2e2bea024c532b933dcff867e58c" +"checksum hyper 0.12.19 (registry+https://github.com/rust-lang/crates.io-index)" = "f1ebec079129e43af5e234ef36ee3d7e6085687d145b7ea653b262d16c6b65f1" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -"checksum indexmap 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08173ba1e906efb6538785a8844dd496f5d34f0a2d88038e95195172fc667220" +"checksum impl-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c88568d828291c50eed30cd7fb9f8e688ad0013620186fa3e777b9f206c79f2" +"checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" +"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" "checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e31a8281fc93ec9693494da65fbf28c0c2aa60a2eaec25dc58e2f31952e95edc" "checksum itertools 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c4a9b56eb56058f43dc66e58f40a214b2ccbc9f3df51861b63d51dec7b65bc3f" "checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" +"checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" +"checksum itertools-num 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a872a22f9e6f7521ca557660adb96dd830e54f0f490fa115bb55dd69d38b27e7" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" "checksum jsonrpc-http-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" @@ -4434,41 +5036,43 @@ dependencies = [ "checksum jsonrpc-ws-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" "checksum keccak-hasher 0.1.0 (git+https://github.com/paritytech/trie)" = "" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum kvdb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "72ae89206cea31c32014b39d5a454b96135894221610dbfd19cf4d2d044fa546" -"checksum kvdb-memorydb 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45bcdf5eb083602cff61a6f8438dce2a7900d714e893fc48781c39fb119d37aa" -"checksum kvdb-rocksdb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "06cf755dc587839ba34d3cbe3f12b6ad55850fbcdfe67336157a021a1a5c43ae" +"checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" +"checksum kvdb-memorydb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" +"checksum kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" -"checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" +"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" +"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" +"checksum libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)" = "023a4cd09b2ff695f9734c1934145a315594b7986398496841c7031a5a1bbdbd" "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" -"checksum libp2p 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-dns 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-floodsub 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-identify 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-kad 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-mplex 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-peerstore 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-ping 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-ratelimit 0.1.1 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-relay 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-secio 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-tcp-transport 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-transport-timeout 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-uds 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-websocket 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum libp2p-yamux 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a92f6f1c0bd32ac7bb23c33af667149df5518e38f9ad2f517df71e52f1f0bbc" +"checksum libp2p-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7bdcd726ea75447b332288169581c921e49e893e34ca9925d49fd28dda16afe3" +"checksum libp2p-core-derive 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e52a2262f187aa45d07054bc80e39f0da582eb0288ca5f2dc0074b372e4b7eaa" +"checksum libp2p-dns 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f7ad92f9711efece48bb7ce30e3f1e662cd3524dc5d9f96b8f68b6e4e7cde96" +"checksum libp2p-floodsub 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4feda0ff3afcf84dfee9ea088835293829d199a34491d7f0990a4ccfd627816c" +"checksum libp2p-identify 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "548f9180101bd5846f4f60e060a00032ba3671a77fc735c48a85b7d1016d28ef" +"checksum libp2p-kad 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91c28bf179a22fd1bfa3bad28ed86b8657ed2d193b76caa6f632ea83356d3a40" +"checksum libp2p-mdns 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1bbcb82063545605abf697967d919d418b1725f7d3688973fa26c98f81e8cda8" +"checksum libp2p-mplex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9406ea58ce4fef47820f7d2d6aa62b7e42b4972c30cc87de577d4da40852d4b1" +"checksum libp2p-ping 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1ca7b60c2edb0cae7f9db56fbe6c21ca6960e96ec92cd1ed265ac06db24a1fe" +"checksum libp2p-plaintext 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84bdbdd4700d5edea10214e4733ab5ac5be87862bac8a9b259c987bc9c15004" +"checksum libp2p-ratelimit 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d3001ea6afed5ccd1e5934715aa388b60b23e7587117db36b89d697e8ea43ff3" +"checksum libp2p-secio 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc2bee2dce0d0d054d81447b06f7e923f1a98e6b240e42674e0fdf2e4a4924f" +"checksum libp2p-tcp 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fcb2bcb9402f5fe42441dd4558306ff83a28624f67c6066bdbaa98928c180e3" +"checksum libp2p-uds 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3e88ac8f419f8d9487aaee9ef8785f592b37d78067c6764fe0adc1874a72c6c" +"checksum libp2p-websocket 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "80b60b65b8d7053220a0c78a09eda0a162db410067639d2b24432a9f1dc06230" +"checksum libp2p-yamux 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71b4fd69a1c038152d017366d759177e2580fb4fbb56ce65429a642e011a07b1" +"checksum librocksdb-sys 5.14.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b9024327233e7fac7982440f73301c00046d438c5b1011e8f4e394226ce19007" +"checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" -"checksum local-encoding 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1ceb20f39ff7ae42f3ff9795f3986b1daad821caaa1e1732a0944103a5a1a66" -"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a" +"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" +"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" +"checksum make-cmd 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8ca8afbe8af1785e09636acb5a41e08a765f5f0340568716c18a8700ba3c0d3" "checksum mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f2d82b34c7fb11bb41719465c060589e291d505ca4735ea30016a91f6fc79c3b" "checksum mashup-impl 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "aa607bfb674b4efb310512527d64266b065de3f894fc52f84efcbf7eaa5965fb" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" +"checksum memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db4c41318937f6e76648f42826b1d9ade5c09cafb5aef7e351240a70f39206e9" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum memory-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" @@ -4477,155 +5081,169 @@ dependencies = [ "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum multihash 0.8.1-pre (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum multistream-select 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum multistream-select 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "886fe7ba983a194afdd9074323171c8e313b2c145561da69464d5443f1a3d121" "checksum names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da" -"checksum nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d4f00fcc2f4c9efa8cc971db0da9e28290e28e97af47585e48691ef10ff31f" -"checksum native-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8b0a7bd714e83db15676d31caf968ad7318e9cc35f93c85a90231c8f22867549" +"checksum native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff8e08de0070bbf4c31f452ea2a70db092f36f6f2e4d897adf5674477d488fb2" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" -"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum nohash-hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "27593c72432b8cec9ae79e92792a73c38341064d525b6b612a9fccf8b7d17407" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum nohash-hasher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d138afcce92d219ccb6eb53d9b1e8a96ac0d633cfd3c53cd9856d96d1741bb8" +"checksum nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c349f68f25f596b9f44cf0e7c69752a5c633b0550c3ff849518bfba0233774a" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3" -"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" +"checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238" "checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" +"checksum once_cell 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d7ce3535d54560c937c1652ba4a0da66bfc63e0f8e07bed127483afb6e5ee925" "checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7" -"checksum openssl 0.10.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6285ab297861546af7a2753593b3160bfc09f0ab9d1f5bb009e39d81a169b499" +"checksum opaque-debug 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "51ecbcb821e1bd256d456fe858aaa7f380b63863eab2eb86eee1bd9f33dd6682" +"checksum openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ec7bd7ca4cce6dbdc77e7c1230682740d307d1218a87fb0349a571272be749f9" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)" = "278c1ad40a89aa1e741a1eed089a2f60b18fab8089c3139b542140fc7d674106" -"checksum owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d52571ddcb42e9c900c901a18d8d67e393df723fcd51dd59c5b1a85d0acb6cc" +"checksum openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)" = "1bb974e77de925ef426b6bc82fce15fd45bdcbeb5728bffcfc7cdeeb7ce1c2d6" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" -"checksum parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5168b4cf41f3835e4bc6ffb32f51bc9365dc50cb351904595b3931d917fd0c" -"checksum parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dca389ea5e1632c89b2ce54f7e2b4a8a8c9d278042222a91e0bf95451218cb4c" +"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" +"checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" +"checksum parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7b6a1290fe78aa6bbb5f3338ecede3062687a98b9e40cd1dbcaa47261d44097" "checksum parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa42c2cb493b60b12c75b26e8c94cb734af4df4d7f2cc229dc04c1953dac189" -"checksum parity-crypto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1117f6574377d21309bfa1f7d69ff734120685d92b02c3f362b122585758840" -"checksum parity-rocksdb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd55d2d6d6000ec99f021cf52c9acc7d2a402e14f95ced4c5de230696fabe00b" -"checksum parity-rocksdb-sys 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0e59eda423021494a6cf1be74f6989add403f53157409993f794e17b123cab51" -"checksum parity-snappy-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c2086caac40c79289cb70d7e1c64f5888e1c53f5d38399d3e95101493739f423" +"checksum parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8adf489acb31f1922db0ce43803b6f48a425241a8473611be3cc625a8e4a4c47" +"checksum parity-multiaddr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9a8e5d637787fe097ec1bfca2aa3eb687396518003df991c6c7216d86682d5ff" +"checksum parity-multihash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e8eab0287ccde7821e337a124dc5a4f1d6e4c25d10cc91e3f9361615dd95076" "checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" -"checksum parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fa12d706797d42551663426a45e2db2e0364bd1dbf6aeada87e89c5f981f43e9" "checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" "checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac" "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" +"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" "checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" +"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" +"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" +"checksum pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3294f437119209b084c797604295f40227cffa35c57220b1e99a6ff3bf8ee4" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum pretty_assertions 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28ea5118e2f41bfbc974b28d88c07621befd1fa5d6ec23549be96302a1a59dd2" "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" +"checksum primitive-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f47c18b4601125931d69fcf7b000c2c16a304e4f84d58218d6470b4502e00b58" "checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8" "checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a" -"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" -"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" -"checksum protobuf 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "56c363dfc36e450457f4fa05a91d8c3f0fed00fc21142b4ce2cb7b525675eaeb" -"checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07" -"checksum pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd695333cfae6e9dbe2703a6d040e252b57a6fc3b9a65c712615ac042b2e0c5" +"checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4" +"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" +"checksum protobuf 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eae0479da11de87d371fa47eb033059715ffa8f714748da20aa364d56ec5bee2" +"checksum pwasm-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "efb0dcbddbb600f47a7098d33762a00552c671992171637f5bb310b37fe1f0e4" "checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" +"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" -"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" +"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" +"checksum rand 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b65e163105a6284f841bd23100a015895f54340e88a5ffc9ca7b8b33827cfce0" +"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" "checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" -"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" -"checksum rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df7a791f788cb4c516f0e091301a29c2b71ef680db5e644a7d68835c8ae6dbfa" +"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +"checksum rand_os 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de5ac4de1c2973e1391dc305cb0fbf8788cb58068e98255439b7485a77022273" +"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" +"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +"checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" "checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" -"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" +"checksum redox_syscall 0.1.50 (registry+https://github.com/rust-lang/crates.io-index)" = "52ee9a534dc1301776eff45b4fa92d2c39b1d8c3d3357e6eb593e0d795506fc2" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum ref_thread_local 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d813022b2e00774a48eaf43caaa3c20b45f040ba8cbf398e2e8911a06668dbe6" "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" -"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341" +"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" -"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" +"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum rhododendron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a09bc21b21795c366c8bf0e87afb71175f5f736b3a5b279b6f4e81839d0a877b" -"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" +"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" +"checksum rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1651697fefd273bfb4fd69466cc2a9d20de557a0213b97233b22b5e95924b5e" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" -"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" +"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rw-stream-sink 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" -"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" +"checksum rw-stream-sink 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "108ad7c3d65ba866ec50a224b7b3b0cb6c682c3d805015cea859d491232346a5" +"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" -"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" +"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" "checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum secp256k1 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4070f3906e65249228094cf97b04a90799fba04468190bbbcfa812309cf86e32" "checksum security-framework 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "697d3f3c23a618272ead9e1fb259c1411102b31c6af8b93f1d64cca9c3b0e8e0" -"checksum security-framework-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab01dfbe5756785b5b4d46e0289e5a18071dfa9a7c2b24213ea00b9ef9b665bf" +"checksum security-framework-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "40d95f3d7da09612affe897f320d78264f0d2320f3e8eea27d12bd1bd94445e2" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef" -"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c" -"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce" -"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" -"checksum sha1 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "171698ce4ec7cbb93babeb3190021b4d72e96ccb98e33d277ae4ea959d6f2d9e" +"checksum serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "0e732ed5a5592c17d961555e3b552985baf98d50ce418b7b655f31f6ba7eb1b7" +"checksum serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d6115a3ca25c224e409185325afc16a0d5aaaabc15c42b09587d6f1ba39a5b" +"checksum serde_json 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)" = "bdf540260cfee6da923831f4776ddc495ada940c30117977c70f1313a6130545" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" +"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" "checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" "checksum simplelog 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "24b615b1a3cc51ffa565d9a1d0cfcc49fe7d64737ada84eca284cddb0292d125" -"checksum skeptic 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24ebf8a06f5f8bae61ae5bbc7af7aac4ef6907ae975130faba1199e5fe82256a" -"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" +"checksum simplelog 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e95345f185d5adeb8ec93459d2dc99654e294cc6ccf5b75414d8ea262de9a13" "checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" "checksum slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1a2eec401952cd7b12a84ea120e2d57281329940c3f93c2bf04f462539508e" "checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f" -"checksum slog-json 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddd14b8df2df39378b3e933c79784350bf715b11444d99f903df0253bbe524e5" -"checksum slog-scope 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "053344c94c0e2b22da6305efddb698d7c485809427cf40555dc936085f67a9df" -"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" +"checksum slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a" +"checksum slog-scope 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "60c04b4726fa04595ccf2c2dad7bcd15474242c4c5e109a8a376e8a2c9b1539a" +"checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" -"checksum stdweb 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef5430c8e36b713e13b48a9f709cc21e046723fe44ce34587b73a830203b533e" -"checksum stdweb 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "22203527a18dc1c5c83bbd247fb005f5877d040783b6626571d6b7ed7a6f5e75" +"checksum stdweb 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b84f9c829ef7d2e6abf1965393b231c0fd495f0293d612f32dbadd637e91fd0d" "checksum stdweb-derive 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e21ebd9179de08f2300a65454268a17ea3de204627458588c84319c4def3930" -"checksum stdweb-internal-macros 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bcbc9155af9606d44c740197d7d6672b49c4ee93a176c7cecde8b49322677604" -"checksum stdweb-internal-runtime 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b74fe9de4c0d07e91987f4d798b95f27f3cb7769fbc222fa951fa386908297b5" +"checksum stdweb-internal-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d60e306bddd5d213f86f7b417b6cdcefbf742917414ac9dda6e9750ef4553dce" +"checksum stdweb-internal-runtime 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a2a2f4a2eb556337b2d1a302630bbddf989ae383c70393e89b48152b9896cbda" "checksum stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "30dc6118470d69ce0fdcf7e6f95e95853f7f4f72f80d835d4519577c323814ab" -"checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970" +"checksum string 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98998cced76115b1da46f63388b909d118a37ae0be0f82ad35773d4a4bc9d18d" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc7f6353c2ee5407358d063a14cccc1630804527090a6fb5a9489ce4924280fb" +"checksum structopt 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "670ad348dc73012fcf78c71f06f9d942232cdd4c859d4b6975e27836c3efc0c3" +"checksum structopt-derive 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ef98172b1a00b0bec738508d3726540edcbd186d50dfd326f2b1febbb3559f04" "checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" +"checksum subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "702662512f3ddeb74a64ce2fbbf3707ee1b6bb663d28bb054e0779bbc720d926" +"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum syn 0.15.12 (registry+https://github.com/rust-lang/crates.io-index)" = "34ab9797e47d24cb76b8dc4d24ff36807018c7cc549c4cba050b068be0c586b0" -"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7" -"checksum sysinfo 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "11c5f6e8a7a7146f26ffed9a5ff8bab2706f1ac8a413a415e1d211b819d5c24d" +"checksum syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)" = "734ecc29cd36e8123850d9bf21dfd62ef8300aaa8f879aabaa899721808be37c" +"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" +"checksum sysinfo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c747a1fbe091faa7bf76c19f40099f9f12495384c811485d81cf3d60c0eae62" "checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" "checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -"checksum tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "55c1195ef8513f3273d55ff59fe5da6940287a0d7a98331254397f464833675b" +"checksum tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" +"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" "checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" -"checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "checksum thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bcbb6aa301e5d3b0b5ef639c9a9c7e2f1c944f177b460c04dc24c69b1fa2bd99" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" +"checksum time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "847da467bf0db05882a9e2375934a8a55cffdc9db0d128af1518200260ba1f6c" "checksum tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e9175261fbdb60781fcd388a4d6cc7e14764a2b629a7ad94abb439aed223a44f" -"checksum tk-listen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dec7ba6a80b7695fc2abb21af18bed445a362ffd80b64704771ce142d6d2151d" -"checksum tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6e93c78d23cc61aa245a8acd2c4a79c4d7fa7fb5c3ca90d5737029f043a84895" +"checksum tk-listen 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5462b0f968c0457efe38fcd2df7e487096b992419e4f5337b06775a614bbda4b" +"checksum tokio 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4790d0be6f4ba6ae4f48190efa2ed7780c9e3567796abdb285003cf39840d9c5" "checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" -"checksum tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f90fcd90952f0a496d438a976afba8e5c205fb12123f813d8ab3aa1c8436638c" -"checksum tokio-dns-unofficial 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bb9bf62ca2c53bf2f2faec3e48a98b6d8c9577c27011cb0203a4beacdc8ab328" -"checksum tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c117b6cf86bb730aab4834f10df96e4dd586eff2c3c27d3781348da49e255bde" -"checksum tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5cbe4ca6e71cb0b62a66e4e6f53a8c06a6eefe46cc5f665ad6f274c9906f135" -"checksum tokio-io 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "8b8a85fffbec3c5ab1ab62324570230dcd37ee5996a7859da5caf7b9d45e3e8c" -"checksum tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4b26fd37f1125738b2170c80b551f69ff6fecb277e6e5ca885e53eec2b005018" -"checksum tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ad235e9dadd126b2d47f6736f65aa1fdcd6420e66ca63f44177bc78df89f912" -"checksum tokio-threadpool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bbd8a8b911301c60cbfaa2a6588fb210e5c1038375b8bdecc47aa09a94c3c05f" -"checksum tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3a52f00c97fedb6d535d27f65cccb7181c8dd4c6edc3eda9ea93f6d45d05168e" -"checksum tokio-tls 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e53fdbf3156f588be1676022fe794232b24922d426e8c14f4e46891c1e31c440" -"checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c" -"checksum tokio-uds 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22e3aa6d1fcc19e635418dc0a30ab5bd65d347973d6f43f1a37bf8d9d1335fc9" +"checksum tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "331c8acc267855ec06eb0c94618dcbbfea45bed2d20b77252940095273fb58f6" +"checksum tokio-dns-unofficial 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82c65483db54eb91b4ef3a9389a3364558590faf30ce473141707c0e16fda975" +"checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0" +"checksum tokio-fs 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9cbbc8a3698b7ab652340f46633364f9eaa928ddaaee79d8b8f356dd79a09d" +"checksum tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b53aeb9d3f5ccf2ebb29e19788f96987fa1355f8fe45ea193928eaaaf3ae820f" +"checksum tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afbcdb0f0d2a1e4c440af82d7bbf0bf91a8a8c0575bcd20c05d15be7e9d3a02f" +"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" +"checksum tokio-threadpool 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "17465013014410310f9f61fa10bf4724803c149ea1d51efece131c38efca93aa" +"checksum tokio-timer 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4f37f0111d76cc5da132fe9bc0590b9b9cfd079bc7e75ac3846278430a299ff8" +"checksum tokio-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" +"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" +"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum trie-bench 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum trie-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" @@ -4633,33 +5251,36 @@ dependencies = [ "checksum trie-standardmap 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum twofish 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1eef327f05b0d0ec1b9d7d119d8f4d9f602ceee37e0540aff8071e8e66c2e22e" -"checksum twox-hash 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f85be565a110ed72ed7048cf56570db04ce0a592c98aa59b7dacde3e5718750" +"checksum twox-hash 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "555cd4909480122bbbf21e34faac4cb08a171f324775670447ed116726c474af" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" -"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" -"checksum uint 0.5.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4630460173a57c0af94b8306091e018025d988473f641a4af754b6cde980e1e3" +"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" +"checksum uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "082df6964410f6aa929a61ddfafc997e4f32c62c22490e439ac351cec827f436" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" +"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum unsigned-varint 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5c1441164e5da61f00acd15f5a9e61939693c2c6e8b9fae36a220b82de7e212" "checksum unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8abc4b7d8158bdfbbaaccc35331ed3c30c2673e99000d7ae665a2eb6576f4" -"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" -"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" -"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" +"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" +"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vergen 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "93fb2d57fbc535fcd45548c99b141d2d960995daaf04b864c4d9fe1ea011c819" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum wabt 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "182ae543249ccf2705f324d233891c1176fca142e137b55ba43d9dbfe93f18a2" -"checksum wabt-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ca77c6b934a2b32618941b2f565aac43b8cb7141378c3b4fba4d8fcdcd57da3" +"checksum wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "74e463a508e390cc7447e70f640fbf44ad52e1bd095314ace1fdf99516d32add" +"checksum wabt-sys 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "462336bb61096e64761730e0dea1bc8b777bd4e3689c7e813c81f1cfdf4e8a51" +"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" -"checksum wasmi 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d184c4b7081f30316f74f8d73c197314dcb56ea7af9323522b42a2fa9cb19453" +"checksum wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21ef487a11df1ed468cf613c78798c26282da5c30e9d49f824872d4c77b47d1d" "checksum websocket 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c9faed2bff8af2ea6b9f8b917d3d00b467583f6781fe3def174a9e33c879703" +"checksum which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e84a603e7e0b1ce1aa1ee2b109c7be00155ce52df5081590d1ffb93f4f515cb2" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" @@ -4667,9 +5288,9 @@ dependencies = [ "checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" -"checksum ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)" = "" +"checksum ws 0.7.9 (git+https://github.com/tomusdrw/ws-rs)" = "" "checksum ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "329d3e6dd450a9c5c73024e1047f0be7e24121a68484eb0b5368977bee3cf8c3" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61" +"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" -"checksum yamux 0.1.0 (git+https://github.com/paritytech/yamux)" = "" +"checksum yamux 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e25561b512df3c287cf52404cab0b07ea43d095cb96230e9e2cb635db72d75f0" diff --git a/Cargo.toml b/Cargo.toml index 54ae7d9d82355cd57ee0b61404a3c6c8a32a6329..d67f32ed3c4fe52c8c5ed7e33e5212220d94016f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ path = "node/src/main.rs" [package] name = "substrate" -version = "0.1.0" +version = "0.10.0" authors = ["Parity Technologies "] build = "build.rs" @@ -27,20 +27,34 @@ members = [ "core/consensus/rhd", "core/executor", "core/finality-grandpa", + "core/finality-grandpa/primitives", "core/keyring", "core/network", "core/primitives", "core/rpc", "core/rpc-servers", - "core/sr-api", + "core/serializer", + "core/service", + "core/service/test", + "core/sr-api-macros", "core/sr-io", + "core/sr-primitives", "core/sr-sandbox", "core/sr-std", "core/sr-version", + "core/state-machine", + "core/test-runtime", + "core/telemetry", + "core/trie", + "core/keystore", "core/transaction-pool", "core/transaction-pool/graph", "srml/support", + "srml/support/procedural", + "srml/support/procedural/tools", + "srml/support/procedural/tools/derive", "srml/assets", + "srml/aura", "srml/balances", "srml/consensus", "srml/contract", @@ -48,23 +62,16 @@ members = [ "srml/democracy", "srml/example", "srml/executive", + "srml/grandpa", + "srml/indices", "srml/metadata", - "core/sr-primitives", "srml/session", "srml/staking", + "srml/sudo", "srml/system", "srml/timestamp", "srml/treasury", "srml/upgrade-key", - "core/serializer", - "core/service", - "core/service/test", - "core/state-db", - "core/state-machine", - "core/test-runtime", - "core/telemetry", - "core/trie", - "core/keystore", "node/cli", "node/executor", "node/primitives", @@ -74,8 +81,8 @@ members = [ exclude = [ "node/runtime/wasm", "core/executor/wasm", - "pwasm-alloc", "core/test-runtime/wasm", + "test-utils/chain-spec-builder" ] [badges] diff --git a/Dockerfile b/Dockerfile index d4a43eda8d5417972e5dfb7ef00e374270741c73..5c78740d5ea847f055021e3afbd332fda2647796 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,7 @@ RUN apk add build-base \ cmake \ linux-headers \ openssl-dev \ + clang-dev \ cargo ARG PROFILE=release @@ -17,7 +18,7 @@ RUN cargo build --$PROFILE # ===== SECOND STAGE ====== -FROM alpine:3.8 +FROM alpine:edge LABEL maintainer="chevdor@gmail.com" LABEL description="This is the 2nd stage: a very small image where we copy the Substrate binary." ARG PROFILE=release @@ -34,4 +35,4 @@ RUN rm -rf /usr/lib/python* && \ EXPOSE 30333 9933 9944 VOLUME ["/data"] -CMD ["/usr/local/bin/substrate"] +ENTRYPOINT ["/usr/local/bin/substrate"] diff --git a/README.adoc b/README.adoc index dc51bee6afd71e53f85fbf6738e36fd26be97aba..f51a94a4b79370b3f3ca86c1ce61e28f85b4497f 100644 --- a/README.adoc +++ b/README.adoc @@ -48,38 +48,35 @@ Other examples include the parachain-heads extrinsic in Polkadot and the "note-m === Runtime and API -Substrate chains all have a runtime. The runtime is a WebAssembly "blob" that includes a number of entry-points. Some entry-points are required as part of the underlying Substrate specification. Others are merely convention and required for the default implementation of the Substrate client to be able to author blocks. In short these two sets are: +Substrate chains all have a runtime. The runtime is a WebAssembly "blob" that includes a number of entry-points. Some entry-points are required as part of the underlying Substrate specification. Others are merely convention and required for the default implementation of the Substrate client to be able to author blocks. -The runtime is API entry points are expected to be in the runtime's `api` module. There is a specific ABI based upon the Substrate Simple Codec (`codec`), which is used to encode and decode the arguments for these functions and specify where and how they should be passed. A special macro is provided called `impl_stubs`, which prepares all functionality for marshalling arguments and basically just allows you to write the functions as you would normally (except for the fact that there must be example one argument - tuples are allowed to workaround). +If you want to develop a chain with Substrate, you will need to implement the `Core` trait. This `Core` trait generates an API with the minimum necessary functionality to interact with your runtime. A special macro is provided called `impl_runtime_apis!` that help you implement runtime API traits. All runtime API trait implementations need to be done in one call of the `impl_runtime_apis!` macro. All parameters and return values need to implement https://crates.io/crates/parity-codec[`parity-codec`] to be encodable and decodable. -Here's the Polkadot API implementation as of PoC-2: +Here's a snippet of the Polkadot API implementation as of PoC-3: ```rust -pub mod api { - impl_stubs!( - - // Standard: Required. - version => |()| super::Version::version(), - authorities => |()| super::Consensus::authorities(), - execute_block => |block| super::Executive::execute_block(block), - - // Conventional: Needed for Substrate client's reference block authoring logic to work. - initialise_block => |header| super::Executive::initialise_block(&header), - apply_extrinsic => |extrinsic| super::Executive::apply_extrinsic(extrinsic), - finalise_block => |()| super::Executive::finalise_block(), - inherent_extrinsics => |inherent| super::inherent_extrinsics(inherent), - - // Non-standard (Polkadot-specific). This just exposes some stuff that Polkadot client - // finds useful. - validator_count => |()| super::Session::validator_count(), - validators => |()| super::Session::validators() - ); +impl_runtime_apis! { + impl client_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } + + fn authorities() -> Vec { + Consensus::authorities() + } + + fn execute_block(block: Block) { + Executive::execute_block(block) + } + + fn initialise_block(header: ::Header) { + Executive::initialise_block(&header) + } + } + // ---snip--- } ``` -As you can see, at the minimum there are only three API calls to implement. If you want to reuse as much of Substrate's reference block authoring client code, then you'll want to provide the next four entrypoints (though three of them you probably already implemented as part of `execute_block`). - -Of the first three, there is `execute_block`, which contains the actions to be taken to execute a block and pretty much defines the blockchain. Then there is `authorities` which tells the AfG consensus algorithm sitting in the Substrate client who the given authorities (known as "validators" in some contexts) are that can finalise the next block. Finally, there is `version`, which is a fairly sophisticated version identifier. This includes a key distinction between *specification version* and *authoring version*, with the former essentially versioning the logic of `execute_block` and the latter versioning only the logic of `inherent_extrinsics` and core aspects of extrinsic validity. === Inherent Extrinsics @@ -124,7 +121,7 @@ To get going as fast as possible, there is a simple script that installs all req [source, shell] ---- -curl getsubstrate.io -sSf | bash +curl https://getsubstrate.io -sSf | bash ---- You can start a local Substrate development chain with running `substrate --dev`. @@ -135,7 +132,7 @@ First let's get a template chainspec that you can edit. We'll use the "staging" [source, shell] ---- -substrate build-spec --chain=staging > ~/chainspec.json +substrate --chain=staging build-spec > ~/chainspec.json ---- Now, edit `~/chainspec.json` in your editor. There are a lot of individual fields for each module, and one very large one which contains the Webassembly code blob for this chain. The easiest field to edit is the block `period`. Change it to 10 (seconds): @@ -151,7 +148,7 @@ Now with this new chainspec file, you can build a "raw" chain definition for you [source, shell] ---- -substrate build-spec --chain ~/chainspec.json --raw > ~/mychain.json +substrate --chain ~/chainspec.json build-spec --raw > ~/mychain.json ---- This can be fed into Substrate: @@ -175,12 +172,15 @@ You can distribute `mychain.json` so that everyone can synchronise and (dependin === Hacking on Substrate -If you'd actually like hack on Substrate, you can just grab the source code and +If you'd actually like to hack on Substrate, you can just grab the source code and build it. Ensure you have Rust and the support software installed: [source, shell] ---- curl https://sh.rustup.rs -sSf | sh +# on Windows download and run rustup-init.exe +# from https://rustup.rs instead + rustup update nightly rustup target add wasm32-unknown-unknown --toolchain nightly rustup update stable @@ -191,11 +191,33 @@ You will also need to install the following packages: - Linux: [source, shell] -sudo apt install cmake pkg-config libssl-dev git +sudo apt install cmake pkg-config libssl-dev git clang libclang-dev - Mac: [source, shell] -brew install cmake pkg-config openssl git +brew install cmake pkg-config openssl git llvm + + - Windows (PowerShell): ++ +[source, shell] +---- +# Install LLVM +# Download and install the Pre Build Windows binaries +# of LLVM from http://releases.llvm.org/download.html + +# Install OpenSSL (through vcpkg) +mkdir \Tools +cd \Tools +git clone https://github.com/Microsoft/vcpkg.git +cd vcpkg +.\bootstrap-vcpkg.bat +.\vcpkg.exe install openssl:x64-windows-static + +$env:OPENSSL_DIR = 'C:\Tools\vcpkg\installed\x64-windows-static' +$env:OPENSSL_STATIC = 'Yes' +[System.Environment]::SetEnvironmentVariable('OPENSSL_DIR', $env:OPENSSL_DIR, [System.EnvironmentVariableTarget]::User) +[System.Environment]::SetEnvironmentVariable('OPENSSL_STATIC', $env:OPENSSL_STATIC, [System.EnvironmentVariableTarget]::User) +---- Then, grab the Substrate source code: @@ -223,22 +245,69 @@ You can start a development chain with: [source, shell] cargo run -- --dev -Or you can join the BBQ Birch Testnet with: +Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run \-- --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 specification that have been endowed with a testnet DOTs. We'll give each node a name and expose them so they are listed on [Telemetry](https://telemetry.polkadot.io/#/Local%20Testnet). You'll need two terminals windows open. + +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 `QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN`, which is generated from the `--node-key` value that we specify below: + +[source, shell] +cargo run -- \ + --base-path /tmp/alice \ + --chain=local \ + --key Alice \ + --name "ALICE" \ + --node-key 0000000000000000000000000000000000000000000000000000000000000001 \ + --telemetry-url ws://telemetry.polkadot.io:1024 \ + --validator + +In the second terminal, we'll run the following to 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: + +[source, shell] +cargo run -- \ + --base-path /tmp/bob \ + --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN \ + --chain=local \ + --key Bob \ + --name "BOB" \ + --port 30334 \ + --telemetry-url ws://telemetry.polkadot.io:1024 \ + --validator + +Additional Substate CLI usage options are available and may be shown by running `cargo run \-- --help`. + +=== Joining the Charred Cherry Testnet + +Charred Cherry is the new testnet for Substrate 1.0 beta. Please note that 1.0 beta is not compatible with the BBQ-Birch testnet. Ensure you have the dependencies listed above before compiling. + +[source, shell] +---- +git clone https://github.com/paritytech/substrate.git +cd substrate +---- + +You can run the tests if you like: + +[source, shell] +cargo test --all + +Start your node: + [source, shell] -cargo run +cargo run --release -If you want to see the multi-node consensus algorithm in action locally, then -you can create a local testnet. You'll need two terminals open. In one, run: +To see a list of command line options, enter: [source, shell] -cargo run -- --chain=local --validator --key Alice -d /tmp/alice --node-key 0000000000000000000000000000000000000000000000000000000000000001 +cargo run --release -- --help -and in the other, run: +For example, you can choose a custom node name: [source, shell] -cargo run -- --chain=local --validator --key Bob -d /tmp/bob --port 30334 --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN +cargo run --release -- --name my_custom_name + +If you are successful, you will see your node syncing at https://telemetry.polkadot.io/#/Charred%20Cherry -include::doc/packages/packages.adoc[] == Documentation @@ -251,13 +320,16 @@ You can generate documentation for a Substrate Rust package and have it automati cargo doc --package --open ``` -Replacing `` with one of the following (i.e. `cargo doc --package node-cli --open`): +Replacing `` with one of the following (i.e. `cargo doc --package substrate --open`): +* All Substrate Packages +[source, shell] +substrate * Substrate Core [source, shell] -substrate, substrate-bft, substrate-cli, substrate-client, substrate-client-db, -substrate-executor, substrate-finality-grandpa, substrate-keyring, substrate-keystore, -substrate-metadata, substrate-misbehavior-check, substrate-network, +substrate, substrate-cli, substrate-client, substrate-client-db, +substrate-consensus-common, substrate-consensus-rhd, +substrate-executor, substrate-finality-grandpa, substrate-keyring, substrate-keystore, substrate-network, substrate-network-libp2p, substrate-primitives, substrate-rpc, substrate-rpc-servers, substrate-serializer, substrate-service, substrate-service-test, substrate-state-db, substrate-state-machine, substrate-telemetry, substrate-test-client, @@ -268,17 +340,16 @@ substrate-trie sr-api, sr-io, sr-primitives, sr-sandbox, sr-std, sr-version * Substrate Runtime Module Library (SRML) [source, shell] -srml-balances, srml-consensus, srml-contract, srml-council, srml-democracy, srml-example, -srml-executive, srml-session, srml-staking, srml-support, srml-system, srml-timestamp, +srml-assets, srml-balances, srml-consensus, srml-contract, srml-council, srml-democracy, srml-example, +srml-executive, srml-metadata, srml-session, srml-staking, srml-support, srml-system, srml-timestamp, srml-treasury * Node [source, shell] -node-cli, node-consensus, node-executor, node-network, node-primitives, node-runtime, node-service +node-cli, node-consensus, node-executor, node-network, node-primitives, node-runtime * Subkey [source, shell] subkey - === Contributing to documentation for Substrate packages https://doc.rust-lang.org/1.9.0/book/documentation.html[Document source code] for Substrate packages by annotating the source code with documentation comments. diff --git a/core/basic-authorship/Cargo.toml b/core/basic-authorship/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..6a5ef1087dab023012d9da63870de1b543354800 --- /dev/null +++ b/core/basic-authorship/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "substrate-basic-authorship" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +log = "0.4" +parity-codec = "2.2" +sr-primitives = { path = "../../core/sr-primitives" } +substrate-client = { path = "../../core/client" } +substrate-consensus-aura-primitives = { path = "../../core/consensus/aura/primitives" } +substrate-consensus-common = { path = "../../core/consensus/common" } +substrate-primitives = { path = "../../core/primitives" } +substrate-transaction-pool = { path = "../../core/transaction-pool" } diff --git a/core/service/src/consensus.rs b/core/basic-authorship/src/basic_authorship.rs similarity index 54% rename from core/service/src/consensus.rs rename to core/basic-authorship/src/basic_authorship.rs index c9a528dd2735ae907763cfdce82221286d2b15d6..d3b6421e6ab2c7d29b31c95e2f0b66cf7332aa0c 100644 --- a/core/service/src/consensus.rs +++ b/core/basic-authorship/src/basic_authorship.rs @@ -14,27 +14,27 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! provide consensus service to substrate. +//! A consensus proposer for "basic" chains which use the primitive inherent-data. // FIXME: move this into substrate-consensus-common - https://github.com/paritytech/substrate/issues/1021 use std::sync::Arc; -use std::time::{self, Duration, Instant}; +use std::time; use std; -use client::{self, error, Client as SubstrateClient, CallExecutor}; -use client::runtime_api::{Core, BlockBuilder as BlockBuilderAPI, id::BLOCK_BUILDER}; +use client::{ + self, error, Client as SubstrateClient, CallExecutor, + block_builder::api::BlockBuilder as BlockBuilderApi, runtime_api::{Core, ApiExt} +}; use codec::{Decode, Encode}; -use consensus_common::{self, InherentData, evaluation, offline_tracker::OfflineTracker}; -use primitives::{H256, AuthorityId, ed25519, Blake2Hasher}; -use runtime_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT}; +use consensus_common::{self, evaluation}; +use primitives::{H256, Blake2Hasher}; +use runtime_primitives::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, ProvideRuntimeApi, AuthorityIdFor}; use runtime_primitives::generic::BlockId; +use runtime_primitives::BasicInherentData; use transaction_pool::txpool::{self, Pool as TransactionPool}; +use aura_primitives::AuraConsensusData; -use parking_lot::RwLock; - -/// Shared offline validator tracker. -pub type SharedOfflineTracker = Arc>; type Timestamp = u64; // block size limit. @@ -47,11 +47,8 @@ pub trait BlockBuilder { } /// Local client abstraction for the consensus. -pub trait AuthoringApi: - Send - + Sync - + BlockBuilderAPI<::Block, Error=::Error> - + Core<::Block, AuthorityId, Error=::Error> +pub trait AuthoringApi: Send + Sync + ProvideRuntimeApi where + ::Api: Core { /// The block used for this API type. type Block: BlockT; @@ -62,25 +59,33 @@ pub trait AuthoringApi: fn build_block) -> ()>( &self, at: &BlockId, - inherent_data: InherentData, + inherent_data: BasicInherentData, build_ctx: F, ) -> Result; } -impl<'a, B, E, Block> BlockBuilder for client::block_builder::BlockBuilder<'a, B, E, Block, Blake2Hasher> where - B: client::backend::Backend + Send + Sync + 'static, +impl<'a, B, E, Block, RA> BlockBuilder + for client::block_builder::BlockBuilder<'a, Block, BasicInherentData, SubstrateClient> +where + B: client::backend::Backend + 'static, E: CallExecutor + Send + Sync + Clone + 'static, Block: BlockT, + RA: Send + Sync + 'static, + SubstrateClient : ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilderApi, { fn push_extrinsic(&mut self, extrinsic: ::Extrinsic) -> Result<(), error::Error> { client::block_builder::BlockBuilder::push(self, extrinsic).map_err(Into::into) } } -impl<'a, B, E, Block> AuthoringApi for SubstrateClient where +impl AuthoringApi for SubstrateClient where B: client::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + Clone + 'static, Block: BlockT, + RA: Send + Sync + 'static, + SubstrateClient : ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: BlockBuilderApi, { type Block = Block; type Error = client::error::Error; @@ -88,14 +93,14 @@ impl<'a, B, E, Block> AuthoringApi for SubstrateClient where fn build_block) -> ()>( &self, at: &BlockId, - inherent_data: InherentData, + inherent_data: BasicInherentData, mut build_ctx: F, ) -> Result { - let runtime_version = self.runtime_version_at(at)?; - let mut block_builder = self.new_block_at(at)?; - if runtime_version.has_api(BLOCK_BUILDER, 1) { - self.inherent_extrinsics(at, &inherent_data)? + + let runtime_api = self.runtime_api(); + if runtime_api.has_api::>(at)? { + runtime_api.inherent_extrinsics(at, inherent_data)? .into_iter().try_for_each(|i| block_builder.push(i))?; } @@ -106,105 +111,105 @@ impl<'a, B, E, Block> AuthoringApi for SubstrateClient where } /// Proposer factory. -pub struct ProposerFactory where - C: AuthoringApi, - A: txpool::ChainApi, -{ +pub struct ProposerFactory where A: txpool::ChainApi { /// The client instance. pub client: Arc, /// The transaction pool. pub transaction_pool: Arc>, - /// Offline-tracker. - pub offline: SharedOfflineTracker, - /// Force delay in evaluation this long. - pub force_delay: Timestamp, } -impl consensus_common::Environment<::Block> for ProposerFactory where +impl consensus_common::Environment<::Block, ConsensusData> for ProposerFactory where C: AuthoringApi, + ::Api: BlockBuilderApi<::Block, BasicInherentData>, A: txpool::ChainApi::Block>, - client::error::Error: From<::Error> + client::error::Error: From<::Error>, + Proposer<::Block, C, A>: consensus_common::Proposer<::Block, ConsensusData>, { - type Proposer = Proposer; + type Proposer = Proposer<::Block, C, A>; type Error = error::Error; fn init( &self, parent_header: &<::Block as BlockT>::Header, - _: &[AuthorityId], - _: Arc, + _: &[AuthorityIdFor<::Block>], ) -> Result { let parent_hash = parent_header.hash(); let id = BlockId::hash(parent_hash); - let authorities: Vec = self.client.authorities(&id)?; - self.offline.write().note_new_block(&authorities[..]); - info!("Starting consensus session on top of parent {:?}", parent_hash); - let now = Instant::now(); let proposer = Proposer { client: self.client.clone(), - start: now, parent_hash, parent_id: id, parent_number: *parent_header.number(), transaction_pool: self.transaction_pool.clone(), - offline: self.offline.clone(), - authorities, - minimum_timestamp: current_timestamp() + self.force_delay, }; Ok(proposer) } } +struct ConsensusData { + timestamp: Option, +} + /// The proposer logic. -pub struct Proposer { +pub struct Proposer { client: Arc, - start: Instant, - parent_hash: <::Block as BlockT>::Hash, - parent_id: BlockId<::Block>, - parent_number: <<::Block as BlockT>::Header as HeaderT>::Number, + parent_hash: ::Hash, + parent_id: BlockId, + parent_number: <::Header as HeaderT>::Number, transaction_pool: Arc>, - offline: SharedOfflineTracker, - authorities: Vec, - minimum_timestamp: u64, } -impl consensus_common::Proposer<::Block> for Proposer where - C: AuthoringApi, - A: txpool::ChainApi::Block>, +impl consensus_common::Proposer<::Block, AuraConsensusData> for Proposer where + Block: BlockT, + C: AuthoringApi, + ::Api: BlockBuilderApi, + A: txpool::ChainApi, client::error::Error: From<::Error> { type Create = Result<::Block, error::Error>; type Error = error::Error; - fn propose(&self) -> Result<::Block, error::Error> { - use runtime_primitives::traits::BlakeTwo256; - - const MAX_VOTE_OFFLINE_SECONDS: Duration = Duration::from_secs(60); + fn propose(&self, consensus_data: AuraConsensusData) + -> Result<::Block, error::Error> + { + self.propose_with(ConsensusData { timestamp: Some(consensus_data.timestamp) }) + } +} - let timestamp = ::std::cmp::max(self.minimum_timestamp, current_timestamp()); +impl consensus_common::Proposer<::Block, ()> for Proposer where + Block: BlockT, + C: AuthoringApi, + ::Api: BlockBuilderApi, + A: txpool::ChainApi, + client::error::Error: From<::Error> +{ + type Create = Result<::Block, error::Error>; + type Error = error::Error; - let elapsed_since_start = self.start.elapsed(); - let offline_indices = if elapsed_since_start > MAX_VOTE_OFFLINE_SECONDS { - Vec::new() - } else { - self.offline.read().reports(&self.authorities[..]) - }; + fn propose(&self, _consensus_data: ()) -> Result<::Block, error::Error> { + self.propose_with(ConsensusData { timestamp: None }) + } +} - if !offline_indices.is_empty() { - info!("Submitting offline authorities {:?} for slash-vote", - offline_indices.iter().map(|&i| self.authorities[i as usize]).collect::>(), - ) - } +impl Proposer where + Block: BlockT, + C: AuthoringApi, + ::Api: BlockBuilderApi, + A: txpool::ChainApi, + client::error::Error: From<::Error>, +{ + fn propose_with(&self, consensus_data: ConsensusData) + -> Result<::Block, error::Error> + { + use runtime_primitives::traits::BlakeTwo256; - let inherent_data = InherentData { - timestamp, - offline_indices, - }; + let timestamp = consensus_data.timestamp.unwrap_or_else(current_timestamp); + let inherent_data = BasicInherentData::new(timestamp, 0); let block = self.client.build_block( &self.parent_id, @@ -233,15 +238,16 @@ impl consensus_common::Proposer<::Block> for Proposer::Block as BlockT>::Hash::from(block.header().hash()), - block.header().parent_hash(), - block.extrinsics().iter() - .map(|xt| format!("{}", BlakeTwo256::hash_of(xt))) - .collect::>() - .join(", ") - ); + info!("Prepared block for proposing at {} [hash: {:?}; parent_hash: {}; extrinsics: [{}]]", + block.header().number(), + <::Block as BlockT>::Hash::from(block.header().hash()), + block.header().parent_hash(), + block.extrinsics() + .iter() + .map(|xt| format!("{}", BlakeTwo256::hash_of(xt))) + .collect::>() + .join(", ") + ); let substrate_block = Decode::decode(&mut block.encode().as_slice()) .expect("blocks are defined to serialize to substrate blocks correctly; qed"); diff --git a/core/basic-authorship/src/lib.rs b/core/basic-authorship/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..0d7e31075084eca660cd7d960bdd95dfb356a9b8 --- /dev/null +++ b/core/basic-authorship/src/lib.rs @@ -0,0 +1,34 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Basic implementation of block-authoring logic. + +#![warn(unused_extern_crates)] + +extern crate substrate_consensus_aura_primitives as aura_primitives; +extern crate substrate_primitives as primitives; +extern crate sr_primitives as runtime_primitives; +extern crate substrate_consensus_common as consensus_common; +extern crate substrate_client as client; +extern crate parity_codec as codec; +extern crate substrate_transaction_pool as transaction_pool; + +#[macro_use] +extern crate log; + +mod basic_authorship; + +pub use basic_authorship::{ProposerFactory, BlockBuilder, AuthoringApi, Proposer}; diff --git a/core/cli/Cargo.toml b/core/cli/Cargo.toml index 4fc17e34cb09aae732da8f6c8a8cdb305f0f5b67..88db4d87c0c5c967eb4c39a0045201a6e49e7be6 100644 --- a/core/cli/Cargo.toml +++ b/core/cli/Cargo.toml @@ -3,10 +3,9 @@ name = "substrate-cli" version = "0.3.0" authors = ["Parity Technologies "] description = "Substrate CLI interface." -build = "build.rs" [dependencies] -clap = { version = "~2.32", features = ["yaml"] } +clap = "~2.32" backtrace = "0.3" env_logger = "0.5" error-chain = "0.12" @@ -22,15 +21,12 @@ tokio = "0.1.7" futures = "0.1.17" fdlimit = "0.1" exit-future = "0.1" -sysinfo = "0.6.2" +sysinfo = "0.7" substrate-client = { path = "../../core/client" } substrate-network = { path = "../../core/network" } -substrate-network-libp2p = { path = "../../core/network-libp2p" } sr-primitives = { path = "../../core/sr-primitives" } substrate-primitives = { path = "../../core/primitives" } substrate-service = { path = "../../core/service" } substrate-telemetry = { path = "../../core/telemetry" } names = "0.11.0" - -[build-dependencies] -clap = "~2.32" +structopt = "0.2.13" diff --git a/core/cli/README.adoc b/core/cli/README.adoc index f847930dab1cd368cd958e3601727127bfabfddc..fc58908fdf23d750409fc5ac8ce20fc40b3800e8 100644 --- a/core/cli/README.adoc +++ b/core/cli/README.adoc @@ -1,13 +1,6 @@ = Substrate CLI -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description Substrate CLI library include::doc/shell-completion.adoc[] diff --git a/core/cli/src/cli.yml b/core/cli/src/cli.yml deleted file mode 100644 index fed66ad91d2a2fe5e6649210b5251b48aff9d274..0000000000000000000000000000000000000000 --- a/core/cli/src/cli.yml +++ /dev/null @@ -1,253 +0,0 @@ -name: {name} -author: {author} -about: {description} -args: - - log: - short: l - long: log - value_name: LOG_PATTERN - help: Sets a custom logging filter - takes_value: true - - base-path: - long: base-path - short: d - value_name: PATH - help: Specify custom base path - takes_value: true - - keystore-path: - long: keystore-path - value_name: PATH - help: Specify custom keystore path - takes_value: true - - key: - long: key - value_name: STRING - help: Specify additional key seed - takes_value: true - - node-key: - long: node-key - value_name: KEY - help: Specify node secret key (64-character hex string) - takes_value: true - - validator: - long: validator - help: Enable validator mode - takes_value: false - - light: - long: light - help: Run in light client mode - takes_value: false - - dev: - long: dev - help: Run in development mode; implies --chain=dev --validator --key Alice - takes_value: false - - listen-addr: - long: listen-addr - value_name: LISTEN_ADDR - help: Listen on this multiaddress - takes_value: true - multiple: true - - port: - long: port - value_name: PORT - help: Specify p2p protocol TCP port. Only used if --listen-addr is not specified. - takes_value: true - - rpc-external: - long: rpc-external - help: Listen to all RPC interfaces (default is local) - takes_value: false - - ws-external: - long: ws-external - help: Listen to all Websocket interfaces (default is local) - takes_value: false - - rpc-port: - long: rpc-port - value_name: PORT - help: Specify HTTP RPC server TCP port - takes_value: true - - ws-port: - long: ws-port - value_name: PORT - help: Specify WebSockets RPC server TCP port - takes_value: true - - bootnodes: - long: bootnodes - value_name: URL - help: Specify a list of bootnodes - takes_value: true - multiple: true - - reserved-nodes: - long: reserved-nodes - value_name: URL - help: Specify a list of reserved node addresses - takes_value: true - multiple: true - - out-peers: - long: out-peers - value_name: OUT_PEERS - help: Specify the number of outgoing connections we're trying to maintain - takes_value: true - - in-peers: - long: in-peers - value_name: IN_PEERS - help: Specify the maximum number of incoming connections we're accepting - takes_value: true - - chain: - long: chain - value_name: CHAIN_SPEC - help: Specify the chain specification (one of dev, local or staging) - takes_value: true - - pruning: - long: pruning - value_name: PRUNING_MODE - help: Specify the pruning mode, a number of blocks to keep or "archive". Default is 256. - takes_value: true - - name: - long: name - value_name: NAME - help: The human-readable name for this node, as reported to the telemetry server, if enabled - takes_value: true - - telemetry: - short: t - long: telemetry - help: Should connect to the Substrate telemetry server (telemetry is off by default on local chains) - takes_value: false - - no-telemetry: - long: no-telemetry - help: Should not connect to the Substrate telemetry server (telemetry is on by default on global chains) - takes_value: false - - telemetry-url: - long: telemetry-url - value_name: TELEMETRY_URL - help: The URL of the telemetry server. Implies --telemetry - takes_value: true - - execution: - long: execution - value_name: STRATEGY - help: The means of execution used when calling into the runtime. Can be either wasm, native or both. -subcommands: - - build-spec: - about: Build a spec.json file, outputing to stdout - args: - - raw: - long: raw - help: Force raw genesis storage output. - takes_value: false - - chain: - long: chain - value_name: CHAIN_SPEC - help: Specify the chain specification (one of dev, local or staging) - takes_value: true - - dev: - long: dev - help: Specify the development chain - takes_value: false - - export-blocks: - about: Export blocks to a file - args: - - OUTPUT: - index: 1 - help: Output file name or stdout if unspecified. - required: false - - chain: - long: chain - value_name: CHAIN_SPEC - help: Specify the chain specification. - takes_value: true - - dev: - long: dev - help: Specify the development chain - takes_value: false - - base-path: - long: base-path - short: d - value_name: PATH - help: Specify custom base path. - takes_value: true - - from: - long: from - value_name: BLOCK - help: Specify starting block number. 1 by default. - takes_value: true - - to: - long: to - value_name: BLOCK - help: Specify last block number. Best block by default. - takes_value: true - - json: - long: json - help: Use JSON output rather than binary. - takes_value: false - - import-blocks: - about: Import blocks from file. - args: - - INPUT: - index: 1 - help: Input file or stdin if unspecified. - required: false - - chain: - long: chain - value_name: CHAIN_SPEC - help: Specify the chain specification. - takes_value: true - - dev: - long: dev - help: Specify the development chain - takes_value: false - - base-path: - long: base-path - short: d - value_name: PATH - help: Specify custom base path. - takes_value: true - - execution: - long: execution - value_name: STRATEGY - help: The means of execution used when executing blocks. Can be either wasm, native or both. - - api-execution: - long: api-execution - value_name: STRATEGY - help: The means of execution used when calling into the runtime. Can be either wasm, native or both. - - max-heap-pages: - long: max-heap-pages - value_name: COUNT - help: The maximum number of 64KB pages to ever allocate for Wasm execution. Don't alter this unless you know what you're doing. - - revert: - about: Revert chain to the previous state - args: - - NUM: - index: 1 - help: Number of blocks to revert. Default is 256. - - chain: - long: chain - value_name: CHAIN_SPEC - help: Specify the chain specification. - takes_value: true - - dev: - long: dev - help: Specify the development chain - takes_value: false - - base-path: - long: base-path - short: d - value_name: PATH - help: Specify custom base path. - takes_value: true - - purge-chain: - about: Remove the whole chain data. - args: - - chain: - long: chain - value_name: CHAIN_SPEC - help: Specify the chain specification. - takes_value: true - - dev: - long: dev - help: Specify the development chain - takes_value: false - - base-path: - long: base-path - short: d - value_name: PATH - help: Specify custom base path. - takes_value: true diff --git a/core/cli/src/informant.rs b/core/cli/src/informant.rs index 85d82132b4f3f5dafa78f331f7d452242a483f8e..0f24f5f6e69f7b5791f2d39b70c33886b1589882 100644 --- a/core/cli/src/informant.rs +++ b/core/cli/src/informant.rs @@ -24,15 +24,16 @@ use tokio::runtime::TaskExecutor; use tokio::timer::Interval; use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; use network::{SyncState, SyncProvider}; -use client::BlockchainEvents; +use client::{backend::Backend, BlockchainEvents}; + +use runtime_primitives::generic::BlockId; use runtime_primitives::traits::{Header, As}; const TIMER_INTERVAL_MS: u64 = 5000; /// Spawn informant on the event loop -pub fn start(service: &Service, exit: ::exit_future::Exit, handle: TaskExecutor) - where - C: Components, +pub fn start(service: &Service, exit: ::exit_future::Exit, handle: TaskExecutor) where + C: Components, { let interval = Interval::new(Instant::now(), Duration::from_millis(TIMER_INTERVAL_MS)); @@ -47,10 +48,10 @@ pub fn start(service: &Service, exit: ::exit_future::Exit, handle: TaskExe let display_notifications = interval.map_err(|e| debug!("Timer error: {:?}", e)).for_each(move |_| { let sync_status = network.status(); - if let Ok(best_block) = client.best_block_header() { - let hash = best_block.hash(); + if let Ok(info) = client.info() { + let best_number: u64 = info.chain.best_number.as_(); + let best_hash = info.chain.best_hash; let num_peers = sync_status.num_peers; - let best_number: u64 = best_block.number().as_(); let speed = move || speed(best_number, last_number); let (status, target) = match (sync_status.sync.state, sync_status.sync.best_seen_block) { (SyncState::Idle, _) => ("Idle".into(), "".into()), @@ -59,14 +60,17 @@ pub fn start(service: &Service, exit: ::exit_future::Exit, handle: TaskExe }; last_number = Some(best_number); let txpool_status = txpool.status(); + let finalized_number: u64 = info.chain.finalized_number.as_(); info!( target: "substrate", - "{}{} ({} peers), best: #{} ({})", + "{}{} ({} peers), best: #{} ({}), finalized #{} ({})", Colour::White.bold().paint(&status), target, Colour::White.bold().paint(format!("{}", sync_status.num_peers)), Colour::White.paint(format!("{}", best_number)), - hash + best_hash, + Colour::White.paint(format!("{}", finalized_number)), + info.chain.finalized_hash, ); // get cpu usage and memory usage of this process @@ -80,10 +84,12 @@ pub fn start(service: &Service, exit: ::exit_future::Exit, handle: TaskExe "status" => format!("{}{}", status, target), "peers" => num_peers, "height" => best_number, - "best" => ?hash, + "best" => ?best_hash, "txcount" => txpool_status.ready, "cpu" => cpu_usage, - "memory" => memory + "memory" => memory, + "finalized_height" => finalized_number, + "finalized_hash" => ?info.chain.finalized_hash, ); } else { warn!("Error getting best block information"); @@ -93,7 +99,36 @@ pub fn start(service: &Service, exit: ::exit_future::Exit, handle: TaskExe }); let client = service.client(); - let display_block_import = client.import_notification_stream().for_each(|n| { + let mut last = match client.info() { + Ok(info) => Some((info.chain.best_number, info.chain.best_hash)), + Err(e) => { warn!("Error getting best block information: {:?}", e); None } + }; + + let display_block_import = client.import_notification_stream().for_each(move |n| { + // detect and log reorganizations. + if let Some((ref last_num, ref last_hash)) = last { + if n.header.parent_hash() != last_hash { + let tree_route = ::client::blockchain::tree_route( + client.backend().blockchain(), + BlockId::Hash(last_hash.clone()), + BlockId::Hash(n.hash), + ); + + match tree_route { + Ok(ref t) if !t.retracted().is_empty() => info!( + "Reorg from #{},{} to #{},{}, common ancestor #{},{}", + last_num, last_hash, + n.header.number(), n.hash, + t.common_block().number, t.common_block().hash, + ), + Ok(_) => {}, + Err(e) => warn!("Error computing tree route: {}", e), + } + } + } + + last = Some((n.header.number().clone(), n.hash.clone())); + info!(target: "substrate", "Imported #{} ({})", n.header.number(), n.hash); Ok(()) }); @@ -121,4 +156,3 @@ fn speed(best_number: u64, last_number: Option) -> String { format!(" {:4.1} bps", speed / 10.0) } } - diff --git a/core/cli/src/lib.rs b/core/cli/src/lib.rs index 59d653bfed7529ab95a2539aecfa6ba1982f0c7c..3205269faf726346be044545607a7b06312f4c47 100644 --- a/core/cli/src/lib.rs +++ b/core/cli/src/lib.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Substrate CLI library. -// end::description[] #![warn(missing_docs)] #![warn(unused_extern_crates)] @@ -36,7 +34,6 @@ extern crate sysinfo; extern crate substrate_client as client; extern crate substrate_network as network; -extern crate substrate_network_libp2p as network_libp2p; extern crate sr_primitives as runtime_primitives; extern crate substrate_service as service; extern crate substrate_primitives as primitives; @@ -53,18 +50,22 @@ extern crate clap; extern crate error_chain; #[macro_use] extern crate log; +extern crate structopt; +mod params; pub mod error; pub mod informant; mod panic_hook; -use network_libp2p::Protocol; use runtime_primitives::traits::As; use service::{ ServiceFactory, FactoryFullConfiguration, RuntimeGenesis, FactoryGenesis, PruningMode, ChainSpec, }; -use network::NonReservedPeerMode; +use network::{ + Protocol, config::{NetworkConfiguration, NonReservedPeerMode}, + multiaddr, +}; use primitives::H256; use std::io::{Write, Read, stdin, stdout}; @@ -76,11 +77,16 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use names::{Generator, Name}; use regex::Regex; +use structopt::StructOpt; +pub use params::{CoreParams, CoreCommands, ExecutionStrategy}; +use app_dirs::{AppInfo, AppDataType}; use futures::Future; /// Executable version. Used to pass version information from the root crate. pub struct VersionInfo { + /// Implemtation name. + pub name: &'static str, /// Implementation version. pub version: &'static str, /// SCM Commit hash. @@ -94,11 +100,11 @@ pub struct VersionInfo { } /// CLI Action -pub enum Action { +pub enum Action { /// Substrate handled the command. No need to do anything. ExecutedInternally, /// Service mode requested. Caller should start the service. - RunService((FactoryFullConfiguration, E)), + RunService(E), } /// Something that can be converted into an exit signal. @@ -109,21 +115,39 @@ pub trait IntoExit { fn into_exit(self) -> Self::Exit; } +fn get_chain_key(matches: &clap::ArgMatches) -> String { + matches.value_of("chain").unwrap_or_else( + || if matches.is_present("dev") { "dev" } else { "" } + ).into() +} + fn load_spec(matches: &clap::ArgMatches, factory: F) -> Result, String> where G: RuntimeGenesis, F: FnOnce(&str) -> Result>, String>, { - let chain_key = matches.value_of("chain").unwrap_or_else(|| if matches.is_present("dev") { "dev" } else { "" }); - let spec = match factory(chain_key)? { + let chain_key = get_chain_key(matches); + let spec = match factory(&chain_key)? { Some(spec) => spec, None => ChainSpec::from_json_file(PathBuf::from(chain_key))? }; Ok(spec) } -fn base_path(matches: &clap::ArgMatches) -> PathBuf { - matches.value_of("base-path") +fn base_path(matches: &clap::ArgMatches, version: &VersionInfo) -> PathBuf { + matches.value_of("base_path") .map(|x| Path::new(x).to_owned()) - .unwrap_or_else(default_base_path) + .unwrap_or_else(|| + app_dirs::get_app_root( + AppDataType::UserData, + &AppInfo { + name: version.executable_name, + author: version.author + } + ).expect("app directories exist on all supported platforms; qed") + ) +} + +fn create_input_err>(msg: T) -> error::Error { + error::ErrorKind::Input(msg.into()).into() } /// Check whether a node name is considered as valid @@ -149,84 +173,42 @@ fn is_node_name_valid(_name: &str) -> Result<(), &str> { Ok(()) } -/// Parse command line arguments and execute commands or return service configuration. -/// -/// IANA unassigned port ranges that we could use: -/// 6717-6766 Unassigned -/// 8504-8553 Unassigned -/// 9556-9591 Unassigned -/// 9803-9874 Unassigned -/// 9926-9949 Unassigned -pub fn prepare_execution( - args: I, - exit: E, - version: VersionInfo, - spec_factory: S, - impl_name: &'static str, -) -> error::Result> +/// Parse command line arguments +pub fn parse_args_default<'a, I, T>(args: I, version: VersionInfo) -> clap::ArgMatches<'a> where I: IntoIterator, T: Into + Clone, - E: IntoExit, - F: ServiceFactory, - S: FnOnce(&str) -> Result>>, String>, { - panic_hook::set(); - let full_version = service::config::full_version_from_strs( version.version, version.commit ); - let yaml = format!(include_str!("./cli.yml"), - name = version.executable_name, - description = version.description, - author = version.author, - ); - let yaml = &clap::YamlLoader::load_from_str(&yaml).expect("Invalid yml file")[0]; - let matches = match clap::App::from_yaml(yaml) + + match CoreParams::clap() + .name(version.executable_name) + .author(version.author) + .about(version.description) .version(&(full_version + "\n")[..]) .get_matches_from_safe(args) { Ok(m) => m, Err(e) => e.exit(), - }; - - // TODO [ToDr] Split parameters parsing from actual execution. - let log_pattern = matches.value_of("log").unwrap_or(""); - init_logger(log_pattern); - fdlimit::raise_fd_limit(); - - if let Some(matches) = matches.subcommand_matches("build-spec") { - let spec = load_spec(&matches, spec_factory)?; - build_spec::(matches, spec)?; - return Ok(Action::ExecutedInternally); - } - - if let Some(matches) = matches.subcommand_matches("export-blocks") { - let spec = load_spec(&matches, spec_factory)?; - export_blocks::(matches, spec, exit.into_exit())?; - return Ok(Action::ExecutedInternally); - } - - if let Some(matches) = matches.subcommand_matches("import-blocks") { - let spec = load_spec(&matches, spec_factory)?; - import_blocks::(matches, spec, exit.into_exit())?; - return Ok(Action::ExecutedInternally); - } - - if let Some(matches) = matches.subcommand_matches("revert") { - let spec = load_spec(&matches, spec_factory)?; - revert_chain::(matches, spec)?; - return Ok(Action::ExecutedInternally); } +} - if let Some(matches) = matches.subcommand_matches("purge-chain") { - let spec = load_spec(&matches, spec_factory)?; - purge_chain::(matches, spec)?; - return Ok(Action::ExecutedInternally); - } +/// Parse clap::Matches into config and chain specification +pub fn parse_matches<'a, F, S>( + spec_factory: S, + version: &VersionInfo, + impl_name: &'static str, + matches: &clap::ArgMatches<'a>, +) -> error::Result<(ChainSpec<::Genesis>, FactoryFullConfiguration)> +where + F: ServiceFactory, + S: FnOnce(&str) -> Result>>, String>, +{ let spec = load_spec(&matches, spec_factory)?; - let mut config = service::Configuration::default_with_spec(spec); + let mut config = service::Configuration::default_with_spec(spec.clone()); config.impl_name = impl_name; config.impl_commit = version.commit; @@ -238,11 +220,17 @@ where }; match is_node_name_valid(&config.name) { Ok(_) => (), - Err(msg) => return Err(error::ErrorKind::Input( - format!("Invalid node name '{}'. Reason: {}. If unsure, use none.", config.name, msg)).into()) + Err(msg) => bail!( + create_input_err( + format!("Invalid node name '{}'. Reason: {}. If unsure, use none.", + config.name, + msg + ) + ) + ) } - let base_path = base_path(&matches); + let base_path = base_path(&matches, version); config.keystore_path = matches.value_of("keystore") .map(|x| Path::new(x).to_owned()) @@ -251,12 +239,15 @@ where .into(); config.database_path = db_path(&base_path, config.chain_spec.id()).to_string_lossy().into(); - + config.database_cache_size = match matches.value_of("database_cache_size") { + Some(s) => Some(s.parse().map_err(|_| "Invalid Database Cache size specified")?), + _=> None + }; config.pruning = match matches.value_of("pruning") { Some("archive") => PruningMode::ArchiveAll, None => PruningMode::default(), Some(s) => PruningMode::keep_blocks(s.parse() - .map_err(|_| error::ErrorKind::Input("Invalid pruning mode specified".to_owned()))?), + .map_err(|_| create_input_err("Invalid pruning mode specified"))?), }; let role = @@ -276,7 +267,7 @@ where "both" => service::ExecutionStrategy::Both, "native" => service::ExecutionStrategy::NativeWhenPossible, "wasm" => service::ExecutionStrategy::AlwaysWasm, - _ => return Err(error::ErrorKind::Input("Invalid execution mode specified".to_owned()).into()), + _ => bail!(create_input_err("Invalid execution mode specified")), }; } @@ -288,14 +279,14 @@ where config.network.config_path = Some(network_path(&base_path, config.chain_spec.id()).to_string_lossy().into()); config.network.net_config_path = config.network.config_path.clone(); config.network.reserved_nodes.extend(matches - .values_of("reserved-nodes") + .values_of("reserved_nodes") .map_or(Default::default(), |v| v.map(|n| n.to_owned()).collect::>())); if !config.network.reserved_nodes.is_empty() { config.network.non_reserved_mode = NonReservedPeerMode::Deny; } config.network.listen_addresses = Vec::new(); - for addr in matches.values_of("listen-addr").unwrap_or_default() { + for addr in matches.values_of("listen_addr").unwrap_or_default() { let addr = addr.parse().map_err(|_| "Invalid listen multiaddress")?; config.network.listen_addresses.push(addr); } @@ -314,17 +305,18 @@ where config.network.public_addresses = Vec::new(); config.network.client_version = config.client_id(); - config.network.use_secret = match matches.value_of("node-key").map(H256::from_str) { + config.network.node_name = config.name.clone(); + config.network.use_secret = match matches.value_of("node_key").map(H256::from_str) { Some(Ok(secret)) => Some(secret.into()), - Some(Err(err)) => return Err(format!("Error parsing node key: {}", err).into()), + Some(Err(err)) => bail!(create_input_err(format!("Error parsing node key: {}", err))), None => None, }; - let in_peers = match matches.value_of("in-peers") { + let in_peers = match matches.value_of("in_peers") { Some(in_peers) => in_peers.parse().map_err(|_| "Invalid in-peers value specified.")?, None => 25, }; - let out_peers = match matches.value_of("out-peers") { + let out_peers = match matches.value_of("out_peers") { Some(out_peers) => out_peers.parse().map_err(|_| "Invalid out-peers value specified.")?, None => 25, }; @@ -338,38 +330,130 @@ where config.keys.push("Alice".into()); } - let rpc_interface: &str = if matches.is_present("rpc-external") { "0.0.0.0" } else { "127.0.0.1" }; - let ws_interface: &str = if matches.is_present("ws-external") { "0.0.0.0" } else { "127.0.0.1" }; + let rpc_interface: &str = if matches.is_present("rpc_external") { "0.0.0.0" } else { "127.0.0.1" }; + let ws_interface: &str = if matches.is_present("ws_external") { "0.0.0.0" } else { "127.0.0.1" }; - config.rpc_http = Some(parse_address(&format!("{}:{}", rpc_interface, 9933), "rpc-port", &matches)?); - config.rpc_ws = Some(parse_address(&format!("{}:{}", ws_interface, 9944), "ws-port", &matches)?); + config.rpc_http = Some(parse_address(&format!("{}:{}", rpc_interface, 9933), "rpc_port", &matches)?); + config.rpc_ws = Some(parse_address(&format!("{}:{}", ws_interface, 9944), "ws_port", &matches)?); // Override telemetry - if matches.is_present("no-telemetry") { + if matches.is_present("no_telemetry") { config.telemetry_url = None; - } else if let Some(url) = matches.value_of("telemetry-url") { + } else if let Some(url) = matches.value_of("telemetry_url") { config.telemetry_url = Some(url.to_owned()); } - Ok(Action::RunService((config, exit))) + Ok((spec, config)) } -fn build_spec(matches: &clap::ArgMatches, spec: ChainSpec>) -> error::Result<()> - where F: ServiceFactory, +// +// IANA unassigned port ranges that we could use: +// 6717-6766 Unassigned +// 8504-8553 Unassigned +// 9556-9591 Unassigned +// 9803-9874 Unassigned +// 9926-9949 Unassigned + +/// execute default commands or return service configuration +pub fn execute_default<'a, F, E>( + spec: ChainSpec>, + exit: E, + matches: &clap::ArgMatches<'a>, + config: &FactoryFullConfiguration +) -> error::Result> +where + E: IntoExit, + F: ServiceFactory, +{ + panic_hook::set(); + + let log_pattern = matches.value_of("log").unwrap_or(""); + init_logger(log_pattern); + fdlimit::raise_fd_limit(); + + if let Some(sub_matches) = matches.subcommand_matches("build-spec") { + build_spec::(sub_matches, spec, config)?; + return Ok(Action::ExecutedInternally); + } else if let Some(sub_matches) = matches.subcommand_matches("export-blocks") { + export_blocks::( + &config.database_path, + sub_matches, + spec, + exit.into_exit() + )?; + return Ok(Action::ExecutedInternally); + } else if let Some(sub_matches) = matches.subcommand_matches("import-blocks") { + import_blocks::( + &config.database_path, + sub_matches, + spec, + exit.into_exit() + )?; + return Ok(Action::ExecutedInternally); + } else if let Some(sub_matches) = matches.subcommand_matches("revert") { + revert_chain::( + &config.database_path, + sub_matches, + spec + )?; + return Ok(Action::ExecutedInternally); + } else if let Some(_sub_matches) = matches.subcommand_matches("purge-chain") { + purge_chain::(&config.database_path)?; + return Ok(Action::ExecutedInternally); + } + + Ok(Action::RunService(exit)) +} + +fn with_default_boot_node( + spec: &ChainSpec>, + config: &NetworkConfiguration +) -> error::Result>> +where + F: ServiceFactory +{ + let mut spec = spec.clone(); + if spec.boot_nodes().is_empty() { + let network_keys = + network::obtain_private_key(config) + .map_err(|err| format!("Error obtaining network key: {}", err))?; + let peer_id = network_keys.to_peer_id(); + let addr = multiaddr![ + Ip4([127, 0, 0, 1]), + Tcp(30333u16), + P2p(peer_id) + ]; + spec.add_boot_node(addr) + } + Ok(spec) +} + +fn build_spec( + matches: &clap::ArgMatches, + spec: ChainSpec>, + config: &FactoryFullConfiguration +) -> error::Result<()> +where + F: ServiceFactory { info!("Building chain spec"); let raw = matches.is_present("raw"); + let spec = with_default_boot_node::(&spec, &config.network)?; let json = service::chain_ops::build_spec::>(spec, raw)?; print!("{}", json); Ok(()) } -fn export_blocks(matches: &clap::ArgMatches, spec: ChainSpec>, exit: E) -> error::Result<()> +fn export_blocks( + db_path: &str, + matches: &clap::ArgMatches, + spec: ChainSpec>, + exit: E +) -> error::Result<()> where F: ServiceFactory, E: Future + Send + 'static, { - let base_path = base_path(matches); let mut config = service::Configuration::default_with_spec(spec); - config.database_path = db_path(&base_path, config.chain_spec.id()).to_string_lossy().into(); + config.database_path = db_path.to_string(); info!("DB path: {}", config.database_path); let from: u64 = match matches.value_of("from") { Some(v) => v.parse().map_err(|_| "Invalid --from argument")?, @@ -382,7 +466,7 @@ fn export_blocks(matches: &clap::ArgMatches, spec: ChainSpec = match matches.value_of("OUTPUT") { + let file: Box = match matches.value_of("output") { Some(filename) => Box::new(File::create(filename)?), None => Box::new(stdout()), }; @@ -390,12 +474,16 @@ fn export_blocks(matches: &clap::ArgMatches, spec: ChainSpec(config, exit, file, As::sa(from), to.map(As::sa), json)?) } -fn import_blocks(matches: &clap::ArgMatches, spec: ChainSpec>, exit: E) -> error::Result<()> +fn import_blocks( + db_path: &str, + matches: &clap::ArgMatches, + spec: ChainSpec>, + exit: E +) -> error::Result<()> where F: ServiceFactory, E: Future + Send + 'static, { - let base_path = base_path(matches); let mut config = service::Configuration::default_with_spec(spec); - config.database_path = db_path(&base_path, config.chain_spec.id()).to_string_lossy().into(); + config.database_path = db_path.to_string(); if let Some(s) = matches.value_of("execution") { config.block_execution_strategy = match s { @@ -415,7 +503,7 @@ fn import_blocks(matches: &clap::ArgMatches, spec: ChainSpec = match matches.value_of("INPUT") { + let file: Box = match matches.value_of("input") { Some(filename) => Box::new(File::open(filename)?), None => Box::new(stdin()), }; @@ -423,14 +511,17 @@ fn import_blocks(matches: &clap::ArgMatches, spec: ChainSpec(config, exit, file)?) } -fn revert_chain(matches: &clap::ArgMatches, spec: ChainSpec>) -> error::Result<()> +fn revert_chain( + db_path: &str, + matches: &clap::ArgMatches, + spec: ChainSpec> +) -> error::Result<()> where F: ServiceFactory, { - let base_path = base_path(matches); let mut config = service::Configuration::default_with_spec(spec); - config.database_path = db_path(&base_path, config.chain_spec.id()).to_string_lossy().into(); + config.database_path = db_path.to_string(); - let blocks = match matches.value_of("NUM") { + let blocks = match matches.value_of("num") { Some(v) => v.parse().map_err(|_| "Invalid block count specified")?, None => 256, }; @@ -438,13 +529,12 @@ fn revert_chain(matches: &clap::ArgMatches, spec: ChainSpec Ok(service::chain_ops::revert_chain::(config, As::sa(blocks))?) } -fn purge_chain(matches: &clap::ArgMatches, spec: ChainSpec>) -> error::Result<()> +fn purge_chain( + db_path: &str, +) -> error::Result<()> where F: ServiceFactory, { - let base_path = base_path(matches); - let database_path = db_path(&base_path, spec.id()); - - print!("Are you sure to remove {:?}? (y/n)", &database_path); + print!("Are you sure to remove {:?}? (y/n)", &db_path); stdout().flush().expect("failed to flush stdout"); let mut input = String::new(); @@ -453,8 +543,8 @@ fn purge_chain(matches: &clap::ArgMatches, spec: ChainSpec> match input.chars().nth(0) { Some('y') | Some('Y') => { - fs::remove_dir_all(&database_path)?; - println!("{:?} removed.", &database_path); + fs::remove_dir_all(&db_path)?; + println!("{:?} removed.", &db_path); }, _ => println!("Aborted"), } @@ -462,10 +552,18 @@ fn purge_chain(matches: &clap::ArgMatches, spec: ChainSpec> Ok(()) } -fn parse_address(default: &str, port_param: &str, matches: &clap::ArgMatches) -> Result { - let mut address: SocketAddr = default.parse().ok().ok_or_else(|| format!("Invalid address specified for --{}.", port_param))?; +fn parse_address( + default: &str, + port_param: &str, + matches: &clap::ArgMatches +) -> Result { + let mut address: SocketAddr = default.parse().ok().ok_or_else( + || format!("Invalid address specified for --{}.", port_param) + )?; if let Some(port) = matches.value_of(port_param) { - let port: u16 = port.parse().ok().ok_or_else(|| format!("Invalid port for --{} specified.", port_param))?; + let port: u16 = port.parse().ok().ok_or_else( + || format!("Invalid port for --{} specified.", port_param) + )?; address.set_port(port); } @@ -496,20 +594,6 @@ fn network_path(base_path: &Path, chain_id: &str) -> PathBuf { path } -fn default_base_path() -> PathBuf { - use app_dirs::{AppInfo, AppDataType}; - - let app_info = AppInfo { - name: "Substrate", - author: "Parity Technologies", - }; - - app_dirs::get_app_root( - AppDataType::UserData, - &app_info, - ).expect("app directories exist on all supported platforms; qed") -} - fn init_logger(pattern: &str) { use ansi_term::Colour; diff --git a/core/cli/src/params.rs b/core/cli/src/params.rs new file mode 100644 index 0000000000000000000000000000000000000000..a73c7cf65f8190cc9cea7333da30a2325e1f8a44 --- /dev/null +++ b/core/cli/src/params.rs @@ -0,0 +1,243 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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::path::PathBuf; +use structopt::StructOpt; + +/// CLI Parameters provided by default +#[derive(Debug, StructOpt)] +#[structopt(name = "Substrate")] +pub struct CoreParams { + ///Sets a custom logging filter + #[structopt(short = "l", long = "log", value_name = "LOG_PATTERN")] + log: Option, + + /// Specify custom keystore path + #[structopt(long = "keystore-path", value_name = "PATH", parse(from_os_str))] + keystore_path: Option, + + /// Specify additional key seed + #[structopt(long = "key", value_name = "STRING")] + key: Option, + + /// Specify node secret key (64-character hex string) + #[structopt(long = "node-key", value_name = "KEY")] + node_key: Option, + + /// Enable validator mode + #[structopt(long = "validator")] + validator: bool, + + /// Run in light client mode + #[structopt(long = "light")] + light: bool, + + /// Limit the memory the database cache can use + #[structopt(long = "db-cache", value_name = "MiB")] + database_cache_size: Option, + + /// Listen on this multiaddress + #[structopt(long = "listen-addr", value_name = "LISTEN_ADDR")] + listen_addr: Vec, + + /// Specify p2p protocol TCP port. Only used if --listen-addr is not specified. + #[structopt(long = "port", value_name = "PORT")] + port: Option, + + /// Listen to all RPC interfaces (default is local) + #[structopt(long = "rpc-external")] + rpc_external: bool, + + /// Listen to all Websocket interfaces (default is local) + #[structopt(long = "ws-external")] + ws_external: bool, + + /// Specify HTTP RPC server TCP port + #[structopt(long = "rpc-port", value_name = "PORT")] + rpc_port: Option, + + /// Specify WebSockets RPC server TCP port + #[structopt(long = "ws-port", value_name = "PORT")] + ws_port: Option, + + /// Specify a list of bootnodes + #[structopt(long = "bootnodes", value_name = "URL")] + bootnodes: Vec, + + /// Specify a list of reserved node addresses + #[structopt(long = "reserved-nodes", value_name = "URL")] + reserved_nodes: Vec, + + /// Specify the number of outgoing connections we're trying to maintain + #[structopt(long = "out-peers", value_name = "OUT_PEERS")] + out_peers: Option, + + /// Specify the maximum number of incoming connections we're accepting + #[structopt(long = "in-peers", value_name = "IN_PEERS")] + in_peers: Option, + + /// Specify the pruning mode, a number of blocks to keep or 'archive'. Default is 256. + #[structopt(long = "pruning", value_name = "PRUNING_MODE")] + pruning: Option, + + /// The human-readable name for this node, as reported to the telemetry server, if enabled + #[structopt(long = "name", value_name = "NAME")] + name: Option, + + /// Should not connect to the Substrate telemetry server (telemetry is on by default on global chains) + #[structopt(long = "no-telemetry")] + no_telemetry: bool, + + /// The URL of the telemetry server to connect to + #[structopt(long = "telemetry-url", value_name = "TELEMETRY_URL")] + telemetry_url: Option, + + /// The means of execution used when calling into the runtime. Can be either wasm, native or both. + #[structopt(long = "execution", value_name = "STRATEGY")] + execution: Option, + + #[allow(missing_docs)] + #[structopt(flatten)] + shared_flags: SharedFlags, + + #[structopt(subcommand)] + cmds: Option, +} + +/// How to execute blocks +#[derive(Debug, StructOpt)] +pub enum ExecutionStrategy { + /// Execute native only + Native, + /// Execute wasm only + Wasm, + /// Execute natively when possible, wasm otherwise + Both, +} + +impl Default for ExecutionStrategy { + fn default() -> Self { + ExecutionStrategy::Both + } +} + +impl std::str::FromStr for ExecutionStrategy { + type Err = String; + fn from_str(input: &str) -> Result { + match input { + "native" => Ok(ExecutionStrategy::Native), + "wasm" | "webassembly" => Ok(ExecutionStrategy::Wasm), + "both" => Ok(ExecutionStrategy::Both), + _ => Err("Please specify either 'native', 'wasm' or 'both".to_owned()) + + } + } +} + +/// Flags used by `CoreParams` and almost all `CoreCommands`. +#[derive(Debug, StructOpt)] +pub struct SharedFlags { + /// Specify the chain specification (one of dev, local or staging) + #[structopt(long = "chain", value_name = "CHAIN_SPEC")] + chain: Option, + + /// Specify the development chain + #[structopt(long = "dev")] + dev: bool, + + /// Specify custom base path. + #[structopt(long = "base-path", short = "d", value_name = "PATH")] + base_path: Option, +} + +/// Subcommands provided by Default +#[derive(Debug, StructOpt)] +pub enum CoreCommands { + /// Build a spec.json file, outputing to stdout + #[structopt(name = "build-spec")] + BuildSpec { + /// Force raw genesis storage output. + #[structopt(long = "raw")] + raw: bool, + }, + + /// Export blocks to a file + #[structopt(name = "export-blocks")] + ExportBlocks { + /// Output file name or stdout if unspecified. + #[structopt(parse(from_os_str))] + output: Option, + + /// Specify starting block number. 1 by default. + #[structopt(long = "from", value_name = "BLOCK")] + from: Option, + + /// Specify last block number. Best block by default. + #[structopt(long = "to", value_name = "BLOCK")] + to: Option, + + /// Use JSON output rather than binary. + #[structopt(long = "json")] + json: bool, + + #[allow(missing_docs)] + #[structopt(flatten)] + shared_flags: SharedFlags, + }, + + /// Import blocks from file. + #[structopt(name = "import-blocks")] + ImportBlocks { + /// Input file or stdin if unspecified. + #[structopt(parse(from_os_str))] + input: Option, + + /// The means of execution used when executing blocks. Can be either wasm, native or both. + #[structopt(long = "execution", value_name = "STRATEGY")] + execution: ExecutionStrategy, + + /// The means of execution used when calling into the runtime. Can be either wasm, native or both. + #[structopt(long = "api-execution", value_name = "STRATEGY")] + api_execution: ExecutionStrategy, + + /// The maximum number of 64KB pages to ever allocate for Wasm execution. Don't alter this unless you know what you're doing. + #[structopt(long = "max-heap-pages", value_name = "COUNT")] + max_heap_pages: Option, + + #[allow(missing_docs)] + #[structopt(flatten)] + shared_flags: SharedFlags, + }, + + ///Revert chain to the previous state + #[structopt(name = "revert")] + Revert { + /// Number of blocks to revert. Default is 256. + num: Option, + + #[allow(missing_docs)] + #[structopt(flatten)] + shared_flags: SharedFlags, + }, + + /// Remove the whole chain data. + #[structopt(name = "purge-chain")] + PurgeChain { + #[allow(missing_docs)] + #[structopt(flatten)] + shared_flags: SharedFlags, + }, +} diff --git a/core/client/Cargo.toml b/core/client/Cargo.toml index 5eeb75940d4b188270921d440bd5469624ebf86b..e06139cc11dec0211cb90fce2e5c3581ad589562 100644 --- a/core/client/Cargo.toml +++ b/core/client/Cargo.toml @@ -2,29 +2,59 @@ name = "substrate-client" version = "0.1.0" authors = ["Parity Technologies "] +edition = "2018" [dependencies] -error-chain = "0.12" -fnv = "1.0" -log = "0.4" -parking_lot = "0.4" -hex-literal = "0.1" -futures = "0.1.17" -slog = "^2" -heapsize = "0.4" -substrate-consensus-common = { path = "../consensus/common" } -parity-codec = "2.1" -substrate-executor = { path = "../executor" } -substrate-primitives = { path = "../primitives" } -sr-primitives = { path = "../sr-primitives" } -sr-api = { path = "../sr-api" } -substrate-state-machine = { path = "../state-machine" } -substrate-keyring = { path = "../keyring" } -substrate-trie = { path = "../trie" } -substrate-telemetry = { path = "../telemetry" } -hash-db = { git = "https://github.com/paritytech/trie" } -kvdb = "0.1" +error-chain = { version = "0.12", optional = true } +fnv = { version = "1.0", optional = true } +log = { version = "0.4", optional = true } +parking_lot = { version = "0.7.1", optional = true } +hex = { package = "hex-literal", version = "0.1", optional = true } +futures = { version = "0.1.17", optional = true } +slog = { version = "^2", optional = true } +heapsize = { version = "0.4", optional = true } +consensus = { package = "substrate-consensus-common", path = "../consensus/common", optional = true } +executor = { package = "substrate-executor", path = "../executor", optional = true } +state-machine = { package = "substrate-state-machine", path = "../state-machine", optional = true } +keyring = { package = "substrate-keyring", path = "../keyring", optional = true } +trie = { package = "substrate-trie", path = "../trie", optional = true } +substrate-telemetry = { path = "../telemetry", optional = true } +hash-db = { version = "0.9" , optional = true } +kvdb = { git = "https://github.com/paritytech/parity-common", optional = true, rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } + +codec = { package = "parity-codec", version = "2.1", default-features = false } +primitives = { package = "substrate-primitives", path = "../primitives", default-features = false } +runtime-primitives = { package = "sr-primitives", path = "../sr-primitives", default-features = false } +runtime-version = { package = "sr-version", path = "../sr-version", default-features = false } +rstd = { package = "sr-std", path = "../sr-std", default-features = false } +sr-api-macros = { path = "../sr-api-macros" } [dev-dependencies] -substrate-test-client = { path = "../test-client" } -kvdb-memorydb = "0.1" +test-client = { package = "substrate-test-client", path = "../test-client" } +kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } + +[features] +default = ["std"] +std = [ + "codec/std", + "consensus", + "primitives/std", + "parking_lot", + "error-chain", + "fnv", + "log", + "hex", + "futures", + "slog", + "heapsize", + "executor", + "runtime-primitives/std", + "runtime-version/std", + "rstd/std", + "state-machine", + "keyring", + "trie", + "substrate-telemetry", + "hash-db", + "kvdb" +] diff --git a/core/client/README.adoc b/core/client/README.adoc deleted file mode 100644 index d644b1d039b118136d21545d05c0f47ab19443da..0000000000000000000000000000000000000000 --- a/core/client/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Client - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/client/db/Cargo.toml b/core/client/db/Cargo.toml index 4f6c78583302f336f5631038ca02c456e7f2e639..ac89782fdffefc8f27b8930b4487a4e1f3e3dde4 100644 --- a/core/client/db/Cargo.toml +++ b/core/client/db/Cargo.toml @@ -4,22 +4,24 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -parking_lot = "0.4" +parking_lot = "0.7.1" log = "0.4" -kvdb = "0.1" -kvdb-rocksdb = "0.1.3" -hash-db = { git = "https://github.com/paritytech/trie" } +kvdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } +# FIXME replace with release as soon as our rocksdb changes are released upstream https://github.com/paritytech/parity-common/issues/88 +kvdb-rocksdb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } +lru-cache = "0.1" +hash-db = { version = "0.9" } substrate-primitives = { path = "../../primitives" } sr-primitives = { path = "../../sr-primitives" } substrate-client = { path = "../../client" } substrate-state-machine = { path = "../../state-machine" } -parity-codec = "2.1" +parity-codec = "2.2" parity-codec-derive = "2.1" substrate-executor = { path = "../../executor" } substrate-state-db = { path = "../../state-db" } substrate-trie = { path = "../../trie" } [dev-dependencies] -kvdb-memorydb = "0.1" +kvdb-memorydb = { git = "https://github.com/paritytech/parity-common", rev="b0317f649ab2c665b7987b8475878fc4d2e1f81d" } substrate-keyring = { path = "../../keyring" } substrate-test-client = { path = "../../test-client" } diff --git a/core/client/db/README.adoc b/core/client/db/README.adoc deleted file mode 100644 index c0b123392c81687523fc582182c6278ebf085a53..0000000000000000000000000000000000000000 --- a/core/client/db/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Client DB - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/client/db/src/cache/list_storage.rs b/core/client/db/src/cache/list_storage.rs index ea3fbb94acc8069a3f2389987f1b7568685f47ea..ec6883d26296b98a95485c4053841656dcfcfaed 100644 --- a/core/client/db/src/cache/list_storage.rs +++ b/core/client/db/src/cache/list_storage.rs @@ -86,7 +86,7 @@ pub struct DbColumns { /// Column holding cache meta. pub meta: Option, /// Column holding the mapping of { block number => block hash } for blocks of the best chain. - pub hash_lookup: Option, + pub key_lookup: Option, /// Column holding the mapping of { block hash => block header }. pub header: Option, /// Column holding cache entries. @@ -126,12 +126,12 @@ impl DbStorage { impl Storage for DbStorage { fn read_id(&self, at: NumberFor) -> ClientResult> { - utils::read_header::(&*self.db, self.columns.hash_lookup, self.columns.header, BlockId::Number(at)) + utils::read_header::(&*self.db, self.columns.key_lookup, self.columns.header, BlockId::Number(at)) .map(|maybe_header| maybe_header.map(|header| header.hash())) } fn read_header(&self, at: &Block::Hash) -> ClientResult> { - utils::read_header::(&*self.db, self.columns.hash_lookup, self.columns.header, BlockId::Hash(*at)) + utils::read_header::(&*self.db, self.columns.key_lookup, self.columns.header, BlockId::Hash(*at)) } fn read_meta(&self) -> ClientResult> { @@ -197,7 +197,7 @@ impl<'a, Block: BlockT, T: CacheItemT> StorageTransaction for DbStorag mod meta { use super::*; - /// Convert cache name into cache metadata key. + /// Convert cache name into cache metadata key. pub fn key(name: &[u8]) -> Vec { let mut key_name = meta_keys::CACHE_META_PREFIX.to_vec(); key_name.extend_from_slice(name); diff --git a/core/client/db/src/cache/mod.rs b/core/client/db/src/cache/mod.rs index 788ad8b61e4adfd16babbc8d8c6a91c98c04db02..11fbd93392ce7cd83fcb782aa447439b57015cdc 100644 --- a/core/client/db/src/cache/mod.rs +++ b/core/client/db/src/cache/mod.rs @@ -24,9 +24,8 @@ use kvdb::{KeyValueDB, DBTransaction}; use client::blockchain::Cache as BlockchainCache; use client::error::Result as ClientResult; use codec::{Encode, Decode}; -use primitives::AuthorityId; use runtime_primitives::generic::BlockId; -use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, As}; +use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, As, AuthorityIdFor}; use utils::{self, COLUMN_META}; use self::list_cache::ListCache; @@ -65,14 +64,14 @@ impl CacheItemT for T where T: Clone + Decode + Encode + PartialEq {} /// Database-backed blockchain data cache. pub struct DbCache { - authorities_at: ListCache, self::list_storage::DbStorage>, + authorities_at: ListCache>, self::list_storage::DbStorage>, } impl DbCache { /// Create new cache. pub fn new( db: Arc, - hash_lookup_column: Option, + key_lookup_column: Option, header_column: Option, authorities_column: Option, best_finalized_block: ComplexBlockId, @@ -82,7 +81,7 @@ impl DbCache { self::list_storage::DbStorage::new(b"auth".to_vec(), db, self::list_storage::DbColumns { meta: COLUMN_META, - hash_lookup: hash_lookup_column, + key_lookup: key_lookup_column, header: header_column, cache: authorities_column, }, @@ -112,14 +111,14 @@ impl DbCache { /// Cache operations that are to be committed after database transaction is committed. pub struct DbCacheTransactionOps { - authorities_at_op: Option>>, + authorities_at_op: Option>>>, } /// Database-backed blockchain data cache transaction valid for single block import. pub struct DbCacheTransaction<'a, Block: BlockT> { cache: &'a mut DbCache, tx: &'a mut DBTransaction, - authorities_at_op: Option>>, + authorities_at_op: Option>>>, } impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> { @@ -135,7 +134,7 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> { mut self, parent: ComplexBlockId, block: ComplexBlockId, - authorities_at: Option>, + authorities_at: Option>>, is_final: bool, ) -> ClientResult { assert!(self.authorities_at_op.is_none()); @@ -179,7 +178,7 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> { pub struct DbCacheSync(pub RwLock>); impl BlockchainCache for DbCacheSync { - fn authorities_at(&self, at: BlockId) -> Option> { + fn authorities_at(&self, at: BlockId) -> Option>> { let cache = self.0.read(); let storage = cache.authorities_at.storage(); let db = storage.db(); @@ -188,7 +187,7 @@ impl BlockchainCache for DbCacheSync { BlockId::Hash(hash) => { let header = utils::read_header::( &**db, - columns.hash_lookup, + columns.key_lookup, columns.header, BlockId::Hash(hash.clone())).ok()??; ComplexBlockId::new(hash, *header.number()) @@ -196,7 +195,7 @@ impl BlockchainCache for DbCacheSync { BlockId::Number(number) => { let hash = utils::read_header::( &**db, - columns.hash_lookup, + columns.key_lookup, columns.header, BlockId::Number(number.clone())).ok()??.hash(); ComplexBlockId::new(hash, number) diff --git a/core/client/db/src/lib.rs b/core/client/db/src/lib.rs index 1e37b61cfd4e20cc4352873762f8c0dbd9e6222e..0b61334b4ea4a14ead780a8f79f860eaf4d093a4 100644 --- a/core/client/db/src/lib.rs +++ b/core/client/db/src/lib.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Client backend that uses RocksDB database as storage. //! //! # Canonicality vs. Finality @@ -24,14 +23,13 @@ //! having discarded heavy state that will allow a chain reorganization. //! //! Finality implies canonicality but not vice-versa. -//! -// end::description[] extern crate substrate_client as client; extern crate kvdb_rocksdb; extern crate kvdb; extern crate hash_db; extern crate parking_lot; +extern crate lru_cache; extern crate substrate_state_machine as state_machine; extern crate substrate_primitives as primitives; extern crate sr_primitives as runtime_primitives; @@ -55,6 +53,7 @@ extern crate kvdb_memorydb; pub mod light; mod cache; +mod storage_cache; mod utils; use std::sync::Arc; @@ -67,10 +66,10 @@ use hash_db::Hasher; use kvdb::{KeyValueDB, DBTransaction}; use trie::MemoryDB; use parking_lot::RwLock; -use primitives::{H256, AuthorityId, Blake2Hasher, ChangesTrieConfiguration}; +use primitives::{H256, Blake2Hasher, ChangesTrieConfiguration, convert_hash}; use primitives::storage::well_known_keys; use runtime_primitives::{generic::BlockId, Justification, StorageMap, ChildrenStorageMap}; -use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberFor, Zero, Digest, DigestItem}; +use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberFor, Zero, Digest, DigestItem, AuthorityIdFor}; use runtime_primitives::BuildStorage; use state_machine::backend::Backend as StateBackend; use executor::RuntimeInfo; @@ -78,10 +77,12 @@ use state_machine::{CodeExecutor, DBValue, ExecutionStrategy}; use utils::{Meta, db_err, meta_keys, open_database, read_db, block_id_to_lookup_key, read_meta}; use client::LeafSet; use state_db::StateDb; +use storage_cache::{CachingState, SharedCache, new_shared_cache}; pub use state_db::PruningMode; const CANONICALIZATION_DELAY: u64 = 256; const MIN_BLOCKS_TO_KEEP_CHANGES_TRIES_FOR: u64 = 32768; +const STATE_CACHE_SIZE_BYTES: usize = 16 * 1024 * 1024; /// DB-backed patricia trie state, transaction type is an overlay of changes to commit. pub type DbState = state_machine::TrieBackend>, Blake2Hasher>; @@ -97,17 +98,17 @@ pub struct DatabaseSettings { } /// Create an instance of db-backed client. -pub fn new_client( +pub fn new_client( settings: DatabaseSettings, executor: E, genesis_storage: S, block_execution_strategy: ExecutionStrategy, api_execution_strategy: ExecutionStrategy, -) -> Result, client::LocalCallExecutor, E>, Block>, client::error::Error> -where - Block: BlockT, - E: CodeExecutor + RuntimeInfo, - S: BuildStorage, +) -> Result, client::LocalCallExecutor, E>, Block, RA>, client::error::Error> + where + Block: BlockT, + E: CodeExecutor + RuntimeInfo, + S: BuildStorage, { let backend = Arc::new(Backend::new(settings, CANONICALIZATION_DELAY)?); let executor = client::LocalCallExecutor::new(backend.clone(), executor); @@ -118,8 +119,8 @@ mod columns { pub const META: Option = ::utils::COLUMN_META; pub const STATE: Option = Some(1); pub const STATE_META: Option = Some(2); - /// maps hashes to lookup keys - pub const HASH_LOOKUP: Option = Some(3); + /// maps hashes to lookup keys and numbers to canon hashes. + pub const KEY_LOOKUP: Option = Some(3); pub const HEADER: Option = Some(4); pub const BODY: Option = Some(5); pub const JUSTIFICATION: Option = Some(6); @@ -148,7 +149,7 @@ impl<'a> state_db::MetaDb for StateMetaDb<'a> { /// Block database pub struct BlockchainDb { db: Arc, - meta: RwLock, Block::Hash>>, + meta: Arc, Block::Hash>>>, leaves: RwLock>>, } @@ -159,7 +160,7 @@ impl BlockchainDb { Ok(BlockchainDb { db, leaves: RwLock::new(leaves), - meta: RwLock::new(meta), + meta: Arc::new(RwLock::new(meta)), }) } @@ -171,7 +172,7 @@ impl BlockchainDb { is_finalized: bool ) { let mut meta = self.meta.write(); - if number == Zero::zero() { + if number.is_zero() { meta.genesis_hash = hash; meta.finalized_hash = hash; } @@ -190,7 +191,7 @@ impl BlockchainDb { impl client::blockchain::HeaderBackend for BlockchainDb { fn header(&self, id: BlockId) -> Result, client::error::Error> { - ::utils::read_header(&*self.db, columns::HASH_LOOKUP, columns::HEADER, id) + ::utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id) } fn info(&self) -> Result, client::error::Error> { @@ -208,7 +209,7 @@ impl client::blockchain::HeaderBackend for BlockchainDb read_db( &*self.db, - columns::HASH_LOOKUP, + columns::KEY_LOOKUP, columns::HEADER, id )?.is_some(), @@ -221,7 +222,7 @@ impl client::blockchain::HeaderBackend for BlockchainDb Result>, client::error::Error> { - if let Some(lookup_key) = block_id_to_lookup_key::(&*self.db, columns::HASH_LOOKUP, BlockId::Hash(hash))? { + if let Some(lookup_key) = block_id_to_lookup_key::(&*self.db, columns::KEY_LOOKUP, BlockId::Hash(hash))? { let number = utils::lookup_key_to_number(&lookup_key)?; Ok(Some(number)) } else { @@ -239,7 +240,7 @@ impl client::blockchain::HeaderBackend for BlockchainDb client::blockchain::Backend for BlockchainDb { fn body(&self, id: BlockId) -> Result>, client::error::Error> { - match read_db(&*self.db, columns::HASH_LOOKUP, columns::BODY, id)? { + match read_db(&*self.db, columns::KEY_LOOKUP, columns::BODY, id)? { Some(body) => match Decode::decode(&mut &body[..]) { Some(body) => Ok(Some(body)), None => return Err(client::error::ErrorKind::Backend("Error decoding body".into()).into()), @@ -249,7 +250,7 @@ impl client::blockchain::Backend for BlockchainDb { } fn justification(&self, id: BlockId) -> Result, client::error::Error> { - match read_db(&*self.db, columns::HASH_LOOKUP, columns::JUSTIFICATION, id)? { + match read_db(&*self.db, columns::KEY_LOOKUP, columns::JUSTIFICATION, id)? { Some(justification) => match Decode::decode(&mut &justification[..]) { Some(justification) => Ok(Some(justification)), None => return Err(client::error::ErrorKind::Backend("Error decoding justification".into()).into()), @@ -273,17 +274,30 @@ impl client::blockchain::Backend for BlockchainDb { /// Database transaction pub struct BlockImportOperation { - old_state: DbState, - updates: MemoryDB, + old_state: CachingState, + db_updates: MemoryDB, + storage_updates: Vec<(Vec, Option>)>, changes_trie_updates: MemoryDB, pending_block: Option>, + aux_ops: Vec<(Vec, Option>)>, +} + +impl BlockImportOperation { + fn apply_aux(&mut self, transaction: &mut DBTransaction) { + for (key, maybe_val) in self.aux_ops.drain(..) { + match maybe_val { + Some(val) => transaction.put_vec(columns::AUX, &key, val), + None => transaction.delete(columns::AUX, &key), + } + } + } } impl client::backend::BlockImportOperation for BlockImportOperation where Block: BlockT, { - type State = DbState; + type State = CachingState; fn state(&self) -> Result, client::error::Error> { Ok(Some(&self.old_state)) @@ -306,12 +320,12 @@ where Block: BlockT, Ok(()) } - fn update_authorities(&mut self, _authorities: Vec) { + fn update_authorities(&mut self, _authorities: Vec>) { // currently authorities are not cached on full nodes } - fn update_storage(&mut self, update: MemoryDB) -> Result<(), client::error::Error> { - self.updates = update; + fn update_db_storage(&mut self, update: MemoryDB) -> Result<(), client::error::Error> { + self.db_updates = update; Ok(()) } @@ -340,7 +354,7 @@ where Block: BlockT, let (root, update) = self.old_state.storage_root(top.into_iter().map(|(k, v)| (k, Some(v)))); transaction.consolidate(update); - self.updates = transaction; + self.db_updates = transaction; Ok(root) } @@ -348,6 +362,18 @@ where Block: BlockT, self.changes_trie_updates = update; Ok(()) } + + fn set_aux(&mut self, ops: I) -> Result<(), client::error::Error> + where I: IntoIterator, Option>)> + { + self.aux_ops = ops.into_iter().collect(); + Ok(()) + } + + fn update_storage(&mut self, update: Vec<(Vec, Option>)>) -> Result<(), client::error::Error> { + self.storage_updates = update; + Ok(()) + } } struct StorageDb { @@ -390,6 +416,7 @@ impl state_machine::Storage for DbGenesisStorage { pub struct DbChangesTrieStorage { db: Arc, + meta: Arc, Block::Hash>>>, min_blocks_to_keep: Option, _phantom: ::std::marker::PhantomData, } @@ -403,7 +430,7 @@ impl DbChangesTrieStorage { } /// Prune obsolete changes tries. - pub fn prune(&self, config: Option, tx: &mut DBTransaction, block: NumberFor) { + pub fn prune(&self, config: Option, tx: &mut DBTransaction, block_hash: Block::Hash, block_num: NumberFor) { // never prune on archive nodes let min_blocks_to_keep = match self.min_blocks_to_keep { Some(min_blocks_to_keep) => min_blocks_to_keep, @@ -421,23 +448,71 @@ impl DbChangesTrieStorage { &config, &*self, min_blocks_to_keep, - block.as_(), + &state_machine::ChangesTrieAnchorBlockId { + hash: convert_hash(&block_hash), + number: block_num.as_(), + }, |node| tx.delete(columns::CHANGES_TRIE, node.as_ref())); } } +impl client::backend::PrunableStateChangesTrieStorage for DbChangesTrieStorage { + fn oldest_changes_trie_block( + &self, + config: &ChangesTrieConfiguration, + best_finalized_block: u64 + ) -> u64 { + match self.min_blocks_to_keep { + Some(min_blocks_to_keep) => state_machine::oldest_non_pruned_changes_trie( + config, + min_blocks_to_keep, + best_finalized_block, + ), + None => 1, + } + } +} + impl state_machine::ChangesTrieRootsStorage for DbChangesTrieStorage { - fn root(&self, block: u64) -> Result, String> { - Ok(read_db::(&*self.db, columns::HASH_LOOKUP, columns::HEADER, BlockId::Number(As::sa(block))) - .map_err(|err| format!("{}", err)) - .and_then(|header| match header { - Some(header) => Block::Header::decode(&mut &header[..]) - .ok_or_else(|| format!("Failed to parse header of block {}", block)) - .map(Some), - None => Ok(None) - })? - .and_then(|header| header.digest().log(DigestItem::as_changes_trie_root) - .map(|root| H256::from_slice(root.as_ref())))) + fn root(&self, anchor: &state_machine::ChangesTrieAnchorBlockId, block: u64) -> Result, String> { + // check API requirement + assert!(block <= anchor.number, "API requirement"); + + // we need to get hash of the block to resolve changes trie root + let block_id = if block <= self.meta.read().finalized_number.as_() { + // if block is finalized, we could just read canonical hash + BlockId::Number(As::sa(block)) + } else { + // the block is not finalized + let mut current_num = anchor.number; + let mut current_hash: Block::Hash = convert_hash(&anchor.hash); + let maybe_anchor_header: Block::Header = ::utils::require_header::( + &*self.db, columns::KEY_LOOKUP, columns::HEADER, BlockId::Number(As::sa(current_num)) + ).map_err(|e| e.to_string())?; + if maybe_anchor_header.hash() == current_hash { + // if anchor is canonicalized, then the block is also canonicalized + BlockId::Number(As::sa(block)) + } else { + // else (block is not finalized + anchor is not canonicalized): + // => we should find the required block hash by traversing + // back from the anchor to the block with given number + while current_num != block { + let current_header: Block::Header = ::utils::require_header::( + &*self.db, columns::KEY_LOOKUP, columns::HEADER, BlockId::Hash(current_hash) + ).map_err(|e| e.to_string())?; + + current_hash = *current_header.parent_hash(); + current_num = current_num - 1; + } + + BlockId::Hash(current_hash) + } + }; + + Ok(::utils::require_header::(&*self.db, columns::KEY_LOOKUP, columns::HEADER, block_id) + .map_err(|e| e.to_string())? + .digest().log(DigestItem::as_changes_trie_root) + .map(|root| H256::from_slice(root.as_ref()))) } } @@ -455,6 +530,7 @@ pub struct Backend { changes_tries_storage: DbChangesTrieStorage, blockchain: BlockchainDb, canonicalization_delay: u64, + shared_cache: SharedCache, } impl Backend { @@ -483,6 +559,7 @@ impl Backend { fn from_kvdb(db: Arc, pruning: PruningMode, canonicalization_delay: u64) -> Result { let is_archive_pruning = pruning.is_archive(); let blockchain = BlockchainDb::new(db.clone())?; + let meta = blockchain.meta.clone(); let map_e = |e: state_db::Error| ::client::error::Error::from(format!("State database error: {:?}", e)); let state_db: StateDb = StateDb::new(pruning, &StateMetaDb(&*db)).map_err(map_e)?; let storage_db = StorageDb { @@ -491,6 +568,7 @@ impl Backend { }; let changes_tries_storage = DbChangesTrieStorage { db, + meta, min_blocks_to_keep: if is_archive_pruning { None } else { Some(MIN_BLOCKS_TO_KEEP_CHANGES_TRIES_FOR) }, _phantom: Default::default(), }; @@ -500,6 +578,7 @@ impl Backend { changes_tries_storage, blockchain, canonicalization_delay, + shared_cache: new_shared_cache(STATE_CACHE_SIZE_BYTES), }) } @@ -559,7 +638,7 @@ impl Backend { ).into()) } - let lookup_key = ::utils::number_to_lookup_key(f_num); + let lookup_key = ::utils::number_and_hash_to_lookup_key(f_num, f_hash.clone()); transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key); let commit = self.storage.state_db.canonicalize_block(&f_hash); @@ -570,7 +649,7 @@ impl Backend { let changes_trie_config: Option = self.state_at(BlockId::Hash(parent_hash))? .storage(well_known_keys::CHANGES_TRIE_CONFIG)? .and_then(|v| Decode::decode(&mut &*v)); - self.changes_tries_storage.prune(changes_trie_config, transaction, f_num); + self.changes_tries_storage.prune(changes_trie_config, transaction, f_hash, f_num); } Ok(()) @@ -592,10 +671,34 @@ fn apply_state_commit(transaction: &mut DBTransaction, commit: state_db::CommitS } } +impl client::backend::AuxStore for Backend where Block: BlockT { + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >(&self, insert: I, delete: D) -> client::error::Result<()> { + let mut transaction = DBTransaction::new(); + for (k, v) in insert { + transaction.put(columns::AUX, k, v); + } + for k in delete { + transaction.delete(columns::AUX, k); + } + self.storage.db.write(transaction).map_err(db_err)?; + Ok(()) + } + + fn get_aux(&self, key: &[u8]) -> Result>, client::error::Error> { + Ok(self.storage.db.get(columns::AUX, key).map(|r| r.map(|v| v.to_vec())).map_err(db_err)?) + } +} + impl client::backend::Backend for Backend where Block: BlockT { type BlockImportOperation = BlockImportOperation; type Blockchain = BlockchainDb; - type State = DbState; + type State = CachingState; type ChangesTrieStorage = DbChangesTrieStorage; fn begin_operation(&self, block: BlockId) -> Result { @@ -603,8 +706,10 @@ impl client::backend::Backend for Backend whe Ok(BlockImportOperation { pending_block: None, old_state: state, - updates: MemoryDB::default(), + db_updates: MemoryDB::default(), + storage_updates: Default::default(), changes_trie_updates: MemoryDB::default(), + aux_ops: Vec::new(), }) } @@ -612,19 +717,18 @@ impl client::backend::Backend for Backend whe -> Result<(), client::error::Error> { let mut transaction = DBTransaction::new(); + operation.apply_aux(&mut transaction); if let Some(pending_block) = operation.pending_block { let hash = pending_block.header.hash(); let parent_hash = *pending_block.header.parent_hash(); let number = pending_block.header.number().clone(); - // blocks in longest chain are keyed by number - let lookup_key = if pending_block.leaf_state.is_best() { - ::utils::number_to_lookup_key(number).to_vec() - } else { - // other blocks are keyed by number + hash - ::utils::number_and_hash_to_lookup_key(number, hash) - }; + // blocks are keyed by number + hash. + let lookup_key = ::utils::number_and_hash_to_lookup_key(number, hash); + + let mut enacted = Vec::default(); + let mut retracted = Vec::default(); if pending_block.leaf_state.is_best() { let meta = self.blockchain.meta.read(); @@ -637,85 +741,52 @@ impl client::backend::Backend for Backend whe BlockId::Hash(parent_hash), )?; - // uncanonicalize - for retracted in tree_route.retracted() { - if retracted.hash == meta.finalized_hash { + // uncanonicalize: check safety violations and ensure the numbers no longer + // point to these block hashes in the key mapping. + for r in tree_route.retracted() { + retracted.push(r.hash.clone()); + if r.hash == meta.finalized_hash { warn!("Potential safety failure: reverting finalized block {:?}", - (&retracted.number, &retracted.hash)); + (&r.number, &r.hash)); return Err(::client::error::ErrorKind::NotInFinalizedChain.into()); } - let prev_lookup_key = ::utils::number_to_lookup_key(retracted.number); - let new_lookup_key = ::utils::number_and_hash_to_lookup_key(retracted.number, retracted.hash); - - // change mapping from `number -> header` - // to `number + hash -> header` - let retracted_header = if let Some(header) = ::client::blockchain::HeaderBackend::::header(&self.blockchain, BlockId::Number(retracted.number))? { - header - } else { - return Err(client::error::ErrorKind::UnknownBlock(format!("retracted {:?}", retracted)).into()); - }; - transaction.delete(columns::HEADER, &prev_lookup_key); - transaction.put(columns::HEADER, &new_lookup_key, &retracted_header.encode()); - - // if body is stored - // change mapping from `number -> body` - // to `number + hash -> body` - if let Some(retracted_body) = ::client::blockchain::Backend::::body(&self.blockchain, BlockId::Number(retracted.number))? { - transaction.delete(columns::BODY, &prev_lookup_key); - transaction.put(columns::BODY, &new_lookup_key, &retracted_body.encode()); - } - - // if justification is stored - // change mapping from `number -> justification` - // to `number + hash -> justification` - if let Some(retracted_justification) = ::client::blockchain::Backend::::justification(&self.blockchain, BlockId::Number(retracted.number))? { - transaction.delete(columns::JUSTIFICATION, &prev_lookup_key); - transaction.put(columns::JUSTIFICATION, &new_lookup_key, &retracted_justification.encode()); - } - - transaction.put(columns::HASH_LOOKUP, retracted.hash.as_ref(), &new_lookup_key); + ::utils::remove_number_to_key_mapping( + &mut transaction, + columns::KEY_LOOKUP, + r.number + ); } - // canonicalize - for enacted in tree_route.enacted() { - let prev_lookup_key = ::utils::number_and_hash_to_lookup_key(enacted.number, enacted.hash); - let new_lookup_key = ::utils::number_to_lookup_key(enacted.number); - - // change mapping from `number + hash -> header` - // to `number -> header` - let enacted_header = if let Some(header) = ::client::blockchain::HeaderBackend::::header(&self.blockchain, BlockId::Number(enacted.number))? { - header - } else { - return Err(client::error::ErrorKind::UnknownBlock(format!("enacted {:?}", enacted)).into()); - }; - transaction.delete(columns::HEADER, &prev_lookup_key); - transaction.put(columns::HEADER, &new_lookup_key, &enacted_header.encode()); - - // if body is stored - // change mapping from `number + hash -> body` - // to `number -> body` - if let Some(enacted_body) = ::client::blockchain::Backend::::body(&self.blockchain, BlockId::Number(enacted.number))? { - transaction.delete(columns::BODY, &prev_lookup_key); - transaction.put(columns::BODY, &new_lookup_key, &enacted_body.encode()); - } - - // if justification is stored - // change mapping from `number -> justification` - // to `number + hash -> justification` - if let Some(enacted_justification) = ::client::blockchain::Backend::::justification(&self.blockchain, BlockId::Number(enacted.number))? { - transaction.delete(columns::JUSTIFICATION, &prev_lookup_key); - transaction.put(columns::JUSTIFICATION, &new_lookup_key, &enacted_justification.encode()); - } - - transaction.put(columns::HASH_LOOKUP, enacted.hash.as_ref(), &new_lookup_key); + // canonicalize: set the number lookup to map to this block's hash. + for e in tree_route.enacted() { + enacted.push(e.hash.clone()); + ::utils::insert_number_to_key_mapping( + &mut transaction, + columns::KEY_LOOKUP, + e.number, + e.hash + ); } } transaction.put(columns::META, meta_keys::BEST_BLOCK, &lookup_key); + ::utils::insert_number_to_key_mapping( + &mut transaction, + columns::KEY_LOOKUP, + number, + hash, + ); } + ::utils::insert_hash_to_key_mapping( + &mut transaction, + columns::KEY_LOOKUP, + number, + hash, + ); + transaction.put(columns::HEADER, &lookup_key, &pending_block.header.encode()); if let Some(body) = pending_block.body { transaction.put(columns::BODY, &lookup_key, &body.encode()); @@ -724,15 +795,13 @@ impl client::backend::Backend for Backend whe transaction.put(columns::JUSTIFICATION, &lookup_key, &justification.encode()); } - transaction.put(columns::HASH_LOOKUP, hash.as_ref(), &lookup_key); - - if number == Zero::zero() { + if number.is_zero() { transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key); transaction.put(columns::META, meta_keys::GENESIS_HASH, hash.as_ref()); } let mut changeset: state_db::ChangeSet = state_db::ChangeSet::default(); - for (key, (val, rc)) in operation.updates.drain() { + for (key, (val, rc)) in operation.db_updates.drain() { if rc > 0 { changeset.inserted.push((key, val.to_vec())); } else if rc < 0 { @@ -758,8 +827,8 @@ impl client::backend::Backend for Backend whe self.force_delayed_canonicalize(&mut transaction, hash, *pending_block.header.number())? } - debug!(target: "db", "DB Commit {:?} ({}), best = {}", hash, number, - pending_block.leaf_state.is_best()); + let is_best = pending_block.leaf_state.is_best(); + debug!(target: "db", "DB Commit {:?} ({}), best = {}", hash, number, is_best); { let mut leaves = self.blockchain.leaves.write(); @@ -783,11 +852,23 @@ impl client::backend::Backend for Backend whe pending_block.leaf_state.is_best(), finalized, ); + + // sync canonical state cache + operation.old_state.sync_cache( + &enacted, + &retracted, + operation.storage_updates, + Some(hash), + Some(number), + || is_best + ); } Ok(()) } - fn finalize_block(&self, block: BlockId) -> Result<(), client::error::Error> { + fn finalize_block(&self, block: BlockId, justification: Option) + -> Result<(), client::error::Error> + { use runtime_primitives::traits::Header; if let Some(header) = ::client::blockchain::HeaderBackend::header(&self.blockchain, block)? { @@ -795,6 +876,14 @@ impl client::backend::Backend for Backend whe // TODO: ensure best chain contains this block. let hash = header.hash(); self.note_finalized(&mut transaction, &header, hash.clone())?; + if let Some(justification) = justification { + let number = header.number().clone(); + transaction.put( + columns::JUSTIFICATION, + &::utils::number_and_hash_to_lookup_key(number, hash.clone()), + &justification.encode(), + ); + } self.storage.db.write(transaction).map_err(db_err)?; self.blockchain.update_meta(hash, header.number().clone(), false, true); Ok(()) @@ -809,7 +898,12 @@ impl client::backend::Backend for Backend whe fn revert(&self, n: NumberFor) -> Result, client::error::Error> { use client::blockchain::HeaderBackend; + let mut best = self.blockchain.info()?.best_number; + let finalized = self.blockchain.info()?.finalized_number; + let revertible = best - finalized; + let n = if revertible < n { revertible } else { n }; + for c in 0 .. n.as_() { if best == As::sa(0) { return Ok(As::sa(c)) @@ -818,18 +912,20 @@ impl client::backend::Backend for Backend whe match self.storage.state_db.revert_one() { Some(commit) => { apply_state_commit(&mut transaction, commit); - let _removed = best.clone(); - best -= As::sa(1); - let header = self.blockchain.header(BlockId::Number(best))?.ok_or_else( + let removed = self.blockchain.header(BlockId::Number(best))?.ok_or_else( || client::error::ErrorKind::UnknownBlock( - format!("Error reverting to {}. Block header not found.", best)))?; + format!("Error reverting to {}. Block hash not found.", best)))?; - let lookup_key = ::utils::number_to_lookup_key(header.number().clone()); - transaction.put(columns::META, meta_keys::BEST_BLOCK, &lookup_key); - transaction.delete(columns::HASH_LOOKUP, header.hash().as_ref()); + best -= As::sa(1); // prev block + let hash = self.blockchain.hash(best)?.ok_or_else( + || client::error::ErrorKind::UnknownBlock( + format!("Error reverting to {}. Block hash not found.", best)))?; + let key = ::utils::number_and_hash_to_lookup_key(best.clone(), hash.clone()); + transaction.put(columns::META, meta_keys::BEST_BLOCK, &key); + transaction.delete(columns::KEY_LOOKUP, removed.hash().as_ref()); self.storage.db.write(transaction).map_err(db_err)?; - self.blockchain.update_meta(header.hash().clone(), best.clone(), true, false); - self.blockchain.leaves.write().revert(header.hash().clone(), header.number().clone(), header.parent_hash().clone()); + self.blockchain.update_meta(hash, best, true, false); + self.blockchain.leaves.write().revert(removed.hash().clone(), removed.number().clone(), removed.parent_hash().clone()); } None => return Ok(As::sa(c)) } @@ -849,7 +945,8 @@ impl client::backend::Backend for Backend whe BlockId::Hash(h) if h == Default::default() => { let genesis_storage = DbGenesisStorage::new(); let root = genesis_storage.0.clone(); - return Ok(DbState::new(Arc::new(genesis_storage), root)); + let state = DbState::new(Arc::new(genesis_storage), root); + return Ok(CachingState::new(state, self.shared_cache.clone(), None)); }, _ => {} } @@ -857,30 +954,21 @@ impl client::backend::Backend for Backend whe match self.blockchain.header(block) { Ok(Some(ref hdr)) if !self.storage.state_db.is_pruned(hdr.number().as_()) => { let root = H256::from_slice(hdr.state_root().as_ref()); - Ok(DbState::new(self.storage.clone(), root)) + let state = DbState::new(self.storage.clone(), root); + Ok(CachingState::new(state, self.shared_cache.clone(), Some(hdr.hash()))) }, Err(e) => Err(e), _ => Err(client::error::ErrorKind::UnknownBlock(format!("{:?}", block)).into()), } } - fn insert_aux<'a, 'b: 'a, 'c: 'a, I: IntoIterator, D: IntoIterator> - (&self, insert: I, delete: D) -> Result<(), client::error::Error> - { - let mut transaction = DBTransaction::new(); - for (k, v) in insert { - transaction.put(columns::AUX, k, v); + fn destroy_state(&self, mut state: Self::State) -> Result<(), client::error::Error> { + if let Some(hash) = state.parent_hash.clone() { + let is_best = || self.blockchain.meta.read().best_hash == hash; + state.sync_cache(&[], &[], vec![], None, None, is_best); } - for k in delete { - transaction.delete(columns::AUX, k); - } - self.storage.db.write(transaction).map_err(db_err)?; Ok(()) } - - fn get_aux(&self, key: &[u8]) -> Result>, client::error::Error> { - Ok(self.storage.db.get(columns::AUX, key).map(|r| r.map(|v| v.to_vec())).map_err(db_err)?) - } } impl client::backend::LocalBackend for Backend @@ -1061,7 +1149,7 @@ mod tests { ]; let (root, overlay) = op.old_state.storage_root(storage.iter().cloned()); - op.update_storage(overlay).unwrap(); + op.update_db_storage(overlay).unwrap(); header.state_root = root.into(); op.set_block_data( @@ -1107,7 +1195,7 @@ mod tests { op.reset_storage(storage.iter().cloned().collect(), Default::default()).unwrap(); - key = op.updates.insert(b"hello"); + key = op.db_updates.insert(b"hello"); op.set_block_data( header, Some(vec![]), @@ -1140,8 +1228,8 @@ mod tests { ).0.into(); let hash = header.hash(); - op.updates.insert(b"hello"); - op.updates.remove(&key); + op.db_updates.insert(b"hello"); + op.db_updates.remove(&key); op.set_block_data( header, Some(vec![]), @@ -1173,7 +1261,7 @@ mod tests { .map(|(x, y)| (x, Some(y))) ).0.into(); - op.updates.remove(&key); + op.db_updates.remove(&key); op.set_block_data( header, Some(vec![]), @@ -1186,18 +1274,21 @@ mod tests { assert!(backend.storage.db.get(::columns::STATE, key.as_bytes()).unwrap().is_none()); } - backend.finalize_block(BlockId::Number(1)).unwrap(); - backend.finalize_block(BlockId::Number(2)).unwrap(); + backend.finalize_block(BlockId::Number(1), None).unwrap(); + backend.finalize_block(BlockId::Number(2), None).unwrap(); assert!(backend.storage.db.get(::columns::STATE, key.as_bytes()).unwrap().is_none()); } #[test] fn changes_trie_storage_works() { let backend = Backend::::new_test(1000, 100); + backend.changes_tries_storage.meta.write().finalized_number = 1000; + let check_changes = |backend: &Backend, block: u64, changes: Vec<(Vec, Vec)>| { let (changes_root, mut changes_trie_update) = prepare_changes(changes); - assert_eq!(backend.changes_tries_storage.root(block), Ok(Some(changes_root))); + let anchor = state_machine::ChangesTrieAnchorBlockId { hash: Default::default(), number: block }; + assert_eq!(backend.changes_tries_storage.root(&anchor, block), Ok(Some(changes_root))); for (key, (val, _)) in changes_trie_update.drain() { assert_eq!(backend.changes_trie_storage().unwrap().get(&key), Ok(Some(val))); @@ -1222,8 +1313,65 @@ mod tests { } #[test] - fn changes_tries_are_pruned_on_finalization() { + fn changes_trie_storage_works_with_forks() { + let backend = Backend::::new_test(1000, 100); + + let changes0 = vec![(b"k0".to_vec(), b"v0".to_vec())]; + let changes1 = vec![(b"k1".to_vec(), b"v1".to_vec())]; + let changes2 = vec![(b"k2".to_vec(), b"v2".to_vec())]; + let block0 = insert_header(&backend, 0, Default::default(), changes0.clone(), Default::default()); + let block1 = insert_header(&backend, 1, block0, changes1.clone(), Default::default()); + let block2 = insert_header(&backend, 2, block1, changes2.clone(), Default::default()); + + let changes2_1_0 = vec![(b"k3".to_vec(), b"v3".to_vec())]; + let changes2_1_1 = vec![(b"k4".to_vec(), b"v4".to_vec())]; + let block2_1_0 = insert_header(&backend, 3, block2, changes2_1_0.clone(), Default::default()); + let block2_1_1 = insert_header(&backend, 4, block2_1_0, changes2_1_1.clone(), Default::default()); + + let changes2_2_0 = vec![(b"k5".to_vec(), b"v5".to_vec())]; + let changes2_2_1 = vec![(b"k6".to_vec(), b"v6".to_vec())]; + let block2_2_0 = insert_header(&backend, 3, block2, changes2_2_0.clone(), Default::default()); + let block2_2_1 = insert_header(&backend, 4, block2_2_0, changes2_2_1.clone(), Default::default()); + + // finalize block1 + backend.changes_tries_storage.meta.write().finalized_number = 1; + + // branch1: when asking for finalized block hash + let (changes1_root, _) = prepare_changes(changes1); + let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block2_1_1, number: 4 }; + assert_eq!(backend.changes_tries_storage.root(&anchor, 1), Ok(Some(changes1_root))); + + // branch2: when asking for finalized block hash + let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block2_2_1, number: 4 }; + assert_eq!(backend.changes_tries_storage.root(&anchor, 1), Ok(Some(changes1_root))); + + // branch1: when asking for non-finalized block hash (search by traversal) + let (changes2_1_0_root, _) = prepare_changes(changes2_1_0); + let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block2_1_1, number: 4 }; + assert_eq!(backend.changes_tries_storage.root(&anchor, 3), Ok(Some(changes2_1_0_root))); + + // branch2: when asking for non-finalized block hash (search using canonicalized hint) + let (changes2_2_0_root, _) = prepare_changes(changes2_2_0); + let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block2_2_1, number: 4 }; + assert_eq!(backend.changes_tries_storage.root(&anchor, 3), Ok(Some(changes2_2_0_root))); + + // finalize first block of branch2 (block2_2_0) + backend.changes_tries_storage.meta.write().finalized_number = 3; + + // branch2: when asking for finalized block of this branch + assert_eq!(backend.changes_tries_storage.root(&anchor, 3), Ok(Some(changes2_2_0_root))); + + // branch1: when asking for finalized block of other branch + // => result is incorrect (returned for the block of branch1), but this is expected, + // because the other fork is abandoned (forked before finalized header) + let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block2_1_1, number: 4 }; + assert_eq!(backend.changes_tries_storage.root(&anchor, 3), Ok(Some(changes2_2_0_root))); + } + + #[test] + fn changes_tries_with_digest_are_pruned_on_finalization() { let mut backend = Backend::::new_test(1000, 100); + backend.changes_tries_storage.meta.write().finalized_number = 1000; backend.changes_tries_storage.min_blocks_to_keep = Some(8); let config = ChangesTrieConfiguration { digest_interval: 2, @@ -1246,26 +1394,27 @@ mod tests { let _ = insert_header(&backend, 12, block11, vec![(b"key_at_12".to_vec(), b"val_at_12".to_vec())], Default::default()); // check that roots of all tries are in the columns::CHANGES_TRIE + let anchor = state_machine::ChangesTrieAnchorBlockId { hash: Default::default(), number: 100 }; fn read_changes_trie_root(backend: &Backend, num: u64) -> H256 { backend.blockchain().header(BlockId::Number(num)).unwrap().unwrap().digest().logs().iter() .find(|i| i.as_changes_trie_root().is_some()).unwrap().as_changes_trie_root().unwrap().clone() } - let root1 = read_changes_trie_root(&backend, 1); assert_eq!(backend.changes_tries_storage.root(1).unwrap(), Some(root1)); - let root2 = read_changes_trie_root(&backend, 2); assert_eq!(backend.changes_tries_storage.root(2).unwrap(), Some(root2)); - let root3 = read_changes_trie_root(&backend, 3); assert_eq!(backend.changes_tries_storage.root(3).unwrap(), Some(root3)); - let root4 = read_changes_trie_root(&backend, 4); assert_eq!(backend.changes_tries_storage.root(4).unwrap(), Some(root4)); - let root5 = read_changes_trie_root(&backend, 5); assert_eq!(backend.changes_tries_storage.root(5).unwrap(), Some(root5)); - let root6 = read_changes_trie_root(&backend, 6); assert_eq!(backend.changes_tries_storage.root(6).unwrap(), Some(root6)); - let root7 = read_changes_trie_root(&backend, 7); assert_eq!(backend.changes_tries_storage.root(7).unwrap(), Some(root7)); - let root8 = read_changes_trie_root(&backend, 8); assert_eq!(backend.changes_tries_storage.root(8).unwrap(), Some(root8)); - let root9 = read_changes_trie_root(&backend, 9); assert_eq!(backend.changes_tries_storage.root(9).unwrap(), Some(root9)); - let root10 = read_changes_trie_root(&backend, 10); assert_eq!(backend.changes_tries_storage.root(10).unwrap(), Some(root10)); - let root11 = read_changes_trie_root(&backend, 11); assert_eq!(backend.changes_tries_storage.root(11).unwrap(), Some(root11)); - let root12 = read_changes_trie_root(&backend, 12); assert_eq!(backend.changes_tries_storage.root(12).unwrap(), Some(root12)); + let root1 = read_changes_trie_root(&backend, 1); assert_eq!(backend.changes_tries_storage.root(&anchor, 1).unwrap(), Some(root1)); + let root2 = read_changes_trie_root(&backend, 2); assert_eq!(backend.changes_tries_storage.root(&anchor, 2).unwrap(), Some(root2)); + let root3 = read_changes_trie_root(&backend, 3); assert_eq!(backend.changes_tries_storage.root(&anchor, 3).unwrap(), Some(root3)); + let root4 = read_changes_trie_root(&backend, 4); assert_eq!(backend.changes_tries_storage.root(&anchor, 4).unwrap(), Some(root4)); + let root5 = read_changes_trie_root(&backend, 5); assert_eq!(backend.changes_tries_storage.root(&anchor, 5).unwrap(), Some(root5)); + let root6 = read_changes_trie_root(&backend, 6); assert_eq!(backend.changes_tries_storage.root(&anchor, 6).unwrap(), Some(root6)); + let root7 = read_changes_trie_root(&backend, 7); assert_eq!(backend.changes_tries_storage.root(&anchor, 7).unwrap(), Some(root7)); + let root8 = read_changes_trie_root(&backend, 8); assert_eq!(backend.changes_tries_storage.root(&anchor, 8).unwrap(), Some(root8)); + let root9 = read_changes_trie_root(&backend, 9); assert_eq!(backend.changes_tries_storage.root(&anchor, 9).unwrap(), Some(root9)); + let root10 = read_changes_trie_root(&backend, 10); assert_eq!(backend.changes_tries_storage.root(&anchor, 10).unwrap(), Some(root10)); + let root11 = read_changes_trie_root(&backend, 11); assert_eq!(backend.changes_tries_storage.root(&anchor, 11).unwrap(), Some(root11)); + let root12 = read_changes_trie_root(&backend, 12); assert_eq!(backend.changes_tries_storage.root(&anchor, 12).unwrap(), Some(root12)); // now simulate finalization of block#12, causing prune of tries at #1..#4 let mut tx = DBTransaction::new(); - backend.changes_tries_storage.prune(Some(config.clone()), &mut tx, 12); + backend.changes_tries_storage.prune(Some(config.clone()), &mut tx, Default::default(), 12); backend.storage.db.write(tx).unwrap(); assert!(backend.changes_tries_storage.get(&root1).unwrap().is_none()); assert!(backend.changes_tries_storage.get(&root2).unwrap().is_none()); @@ -1278,7 +1427,7 @@ mod tests { // now simulate finalization of block#16, causing prune of tries at #5..#8 let mut tx = DBTransaction::new(); - backend.changes_tries_storage.prune(Some(config.clone()), &mut tx, 16); + backend.changes_tries_storage.prune(Some(config.clone()), &mut tx, Default::default(), 16); backend.storage.db.write(tx).unwrap(); assert!(backend.changes_tries_storage.get(&root5).unwrap().is_none()); assert!(backend.changes_tries_storage.get(&root6).unwrap().is_none()); @@ -1289,7 +1438,7 @@ mod tests { // => no changes tries are pruned, because we never prune in archive mode backend.changes_tries_storage.min_blocks_to_keep = None; let mut tx = DBTransaction::new(); - backend.changes_tries_storage.prune(Some(config), &mut tx, 20); + backend.changes_tries_storage.prune(Some(config), &mut tx, Default::default(), 20); backend.storage.db.write(tx).unwrap(); assert!(backend.changes_tries_storage.get(&root9).unwrap().is_some()); assert!(backend.changes_tries_storage.get(&root10).unwrap().is_some()); @@ -1297,6 +1446,53 @@ mod tests { assert!(backend.changes_tries_storage.get(&root12).unwrap().is_some()); } + #[test] + fn changes_tries_without_digest_are_pruned_on_finalization() { + let mut backend = Backend::::new_test(1000, 100); + backend.changes_tries_storage.min_blocks_to_keep = Some(4); + let config = ChangesTrieConfiguration { + digest_interval: 0, + digest_levels: 0, + }; + + // insert some blocks + let block0 = insert_header(&backend, 0, Default::default(), vec![(b"key_at_0".to_vec(), b"val_at_0".to_vec())], Default::default()); + let block1 = insert_header(&backend, 1, block0, vec![(b"key_at_1".to_vec(), b"val_at_1".to_vec())], Default::default()); + let block2 = insert_header(&backend, 2, block1, vec![(b"key_at_2".to_vec(), b"val_at_2".to_vec())], Default::default()); + let block3 = insert_header(&backend, 3, block2, vec![(b"key_at_3".to_vec(), b"val_at_3".to_vec())], Default::default()); + let block4 = insert_header(&backend, 4, block3, vec![(b"key_at_4".to_vec(), b"val_at_4".to_vec())], Default::default()); + let block5 = insert_header(&backend, 5, block4, vec![(b"key_at_5".to_vec(), b"val_at_5".to_vec())], Default::default()); + let block6 = insert_header(&backend, 6, block5, vec![(b"key_at_6".to_vec(), b"val_at_6".to_vec())], Default::default()); + + // check that roots of all tries are in the columns::CHANGES_TRIE + let anchor = state_machine::ChangesTrieAnchorBlockId { hash: block6, number: 6 }; + fn read_changes_trie_root(backend: &Backend, num: u64) -> H256 { + backend.blockchain().header(BlockId::Number(num)).unwrap().unwrap().digest().logs().iter() + .find(|i| i.as_changes_trie_root().is_some()).unwrap().as_changes_trie_root().unwrap().clone() + } + + let root1 = read_changes_trie_root(&backend, 1); assert_eq!(backend.changes_tries_storage.root(&anchor, 1).unwrap(), Some(root1)); + let root2 = read_changes_trie_root(&backend, 2); assert_eq!(backend.changes_tries_storage.root(&anchor, 2).unwrap(), Some(root2)); + let root3 = read_changes_trie_root(&backend, 3); assert_eq!(backend.changes_tries_storage.root(&anchor, 3).unwrap(), Some(root3)); + let root4 = read_changes_trie_root(&backend, 4); assert_eq!(backend.changes_tries_storage.root(&anchor, 4).unwrap(), Some(root4)); + let root5 = read_changes_trie_root(&backend, 5); assert_eq!(backend.changes_tries_storage.root(&anchor, 5).unwrap(), Some(root5)); + let root6 = read_changes_trie_root(&backend, 6); assert_eq!(backend.changes_tries_storage.root(&anchor, 6).unwrap(), Some(root6)); + + // now simulate finalization of block#5, causing prune of trie at #1 + let mut tx = DBTransaction::new(); + backend.changes_tries_storage.prune(Some(config.clone()), &mut tx, block5, 5); + backend.storage.db.write(tx).unwrap(); + assert!(backend.changes_tries_storage.get(&root1).unwrap().is_none()); + assert!(backend.changes_tries_storage.get(&root2).unwrap().is_some()); + + // now simulate finalization of block#6, causing prune of tries at #2 + let mut tx = DBTransaction::new(); + backend.changes_tries_storage.prune(Some(config.clone()), &mut tx, block6, 6); + backend.storage.db.write(tx).unwrap(); + assert!(backend.changes_tries_storage.get(&root2).unwrap().is_none()); + assert!(backend.changes_tries_storage.get(&root3).unwrap().is_some()); + } + #[test] fn tree_route_works() { let backend = Backend::::new_test(1000, 100); @@ -1381,4 +1577,39 @@ mod tests { backend.insert_aux(&[], &[&b"test"[..]]).unwrap(); assert!(backend.get_aux(b"test").unwrap().is_none()); } + + #[test] + fn test_finalize_block_with_justification() { + use client::blockchain::{Backend as BlockChainBackend}; + + let backend = Backend::::new_test(0, 0); + + { + let mut op = backend.begin_operation(BlockId::Hash(Default::default())).unwrap(); + let header = Header { + number: 0, + parent_hash: Default::default(), + state_root: Default::default(), + digest: Default::default(), + extrinsics_root: Default::default(), + }; + + op.set_block_data( + header, + Some(vec![]), + None, + NewBlockState::Best, + ).unwrap(); + + backend.commit_operation(op).unwrap(); + } + + let justification = Some(vec![1, 2, 3]); + backend.finalize_block(BlockId::Number(0), justification.clone()).unwrap(); + + assert_eq!( + backend.blockchain().justification(BlockId::Number(0)).unwrap(), + justification, + ); + } } diff --git a/core/client/db/src/light.rs b/core/client/db/src/light.rs index f336df4d28effc231b3cf37504c71a13f8b7a250..cbed1348a93a2efa4f6f8d15c4bda4be0dd3ddd3 100644 --- a/core/client/db/src/light.rs +++ b/core/client/db/src/light.rs @@ -21,47 +21,45 @@ use parking_lot::RwLock; use kvdb::{KeyValueDB, DBTransaction}; -use client::backend::NewBlockState; +use client::backend::{AuxStore, NewBlockState}; use client::blockchain::{BlockStatus, Cache as BlockchainCache, HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo}; use client::{cht, LeafSet}; use client::error::{ErrorKind as ClientErrorKind, Result as ClientResult}; use client::light::blockchain::Storage as LightBlockchainStorage; use codec::{Decode, Encode}; -use primitives::{AuthorityId, Blake2Hasher}; +use primitives::Blake2Hasher; use runtime_primitives::generic::BlockId; use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, - Zero, One, As, NumberFor}; + Zero, One, As, NumberFor, Digest, DigestItem, AuthorityIdFor}; use cache::{DbCacheSync, DbCache, ComplexBlockId}; -use utils::{meta_keys, Meta, db_err, number_to_lookup_key, open_database, +use utils::{meta_keys, Meta, db_err, open_database, read_db, block_id_to_lookup_key, read_meta}; use DatabaseSettings; pub(crate) mod columns { pub const META: Option = ::utils::COLUMN_META; - pub const HASH_LOOKUP: Option = Some(1); + pub const KEY_LOOKUP: Option = Some(1); pub const HEADER: Option = Some(2); pub const CACHE: Option = Some(3); pub const CHT: Option = Some(4); + pub const AUX: Option = Some(5); } +/// Prefix for headers CHT. +const HEADER_CHT_PREFIX: u8 = 0; +/// Prefix for changes tries roots CHT. +const CHANGES_TRIE_CHT_PREFIX: u8 = 1; + /// Light blockchain storage. Stores most recent headers + CHTs for older headers. /// Locks order: meta, leaves, cache. pub struct LightStorage { db: Arc, - meta: RwLock::Header as HeaderT>::Number, Block::Hash>>, + meta: RwLock, Block::Hash>>, leaves: RwLock>>, cache: DbCacheSync, } -#[derive(Clone, PartialEq, Debug)] -struct BestAuthorities { - /// first block, when this set became actual - valid_from: N, - /// None means that we do not know the set starting from `valid_from` block - authorities: Option>, -} - impl LightStorage where Block: BlockT, @@ -87,7 +85,7 @@ impl LightStorage let leaves = LeafSet::read_from_db(&*db, columns::META, meta_keys::LEAF_PREFIX)?; let cache = DbCache::new( db.clone(), - columns::HASH_LOOKUP, + columns::KEY_LOOKUP, columns::HEADER, columns::CACHE, ComplexBlockId::new(meta.finalized_hash, meta.finalized_number), @@ -109,13 +107,13 @@ impl LightStorage fn update_meta( &self, hash: Block::Hash, - number: <::Header as HeaderT>::Number, + number: NumberFor, is_best: bool, is_finalized: bool, ) { let mut meta = self.meta.write(); - if number == Zero::zero() { + if number.is_zero() { meta.genesis_hash = hash; meta.finalized_hash = hash; } @@ -137,7 +135,7 @@ impl BlockchainHeaderBackend for LightStorage Block: BlockT, { fn header(&self, id: BlockId) -> ClientResult> { - ::utils::read_header(&*self.db, columns::HASH_LOOKUP, columns::HEADER, id) + ::utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id) } fn info(&self) -> ClientResult> { @@ -155,7 +153,7 @@ impl BlockchainHeaderBackend for LightStorage let exists = match id { BlockId::Hash(_) => read_db( &*self.db, - columns::HASH_LOOKUP, + columns::KEY_LOOKUP, columns::HEADER, id )?.is_some(), @@ -167,8 +165,8 @@ impl BlockchainHeaderBackend for LightStorage } } - fn number(&self, hash: Block::Hash) -> ClientResult::Header as HeaderT>::Number>> { - if let Some(lookup_key) = block_id_to_lookup_key::(&*self.db, columns::HASH_LOOKUP, BlockId::Hash(hash))? { + fn number(&self, hash: Block::Hash) -> ClientResult>> { + if let Some(lookup_key) = block_id_to_lookup_key::(&*self.db, columns::KEY_LOOKUP, BlockId::Hash(hash))? { let number = ::utils::lookup_key_to_number(&lookup_key)?; Ok(Some(number)) } else { @@ -176,12 +174,21 @@ impl BlockchainHeaderBackend for LightStorage } } - fn hash(&self, number: <::Header as HeaderT>::Number) -> ClientResult> { + fn hash(&self, number: NumberFor) -> ClientResult> { Ok(self.header(BlockId::Number(number))?.map(|header| header.hash().clone())) } } impl LightStorage { + // Get block changes trie root, if available. + fn changes_trie_root(&self, block: BlockId) -> ClientResult> { + self.header(block) + .map(|header| header.and_then(|header| + header.digest().log(DigestItem::as_changes_trie_root) + .cloned())) + } + + // Note that a block is finalized. Only call with child of last finalized block. fn note_finalized( &self, transaction: &mut DBTransaction, @@ -196,38 +203,101 @@ impl LightStorage { ).into()) } - let lookup_key = ::utils::number_to_lookup_key(header.number().clone()); + let lookup_key = ::utils::number_and_hash_to_lookup_key(header.number().clone(), hash); transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key); - // build new CHT if required + // build new CHT(s) if required if let Some(new_cht_number) = cht::is_build_required(cht::SIZE, *header.number()) { let new_cht_start: NumberFor = cht::start_number(cht::SIZE, new_cht_number); - let new_cht_root = cht::compute_root::( + + let new_header_cht_root = cht::compute_root::( cht::SIZE, new_cht_number, (new_cht_start.as_()..) - .map(|num| self.hash(As::sa(num)).unwrap_or_default()) + .map(|num| self.hash(As::sa(num))) + )?; + transaction.put( + columns::CHT, + &cht_key(HEADER_CHT_PREFIX, new_cht_start), + new_header_cht_root.as_ref() ); - if let Some(new_cht_root) = new_cht_root { - transaction.put(columns::CHT, &number_to_lookup_key(new_cht_start), new_cht_root.as_ref()); - - let mut prune_block = new_cht_start; - let new_cht_end = cht::end_number(cht::SIZE, new_cht_number); - trace!(target: "db", "Replacing blocks [{}..{}] with CHT#{}", new_cht_start, new_cht_end, new_cht_number); + // if the header includes changes trie root, let's build a changes tries roots CHT + if header.digest().log(DigestItem::as_changes_trie_root).is_some() { + let new_changes_trie_cht_root = cht::compute_root::( + cht::SIZE, new_cht_number, (new_cht_start.as_()..) + .map(|num| self.changes_trie_root(BlockId::Number(As::sa(num)))) + )?; + transaction.put( + columns::CHT, + &cht_key(CHANGES_TRIE_CHT_PREFIX, new_cht_start), + new_changes_trie_cht_root.as_ref() + ); + } - while prune_block <= new_cht_end { - if let Some(hash) = self.hash(prune_block)? { - let lookup_key = block_id_to_lookup_key::(&*self.db, columns::HASH_LOOKUP, BlockId::Number(prune_block))? - .expect("retrieved hash for `prune_block` right above. therefore retrieving lookup key must succeed. q.e.d."); - transaction.delete(columns::HASH_LOOKUP, hash.as_ref()); - transaction.delete(columns::HEADER, &lookup_key); - } - prune_block += NumberFor::::one(); + // prune headers that are replaced with CHT + let mut prune_block = new_cht_start; + let new_cht_end = cht::end_number(cht::SIZE, new_cht_number); + trace!(target: "db", "Replacing blocks [{}..{}] with CHT#{}", + new_cht_start, new_cht_end, new_cht_number); + + while prune_block <= new_cht_end { + if let Some(hash) = self.hash(prune_block)? { + let lookup_key = block_id_to_lookup_key::(&*self.db, columns::KEY_LOOKUP, BlockId::Number(prune_block))? + .expect("retrieved hash for `prune_block` right above. therefore retrieving lookup key must succeed. q.e.d."); + ::utils::remove_key_mappings( + transaction, + columns::KEY_LOOKUP, + prune_block, + hash + ); + transaction.delete(columns::HEADER, &lookup_key); } + prune_block += One::one(); } } Ok(()) } + + /// Read CHT root of given type for the block. + fn read_cht_root( + &self, + cht_type: u8, + cht_size: u64, + block: NumberFor + ) -> ClientResult { + let no_cht_for_block = || ClientErrorKind::Backend(format!("CHT for block {} not exists", block)).into(); + + let cht_number = cht::block_to_cht_number(cht_size, block).ok_or_else(no_cht_for_block)?; + let cht_start = cht::start_number(cht_size, cht_number); + self.db.get(columns::CHT, &cht_key(cht_type, cht_start)).map_err(db_err)? + .ok_or_else(no_cht_for_block) + .and_then(|hash| Block::Hash::decode(&mut &*hash).ok_or_else(no_cht_for_block)) + } +} + +impl AuxStore for LightStorage + where Block: BlockT, +{ + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >(&self, insert: I, delete: D) -> ClientResult<()> { + let mut transaction = DBTransaction::new(); + for (k, v) in insert { + transaction.put(columns::AUX, k, v); + } + for k in delete { + transaction.delete(columns::AUX, k); + } + self.db.write(transaction).map_err(db_err) + } + + fn get_aux(&self, key: &[u8]) -> ClientResult>> { + self.db.get(columns::AUX, key).map(|r| r.map(|v| v.to_vec())).map_err(db_err) + } } impl LightBlockchainStorage for LightStorage @@ -236,8 +306,9 @@ impl LightBlockchainStorage for LightStorage fn import_header( &self, header: Block::Header, - authorities: Option>, + authorities: Option>>, leaf_state: NewBlockState, + aux_ops: Vec<(Vec, Option>)>, ) -> ClientResult<()> { let mut transaction = DBTransaction::new(); @@ -245,13 +316,15 @@ impl LightBlockchainStorage for LightStorage let number = *header.number(); let parent_hash = *header.parent_hash(); - // blocks in longest chain are keyed by number - let lookup_key = if leaf_state.is_best() { - ::utils::number_to_lookup_key(number).to_vec() - } else { - // other blocks are keyed by number + hash - ::utils::number_and_hash_to_lookup_key(number, hash) - }; + for (key, maybe_val) in aux_ops { + match maybe_val { + Some(val) => transaction.put_vec(columns::AUX, &key, val), + None => transaction.delete(columns::AUX, &key), + } + } + + // blocks are keyed by number + hash. + let lookup_key = ::utils::number_and_hash_to_lookup_key(number, hash); if leaf_state.is_best() { // handle reorg. @@ -272,46 +345,45 @@ impl LightBlockchainStorage for LightStorage (&retracted.number, &retracted.hash)); } - let prev_lookup_key = ::utils::number_to_lookup_key(retracted.number); - let new_lookup_key = ::utils::number_and_hash_to_lookup_key(retracted.number, retracted.hash); - - // change mapping from `number -> header` - // to `number + hash -> header` - let retracted_header = if let Some(header) = self.header(BlockId::Number(retracted.number))? { - header - } else { - return Err(::client::error::ErrorKind::UnknownBlock(format!("retracted {:?}", retracted)).into()); - }; - transaction.delete(columns::HEADER, &prev_lookup_key); - transaction.put(columns::HEADER, &new_lookup_key, &retracted_header.encode()); - - transaction.put(columns::HASH_LOOKUP, retracted.hash.as_ref(), &new_lookup_key); + ::utils::remove_number_to_key_mapping( + &mut transaction, + columns::KEY_LOOKUP, + retracted.number + ); } for enacted in tree_route.enacted() { - let prev_lookup_key = ::utils::number_and_hash_to_lookup_key(enacted.number, enacted.hash); - let new_lookup_key = ::utils::number_to_lookup_key(enacted.number); - - // change mapping from `number + hash -> header` - // to `number -> header` - let enacted_header = if let Some(header) = self.header(BlockId::Number(enacted.number))? { - header - } else { - return Err(::client::error::ErrorKind::UnknownBlock(format!("enacted {:?}", enacted)).into()); - }; - transaction.delete(columns::HEADER, &prev_lookup_key); - transaction.put(columns::HEADER, &new_lookup_key, &enacted_header.encode()); - - transaction.put(columns::HASH_LOOKUP, enacted.hash.as_ref(), &new_lookup_key); + ::utils::insert_number_to_key_mapping( + &mut transaction, + columns::KEY_LOOKUP, + enacted.number, + enacted.hash + ); } } } transaction.put(columns::META, meta_keys::BEST_BLOCK, &lookup_key); + ::utils::insert_number_to_key_mapping( + &mut transaction, + columns::KEY_LOOKUP, + number, + hash, + ); } + ::utils::insert_hash_to_key_mapping( + &mut transaction, + columns::KEY_LOOKUP, + number, + hash, + ); transaction.put(columns::HEADER, &lookup_key, &header.encode()); - transaction.put(columns::HASH_LOOKUP, hash.as_ref(), &lookup_key); + + if number.is_zero() { + transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key); + transaction.put(columns::META, meta_keys::GENESIS_HASH, hash.as_ref()); + } let finalized = match leaf_state { NewBlockState::Final => true, @@ -329,7 +401,7 @@ impl LightBlockchainStorage for LightStorage let mut cache = self.cache.0.write(); let cache_ops = cache.transaction(&mut transaction) .on_block_insert( - ComplexBlockId::new(*header.parent_hash(), if number == Zero::zero() { Zero::zero() } else { number - One::one() }), + ComplexBlockId::new(*header.parent_hash(), if number.is_zero() { Zero::zero() } else { number - One::one() }), ComplexBlockId::new(hash, number), authorities, finalized, @@ -354,14 +426,12 @@ impl LightBlockchainStorage for LightStorage Ok(()) } - fn cht_root(&self, cht_size: u64, block: <::Header as HeaderT>::Number) -> ClientResult { - let no_cht_for_block = || ClientErrorKind::Backend(format!("CHT for block {} not exists", block)).into(); + fn header_cht_root(&self, cht_size: u64, block: NumberFor) -> ClientResult { + self.read_cht_root(HEADER_CHT_PREFIX, cht_size, block) + } - let cht_number = cht::block_to_cht_number(cht_size, block).ok_or_else(no_cht_for_block)?; - let cht_start = cht::start_number(cht_size, cht_number); - self.db.get(columns::CHT, &number_to_lookup_key(cht_start)).map_err(db_err)? - .ok_or_else(no_cht_for_block) - .and_then(|hash| Block::Hash::decode(&mut &*hash).ok_or_else(no_cht_for_block)) + fn changes_trie_cht_root(&self, cht_size: u64, block: NumberFor) -> ClientResult { + self.read_cht_root(CHANGES_TRIE_CHT_PREFIX, cht_size, block) } fn finalize_header(&self, id: BlockId) -> ClientResult<()> { @@ -375,7 +445,7 @@ impl LightBlockchainStorage for LightStorage let mut cache = self.cache.0.write(); let cache_ops = cache.transaction(&mut transaction) .on_block_finalize( - ComplexBlockId::new(*header.parent_hash(), if number == Zero::zero() { Zero::zero() } else { number - One::one() }), + ComplexBlockId::new(*header.parent_hash(), if number.is_zero() { Zero::zero() } else { number - One::one() }), ComplexBlockId::new(hash, number) )? .into_ops(); @@ -400,77 +470,81 @@ impl LightBlockchainStorage for LightStorage } } +/// Build the key for inserting header-CHT at given block. +fn cht_key>(cht_type: u8, block: N) -> [u8; 5] { + let mut key = [cht_type; 5]; + key[1..].copy_from_slice(&::utils::number_index_key(block)); + key +} + #[cfg(test)] pub(crate) mod tests { use client::cht; + use runtime_primitives::generic::DigestItem; use runtime_primitives::testing::{H256 as Hash, Header, Block as RawBlock, ExtrinsicWrapper}; use super::*; type Block = RawBlock>; - fn prepare_header(parent: &Hash, number: u64, extrinsics_root: Hash) -> Header { + pub fn default_header(parent: &Hash, number: u64) -> Header { Header { number: number.into(), parent_hash: *parent, state_root: Hash::random(), digest: Default::default(), - extrinsics_root, + extrinsics_root: Default::default(), } } - pub fn insert_block_with_extrinsics_root( - db: &LightStorage, - parent: &Hash, - number: u64, - authorities: Option>, - extrinsics_root: Hash, - ) -> Hash { - let header = prepare_header(parent, number, extrinsics_root); - let hash = header.hash(); - db.import_header(header, authorities, NewBlockState::Best).unwrap(); - hash + fn header_with_changes_trie(parent: &Hash, number: u64) -> Header { + let mut header = default_header(parent, number); + header.digest.logs.push(DigestItem::ChangesTrieRoot([(number % 256) as u8; 32].into())); + header } - pub fn insert_block( + fn header_with_extrinsics_root(parent: &Hash, number: u64, extrinsics_root: Hash) -> Header { + let mut header = default_header(parent, number); + header.extrinsics_root = extrinsics_root; + header + } + + pub fn insert_block Header>( db: &LightStorage, - parent: &Hash, - number: u64, - authorities: Option> + authorities: Option>>, + header: F, ) -> Hash { - let header = prepare_header(parent, number, Default::default()); + let header = header(); let hash = header.hash(); - db.import_header(header, authorities, NewBlockState::Best).unwrap(); + db.import_header(header, authorities, NewBlockState::Best, Vec::new()).unwrap(); hash } - fn insert_final_block( + fn insert_final_block Header>( db: &LightStorage, - parent: &Hash, - number: u64, - authorities: Option> + authorities: Option>>, + header: F, ) -> Hash { - let header = prepare_header(parent, number, Default::default()); + let header = header(); let hash = header.hash(); - db.import_header(header, authorities, NewBlockState::Final).unwrap(); + db.import_header(header, authorities, NewBlockState::Final, Vec::new()).unwrap(); hash } - fn insert_non_best_block( + fn insert_non_best_block Header>( db: &LightStorage, - parent: &Hash, - number: u64, - authorities: Option> + authorities: Option>>, + header: F, ) -> Hash { - let header = prepare_header(parent, number, Default::default()); + let header = header(); let hash = header.hash(); - db.import_header(header, authorities, NewBlockState::Normal).unwrap(); + db.import_header(header, authorities, NewBlockState::Normal, Vec::new()).unwrap(); hash } #[test] fn returns_known_header() { let db = LightStorage::new_test(); - let known_hash = insert_block(&db, &Default::default(), 0, None); + let known_hash = insert_block(&db, None, || default_header(&Default::default(), 0)); let header_by_hash = db.header(BlockId::Hash(known_hash)).unwrap().unwrap(); let header_by_number = db.header(BlockId::Number(0)).unwrap().unwrap(); assert_eq!(header_by_hash, header_by_number); @@ -486,12 +560,12 @@ pub(crate) mod tests { #[test] fn returns_info() { let db = LightStorage::new_test(); - let genesis_hash = insert_block(&db, &Default::default(), 0, None); + let genesis_hash = insert_block(&db, None, || default_header(&Default::default(), 0)); let info = db.info().unwrap(); assert_eq!(info.best_hash, genesis_hash); assert_eq!(info.best_number, 0); assert_eq!(info.genesis_hash, genesis_hash); - let best_hash = insert_block(&db, &genesis_hash, 1, None); + let best_hash = insert_block(&db, None, || default_header(&genesis_hash, 1)); let info = db.info().unwrap(); assert_eq!(info.best_hash, best_hash); assert_eq!(info.best_number, 1); @@ -501,7 +575,7 @@ pub(crate) mod tests { #[test] fn returns_block_status() { let db = LightStorage::new_test(); - let genesis_hash = insert_block(&db, &Default::default(), 0, None); + let genesis_hash = insert_block(&db, None, || default_header(&Default::default(), 0)); assert_eq!(db.status(BlockId::Hash(genesis_hash)).unwrap(), BlockStatus::InChain); assert_eq!(db.status(BlockId::Number(0)).unwrap(), BlockStatus::InChain); assert_eq!(db.status(BlockId::Hash(1.into())).unwrap(), BlockStatus::Unknown); @@ -511,7 +585,7 @@ pub(crate) mod tests { #[test] fn returns_block_hash() { let db = LightStorage::new_test(); - let genesis_hash = insert_block(&db, &Default::default(), 0, None); + let genesis_hash = insert_block(&db, None, || default_header(&Default::default(), 0)); assert_eq!(db.hash(0).unwrap(), Some(genesis_hash)); assert_eq!(db.hash(1).unwrap(), None); } @@ -520,64 +594,81 @@ pub(crate) mod tests { fn import_header_works() { let db = LightStorage::new_test(); - let genesis_hash = insert_block(&db, &Default::default(), 0, None); + let genesis_hash = insert_block(&db, None, || default_header(&Default::default(), 0)); assert_eq!(db.db.iter(columns::HEADER).count(), 1); - assert_eq!(db.db.iter(columns::HASH_LOOKUP).count(), 1); + assert_eq!(db.db.iter(columns::KEY_LOOKUP).count(), 2); - let _ = insert_block(&db, &genesis_hash, 1, None); + let _ = insert_block(&db, None, || default_header(&genesis_hash, 1)); assert_eq!(db.db.iter(columns::HEADER).count(), 2); - assert_eq!(db.db.iter(columns::HASH_LOOKUP).count(), 2); + assert_eq!(db.db.iter(columns::KEY_LOOKUP).count(), 4); } #[test] fn finalized_ancient_headers_are_replaced_with_cht() { - let db = LightStorage::new_test(); + fn insert_headers Header>(header_producer: F) -> LightStorage { + let db = LightStorage::new_test(); - // insert genesis block header (never pruned) - let mut prev_hash = insert_final_block(&db, &Default::default(), 0, None); + // insert genesis block header (never pruned) + let mut prev_hash = insert_final_block(&db, None, || header_producer(&Default::default(), 0)); - // insert SIZE blocks && ensure that nothing is pruned - for number in 0..cht::SIZE { - prev_hash = insert_block(&db, &prev_hash, 1 + number, None); - } - assert_eq!(db.db.iter(columns::HEADER).count(), (1 + cht::SIZE) as usize); - assert_eq!(db.db.iter(columns::HASH_LOOKUP).count(), (1 + cht::SIZE) as usize); - assert_eq!(db.db.iter(columns::CHT).count(), 0); + // insert SIZE blocks && ensure that nothing is pruned + for number in 0..cht::SIZE { + prev_hash = insert_block(&db, None, || header_producer(&prev_hash, 1 + number)); + } + assert_eq!(db.db.iter(columns::HEADER).count(), (1 + cht::SIZE) as usize); + assert_eq!(db.db.iter(columns::CHT).count(), 0); - // insert next SIZE blocks && ensure that nothing is pruned - for number in 0..cht::SIZE { - prev_hash = insert_block(&db, &prev_hash, 1 + cht::SIZE + number, None); - } - assert_eq!(db.db.iter(columns::HEADER).count(), (1 + cht::SIZE + cht::SIZE) as usize); - assert_eq!(db.db.iter(columns::HASH_LOOKUP).count(), (1 + cht::SIZE + cht::SIZE) as usize); - assert_eq!(db.db.iter(columns::CHT).count(), 0); - - // insert block #{2 * cht::SIZE + 1} && check that new CHT is created + headers of this CHT are pruned - // nothing is yet finalized, so nothing is pruned. - prev_hash = insert_block(&db, &prev_hash, 1 + cht::SIZE + cht::SIZE, None); - assert_eq!(db.db.iter(columns::HEADER).count(), (2 + cht::SIZE + cht::SIZE) as usize); - assert_eq!(db.db.iter(columns::HASH_LOOKUP).count(), (2 + cht::SIZE + cht::SIZE) as usize); - assert_eq!(db.db.iter(columns::CHT).count(), 0); - - // now finalize the block. - for i in (0..(cht::SIZE + cht::SIZE)).map(|i| i + 1) { - db.finalize_header(BlockId::Number(i)).unwrap(); + // insert next SIZE blocks && ensure that nothing is pruned + for number in 0..cht::SIZE { + prev_hash = insert_block(&db, None, || header_producer(&prev_hash, 1 + cht::SIZE + number)); + } + assert_eq!(db.db.iter(columns::HEADER).count(), (1 + cht::SIZE + cht::SIZE) as usize); + assert_eq!(db.db.iter(columns::CHT).count(), 0); + + // insert block #{2 * cht::SIZE + 1} && check that new CHT is created + headers of this CHT are pruned + // nothing is yet finalized, so nothing is pruned. + prev_hash = insert_block(&db, None, || header_producer(&prev_hash, 1 + cht::SIZE + cht::SIZE)); + assert_eq!(db.db.iter(columns::HEADER).count(), (2 + cht::SIZE + cht::SIZE) as usize); + assert_eq!(db.db.iter(columns::CHT).count(), 0); + + // now finalize the block. + for i in (0..(cht::SIZE + cht::SIZE)).map(|i| i + 1) { + db.finalize_header(BlockId::Number(i)).unwrap(); + } + db.finalize_header(BlockId::Hash(prev_hash)).unwrap(); + db } - db.finalize_header(BlockId::Hash(prev_hash)).unwrap(); + + // when headers are created without changes tries roots + let db = insert_headers(default_header); assert_eq!(db.db.iter(columns::HEADER).count(), (1 + cht::SIZE + 1) as usize); - assert_eq!(db.db.iter(columns::HASH_LOOKUP).count(), (1 + cht::SIZE + 1) as usize); + assert_eq!(db.db.iter(columns::KEY_LOOKUP).count(), (2 * (1 + cht::SIZE + 1)) as usize); assert_eq!(db.db.iter(columns::CHT).count(), 1); - assert!((0..cht::SIZE).all(|i| db.db.get(columns::HEADER, &number_to_lookup_key(1 + i)).unwrap().is_none())); + assert!((0..cht::SIZE).all(|i| db.header(BlockId::Number(1 + i)).unwrap().is_none())); + assert!(db.header_cht_root(cht::SIZE, cht::SIZE / 2).is_ok()); + assert!(db.header_cht_root(cht::SIZE, cht::SIZE + cht::SIZE / 2).is_err()); + assert!(db.changes_trie_cht_root(cht::SIZE, cht::SIZE / 2).is_err()); + assert!(db.changes_trie_cht_root(cht::SIZE, cht::SIZE + cht::SIZE / 2).is_err()); + + // when headers are created with changes tries roots + let db = insert_headers(header_with_changes_trie); + assert_eq!(db.db.iter(columns::HEADER).count(), (1 + cht::SIZE + 1) as usize); + assert_eq!(db.db.iter(columns::CHT).count(), 2); + assert!((0..cht::SIZE).all(|i| db.header(BlockId::Number(1 + i)).unwrap().is_none())); + assert!(db.header_cht_root(cht::SIZE, cht::SIZE / 2).is_ok()); + assert!(db.header_cht_root(cht::SIZE, cht::SIZE + cht::SIZE / 2).is_err()); + assert!(db.changes_trie_cht_root(cht::SIZE, cht::SIZE / 2).is_ok()); + assert!(db.changes_trie_cht_root(cht::SIZE, cht::SIZE + cht::SIZE / 2).is_err()); } #[test] fn get_cht_fails_for_genesis_block() { - assert!(LightStorage::::new_test().cht_root(cht::SIZE, 0).is_err()); + assert!(LightStorage::::new_test().header_cht_root(cht::SIZE, 0).is_err()); } #[test] fn get_cht_fails_for_non_existant_cht() { - assert!(LightStorage::::new_test().cht_root(cht::SIZE, (cht::SIZE / 2) as u64).is_err()); + assert!(LightStorage::::new_test().header_cht_root(cht::SIZE, (cht::SIZE / 2) as u64).is_err()); } #[test] @@ -585,15 +676,21 @@ pub(crate) mod tests { let db = LightStorage::new_test(); // insert 1 + SIZE + SIZE + 1 blocks so that CHT#0 is created - let mut prev_hash = insert_final_block(&db, &Default::default(), 0, None); + let mut prev_hash = insert_final_block(&db, None, || header_with_changes_trie(&Default::default(), 0)); for i in 1..1 + cht::SIZE + cht::SIZE + 1 { - prev_hash = insert_block(&db, &prev_hash, i as u64, None); + prev_hash = insert_block(&db, None, || header_with_changes_trie(&prev_hash, i as u64)); db.finalize_header(BlockId::Hash(prev_hash)).unwrap(); } - let cht_root_1 = db.cht_root(cht::SIZE, cht::start_number(cht::SIZE, 0)).unwrap(); - let cht_root_2 = db.cht_root(cht::SIZE, (cht::start_number(cht::SIZE, 0) + cht::SIZE / 2) as u64).unwrap(); - let cht_root_3 = db.cht_root(cht::SIZE, cht::end_number(cht::SIZE, 0)).unwrap(); + let cht_root_1 = db.header_cht_root(cht::SIZE, cht::start_number(cht::SIZE, 0)).unwrap(); + let cht_root_2 = db.header_cht_root(cht::SIZE, (cht::start_number(cht::SIZE, 0) + cht::SIZE / 2) as u64).unwrap(); + let cht_root_3 = db.header_cht_root(cht::SIZE, cht::end_number(cht::SIZE, 0)).unwrap(); + assert_eq!(cht_root_1, cht_root_2); + assert_eq!(cht_root_2, cht_root_3); + + let cht_root_1 = db.changes_trie_cht_root(cht::SIZE, cht::start_number(cht::SIZE, 0)).unwrap(); + let cht_root_2 = db.changes_trie_cht_root(cht::SIZE, (cht::start_number(cht::SIZE, 0) + cht::SIZE / 2) as u64).unwrap(); + let cht_root_3 = db.changes_trie_cht_root(cht::SIZE, cht::end_number(cht::SIZE, 0)).unwrap(); assert_eq!(cht_root_1, cht_root_2); assert_eq!(cht_root_2, cht_root_3); } @@ -601,16 +698,16 @@ pub(crate) mod tests { #[test] fn tree_route_works() { let db = LightStorage::new_test(); - let block0 = insert_block(&db, &Default::default(), 0, None); + let block0 = insert_block(&db, None, || default_header(&Default::default(), 0)); // fork from genesis: 3 prong. - let a1 = insert_block(&db, &block0, 1, None); - let a2 = insert_block(&db, &a1, 2, None); - let a3 = insert_block(&db, &a2, 3, None); + let a1 = insert_block(&db, None, || default_header(&block0, 1)); + let a2 = insert_block(&db, None, || default_header(&a1, 2)); + let a3 = insert_block(&db, None, || default_header(&a2, 3)); // fork from genesis: 2 prong. - let b1 = insert_block_with_extrinsics_root(&db, &block0, 1, None, Hash::from([1; 32])); - let b2 = insert_block(&db, &b1, 2, None); + let b1 = insert_block(&db, None, || header_with_extrinsics_root(&block0, 1, Hash::from([1; 32]))); + let b2 = insert_block(&db, None, || default_header(&b1, 2)); { let tree_route = ::client::blockchain::tree_route( @@ -665,7 +762,7 @@ pub(crate) mod tests { fn authorites_are_cached() { let db = LightStorage::new_test(); - fn run_checks(db: &LightStorage, max: u64, checks: &[(u64, Option>)]) { + fn run_checks(db: &LightStorage, max: u64, checks: &[(u64, Option>>)]) { for (at, expected) in checks.iter().take_while(|(at, _)| *at <= max) { let actual = db.cache().authorities_at(BlockId::Number(*at)); assert_eq!(*expected, actual); @@ -686,19 +783,19 @@ pub(crate) mod tests { (7, None), // block will work for 'future' block too ]; - let hash0 = insert_final_block(&db, &Default::default(), 0, None); + let hash0 = insert_final_block(&db, None, || default_header(&Default::default(), 0)); run_checks(&db, 0, &checks); - let hash1 = insert_final_block(&db, &hash0, 1, None); + let hash1 = insert_final_block(&db, None, || default_header(&hash0, 1)); run_checks(&db, 1, &checks); - let hash2 = insert_final_block(&db, &hash1, 2, Some(vec![[1u8; 32].into()])); + let hash2 = insert_final_block(&db, Some(vec![[1u8; 32].into()]), || default_header(&hash1, 2)); run_checks(&db, 2, &checks); - let hash3 = insert_final_block(&db, &hash2, 3, Some(vec![[1u8; 32].into()])); + let hash3 = insert_final_block(&db, Some(vec![[1u8; 32].into()]), || default_header(&hash2, 3)); run_checks(&db, 3, &checks); - let hash4 = insert_final_block(&db, &hash3, 4, Some(vec![[1u8; 32].into(), [2u8; 32].into()])); + let hash4 = insert_final_block(&db, Some(vec![[1u8; 32].into(), [2u8; 32].into()]), || default_header(&hash3, 4)); run_checks(&db, 4, &checks); - let hash5 = insert_final_block(&db, &hash4, 5, Some(vec![[1u8; 32].into(), [2u8; 32].into()])); + let hash5 = insert_final_block(&db, Some(vec![[1u8; 32].into(), [2u8; 32].into()]), || default_header(&hash4, 5)); run_checks(&db, 5, &checks); - let hash6 = insert_final_block(&db, &hash5, 6, None); + let hash6 = insert_final_block(&db, None, || default_header(&hash5, 6)); run_checks(&db, 7, &checks); (hash2, hash6) @@ -708,9 +805,9 @@ pub(crate) mod tests { // some older non-best blocks are inserted // ... -> B2(1) -> B2_1(1) -> B2_2(2) // => the cache ignores all writes before best finalized block - let hash2_1 = insert_non_best_block(&db, &hash2, 3, Some(vec![[1u8; 32].into()])); + let hash2_1 = insert_non_best_block(&db, Some(vec![[1u8; 32].into()]), || default_header(&hash2, 3)); assert_eq!(None, db.cache().authorities_at(BlockId::Hash(hash2_1))); - let hash2_2 = insert_non_best_block(&db, &hash2_1, 4, Some(vec![[1u8; 32].into(), [2u8; 32].into()])); + let hash2_2 = insert_non_best_block(&db, Some(vec![[1u8; 32].into(), [2u8; 32].into()]), || default_header(&hash2_1, 4)); assert_eq!(None, db.cache().authorities_at(BlockId::Hash(hash2_2))); } @@ -721,32 +818,32 @@ pub(crate) mod tests { // \> B6_1_1(5) // \> B6_1_2(6) -> B6_1_3(7) - let hash7 = insert_block(&db, &hash6, 7, Some(vec![[3u8; 32].into()])); + let hash7 = insert_block(&db, Some(vec![[3u8; 32].into()]), || default_header(&hash6, 7)); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6)), None); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash7)), Some(vec![[3u8; 32].into()])); - let hash8 = insert_block(&db, &hash7, 8, Some(vec![[3u8; 32].into()])); + let hash8 = insert_block(&db, Some(vec![[3u8; 32].into()]), || default_header(&hash7, 8)); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6)), None); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash7)), Some(vec![[3u8; 32].into()])); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash8)), Some(vec![[3u8; 32].into()])); - let hash6_1 = insert_block(&db, &hash6, 7, Some(vec![[4u8; 32].into()])); + let hash6_1 = insert_block(&db, Some(vec![[4u8; 32].into()]), || default_header(&hash6, 7)); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6)), None); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash7)), Some(vec![[3u8; 32].into()])); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash8)), Some(vec![[3u8; 32].into()])); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6_1)), Some(vec![[4u8; 32].into()])); - let hash6_1_1 = insert_non_best_block(&db, &hash6_1, 8, Some(vec![[5u8; 32].into()])); + let hash6_1_1 = insert_non_best_block(&db, Some(vec![[5u8; 32].into()]), || default_header(&hash6_1, 8)); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6)), None); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash7)), Some(vec![[3u8; 32].into()])); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash8)), Some(vec![[3u8; 32].into()])); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6_1)), Some(vec![[4u8; 32].into()])); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6_1_1)), Some(vec![[5u8; 32].into()])); - let hash6_1_2 = insert_non_best_block(&db, &hash6_1, 8, Some(vec![[6u8; 32].into()])); + let hash6_1_2 = insert_non_best_block(&db, Some(vec![[6u8; 32].into()]), || default_header(&hash6_1, 8)); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6)), None); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash7)), Some(vec![[3u8; 32].into()])); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash8)), Some(vec![[3u8; 32].into()])); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6_1)), Some(vec![[4u8; 32].into()])); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6_1_1)), Some(vec![[5u8; 32].into()])); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6_1_2)), Some(vec![[6u8; 32].into()])); - let hash6_2 = insert_block(&db, &hash6_1, 8, Some(vec![[4u8; 32].into()])); + let hash6_2 = insert_block(&db, Some(vec![[4u8; 32].into()]), || default_header(&hash6_1, 8)); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6)), None); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash7)), Some(vec![[3u8; 32].into()])); assert_eq!(db.cache().authorities_at(BlockId::Hash(hash8)), Some(vec![[3u8; 32].into()])); @@ -779,4 +876,41 @@ pub(crate) mod tests { assert_eq!(db.cache().authorities_at(BlockId::Hash(hash6_2)), Some(vec![[4u8; 32].into()])); } } + + #[test] + fn database_is_reopened() { + let db = LightStorage::new_test(); + let hash0 = insert_final_block(&db, None, || default_header(&Default::default(), 0)); + assert_eq!(db.info().unwrap().best_hash, hash0); + assert_eq!(db.header(BlockId::Hash(hash0)).unwrap().unwrap().hash(), hash0); + + let db = db.db; + let db = LightStorage::from_kvdb(db).unwrap(); + assert_eq!(db.info().unwrap().best_hash, hash0); + assert_eq!(db.header(BlockId::Hash::(hash0)).unwrap().unwrap().hash(), hash0); + } + + #[test] + fn aux_store_works() { + let db = LightStorage::::new_test(); + + // insert aux1 + aux2 using direct store access + db.insert_aux(&[(&[1][..], &[101][..]), (&[2][..], &[102][..])], ::std::iter::empty()).unwrap(); + + // check aux values + assert_eq!(db.get_aux(&[1]).unwrap(), Some(vec![101])); + assert_eq!(db.get_aux(&[2]).unwrap(), Some(vec![102])); + assert_eq!(db.get_aux(&[3]).unwrap(), None); + + // delete aux1 + insert aux3 using import operation + db.import_header(default_header(&Default::default(), 0), None, NewBlockState::Best, vec![ + (vec![3], Some(vec![103])), + (vec![1], None), + ]).unwrap(); + + // check aux values + assert_eq!(db.get_aux(&[1]).unwrap(), None); + assert_eq!(db.get_aux(&[2]).unwrap(), Some(vec![102])); + assert_eq!(db.get_aux(&[3]).unwrap(), Some(vec![103])); + } } diff --git a/core/client/db/src/storage_cache.rs b/core/client/db/src/storage_cache.rs new file mode 100644 index 0000000000000000000000000000000000000000..3411987d48cdc4db997096567ffeb39cccdafd92 --- /dev/null +++ b/core/client/db/src/storage_cache.rs @@ -0,0 +1,420 @@ +// 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 . + +//! Global cache state. + +use std::collections::{VecDeque, HashSet, HashMap}; +use std::sync::Arc; +use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard}; +use lru_cache::LruCache; +use hash_db::Hasher; +use runtime_primitives::traits::{Block, Header}; +use state_machine::{backend::Backend as StateBackend, TrieBackend}; + +const STATE_CACHE_BLOCKS: usize = 12; + +type StorageKey = Vec; +type StorageValue = Vec; + +/// Shared canonical state cache. +pub struct Cache { + /// Storage cache. `None` indicates that key is known to be missing. + storage: LruCache>, + /// Storage hashes cache. `None` indicates that key is known to be missing. + hashes: LruCache>, + /// Information on the modifications in recently committed blocks; specifically which keys + /// changed in which block. Ordered by block number. + modifications: VecDeque>, +} + +pub type SharedCache = Arc>>; + +/// Create new shared cache instance with given max memory usage. +pub fn new_shared_cache(shared_cache_size: usize) -> SharedCache { + let cache_items = shared_cache_size / 100; // Estimated average item size. TODO: more accurate tracking + Arc::new(Mutex::new(Cache { + storage: LruCache::new(cache_items), + hashes: LruCache::new(cache_items), + modifications: VecDeque::new(), + })) +} + +#[derive(Debug)] +/// Accumulates a list of storage changed in a block. +struct BlockChanges { + /// Block number. + number: B::Number, + /// Block hash. + hash: B::Hash, + /// Parent block hash. + parent: B::Hash, + /// A set of modified storage keys. + storage: HashSet, + /// Block is part of the canonical chain. + is_canon: bool, +} + +/// Cached values specific to a state. +struct LocalCache { + /// Storage cache. `None` indicates that key is known to be missing. + storage: HashMap>, + /// Storage hashes cache. `None` indicates that key is known to be missing. + hashes: HashMap>, +} + +/// State abstraction. +/// Manages shared global state cache which reflects the canonical +/// state as it is on the disk. +/// A instance of `CachingState` may be created as canonical or not. +/// For canonical instances local cache is accumulated and applied +/// in `sync_cache` along with the change overlay. +/// For non-canonical clones local cache and changes are dropped. +pub struct CachingState, B: Block> { + /// Backing state. + state: S, + /// Shared canonical state cache. + shared_cache: SharedCache, + /// Local cache of values for this state. + local_cache: RwLock>, + /// Hash of the block on top of which this instance was created or + /// `None` if cache is disabled + pub parent_hash: Option, +} + +impl, B: Block> CachingState { + /// Create a new instance wrapping generic State and shared cache. + pub fn new(state: S, shared_cache: SharedCache, parent_hash: Option) -> CachingState { + CachingState { + state, + shared_cache, + local_cache: RwLock::new(LocalCache { + storage: Default::default(), + hashes: Default::default(), + }), + parent_hash: parent_hash, + } + } + + /// Propagate local cache into the shared cache and synchonize + /// the shared cache with the best block state. + /// This function updates the shared cache by removing entries + /// that are invalidated by chain reorganization. `sync_cache` + /// should be called after the block has been committed and the + /// blockchain route has been calculated. + pub fn sync_cache bool> ( + &mut self, + enacted: &[B::Hash], + retracted: &[B::Hash], + changes: Vec<(StorageKey, Option)>, + commit_hash: Option, + commit_number: Option<::Number>, + is_best: F, + ) { + let mut cache = self.shared_cache.lock(); + let is_best = is_best(); + trace!("Syncing cache, id = (#{:?}, {:?}), parent={:?}, best={}", commit_number, commit_hash, self.parent_hash, is_best); + let cache = &mut *cache; + + // Purge changes from re-enacted and retracted blocks. + // Filter out commiting block if any. + let mut clear = false; + for block in enacted.iter().filter(|h| commit_hash.as_ref().map_or(true, |p| *h != p)) { + clear = clear || { + if let Some(ref mut m) = cache.modifications.iter_mut().find(|m| &m.hash == block) { + trace!("Reverting enacted block {:?}", block); + m.is_canon = true; + for a in &m.storage { + trace!("Reverting enacted key {:?}", a); + cache.storage.remove(a); + } + false + } else { + true + } + }; + } + + for block in retracted { + clear = clear || { + if let Some(ref mut m) = cache.modifications.iter_mut().find(|m| &m.hash == block) { + trace!("Retracting block {:?}", block); + m.is_canon = false; + for a in &m.storage { + trace!("Retracted key {:?}", a); + cache.storage.remove(a); + } + false + } else { + true + } + }; + } + if clear { + // We don't know anything about the block; clear everything + trace!("Wiping cache"); + cache.storage.clear(); + cache.modifications.clear(); + } + + // Propagate cache only if committing on top of the latest canonical state + // blocks are ordered by number and only one block with a given number is marked as canonical + // (contributed to canonical state cache) + if let Some(_) = self.parent_hash { + let mut local_cache = self.local_cache.write(); + if is_best { + trace!("Committing {} local, {} hashes, {} modified entries", local_cache.storage.len(), local_cache.hashes.len(), changes.len()); + for (k, v) in local_cache.storage.drain() { + cache.storage.insert(k, v); + } + for (k, v) in local_cache.hashes.drain() { + cache.hashes.insert(k, v); + } + } + } + + if let ( + Some(ref number), Some(ref hash), Some(ref parent)) + = (commit_number, commit_hash, self.parent_hash) + { + if cache.modifications.len() == STATE_CACHE_BLOCKS { + cache.modifications.pop_back(); + } + let mut modifications = HashSet::new(); + for (k, v) in changes.into_iter() { + modifications.insert(k.clone()); + if is_best { + cache.hashes.remove(&k); + cache.storage.insert(k, v); + } + } + // Save modified storage. These are ordered by the block number. + let block_changes = BlockChanges { + storage: modifications, + number: *number, + hash: hash.clone(), + is_canon: is_best, + parent: parent.clone(), + }; + let insert_at = cache.modifications.iter() + .enumerate() + .find(|&(_, m)| m.number < *number) + .map(|(i, _)| i); + trace!("Inserting modifications at {:?}", insert_at); + if let Some(insert_at) = insert_at { + cache.modifications.insert(insert_at, block_changes); + } else { + cache.modifications.push_back(block_changes); + } + } + } + + /// Check if the key can be returned from cache by matching current block parent hash against canonical + /// state and filtering out entries modified in later blocks. + fn is_allowed( + key: &[u8], + parent_hash: &Option, + modifications: + &VecDeque> + ) -> bool + { + let mut parent = match *parent_hash { + None => { + trace!("Cache lookup skipped for {:?}: no parent hash", key); + return false; + } + Some(ref parent) => parent, + }; + if modifications.is_empty() { + trace!("Cache lookup allowed for {:?}", key); + return true; + } + // Ignore all storage modified in later blocks + // Modifications contains block ordered by the number + // We search for our parent in that list first and then for + // all its parent until we hit the canonical block, + // checking against all the intermediate modifications. + for m in modifications { + if &m.hash == parent { + if m.is_canon { + return true; + } + parent = &m.parent; + } + if m.storage.contains(key) { + trace!("Cache lookup skipped for {:?}: modified in a later block", key); + return false; + } + } + trace!("Cache lookup skipped for {:?}: parent hash is unknown", key); + false + } +} + +impl, B:Block> StateBackend for CachingState { + type Error = S::Error; + type Transaction = S::Transaction; + type TrieBackendStorage = S::TrieBackendStorage; + + fn storage(&self, key: &[u8]) -> Result>, Self::Error> { + let local_cache = self.local_cache.upgradable_read(); + if let Some(entry) = local_cache.storage.get(key).cloned() { + trace!("Found in local cache: {:?}", key); + return Ok(entry) + } + let mut cache = self.shared_cache.lock(); + if Self::is_allowed(key, &self.parent_hash, &cache.modifications) { + if let Some(entry) = cache.storage.get_mut(key).map(|a| a.clone()) { + trace!("Found in shared cache: {:?}", key); + return Ok(entry) + } + } + trace!("Cache miss: {:?}", key); + let value = self.state.storage(key)?; + RwLockUpgradableReadGuard::upgrade(local_cache).storage.insert(key.to_vec(), value.clone()); + Ok(value) + } + + fn storage_hash(&self, key: &[u8]) -> Result, Self::Error> { + let local_cache = self.local_cache.upgradable_read(); + if let Some(entry) = local_cache.hashes.get(key).cloned() { + trace!("Found hash in local cache: {:?}", key); + return Ok(entry) + } + let mut cache = self.shared_cache.lock(); + if Self::is_allowed(key, &self.parent_hash, &cache.modifications) { + if let Some(entry) = cache.hashes.get_mut(key).map(|a| a.clone()) { + trace!("Found hash in shared cache: {:?}", key); + return Ok(entry) + } + } + trace!("Cache hash miss: {:?}", key); + let hash = self.state.storage_hash(key)?; + RwLockUpgradableReadGuard::upgrade(local_cache).hashes.insert(key.to_vec(), hash.clone()); + Ok(hash) + } + + fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, Self::Error> { + self.state.child_storage(storage_key, key) + } + + fn exists_storage(&self, key: &[u8]) -> Result { + Ok(self.storage(key)?.is_some()) + } + + fn exists_child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result { + self.state.exists_child_storage(storage_key, key) + } + + fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { + self.state.for_keys_with_prefix(prefix, f) + } + + fn for_keys_in_child_storage(&self, storage_key: &[u8], f: F) { + self.state.for_keys_in_child_storage(storage_key, f) + } + + fn storage_root(&self, delta: I) -> (H::Out, Self::Transaction) + where + I: IntoIterator, Option>)>, + H::Out: Ord + { + self.state.storage_root(delta) + } + + fn child_storage_root(&self, storage_key: &[u8], delta: I) -> (Vec, bool, Self::Transaction) + where + I: IntoIterator, Option>)>, + H::Out: Ord + { + self.state.child_storage_root(storage_key, delta) + } + + fn pairs(&self) -> Vec<(Vec, Vec)> { + self.state.pairs() + } + + fn keys(&self, prefix: &Vec) -> Vec> { + self.state.keys(prefix) + } + + fn try_into_trie_backend(self) -> Option> { + self.state.try_into_trie_backend() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use runtime_primitives::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; + use state_machine::backend::InMemory; + use primitives::Blake2Hasher; + + type Block = RawBlock>; + #[test] + fn smoke() { + //init_log(); + let root_parent = H256::random(); + let key = H256::random()[..].to_vec(); + let h0 = H256::random(); + let h1a = H256::random(); + let h1b = H256::random(); + let h2a = H256::random(); + let h2b = H256::random(); + let h3a = H256::random(); + let h3b = H256::random(); + + let shared = new_shared_cache::(256*1024); + + // blocks [ 3a(c) 2a(c) 2b 1b 1a(c) 0 ] + // state [ 5 5 4 3 2 2 ] + let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(root_parent.clone())); + s.sync_cache(&[], &[], vec![(key.clone(), Some(vec![2]))], Some(h0.clone()), Some(0), || true); + + let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h0.clone())); + s.sync_cache(&[], &[], vec![], Some(h1a.clone()), Some(1), || true); + + let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h0.clone())); + s.sync_cache(&[], &[], vec![(key.clone(), Some(vec![3]))], Some(h1b.clone()), Some(1), || false); + + let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1b.clone())); + s.sync_cache(&[], &[], vec![(key.clone(), Some(vec![4]))], Some(h2b.clone()), Some(2), || false); + + let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1a.clone())); + s.sync_cache(&[], &[], vec![(key.clone(), Some(vec![5]))], Some(h2a.clone()), Some(2), || true); + + let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h2a.clone())); + s.sync_cache(&[], &[], vec![], Some(h3a.clone()), Some(3), || true); + + let s = CachingState::new(InMemory::::default(), shared.clone(), Some(h3a.clone())); + assert_eq!(s.storage(&key).unwrap().unwrap(), vec![5]); + + let s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1a.clone())); + assert!(s.storage(&key).unwrap().is_none()); + + let s = CachingState::new(InMemory::::default(), shared.clone(), Some(h2b.clone())); + assert!(s.storage(&key).unwrap().is_none()); + + let s = CachingState::new(InMemory::::default(), shared.clone(), Some(h1b.clone())); + assert!(s.storage(&key).unwrap().is_none()); + + // reorg to 3b + // blocks [ 3b(c) 3a 2a 2b(c) 1b 1a 0 ] + let mut s = CachingState::new(InMemory::::default(), shared.clone(), Some(h2b.clone())); + s.sync_cache(&[h1b.clone(), h2b.clone(), h3b.clone()], &[h1a.clone(), h2a.clone(), h3a.clone()], vec![], Some(h3b.clone()), Some(3), || true); + let s = CachingState::new(InMemory::::default(), shared.clone(), Some(h3a.clone())); + assert!(s.storage(&key).unwrap().is_none()); + } +} diff --git a/core/client/db/src/utils.rs b/core/client/db/src/utils.rs index f7b81845e8e7ca93edb184722a74942147e0f6a2..416bf239b280faa794b1d8e51cd7a1a7b1c8d2f0 100644 --- a/core/client/db/src/utils.rs +++ b/core/client/db/src/utils.rs @@ -68,11 +68,14 @@ pub struct Meta { } /// A block lookup key: used for canonical lookup from block number to hash -pub type ShortBlockLookupKey = [u8; 4]; +pub type NumberIndexKey = [u8; 4]; /// Convert block number into short lookup key (LE representation) for /// blocks that are in the canonical chain. -pub fn number_to_lookup_key(n: N) -> ShortBlockLookupKey where N: As { +/// +/// In the current database schema, this kind of key is only used for +/// lookups into an index, NOT for storing header data or others. +pub fn number_index_key(n: N) -> NumberIndexKey where N: As { let n: u64 = n.as_(); assert!(n & 0xffffffff00000000 == 0); @@ -90,7 +93,7 @@ pub fn number_and_hash_to_lookup_key(number: N, hash: H) -> Vec where N: As, H: AsRef<[u8]> { - let mut lookup_key = number_to_lookup_key(number).to_vec(); + let mut lookup_key = number_index_key(number).to_vec(); lookup_key.extend_from_slice(hash.as_ref()); lookup_key } @@ -107,25 +110,76 @@ pub fn lookup_key_to_number(key: &[u8]) -> client::error::Result where N: | (key[3] as u64)).map(As::sa) } +/// Delete number to hash mapping in DB transaction. +pub fn remove_number_to_key_mapping>( + transaction: &mut DBTransaction, + key_lookup_col: Option, + number: N, +) { + transaction.delete(key_lookup_col, number_index_key(number).as_ref()) +} + +/// Remove key mappings. +pub fn remove_key_mappings, H: AsRef<[u8]>>( + transaction: &mut DBTransaction, + key_lookup_col: Option, + number: N, + hash: H, +) { + remove_number_to_key_mapping(transaction, key_lookup_col, number); + transaction.delete(key_lookup_col, hash.as_ref()); +} + +/// Place a number mapping into the database. This maps number to current perceived +/// block hash at that position. +pub fn insert_number_to_key_mapping + Clone, H: AsRef<[u8]>>( + transaction: &mut DBTransaction, + key_lookup_col: Option, + number: N, + hash: H, +) { + transaction.put_vec( + key_lookup_col, + number_index_key(number.clone()).as_ref(), + number_and_hash_to_lookup_key(number, hash), + ) +} + +/// Insert a hash to key mapping in the database. +pub fn insert_hash_to_key_mapping, H: AsRef<[u8]> + Clone>( + transaction: &mut DBTransaction, + key_lookup_col: Option, + number: N, + hash: H, +) { + transaction.put_vec( + key_lookup_col, + hash.clone().as_ref(), + number_and_hash_to_lookup_key(number, hash), + ) +} + /// Convert block id to block lookup key. /// block lookup key is the DB-key header, block and justification are stored under. /// looks up lookup key by hash from DB as necessary. pub fn block_id_to_lookup_key( db: &KeyValueDB, - hash_lookup_col: Option, + key_lookup_col: Option, id: BlockId ) -> Result>, client::error::Error> where Block: BlockT, + ::runtime_primitives::traits::NumberFor: As, { - match id { - // numbers are solely looked up in canonical chain - BlockId::Number(n) => Ok(Some(number_to_lookup_key(n).to_vec())), - BlockId::Hash(h) => db.get(hash_lookup_col, h.as_ref()).map(|v| - v.map(|v| { v.into_vec() }) - ).map_err(db_err), - } -} + let res = match id { + BlockId::Number(n) => db.get( + key_lookup_col, + number_index_key(n).as_ref(), + ), + BlockId::Hash(h) => db.get(key_lookup_col, h.as_ref()), + }; + res.map(|v| v.map(|v| v.into_vec())).map_err(db_err) +} /// Maps database error to client error pub fn db_err(err: io::Error) -> client::error::Error { @@ -187,6 +241,17 @@ pub fn read_header( } } +/// Required header from the database. +pub fn require_header( + db: &KeyValueDB, + col_index: Option, + col: Option, + id: BlockId, +) -> client::error::Result { + read_header(db, col_index, col, id) + .and_then(|header| header.ok_or_else(|| client::error::ErrorKind::UnknownBlock(format!("{}", id)).into())) +} + /// Read meta from the database. pub fn read_meta(db: &KeyValueDB, col_meta: Option, col_header: Option) -> Result< Meta<<::Header as HeaderT>::Number, Block::Hash>, diff --git a/core/client/src/backend.rs b/core/client/src/backend.rs index e613c155343070e7a8b0712805a483819b6abdb0..b4040f59a9fa497515696623cfac1e4944b0bbd4 100644 --- a/core/client/src/backend.rs +++ b/core/client/src/backend.rs @@ -16,10 +16,10 @@ //! Substrate Client data backend -use error; -use primitives::AuthorityId; +use crate::error; +use primitives::ChangesTrieConfiguration; use runtime_primitives::{generic::BlockId, Justification, StorageMap, ChildrenStorageMap}; -use runtime_primitives::traits::{Block as BlockT, NumberFor}; +use runtime_primitives::traits::{AuthorityIdFor, Block as BlockT, NumberFor}; use state_machine::backend::Backend as StateBackend; use state_machine::ChangesTrieStorage as StateChangesTrieStorage; use hash_db::Hasher; @@ -47,8 +47,7 @@ impl NewBlockState { } /// Block insertion operation. Keeps hold if the inserted block state and data. -pub trait BlockImportOperation -where +pub trait BlockImportOperation where Block: BlockT, H: Hasher, { @@ -68,13 +67,32 @@ where /// Append authorities set to the transaction. This is a set of parent block (set which /// has been used to check justification of this block). - fn update_authorities(&mut self, authorities: Vec); + fn update_authorities(&mut self, authorities: Vec>); /// Inject storage data into the database. - fn update_storage(&mut self, update: >::Transaction) -> error::Result<()>; + fn update_db_storage(&mut self, update: >::Transaction) -> error::Result<()>; /// Inject storage data into the database replacing any existing data. fn reset_storage(&mut self, top: StorageMap, children: ChildrenStorageMap) -> error::Result; + /// Set top level storage changes. + fn update_storage(&mut self, update: Vec<(Vec, Option>)>) -> error::Result<()>; /// Inject changes trie data into the database. fn update_changes_trie(&mut self, update: MemoryDB) -> error::Result<()>; + /// Update auxiliary keys. Values are `None` if should be deleted. + fn set_aux(&mut self, ops: I) -> error::Result<()> + where I: IntoIterator, Option>)>; +} + +/// Provides access to an auxiliary database. +pub trait AuxStore { + /// Insert auxiliary data into key-value store. Deletions occur after insertions. + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >(&self, insert: I, delete: D) -> error::Result<()>; + /// Query auxiliary data from key-value store. + fn get_aux(&self, key: &[u8]) -> error::Result>>; } /// Client backend. Manages the data layer. @@ -85,20 +103,18 @@ where /// /// The same applies for live `BlockImportOperation`s: while an import operation building on a parent `P` /// is alive, the state for `P` should not be pruned. -pub trait Backend: Send + Sync -where +pub trait Backend: AuxStore + Send + Sync where Block: BlockT, H: Hasher, - { /// Associated block insertion operation type. type BlockImportOperation: BlockImportOperation; /// Associated blockchain backend type. - type Blockchain: ::blockchain::Backend; + type Blockchain: crate::blockchain::Backend; /// Associated state backend type. type State: StateBackend; /// Changes trie storage. - type ChangesTrieStorage: StateChangesTrieStorage; + type ChangesTrieStorage: PrunableStateChangesTrieStorage; /// Begin a new block insertion transaction with given parent block id. /// When constructing the genesis, this is called with all-zero hash. @@ -107,20 +123,42 @@ where fn commit_operation(&self, transaction: Self::BlockImportOperation) -> error::Result<()>; /// Finalize block with given Id. This should only be called if the parent of the given /// block has been finalized. - fn finalize_block(&self, block: BlockId) -> error::Result<()>; + fn finalize_block(&self, block: BlockId, justification: Option) -> error::Result<()>; /// Returns reference to blockchain backend. fn blockchain(&self) -> &Self::Blockchain; /// Returns reference to changes trie storage. fn changes_trie_storage(&self) -> Option<&Self::ChangesTrieStorage>; /// Returns state backend with post-state of given block. fn state_at(&self, block: BlockId) -> error::Result; + /// Destroy state and save any useful data, such as cache. + fn destroy_state(&self, _state: Self::State) -> error::Result<()> { + Ok(()) + } /// Attempts to revert the chain by `n` blocks. Returns the number of blocks that were /// successfully reverted. fn revert(&self, n: NumberFor) -> error::Result>; + /// Insert auxiliary data into key-value store. - fn insert_aux<'a, 'b: 'a, 'c: 'a, I: IntoIterator, D: IntoIterator>(&self, insert: I, delete: D) -> error::Result<()>; + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >(&self, insert: I, delete: D) -> error::Result<()> + { + AuxStore::insert_aux(self, insert, delete) + } /// Query auxiliary data from key-value store. - fn get_aux(&self, key: &[u8]) -> error::Result>>; + fn get_aux(&self, key: &[u8]) -> error::Result>> { + AuxStore::get_aux(self, key) + } +} + +/// Changes trie storage that supports pruning. +pub trait PrunableStateChangesTrieStorage: StateChangesTrieStorage { + /// Get number block of oldest, non-pruned changes trie. + fn oldest_changes_trie_block(&self, config: &ChangesTrieConfiguration, best_finalized: u64) -> u64; } /// Mark for all Backend implementations, that are making use of state data, stored locally. diff --git a/core/client/src/block_builder/api.rs b/core/client/src/block_builder/api.rs new file mode 100644 index 0000000000000000000000000000000000000000..540c135de226ea1b7bed2bef281b70836d27378f --- /dev/null +++ b/core/client/src/block_builder/api.rs @@ -0,0 +1,37 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 runtime api for building blocks. + +use runtime_primitives::{traits::Block as BlockT, ApplyResult, CheckInherentError}; +use rstd::vec::Vec; +use sr_api_macros::decl_runtime_apis; + +decl_runtime_apis! { + /// The `BlockBuilder` api trait that provides required functions for building a block for a runtime. + pub trait BlockBuilder { + /// Apply the given extrinsics. + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyResult; + /// Finish the current block. + fn finalise_block() -> ::Header; + /// Generate inherent extrinsics. The inherent data will vary from chain to chain. + fn inherent_extrinsics(inherent: InherentData) -> Vec<::Extrinsic>; + /// Check that the inherents are valid. The inherent data will vary from chain to chain. + fn check_inherents(block: Block, data: InherentData) -> Result<(), CheckInherentError>; + /// Generate a random seed. + fn random_seed() -> ::Hash; + } +} diff --git a/core/client/src/block_builder.rs b/core/client/src/block_builder/block_builder.rs similarity index 56% rename from core/client/src/block_builder.rs rename to core/client/src/block_builder/block_builder.rs index d7365750a2cafbea6f9de9c9c850810fe29f9bbc..a0e9d67827b647dae8a8f0b5964fb693f2d74a1c 100644 --- a/core/client/src/block_builder.rs +++ b/core/client/src/block_builder/block_builder.rs @@ -14,60 +14,51 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Utility struct to build a block. - +use super::api::BlockBuilder as BlockBuilderApi; use std::vec::Vec; use std::marker::PhantomData; use codec::Encode; -use state_machine; -use runtime_primitives::traits::{Header as HeaderT, Hash, Block as BlockT, One, HashFor}; +use crate::blockchain::HeaderBackend; +use runtime_primitives::traits::{ + Header as HeaderT, Hash, Block as BlockT, One, HashFor, ProvideRuntimeApi, ApiRef +}; +use primitives::H256; use runtime_primitives::generic::BlockId; -use runtime_api::BlockBuilder as BlockBuilderAPI; -use {backend, error, Client, CallExecutor}; +use crate::runtime_api::Core; +use crate::error; use runtime_primitives::ApplyOutcome; -use primitives::{Blake2Hasher, H256}; -use hash_db::Hasher; -/// Utility for building new (valid) blocks from a stream of extrinsics. -pub struct BlockBuilder<'a, B, E, Block, H> -where - B: backend::Backend + 'a, - E: CallExecutor + Clone + 'a, - Block: BlockT, - H: Hasher, - H::Out: Ord, -{ +/// Utility for building new (valid) blocks from a stream of extrinsics. +pub struct BlockBuilder<'a, Block, InherentData, A: ProvideRuntimeApi> where Block: BlockT { header: ::Header, extrinsics: Vec<::Extrinsic>, - client: &'a Client, + api: ApiRef<'a, A::Api>, block_id: BlockId, - changes: state_machine::OverlayedChanges, - _marker: PhantomData, + _marker: PhantomData, } -impl<'a, B, E, Block> BlockBuilder<'a, B, E, Block, Blake2Hasher> +impl<'a, Block, A, InherentData> BlockBuilder<'a, Block, InherentData, A> where - B: backend::Backend + 'a, - E: CallExecutor + Clone + 'a, Block: BlockT, + A: ProvideRuntimeApi + HeaderBackend + 'a, + A::Api: BlockBuilderApi, { /// Create a new instance of builder from the given client, building on the latest block. - pub fn new(client: &'a Client) -> error::Result { - client.info().and_then(|i| Self::at_block(&BlockId::Hash(i.chain.best_hash), client)) + pub fn new(api: &'a A) -> error::Result { + api.info().and_then(|i| Self::at_block(&BlockId::Hash(i.best_hash), api)) } /// Create a new instance of builder from the given client using a particular block's ID to /// build upon. - pub fn at_block(block_id: &BlockId, client: &'a Client) -> error::Result { - let number = client.block_number_from_id(block_id)? + pub fn at_block(block_id: &BlockId, api: &'a A) -> error::Result { + let number = api.block_number_from_id(block_id)? .ok_or_else(|| error::ErrorKind::UnknownBlock(format!("{}", block_id)))? + One::one(); - let parent_hash = client.block_hash_from_id(block_id)? + let parent_hash = api.block_hash_from_id(block_id)? .ok_or_else(|| error::ErrorKind::UnknownBlock(format!("{}", block_id)))?; - let mut changes = Default::default(); let header = <::Header as HeaderT>::new( number, Default::default(), @@ -76,16 +67,15 @@ where Default::default() ); - client.initialise_block(block_id, &mut changes, &header)?; - changes.commit_prospective(); + let api = api.runtime_api(); + api.initialise_block(block_id, &header)?; Ok(BlockBuilder { header, extrinsics: Vec::new(), - client, + api, block_id: *block_id, - changes, - _marker: Default::default(), + _marker: PhantomData, }) } @@ -93,30 +83,27 @@ where /// can be validly executed (by executing it); if it is invalid, it'll be returned along with /// the error. Otherwise, it will return a mutable reference to self (in order to chain). pub fn push(&mut self, xt: ::Extrinsic) -> error::Result<()> { - match self.client.apply_extrinsic(&self.block_id, &mut self.changes, &xt) { - Ok(result) => { - match result { - Ok(ApplyOutcome::Success) | Ok(ApplyOutcome::Fail) => { - self.extrinsics.push(xt); - self.changes.commit_prospective(); - Ok(()) - } - Err(e) => { - self.changes.discard_prospective(); - Err(error::ErrorKind::ApplyExtrinsicFailed(e).into()) - } + use crate::runtime_api::ApiExt; + + let block_id = &self.block_id; + let extrinsics = &mut self.extrinsics; + + self.api.map_api_result(|api| { + match api.apply_extrinsic(block_id, xt.clone())? { + Ok(ApplyOutcome::Success) | Ok(ApplyOutcome::Fail) => { + extrinsics.push(xt); + Ok(()) + } + Err(e) => { + Err(error::ErrorKind::ApplyExtrinsicFailed(e).into()) } } - Err(e) => { - self.changes.discard_prospective(); - Err(e) - } - } + }) } /// Consume the builder to return a valid `Block` containing all pushed extrinsics. pub fn bake(mut self) -> error::Result { - self.header = self.client.finalise_block(&self.block_id, &mut self.changes)?; + self.header = self.api.finalise_block(&self.block_id)?; debug_assert_eq!( self.header.extrinsics_root().clone(), diff --git a/core/client/src/block_builder/mod.rs b/core/client/src/block_builder/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..f22f599ffdd9a2ae356bef3006aff19a4225bd2d --- /dev/null +++ b/core/client/src/block_builder/mod.rs @@ -0,0 +1,23 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Utility struct to build a block. + +#[cfg(feature = "std")] +mod block_builder; +#[cfg(feature = "std")] +pub use self::block_builder::*; +pub mod api; diff --git a/core/client/src/blockchain.rs b/core/client/src/blockchain.rs index a2896ab7f366a2fdc3438ed4b36c320095c4382f..94eecf1505fbaaeb0c5d1f9481ee945adb24bbe4 100644 --- a/core/client/src/blockchain.rs +++ b/core/client/src/blockchain.rs @@ -16,12 +16,11 @@ //! Substrate blockchain trait -use primitives::AuthorityId; -use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; +use runtime_primitives::traits::{AuthorityIdFor, Block as BlockT, Header as HeaderT, NumberFor}; use runtime_primitives::generic::BlockId; use runtime_primitives::Justification; -use error::{ErrorKind, Result}; +use crate::error::{ErrorKind, Result}; /// Blockchain database header backend. Does not perform any validation. pub trait HeaderBackend: Send + Sync { @@ -36,10 +35,38 @@ pub trait HeaderBackend: Send + Sync { /// Get block hash by number. Returns `None` if the header is not in the chain. fn hash(&self, number: NumberFor) -> Result>; + /// Convert an arbitrary block ID into a block hash. + fn block_hash_from_id(&self, id: &BlockId) -> Result> { + match *id { + BlockId::Hash(h) => Ok(Some(h)), + BlockId::Number(n) => self.hash(n), + } + } + + /// Convert an arbitrary block ID into a block hash. + fn block_number_from_id(&self, id: &BlockId) -> Result>> { + match *id { + BlockId::Hash(_) => Ok(self.header(*id)?.map(|h| h.number().clone())), + BlockId::Number(n) => Ok(Some(n)), + } + } + /// Get block header. Returns `UnknownBlock` error if block is not found. fn expect_header(&self, id: BlockId) -> Result { self.header(id)?.ok_or_else(|| ErrorKind::UnknownBlock(format!("{}", id)).into()) } + + /// Convert an arbitrary block ID into a block number. Returns `UnknownBlock` error if block is not found. + fn expect_block_number_from_id(&self, id: &BlockId) -> Result> { + self.block_number_from_id(id) + .and_then(|n| n.ok_or_else(|| ErrorKind::UnknownBlock(format!("{}", id)).into())) + } + + /// Convert an arbitrary block ID into a block hash. Returns `UnknownBlock` error if block is not found. + fn expect_block_hash_from_id(&self, id: &BlockId) -> Result { + self.block_hash_from_id(id) + .and_then(|n| n.ok_or_else(|| ErrorKind::UnknownBlock(format!("{}", id)).into())) + } } /// Blockchain database backend. Does not perform any validation. @@ -62,7 +89,7 @@ pub trait Backend: HeaderBackend { /// Blockchain optional data cache. pub trait Cache: Send + Sync { /// Returns the set of authorities, that was active at given block or None if there's no entry in the cache. - fn authorities_at(&self, block: BlockId) -> Option>; + fn authorities_at(&self, block: BlockId) -> Option>>; } /// Block import outcome diff --git a/core/client/src/call_executor.rs b/core/client/src/call_executor.rs index 16580fe8d9c07e5fbdbdd8a9e86c55573ed8e2a9..263c43596b873241a3995d3290676c52b44df996 100644 --- a/core/client/src/call_executor.rs +++ b/core/client/src/call_executor.rs @@ -14,30 +14,20 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::sync::Arc; -use std::cmp::Ord; +use std::{sync::Arc, cmp::Ord, panic::UnwindSafe}; +use codec::{Encode, Decode}; use runtime_primitives::generic::BlockId; use runtime_primitives::traits::Block as BlockT; -use state_machine::{self, OverlayedChanges, Ext, - CodeExecutor, ExecutionManager, native_when_possible}; +use state_machine::{ + self, OverlayedChanges, Ext, CodeExecutor, ExecutionManager, native_when_possible +}; use executor::{RuntimeVersion, RuntimeInfo, NativeVersion}; use hash_db::Hasher; use trie::MemoryDB; -use codec::Decode; -use primitives::{H256, Blake2Hasher}; -use primitives::storage::well_known_keys; - -use backend; -use error; - -/// Information regarding the result of a call. -#[derive(Debug, Clone)] -pub struct CallResult { - /// The data that was returned from the call. - pub return_data: Vec, - /// The changes made to the state by the call. - pub changes: OverlayedChanges, -} +use primitives::{H256, Blake2Hasher, NativeOrEncoded, NeverNativeValue}; + +use crate::backend; +use crate::error; /// Method call executor. pub trait CallExecutor @@ -45,7 +35,6 @@ where B: BlockT, H: Hasher, H::Out: Ord, - { /// Externalities error type. type Error: state_machine::Error; @@ -53,11 +42,37 @@ where /// Execute a call to a contract on top of state in a block of given hash. /// /// No changes are made. - fn call(&self, + fn call( + &self, id: &BlockId, method: &str, call_data: &[u8], - ) -> Result; + ) -> Result, error::Error>; + + /// Execute a contextual call on top of state in a block of a given hash. + /// + /// No changes are made. + /// Before executing the method, passed header is installed as the current header + /// of the execution context. + fn contextual_call< + PB: Fn() -> error::Result, + EM: Fn( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> R + UnwindSafe, + >( + &self, + at: &BlockId, + method: &str, + call_data: &[u8], + changes: &mut OverlayedChanges, + initialised_block: &mut Option>, + prepare_environment_block: PB, + manager: ExecutionManager, + native_call: Option, + ) -> error::Result> where ExecutionManager: Clone; /// Extract RuntimeVersion of given block /// @@ -69,23 +84,45 @@ where /// No changes are made. fn call_at_state< S: state_machine::Backend, - F: FnOnce(Result, Self::Error>, Result, Self::Error>) -> Result, Self::Error>, + F: FnOnce( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> R + UnwindSafe, >(&self, state: &S, overlay: &mut OverlayedChanges, method: &str, call_data: &[u8], - manager: ExecutionManager - ) -> Result<(Vec, S::Transaction, Option>), error::Error>; + manager: ExecutionManager, + native_call: Option, + ) -> Result<(NativeOrEncoded, S::Transaction, Option>), error::Error>; /// Execute a call to a contract on top of given state, gathering execution proof. /// /// No changes are made. - fn prove_at_state>(&self, + fn prove_at_state>( + &self, state: S, overlay: &mut OverlayedChanges, method: &str, call_data: &[u8] + ) -> Result<(Vec, Vec>), error::Error> { + let trie_state = state.try_into_trie_backend() + .ok_or_else(|| Box::new(state_machine::ExecutionError::UnableToGenerateProof) as Box)?; + self.prove_at_trie_state(&trie_state, overlay, method, call_data) + } + + /// Execute a call to a contract on top of given trie state, gathering execution proof. + /// + /// No changes are made. + fn prove_at_trie_state>( + &self, + trie_state: &state_machine::TrieBackend, + overlay: &mut OverlayedChanges, + method: &str, + call_data: &[u8] ) -> Result<(Vec, Vec>), error::Error>; /// Get runtime version if supported. @@ -127,46 +164,106 @@ where id: &BlockId, method: &str, call_data: &[u8], - ) -> error::Result { + ) -> error::Result> { let mut changes = OverlayedChanges::default(); - let (return_data, _, _) = self.call_at_state( - &self.backend.state_at(*id)?, + let state = self.backend.state_at(*id)?; + let return_data = state_machine::execute_using_consensus_failure_handler::< + _, _, _, _, _, _, fn() -> NeverNativeValue + >( + &state, + self.backend.changes_trie_storage(), &mut changes, + &self.executor, method, call_data, native_when_possible(), - )?; - Ok(CallResult { return_data, changes }) + false, + None, + ) + .map(|(result, _, _)| result)?; + self.backend.destroy_state(state)?; + Ok(return_data.into_encoded()) + } + + fn contextual_call< + PB: Fn() -> error::Result, + EM: Fn( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> R + UnwindSafe, + >( + &self, + at: &BlockId, + method: &str, + call_data: &[u8], + changes: &mut OverlayedChanges, + initialised_block: &mut Option>, + prepare_environment_block: PB, + manager: ExecutionManager, + native_call: Option, + ) -> Result, error::Error> where ExecutionManager: Clone { + let state = self.backend.state_at(*at)?; + //TODO: Find a better way to prevent double block initialization + if method != "Core_initialise_block" && initialised_block.map(|id| id != *at).unwrap_or(true) { + let header = prepare_environment_block()?; + state_machine::execute_using_consensus_failure_handler::< + _, _, _, _, _, R, fn() -> R, + >( + &state, + self.backend.changes_trie_storage(), + changes, + &self.executor, + "Core_initialise_block", + &header.encode(), + manager.clone(), + false, + None, + )?; + *initialised_block = Some(*at); + } + + let result = state_machine::execute_using_consensus_failure_handler( + &state, + self.backend.changes_trie_storage(), + changes, + &self.executor, + method, + call_data, + manager, + false, + native_call, + ).map(|(result, _, _)| result)?; + + self.backend.destroy_state(state)?; + Ok(result) } fn runtime_version(&self, id: &BlockId) -> error::Result { let mut overlay = OverlayedChanges::default(); let state = self.backend.state_at(*id)?; - use state_machine::Backend; - let code = state.storage(well_known_keys::CODE) - .map_err(|e| error::ErrorKind::Execution(Box::new(e)))? - .ok_or(error::ErrorKind::VersionInvalid)? - .to_vec(); - let heap_pages = state.storage(well_known_keys::HEAP_PAGES) - .map_err(|e| error::ErrorKind::Execution(Box::new(e)))? - .and_then(|v| u64::decode(&mut &v[..])) - .unwrap_or(1024) as usize; - let mut ext = Ext::new(&mut overlay, &state, self.backend.changes_trie_storage()); - self.executor.runtime_version(&mut ext, heap_pages, &code) + self.executor.runtime_version(&mut ext) .ok_or(error::ErrorKind::VersionInvalid.into()) } fn call_at_state< S: state_machine::Backend, - F: FnOnce(Result, Self::Error>, Result, Self::Error>) -> Result, Self::Error>, + F: FnOnce( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> R + UnwindSafe, >(&self, state: &S, changes: &mut OverlayedChanges, method: &str, call_data: &[u8], manager: ExecutionManager, - ) -> error::Result<(Vec, S::Transaction, Option>)> { + native_call: Option, + ) -> error::Result<(NativeOrEncoded, S::Transaction, Option>)> { state_machine::execute_using_consensus_failure_handler( state, self.backend.changes_trie_storage(), @@ -175,18 +272,27 @@ where method, call_data, manager, - ).map_err(Into::into) + true, + native_call, + ) + .map(|(result, storage_tx, changes_tx)| ( + result, + storage_tx.expect("storage_tx is always computed when compute_tx is true; qed"), + changes_tx, + )) + .map_err(Into::into) } - fn prove_at_state>(&self, - state: S, - changes: &mut OverlayedChanges, + fn prove_at_trie_state>( + &self, + trie_state: &state_machine::TrieBackend, + overlay: &mut OverlayedChanges, method: &str, call_data: &[u8] ) -> Result<(Vec, Vec>), error::Error> { - state_machine::prove_execution( - state, - changes, + state_machine::prove_execution_on_trie_backend( + trie_state, + overlay, &self.executor, method, call_data, diff --git a/core/client/src/cht.rs b/core/client/src/cht.rs index fd8e07c3dd4bc8632eebdccc7c7237e3d3032435..5797f3e279f1db9d9e4f58405443ec16b7f738e8 100644 --- a/core/client/src/cht.rs +++ b/core/client/src/cht.rs @@ -23,16 +23,19 @@ //! root has. A correct proof implies that the claimed block is identical to the one //! we discarded. +use std::collections::HashSet; + use hash_db; use heapsize::HeapSizeOf; use trie; -use primitives::H256; +use primitives::{H256, convert_hash}; use runtime_primitives::traits::{As, Header as HeaderT, SimpleArithmetic, One}; use state_machine::backend::InMemory as InMemoryState; -use state_machine::{prove_read, read_proof_check}; +use state_machine::{MemoryDB, TrieBackend, Backend as StateBackend, + prove_read_on_trie_backend, read_proof_check, read_proof_check_on_proving_backend}; -use error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult}; +use crate::error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult}; /// The size of each CHT. This value is passed to every CHT-related function from /// production code. Other values are passed from tests. @@ -63,41 +66,48 @@ pub fn compute_root( cht_size: u64, cht_num: Header::Number, hashes: I, -) -> Option +) -> ClientResult where Header: HeaderT, Hasher: hash_db::Hasher, Hasher::Out: Ord, - I: IntoIterator>, + I: IntoIterator>>, { - build_pairs::(cht_size, cht_num, hashes) - .map(|pairs| trie::trie_root::(pairs)) + Ok(trie::trie_root::( + build_pairs::(cht_size, cht_num, hashes)? + )) } /// Build CHT-based header proof. -pub fn build_proof( +pub fn build_proof( cht_size: u64, cht_num: Header::Number, - block_num: Header::Number, - hashes: I -) -> Option>> + blocks: BlocksI, + hashes: HashesI +) -> ClientResult>> where Header: HeaderT, Hasher: hash_db::Hasher, Hasher::Out: Ord + HeapSizeOf, - I: IntoIterator>, + BlocksI: IntoIterator, + HashesI: IntoIterator>>, { - let transaction = build_pairs::(cht_size, cht_num, hashes)? + let transaction = build_pairs::(cht_size, cht_num, hashes)? .into_iter() .map(|(k, v)| (None, k, Some(v))) .collect::>(); let storage = InMemoryState::::default().update(transaction); - let (value, proof) = prove_read(storage, &encode_cht_key(block_num)).ok()?; - if value.is_none() { - None - } else { - Some(proof) + let trie_storage = storage.try_into_trie_backend() + .expect("InMemoryState::try_into_trie_backend always returns Some; qed"); + let mut total_proof = HashSet::new(); + for block in blocks.into_iter() { + debug_assert_eq!(block_to_cht_number(cht_size, block), Some(cht_num)); + + let (value, proof) = prove_read_on_trie_backend(&trie_storage, &encode_cht_key(block))?; + assert!(value.is_some(), "we have just built trie that includes the value for block"); + total_proof.extend(proof); } + Ok(total_proof.into_iter().collect()) } /// Check CHT-based header proof. @@ -109,21 +119,104 @@ pub fn check_proof( ) -> ClientResult<()> where Header: HeaderT, - Header::Hash: AsRef<[u8]>, Hasher: hash_db::Hasher, Hasher::Out: Ord + HeapSizeOf, { - let mut root: Hasher::Out = Default::default(); - root.as_mut().copy_from_slice(local_root.as_ref()); + do_check_proof::(local_root, local_number, remote_hash, move |local_root, local_cht_key| + read_proof_check::(local_root, remote_proof, + local_cht_key).map_err(|e| ClientError::from(e))) +} + +/// Check CHT-based header proof on pre-created proving backend. +pub fn check_proof_on_proving_backend( + local_root: Header::Hash, + local_number: Header::Number, + remote_hash: Header::Hash, + proving_backend: &TrieBackend, Hasher>, +) -> ClientResult<()> + where + Header: HeaderT, + Hasher: hash_db::Hasher, + Hasher::Out: Ord + HeapSizeOf, +{ + do_check_proof::(local_root, local_number, remote_hash, |_, local_cht_key| + read_proof_check_on_proving_backend::( + proving_backend, local_cht_key).map_err(|e| ClientError::from(e))) +} + +/// Check CHT-based header proof using passed checker function. +fn do_check_proof( + local_root: Header::Hash, + local_number: Header::Number, + remote_hash: Header::Hash, + checker: F, +) -> ClientResult<()> + where + Header: HeaderT, + Hasher: hash_db::Hasher, + Hasher::Out: Ord + HeapSizeOf, + F: FnOnce(Hasher::Out, &[u8]) -> ClientResult>>, +{ + let root: Hasher::Out = convert_hash(&local_root); let local_cht_key = encode_cht_key(local_number); - let local_cht_value = read_proof_check::(root, remote_proof, - &local_cht_key).map_err(|e| ClientError::from(e))?; - let local_cht_value = local_cht_value.ok_or_else(|| ClientErrorKind::InvalidHeaderProof)?; - let local_hash = decode_cht_value(&local_cht_value).ok_or_else(|| ClientErrorKind::InvalidHeaderProof)?; + let local_cht_value = checker(root, &local_cht_key)?; + let local_cht_value = local_cht_value.ok_or_else(|| ClientErrorKind::InvalidCHTProof)?; + let local_hash = decode_cht_value(&local_cht_value).ok_or_else(|| ClientErrorKind::InvalidCHTProof)?; match &local_hash[..] == remote_hash.as_ref() { true => Ok(()), - false => Err(ClientErrorKind::InvalidHeaderProof.into()), + false => Err(ClientErrorKind::InvalidCHTProof.into()), } + +} + +/// Group ordered blocks by CHT number and call functor with blocks of each group. +pub fn for_each_cht_group( + cht_size: u64, + blocks: I, + mut functor: F, + mut functor_param: P, +) -> ClientResult<()> + where + Header: HeaderT, + I: IntoIterator, + F: FnMut(P, Header::Number, Vec) -> ClientResult

, +{ + let mut current_cht_num = None; + let mut current_cht_blocks = Vec::new(); + for block in blocks { + let new_cht_num = match block_to_cht_number(cht_size, block.as_()) { + Some(new_cht_num) => new_cht_num, + None => return Err(ClientErrorKind::Backend(format!( + "Cannot compute CHT root for the block #{}", block)).into() + ), + }; + + let advance_to_next_cht = current_cht_num.is_some() && current_cht_num != Some(new_cht_num); + if advance_to_next_cht { + let current_cht_num = current_cht_num.expect("advance_to_next_cht is true; + it is true only when current_cht_num is Some; qed"); + assert!(new_cht_num > current_cht_num, "for_each_cht_group only supports ordered iterators"); + + functor_param = functor( + functor_param, + As::sa(current_cht_num), + ::std::mem::replace(&mut current_cht_blocks, Vec::new()), + )?; + } + + current_cht_blocks.push(block); + current_cht_num = Some(new_cht_num); + } + + if let Some(current_cht_num) = current_cht_num { + functor( + functor_param, + As::sa(current_cht_num), + ::std::mem::replace(&mut current_cht_blocks, Vec::new()), + )?; + } + + Ok(()) } /// Build pairs for computing CHT. @@ -131,26 +224,29 @@ fn build_pairs( cht_size: u64, cht_num: Header::Number, hashes: I -) -> Option, Vec)>> +) -> ClientResult, Vec)>> where Header: HeaderT, - I: IntoIterator>, + I: IntoIterator>>, { let start_num = start_number(cht_size, cht_num); let mut pairs = Vec::new(); let mut hash_number = start_num; for hash in hashes.into_iter().take(cht_size as usize) { - pairs.push(hash.map(|hash| ( + let hash = hash?.ok_or_else(|| ClientError::from( + ClientErrorKind::MissingHashRequiredForCHT(cht_num.as_(), hash_number.as_()) + ))?; + pairs.push(( encode_cht_key(hash_number).to_vec(), encode_cht_value(hash) - ))?); + )); hash_number += Header::Number::one(); } if pairs.len() as u64 == cht_size { - Some(pairs) + Ok(pairs) } else { - None + Err(ClientErrorKind::MissingHashRequiredForCHT(cht_num.as_(), hash_number.as_()).into()) } } @@ -242,30 +338,59 @@ mod tests { #[test] fn build_pairs_fails_when_no_enough_blocks() { - assert!(build_pairs::(SIZE, 0, vec![Some(1.into()); SIZE as usize / 2]).is_none()); + assert!(build_pairs::(SIZE, 0, + ::std::iter::repeat_with(|| Ok(Some(1.into()))).take(SIZE as usize / 2)).is_err()); } #[test] fn build_pairs_fails_when_missing_block() { - assert!(build_pairs::(SIZE, 0, ::std::iter::repeat(Some(1.into())).take(SIZE as usize / 2) - .chain(::std::iter::once(None)) - .chain(::std::iter::repeat(Some(2.into())).take(SIZE as usize / 2 - 1))).is_none()); + assert!(build_pairs::(SIZE, 0, ::std::iter::repeat_with(|| Ok(Some(1.into()))).take(SIZE as usize / 2) + .chain(::std::iter::once(Ok(None))) + .chain(::std::iter::repeat_with(|| Ok(Some(2.into()))).take(SIZE as usize / 2 - 1))).is_err()); } #[test] fn compute_root_works() { - assert!(compute_root::(SIZE, 42, vec![Some(1.into()); SIZE as usize]).is_some()); + assert!(compute_root::(SIZE, 42, + ::std::iter::repeat_with(|| Ok(Some(1.into()))).take(SIZE as usize)).is_ok()); } #[test] - fn build_proof_fails_when_querying_wrong_block() { - assert!(build_proof::( - SIZE, 0, (SIZE * 1000) as u64, vec![Some(1.into()); SIZE as usize]).is_none()); + #[should_panic] + fn build_proof_panics_when_querying_wrong_block() { + assert!(build_proof::( + SIZE, 0, vec![(SIZE * 1000) as u64], + ::std::iter::repeat_with(|| Ok(Some(1.into()))).take(SIZE as usize)).is_err()); } #[test] fn build_proof_works() { - assert!(build_proof::( - SIZE, 0, (SIZE / 2) as u64, vec![Some(1.into()); SIZE as usize]).is_some()); + assert!(build_proof::( + SIZE, 0, vec![(SIZE / 2) as u64], + ::std::iter::repeat_with(|| Ok(Some(1.into()))).take(SIZE as usize)).is_ok()); + } + + #[test] + #[should_panic] + fn for_each_cht_group_panics() { + let _ = for_each_cht_group::(SIZE, vec![SIZE * 5, SIZE * 2], |_, _, _| Ok(()), ()); + } + + #[test] + fn for_each_cht_group_works() { + let _ = for_each_cht_group::(SIZE, vec![ + SIZE * 2 + 1, SIZE * 2 + 2, SIZE * 2 + 5, + SIZE * 4 + 1, SIZE * 4 + 7, + SIZE * 6 + 1 + ], |_, cht_num, blocks| { + match cht_num { + 2 => assert_eq!(blocks, vec![SIZE * 2 + 1, SIZE * 2 + 2, SIZE * 2 + 5]), + 4 => assert_eq!(blocks, vec![SIZE * 4 + 1, SIZE * 4 + 7]), + 6 => assert_eq!(blocks, vec![SIZE * 6 + 1]), + _ => unreachable!(), + } + + Ok(()) + }, ()); } } diff --git a/core/client/src/client.rs b/core/client/src/client.rs index 4645a56a2f6448d0a36e56166269d09739dcf6b3..67052ff7f176cfefb83e136519e3f80f7c34fb86 100644 --- a/core/client/src/client.rs +++ b/core/client/src/client.rs @@ -16,36 +16,53 @@ //! Substrate Client -use std::sync::Arc; -use error::{Error, ErrorKind}; +use std::{marker::PhantomData, collections::{HashSet, BTreeMap}, sync::Arc, panic::UnwindSafe}; +use crate::error::Error; use futures::sync::mpsc; use parking_lot::{Mutex, RwLock}; -use primitives::AuthorityId; +use primitives::NativeOrEncoded; use runtime_primitives::{ Justification, - generic::{BlockId, SignedBlock, Block as RuntimeBlock}, - transaction_validity::{TransactionValidity, TransactionTag}, + generic::{BlockId, SignedBlock}, }; -use consensus::{ImportBlock, ImportResult, BlockOrigin}; -use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, As, NumberFor, CurrentHeight, BlockNumberToHash}; -use runtime_primitives::{ApplyResult, BuildStorage}; -use runtime_api as api; -use primitives::{Blake2Hasher, H256, ChangesTrieConfiguration}; +use consensus::{ + Error as ConsensusError, ErrorKind as ConsensusErrorKind, ImportBlock, ImportResult, + BlockOrigin, ForkChoiceStrategy +}; +use runtime_primitives::traits::{ + Block as BlockT, Header as HeaderT, Zero, As, NumberFor, CurrentHeight, BlockNumberToHash, + ApiRef, ProvideRuntimeApi, Digest, DigestItem, AuthorityIdFor +}; +use runtime_primitives::BuildStorage; +use crate::runtime_api::{CallRuntimeAt, ConstructRuntimeApi}; +use primitives::{Blake2Hasher, H256, ChangesTrieConfiguration, convert_hash, NeverNativeValue}; use primitives::storage::{StorageKey, StorageData}; use primitives::storage::well_known_keys; use codec::{Encode, Decode}; use state_machine::{ - Backend as StateBackend, CodeExecutor, + DBValue, Backend as StateBackend, CodeExecutor, ChangesTrieAnchorBlockId, ExecutionStrategy, ExecutionManager, prove_read, + ChangesTrieRootsStorage, ChangesTrieStorage, key_changes, key_changes_proof, OverlayedChanges }; -use backend::{self, BlockImportOperation}; -use blockchain::{self, Info as ChainInfo, Backend as ChainBackend, HeaderBackend as ChainHeaderBackend}; -use call_executor::{CallExecutor, LocalCallExecutor}; +use crate::backend::{self, BlockImportOperation, PrunableStateChangesTrieStorage}; +use crate::blockchain::{self, Info as ChainInfo, Backend as ChainBackend, HeaderBackend as ChainHeaderBackend}; +use crate::call_executor::{CallExecutor, LocalCallExecutor}; use executor::{RuntimeVersion, RuntimeInfo}; -use notifications::{StorageNotifications, StorageEventStream}; -use {cht, error, in_mem, block_builder, genesis, consensus}; +use crate::notifications::{StorageNotifications, StorageEventStream}; +use crate::light::{call_executor::prove_execution, fetcher::ChangesProof}; +use crate::cht; +use crate::error; +use crate::in_mem; +use crate::block_builder::{self, api::BlockBuilder as BlockBuilderAPI}; +use crate::genesis; +use consensus; +use substrate_telemetry::telemetry; + +use slog::slog_info; +use log::{info, trace, warn}; +use error_chain::bail; /// Type that implements `futures::Stream` of block import events. pub type ImportNotifications = mpsc::UnboundedReceiver>; @@ -54,7 +71,7 @@ pub type ImportNotifications = mpsc::UnboundedReceiver = mpsc::UnboundedReceiver>; /// Substrate Client -pub struct Client where Block: BlockT { +pub struct Client where Block: BlockT { backend: Arc, executor: E, storage_notifications: Mutex>, @@ -64,7 +81,7 @@ pub struct Client where Block: BlockT { importing_block: RwLock>, // holds the block hash currently being imported. TODO: replace this with block queue block_execution_strategy: ExecutionStrategy, api_execution_strategy: ExecutionStrategy, - changes_trie_config: Option, + _phantom: PhantomData, } /// A source of blockchain events. @@ -87,6 +104,9 @@ pub trait BlockchainEvents { pub trait ChainHead { /// Get best block header. fn best_block_header(&self) -> Result<::Header, error::Error>; + /// Get all leaves of the chain: block hashes that have no children currently. + /// Leaves that can never be finalized will not be returned. + fn leaves(&self) -> Result::Hash>, error::Error>; } /// Fetch block body by ID. @@ -131,8 +151,6 @@ pub struct BlockImportNotification { pub header: Block::Header, /// Is this the new best block. pub is_new_best: bool, - /// Tags provided by transactions imported in that block. - pub tags: Vec, } /// Summary of a finalized block. @@ -180,36 +198,36 @@ impl PrePostHeader { } /// Create an instance of in-memory client. -pub fn new_in_mem( +pub fn new_in_mem( executor: E, genesis_storage: S, -) -> error::Result, LocalCallExecutor, E>, Block>> -where - E: CodeExecutor + RuntimeInfo, - S: BuildStorage, - Block: BlockT, +) -> error::Result, LocalCallExecutor, E>, Block, RA>> + where + E: CodeExecutor + RuntimeInfo, + S: BuildStorage, + Block: BlockT, { new_with_backend(Arc::new(in_mem::Backend::new()), executor, genesis_storage) } /// Create a client with the explicitely provided backend. /// This is useful for testing backend implementations. -pub fn new_with_backend( +pub fn new_with_backend( backend: Arc, executor: E, build_genesis_storage: S, -) -> error::Result, Block>> -where - E: CodeExecutor + RuntimeInfo, - S: BuildStorage, - Block: BlockT, - B: backend::LocalBackend +) -> error::Result, Block, RA>> + where + E: CodeExecutor + RuntimeInfo, + S: BuildStorage, + Block: BlockT, + B: backend::LocalBackend { let call_executor = LocalCallExecutor::new(backend.clone(), executor); Client::new(backend, call_executor, build_genesis_storage, ExecutionStrategy::NativeWhenPossible, ExecutionStrategy::NativeWhenPossible) } -impl Client where +impl Client where B: backend::Backend, E: CallExecutor, Block: BlockT, @@ -226,24 +244,17 @@ impl Client where let (genesis_storage, children_genesis_storage) = build_genesis_storage.build_storage()?; let mut op = backend.begin_operation(BlockId::Hash(Default::default()))?; let state_root = op.reset_storage(genesis_storage, children_genesis_storage)?; - let genesis_block = genesis::construct_genesis_block::(state_root.into()); info!("Initialising Genesis block/state (state: {}, header-hash: {})", genesis_block.header().state_root(), genesis_block.header().hash()); op.set_block_data( genesis_block.deconstruct().0, Some(vec![]), None, - ::backend::NewBlockState::Final + crate::backend::NewBlockState::Final )?; backend.commit_operation(op)?; } - // changes trie configuration should never change => we can read it in advance - let changes_trie_config = backend.state_at(BlockId::Number(backend.blockchain().info()?.best_number))? - .storage(well_known_keys::CHANGES_TRIE_CONFIG) - .map_err(|e| error::Error::from_state(Box::new(e)))? - .and_then(|c| Decode::decode(&mut &*c)); - Ok(Client { backend, executor, @@ -254,7 +265,7 @@ impl Client where importing_block: Default::default(), block_execution_strategy, api_execution_strategy, - changes_trie_config, + _phantom: Default::default(), }) } @@ -268,6 +279,12 @@ impl Client where &self.backend } + /// Return storage entry keys in state in a block of given hash with given prefix. + pub fn storage_keys(&self, id: &BlockId, key_prefix: &StorageKey) -> error::Result> { + let keys = self.state_at(id)?.keys(&key_prefix.0).into_iter().map(StorageKey).collect(); + Ok(keys) + } + /// Return single storage entry of contract under given address in state in a block of given hash. pub fn storage(&self, id: &BlockId, key: &StorageKey) -> error::Result> { Ok(self.state_at(id)? @@ -282,12 +299,12 @@ impl Client where } /// Get the set of authorities at a given block. - pub fn authorities_at(&self, id: &BlockId) -> error::Result> { + pub fn authorities_at(&self, id: &BlockId) -> error::Result>> { match self.backend.blockchain().cache().and_then(|cache| cache.authorities_at(*id)) { Some(cached_value) => Ok(cached_value), - None => self.executor.call(id, "authorities",&[]) - .and_then(|r| Vec::::decode(&mut &r.return_data[..]) - .ok_or(error::ErrorKind::InvalidAuthoritiesSet.into())) + None => self.executor.call(id, "Core_authorities", &[]) + .and_then(|r| Vec::>::decode(&mut &r[..]) + .ok_or_else(|| error::ErrorKind::InvalidAuthoritiesSet.into())) } } @@ -315,7 +332,9 @@ impl Client where /// /// No changes are made. pub fn execution_proof(&self, id: &BlockId, method: &str, call_data: &[u8]) -> error::Result<(Vec, Vec>)> { - self.state_at(id).and_then(|state| self.executor.prove_at_state(state, &mut Default::default(), method, call_data)) + let state = self.state_at(id)?; + let header = self.prepare_environment_block(id)?; + prove_execution(state, header, &self.executor, method, call_data) } /// Reads given header and generates CHT-based header proof. @@ -323,46 +342,76 @@ impl Client where self.header_proof_with_cht_size(id, cht::SIZE) } + /// Get block hash by number. + pub fn block_hash(&self, block_number: <::Header as HeaderT>::Number) -> error::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, id: &BlockId, cht_size: u64) -> error::Result<(Block::Header, Vec>)> { let proof_error = || error::ErrorKind::Backend(format!("Failed to generate header proof for {:?}", id)); - let header = self.header(id)?.ok_or_else(|| error::ErrorKind::UnknownBlock(format!("{:?}", id)))?; + let header = self.backend.blockchain().expect_header(*id)?; let block_num = *header.number(); let cht_num = cht::block_to_cht_number(cht_size, block_num).ok_or_else(proof_error)?; let cht_start = cht::start_number(cht_size, cht_num); - let headers = (cht_start.as_()..).map(|num| self.block_hash(As::sa(num)).unwrap_or_default()); - let proof = cht::build_proof::(cht_size, cht_num, block_num, headers) - .ok_or_else(proof_error)?; + let headers = (cht_start.as_()..).map(|num| self.block_hash(As::sa(num))); + let proof = cht::build_proof::(cht_size, cht_num, ::std::iter::once(block_num), headers)?; Ok((header, proof)) } + /// Get longest range within [first; last] that is possible to use in `key_changes` + /// and `key_changes_proof` calls. + /// Range could be shortened from the beginning if some changes tries have been pruned. + /// Returns Ok(None) if changes trues are not supported. + pub fn max_key_changes_range( + &self, + first: NumberFor, + last: BlockId, + ) -> error::Result, BlockId)>> { + let (config, storage) = match self.require_changes_trie().ok() { + Some((config, storage)) => (config, storage), + None => return Ok(None), + }; + let first = first.as_(); + let last_num = self.backend.blockchain().expect_block_number_from_id(&last)?.as_(); + if first > last_num { + return Err(error::ErrorKind::ChangesTrieAccessFailed("Invalid changes trie range".into()).into()); + } + let finalized_number = self.backend.blockchain().info()?.finalized_number; + let oldest = storage.oldest_changes_trie_block(&config, finalized_number.as_()); + let first = As::sa(::std::cmp::max(first, oldest)); + Ok(Some((first, last))) + } + /// Get pairs of (block, extrinsic) where key has been changed at given blocks range. /// Works only for runtimes that are supporting changes tries. pub fn key_changes( &self, - first: Block::Hash, - last: Block::Hash, - key: &[u8] + first: NumberFor, + last: BlockId, + key: &StorageKey ) -> error::Result, u32)>> { - let config = self.changes_trie_config.as_ref(); - let storage = self.backend.changes_trie_storage(); - let (config, storage) = match (config, storage) { - (Some(config), Some(storage)) => (config, storage), - _ => return Err(error::ErrorKind::ChangesTriesNotSupported.into()), - }; + let (config, storage) = self.require_changes_trie()?; + let last_number = self.backend.blockchain().expect_block_number_from_id(&last)?.as_(); + let last_hash = self.backend.blockchain().expect_block_hash_from_id(&last)?; key_changes::<_, Blake2Hasher>( - config, - storage, - self.require_block_number_from_id(&BlockId::Hash(first))?.as_(), - self.require_block_number_from_id(&BlockId::Hash(last))?.as_(), + &config, + &*storage, + first.as_(), + &ChangesTrieAnchorBlockId { + hash: convert_hash(&last_hash), + number: last_number, + }, self.backend.blockchain().info()?.best_number.as_(), - key) + &key.0) + .and_then(|r| r.map(|r| r.map(|(block, tx)| (As::sa(block), tx))).collect::>()) .map_err(|err| error::ErrorKind::ChangesTrieAccessFailed(err).into()) - .map(|r| r.into_iter().map(|(b, e)| (As::sa(b), e)).collect()) } /// Get proof for computation of (block, extrinsic) pairs where key has been changed at given blocks range. + /// `min` is the hash of the first block, which changes trie root is known to the requester - when we're using + /// changes tries from ascendants of this block, we should provide proofs for changes tries roots /// `max` is the hash of the last block known to the requester - we can't use changes tries from descendants /// of this block. /// Works only for runtimes that are supporting changes tries. @@ -370,127 +419,165 @@ impl Client where &self, first: Block::Hash, last: Block::Hash, + min: Block::Hash, max: Block::Hash, - key: &[u8] - ) -> error::Result<(NumberFor, Vec>)> { - let config = self.changes_trie_config.as_ref(); - let storage = self.backend.changes_trie_storage(); - let (config, storage) = match (config, storage) { - (Some(config), Some(storage)) => (config, storage), - _ => return Err(error::ErrorKind::ChangesTriesNotSupported.into()), + key: &StorageKey + ) -> error::Result> { + self.key_changes_proof_with_cht_size( + first, + last, + min, + max, + key, + cht::SIZE, + ) + } + + /// Does the same work as `key_changes_proof`, but assumes that CHTs are of passed size. + pub fn key_changes_proof_with_cht_size( + &self, + first: Block::Hash, + last: Block::Hash, + min: Block::Hash, + max: Block::Hash, + key: &StorageKey, + cht_size: u64, + ) -> error::Result> { + struct AccessedRootsRecorder<'a, Block: BlockT> { + storage: &'a ChangesTrieStorage, + min: u64, + required_roots_proofs: Mutex, H256>>, + }; + + impl<'a, Block: BlockT> ChangesTrieRootsStorage for AccessedRootsRecorder<'a, Block> { + fn root(&self, anchor: &ChangesTrieAnchorBlockId, block: u64) -> Result, String> { + let root = self.storage.root(anchor, block)?; + if block < self.min { + if let Some(ref root) = root { + self.required_roots_proofs.lock().insert( + As::sa(block), + root.clone() + ); + } + } + Ok(root) + } + } + + impl<'a, Block: BlockT> ChangesTrieStorage for AccessedRootsRecorder<'a, Block> { + fn get(&self, key: &H256) -> Result, String> { + self.storage.get(key) + } + } + + let (config, storage) = self.require_changes_trie()?; + let min_number = self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(min))?; + + let recording_storage = AccessedRootsRecorder:: { + storage, + min: min_number.as_(), + required_roots_proofs: Mutex::new(BTreeMap::new()), }; let max_number = ::std::cmp::min( self.backend.blockchain().info()?.best_number, - self.require_block_number_from_id(&BlockId::Hash(max))?, + self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(max))?, ); - key_changes_proof::<_, Blake2Hasher>( - config, - storage, - self.require_block_number_from_id(&BlockId::Hash(first))?.as_(), - self.require_block_number_from_id(&BlockId::Hash(last))?.as_(), - max_number.as_(), - key) - .map_err(|err| error::ErrorKind::ChangesTrieAccessFailed(err).into()) - .map(|proof| (max_number, proof)) - } - /// Create a new block, built on the head of the chain. - pub fn new_block(&self) -> error::Result> - where E: Clone - { - block_builder::BlockBuilder::new(self) - } - - /// Create a new block, built on top of `parent`. - pub fn new_block_at(&self, parent: &BlockId) -> error::Result> - where E: Clone - { - block_builder::BlockBuilder::at_block(parent, &self) + // fetch key changes proof + let first_number = self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(first))?.as_(); + let last_number = self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(last))?.as_(); + let key_changes_proof = key_changes_proof::<_, Blake2Hasher>( + &config, + &recording_storage, + first_number, + &ChangesTrieAnchorBlockId { + hash: convert_hash(&last), + number: last_number, + }, + max_number.as_(), + &key.0 + ) + .map_err(|err| error::Error::from(error::ErrorKind::ChangesTrieAccessFailed(err)))?; + + // now gather proofs for all changes tries roots that were touched during key_changes_proof + // execution AND are unknown (i.e. replaced with CHT) to the requester + let roots = recording_storage.required_roots_proofs.into_inner(); + let roots_proof = self.changes_trie_roots_proof(cht_size, roots.keys().cloned())?; + + Ok(ChangesProof { + max_block: max_number, + proof: key_changes_proof, + roots: roots.into_iter().map(|(n, h)| (n, convert_hash(&h))).collect(), + roots_proof, + }) } - /// Set up the native execution environment to call into a native runtime code. - pub fn call_api(&self, function: &'static str, args: &A) -> error::Result - where A: Encode, R: Decode - { - self.call_api_at(&BlockId::Number(self.info()?.chain.best_number), function, args) - } + /// Generate CHT-based proof for roots of changes tries at given blocks. + fn changes_trie_roots_proof>>( + &self, + cht_size: u64, + blocks: I + ) -> error::Result>> { + // most probably we have touched several changes tries that are parts of the single CHT + // => GroupBy changes tries by CHT number and then gather proof for the whole group at once + let mut proof = HashSet::new(); - /// Call a runtime function at given block. - pub fn call_api_at(&self, at: &BlockId, function: &'static str, args: &A) -> error::Result - where A: Encode, R: Decode - { - let parent = at; - let header = <::Header as HeaderT>::new( - self.block_number_from_id(&parent)? - .ok_or_else(|| error::ErrorKind::UnknownBlock(format!("{:?}", parent)))? + As::sa(1), - Default::default(), - Default::default(), - self.block_hash_from_id(&parent)? - .ok_or_else(|| error::ErrorKind::UnknownBlock(format!("{:?}", parent)))?, - Default::default() - ); - let mut overlay = Default::default(); + cht::for_each_cht_group::(cht_size, blocks, |_, cht_num, cht_blocks| { + let cht_proof = self.changes_trie_roots_proof_at_cht(cht_size, cht_num, cht_blocks)?; + proof.extend(cht_proof); + Ok(()) + }, ())?; - self.call_at_state(at, "initialise_block", &header, &mut overlay)?; - self.call_at_state(at, function, args, &mut overlay) + Ok(proof.into_iter().collect()) } - fn call_at_state( + /// Generates CHT-based proof for roots of changes tries at given blocks (that are part of single CHT). + fn changes_trie_roots_proof_at_cht( &self, - at: &BlockId, - function: &'static str, - args: &A, - changes: &mut OverlayedChanges - ) -> error::Result { - let state = self.state_at(at)?; - - let execution_manager = || match self.api_execution_strategy { - ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible, - ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm, - ExecutionStrategy::Both => ExecutionManager::Both(|wasm_result, native_result| { - warn!("Consensus error between wasm and native runtime execution at block {:?}", at); - warn!(" Function {:?}", function); - warn!(" Native result {:?}", native_result); - warn!(" Wasm result {:?}", wasm_result); - wasm_result - }), - }; + cht_size: u64, + cht_num: NumberFor, + blocks: Vec> + ) -> error::Result>> { + let cht_start = cht::start_number(cht_size, cht_num); + let roots = (cht_start.as_()..).map(|num| self.header(&BlockId::Number(As::sa(num))) + .map(|block| block.and_then(|block| block.digest().log(DigestItem::as_changes_trie_root).cloned()))); + let proof = cht::build_proof::(cht_size, cht_num, blocks, roots)?; + Ok(proof) + } - self.executor.call_at_state( - &state, - changes, - function, - &args.encode(), - execution_manager() - ).and_then(|res| - R::decode(&mut &res.0[..]) - .ok_or_else(|| Error::from(ErrorKind::CallResultDecode(function))) - ) + /// Returns changes trie configuration and storage or an error if it is not supported. + fn require_changes_trie(&self) -> error::Result<(ChangesTrieConfiguration, &B::ChangesTrieStorage)> { + let config = self.changes_trie_config()?; + let storage = self.backend.changes_trie_storage(); + match (config, storage) { + (Some(config), Some(storage)) => Ok((config, storage)), + _ => Err(error::ErrorKind::ChangesTriesNotSupported.into()), + } } - // TODO [ToDr] Optimize and re-use tags from the pool. - fn transaction_tags(&self, at: Block::Hash, body: &Option>) -> error::Result> { - let id = BlockId::Hash(at); - Ok(match body { - None => vec![], - Some(ref extrinsics) => { - let mut tags = vec![]; - for tx in extrinsics { - let tx = api::TaggedTransactionQueue::validate_transaction(self, &id, &tx)?; - match tx { - TransactionValidity::Valid { mut provides, .. } => { - tags.append(&mut provides); - }, - // silently ignore invalid extrinsics, - // cause they might just be inherent - _ => {} - } + /// Create a new block, built on the head of the chain. + pub fn new_block( + &self + ) -> error::Result> where + E: Clone + Send + Sync, + RA: Send + Sync, + Self: ProvideRuntimeApi, + ::Api: BlockBuilderAPI + { + block_builder::BlockBuilder::new(self) + } - } - tags - }, - }) + /// Create a new block, built on top of `parent`. + pub fn new_block_at( + &self, parent: &BlockId + ) -> error::Result> where + E: Clone + Send + Sync, + RA: Send + Sync, + Self: ProvideRuntimeApi, + ::Api: BlockBuilderAPI + { + block_builder::BlockBuilder::at_block(parent, &self) } fn execute_and_import_block( @@ -498,11 +585,15 @@ impl Client where origin: BlockOrigin, hash: Block::Hash, import_headers: PrePostHeader, - justification: Justification, + justification: Option, body: Option>, - authorities: Option>, + authorities: Option>>, finalized: bool, - ) -> error::Result { + aux: Vec<(Vec, Option>)>, + fork_choice: ForkChoiceStrategy, + ) -> error::Result where + E: CallExecutor + Send + Sync + Clone, + { let parent_hash = import_headers.post().parent_hash().clone(); match self.backend.blockchain().status(BlockId::Hash(hash))? { blockchain::BlockStatus::InChain => return Ok(ImportResult::AlreadyInChain), @@ -525,18 +616,17 @@ impl Client where // ensure parent block is finalized to maintain invariant that // finality is called sequentially. if finalized { - self.apply_finality(parent_hash, last_best, make_notifications)?; + self.apply_finality(parent_hash, None, last_best, make_notifications)?; } - let tags = self.transaction_tags(parent_hash, &body)?; let mut transaction = self.backend.begin_operation(BlockId::Hash(parent_hash))?; let (storage_update, changes_update, storage_changes) = match transaction.state()? { Some(transaction_state) => { let mut overlay = Default::default(); - let mut r = self.executor.call_at_state( + let r = self.executor.call_at_state::<_, _, NeverNativeValue, fn() -> NeverNativeValue>( transaction_state, &mut overlay, - "execute_block", + "Core_execute_block", &::new(import_headers.pre().clone(), body.clone().unwrap_or_default()).encode(), match (origin, self.block_execution_strategy) { (BlockOrigin::NetworkInitialSync, _) | (_, ExecutionStrategy::NativeWhenPossible) => @@ -556,22 +646,26 @@ impl Client where wasm_result }), }, + None, ); let (_, storage_update, changes_update) = r?; overlay.commit_prospective(); - (Some(storage_update), Some(changes_update), Some(overlay.into_committed())) + (Some(storage_update), Some(changes_update), Some(overlay.into_committed().collect())) }, None => (None, None, None) }; // TODO: non longest-chain rule. - let is_new_best = finalized || import_headers.post().number() > &last_best_number; + let is_new_best = finalized || match fork_choice { + ForkChoiceStrategy::LongestChain => import_headers.post().number() > &last_best_number, + ForkChoiceStrategy::Custom(v) => v, + }; let leaf_state = if finalized { - ::backend::NewBlockState::Final + crate::backend::NewBlockState::Final } else if is_new_best { - ::backend::NewBlockState::Best + crate::backend::NewBlockState::Best } else { - ::backend::NewBlockState::Normal + crate::backend::NewBlockState::Normal }; trace!("Imported {}, (#{}), best={}, origin={:?}", hash, import_headers.post().number(), is_new_best, origin); @@ -579,7 +673,7 @@ impl Client where transaction.set_block_data( import_headers.post().clone(), body, - Some(justification), + justification, leaf_state, )?; @@ -587,18 +681,23 @@ impl Client where transaction.update_authorities(authorities); } if let Some(storage_update) = storage_update { - transaction.update_storage(storage_update)?; + transaction.update_db_storage(storage_update)?; + } + if let Some(storage_changes) = storage_changes.clone() { + transaction.update_storage(storage_changes)?; } if let Some(Some(changes_update)) = changes_update { transaction.update_changes_trie(changes_update)?; } + + transaction.set_aux(aux)?; self.backend.commit_operation(transaction)?; if make_notifications { if let Some(storage_changes) = storage_changes { // TODO [ToDr] How to handle re-orgs? Should we re-emit all storage changes? self.storage_notifications.lock() - .trigger(&hash, storage_changes); + .trigger(&hash, storage_changes.into_iter()); } if finalized { @@ -616,7 +715,6 @@ impl Client where origin, header: import_headers.into_post(), is_new_best, - tags, }; self.import_notification_sinks.lock() @@ -626,13 +724,25 @@ impl Client where Ok(ImportResult::Queued) } - /// Finalizes all blocks up to given. - fn apply_finality(&self, block: Block::Hash, best_block: Block::Hash, notify: bool) -> error::Result<()> { + /// Finalizes all blocks up to given. If a justification is provided it is + /// stored with the given finalized block (any other finalized blocks are + /// left unjustified). + fn apply_finality( + &self, + block: Block::Hash, + justification: Option, + best_block: Block::Hash, + notify: bool, + ) -> error::Result<()> { // find tree route from last finalized to given block. let last_finalized = self.backend.blockchain().last_finalized()?; - if block == last_finalized { return Ok(()) } - let route_from_finalized = ::blockchain::tree_route( + if block == last_finalized { + warn!("Possible safety violation: attempted to re-finalize last finalized block {:?} ", last_finalized); + return Ok(()); + } + + let route_from_finalized = crate::blockchain::tree_route( self.backend.blockchain(), BlockId::Hash(last_finalized), BlockId::Hash(block), @@ -645,7 +755,7 @@ impl Client where bail!(error::ErrorKind::NotInFinalizedChain); } - let route_from_best = ::blockchain::tree_route( + let route_from_best = crate::blockchain::tree_route( self.backend.blockchain(), BlockId::Hash(best_block), BlockId::Hash(block), @@ -658,10 +768,15 @@ impl Client where // `block`. } - for finalize_new in route_from_finalized.enacted() { - self.backend.finalize_block(BlockId::Hash(finalize_new.hash))?; + let enacted = route_from_finalized.enacted(); + assert!(enacted.len() > 0); + for finalize_new in &enacted[..enacted.len() - 1] { + self.backend.finalize_block(BlockId::Hash(finalize_new.hash), None)?; } + assert_eq!(enacted.last().map(|e| e.hash), Some(block)); + self.backend.finalize_block(BlockId::Hash(block), justification)?; + if notify { // sometimes when syncing, tons of blocks can be finalized at once. // we'll send notifications spuriously in that case. @@ -690,15 +805,10 @@ impl Client where /// Pass a flag to indicate whether finality notifications should be propagated. /// This is usually tied to some synchronization state, where we don't send notifications /// while performing major synchronization work. - pub fn finalize_block(&self, id: BlockId, notify: bool) -> error::Result<()> { + pub fn finalize_block(&self, id: BlockId, justification: Option, notify: bool) -> error::Result<()> { let last_best = self.backend.blockchain().info()?.best_hash; - let to_finalize_hash = match id { - BlockId::Hash(h) => h, - BlockId::Number(n) => self.backend.blockchain().hash(n)? - .ok_or_else(|| error::ErrorKind::UnknownBlock(format!("No block with number {:?}", n)))?, - }; - - self.apply_finality(to_finalize_hash, last_best, notify) + let to_finalize_hash = self.backend.blockchain().expect_block_hash_from_id(&id)?; + self.apply_finality(to_finalize_hash, justification, last_best, notify) } /// Attempts to revert the chain by `n` blocks. Returns the number of blocks that were @@ -731,33 +841,6 @@ impl Client where } } - /// Get block hash by number. - pub fn block_hash(&self, block_number: <::Header as HeaderT>::Number) -> error::Result> { - self.backend.blockchain().hash(block_number) - } - - /// Convert an arbitrary block ID into a block hash. - pub fn block_hash_from_id(&self, id: &BlockId) -> error::Result> { - match *id { - BlockId::Hash(h) => Ok(Some(h)), - BlockId::Number(n) => self.block_hash(n), - } - } - - /// Convert an arbitrary block ID into a block hash. - pub fn block_number_from_id(&self, id: &BlockId) -> error::Result>> { - match *id { - BlockId::Hash(_) => Ok(self.header(id)?.map(|h| h.number().clone())), - BlockId::Number(n) => Ok(Some(n)), - } - } - - /// Convert an arbitrary block ID into a block hash, returning error if the block is unknown. - fn require_block_number_from_id(&self, id: &BlockId) -> error::Result> { - self.block_number_from_id(id) - .and_then(|n| n.ok_or_else(|| error::ErrorKind::UnknownBlock(format!("{}", id)).into())) - } - /// Get block header by id. pub fn header(&self, id: &BlockId) -> error::Result::Header>> { self.backend.blockchain().header(*id) @@ -775,11 +858,11 @@ impl Client where /// Get full block by id. pub fn block(&self, id: &BlockId) - -> error::Result>> + -> error::Result>> { Ok(match (self.header(id)?, self.body(id)?, self.justification(id)?) { - (Some(header), Some(extrinsics), Some(justification)) => - Some(SignedBlock { block: RuntimeBlock { header, extrinsics }, justification }), + (Some(header), Some(extrinsics), justification) => + Some(SignedBlock { block: Block::new(header, extrinsics), justification }), _ => None, }) } @@ -798,7 +881,9 @@ impl Client where /// TODO [snd] possibly implement this on blockchain::Backend and just redirect here /// Returns `Ok(None)` if `target_hash` is not found in search space. /// TODO [snd] write down time complexity - pub fn best_containing(&self, target_hash: Block::Hash, maybe_max_number: Option>) -> error::Result> { + pub fn best_containing(&self, target_hash: Block::Hash, maybe_max_number: Option>) + -> error::Result> + { let target_header = { match self.backend.blockchain().header(BlockId::Hash(target_hash))? { Some(x) => x, @@ -826,12 +911,14 @@ impl Client where .ok_or_else(|| error::Error::from(format!("failed to get hash for block number {}", target_header.number())))?; if canon_hash == target_hash { + // if no block at the given max depth exists fallback to the best block if let Some(max_number) = maybe_max_number { - // something has to guarantee that max_number is in chain - return Ok(Some(self.backend.blockchain().hash(max_number)?.ok_or_else(|| error::Error::from(format!("failed to get hash for block number {}", max_number)))?)); - } else { - return Ok(Some(info.best_hash)); + if let Some(header) = self.backend.blockchain().hash(max_number)? { + return Ok(Some(header)); + } } + + return Ok(Some(info.best_hash)); } (self.backend.blockchain().leaves()?, info.best_hash) }; @@ -888,45 +975,152 @@ impl Client where unreachable!("this is a bug. `target_hash` is in blockchain but wasn't found following all leaves backwards"); } + + fn changes_trie_config(&self) -> Result, Error> { + Ok(self.backend.state_at(BlockId::Number(self.backend.blockchain().info()?.best_number))? + .storage(well_known_keys::CHANGES_TRIE_CONFIG) + .map_err(|e| error::Error::from_state(Box::new(e)))? + .and_then(|c| Decode::decode(&mut &*c))) + } + + /// Prepare in-memory header that is used in execution environment. + fn prepare_environment_block(&self, parent: &BlockId) -> error::Result { + Ok(<::Header as HeaderT>::new( + self.backend.blockchain().expect_block_number_from_id(parent)? + As::sa(1), + Default::default(), + Default::default(), + self.backend.blockchain().expect_block_hash_from_id(&parent)?, + Default::default(), + )) + } } +impl ChainHeaderBackend for Client where + B: backend::Backend, + E: CallExecutor + Send + Sync, + Block: BlockT, + RA: Send + Sync +{ + fn header(&self, id: BlockId) -> error::Result> { + self.backend.blockchain().header(id) + } + + fn info(&self) -> error::Result> { + self.backend.blockchain().info() + } -impl consensus::BlockImport for Client where + fn status(&self, id: BlockId) -> error::Result { + self.backend.blockchain().status(id) + } + + fn number(&self, hash: Block::Hash) -> error::Result::Header as HeaderT>::Number>> { + self.backend.blockchain().number(hash) + } + + fn hash(&self, number: NumberFor) -> error::Result> { + self.backend.blockchain().hash(number) + } +} + +impl ProvideRuntimeApi for Client where B: backend::Backend, - E: CallExecutor + Clone, + E: CallExecutor + Clone + Send + Sync, Block: BlockT, + RA: ConstructRuntimeApi { - type Error = Error; + type Api = >::RuntimeApi; - /// Import a checked and validated block + fn runtime_api<'a>(&'a self) -> ApiRef<'a, Self::Api> { + RA::construct_runtime_api(self) + } +} + +impl CallRuntimeAt for Client where + B: backend::Backend, + E: CallExecutor + Clone + Send + Sync, + Block: BlockT +{ + fn call_api_at R + UnwindSafe>( + &self, + at: &BlockId, + function: &'static str, + args: Vec, + changes: &mut OverlayedChanges, + initialised_block: &mut Option>, + native_call: Option, + ) -> error::Result> { + let execution_manager = match self.api_execution_strategy { + ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible, + ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm, + ExecutionStrategy::Both => ExecutionManager::Both(|wasm_result, native_result| { + warn!("Consensus error between wasm and native runtime execution at block {:?}", at); + warn!(" Function {:?}", function); + warn!(" Native result {:?}", native_result); + warn!(" Wasm result {:?}", wasm_result); + wasm_result + }), + }; + + self.executor.contextual_call( + at, + function, + &args, + changes, + initialised_block, + || self.prepare_environment_block(at), + execution_manager, + native_call, + ) + } + + fn runtime_version_at(&self, at: &BlockId) -> error::Result { + self.runtime_version_at(at) + } +} + + +impl consensus::BlockImport for Client where + B: backend::Backend, + E: CallExecutor + Clone + Send + Sync, + Block: BlockT, +{ + type Error = ConsensusError; + + /// Import a checked and validated block. If a justification is provided in + /// `ImportBlock` then `finalized` *must* be true. fn import_block( &self, import_block: ImportBlock, - new_authorities: Option>, + new_authorities: Option>>, ) -> Result { use runtime_primitives::traits::Digest; let ImportBlock { origin, header, - external_justification, - post_runtime_digests, + justification, + post_digests, body, finalized, - .. + auxiliary, + fork_choice, } = import_block; + + assert!(justification.is_some() && finalized || justification.is_none()); + let parent_hash = header.parent_hash().clone(); - match self.backend.blockchain().status(BlockId::Hash(parent_hash))? { - blockchain::BlockStatus::InChain => {}, - blockchain::BlockStatus::Unknown => return Ok(ImportResult::UnknownParent), + match self.backend.blockchain().status(BlockId::Hash(parent_hash)) { + Ok(blockchain::BlockStatus::InChain) => {}, + Ok(blockchain::BlockStatus::Unknown) => return Ok(ImportResult::UnknownParent), + Err(e) => return Err(ConsensusErrorKind::ClientImport(e.to_string()).into()), } - let import_headers = if post_runtime_digests.is_empty() { + let import_headers = if post_digests.is_empty() { PrePostHeader::Same(header) } else { let mut post_header = header.clone(); - for item in post_runtime_digests { + for item in post_digests { post_header.digest_mut().push(item); } PrePostHeader::Different(header, post_header) @@ -941,10 +1135,12 @@ impl consensus::BlockImport for Client where origin, hash, import_headers, - external_justification, + justification, body, new_authorities, finalized, + auxiliary, + fork_choice, ); *self.importing_block.write() = None; @@ -953,22 +1149,35 @@ impl consensus::BlockImport for Client where "best" => ?hash, "origin" => ?origin ); - result.map_err(|e| e.into()) + result.map_err(|e| ConsensusErrorKind::ClientImport(e.to_string()).into()) + } + + /// Import a block justification and finalize the block. The justification + /// isn't interpreted by the client and is assumed to have been validated + /// previously. The block is finalized unconditionally. + fn import_justification( + &self, + hash: Block::Hash, + _number: NumberFor, + justification: Justification, + ) -> Result<(), Self::Error> { + self.finalize_block(BlockId::Hash(hash), Some(justification), true) + .map_err(|_| ConsensusErrorKind::InvalidJustification.into()) } } -impl consensus::Authorities for Client where +impl consensus::Authorities for Client where B: backend::Backend, E: CallExecutor + Clone, Block: BlockT, { type Error = Error; - fn authorities(&self, at: &BlockId) -> Result, Self::Error> { + fn authorities(&self, at: &BlockId) -> Result>, Self::Error> { self.authorities_at(at).map_err(|e| e.into()) } } -impl CurrentHeight for Client where +impl CurrentHeight for Client where B: backend::Backend, E: CallExecutor + Clone, Block: BlockT, @@ -979,7 +1188,7 @@ impl CurrentHeight for Client where } } -impl BlockNumberToHash for Client where +impl BlockNumberToHash for Client where B: backend::Backend, E: CallExecutor + Clone, Block: BlockT, @@ -992,7 +1201,7 @@ impl BlockNumberToHash for Client where } -impl BlockchainEvents for Client +impl BlockchainEvents for Client where E: CallExecutor, Block: BlockT, @@ -1016,7 +1225,7 @@ where } } -impl ChainHead for Client +impl ChainHead for Client where B: backend::Backend, E: CallExecutor, @@ -1025,138 +1234,64 @@ where fn best_block_header(&self) -> error::Result<::Header> { Client::best_block_header(self) } -} - -impl BlockBody for Client where - B: backend::Backend, - E: CallExecutor, - Block: BlockT, -{ - fn block_body(&self, id: &BlockId) -> error::Result::Extrinsic>>> { - self.body(id) - } -} - -impl api::Core for Client where - B: backend::Backend, - E: CallExecutor, - Block: BlockT, -{ - type Error = Error; - - fn version(&self, at: &BlockId) -> Result { - self.call_api_at(at, "version", &()) - } - - fn authorities(&self, at: &BlockId) -> Result, Self::Error> { - self.authorities_at(at) - } - fn execute_block(&self, at: &BlockId, block: &Block) -> Result<(), Self::Error> { - self.call_api_at(at, "execute_block", &(block)) + fn leaves(&self) -> Result::Hash>, error::Error> { + self.backend.blockchain().leaves() } } -impl api::Metadata> for Client where - B: backend::Backend, - E: CallExecutor, - Block: BlockT, +impl BlockBody for Client + where + B: backend::Backend, + E: CallExecutor, + Block: BlockT, { - type Error = Error; - - fn metadata(&self, at: &BlockId) -> Result, Self::Error> { - self.executor.call(at, "metadata",&[]).map(|v| v.return_data) - } -} - -impl api::BlockBuilder for Client where - B: backend::Backend, - E: CallExecutor, - Block: BlockT, -{ - type Error = Error; - type OverlayedChanges = OverlayedChanges; - - fn initialise_block( - &self, - at: &BlockId, - changes: &mut OverlayedChanges, - header: &::Header - ) -> Result<(), Self::Error> { - self.call_at_state(at, "initialise_block", header, changes) - } - - fn apply_extrinsic( - &self, - at: &BlockId, - changes: &mut OverlayedChanges, - extrinsic: &::Extrinsic - ) -> Result { - self.call_at_state(at, "apply_extrinsic", extrinsic, changes) - } - - fn finalise_block( - &self, - at: &BlockId, - changes: &mut OverlayedChanges - ) -> Result<::Header, Self::Error> { - self.call_at_state(at, "finalise_block", &(), changes) - } - - fn inherent_extrinsics( - &self, at: &BlockId, inherent: &InherentExtrinsic - ) -> Result, Self::Error> { - self.call_api_at(at, "inherent_extrinsics", &(inherent)) - } - - fn check_inherents( - &self, - at: &BlockId, - block: &Block, - data: &InherentData - ) -> Result, Self::Error> { - self.call_api_at(at, "check_inherents", &(block, data)) - } - - fn random_seed(&self, at: &BlockId) -> Result<::Hash, Self::Error> { - self.call_api_at(at, "random_seed", &()) + fn block_body(&self, id: &BlockId) -> error::Result::Extrinsic>>> { + self.body(id) } } -impl api::TaggedTransactionQueue for Client where - B: backend::Backend, - E: CallExecutor, - Block: BlockT, +impl backend::AuxStore for Client + where + B: backend::Backend, + E: CallExecutor, + Block: BlockT, { - type Error = Error; - - fn validate_transaction( - &self, at: &BlockId, tx: &::Extrinsic - ) -> Result { - self.call_api_at(at, "validate_transaction", &(tx)) + /// Insert auxiliary data into key-value store. + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >(&self, insert: I, delete: D) -> error::Result<()> { + crate::backend::AuxStore::insert_aux(&*self.backend, insert, delete) + } + /// Query auxiliary data from key-value store. + fn get_aux(&self, key: &[u8]) -> error::Result>> { + crate::backend::AuxStore::get_aux(&*self.backend, key) } } - #[cfg(test)] pub(crate) mod tests { use std::collections::HashMap; use super::*; use keyring::Keyring; use primitives::twox_128; - use runtime_primitives::traits::{Digest as DigestT, DigestItem as DigestItemT}; + use runtime_primitives::traits::DigestItem as DigestItemT; use runtime_primitives::generic::DigestItem; use test_client::{self, TestClient}; use consensus::BlockOrigin; - use test_client::client::backend::Backend as TestBackend; + use test_client::client::{backend::Backend as TestBackend, runtime_api::ApiExt}; use test_client::BlockBuilderExt; - use test_client::runtime::{self, Block, Transfer}; + use test_client::runtime::{self, Block, Transfer, RuntimeApi, TestAPI}; /// Returns tuple, consisting of: /// 1) test client pre-filled with blocks changing balances; /// 2) roots of changes tries for these blocks /// 3) test cases in form (begin, end, key, vec![(block, extrinsic)]) that are required to pass pub fn prepare_client_with_key_changes() -> ( - test_client::client::Client, + test_client::client::Client, Vec, Vec<(u64, u64, Vec, Vec<(u64, u32)>)>, ) { @@ -1182,7 +1317,7 @@ pub(crate) mod tests { nonce: *nonces.entry(from).and_modify(|n| { *n = *n + 1 }).or_default(), }).unwrap(); } - remote_client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + remote_client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); let header = remote_client.header(&BlockId::Number(i as u64 + 1)).unwrap().unwrap(); let trie_root = header.digest().log(DigestItem::as_changes_trie_root) @@ -1228,8 +1363,31 @@ pub(crate) mod tests { fn client_initialises_from_genesis_ok() { let client = test_client::new(); - assert_eq!(client.call_api::<_, u64>("balance_of", &Keyring::Alice.to_raw_public()).unwrap(), 1000); - assert_eq!(client.call_api::<_, u64>("balance_of", &Keyring::Ferdie.to_raw_public()).unwrap(), 0); + assert_eq!( + client.runtime_api().balance_of( + &BlockId::Number(client.info().unwrap().chain.best_number), + Keyring::Alice.to_raw_public().into() + ).unwrap(), + 1000 + ); + assert_eq!( + client.runtime_api().balance_of( + &BlockId::Number(client.info().unwrap().chain.best_number), + Keyring::Ferdie.to_raw_public().into() + ).unwrap(), + 0 + ); + } + + #[test] + fn runtime_api_has_test_api() { + let client = test_client::new(); + + assert!( + client.runtime_api().has_api::>( + &BlockId::Number(client.info().unwrap().chain.best_number), + ).unwrap() + ); } #[test] @@ -1250,7 +1408,7 @@ pub(crate) mod tests { let builder = client.new_block().unwrap(); - client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); assert_eq!(client.info().unwrap().chain.best_number, 1); } @@ -1268,12 +1426,24 @@ pub(crate) mod tests { nonce: 0, }).unwrap(); - client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); assert_eq!(client.info().unwrap().chain.best_number, 1); assert!(client.state_at(&BlockId::Number(1)).unwrap() != client.state_at(&BlockId::Number(0)).unwrap()); - assert_eq!(client.call_api::<_, u64>("balance_of", &Keyring::Alice.to_raw_public()).unwrap(), 958); - assert_eq!(client.call_api::<_, u64>("balance_of", &Keyring::Ferdie.to_raw_public()).unwrap(), 42); + assert_eq!( + client.runtime_api().balance_of( + &BlockId::Number(client.info().unwrap().chain.best_number), + Keyring::Alice.to_raw_public().into() + ).unwrap(), + 958 + ); + assert_eq!( + client.runtime_api().balance_of( + &BlockId::Number(client.info().unwrap().chain.best_number), + Keyring::Ferdie.to_raw_public().into() + ).unwrap(), + 42 + ); } #[test] @@ -1308,7 +1478,7 @@ pub(crate) mod tests { nonce: 0, }).is_err()); - client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); assert_eq!(client.info().unwrap().chain.best_number, 1); assert!(client.state_at(&BlockId::Number(1)).unwrap() != client.state_at(&BlockId::Number(0)).unwrap()); @@ -1348,11 +1518,11 @@ pub(crate) mod tests { // G -> A1 let a1 = client.new_block().unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a1.clone()).unwrap(); + client.import(BlockOrigin::Own, a1.clone()).unwrap(); // A1 -> A2 let a2 = client.new_block().unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a2.clone()).unwrap(); + client.import(BlockOrigin::Own, a2.clone()).unwrap(); let genesis_hash = client.info().unwrap().chain.genesis_hash; @@ -1377,23 +1547,23 @@ pub(crate) mod tests { // G -> A1 let a1 = client.new_block().unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a1.clone()).unwrap(); + client.import(BlockOrigin::Own, a1.clone()).unwrap(); // A1 -> A2 let a2 = client.new_block_at(&BlockId::Hash(a1.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a2.clone()).unwrap(); + client.import(BlockOrigin::Own, a2.clone()).unwrap(); // A2 -> A3 let a3 = client.new_block_at(&BlockId::Hash(a2.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a3.clone()).unwrap(); + client.import(BlockOrigin::Own, a3.clone()).unwrap(); // A3 -> A4 let a4 = client.new_block_at(&BlockId::Hash(a3.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a4.clone()).unwrap(); + client.import(BlockOrigin::Own, a4.clone()).unwrap(); // A4 -> A5 let a5 = client.new_block_at(&BlockId::Hash(a4.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a5.clone()).unwrap(); + client.import(BlockOrigin::Own, a5.clone()).unwrap(); // A1 -> B2 let mut builder = client.new_block_at(&BlockId::Hash(a1.hash())).unwrap(); @@ -1405,15 +1575,15 @@ pub(crate) mod tests { nonce: 0, }).unwrap(); let b2 = builder.bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, b2.clone()).unwrap(); + client.import(BlockOrigin::Own, b2.clone()).unwrap(); // B2 -> B3 let b3 = client.new_block_at(&BlockId::Hash(b2.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, b3.clone()).unwrap(); + client.import(BlockOrigin::Own, b3.clone()).unwrap(); // B3 -> B4 let b4 = client.new_block_at(&BlockId::Hash(b3.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, b4.clone()).unwrap(); + client.import(BlockOrigin::Own, b4.clone()).unwrap(); // // B2 -> C3 let mut builder = client.new_block_at(&BlockId::Hash(b2.hash())).unwrap(); @@ -1425,7 +1595,7 @@ pub(crate) mod tests { nonce: 1, }).unwrap(); let c3 = builder.bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, c3.clone()).unwrap(); + client.import(BlockOrigin::Own, c3.clone()).unwrap(); // A1 -> D2 let mut builder = client.new_block_at(&BlockId::Hash(a1.hash())).unwrap(); @@ -1437,7 +1607,7 @@ pub(crate) mod tests { nonce: 0, }).unwrap(); let d2 = builder.bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, d2.clone()).unwrap(); + client.import(BlockOrigin::Own, d2.clone()).unwrap(); assert_eq!(client.info().unwrap().chain.best_hash, a5.hash()); @@ -1575,14 +1745,33 @@ pub(crate) mod tests { assert_eq!(None, client.best_containing(d2.hash().clone(), Some(0)).unwrap()); } + #[test] + fn best_containing_with_max_depth_higher_than_best() { + // block tree: + // G -> A1 -> A2 + + let client = test_client::new(); + + // G -> A1 + let a1 = client.new_block().unwrap().bake().unwrap(); + client.import(BlockOrigin::Own, a1.clone()).unwrap(); + + // A1 -> A2 + let a2 = client.new_block().unwrap().bake().unwrap(); + client.import(BlockOrigin::Own, a2.clone()).unwrap(); + + let genesis_hash = client.info().unwrap().chain.genesis_hash; + + assert_eq!(a2.hash(), client.best_containing(genesis_hash, Some(10)).unwrap().unwrap()); + } + #[test] fn key_changes_works() { let (client, _, test_cases) = prepare_client_with_key_changes(); for (index, (begin, end, key, expected_result)) in test_cases.into_iter().enumerate() { - let begin = client.block_hash(begin).unwrap().unwrap(); let end = client.block_hash(end).unwrap().unwrap(); - let actual_result = client.key_changes(begin, end, &key).unwrap(); + let actual_result = client.key_changes(begin, BlockId::Hash(end), &StorageKey(key)).unwrap(); match actual_result == expected_result { true => (), false => panic!(format!("Failed test {}: actual = {:?}, expected = {:?}", @@ -1590,4 +1779,44 @@ pub(crate) mod tests { } } } + + #[test] + fn import_with_justification() { + use test_client::blockchain::Backend; + + let client = test_client::new(); + + // G -> A1 + let a1 = client.new_block().unwrap().bake().unwrap(); + client.import(BlockOrigin::Own, a1.clone()).unwrap(); + + // A1 -> A2 + let a2 = client.new_block_at(&BlockId::Hash(a1.hash())).unwrap().bake().unwrap(); + client.import(BlockOrigin::Own, a2.clone()).unwrap(); + + // A2 -> A3 + let justification = vec![1, 2, 3]; + let a3 = client.new_block_at(&BlockId::Hash(a2.hash())).unwrap().bake().unwrap(); + client.import_justified(BlockOrigin::Own, a3.clone(), justification.clone()).unwrap(); + + assert_eq!( + client.backend().blockchain().last_finalized().unwrap(), + a3.hash(), + ); + + assert_eq!( + client.backend().blockchain().justification(BlockId::Hash(a3.hash())).unwrap(), + Some(justification), + ); + + assert_eq!( + client.backend().blockchain().justification(BlockId::Hash(a1.hash())).unwrap(), + None, + ); + + assert_eq!( + client.backend().blockchain().justification(BlockId::Hash(a2.hash())).unwrap(), + None, + ); + } } diff --git a/core/client/src/error.rs b/core/client/src/error.rs index aa09344c9980c1a0fea6438f28e735dc431dad87..b4ed76508480b47c34a8f5db1380a11c3fde05ab 100644 --- a/core/client/src/error.rs +++ b/core/client/src/error.rs @@ -22,6 +22,7 @@ use std; use state_machine; use runtime_primitives::ApplyError; use consensus; +use error_chain::*; error_chain! { links { @@ -88,8 +89,8 @@ error_chain! { display("This method is not currently available when running in light client mode"), } - /// Invalid remote header proof. - InvalidHeaderProof { + /// Invalid remote CHT-based proof. + InvalidCHTProof { description("invalid header proof"), display("Remote node has responded with invalid header proof"), } @@ -135,6 +136,12 @@ error_chain! { description("Potential long-range attack: block not in finalized chain."), display("Potential long-range attack: block not in finalized chain."), } + + /// Hash that is required for building CHT is missing. + MissingHashRequiredForCHT(cht_num: u64, block_number: u64) { + description("missed hash required for building CHT"), + display("Failed to get hash of block#{} for building CHT#{}", block_number, cht_num), + } } } diff --git a/core/client/src/genesis.rs b/core/client/src/genesis.rs index 83c4338b8b7d7f236c01e94dbdbfbca5b0e8ba92..468d7137db724d6bab26f3a41701d1d9cb323c17 100644 --- a/core/client/src/genesis.rs +++ b/core/client/src/genesis.rs @@ -42,18 +42,18 @@ mod tests { use super::*; use codec::{Encode, Decode, Joiner}; use keyring::Keyring; - use executor::NativeExecutionDispatch; + use executor::{NativeExecutionDispatch, native_executor_instance}; use state_machine::{execute, OverlayedChanges, ExecutionStrategy, InMemoryChangesTrieStorage}; use state_machine::backend::InMemory; - use test_client; use test_client::runtime::genesismap::{GenesisConfig, additional_storage_with_genesis}; use test_client::runtime::{Hash, Transfer, Block, BlockNumber, Header, Digest, Extrinsic}; use runtime_primitives::traits::BlakeTwo256; use primitives::{Blake2Hasher, ed25519::{Public, Pair}}; + use hex::*; native_executor_instance!(Executor, test_client::runtime::api::dispatch, test_client::runtime::native_version, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm")); - fn executor() -> ::executor::NativeExecutor { + fn executor() -> executor::NativeExecutor { NativeExecutionDispatch::new() } @@ -70,7 +70,7 @@ mod tests { let signature = Pair::from(Keyring::from_public(Public::from_raw(tx.from.to_fixed_bytes())).unwrap()) .sign(&tx.encode()).into(); - Extrinsic { transfer: tx, signature } + Extrinsic::Transfer(tx, signature) }).collect::>(); let extrinsics_root = ordered_trie_root::(transactions.iter().map(Encode::encode)).into(); @@ -91,7 +91,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &executor(), - "initialise_block", + "Core_initialise_block", &header.encode(), ExecutionStrategy::NativeWhenPossible, ).unwrap(); @@ -102,7 +102,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &executor(), - "apply_extrinsic", + "BlockBuilder_apply_extrinsic", &tx.encode(), ExecutionStrategy::NativeWhenPossible, ).unwrap(); @@ -113,7 +113,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &executor(), - "finalise_block", + "BlockBuilder_finalise_block", &[], ExecutionStrategy::NativeWhenPossible, ).unwrap(); @@ -157,7 +157,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &executor(), - "execute_block", + "Core_execute_block", &b1data, ExecutionStrategy::NativeWhenPossible, ).unwrap(); @@ -182,7 +182,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &executor(), - "execute_block", + "Core_execute_block", &b1data, ExecutionStrategy::AlwaysWasm, ).unwrap(); @@ -208,7 +208,7 @@ mod tests { Some(&InMemoryChangesTrieStorage::new()), &mut overlay, &Executor::new(), - "execute_block", + "Core_execute_block", &b1data, ExecutionStrategy::NativeWhenPossible, ).unwrap(); diff --git a/core/client/src/in_mem.rs b/core/client/src/in_mem.rs index 70adb97607bc6954c0aec6f7b305c39377da68b1..d5065d764139b436827d7a8b942caeab7b515708 100644 --- a/core/client/src/in_mem.rs +++ b/core/client/src/in_mem.rs @@ -19,20 +19,20 @@ use std::collections::HashMap; use std::sync::Arc; use parking_lot::RwLock; -use error; -use backend::{self, NewBlockState}; -use light; -use primitives::{AuthorityId, storage::well_known_keys}; +use crate::error; +use crate::backend::{self, NewBlockState}; +use crate::light; +use primitives::{ChangesTrieConfiguration, storage::well_known_keys}; use runtime_primitives::generic::BlockId; use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Zero, - NumberFor, As, Digest, DigestItem}; + NumberFor, As, Digest, DigestItem, AuthorityIdFor}; use runtime_primitives::{Justification, StorageMap, ChildrenStorageMap}; -use blockchain::{self, BlockStatus, HeaderBackend}; +use crate::blockchain::{self, BlockStatus, HeaderBackend}; use state_machine::backend::{Backend as StateBackend, InMemory, Consolidate}; -use state_machine::InMemoryChangesTrieStorage; +use state_machine::{self, InMemoryChangesTrieStorage, ChangesTrieAnchorBlockId}; use hash_db::Hasher; use heapsize::HeapSizeOf; -use leaves::LeafSet; +use crate::leaves::LeafSet; use trie::MemoryDB; struct PendingBlock { @@ -94,8 +94,10 @@ struct BlockchainStorage { finalized_hash: Block::Hash, finalized_number: NumberFor, genesis_hash: Block::Hash, - cht_roots: HashMap, Block::Hash>, + header_cht_roots: HashMap, Block::Hash>, + changes_trie_cht_roots: HashMap, Block::Hash>, leaves: LeafSet>, + aux: HashMap, Vec>, } /// In-memory blockchain. Supports concurrent reads. @@ -106,7 +108,7 @@ pub struct Blockchain { struct Cache { storage: Arc>>, - authorities_at: RwLock>>>, + authorities_at: RwLock>>>>, } impl Clone for Blockchain { @@ -142,8 +144,10 @@ impl Blockchain { finalized_hash: Default::default(), finalized_number: Zero::zero(), genesis_hash: Default::default(), - cht_roots: HashMap::new(), + header_cht_roots: HashMap::new(), + changes_trie_cht_roots: HashMap::new(), leaves: LeafSet::new(), + aux: HashMap::new(), })); Blockchain { storage: storage.clone(), @@ -162,7 +166,7 @@ impl Blockchain { justification: Option, body: Option::Extrinsic>>, new_state: NewBlockState, - ) -> ::error::Result<()> { + ) -> crate::error::Result<()> { let number = header.number().clone(); let best_tree_route = match new_state.is_best() { false => None, @@ -171,7 +175,7 @@ impl Blockchain { if &best_hash == header.parent_hash() { None } else { - let route = ::blockchain::tree_route( + let route = crate::blockchain::tree_route( self, BlockId::Hash(best_hash), BlockId::Hash(*header.parent_hash()), @@ -233,20 +237,43 @@ impl Blockchain { && this.genesis_hash == other.genesis_hash } - /// Insert CHT root. + /// Insert header CHT root. pub fn insert_cht_root(&self, block: NumberFor, cht_root: Block::Hash) { - self.storage.write().cht_roots.insert(block, cht_root); + self.storage.write().header_cht_roots.insert(block, cht_root); } - fn finalize_header(&self, id: BlockId) -> error::Result<()> { + fn finalize_header(&self, id: BlockId, justification: Option) -> error::Result<()> { let hash = match self.header(id)? { Some(h) => h.hash(), None => return Err(error::ErrorKind::UnknownBlock(format!("{}", id)).into()), }; - self.storage.write().finalized_hash = hash; + let mut storage = self.storage.write(); + storage.finalized_hash = hash; + + if justification.is_some() { + let block = storage.blocks.get_mut(&hash) + .expect("hash was fetched from a block in the db; qed"); + + let block_justification = match block { + StoredBlock::Header(_, ref mut j) | StoredBlock::Full(_, ref mut j) => j + }; + + *block_justification = justification; + } + Ok(()) } + + fn write_aux(&self, ops: Vec<(Vec, Option>)>) { + let mut storage = self.storage.write(); + for (k, v) in ops { + match v { + Some(v) => storage.aux.insert(k, v), + None => storage.aux.remove(&k), + }; + } + } } impl HeaderBackend for Blockchain { @@ -311,6 +338,29 @@ impl blockchain::Backend for Blockchain { } } +impl backend::AuxStore for Blockchain { + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >(&self, insert: I, delete: D) -> error::Result<()> { + let mut storage = self.storage.write(); + for (k, v) in insert { + storage.aux.insert(k.to_vec(), v.to_vec()); + } + for k in delete { + storage.aux.remove(*k); + } + Ok(()) + } + + fn get_aux(&self, key: &[u8]) -> error::Result>> { + Ok(self.storage.read().aux.get(key).cloned()) + } +} + impl light::blockchain::Storage for Blockchain where Block::Hash: From<[u8; 32]>, @@ -318,8 +368,9 @@ impl light::blockchain::Storage for Blockchain fn import_header( &self, header: Block::Header, - authorities: Option>, + authorities: Option>>, state: NewBlockState, + aux_ops: Vec<(Vec, Option>)>, ) -> error::Result<()> { let hash = header.hash(); let parent_hash = *header.parent_hash(); @@ -328,6 +379,7 @@ impl light::blockchain::Storage for Blockchain self.cache.insert(parent_hash, authorities); } + self.write_aux(aux_ops); Ok(()) } @@ -336,12 +388,17 @@ impl light::blockchain::Storage for Blockchain } fn finalize_header(&self, id: BlockId) -> error::Result<()> { - Blockchain::finalize_header(self, id) + Blockchain::finalize_header(self, id, None) + } + + fn header_cht_root(&self, _cht_size: u64, block: NumberFor) -> error::Result { + self.storage.read().header_cht_roots.get(&block).cloned() + .ok_or_else(|| error::ErrorKind::Backend(format!("Header CHT for block {} not exists", block)).into()) } - fn cht_root(&self, _cht_size: u64, block: NumberFor) -> error::Result { - self.storage.read().cht_roots.get(&block).cloned() - .ok_or_else(|| error::ErrorKind::Backend(format!("CHT for block {} not exists", block)).into()) + fn changes_trie_cht_root(&self, _cht_size: u64, block: NumberFor) -> error::Result { + self.storage.read().changes_trie_cht_roots.get(&block).cloned() + .ok_or_else(|| error::ErrorKind::Backend(format!("Changes trie CHT for block {} not exists", block)).into()) } fn cache(&self) -> Option<&blockchain::Cache> { @@ -352,10 +409,11 @@ impl light::blockchain::Storage for Blockchain /// In-memory operation. pub struct BlockImportOperation { pending_block: Option>, - pending_authorities: Option>, + pending_authorities: Option>>, old_state: InMemory, new_state: Option>, changes_trie_update: Option>, + aux: Option, Option>)>>, } impl backend::BlockImportOperation for BlockImportOperation @@ -386,11 +444,11 @@ where Ok(()) } - fn update_authorities(&mut self, authorities: Vec) { + fn update_authorities(&mut self, authorities: Vec>) { self.pending_authorities = Some(authorities); } - fn update_storage(&mut self, update: as StateBackend>::Transaction) -> error::Result<()> { + fn update_db_storage(&mut self, update: as StateBackend>::Transaction) -> error::Result<()> { self.new_state = Some(self.old_state.update(update)); Ok(()) } @@ -426,6 +484,17 @@ where self.new_state = Some(InMemory::from(transaction)); Ok(root) } + + fn set_aux(&mut self, ops: I) -> error::Result<()> + where I: IntoIterator, Option>)> + { + self.aux = Some(ops.into_iter().collect()); + Ok(()) + } + + fn update_storage(&mut self, _update: Vec<(Vec, Option>)>) -> error::Result<()> { + Ok(()) + } } /// In-memory backend. Keeps all states and blocks in memory. Useful for testing. @@ -436,9 +505,8 @@ where H::Out: HeapSizeOf + Ord, { states: RwLock>>, - changes_trie_storage: InMemoryChangesTrieStorage, + changes_trie_storage: ChangesTrieStorage, blockchain: Blockchain, - aux: RwLock, Vec>>, } impl Backend @@ -451,13 +519,33 @@ where pub fn new() -> Backend { Backend { states: RwLock::new(HashMap::new()), - changes_trie_storage: InMemoryChangesTrieStorage::new(), + changes_trie_storage: ChangesTrieStorage(InMemoryChangesTrieStorage::new()), blockchain: Blockchain::new(), - aux: RwLock::new(HashMap::new()), } } } +impl backend::AuxStore for Backend +where + Block: BlockT, + H: Hasher, + H::Out: HeapSizeOf + Ord, +{ + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >(&self, insert: I, delete: D) -> error::Result<()> { + self.blockchain.insert_aux(insert, delete) + } + + fn get_aux(&self, key: &[u8]) -> error::Result>> { + self.blockchain.get_aux(key) + } +} + impl backend::Backend for Backend where Block: BlockT, @@ -467,7 +555,7 @@ where type BlockImportOperation = BlockImportOperation; type Blockchain = Blockchain; type State = InMemory; - type ChangesTrieStorage = InMemoryChangesTrieStorage; + type ChangesTrieStorage = ChangesTrieStorage; fn begin_operation(&self, block: BlockId) -> error::Result { let state = match block { @@ -481,6 +569,7 @@ where old_state: state, new_state: None, changes_trie_update: None, + aux: None, }) } @@ -498,7 +587,7 @@ where if let Some(changes_trie_root) = changes_trie_root { if let Some(changes_trie_update) = operation.changes_trie_update { let changes_trie_root: H::Out = changes_trie_root.into(); - self.changes_trie_storage.insert(header.number().as_(), changes_trie_root, changes_trie_update); + self.changes_trie_storage.0.insert(header.number().as_(), changes_trie_root, changes_trie_update); } } @@ -508,11 +597,15 @@ where self.blockchain.cache.insert(parent_hash, operation.pending_authorities); } } + + if let Some(ops) = operation.aux { + self.blockchain.write_aux(ops); + } Ok(()) } - fn finalize_block(&self, block: BlockId) -> error::Result<()> { - self.blockchain.finalize_header(block) + fn finalize_block(&self, block: BlockId, justification: Option) -> error::Result<()> { + self.blockchain.finalize_header(block, justification) } fn blockchain(&self) -> &Self::Blockchain { @@ -533,21 +626,6 @@ where fn revert(&self, _n: NumberFor) -> error::Result> { Ok(As::sa(0)) } - - fn insert_aux<'a, 'b: 'a, 'c: 'a, I: IntoIterator, D: IntoIterator>(&self, insert: I, delete: D) -> error::Result<()> { - let mut aux = self.aux.write(); - for (k, v) in insert { - aux.insert(k.to_vec(), v.to_vec()); - } - for k in delete { - aux.remove(*k); - } - Ok(()) - } - - fn get_aux(&self, key: &[u8]) -> error::Result>> { - Ok(self.aux.read().get(key).cloned()) - } } impl backend::LocalBackend for Backend @@ -558,13 +636,13 @@ where {} impl Cache { - fn insert(&self, at: Block::Hash, authorities: Option>) { + fn insert(&self, at: Block::Hash, authorities: Option>>) { self.authorities_at.write().insert(at, authorities); } } impl blockchain::Cache for Cache { - fn authorities_at(&self, block: BlockId) -> Option> { + fn authorities_at(&self, block: BlockId) -> Option>> { let hash = match block { BlockId::Hash(hash) => hash, BlockId::Number(number) => self.storage.read().hashes.get(&number).cloned()?, @@ -574,11 +652,31 @@ impl blockchain::Cache for Cache { } } +/// Prunable in-memory changes trie storage. +pub struct ChangesTrieStorage(InMemoryChangesTrieStorage) where H::Out: HeapSizeOf; +impl backend::PrunableStateChangesTrieStorage for ChangesTrieStorage where H::Out: HeapSizeOf { + fn oldest_changes_trie_block(&self, _config: &ChangesTrieConfiguration, _best_finalized: u64) -> u64 { + 0 + } +} + +impl state_machine::ChangesTrieRootsStorage for ChangesTrieStorage where H::Out: HeapSizeOf { + fn root(&self, anchor: &ChangesTrieAnchorBlockId, block: u64) -> Result, String> { + self.0.root(anchor, block) + } +} + +impl state_machine::ChangesTrieStorage for ChangesTrieStorage where H::Out: HeapSizeOf { + fn get(&self, key: &H::Out) -> Result, String> { + self.0.get(key) + } +} + /// Insert authorities entry into in-memory blockchain cache. Extracted as a separate function to use it in tests. pub fn cache_authorities_at( blockchain: &Blockchain, at: Block::Hash, - authorities: Option> + authorities: Option>> ) { blockchain.cache.insert(at, authorities); } diff --git a/core/client/src/leaves.rs b/core/client/src/leaves.rs index a41f91933c07680e0bb100623c7e945cb4df143d..1fa4cb3122f8de519779d54e6b6cc4acc64f3c88 100644 --- a/core/client/src/leaves.rs +++ b/core/client/src/leaves.rs @@ -19,7 +19,7 @@ use std::cmp::{Ord, Ordering}; use kvdb::{KeyValueDB, DBTransaction}; use runtime_primitives::traits::SimpleArithmetic; use codec::{Encode, Decode}; -use error; +use crate::error; /// helper wrapper type to keep a list of block hashes ordered /// by `number` descending in a `BTreeSet` which allows faster and simpler @@ -64,6 +64,8 @@ pub struct DisplacedLeaf { #[derive(Debug, Clone, PartialEq, Eq)] pub struct LeafSet { storage: BTreeSet>, + pending_added: Vec>, + pending_removed: Vec, } impl LeafSet where @@ -73,7 +75,9 @@ impl LeafSet where /// Construct a new, blank leaf set. pub fn new() -> Self { Self { - storage: BTreeSet::new() + storage: BTreeSet::new(), + pending_added: Vec::new(), + pending_removed: Vec::new(), } } @@ -94,7 +98,11 @@ impl LeafSet where }; storage.insert(LeafSetItem { hash, number }); } - Ok(Self { storage }) + Ok(Self { + storage, + pending_added: Vec::new(), + pending_removed: Vec::new(), + }) } /// update the leaf list on import. returns a displaced leaf if there was one. @@ -102,12 +110,13 @@ impl LeafSet where // avoid underflow for genesis. let displaced = if number != N::zero() { let displaced = LeafSetItem { - hash: parent_hash, + hash: parent_hash.clone(), number: number.clone() - N::one(), }; let was_displaced = self.storage.remove(&displaced); if was_displaced { + self.pending_removed.push(parent_hash); Some(DisplacedLeaf { new_hash: hash.clone(), displaced, @@ -119,7 +128,9 @@ impl LeafSet where None }; - self.storage.insert(LeafSetItem { hash, number }); + let item = LeafSetItem { hash, number }; + self.storage.insert(item.clone()); + self.pending_added.push(item); displaced } @@ -128,6 +139,8 @@ impl LeafSet where let new_number = displaced.displaced.number.clone() + N::one(); self.storage.remove(&LeafSetItem { hash: displaced.new_hash, number: new_number }); self.storage.insert(displaced.displaced); + self.pending_added.clear(); + self.pending_removed.clear(); } /// currently since revert only affects the canonical chain @@ -148,13 +161,18 @@ impl LeafSet where } /// Write the leaf list to the database transaction. - pub fn prepare_transaction(&self, tx: &mut DBTransaction, column: Option, prefix: &[u8]) { + pub fn prepare_transaction(&mut self, tx: &mut DBTransaction, column: Option, prefix: &[u8]) { let mut buf = prefix.to_vec(); - for &LeafSetItem { ref hash, ref number } in &self.storage { + for LeafSetItem { hash, number } in self.pending_added.drain(..) { hash.using_encoded(|s| buf.extend(s)); tx.put_vec(column, &buf[..], number.encode()); buf.truncate(prefix.len()); // reuse allocation. } + for hash in self.pending_removed.drain(..) { + hash.using_encoded(|s| buf.extend(s)); + tx.delete(column, &buf[..]); + buf.truncate(prefix.len()); // reuse allocation. + } } } diff --git a/core/client/src/lib.rs b/core/client/src/lib.rs index a0332779052b48414607b0460af3eefb88ec2243..4a8f06dfde1233d85511a82005b7b6824ffa6f0d 100644 --- a/core/client/src/lib.rs +++ b/core/client/src/lib.rs @@ -14,64 +14,55 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Substrate Client and associated logic. -// end::description[] +#![cfg_attr(not(feature = "std"), no_std)] #![warn(missing_docs)] #![recursion_limit="128"] -extern crate substrate_trie as trie; -extern crate parity_codec as codec; -extern crate substrate_primitives as primitives; -extern crate sr_primitives as runtime_primitives; -extern crate substrate_state_machine as state_machine; -extern crate substrate_consensus_common as consensus; -#[cfg(test)] extern crate substrate_keyring as keyring; -#[cfg(test)] extern crate substrate_test_client as test_client; -#[macro_use] extern crate substrate_telemetry; -#[macro_use] extern crate slog; // needed until we can reexport `slog_info` from `substrate_telemetry` - -extern crate fnv; -extern crate futures; -extern crate parking_lot; -extern crate hash_db; -extern crate heapsize; -extern crate kvdb; -extern crate sr_api; - -#[macro_use] extern crate error_chain; -#[macro_use] extern crate log; -#[cfg_attr(test, macro_use)] extern crate substrate_executor as executor; -#[cfg(test)] #[macro_use] extern crate hex_literal; -#[cfg(test)] extern crate kvdb_memorydb; - +#[macro_use] +pub mod runtime_api; +#[cfg(feature = "std")] pub mod error; +#[cfg(feature = "std")] pub mod blockchain; +#[cfg(feature = "std")] pub mod backend; +#[cfg(feature = "std")] pub mod cht; +#[cfg(feature = "std")] pub mod in_mem; +#[cfg(feature = "std")] pub mod genesis; pub mod block_builder; +#[cfg(feature = "std")] pub mod light; +#[cfg(feature = "std")] mod leaves; +#[cfg(feature = "std")] mod call_executor; +#[cfg(feature = "std")] mod client; +#[cfg(feature = "std")] mod notifications; -pub use blockchain::Info as ChainInfo; -pub use call_executor::{CallResult, CallExecutor, LocalCallExecutor}; -pub use client::{ +#[cfg(feature = "std")] +pub use crate::blockchain::Info as ChainInfo; +#[cfg(feature = "std")] +pub use crate::call_executor::{CallExecutor, LocalCallExecutor}; +#[cfg(feature = "std")] +pub use crate::client::{ new_with_backend, new_in_mem, BlockBody, BlockStatus, ImportNotifications, FinalityNotifications, BlockchainEvents, - Client, ClientInfo, ChainHead, + BlockImportNotification, Client, ClientInfo, ChainHead, }; -pub use notifications::{StorageEventStream, StorageChangeSet}; +#[cfg(feature = "std")] +pub use crate::notifications::{StorageEventStream, StorageChangeSet}; +#[cfg(feature = "std")] pub use state_machine::ExecutionStrategy; -pub use leaves::LeafSet; +#[cfg(feature = "std")] +pub use crate::leaves::LeafSet; -/// Traits for interfacing with the runtime from the client. -pub mod runtime_api { - pub use sr_api::*; -} +#[doc(inline)] +pub use sr_api_macros::{decl_runtime_apis, impl_runtime_apis}; diff --git a/core/client/src/light/backend.rs b/core/client/src/light/backend.rs index 8d2414396a8dfc85420b7e4e967d97e786bd20a4..c144ffa52036fca58156eac7648b5554055273d8 100644 --- a/core/client/src/light/backend.rs +++ b/core/client/src/light/backend.rs @@ -21,17 +21,15 @@ use std::sync::{Arc, Weak}; use futures::{Future, IntoFuture}; use parking_lot::RwLock; -use primitives::AuthorityId; use runtime_primitives::{generic::BlockId, Justification, StorageMap, ChildrenStorageMap}; -use state_machine::{Backend as StateBackend, InMemoryChangesTrieStorage, TrieBackend}; -use runtime_primitives::traits::{Block as BlockT, NumberFor}; - -use in_mem; -use backend::{Backend as ClientBackend, BlockImportOperation, RemoteBackend, NewBlockState}; -use blockchain::HeaderBackend as BlockchainHeaderBackend; -use error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult}; -use light::blockchain::{Blockchain, Storage as BlockchainStorage}; -use light::fetcher::{Fetcher, RemoteReadRequest}; +use state_machine::{Backend as StateBackend, TrieBackend}; +use runtime_primitives::traits::{Block as BlockT, NumberFor, AuthorityIdFor}; +use crate::in_mem; +use crate::backend::{AuxStore, Backend as ClientBackend, BlockImportOperation, RemoteBackend, NewBlockState}; +use crate::blockchain::HeaderBackend as BlockchainHeaderBackend; +use crate::error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult}; +use crate::light::blockchain::{Blockchain, Storage as BlockchainStorage}; +use crate::light::fetcher::{Fetcher, RemoteReadRequest}; use hash_db::Hasher; use trie::MemoryDB; use heapsize::HeapSizeOf; @@ -44,8 +42,9 @@ pub struct Backend { /// Light block (header and justification) import operation. pub struct ImportOperation { header: Option, - authorities: Option>, + authorities: Option>>, leaf_state: NewBlockState, + aux_ops: Vec<(Vec, Option>)>, _phantom: ::std::marker::PhantomData<(S, F)>, } @@ -69,6 +68,22 @@ impl Backend { } } +impl AuxStore for Backend { + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >(&self, insert: I, delete: D) -> ClientResult<()> { + self.blockchain.storage().insert_aux(insert, delete) + } + + fn get_aux(&self, key: &[u8]) -> ClientResult>> { + self.blockchain.storage().get_aux(key) + } +} + impl ClientBackend for Backend where Block: BlockT, S: BlockchainStorage, @@ -79,13 +94,14 @@ impl ClientBackend for Backend where type BlockImportOperation = ImportOperation; type Blockchain = Blockchain; type State = OnDemandState; - type ChangesTrieStorage = InMemoryChangesTrieStorage; + type ChangesTrieStorage = in_mem::ChangesTrieStorage; fn begin_operation(&self, _block: BlockId) -> ClientResult { Ok(ImportOperation { header: None, authorities: None, leaf_state: NewBlockState::Normal, + aux_ops: Vec::new(), _phantom: Default::default(), }) } @@ -96,10 +112,11 @@ impl ClientBackend for Backend where header, operation.authorities, operation.leaf_state, + operation.aux_ops, ) } - fn finalize_block(&self, block: BlockId) -> ClientResult<()> { + fn finalize_block(&self, block: BlockId, _justification: Option) -> ClientResult<()> { self.blockchain.storage().finalize_header(block) } @@ -128,14 +145,6 @@ impl ClientBackend for Backend where fn revert(&self, _n: NumberFor) -> ClientResult> { Err(ClientErrorKind::NotAvailableOnLightClient.into()) } - - fn insert_aux<'a, 'b: 'a, 'c: 'a, I: IntoIterator, D: IntoIterator>(&self, _insert: I, _delete: D) -> ClientResult<()> { - Err(ClientErrorKind::NotAvailableOnLightClient.into()) - } - - fn get_aux(&self, _key: &[u8]) -> ClientResult>> { - Err(ClientErrorKind::NotAvailableOnLightClient.into()) - } } impl RemoteBackend for Backend @@ -174,11 +183,11 @@ where Ok(()) } - fn update_authorities(&mut self, authorities: Vec) { + fn update_authorities(&mut self, authorities: Vec>) { self.authorities = Some(authorities); } - fn update_storage(&mut self, _update: >::Transaction) -> ClientResult<()> { + fn update_db_storage(&mut self, _update: >::Transaction) -> ClientResult<()> { // we're not storing anything locally => ignore changes Ok(()) } @@ -193,6 +202,18 @@ where let mut op = in_mem.begin_operation(BlockId::Hash(Default::default()))?; op.reset_storage(top, children) } + + fn set_aux(&mut self, ops: I) -> ClientResult<()> + where I: IntoIterator, Option>)> + { + self.aux_ops = ops.into_iter().collect(); + Ok(()) + } + + fn update_storage(&mut self, _update: Vec<(Vec, Option>)>) -> ClientResult<()> { + // we're not storing anything locally => ignore changes + Ok(()) + } } impl StateBackend for OnDemandState @@ -257,6 +278,11 @@ where Vec::new() } + fn keys(&self, _prefix: &Vec) -> Vec> { + // whole state is not available on light node + Vec::new() + } + fn try_into_trie_backend(self) -> Option> { None } diff --git a/core/client/src/light/blockchain.rs b/core/client/src/light/blockchain.rs index 97c20ecc907468a06e8497d17e14ffdbac98012b..94d9da9994547a40552463bf6003a33455308200 100644 --- a/core/client/src/light/blockchain.rs +++ b/core/client/src/light/blockchain.rs @@ -21,25 +21,28 @@ use std::sync::Weak; use futures::{Future, IntoFuture}; use parking_lot::Mutex; -use primitives::AuthorityId; use runtime_primitives::{Justification, generic::BlockId}; -use runtime_primitives::traits::{Block as BlockT, Header as HeaderT,NumberFor, Zero}; +use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero, AuthorityIdFor}; -use backend::NewBlockState; -use blockchain::{Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache, +use crate::backend::{AuxStore, NewBlockState}; +use crate::blockchain::{Backend as BlockchainBackend, BlockStatus, Cache as BlockchainCache, HeaderBackend as BlockchainHeaderBackend, Info as BlockchainInfo}; -use cht; -use error::{ErrorKind as ClientErrorKind, Result as ClientResult}; -use light::fetcher::{Fetcher, RemoteHeaderRequest}; +use crate::cht; +use crate::error::{ErrorKind as ClientErrorKind, Result as ClientResult}; +use crate::light::fetcher::{Fetcher, RemoteHeaderRequest}; /// Light client blockchain storage. -pub trait Storage: BlockchainHeaderBackend { +pub trait Storage: AuxStore + BlockchainHeaderBackend { /// Store new header. Should refuse to revert any finalized blocks. + /// + /// Takes new authorities, the leaf state of the new block, and + /// any auxiliary storage updates to place in the same operation. fn import_header( &self, header: Block::Header, - authorities: Option>, + authorities: Option>>, state: NewBlockState, + aux_ops: Vec<(Vec, Option>)>, ) -> ClientResult<()>; /// Mark historic header as finalized. @@ -48,8 +51,11 @@ pub trait Storage: BlockchainHeaderBackend { /// Get last finalized header. fn last_finalized(&self) -> ClientResult; - /// Get CHT root for given block. Fails if the block is not pruned (not a part of any CHT). - fn cht_root(&self, cht_size: u64, block: NumberFor) -> ClientResult; + /// Get headers CHT root for given block. Fails if the block is not pruned (not a part of any CHT). + fn header_cht_root(&self, cht_size: u64, block: NumberFor) -> ClientResult; + + /// Get changes trie CHT root for given block. Fails if the block is not pruned (not a part of any CHT). + fn changes_trie_cht_root(&self, cht_size: u64, block: NumberFor) -> ClientResult; /// Get storage cache. fn cache(&self) -> Option<&BlockchainCache>; @@ -106,7 +112,7 @@ impl BlockchainHeaderBackend for Blockchain where Bloc self.fetcher().upgrade().ok_or(ClientErrorKind::NotAvailableOnLightClient)? .remote_header(RemoteHeaderRequest { - cht_root: self.storage.cht_root(cht::SIZE, number)?, + cht_root: self.storage.header_cht_root(cht::SIZE, number)?, block: number, retry_count: None, }) @@ -155,3 +161,101 @@ impl BlockchainBackend for Blockchain where Block: Blo unimplemented!() } } + +#[cfg(test)] +pub mod tests { + use std::collections::HashMap; + use test_client::runtime::{Hash, Block, Header}; + use crate::blockchain::Info; + use crate::light::fetcher::tests::OkCallFetcher; + use super::*; + + pub type DummyBlockchain = Blockchain; + + pub struct DummyStorage { + pub changes_tries_cht_roots: HashMap, + } + + impl DummyStorage { + pub fn new() -> Self { + DummyStorage { + changes_tries_cht_roots: HashMap::new(), + } + } + } + + impl BlockchainHeaderBackend for DummyStorage { + fn header(&self, _id: BlockId) -> ClientResult> { + Err(ClientErrorKind::Backend("Test error".into()).into()) + } + + fn info(&self) -> ClientResult> { + Err(ClientErrorKind::Backend("Test error".into()).into()) + } + + fn status(&self, _id: BlockId) -> ClientResult { + Err(ClientErrorKind::Backend("Test error".into()).into()) + } + + fn number(&self, _hash: Hash) -> ClientResult>> { + Err(ClientErrorKind::Backend("Test error".into()).into()) + } + + fn hash(&self, _number: u64) -> ClientResult> { + Err(ClientErrorKind::Backend("Test error".into()).into()) + } + } + + impl AuxStore for DummyStorage { + fn insert_aux< + 'a, + 'b: 'a, + 'c: 'a, + I: IntoIterator, + D: IntoIterator, + >(&self, _insert: I, _delete: D) -> ClientResult<()> { + Err(ClientErrorKind::Backend("Test error".into()).into()) + } + + fn get_aux(&self, _key: &[u8]) -> ClientResult>> { + Err(ClientErrorKind::Backend("Test error".into()).into()) + } + } + + impl Storage for DummyStorage { + fn import_header( + &self, + _header: Header, + _authorities: Option>>, + _state: NewBlockState, + _aux_ops: Vec<(Vec, Option>)>, + ) -> ClientResult<()> { + Err(ClientErrorKind::Backend("Test error".into()).into()) + } + + fn finalize_header(&self, _block: BlockId) -> ClientResult<()> { + Err(ClientErrorKind::Backend("Test error".into()).into()) + } + + fn last_finalized(&self) -> ClientResult { + Err(ClientErrorKind::Backend("Test error".into()).into()) + } + + fn header_cht_root(&self, _cht_size: u64, _block: u64) -> ClientResult { + Err(ClientErrorKind::Backend("Test error".into()).into()) + } + + fn changes_trie_cht_root(&self, cht_size: u64, block: u64) -> ClientResult { + cht::block_to_cht_number(cht_size, block) + .and_then(|cht_num| self.changes_tries_cht_roots.get(&cht_num)) + .cloned() + .ok_or_else(|| ClientErrorKind::Backend( + format!("Test error: CHT for block #{} not found", block) + ).into()) + } + + fn cache(&self) -> Option<&BlockchainCache> { + None + } + } +} diff --git a/core/client/src/light/call_executor.rs b/core/client/src/light/call_executor.rs index d52883db64f01f626b161d7f1064bbb0d360c65f..734a1994bfb1b52b6108ae4cc818d5e433f1e283 100644 --- a/core/client/src/light/call_executor.rs +++ b/core/client/src/light/call_executor.rs @@ -17,22 +17,22 @@ //! Light client call exector. Executes methods on remote full nodes, fetching //! execution proof and checking it locally. -use std::marker::PhantomData; -use std::sync::Arc; +use std::{collections::HashSet, marker::PhantomData, sync::Arc}; use futures::{IntoFuture, Future}; +use codec::{Encode, Decode}; +use primitives::{H256, Blake2Hasher, convert_hash, NativeOrEncoded}; use runtime_primitives::generic::BlockId; -use runtime_primitives::traits::{Block as BlockT, Header as HeaderT}; -use state_machine::{Backend as StateBackend, CodeExecutor, OverlayedChanges, - execution_proof_check, ExecutionManager}; +use runtime_primitives::traits::{As, Block as BlockT, Header as HeaderT}; +use state_machine::{self, Backend as StateBackend, CodeExecutor, OverlayedChanges, + create_proof_check_backend, execution_proof_check_on_trie_backend, ExecutionManager}; use hash_db::Hasher; -use blockchain::Backend as ChainBackend; -use call_executor::{CallExecutor, CallResult}; -use error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult}; -use light::fetcher::{Fetcher, RemoteCallRequest}; +use crate::blockchain::Backend as ChainBackend; +use crate::call_executor::CallExecutor; +use crate::error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult}; +use crate::light::fetcher::{Fetcher, RemoteCallRequest}; use executor::{RuntimeVersion, NativeVersion}; -use codec::Decode; use heapsize::HeapSizeOf; use trie::MemoryDB; @@ -71,12 +71,8 @@ where { type Error = ClientError; - fn call(&self, id: &BlockId, method: &str, call_data: &[u8]) -> ClientResult { - let block_hash = match *id { - BlockId::Hash(hash) => hash, - BlockId::Number(number) => self.blockchain.hash(number)? - .ok_or_else(|| ClientErrorKind::UnknownBlock(format!("{}", number)))?, - }; + fn call(&self, id: &BlockId, method: &str, call_data: &[u8]) -> ClientResult> { + let block_hash = self.blockchain.expect_block_hash_from_id(id)?; let block_header = self.blockchain.expect_header(id.clone())?; self.fetcher.remote_call(RemoteCallRequest { @@ -88,28 +84,61 @@ where }).into_future().wait() } + fn contextual_call< + PB: Fn() -> ClientResult, + EM: Fn( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC, + >( + &self, + at: &BlockId, + method: &str, + call_data: &[u8], + changes: &mut OverlayedChanges, + initialised_block: &mut Option>, + _prepare_environment_block: PB, + _manager: ExecutionManager, + _native_call: Option, + ) -> ClientResult> where ExecutionManager: Clone { + // it is only possible to execute contextual call if changes are empty + if !changes.is_empty() || initialised_block.is_some() { + return Err(ClientErrorKind::NotAvailableOnLightClient.into()); + } + + self.call(at, method, call_data).map(NativeOrEncoded::Encoded) + } + fn runtime_version(&self, id: &BlockId) -> ClientResult { let call_result = self.call(id, "version", &[])?; - RuntimeVersion::decode(&mut call_result.return_data.as_slice()) + RuntimeVersion::decode(&mut call_result.as_slice()) .ok_or_else(|| ClientErrorKind::VersionInvalid.into()) } fn call_at_state< S: StateBackend, - FF: FnOnce(Result, Self::Error>, Result, Self::Error>) -> Result, Self::Error> + FF: FnOnce( + Result, Self::Error>, + Result, Self::Error> + ) -> Result, Self::Error>, + R: Encode + Decode + PartialEq, + NC: FnOnce() -> R, >(&self, _state: &S, _changes: &mut OverlayedChanges, _method: &str, _call_data: &[u8], - _m: ExecutionManager - ) -> ClientResult<(Vec, S::Transaction, Option>)> { + _m: ExecutionManager, + _native_call: Option, + ) -> ClientResult<(NativeOrEncoded, S::Transaction, Option>)> { Err(ClientErrorKind::NotAvailableOnLightClient.into()) } - fn prove_at_state>( + fn prove_at_trie_state>( &self, - _state: S, + _state: &state_machine::TrieBackend, _changes: &mut OverlayedChanges, _method: &str, _call_data: &[u8] @@ -122,66 +151,162 @@ where } } -/// Check remote execution proof using given backend. +/// Prove contextual execution using given block header in environment. +/// +/// Method is executed using passed header as environment' current block. +/// Proof includes both environment preparation proof and method execution proof. +pub fn prove_execution( + state: S, + header: Block::Header, + executor: &E, + method: &str, + call_data: &[u8], +) -> ClientResult<(Vec, Vec>)> + where + Block: BlockT, + S: StateBackend, + E: CallExecutor, +{ + let trie_state = state.try_into_trie_backend() + .ok_or_else(|| Box::new(state_machine::ExecutionError::UnableToGenerateProof) as Box)?; + + // prepare execution environment + record preparation proof + let mut changes = Default::default(); + let (_, init_proof) = executor.prove_at_trie_state( + &trie_state, + &mut changes, + "Core_initialise_block", + &header.encode(), + )?; + + // execute method + record execution proof + let (result, exec_proof) = executor.prove_at_trie_state(&trie_state, &mut changes, method, call_data)?; + let total_proof = init_proof.into_iter() + .chain(exec_proof.into_iter()) + .collect::>() + .into_iter() + .collect(); + + Ok((result, total_proof)) +} + +/// Check remote contextual execution proof using given backend. +/// +/// Method is executed using passed header as environment' current block. +/// Proof shoul include both environment preparation proof and method execution proof. pub fn check_execution_proof( executor: &E, request: &RemoteCallRequest

, remote_proof: Vec> -) -> ClientResult +) -> ClientResult> where Header: HeaderT, E: CodeExecutor, H: Hasher, H::Out: Ord + HeapSizeOf, - { let local_state_root = request.header.state_root(); - let mut root: H::Out = Default::default(); - root.as_mut().copy_from_slice(local_state_root.as_ref()); + let root: H::Out = convert_hash(&local_state_root); + // prepare execution environment + check preparation proof let mut changes = OverlayedChanges::default(); - let local_result = execution_proof_check::( - root, - remote_proof, + let trie_backend = create_proof_check_backend(root, remote_proof)?; + let next_block =
::new( + *request.header.number() + As::sa(1), + Default::default(), + Default::default(), + request.header.hash(), + Default::default(), + ); + execution_proof_check_on_trie_backend::( + &trie_backend, + &mut changes, + executor, + "Core_initialise_block", + &next_block.encode(), + )?; + + // execute method + let local_result = execution_proof_check_on_trie_backend::( + &trie_backend, &mut changes, executor, &request.method, - &request.call_data)?; + &request.call_data, + )?; - Ok(CallResult { return_data: local_result, changes }) + Ok(local_result) } #[cfg(test)] mod tests { - use test_client; + use consensus::BlockOrigin; + use test_client::{self, runtime::{Block, Header}, runtime::RuntimeApi, TestClient}; use executor::NativeExecutionDispatch; use super::*; #[test] fn execution_proof_is_generated_and_checked() { + type TestClient = test_client::client::Client< + test_client::Backend, + test_client::Executor, + Block, + RuntimeApi + >; + + fn execute(remote_client: &TestClient, at: u64, method: &'static str) -> (Vec, Vec) { + let remote_block_id = BlockId::Number(at); + let remote_root = remote_client.state_at(&remote_block_id) + .unwrap().storage_root(::std::iter::empty()).0; + + // 'fetch' execution proof from remote node + let (remote_result, remote_execution_proof) = remote_client.execution_proof( + &remote_block_id, + method, + &[] + ).unwrap(); + + // check remote execution proof locally + let local_executor = test_client::LocalExecutor::new(); + let local_result = check_execution_proof(&local_executor, &RemoteCallRequest { + block: test_client::runtime::Hash::default(), + header: test_client::runtime::Header { + state_root: remote_root.into(), + parent_hash: Default::default(), + number: at, + extrinsics_root: Default::default(), + digest: Default::default(), + }, + method: method.into(), + call_data: vec![], + retry_count: None, + }, remote_execution_proof).unwrap(); + + (remote_result, local_result) + } + // prepare remote client let remote_client = test_client::new(); - let remote_block_id = BlockId::Number(0); - let remote_block_storage_root = remote_client.state_at(&remote_block_id) - .unwrap().storage_root(::std::iter::empty()).0; - - // 'fetch' execution proof from remote node - let remote_execution_proof = remote_client.execution_proof(&remote_block_id, "authorities", &[]).unwrap().1; - - // check remote execution proof locally - let local_executor = test_client::LocalExecutor::new(); - check_execution_proof(&local_executor, &RemoteCallRequest { - block: test_client::runtime::Hash::default(), - header: test_client::runtime::Header { - state_root: remote_block_storage_root.into(), - parent_hash: Default::default(), - number: 0, - extrinsics_root: Default::default(), - digest: Default::default(), - }, - method: "authorities".into(), - call_data: vec![], - retry_count: None, - }, remote_execution_proof).unwrap(); + for _ in 1..3 { + remote_client.import_justified( + BlockOrigin::Own, + remote_client.new_block().unwrap().bake().unwrap(), + Default::default(), + ).unwrap(); + } + + // check method that doesn't requires environment + let (remote, local) = execute(&remote_client, 0, "Core_authorities"); + assert_eq!(remote, local); + + // check method that requires environment + let (_, block) = execute(&remote_client, 0, "BlockBuilder_finalise_block"); + let local_block: Header = Decode::decode(&mut &block[..]).unwrap(); + assert_eq!(local_block.number, 1); + + // check method that requires environment + let (_, block) = execute(&remote_client, 2, "BlockBuilder_finalise_block"); + let local_block: Header = Decode::decode(&mut &block[..]).unwrap(); + assert_eq!(local_block.number, 3); } } diff --git a/core/client/src/light/fetcher.rs b/core/client/src/light/fetcher.rs index 95e02b91f9f65f86cf18d2cd5a5dcf243bb7f391..49c7a5a5f20e20e7c8db1dd3eb31cfe7417996fc 100644 --- a/core/client/src/light/fetcher.rs +++ b/core/client/src/light/fetcher.rs @@ -16,20 +16,22 @@ //! Light client data fetcher. Fetches requested data from remote full nodes. +use std::sync::Arc; +use std::collections::BTreeMap; use std::marker::PhantomData; use futures::IntoFuture; -use hash_db::Hasher; +use hash_db::{HashDB, Hasher}; use heapsize::HeapSizeOf; -use primitives::ChangesTrieConfiguration; +use primitives::{ChangesTrieConfiguration, convert_hash}; use runtime_primitives::traits::{As, Block as BlockT, Header as HeaderT, NumberFor}; -use state_machine::{CodeExecutor, ChangesTrieRootsStorage, read_proof_check, - key_changes_proof_check}; +use state_machine::{CodeExecutor, ChangesTrieRootsStorage, ChangesTrieAnchorBlockId, + TrieBackend, read_proof_check, key_changes_proof_check, create_proof_check_backend_storage}; -use call_executor::CallResult; -use cht; -use error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult}; -use light::call_executor::check_execution_proof; +use crate::cht; +use crate::error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult}; +use crate::light::blockchain::{Blockchain, Storage as BlockchainStorage}; +use crate::light::call_executor::check_execution_proof; /// Remote call request. #[derive(Clone, Debug, PartialEq, Eq, Hash)] @@ -83,15 +85,30 @@ pub struct RemoteChangesRequest { /// Only use digests from blocks up to this hash. Should be last_block OR come /// after this block and be the part of the same fork. pub max_block: (Header::Number, Header::Hash), - // TODO: get rid of this + preserve change_trie_roots when replacing headers with CHT!!! - /// Changes trie roots for the range of blocks [first_block..max_block]. - pub tries_roots: Vec, + /// Known changes trie roots for the range of blocks [tries_roots.0..max_block]. + /// Proofs for roots of ascendants of tries_roots.0 are provided by the remote node. + pub tries_roots: (Header::Number, Header::Hash, Vec), /// Storage key to read. pub key: Vec, /// Number of times to retry request. None means that default RETRY_COUNT is used. pub retry_count: Option, } +/// Key changes read proof. +#[derive(Debug, PartialEq, Eq)] +pub struct ChangesProof { + /// Max block that has been used in changes query. + pub max_block: Header::Number, + /// All touched nodes of all changes tries. + pub proof: Vec>, + /// All changes tries roots that have been touched AND are missing from + /// the requester' node. It is a map of block number => changes trie root. + pub roots: BTreeMap, + /// The proofs for all changes tries roots that have been touched AND are + /// missing from the requester' node. It is a map of CHT number => proof. + pub roots_proof: Vec>, +} + /// Light client data fetcher. Implementations of this trait must check if remote data /// is correct (see FetchedDataChecker) and return already checked data. pub trait Fetcher: Send + Sync { @@ -100,7 +117,7 @@ pub trait Fetcher: Send + Sync { /// Remote storage read future. type RemoteReadResult: IntoFuture>, Error=ClientError>; /// Remote call result future. - type RemoteCallResult: IntoFuture; + type RemoteCallResult: IntoFuture, Error=ClientError>; /// Remote changes result future. type RemoteChangesResult: IntoFuture, u32)>, Error=ClientError>; @@ -117,8 +134,8 @@ pub trait Fetcher: Send + Sync { /// Light client remote data checker. /// -/// Implementations of this trait should not use any blockchain data except that is -/// passed to its methods. +/// Implementations of this trait should not use any prunable blockchain data +/// except that is passed to its methods. pub trait FetchChecker: Send + Sync { /// Check remote header proof. fn check_header_proof( @@ -138,37 +155,163 @@ pub trait FetchChecker: Send + Sync { &self, request: &RemoteCallRequest, remote_proof: Vec> - ) -> ClientResult; + ) -> ClientResult>; /// Check remote changes query proof. fn check_changes_proof( &self, request: &RemoteChangesRequest, - remote_max: NumberFor, - remote_proof: Vec> + proof: ChangesProof ) -> ClientResult, u32)>>; } /// Remote data checker. -pub struct LightDataChecker { +pub struct LightDataChecker, F> { + blockchain: Arc>, executor: E, - _hasher: PhantomData, + _hasher: PhantomData<(B, H)>, } -impl LightDataChecker { +impl, F> LightDataChecker { /// Create new light data checker. - pub fn new(executor: E) -> Self { + pub fn new(blockchain: Arc>, executor: E) -> Self { Self { - executor, _hasher: PhantomData + blockchain, executor, _hasher: PhantomData + } + } + + /// Check remote changes query proof assuming that CHT-s are of given size. + fn check_changes_proof_with_cht_size( + &self, + request: &RemoteChangesRequest, + remote_proof: ChangesProof, + cht_size: u64, + ) -> ClientResult, u32)>> + where + H: Hasher, + H::Out: Ord + HeapSizeOf, + { + // since we need roots of all changes tries for the range begin..max + // => remote node can't use max block greater that one that we have passed + if remote_proof.max_block > request.max_block.0 || remote_proof.max_block < request.last_block.0 { + return Err(ClientErrorKind::ChangesTrieAccessFailed(format!( + "Invalid max_block used by the remote node: {}. Local: {}..{}..{}", + remote_proof.max_block, request.first_block.0, request.last_block.0, request.max_block.0, + )).into()); + } + + // check if remote node has responded with extra changes trie roots proofs + // all changes tries roots must be in range [request.first_block.0; request.tries_roots.0) + let is_extra_first_root = remote_proof.roots.keys().next() + .map(|first_root| *first_root < request.first_block.0 + || *first_root >= request.tries_roots.0) + .unwrap_or(false); + let is_extra_last_root = remote_proof.roots.keys().next_back() + .map(|last_root| *last_root >= request.tries_roots.0) + .unwrap_or(false); + if is_extra_first_root || is_extra_last_root { + return Err(ClientErrorKind::ChangesTrieAccessFailed(format!( + "Extra changes tries roots proofs provided by the remote node: [{:?}..{:?}]. Expected in range: [{}; {})", + remote_proof.roots.keys().next(), remote_proof.roots.keys().next_back(), + request.first_block.0, request.tries_roots.0, + )).into()); + } + + // if request has been composed when some required headers were already pruned + // => remote node has sent us CHT-based proof of required changes tries roots + // => check that this proof is correct before proceeding with changes proof + let remote_max_block = remote_proof.max_block; + let remote_roots = remote_proof.roots; + let remote_roots_proof = remote_proof.roots_proof; + let remote_proof = remote_proof.proof; + if !remote_roots.is_empty() { + self.check_changes_tries_proof( + cht_size, + &remote_roots, + remote_roots_proof, + )?; } + + // and now check the key changes proof + get the changes + key_changes_proof_check::<_, H>( + &request.changes_trie_config, + &RootsStorage { + roots: (request.tries_roots.0, &request.tries_roots.2), + prev_roots: remote_roots, + }, + remote_proof, + request.first_block.0.as_(), + &ChangesTrieAnchorBlockId { + hash: convert_hash(&request.last_block.1), + number: request.last_block.0.as_(), + }, + remote_max_block.as_(), + &request.key) + .map(|pairs| pairs.into_iter().map(|(b, x)| (As::sa(b), x)).collect()) + .map_err(|err| ClientErrorKind::ChangesTrieAccessFailed(err).into()) + } + + /// Check CHT-based proof for changes tries roots. + fn check_changes_tries_proof( + &self, + cht_size: u64, + remote_roots: &BTreeMap, B::Hash>, + remote_roots_proof: Vec>, + ) -> ClientResult<()> + where + H: Hasher, + H::Out: Ord + HeapSizeOf, + { + // all the checks are sharing the same storage + let storage = create_proof_check_backend_storage(remote_roots_proof); + + // we remote_roots.keys() are sorted => we can use this to group changes tries roots + // that are belongs to the same CHT + let blocks = remote_roots.keys().cloned(); + cht::for_each_cht_group::(cht_size, blocks, |mut storage, _, cht_blocks| { + // get local changes trie CHT root for given CHT + // it should be there, because it is never pruned AND request has been composed + // when required header has been pruned (=> replaced with CHT) + let first_block = cht_blocks.first().cloned() + .expect("for_each_cht_group never calls callback with empty groups"); + let local_cht_root = self.blockchain.storage().changes_trie_cht_root(cht_size, first_block)?; + + // check changes trie root for every block within CHT range + for block in cht_blocks { + // check if the proofs storage contains the root + // normally this happens in when the proving backend is created, but since + // we share the storage for multiple checks, do it here + let mut cht_root = H::Out::default(); + cht_root.as_mut().copy_from_slice(local_cht_root.as_ref()); + if !storage.contains(&cht_root) { + return Err(ClientErrorKind::InvalidCHTProof.into()); + } + + // check proof for single changes trie root + let proving_backend = TrieBackend::new(storage, cht_root); + let remote_changes_trie_root = remote_roots[&block]; + cht::check_proof_on_proving_backend::( + local_cht_root, + block, + remote_changes_trie_root, + &proving_backend)?; + + // and return the storage to use in following checks + storage = proving_backend.into_storage(); + } + + Ok(storage) + }, storage) } } -impl FetchChecker for LightDataChecker +impl FetchChecker for LightDataChecker where Block: BlockT, E: CodeExecutor, H: Hasher, H::Out: Ord + HeapSizeOf, + S: BlockchainStorage, + F: Send + Sync, { fn check_header_proof( &self, @@ -177,7 +320,7 @@ impl FetchChecker for LightDataChecker remote_proof: Vec> ) -> ClientResult { let remote_header = remote_header.ok_or_else(|| - ClientError::from(ClientErrorKind::InvalidHeaderProof))?; + ClientError::from(ClientErrorKind::InvalidCHTProof))?; let remote_header_hash = remote_header.hash(); cht::check_proof::( request.cht_root, @@ -192,71 +335,54 @@ impl FetchChecker for LightDataChecker request: &RemoteReadRequest, remote_proof: Vec> ) -> ClientResult>> { - let mut root: H::Out = Default::default(); - root.as_mut().copy_from_slice(request.header.state_root().as_ref()); - read_proof_check::(root, remote_proof, &request.key).map_err(Into::into) + read_proof_check::(convert_hash(request.header.state_root()), remote_proof, &request.key) + .map_err(Into::into) } fn check_execution_proof( &self, request: &RemoteCallRequest, remote_proof: Vec> - ) -> ClientResult { + ) -> ClientResult> { check_execution_proof::<_, _, H>(&self.executor, request, remote_proof) } fn check_changes_proof( &self, request: &RemoteChangesRequest, - remote_max: NumberFor, - remote_proof: Vec> + remote_proof: ChangesProof ) -> ClientResult, u32)>> { - // since we need roots of all changes tries for the range begin..max - // => remote node can't use max block greater that one that we have passed - if remote_max > request.max_block.0 || remote_max < request.last_block.0 { - return Err(ClientErrorKind::ChangesTrieAccessFailed(format!( - "Invalid max_block used by the remote node: {}. Local: {}..{}..{}", - remote_max, request.first_block.0, request.last_block.0, request.max_block.0, - )).into()); - } - - let first_number = request.first_block.0.as_(); - key_changes_proof_check::<_, H>( - &request.changes_trie_config, - &RootsStorage { - first: first_number, - roots: &request.tries_roots, - }, - remote_proof, - first_number, - request.last_block.0.as_(), - remote_max.as_(), - &request.key) - .map(|pairs| pairs.into_iter().map(|(b, x)| (As::sa(b), x)).collect()) - .map_err(|err| ClientErrorKind::ChangesTrieAccessFailed(err).into()) + self.check_changes_proof_with_cht_size(request, remote_proof, cht::SIZE) } } -/// A view of HashMap as a changes trie roots storage. -struct RootsStorage<'a, Hash: 'a> { - first: u64, - roots: &'a [Hash], +/// A view of BTreeMap as a changes trie roots storage. +struct RootsStorage<'a, Number: As, Hash: 'a> { + roots: (Number, &'a [Hash]), + prev_roots: BTreeMap, } -impl<'a, H, Hash> ChangesTrieRootsStorage for RootsStorage<'a, Hash> +impl<'a, H, Number, Hash> ChangesTrieRootsStorage for RootsStorage<'a, Number, Hash> where H: Hasher, + Number: Send + Sync + Eq + ::std::cmp::Ord + Copy + As, Hash: 'a + Send + Sync + Clone + AsRef<[u8]>, { - fn root(&self, block: u64) -> Result, String> { - Ok(block.checked_sub(self.first) - .and_then(|index| self.roots.get(index as usize)) - .cloned() - .map(|root| { - let mut hasher_root: H::Out = Default::default(); - hasher_root.as_mut().copy_from_slice(root.as_ref()); - hasher_root - })) + fn root(&self, _anchor: &ChangesTrieAnchorBlockId, block: u64) -> Result, String> { + // we can't ask for roots from parallel forks here => ignore anchor + let root = if block < self.roots.0.as_() { + self.prev_roots.get(&As::sa(block)).cloned() + } else { + block.checked_sub(self.roots.0.as_()) + .and_then(|index| self.roots.1.get(index as usize)) + .cloned() + }; + + Ok(root.map(|root| { + let mut hasher_root: H::Out = Default::default(); + hasher_root.as_mut().copy_from_slice(root.as_ref()); + hasher_root + })) } } @@ -264,29 +390,30 @@ impl<'a, H, Hash> ChangesTrieRootsStorage for RootsStorage<'a, Hash> pub mod tests { use futures::future::{ok, err, FutureResult}; use parking_lot::Mutex; - use call_executor::CallResult; - use client::tests::prepare_client_with_key_changes; + use keyring::Keyring; + use crate::client::tests::prepare_client_with_key_changes; use executor::{self, NativeExecutionDispatch}; - use error::Error as ClientError; - use test_client::{self, TestClient}; + use crate::error::Error as ClientError; + use test_client::{self, TestClient, blockchain::HeaderBackend}; use test_client::runtime::{self, Hash, Block, Header}; use consensus::BlockOrigin; - use in_mem::{Blockchain as InMemoryBlockchain}; - use light::fetcher::{Fetcher, FetchChecker, LightDataChecker, + use crate::in_mem::{Blockchain as InMemoryBlockchain}; + use crate::light::fetcher::{Fetcher, FetchChecker, LightDataChecker, RemoteCallRequest, RemoteHeaderRequest}; - use primitives::{Blake2Hasher}; - use primitives::storage::well_known_keys; + use crate::light::blockchain::tests::{DummyStorage, DummyBlockchain}; + use primitives::{twox_128, Blake2Hasher}; + use primitives::storage::{StorageKey, well_known_keys}; use runtime_primitives::generic::BlockId; use state_machine::Backend; use super::*; - pub type OkCallFetcher = Mutex; + pub type OkCallFetcher = Mutex>; impl Fetcher for OkCallFetcher { type RemoteHeaderResult = FutureResult; type RemoteReadResult = FutureResult>, ClientError>; - type RemoteCallResult = FutureResult; + type RemoteCallResult = FutureResult, ClientError>; type RemoteChangesResult = FutureResult, u32)>, ClientError>; fn remote_header(&self, _request: RemoteHeaderRequest
) -> Self::RemoteHeaderResult { @@ -306,10 +433,9 @@ pub mod tests { } } - fn prepare_for_read_proof_check() -> ( - LightDataChecker, Blake2Hasher>, - Header, Vec>, usize) - { + type TestChecker = LightDataChecker, Blake2Hasher, Block, DummyStorage, OkCallFetcher>; + + fn prepare_for_read_proof_check() -> (TestChecker, Header, Vec>, usize) { // prepare remote client let remote_client = test_client::new(); let remote_block_id = BlockId::Number(0); @@ -328,24 +454,22 @@ pub mod tests { remote_block_header.clone(), None, None, - ::backend::NewBlockState::Final, + crate::backend::NewBlockState::Final, ).unwrap(); let local_executor = test_client::LocalExecutor::new(); - let local_checker = LightDataChecker::new(local_executor); + let local_checker = LightDataChecker::new(Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor); (local_checker, remote_block_header, remote_read_proof, authorities_len) } - fn prepare_for_header_proof_check(insert_cht: bool) -> ( - LightDataChecker, Blake2Hasher>, - Hash, Header, Vec>) - { + fn prepare_for_header_proof_check(insert_cht: bool) -> (TestChecker, Hash, Header, Vec>) { // prepare remote client let remote_client = test_client::new(); let mut local_headers_hashes = Vec::new(); for i in 0..4 { let builder = remote_client.new_block().unwrap(); - remote_client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); - local_headers_hashes.push(remote_client.block_hash(i + 1).unwrap()); + remote_client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + local_headers_hashes.push(remote_client.block_hash(i + 1) + .map_err(|_| ClientErrorKind::Backend("TestError".into()).into())); } // 'fetch' header proof from remote node @@ -354,12 +478,12 @@ pub mod tests { // check remote read proof locally let local_storage = InMemoryBlockchain::::new(); - let local_cht_root = cht::compute_root::(4, 0, local_headers_hashes.into_iter()).unwrap(); + let local_cht_root = cht::compute_root::(4, 0, local_headers_hashes).unwrap(); if insert_cht { local_storage.insert_cht_root(1, local_cht_root); } let local_executor = test_client::LocalExecutor::new(); - let local_checker = LightDataChecker::new(local_executor); + let local_checker = LightDataChecker::new(Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor); (local_checker, local_cht_root, remote_block_header, remote_header_proof) } @@ -407,10 +531,12 @@ pub mod tests { } #[test] - fn changes_proof_is_generated_and_checked() { + fn changes_proof_is_generated_and_checked_when_headers_are_not_pruned() { let (remote_client, local_roots, test_cases) = prepare_client_with_key_changes(); - let local_checker = LightDataChecker::<_, Blake2Hasher>::new( - test_client::LocalExecutor::new()); + let local_checker = TestChecker::new( + Arc::new(DummyBlockchain::new(DummyStorage::new())), + test_client::LocalExecutor::new() + ); let local_checker = &local_checker as &FetchChecker; let max = remote_client.info().unwrap().chain.best_number; let max_hash = remote_client.info().unwrap().chain.best_hash; @@ -420,8 +546,9 @@ pub mod tests { let end_hash = remote_client.block_hash(end).unwrap().unwrap(); // 'fetch' changes proof from remote node - let (remote_max, remote_proof) = remote_client.key_changes_proof( - begin_hash, end_hash, max_hash, &key + let key = StorageKey(key); + let remote_proof = remote_client.key_changes_proof( + begin_hash, end_hash, begin_hash, max_hash, &key ).unwrap(); // check proof on local client @@ -431,12 +558,16 @@ pub mod tests { first_block: (begin, begin_hash), last_block: (end, end_hash), max_block: (max, max_hash), - tries_roots: local_roots_range, - key: key, + tries_roots: (begin, begin_hash, local_roots_range), + key: key.0, retry_count: None, }; - let local_result = local_checker.check_changes_proof( - &request, remote_max, remote_proof).unwrap(); + let local_result = local_checker.check_changes_proof(&request, ChangesProof { + max_block: remote_proof.max_block, + proof: remote_proof.proof, + roots: remote_proof.roots, + roots_proof: remote_proof.roots_proof, + }).unwrap(); // ..and ensure that result is the same as on remote node match local_result == expected_result { @@ -447,11 +578,61 @@ pub mod tests { } } + #[test] + fn changes_proof_is_generated_and_checked_when_headers_are_pruned() { + // we're testing this test case here: + // (1, 4, dave.clone(), vec![(4, 0), (1, 1), (1, 0)]), + let (remote_client, remote_roots, _) = prepare_client_with_key_changes(); + let dave = twox_128(&runtime::system::balance_of_key(Keyring::Dave.to_raw_public().into())).to_vec(); + let dave = StorageKey(dave); + + // 'fetch' changes proof from remote node: + // we're fetching changes for range b1..b4 + // we do not know changes trie roots before b3 (i.e. we only know b3+b4) + // but we have changes trie CHT root for b1...b4 + let b1 = remote_client.block_hash_from_id(&BlockId::Number(1)).unwrap().unwrap(); + let b3 = remote_client.block_hash_from_id(&BlockId::Number(3)).unwrap().unwrap(); + let b4 = remote_client.block_hash_from_id(&BlockId::Number(4)).unwrap().unwrap(); + let remote_proof = remote_client.key_changes_proof_with_cht_size( + b1, b4, b3, b4, &dave, 4 + ).unwrap(); + + // prepare local checker, having a root of changes trie CHT#0 + let local_cht_root = cht::compute_root::(4, 0, remote_roots.iter().cloned().map(|ct| Ok(Some(ct)))).unwrap(); + let mut local_storage = DummyStorage::new(); + local_storage.changes_tries_cht_roots.insert(0, local_cht_root); + let local_checker = TestChecker::new( + Arc::new(DummyBlockchain::new(local_storage)), + test_client::LocalExecutor::new() + ); + + // check proof on local client + let request = RemoteChangesRequest::
{ + changes_trie_config: runtime::changes_trie_config(), + first_block: (1, b1), + last_block: (4, b4), + max_block: (4, b4), + tries_roots: (3, b3, vec![remote_roots[2].clone(), remote_roots[3].clone()]), + key: dave.0, + retry_count: None, + }; + let local_result = local_checker.check_changes_proof_with_cht_size(&request, ChangesProof { + max_block: remote_proof.max_block, + proof: remote_proof.proof, + roots: remote_proof.roots, + roots_proof: remote_proof.roots_proof, + }, 4).unwrap(); + + assert_eq!(local_result, vec![(4, 0), (1, 1), (1, 0)]); + } + #[test] fn check_changes_proof_fails_if_proof_is_wrong() { let (remote_client, local_roots, test_cases) = prepare_client_with_key_changes(); - let local_checker = LightDataChecker::<_, Blake2Hasher>::new( - test_client::LocalExecutor::new()); + let local_checker = TestChecker::new( + Arc::new(DummyBlockchain::new(DummyStorage::new())), + test_client::LocalExecutor::new() + ); let local_checker = &local_checker as &FetchChecker; let max = remote_client.info().unwrap().chain.best_number; let max_hash = remote_client.info().unwrap().chain.best_hash; @@ -461,24 +642,88 @@ pub mod tests { let end_hash = remote_client.block_hash(end).unwrap().unwrap(); // 'fetch' changes proof from remote node - let (remote_max, mut remote_proof) = remote_client.key_changes_proof( - begin_hash, end_hash, max_hash, &key).unwrap(); + let key = StorageKey(key); + let remote_proof = remote_client.key_changes_proof( + begin_hash, end_hash, begin_hash, max_hash, &key).unwrap(); + let local_roots_range = local_roots.clone()[(begin - 1) as usize..].to_vec(); let request = RemoteChangesRequest::
{ changes_trie_config: runtime::changes_trie_config(), first_block: (begin, begin_hash), last_block: (end, end_hash), max_block: (max, max_hash), - tries_roots: local_roots_range.clone(), - key: key, + tries_roots: (begin, begin_hash, local_roots_range.clone()), + key: key.0, retry_count: None, }; // check proof on local client using max from the future - assert!(local_checker.check_changes_proof(&request, remote_max + 1, remote_proof.clone()).is_err()); + assert!(local_checker.check_changes_proof(&request, ChangesProof { + max_block: remote_proof.max_block + 1, + proof: remote_proof.proof.clone(), + roots: remote_proof.roots.clone(), + roots_proof: remote_proof.roots_proof.clone(), + }).is_err()); // check proof on local client using broken proof - remote_proof = local_roots_range.into_iter().map(|v| v.as_bytes().to_vec()).collect(); - assert!(local_checker.check_changes_proof(&request, remote_max, remote_proof).is_err()); + assert!(local_checker.check_changes_proof(&request, ChangesProof { + max_block: remote_proof.max_block, + proof: local_roots_range.clone().into_iter().map(|v| v.as_ref().to_vec()).collect(), + roots: remote_proof.roots, + roots_proof: remote_proof.roots_proof, + }).is_err()); + + // extra roots proofs are provided + assert!(local_checker.check_changes_proof(&request, ChangesProof { + max_block: remote_proof.max_block, + proof: remote_proof.proof.clone(), + roots: vec![(begin - 1, Default::default())].into_iter().collect(), + roots_proof: vec![], + }).is_err()); + assert!(local_checker.check_changes_proof(&request, ChangesProof { + max_block: remote_proof.max_block, + proof: remote_proof.proof.clone(), + roots: vec![(end + 1, Default::default())].into_iter().collect(), + roots_proof: vec![], + }).is_err()); + } + + #[test] + fn check_changes_tries_proof_fails_if_proof_is_wrong() { + // we're testing this test case here: + // (1, 4, dave.clone(), vec![(4, 0), (1, 1), (1, 0)]), + let (remote_client, remote_roots, _) = prepare_client_with_key_changes(); + let local_cht_root = cht::compute_root::( + 4, 0, remote_roots.iter().cloned().map(|ct| Ok(Some(ct)))).unwrap(); + let dave = twox_128(&runtime::system::balance_of_key(Keyring::Dave.to_raw_public().into())).to_vec(); + let dave = StorageKey(dave); + + // 'fetch' changes proof from remote node: + // we're fetching changes for range b1..b4 + // we do not know changes trie roots before b3 (i.e. we only know b3+b4) + // but we have changes trie CHT root for b1...b4 + let b1 = remote_client.block_hash_from_id(&BlockId::Number(1)).unwrap().unwrap(); + let b3 = remote_client.block_hash_from_id(&BlockId::Number(3)).unwrap().unwrap(); + let b4 = remote_client.block_hash_from_id(&BlockId::Number(4)).unwrap().unwrap(); + let remote_proof = remote_client.key_changes_proof_with_cht_size( + b1, b4, b3, b4, &dave, 4 + ).unwrap(); + + // fails when changes trie CHT is missing from the local db + let local_checker = TestChecker::new( + Arc::new(DummyBlockchain::new(DummyStorage::new())), + test_client::LocalExecutor::new() + ); + assert!(local_checker.check_changes_tries_proof(4, &remote_proof.roots, + remote_proof.roots_proof.clone()).is_err()); + + // fails when proof is broken + let mut local_storage = DummyStorage::new(); + local_storage.changes_tries_cht_roots.insert(0, local_cht_root); + let local_checker = TestChecker::new( + Arc::new(DummyBlockchain::new(local_storage)), + test_client::LocalExecutor::new() + ); + assert!(local_checker.check_changes_tries_proof(4, &remote_proof.roots, vec![]).is_err()); } } diff --git a/core/client/src/light/mod.rs b/core/client/src/light/mod.rs index 8791e2930fbad0784093de1ac608b9e82564920b..4dc25affd126fed4cc35f87548213e925623cdcf 100644 --- a/core/client/src/light/mod.rs +++ b/core/client/src/light/mod.rs @@ -28,12 +28,12 @@ use runtime_primitives::BuildStorage; use runtime_primitives::traits::Block as BlockT; use state_machine::{CodeExecutor, ExecutionStrategy}; -use client::Client; -use error::Result as ClientResult; -use light::backend::Backend; -use light::blockchain::{Blockchain, Storage as BlockchainStorage}; -use light::call_executor::RemoteCallExecutor; -use light::fetcher::{Fetcher, LightDataChecker}; +use crate::client::Client; +use crate::error::Result as ClientResult; +use crate::light::backend::Backend; +use crate::light::blockchain::{Blockchain, Storage as BlockchainStorage}; +use crate::light::call_executor::RemoteCallExecutor; +use crate::light::fetcher::{Fetcher, LightDataChecker}; use hash_db::Hasher; /// Create an instance of light client blockchain backend. @@ -48,11 +48,11 @@ pub fn new_light_backend, F: Fetcher>(bloc } /// Create an instance of light client. -pub fn new_light( +pub fn new_light( backend: Arc>, fetcher: Arc, genesis_storage: GS, -) -> ClientResult, RemoteCallExecutor, F, Blake2Hasher>, B>> +) -> ClientResult, RemoteCallExecutor, F, Blake2Hasher>, B, RA>> where B: BlockT, S: BlockchainStorage, @@ -65,13 +65,14 @@ where } /// Create an instance of fetch data checker. -pub fn new_fetch_checker( +pub fn new_fetch_checker, F>( + blockchain: Arc>, executor: E, -) -> LightDataChecker +) -> LightDataChecker where E: CodeExecutor, H: Hasher, { - LightDataChecker::new(executor) + LightDataChecker::new(blockchain, executor) } diff --git a/core/client/src/runtime_api.rs b/core/client/src/runtime_api.rs new file mode 100644 index 0000000000000000000000000000000000000000..fbe5d1378ba0f5602d0f0bdffe2121d060e81f26 --- /dev/null +++ b/core/client/src/runtime_api.rs @@ -0,0 +1,119 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! All the functionality required for declaring and implementing runtime apis. + +#[doc(hidden)] +#[cfg(feature = "std")] +pub use state_machine::OverlayedChanges; +#[doc(hidden)] +#[cfg(feature = "std")] +pub use primitives::NativeOrEncoded; +#[doc(hidden)] +pub use runtime_primitives::{ + traits::{AuthorityIdFor, Block as BlockT, GetNodeBlockType, GetRuntimeBlockType, ApiRef, RuntimeApiInfo}, + generic::BlockId, transaction_validity::TransactionValidity +}; +#[doc(hidden)] +pub use runtime_version::{ApiId, RuntimeVersion, ApisVec, create_apis_vec}; +#[doc(hidden)] +pub use rstd::{slice, mem}; +#[cfg(feature = "std")] +use rstd::result; +pub use codec::{Encode, Decode}; +#[cfg(feature = "std")] +use crate::error; +use rstd::vec::Vec; +use sr_api_macros::decl_runtime_apis; +use primitives::OpaqueMetadata; +#[cfg(feature = "std")] +use std::panic::UnwindSafe; + +/// Something that can be constructed to a runtime api. +#[cfg(feature = "std")] +pub trait ConstructRuntimeApi> { + /// The actual runtime api that will be constructed. + type RuntimeApi; + + /// Construct an instance of the runtime api. + fn construct_runtime_api<'a>(call: &'a C) -> ApiRef<'a, Self::RuntimeApi>; +} + +/// An extension for the `RuntimeApi`. +#[cfg(feature = "std")] +pub trait ApiExt { + /// 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>( + &self, + map_call: F + ) -> result::Result where Self: Sized; + + /// Checks if the given api is implemented and versions match. + fn has_api( + &self, + at: &BlockId + ) -> error::Result where Self: Sized; +} + +/// Something that can call into the runtime at a given block. +#[cfg(feature = "std")] +pub trait CallRuntimeAt { + /// Calls the given api function with the given encoded arguments at the given block + /// and returns the encoded result. + fn call_api_at R + UnwindSafe>( + &self, + at: &BlockId, + function: &'static str, + args: Vec, + changes: &mut OverlayedChanges, + initialised_block: &mut Option>, + native_call: Option, + ) -> error::Result>; + + /// Returns the runtime version at the given block. + fn runtime_version_at(&self, at: &BlockId) -> error::Result; +} + +decl_runtime_apis! { + /// The `Core` api trait that is mandantory for each runtime. + #[core_trait] + pub trait Core { + /// Returns the version of the runtime. + fn version() -> RuntimeVersion; + /// Returns the authorities. + fn authorities() -> Vec>; + /// Execute the given block. + fn execute_block(block: Block); + /// Initialise a block with the given header. + fn initialise_block(header: &::Header); + } + + /// The `Metadata` api trait that returns metadata for the runtime. + pub trait Metadata { + /// Returns the metadata of a runtime. + fn metadata() -> OpaqueMetadata; + } + + /// The `TaggedTransactionQueue` api trait for interfering with the new transaction queue. + pub trait TaggedTransactionQueue { + /// Validate the given transaction. + fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity; + } +} diff --git a/core/consensus/aura/Cargo.toml b/core/consensus/aura/Cargo.toml index 0f403ab2ff65f59b9039e55fa42c5267d5cc3bfb..2cc5c6cfa36d77c628204be5fa771bcb6962a57b 100644 --- a/core/consensus/aura/Cargo.toml +++ b/core/consensus/aura/Cargo.toml @@ -2,41 +2,30 @@ name = "substrate-consensus-aura" version = "0.1.0" authors = ["Parity Technologies "] -description = "Rhododendron Round-Based consensus-algorithm for substrate" +description = "Aura consensus algorithm for substrate" [dependencies] -futures = "0.1.17" -parity-codec = { version = "2.1" } -substrate-consensus-common = { path = "../common" } +parity-codec = "2.2" substrate-client = { path = "../../client" } substrate-primitives = { path = "../../primitives" } -substrate-network = { path = "../../network" } srml-support = { path = "../../../srml/support" } sr-primitives = { path = "../../sr-primitives" } sr-version = { path = "../../sr-version" } sr-io = { path = "../../sr-io" } +substrate-consensus-aura-primitives = { path = "primitives" } + srml-consensus = { path = "../../../srml/consensus" } +futures = "0.1.17" tokio = "0.1.7" -parking_lot = "0.4" +parking_lot = "0.7.1" error-chain = "0.12" log = "0.3" +substrate-consensus-common = { path = "../common" } [dev-dependencies] substrate-keyring = { path = "../../keyring" } substrate-executor = { path = "../../executor" } +substrate-network = { path = "../../network", features = ["test-helpers"]} substrate-service = { path = "../../service" } substrate-test-client = { path = "../../test-client" } -env_logger = { version = "0.4" } - -[target.'cfg(test)'.dependencies] -substrate-network = { path = "../../network", features = ["test-helpers"] } - -[features] -default = ["std"] -std = [ - "substrate-primitives/std", - "srml-support/std", - "sr-primitives/std", - "sr-version/std", -] - +env_logger = "0.4" diff --git a/core/consensus/aura/primitives/Cargo.toml b/core/consensus/aura/primitives/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..ea3041c99d84ff2fbd272550b6b2a8ff0f72721f --- /dev/null +++ b/core/consensus/aura/primitives/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "substrate-consensus-aura-primitives" +version = "0.1.0" +authors = ["Parity Technologies "] +description = "Primitives for Aura consensus" + +[dependencies] +parity-codec = { version = "2.2", default-features = false } +substrate-client = { path = "../../../client", default-features = false } +substrate-primitives = { path = "../../../primitives", default-features = false } +srml-support = { path = "../../../../srml/support", default-features = false } +sr-primitives = { path = "../../../sr-primitives", default-features = false } +sr-version = { path = "../../../sr-version", default-features = false } +sr-io = { path = "../../../sr-io", default-features = false } + +[features] +default = ["std"] +std = [ + "parity-codec/std", + "substrate-client/std", + "substrate-primitives/std", + "srml-support/std", + "sr-primitives/std", + "sr-version/std", + "sr-io/std", +] diff --git a/core/consensus/aura/primitives/src/lib.rs b/core/consensus/aura/primitives/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..54e4149f52590cffcf4b8e6eb1fd37597272f22a --- /dev/null +++ b/core/consensus/aura/primitives/src/lib.rs @@ -0,0 +1,60 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Primitives for Aura. + +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate parity_codec as codec; +extern crate substrate_client as client; +extern crate substrate_primitives as primitives; +extern crate srml_support as runtime_support; +extern crate sr_io as runtime_io; +extern crate sr_primitives as runtime_primitives; + +/// The ApiIds for Aura authorship API. +pub mod id { + use client::runtime_api::ApiId; + + /// ApiId for the AuraApi trait. + pub const AURA_API: ApiId = *b"aura_api"; +} + +/// Aura consensus environmental data. Useful for block-proposing code. +pub struct AuraConsensusData { + /// The timestamp the block should be authored with. + pub timestamp: u64, + /// The slot number. + pub slot: u64, + /// The duration of the slot, in seconds. + pub slot_duration: u64, +} + +/// Runtime-APIs +pub mod api { + use client::decl_runtime_apis; + decl_runtime_apis! { + /// API necessary for block authorship with aura. + pub trait AuraApi { + /// Return the slot duration in seconds for Aura. + /// Currently, only the value provided by this type at genesis + /// will be used. + /// + /// Dynamic slot duration may be supported in the future. + fn slot_duration() -> u64; + } + } +} diff --git a/core/consensus/aura/src/lib.rs b/core/consensus/aura/src/lib.rs index 7355119074eba88b7f51fc8cf24fb5ee90a026a7..374c4d613f08bc3e8b3ee060bba0d00a3987bd2f 100644 --- a/core/consensus/aura/src/lib.rs +++ b/core/consensus/aura/src/lib.rs @@ -27,47 +27,55 @@ //! far in the future they are. extern crate parity_codec as codec; -extern crate substrate_consensus_common as consensus_common; extern crate substrate_client as client; extern crate substrate_primitives as primitives; -extern crate substrate_network as network; extern crate srml_support as runtime_support; -extern crate sr_primitives as runtime_primitives; -extern crate sr_version as runtime_version; extern crate sr_io as runtime_io; +extern crate sr_primitives as runtime_primitives; +extern crate substrate_consensus_aura_primitives as aura_primitives; + +extern crate substrate_consensus_common as consensus_common; extern crate tokio; +extern crate sr_version as runtime_version; +extern crate parking_lot; + +#[macro_use] +extern crate log; +#[macro_use] +extern crate futures; #[cfg(test)] extern crate substrate_keyring as keyring; #[cfg(test)] +extern crate substrate_network as network; +#[cfg(test)] extern crate substrate_service as service; #[cfg(test)] extern crate substrate_test_client as test_client; #[cfg(test)] extern crate env_logger; -extern crate parking_lot; - -#[macro_use] -extern crate log; - -extern crate futures; +mod slots; use std::sync::Arc; -use std::time::{Duration, Instant}; +use std::time::Duration; use codec::Encode; -use consensus_common::{Authorities, BlockImport, Environment, Proposer}; +use consensus_common::{Authorities, BlockImport, Environment, Error as ConsensusError, Proposer, ForkChoiceStrategy}; +use consensus_common::import_queue::{Verifier, BasicQueue}; use client::ChainHead; +use client::block_builder::api::BlockBuilder as BlockBuilderApi; use consensus_common::{ImportBlock, BlockOrigin}; -use runtime_primitives::{generic, generic::BlockId}; -use runtime_primitives::traits::{Block, Header, Digest, DigestItemFor}; -use network::import_queue::{Verifier, BasicQueue}; -use primitives::{AuthorityId, ed25519}; +use runtime_primitives::{generic, generic::BlockId, Justification, BasicInherentData}; +use runtime_primitives::traits::{Block, Header, Digest, DigestItemFor, DigestItem, ProvideRuntimeApi}; +use primitives::{Ed25519AuthorityId, ed25519}; use futures::{Stream, Future, IntoFuture, future::{self, Either}}; -use tokio::timer::Interval; +use tokio::timer::Timeout; +use api::AuraApi; +use slots::Slots; +pub use aura_primitives::*; pub use consensus_common::SyncOracle; /// A handle to the network. This is generally implemented by providing some @@ -82,17 +90,8 @@ pub trait Network: Clone { fn send_message(&self, slot: u64, message: Vec); } -/// Configuration for Aura consensus. -#[derive(Clone)] -pub struct Config { - /// The local authority keypair. Can be none if this is just an observer. - pub local_key: Option>, - /// The slot duration in seconds. - pub slot_duration: u64 -} - /// Get slot author for given block along with authorities. -fn slot_author(slot_num: u64, authorities: &[AuthorityId]) -> Option { +fn slot_author(slot_num: u64, authorities: &[Ed25519AuthorityId]) -> Option { if authorities.is_empty() { return None } let idx = slot_num % (authorities.len() as u64); @@ -115,6 +114,13 @@ fn duration_now() -> Option { }).ok() } +fn timestamp_and_slot_now(slot_duration: u64) -> Option<(u64, u64)> { + duration_now().map(|s| { + let s = s.as_secs(); + (s, s / slot_duration) + }) +} + /// Get the slot for now. fn slot_now(slot_duration: u64) -> Option { duration_now().map(|s| s.as_secs() / slot_duration) @@ -130,7 +136,7 @@ pub trait CompatibleDigestItem: Sized { fn as_aura_seal(&self) -> Option<(u64, &ed25519::Signature)>; } -impl CompatibleDigestItem for generic::DigestItem { +impl CompatibleDigestItem for generic::DigestItem { /// Construct a digest item which is a slot number and a signature on the /// hash. fn aura_seal(slot_number: u64, signature: ed25519::Signature) -> Self { @@ -145,79 +151,110 @@ impl CompatibleDigestItem for generic::DigestItem { } } -impl CompatibleDigestItem for generic::DigestItem { - /// Construct a digest item which is a slot number and a signature on the - /// hash. - fn aura_seal(slot_number: u64, signature: ed25519::Signature) -> Self { - generic::DigestItem::Seal(slot_number, signature) - } - /// If this item is an Aura seal, return the slot number and signature. - fn as_aura_seal(&self) -> Option<(u64, &ed25519::Signature)> { - match self { - generic::DigestItem::Seal(slot, ref sign) => Some((*slot, sign)), - _ => None - } - } +/// Start the aura worker in a separate thread. +pub fn start_aura_thread( + slot_duration: SlotDuration, + local_key: Arc, + client: Arc, + block_import: Arc, + env: Arc, + sync_oracle: SO, + on_exit: impl Future + Send + 'static, +) where + B: Block + 'static, + C: Authorities + ChainHead + Send + Sync + 'static, + E: Environment + Send + Sync + 'static, + E::Proposer: Proposer + 'static, + I: BlockImport + Send + Sync + 'static, + Error: From + From + 'static, + SO: SyncOracle + Send + Clone + 'static, + DigestItemFor: CompatibleDigestItem + DigestItem + 'static, + Error: ::std::error::Error + Send + From<::consensus_common::Error> + 'static, +{ + use tokio::runtime::current_thread::Runtime; + + ::std::thread::spawn(move || { + let mut runtime = match Runtime::new() { + Ok(r) => r, + Err(e) => { + warn!("Unable to start authorship: {:?}", e); + return; + } + }; + + let _ = runtime.block_on(start_aura( + slot_duration, + local_key, + client, + block_import, + env, + sync_oracle, + on_exit, + )); + }); } -/// Start the aura worker. This should be run in a tokio runtime. -pub fn start_aura( - config: Config, +/// Start the aura worker. The returned future should be run in a tokio runtime. +pub fn start_aura( + slot_duration: SlotDuration, + local_key: Arc, client: Arc, + block_import: Arc, env: Arc, sync_oracle: SO, -) - -> impl Future where + on_exit: impl Future, +) -> impl Future where B: Block, - C: Authorities + BlockImport + ChainHead, - E: Environment, - E::Proposer: Proposer, + C: Authorities + ChainHead, + E: Environment, + E::Proposer: Proposer, + I: BlockImport, + Error: From + From, SO: SyncOracle + Send + Clone, - DigestItemFor: CompatibleDigestItem, + DigestItemFor: CompatibleDigestItem + DigestItem, Error: ::std::error::Error + Send + 'static + From<::consensus_common::Error>, { let make_authorship = move || { - let config = config.clone(); + let client = client.clone(); + let pair = local_key.clone(); + let block_import = block_import.clone(); let env = env.clone(); let sync_oracle = sync_oracle.clone(); + let SlotDuration(slot_duration) = slot_duration; + + // rather than use a timer interval, we schedule our waits ourselves + Slots::new(slot_duration) + .map_err(|e| debug!(target: "aura", "Faulty timer: {:?}", e)) + .for_each(move |slot_info| { + let client = client.clone(); + let pair = pair.clone(); + let block_import = block_import.clone(); + let env = env.clone(); + let sync_oracle = sync_oracle.clone(); + let public_key = pair.public(); + + // only propose when we are not syncing. + if sync_oracle.is_major_syncing() { + debug!(target: "aura", "Skipping proposal slot due to sync."); + return Either::B(future::ok(())); + } - let local_keys = config.local_key.map(|pair| (pair.public(), pair)); - let slot_duration = config.slot_duration; - let mut last_authored_slot = 0; - let next_slot_start = duration_now().map(|now| { - let remaining_full_secs = slot_duration - (now.as_secs() % slot_duration) - 1; - let remaining_nanos = 1_000_000_000 - now.subsec_nanos(); - Instant::now() + Duration::new(remaining_full_secs, remaining_nanos) - }).unwrap_or_else(|| Instant::now()); - - Interval::new(next_slot_start, Duration::from_secs(slot_duration)) - .filter(move |_| !sync_oracle.is_major_syncing()) // only propose when we are not syncing. - .filter_map(move |_| local_keys.clone()) // skip if not authoring. - .map_err(|e| debug!(target: "aura", "Faulty timer: {:?}", e)) - .for_each(move |(public_key, key)| { - use futures::future; - - let slot_num = match slot_now(slot_duration) { - Some(n) => n, - None => return Either::B(future::err(())), - }; - - if last_authored_slot >= slot_num { return Either::B(future::ok(())) } - last_authored_slot = slot_num; - + let (timestamp, slot_num) = (slot_info.timestamp, slot_info.number); let chain_head = match client.best_block_header() { Ok(x) => x, Err(e) => { - warn!(target:"aura", "Unable to author block in slot {}. no best block header: {:?}", slot_num, e); + warn!(target:"aura", "Unable to author block in slot {}. \ + no best block header: {:?}", slot_num, e); return Either::B(future::ok(())) } }; - let authorities = match client.authorities(&BlockId::Hash(chain_head.hash())){ + let authorities = match client.authorities(&BlockId::Hash(chain_head.hash())) { Ok(authorities) => authorities, Err(e) => { - warn!("Unable to fetch authorities at block {:?}: {:?}", chain_head.hash(), e); + warn!("Unable to fetch authorities at\ + block {:?}: {:?}", chain_head.hash(), e); return Either::B(future::ok(())); } }; @@ -225,8 +262,11 @@ pub fn start_aura( let proposal_work = match slot_author(slot_num, &authorities) { None => return Either::B(future::ok(())), Some(author) => if author.0 == public_key.0 { + debug!(target: "aura", "Starting authorship at slot {}; timestamp = {}", + slot_num, timestamp); + // we are the slot author. make a block and sign it. - let proposer = match env.init(&chain_head, &authorities, key.clone()) { + let proposer = match env.init(&chain_head, &authorities) { Ok(p) => p, Err(e) => { warn!("Unable to author block in slot {:?}: {:?}", slot_num, e); @@ -234,36 +274,69 @@ pub fn start_aura( } }; - proposer.propose().into_future() + let consensus_data = AuraConsensusData { + timestamp, + slot: slot_num, + slot_duration, + }; + + // deadline our production to approx. the end of the + // slot + Timeout::new( + proposer.propose(consensus_data).into_future(), + slot_info.remaining_duration(), + ) } else { return Either::B(future::ok(())); } }; - let block_import = client.clone(); + let block_import = block_import.clone(); Either::A(proposal_work .map(move |b| { + // minor hack since we don't have access to the timestamp + // that is actually set by the proposer. + let slot_after_building = slot_now(slot_duration); + if slot_after_building != Some(slot_num) { + info!("Discarding proposal for slot {}; block production took too long", + slot_num); + return + } + let (header, body) = b.deconstruct(); + let header_num = header.number().clone(); let pre_hash = header.hash(); let parent_hash = header.parent_hash().clone(); // sign the pre-sealed hash of the block and then // add it to a digest item. let to_sign = (slot_num, pre_hash).encode(); - let signature = key.sign(&to_sign[..]); - let item = as CompatibleDigestItem>::aura_seal(slot_num, signature); - let import_block = ImportBlock { + let signature = pair.sign(&to_sign[..]); + let item = as CompatibleDigestItem>::aura_seal( + slot_num, + signature, + ); + + let import_block: ImportBlock = ImportBlock { origin: BlockOrigin::Own, header, - external_justification: Vec::new(), - post_runtime_digests: vec![item], + justification: None, + post_digests: vec![item], body: Some(body), finalized: false, auxiliary: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, }; + info!("Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.", + header_num, + import_block.post_header().hash(), + pre_hash + ); + if let Err(e) = block_import.import_block(import_block, None) { - warn!(target: "aura", "Error with block built on {:?}: {:?}", parent_hash, e); + warn!(target: "aura", "Error with block built on {:?}: {:?}", + parent_hash, e); } }) .map_err(|e| warn!("Failed to construct block: {:?}", e)) @@ -271,7 +344,7 @@ pub fn start_aura( }) }; - future::loop_fn((), move |()| { + let work = future::loop_fn((), move |()| { let authorship_task = ::std::panic::AssertUnwindSafe(make_authorship()); authorship_task.catch_unwind().then(|res| { match res { @@ -288,7 +361,9 @@ pub fn start_aura( Ok(future::Loop::Continue(())) }) - }) + }); + + work.select(on_exit).then(|_| Ok(())) } // a header which has been checked @@ -301,12 +376,11 @@ enum CheckedHeader { Checked(H, u64, ed25519::Signature), } - /// check a header has been signed by the right key. If the slot is too far in the future, an error will be returned. /// if it's successful, returns the pre-header, the slot number, and the signat. // // FIXME: needs misbehavior types - https://github.com/paritytech/substrate/issues/1018 -fn check_header(slot_now: u64, mut header: B::Header, hash: B::Hash, authorities: &[AuthorityId]) +fn check_header(slot_now: u64, mut header: B::Header, hash: B::Hash, authorities: &[Ed25519AuthorityId]) -> Result, String> where DigestItemFor: CompatibleDigestItem { @@ -343,30 +417,68 @@ fn check_header(slot_now: u64, mut header: B::Header, hash: B::Hash, a } } +/// Extra verification for Aura blocks. +pub trait ExtraVerification: Send + Sync { + /// Future that resolves when the block is verified or fails with error if not. + type Verified: IntoFuture; + + /// Do additional verification for this block. + fn verify( + &self, + header: &B::Header, + body: Option<&[B::Extrinsic]>, + ) -> Self::Verified; +} + /// A verifier for Aura blocks. -pub struct AuraVerifier { - config: Config, +pub struct AuraVerifier { + slot_duration: SlotDuration, client: Arc, + make_inherent: MakeInherent, + extra: E, } -impl Verifier for AuraVerifier where - C: Authorities + BlockImport + Send + Sync, - DigestItemFor: CompatibleDigestItem, +/// No-op extra verification. +#[derive(Debug, Clone, Copy)] +pub struct NothingExtra; + +impl ExtraVerification for NothingExtra { + type Verified = Result<(), String>; + + fn verify(&self, _: &B::Header, _: Option<&[B::Extrinsic]>) -> Self::Verified { + Ok(()) + } +} + +impl Verifier for AuraVerifier where + C: Authorities + BlockImport + ProvideRuntimeApi + Send + Sync, + C::Api: BlockBuilderApi, + DigestItemFor: CompatibleDigestItem + DigestItem, + E: ExtraVerification, + MakeInherent: Fn(u64, u64) -> Inherent + Send + Sync, { fn verify( &self, origin: BlockOrigin, header: B::Header, - _justification: Vec, - body: Option> - ) -> Result<(ImportBlock, Option>), String> { - let slot_now = slot_now(self.config.slot_duration) + justification: Option, + mut body: Option>, + ) -> Result<(ImportBlock, Option>), String> { + use runtime_primitives::CheckInherentError; + const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; + + let (timestamp_now, slot_now) = timestamp_and_slot_now(self.slot_duration.0) .ok_or("System time is before UnixTime?".to_owned())?; let hash = header.hash(); let parent_hash = *header.parent_hash(); let authorities = self.client.authorities(&BlockId::Hash(parent_hash)) .map_err(|e| format!("Could not fetch authorities at {:?}: {:?}", parent_hash, e))?; + let extra_verification = self.extra.verify( + &header, + body.as_ref().map(|x| &x[..]), + ); + // we add one to allow for some small drift. // FIXME: in the future, alter this queue to allow deferring of headers // https://github.com/paritytech/substrate/issues/1019 @@ -375,16 +487,52 @@ impl Verifier for AuraVerifier where CheckedHeader::Checked(pre_header, slot_num, sig) => { let item = >::aura_seal(slot_num, sig); - debug!(target: "aura", "Checked {:?}; importing.", pre_header); + // if the body is passed through, we need to use the runtime + // to check that the internally-set timestamp in the inherents + // actually matches the slot set in the seal. + if let Some(inner_body) = body.take() { + let inherent = (self.make_inherent)(timestamp_now, slot_num); + let block: B = Block::new(pre_header.clone(), inner_body); + + let inherent_res = self.client.runtime_api().check_inherents( + &BlockId::Hash(parent_hash), + block.clone(), + inherent, + ).map_err(|e| format!("{:?}", e))?; + + match inherent_res { + Ok(()) => {} + Err(CheckInherentError::ValidAtTimestamp(timestamp)) => { + // halt import until timestamp is valid. + // reject when too far ahead. + if timestamp > timestamp_now + MAX_TIMESTAMP_DRIFT_SECS { + return Err("Rejecting block too far in future".into()); + } + + let diff = timestamp.saturating_sub(timestamp_now); + info!(target: "aura", "halting for block {} seconds in the future", diff); + ::std::thread::sleep(Duration::from_secs(diff)); + }, + Err(CheckInherentError::Other(s)) => return Err(s.into_owned()), + } + + let (_, inner_body) = block.deconstruct(); + body = Some(inner_body); + } + + trace!(target: "aura", "Checked {:?}; importing.", pre_header); + + extra_verification.into_future().wait()?; let import_block = ImportBlock { origin, header: pre_header, - external_justification: Vec::new(), - post_runtime_digests: vec![item], + post_digests: vec![item], body, finalized: false, + justification, auxiliary: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, }; // FIXME: extract authorities - https://github.com/paritytech/substrate/issues/1019 @@ -398,21 +546,75 @@ impl Verifier for AuraVerifier where } } +/// A utility for making the basic-inherent data. +pub fn make_basic_inherent(timestamp: u64, slot_now: u64) -> BasicInherentData { + BasicInherentData::new(timestamp, slot_now) +} + +/// A type for a function which produces inherent. +pub type InherentProducingFn = fn(u64, u64) -> I; + /// The Aura import queue type. -pub type AuraImportQueue = BasicQueue>; +pub type AuraImportQueue = BasicQueue>; + +/// A slot duration. Create with `get_or_compute`. +// The internal member should stay private here. +#[derive(Clone, Copy, Debug)] +pub struct SlotDuration(u64); + +impl SlotDuration { + /// Either fetch the slot duration from disk or compute it from the genesis + /// state. + pub fn get_or_compute(client: &C) -> ::client::error::Result where + C: ::client::backend::AuxStore, + C: ProvideRuntimeApi, + C::Api: AuraApi, + { + use codec::Decode; + const SLOT_KEY: &[u8] = b"aura_slot_duration"; + + match client.get_aux(SLOT_KEY)? { + Some(v) => u64::decode(&mut &v[..]) + .map(SlotDuration) + .ok_or_else(|| ::client::error::ErrorKind::Backend( + format!("Aura slot duration kept in invalid format"), + ).into()), + None => { + use runtime_primitives::traits::Zero; + let genesis_slot_duration = client.runtime_api() + .slot_duration(&BlockId::number(Zero::zero()))?; + + info!("Loaded block-time = {:?} seconds from genesis on first-launch", + genesis_slot_duration); + + genesis_slot_duration.using_encoded(|s| { + client.insert_aux(&[(SLOT_KEY, &s[..])], &[]) + })?; + + Ok(SlotDuration(genesis_slot_duration)) + } + } + } +} /// Start an import queue for the Aura consensus algorithm. -pub fn import_queue(config: Config, client: Arc) -> AuraImportQueue where +pub fn import_queue( + slot_duration: SlotDuration, + client: Arc, + extra: E, + make_inherent: MakeInherent, +) -> AuraImportQueue where B: Block, - C: Authorities + BlockImport + Send + Sync, - DigestItemFor: CompatibleDigestItem, + C: Authorities + BlockImport + ProvideRuntimeApi + Send + Sync, + C::Api: BlockBuilderApi, + DigestItemFor: CompatibleDigestItem + DigestItem, + E: ExtraVerification, + MakeInherent: Fn(u64, u64) -> Inherent + Send + Sync, { - let verifier = Arc::new(AuraVerifier { config, client }); - BasicQueue::new(verifier) + let verifier = Arc::new(AuraVerifier { slot_duration, client: client.clone(), extra, make_inherent }); + BasicQueue::new(verifier, client) } - - #[cfg(test)] mod tests { use super::*; @@ -420,36 +622,36 @@ mod tests { use network::test::*; use network::test::{Block as TestBlock, PeersClient}; use runtime_primitives::traits::Block as BlockT; - use network::ProtocolConfig; + use network::config::ProtocolConfig; use parking_lot::Mutex; use tokio::runtime::current_thread; use keyring::Keyring; use client::BlockchainEvents; use test_client; - type Error = client::error::Error; + type Error = ::client::error::Error; - type TestClient = client::Client; + type TestClient = ::client::Client; struct DummyFactory(Arc); struct DummyProposer(u64, Arc); - impl Environment for DummyFactory { + impl Environment for DummyFactory { type Proposer = DummyProposer; type Error = Error; - fn init(&self, parent_header: &::Header, _authorities: &[AuthorityId], _sign_with: Arc) + fn init(&self, parent_header: &::Header, _authorities: &[Ed25519AuthorityId]) -> Result { Ok(DummyProposer(parent_header.number + 1, self.0.clone())) } } - impl Proposer for DummyProposer { + impl Proposer for DummyProposer { type Error = Error; type Create = Result; - fn propose(&self) -> Result { + fn propose(&self, _consensus_data: AuraConsensusData) -> Result { self.1.new_block().unwrap().bake().map_err(|e| e.into()) } } @@ -458,12 +660,17 @@ mod tests { const TEST_ROUTING_INTERVAL: Duration = Duration::from_millis(50); pub struct AuraTestNet { - peers: Vec>>>, + peers: Vec, + >, ()>>>, started: bool } impl TestNetFactory for AuraTestNet { - type Verifier = AuraVerifier; + type Verifier = AuraVerifier>; + type PeerData = (); /// Create new test network with peers and given config. fn from_config(_config: &ProtocolConfig) -> Self { @@ -476,19 +683,28 @@ mod tests { fn make_verifier(&self, client: Arc, _cfg: &ProtocolConfig) -> Arc { - let config = Config { local_key: None, slot_duration: SLOT_DURATION }; - Arc::new(AuraVerifier { client, config }) + fn make_inherent(_: u64, _: u64) { () } + let slot_duration = SlotDuration::get_or_compute(&*client) + .expect("slot duration available"); + + assert_eq!(slot_duration.0, SLOT_DURATION); + Arc::new(AuraVerifier { + client, + slot_duration, + extra: NothingExtra, + make_inherent: make_inherent as _, + }) } - fn peer(&self, i: usize) -> &Peer { + fn peer(&self, i: usize) -> &Peer { &self.peers[i] } - fn peers(&self) -> &Vec>> { + fn peers(&self) -> &Vec>> { &self.peers } - fn mut_peers>>)>(&mut self, closure: F ) { + fn mut_peers>>)>(&mut self, closure: F) { closure(&mut self.peers); } @@ -528,14 +744,18 @@ mod tests { }) .for_each(move |_| Ok(())) ); + + let slot_duration = SlotDuration::get_or_compute(&*client) + .expect("slot duration available"); + let aura = start_aura( - Config { - local_key: Some(Arc::new(key.clone().into())), - slot_duration: SLOT_DURATION - }, + slot_duration, + Arc::new(key.clone().into()), + client.clone(), client, environ.clone(), DummyOracle, + futures::empty(), ); runtime.spawn(aura); diff --git a/core/consensus/aura/src/slots.rs b/core/consensus/aura/src/slots.rs new file mode 100644 index 0000000000000000000000000000000000000000..37db3b17636b40880573ff37c9d8baaac61095b4 --- /dev/null +++ b/core/consensus/aura/src/slots.rs @@ -0,0 +1,122 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Utility stream for yielding slots in a loop. +//! +//! This is used instead of `tokio_timer::Interval` because it was unreliable. + +use std::time::{Instant, Duration}; +use tokio::timer::Delay; +use futures::prelude::*; + +/// Returns the duration until the next slot, based on current duration since +pub(crate) fn time_until_next(now: Duration, slot_duration: u64) -> Duration { + let remaining_full_secs = slot_duration - (now.as_secs() % slot_duration) - 1; + let remaining_nanos = 1_000_000_000 - now.subsec_nanos(); + Duration::new(remaining_full_secs, remaining_nanos) +} + +/// Information about a slot. +#[derive(Debug, Clone)] +pub(crate) struct SlotInfo { + /// The slot number. + pub(crate) number: u64, + /// Current timestamp. + pub(crate) timestamp: u64, + /// The instant at which the slot ends. + pub(crate) ends_at: Instant, +} + +impl SlotInfo { + /// Yields the remaining duration in the slot. + pub(crate) fn remaining_duration(&self) -> Duration { + let now = Instant::now(); + if now < self.ends_at { + self.ends_at.duration_since(now) + } else { + Duration::from_secs(0) + } + } +} + +/// A stream that returns every time there is a new slot. +pub(crate) struct Slots { + last_slot: u64, + slot_duration: u64, + inner_delay: Option, +} + +impl Slots { + /// Create a new `slots` stream. + pub(crate) fn new(slot_duration: u64) -> Self { + Slots { + last_slot: 0, + slot_duration, + inner_delay: None, + } + } +} + +impl Stream for Slots { + type Item = SlotInfo; + type Error = tokio::timer::Error; + + fn poll(&mut self) -> Poll, Self::Error> { + let slot_duration = self.slot_duration; + self.inner_delay = match self.inner_delay.take() { + None => { + // schedule wait. + let wait_until = match ::duration_now() { + None => return Ok(Async::Ready(None)), + Some(now) => Instant::now() + time_until_next(now, slot_duration), + }; + + Some(Delay::new(wait_until)) + } + Some(d) => Some(d), + }; + + if let Some(ref mut inner_delay) = self.inner_delay { + try_ready!(inner_delay.poll()); + } + + // timeout has fired. + + let (timestamp, slot_num) = match ::timestamp_and_slot_now(slot_duration) { + None => return Ok(Async::Ready(None)), + Some(x) => x, + }; + + // reschedule delay for next slot. + let ends_at = Instant::now() + + time_until_next(Duration::from_secs(timestamp), slot_duration); + self.inner_delay = Some(Delay::new(ends_at)); + + // never yield the same slot twice. + if slot_num > self.last_slot { + self.last_slot = slot_num; + + Ok(Async::Ready(Some(SlotInfo { + number: slot_num, + timestamp, + ends_at, + }))) + } else { + // re-poll until we get a new slot. + self.poll() + } + } +} diff --git a/core/consensus/common/Cargo.toml b/core/consensus/common/Cargo.toml index 08689721a03fcba87158cce42c9fe3b8c14abbbb..f8ae47d70f2c1b5ccc9e6911f8ad890d5f3574a2 100644 --- a/core/consensus/common/Cargo.toml +++ b/core/consensus/common/Cargo.toml @@ -5,11 +5,16 @@ authors = ["Parity Technologies "] description = "Common utilities for substrate consensus" [dependencies] +log = "0.4" +parking_lot = "0.7.1" substrate-primitives = { path= "../../primitives" } error-chain = "0.12" futures = "0.1" sr-version = { path = "../../sr-version" } sr-primitives = { path = "../../sr-primitives" } tokio = "0.1.7" -parity-codec = "2.1" +parity-codec = "2.2" parity-codec-derive = "2.0" + +[dev-dependencies] +substrate-test-client = { path = "../../test-client" } diff --git a/core/consensus/common/README.adoc b/core/consensus/common/README.adoc deleted file mode 100644 index d8f9e1daf28d915bd78ed693d8f40933323aca2f..0000000000000000000000000000000000000000 --- a/core/consensus/common/README.adoc +++ /dev/null @@ -1,12 +0,0 @@ -= Consensus Common - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/consensus/common/src/block_import.rs b/core/consensus/common/src/block_import.rs index 582886d8272e1f853d6f4ee3483807c69bf48bed..4170662721f7cbd94c292eaf30fe4b1cf0dea669 100644 --- a/core/consensus/common/src/block_import.rs +++ b/core/consensus/common/src/block_import.rs @@ -1,10 +1,27 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. -use primitives::AuthorityId; -use runtime_primitives::traits::{Block as BlockT, DigestItemFor}; +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Block import helpers. + +use runtime_primitives::traits::{AuthorityIdFor, Block as BlockT, DigestItemFor, Header as HeaderT, NumberFor}; use runtime_primitives::Justification; +use std::borrow::Cow; /// Block import result. -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub enum ImportResult { /// Added to the import queue. Queued, @@ -16,6 +33,9 @@ pub enum ImportResult { KnownBad, /// Block parent is not in the chain. UnknownParent, + /// Added to the import queue but must be justified + /// (usually required to safely enact consensus changes). + NeedsJustification, } /// Block data origin. @@ -35,6 +55,15 @@ pub enum BlockOrigin { File, } +/// Fork choice strategy. +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum ForkChoiceStrategy { + /// Longest chain fork choice. + LongestChain, + /// Custom fork choice rule, where true indicates the new block should be the best block. + Custom(bool), +} + /// Data required to import a Block pub struct ImportBlock { /// Origin of the Block @@ -44,18 +73,18 @@ pub struct ImportBlock { /// /// Consensus engines which alter the header (by adding post-runtime digests) /// should strip those off in the initial verification process and pass them - /// via the `post_runtime_digests` field. During block authorship, they should + /// via the `post_digests` field. During block authorship, they should /// not be pushed to the header directly. /// /// The reason for this distinction is so the header can be directly /// re-executed in a runtime that checks digest equivalence -- the /// post-runtime digests are pushed back on after. pub header: Block::Header, - /// Justification provided for this block from the outside:. - pub external_justification: Justification, + /// Justification provided for this block from the outside. + pub justification: Option, /// Digest items that have been added after the runtime for external /// work, like a consensus signature. - pub post_runtime_digests: Vec>, + pub post_digests: Vec>, /// Block's body pub body: Option>, /// Is this block finalized already? @@ -65,6 +94,8 @@ pub struct ImportBlock { /// Contains a list of key-value pairs. If values are `None`, the keys /// will be deleted. pub auxiliary: Vec<(Vec, Option>)>, + /// Fork choice strategy of this import. + pub fork_choice: ForkChoiceStrategy, } impl ImportBlock { @@ -73,7 +104,7 @@ impl ImportBlock { -> ( BlockOrigin, ::Header, - Justification, + Option, Vec>, Option::Extrinsic>>, bool, @@ -82,23 +113,52 @@ impl ImportBlock { ( self.origin, self.header, - self.external_justification, - self.post_runtime_digests, + self.justification, + self.post_digests, self.body, self.finalized, self.auxiliary, ) } -} + /// Get a handle to full header (with post-digests applied). + pub fn post_header(&self) -> Cow { + use runtime_primitives::traits::Digest; + if self.post_digests.is_empty() { + Cow::Borrowed(&self.header) + } else { + Cow::Owned({ + let mut hdr = self.header.clone(); + for digest_item in &self.post_digests { + hdr.digest_mut().push(digest_item.clone()); + } + + hdr + }) + } + } +} /// Block import trait. pub trait BlockImport { type Error: ::std::error::Error + Send + 'static; - /// Import a Block alongside the new authorities valid form this block forward - fn import_block(&self, + + /// Called by the import queue when it is started. + fn on_start(&self, _link: &::import_queue::Link) { } + + /// Import a Block alongside the new authorities valid from this block forward + fn import_block( + &self, block: ImportBlock, - new_authorities: Option> + new_authorities: Option>>, ) -> Result; -} \ No newline at end of file + + /// Import a Block justification and finalize the given block. + fn import_justification( + &self, + hash: B::Hash, + number: NumberFor, + justification: Justification, + ) -> Result<(), Self::Error>; +} diff --git a/core/consensus/common/src/error.rs b/core/consensus/common/src/error.rs index ccf57adb9f1be04fb4960c69c7380b62520a069c..ec378d24cbd48815de5e6ff8b3fa892b8b2b6fbb 100644 --- a/core/consensus/common/src/error.rs +++ b/core/consensus/common/src/error.rs @@ -44,13 +44,13 @@ error_chain! { } /// Error checking signature - InvalidSignature(s: ::primitives::ed25519::Signature, a: ::primitives::AuthorityId) { + InvalidSignature(s: ::primitives::ed25519::Signature, a: ::primitives::Ed25519AuthorityId) { description("Message signature is invalid"), display("Message signature {:?} by {:?} is invalid.", s, a), } /// Account is not an authority. - InvalidAuthority(a: ::primitives::AuthorityId) { + InvalidAuthority(a: ::primitives::Ed25519AuthorityId) { description("Message sender is not a valid authority"), display("Message sender {:?} is not a valid authority.", a), } @@ -84,5 +84,11 @@ error_chain! { description("Other error") display("Other error: {}", e.description()) } + + /// Error from the client while importing + ClientImport(reason: String) { + description("Import failed"), + display("Import failed: {}", reason), + } } } diff --git a/core/consensus/common/src/import_queue.rs b/core/consensus/common/src/import_queue.rs new file mode 100644 index 0000000000000000000000000000000000000000..3660a59b03eec0fd7ee60cf27eb3297b2bcb61c5 --- /dev/null +++ b/core/consensus/common/src/import_queue.rs @@ -0,0 +1,485 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Import Queue primitive: something which can verify and import blocks. +//! +//! This serves as an intermediate and abstracted step between synchronization +//! and import. Each mode of consensus will have its own requirements for block verification. +//! Some algorithms can verify in parallel, while others only sequentially. +//! +//! The `ImportQueue` trait allows such verification strategies to be instantiated. +//! The `BasicQueue` and `BasicVerifier` traits allow serial queues to be +//! instantiated simply. + +use block_import::{ImportBlock, BlockImport, ImportResult, BlockOrigin}; +use std::collections::{HashSet, VecDeque}; +use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; +use parking_lot::{Condvar, Mutex, RwLock}; + +use runtime_primitives::Justification; +use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero, AuthorityIdFor}; + +use error::Error as ConsensusError; + +/// Shared block import struct used by the queue. +pub type SharedBlockImport = Arc + Send + Sync>; + +/// Maps to the Origin used by the network. +pub type Origin = usize; + +/// Block data used by the queue. +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct IncomingBlock { + /// Block header hash. + pub hash: ::Hash, + /// Block header if requested. + pub header: Option<::Header>, + /// Block body if requested. + pub body: Option::Extrinsic>>, + /// Justification if requested. + pub justification: Option, + /// The peer, we received this from + pub origin: Option, +} + +/// Verify a justification of a block +pub trait Verifier: Send + Sync + Sized { + /// Verify the given data and return the ImportBlock and an optional + /// new set of validators to import. If not, err with an Error-Message + /// presented to the User in the logs. + fn verify( + &self, + origin: BlockOrigin, + header: B::Header, + justification: Option, + body: Option> + ) -> Result<(ImportBlock, Option>>), String>; +} + +/// Blocks import queue API. +pub trait ImportQueue: Send + Sync { + /// Start background work for the queue as necessary. + /// + /// This is called automatically by the network service when synchronization + /// begins. + fn start(&self, _link: L) -> Result<(), std::io::Error> where + Self: Sized, + L: 'static + Link, + { + Ok(()) + } + /// Clear the queue when sync is restarting. + fn clear(&self); + /// Clears the import queue and stops importing. + fn stop(&self); + /// Get queue status. + fn status(&self) -> ImportQueueStatus; + /// Is block with given hash currently in the queue. + fn is_importing(&self, hash: &B::Hash) -> bool; + /// Import bunch of blocks. + fn import_blocks(&self, origin: BlockOrigin, blocks: Vec>); + /// Import a block justification. + fn import_justification(&self, hash: B::Hash, number: NumberFor, justification: Justification) -> bool; +} + +/// Import queue status. It isn't completely accurate. +pub struct ImportQueueStatus { + /// Number of blocks that are currently in the queue. + pub importing_count: usize, + /// The number of the best block that was ever in the queue since start/last failure. + pub best_importing_number: <::Header as HeaderT>::Number, +} + +/// Basic block import queue that is importing blocks sequentially in a separate thread, +/// with pluggable verification. +pub struct BasicQueue> { + handle: Mutex>>, + data: Arc>, + verifier: Arc, + block_import: SharedBlockImport, +} + +/// Locks order: queue, queue_blocks, best_importing_number +pub struct AsyncImportQueueData { + signal: Condvar, + queue: Mutex>)>>, + queue_blocks: RwLock>, + best_importing_number: RwLock<<::Header as HeaderT>::Number>, + is_stopping: AtomicBool, +} + +impl> BasicQueue { + /// Instantiate a new basic queue, with given verifier. + pub fn new(verifier: Arc, block_import: SharedBlockImport) -> Self { + Self { + handle: Mutex::new(None), + data: Arc::new(AsyncImportQueueData::new()), + verifier, + block_import, + } + } +} + +impl AsyncImportQueueData { + /// Instantiate a new async import queue data. + pub fn new() -> Self { + Self { + signal: Default::default(), + queue: Mutex::new(VecDeque::new()), + queue_blocks: RwLock::new(HashSet::new()), + best_importing_number: RwLock::new(Zero::zero()), + is_stopping: Default::default(), + } + } + + // Signals to stop importing new blocks. + pub fn stop(&self) { + self.is_stopping.store(true, Ordering::SeqCst); + } +} + +impl> ImportQueue for BasicQueue { + fn start>( + &self, + link: L, + ) -> Result<(), std::io::Error> { + debug_assert!(self.handle.lock().is_none()); + + let qdata = self.data.clone(); + let verifier = self.verifier.clone(); + let block_import = self.block_import.clone(); + *self.handle.lock() = Some(::std::thread::Builder::new().name("ImportQueue".into()).spawn(move || { + block_import.on_start(&link); + import_thread(block_import, link, qdata, verifier) + })?); + Ok(()) + } + + fn clear(&self) { + let mut queue = self.data.queue.lock(); + let mut queue_blocks = self.data.queue_blocks.write(); + let mut best_importing_number = self.data.best_importing_number.write(); + queue_blocks.clear(); + queue.clear(); + *best_importing_number = Zero::zero(); + } + + fn stop(&self) { + self.clear(); + if let Some(handle) = self.handle.lock().take() { + { + // Perform storing the stop flag and signalling under a single lock. + let _queue_lock = self.data.queue.lock(); + self.data.stop(); + self.data.signal.notify_one(); + } + + let _ = handle.join(); + } + } + + fn status(&self) -> ImportQueueStatus { + ImportQueueStatus { + importing_count: self.data.queue_blocks.read().len(), + best_importing_number: *self.data.best_importing_number.read(), + } + } + + fn is_importing(&self, hash: &B::Hash) -> bool { + self.data.queue_blocks.read().contains(hash) + } + + fn import_blocks(&self, origin: BlockOrigin, blocks: Vec>) { + if blocks.is_empty() { + return; + } + + trace!(target:"sync", "Scheduling {} blocks for import", blocks.len()); + + let mut queue = self.data.queue.lock(); + let mut queue_blocks = self.data.queue_blocks.write(); + let mut best_importing_number = self.data.best_importing_number.write(); + let new_best_importing_number = blocks.last().and_then(|b| b.header.as_ref().map(|h| h.number().clone())).unwrap_or_else(|| Zero::zero()); + queue_blocks.extend(blocks.iter().map(|b| b.hash.clone())); + if new_best_importing_number > *best_importing_number { + *best_importing_number = new_best_importing_number; + } + queue.push_back((origin, blocks)); + self.data.signal.notify_one(); + } + + fn import_justification(&self, hash: B::Hash, number: NumberFor, justification: Justification) -> bool { + self.block_import.import_justification(hash, number, justification).is_ok() + } +} + +impl> Drop for BasicQueue { + fn drop(&mut self) { + self.stop(); + } +} + +/// Blocks import thread. +fn import_thread, V: Verifier>( + block_import: SharedBlockImport, + link: L, + qdata: Arc>, + verifier: Arc +) { + trace!(target: "sync", "Starting import thread"); + loop { + let new_blocks = { + let mut queue_lock = qdata.queue.lock(); + + // We are holding the same lock that `stop` takes so here we either see that stop flag + // is active or wait for the signal. The latter one unlocks the mutex and this gives a chance + // to `stop` to generate the signal. + if qdata.is_stopping.load(Ordering::SeqCst) { + break; + } + if queue_lock.is_empty() { + qdata.signal.wait(&mut queue_lock); + } + + match queue_lock.pop_front() { + Some(new_blocks) => new_blocks, + None => break, + } + }; + + let blocks_hashes: Vec = new_blocks.1.iter().map(|b| b.hash.clone()).collect(); + if !import_many_blocks( + &*block_import, + &link, + Some(&*qdata), + new_blocks, + verifier.clone(), + ) { + break; + } + + let mut queue_blocks = qdata.queue_blocks.write(); + for blocks_hash in blocks_hashes { + queue_blocks.remove(&blocks_hash); + } + } + + trace!(target: "sync", "Stopping import thread"); +} + +/// Hooks that the verification queue can use to influence the synchronization +/// algorithm. +pub trait Link: Send { + /// Block imported. + fn block_imported(&self, _hash: &B::Hash, _number: NumberFor) { } + /// Request a justification for the given block. + fn request_justification(&self, _hash: &B::Hash, _number: NumberFor) { } + /// Maintain sync. + fn maintain_sync(&self) { } + /// Disconnect from peer. + fn useless_peer(&self, _who: Origin, _reason: &str) { } + /// Disconnect from peer and restart sync. + fn note_useless_and_restart_sync(&self, _who: Origin, _reason: &str) { } + /// Restart sync. + fn restart(&self) { } +} + +/// Block import successful result. +#[derive(Debug, PartialEq)] +pub enum BlockImportResult { + /// Imported known block. + ImportedKnown(H, N), + /// Imported unknown block. + ImportedUnknown(H, N), + /// Imported unjustified block that requires one. + ImportedUnjustified(H, N), +} + +/// Block import error. +#[derive(Debug, PartialEq)] +pub enum BlockImportError { + /// Block missed header, can't be imported + IncompleteHeader(Option), + /// Block verification failed, can't be imported + VerificationFailed(Option, String), + /// Block is known to be Bad + BadBlock(Option), + /// Block has an unknown parent + UnknownParent, + /// Other Error. + Error, +} + +/// Import a bunch of blocks. +pub fn import_many_blocks<'a, B: BlockT, V: Verifier>( + import_handle: &BlockImport, + link: &Link, + qdata: Option<&AsyncImportQueueData>, + blocks: (BlockOrigin, Vec>), + verifier: Arc +) -> bool +{ + let (blocks_origin, blocks) = blocks; + let count = blocks.len(); + let mut imported = 0; + + let blocks_range = match ( + blocks.first().and_then(|b| b.header.as_ref().map(|h| h.number())), + blocks.last().and_then(|b| b.header.as_ref().map(|h| h.number())), + ) { + (Some(first), Some(last)) if first != last => format!(" ({}..{})", first, last), + (Some(first), Some(_)) => format!(" ({})", first), + _ => Default::default(), + }; + trace!(target:"sync", "Starting import of {} blocks {}", count, blocks_range); + + // Blocks in the response/drain should be in ascending order. + for block in blocks { + let import_result = import_single_block( + import_handle, + blocks_origin.clone(), + block, + verifier.clone(), + ); + let is_import_failed = import_result.is_err(); + imported += process_import_result(link, import_result); + if is_import_failed { + qdata.map(|qdata| *qdata.best_importing_number.write() = Zero::zero()); + return true; + } + + if qdata.map(|qdata| qdata.is_stopping.load(Ordering::SeqCst)).unwrap_or_default() { + return false; + } + } + + trace!(target: "sync", "Imported {} of {}", imported, count); + link.maintain_sync(); + true +} + +/// Single block import function. +pub fn import_single_block>( + import_handle: &BlockImport, + block_origin: BlockOrigin, + block: IncomingBlock, + verifier: Arc +) -> Result::Header as HeaderT>::Number>, BlockImportError> +{ + let peer = block.origin; + + let (header, justification) = match (block.header, block.justification) { + (Some(header), justification) => (header, justification), + (None, _) => { + if let Some(peer) = peer { + debug!(target: "sync", "Header {} was not provided by {} ", block.hash, peer); + } else { + debug!(target: "sync", "Header {} was not provided ", block.hash); + } + return Err(BlockImportError::IncompleteHeader(peer)) //TODO: use persistent ID + }, + }; + + let number = header.number().clone(); + let hash = header.hash(); + let parent = header.parent_hash().clone(); + let (import_block, new_authorities) = verifier.verify(block_origin, header, justification, block.body) + .map_err(|msg| { + if let Some(peer) = peer { + trace!(target: "sync", "Verifying {}({}) from {} failed: {}", number, hash, peer, msg); + } else { + trace!(target: "sync", "Verifying {}({}) failed: {}", number, hash, msg); + } + BlockImportError::VerificationFailed(peer, msg) + })?; + + match import_handle.import_block(import_block, new_authorities) { + Ok(ImportResult::AlreadyInChain) => { + trace!(target: "sync", "Block already in chain {}: {:?}", number, hash); + Ok(BlockImportResult::ImportedKnown(hash, number)) + }, + Ok(ImportResult::AlreadyQueued) => { + trace!(target: "sync", "Block already queued {}: {:?}", number, hash); + Ok(BlockImportResult::ImportedKnown(hash, number)) + }, + Ok(ImportResult::Queued) => { + trace!(target: "sync", "Block queued {}: {:?}", number, hash); + Ok(BlockImportResult::ImportedUnknown(hash, number)) + }, + Ok(ImportResult::NeedsJustification) => { + trace!(target: "sync", "Block queued but requires justification {}: {:?}", number, hash); + Ok(BlockImportResult::ImportedUnjustified(hash, number)) + }, + Ok(ImportResult::UnknownParent) => { + debug!(target: "sync", "Block with unknown parent {}: {:?}, parent: {:?}", number, hash, parent); + Err(BlockImportError::UnknownParent) + }, + Ok(ImportResult::KnownBad) => { + debug!(target: "sync", "Peer gave us a bad block {}: {:?}", number, hash); + Err(BlockImportError::BadBlock(peer)) //TODO: use persistent ID + }, + Err(e) => { + debug!(target: "sync", "Error importing block {}: {:?}: {:?}", number, hash, e); + Err(BlockImportError::Error) + } + } +} + +/// Process single block import result. +pub fn process_import_result( + link: &Link, + result: Result::Header as HeaderT>::Number>, BlockImportError> +) -> usize +{ + match result { + Ok(BlockImportResult::ImportedKnown(hash, number)) => { + link.block_imported(&hash, number); + 1 + }, + Ok(BlockImportResult::ImportedUnknown(hash, number)) => { + link.block_imported(&hash, number); + 1 + }, + Ok(BlockImportResult::ImportedUnjustified(hash, number)) => { + link.block_imported(&hash, number); + link.request_justification(&hash, number); + 1 + }, + Err(BlockImportError::IncompleteHeader(who)) => { + if let Some(peer) = who { + link.useless_peer(peer, "Sent block with incomplete header to import"); + } + 0 + }, + Err(BlockImportError::VerificationFailed(who, e)) => { + if let Some(peer) = who { + link.useless_peer(peer, &format!("Verification failed: {}", e)); + } + 0 + }, + Err(BlockImportError::BadBlock(who)) => { + if let Some(peer) = who { + link.note_useless_and_restart_sync(peer, "Sent us a bad block"); + } + 0 + }, + Err(BlockImportError::UnknownParent) | Err(BlockImportError::Error) => { + link.restart(); + 0 + }, + } +} diff --git a/core/consensus/common/src/lib.rs b/core/consensus/common/src/lib.rs index 12d5cfa70df2f27833997ca7adc7d65a9eafc71c..453b6844309eb06aa53e949ed8a546f132027f7b 100644 --- a/core/consensus/common/src/lib.rs +++ b/core/consensus/common/src/lib.rs @@ -14,9 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Substrate Consensus Common. If not, see . -// tag::description[] -//! Consensus basics and common features -// end::description[] +//! 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. // This provides "unused" building blocks to other crates #![allow(dead_code)] @@ -26,52 +28,54 @@ extern crate substrate_primitives as primitives; extern crate futures; +extern crate parking_lot; extern crate sr_version as runtime_version; extern crate sr_primitives as runtime_primitives; +#[cfg(any(test, feature = "test-helpers"))] +extern crate substrate_test_client as test_client; extern crate tokio; extern crate parity_codec as codec; -#[macro_use] extern crate parity_codec_derive; #[macro_use] extern crate error_chain; +#[macro_use] extern crate log; use std::sync::Arc; -use primitives::{ed25519, AuthorityId}; use runtime_primitives::generic::BlockId; -use runtime_primitives::traits::Block; +use runtime_primitives::traits::{AuthorityIdFor, Block}; use futures::prelude::*; pub mod offline_tracker; pub mod error; mod block_import; +pub mod import_queue; pub mod evaluation; // block size limit. const MAX_TRANSACTIONS_SIZE: usize = 4 * 1024 * 1024; pub use self::error::{Error, ErrorKind}; -pub use block_import::{BlockImport, ImportBlock, BlockOrigin, ImportResult}; +pub use block_import::{BlockImport, ImportBlock, BlockOrigin, ImportResult, ForkChoiceStrategy}; /// Trait for getting the authorities at a given block. pub trait Authorities { type Error: ::std::error::Error + Send + 'static; /// Get the authorities at the given block. - fn authorities(&self, at: &BlockId) -> Result, Self::Error>; + fn authorities(&self, at: &BlockId) -> Result>, Self::Error>; } /// Environment producer for a Consensus instance. Creates proposer instance and communication streams. -pub trait Environment { +pub trait Environment { /// The proposer type this creates. - type Proposer: Proposer; + type Proposer: Proposer; /// Error which can occur upon creation. type Error: From; /// Initialize the proposal logic on top of a specific header. Provide - /// the authorities at that header, and a local key to sign any additional - /// consensus messages with as well. - fn init(&self, parent_header: &B::Header, authorities: &[AuthorityId], sign_with: Arc) + /// the authorities at that header. + fn init(&self, parent_header: &B::Header, authorities: &[AuthorityIdFor]) -> Result; } @@ -79,32 +83,15 @@ pub trait Environment { /// /// This will encapsulate creation and evaluation of proposals at a specific /// block. -pub trait Proposer { +/// +/// Proposers are generic over bits of "consensus data" which are engine-specific. +pub trait Proposer { /// Error type which can occur when proposing or evaluating. type Error: From + ::std::fmt::Debug + 'static; /// Future that resolves to a committed proposal. type Create: IntoFuture; /// Create a proposal. - fn propose(&self) -> Self::Create; -} - -/// Inherent data to include in a block. -#[derive(Encode, Decode)] -pub struct InherentData { - /// Current timestamp. - pub timestamp: u64, - /// Indices of offline validators. - pub offline_indices: Vec, -} - -impl InherentData { - /// Create a new `InherentData` instance. - pub fn new(timestamp: u64, offline_indices: Vec) -> Self { - Self { - timestamp, - offline_indices - } - } + fn propose(&self, consensus_data: ConsensusData) -> Self::Create; } /// An oracle for when major synchronization work is being undertaken. diff --git a/core/consensus/common/src/offline_tracker.rs b/core/consensus/common/src/offline_tracker.rs index bd8eab8b1bb51f60a85d543e2d047cd55235cdf1..1ed923da2c590e64ce1b54f63f76801bfaaa3cb0 100644 --- a/core/consensus/common/src/offline_tracker.rs +++ b/core/consensus/common/src/offline_tracker.rs @@ -16,8 +16,6 @@ //! Tracks offline validators. -use primitives::AuthorityId; - use std::collections::HashMap; use std::time::{Instant, Duration}; @@ -55,11 +53,11 @@ impl Observed { } /// Tracks offline validators and can issue a report for those offline. -pub struct OfflineTracker { +pub struct OfflineTracker { observed: HashMap, } -impl OfflineTracker { +impl OfflineTracker { /// Create a new tracker. pub fn new() -> Self { OfflineTracker { observed: HashMap::new() } @@ -114,10 +112,11 @@ impl OfflineTracker { #[cfg(test)] mod tests { use super::*; + use primitives::Ed25519AuthorityId; #[test] fn validator_offline() { - let mut tracker = OfflineTracker::new(); + let mut tracker = OfflineTracker::::new(); let v = [0; 32].into(); let v2 = [1; 32].into(); let v3 = [2; 32].into(); diff --git a/core/consensus/rhd/Cargo.toml b/core/consensus/rhd/Cargo.toml index dce6a6d7f445abd16193672ea726cdf266f2f339..4a3001b12c0929c1d58aa376f1e5a888ddbfe2bd 100644 --- a/core/consensus/rhd/Cargo.toml +++ b/core/consensus/rhd/Cargo.toml @@ -6,7 +6,7 @@ description = "Rhododendron Round-Based consensus-algorithm for substrate" [dependencies] futures = "0.1.17" -parity-codec = { version = "2.1" } +parity-codec = { version = "2.2" } parity-codec-derive = { version = "2.0" } substrate-primitives = { path = "../../primitives" } substrate-consensus-common = { path = "../common" } @@ -19,7 +19,7 @@ sr-primitives = { path = "../../sr-primitives" } sr-version = { path = "../../sr-version" } sr-io = { path = "../../sr-io" } tokio = "0.1.7" -parking_lot = "0.4" +parking_lot = "0.7.1" error-chain = "0.12" log = "0.4" rhododendron = { version = "0.4.0", features = ["codec"] } diff --git a/core/consensus/rhd/README.adoc b/core/consensus/rhd/README.adoc deleted file mode 100644 index ff7bde17146ad5e84d317517c6580347f4221112..0000000000000000000000000000000000000000 --- a/core/consensus/rhd/README.adoc +++ /dev/null @@ -1,12 +0,0 @@ -= Consensus Rhododendron (RHD) - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/consensus/rhd/src/lib.rs b/core/consensus/rhd/src/lib.rs index b99ea4a24c71593654f223aee2edc67153a4e133..6441fb4e34a2f6e3ec30a2a494dc936eb33532a0 100644 --- a/core/consensus/rhd/src/lib.rs +++ b/core/consensus/rhd/src/lib.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! BFT Agreement based on a rotating proposer in different rounds. //! //! Where this crate refers to input stream, should never logically conclude. @@ -30,7 +29,6 @@ //! conclude without having witnessed the conclusion. //! In general, this future should be pre-empted by the import of a justification //! set for this block height. -// end::description[] #![cfg(feature="rhd")] // FIXME: doesn't compile - https://github.com/paritytech/substrate/issues/1020 @@ -198,7 +196,7 @@ pub trait BlockBuilder { pub trait AuthoringApi: Send + Sync - + BlockBuilderAPI<::Block, Error=::Error> + + BlockBuilderAPI<::Block, InherentData, Error=::Error> + Core<::Block, AuthorityId, Error=::Error> + OldTxQueue<::Block, Error=::Error> { @@ -419,10 +417,10 @@ impl Future for BftFuture BaseProposer<::Block> for Proposer where let proposed_timestamp = match self.client.check_inherents( &self.parent_id, &unchecked_proposal, - &inherent + &inherent, ) { Ok(Ok(())) => None, - Ok(Err(BlockBuilderError::TimestampInFuture(timestamp))) => Some(timestamp), + Ok(Err(BlockBuilderError::ValidAtTimestamp(timestamp))) => Some(timestamp), Ok(Err(e)) => { debug!(target: "rhd", "Invalid proposal (check_inherents): {:?}", e); return Box::new(future::ok(false)); diff --git a/core/executor/Cargo.toml b/core/executor/Cargo.toml index a3de26a3cbb886a03e797e1de14d031ae07be9ee..b40dd06fa399ae623cf3bbc61bc9654cc4b055fb 100644 --- a/core/executor/Cargo.toml +++ b/core/executor/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] [dependencies] error-chain = "0.12" -parity-codec = "2.1" +parity-codec = "2.2" sr-io = { path = "../sr-io" } substrate-primitives = { path = "../primitives" } substrate-trie = { path = "../trie" } @@ -14,15 +14,16 @@ substrate-state-machine = { path = "../state-machine" } sr-version = { path = "../sr-version" } serde = "1.0" serde_derive = "1.0" -wasmi = { version = "0.4.1" } +wasmi = { version = "0.4.3" } byteorder = "1.1" lazy_static = "1.0" -parking_lot = "*" +parking_lot = "0.7.1" log = "0.4" +fnv = "1.0.6" [dev-dependencies] assert_matches = "1.1" -wabt = "0.4" +wabt = "~0.7.4" hex-literal = "0.1.0" [features] diff --git a/core/executor/README.adoc b/core/executor/README.adoc deleted file mode 100644 index 6a0ee23565a700b1674fa332c111728428a3f8f9..0000000000000000000000000000000000000000 --- a/core/executor/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Executor - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/executor/src/heap.rs b/core/executor/src/heap.rs new file mode 100644 index 0000000000000000000000000000000000000000..da7aae22eefffce537dee6731e9a38f8d1e3b157 --- /dev/null +++ b/core/executor/src/heap.rs @@ -0,0 +1,473 @@ +// Copyright 2017-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 implements a buddy allocation heap. +//! It uses a binary tree and follows the concepts outlined in +//! https://en.wikipedia.org/wiki/Buddy_memory_allocation. + +extern crate fnv; + +use std::vec; +use self::fnv::FnvHashMap; + +// The pointers need to be aligned to 8 bytes. +const ALIGNMENT: u32 = 8; + +// The block size needs to be a multiple of the memory alignment +// requirement. This is so that the pointer returned by `allocate()` +// always fulfills the alignment. In buddy allocation a pointer always +// points to the start of a block, which with a fitting block size +// will then be a multiple of the alignment requirement. +const BLOCK_SIZE: u32 = 8192; // 2^13 bytes + +#[allow(path_statements)] +fn _assert_block_size_aligned() { + // mem::transmute checks that type sizes are equal. + // this enables us to assert that pointers are aligned -- at compile time. + ::std::mem::transmute::<[u8; BLOCK_SIZE as usize % ALIGNMENT as usize], [u8; 0]>; +} + +#[derive(PartialEq, Copy, Clone)] +enum Node { + Free, + Full, + Split, +} + +/// A buddy allocation heap, which tracks allocations and deallocations +/// using a binary tree. +pub struct Heap { + allocated_bytes: FnvHashMap, + levels: u32, + ptr_offset: u32, + tree: vec::Vec, + total_size: u32, +} + +impl Heap { + + /// Creates a new buddy allocation heap. + /// + /// # Arguments + /// + /// * `ptr_offset` - The pointers returned by `allocate()` + /// start from this offset on. The pointer offset needs + /// to be aligned to a multiple of 8, hence a padding might + /// be added to align `ptr_offset` properly. + /// + /// * `heap_size` - The size available to this heap instance + /// (in bytes) for allocating memory. + /// + pub fn new(mut ptr_offset: u32, heap_size: u32) -> Self { + let padding = ptr_offset % ALIGNMENT; + if padding != 0 { + ptr_offset += ALIGNMENT - padding; + } + + let leaves = heap_size / BLOCK_SIZE; + let levels = Heap::get_necessary_tree_levels(leaves); + let node_count: usize = (1 << levels + 1) - 1; + + Heap { + allocated_bytes: FnvHashMap::default(), + levels, + ptr_offset, + tree: vec![Node::Free; node_count], + total_size: 0, + } + } + + /// Gets requested number of bytes to allocate and returns a pointer. + pub fn allocate(&mut self, size: u32) -> u32 { + // Get the requested level from number of blocks requested + let blocks_needed = (size + BLOCK_SIZE - 1) / BLOCK_SIZE; + let block_offset = match self.allocate_block_in_tree(blocks_needed) { + Some(v) => v, + None => return 0, + }; + + let ptr = BLOCK_SIZE * block_offset as u32; + self.allocated_bytes.insert(ptr, size as u32); + + self.total_size += size; + trace!(target: "wasm-heap", "Heap size over {} bytes after allocation", self.total_size); + + self.ptr_offset + ptr + } + + fn allocate_block_in_tree(&mut self, blocks_needed: u32) -> Option { + let levels_needed = Heap::get_necessary_tree_levels(blocks_needed); + if levels_needed > self.levels { + trace!(target: "wasm-heap", "Heap is too small: {:?} > {:?}", levels_needed, self.levels); + return None; + } + + // Start at tree root and traverse down + let mut index = 0; + let mut current_level = self.levels; + 'down: loop { + let buddy_exists = index & 1 == 1; + + if current_level == levels_needed { + if self.tree[index] == Node::Free { + self.tree[index] = Node::Full; + + if index > 0 { + let parent = self.get_parent_node_index(index); + self.update_parent_nodes(parent); + } + + break 'down; + } + } else { + match self.tree[index] { + Node::Full => { + if buddy_exists { + // Check if buddy is free + index += 1; + } else { + break 'down; + } + continue 'down; + }, + + Node::Free => { + // If node is free we split it and descend further down + self.tree[index] = Node::Split; + index = index * 2 + 1; + current_level -= 1; + continue 'down; + }, + + Node::Split => { + // Descend further + index = index * 2 + 1; + current_level -= 1; + continue 'down; + }, + } + } + + if buddy_exists { + // If a buddy exists it needs to be checked as well + index += 1; + continue 'down; + } + + // Backtrack once we're at the bottom and haven't matched a free block yet + 'up: loop { + if index == 0 { + trace!(target: "wasm-heap", "Heap is too small: tree root reached."); + return None; + } + + index = self.get_parent_node_index(index); + current_level += 1; + let has_buddy = index & 1 == 1; + if has_buddy { + index += 1; + break 'up; + } + } + } + + let current_level_offset = (1 << self.levels - current_level) - 1; + let level_offset = index - current_level_offset; + + let block_offset = level_offset * (1 << current_level); + Some(block_offset as usize) + } + + /// Deallocates all blocks which were allocated for a pointer. + pub fn deallocate(&mut self, mut ptr: u32) { + ptr -= self.ptr_offset; + + let allocated_size = match self.allocated_bytes.get(&ptr) { + Some(v) => *v, + + // If nothing has been allocated for the pointer nothing happens + None => return (), + }; + + let count_blocks = (allocated_size + BLOCK_SIZE - 1) / BLOCK_SIZE; + let block_offset = ptr / BLOCK_SIZE; + self.free(block_offset, count_blocks); + self.allocated_bytes.remove(&ptr).unwrap_or_default(); + + self.total_size = self.total_size.checked_sub(allocated_size).unwrap_or(0); + trace!(target: "wasm-heap", "Heap size over {} bytes after deallocation", self.total_size); + } + + fn free(&mut self, block_offset: u32, count_blocks: u32) { + let requested_level = Heap::get_necessary_tree_levels(count_blocks); + let current_level_offset = (1 << self.levels - requested_level) - 1; + let level_offset = block_offset / (1 << requested_level); + let index_offset = current_level_offset + level_offset; + + if index_offset > self.tree.len() as u32 - 1 { + trace!(target: "wasm-heap", "Index offset {} is > length of tree {}", index_offset, self.tree.len()); + } + + self.free_and_merge(index_offset as usize); + + let parent = self.get_parent_node_index(index_offset as usize); + self.update_parent_nodes(parent); + } + + fn get_parent_node_index(&mut self, index: usize) -> usize { + (index + 1) / 2 - 1 + } + + fn free_and_merge(&mut self, index: usize) { + self.tree[index] = Node::Free; + + if index == 0 { + return; + } + + let has_right_buddy = (index & 1) == 1; + let other_node = if has_right_buddy { + index + 1 + } else { + index - 1 + }; + + if self.tree[other_node] == Node::Free { + let parent = self.get_parent_node_index(index); + self.free_and_merge(parent); + } + } + + fn update_parent_nodes(&mut self, index: usize) { + let left_child = index * 2 + 1; + let right_child = index * 2 + 2; + + let children_free = self.tree[left_child] == Node::Free && self.tree[right_child] == Node::Free; + let children_full = self.tree[left_child] == Node::Full && self.tree[right_child] == Node::Full; + if children_free { + self.tree[index] = Node::Free; + } else if children_full { + self.tree[index] = Node::Full; + } else { + self.tree[index] = Node::Split; + } + + if index == 0 { + // Tree root + return; + } + + let parent = self.get_parent_node_index(index); + self.update_parent_nodes(parent); + } + + fn get_necessary_tree_levels(count_blocks: u32) -> u32 { + if count_blocks == 0 { + 0 + } else { + let mut necessary_levels = 0; + let mut necessary_blocks = count_blocks.next_power_of_two(); + while {necessary_blocks >>= 1; necessary_blocks > 0} { + necessary_levels += 1; + } + necessary_levels + } + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn should_always_align_pointers_to_multiples_of_8() { + let heap_size = BLOCK_SIZE * 4; + let mut heap = super::Heap::new(13, heap_size); + + let ptr = heap.allocate(1); + assert_eq!(ptr, 16); // 16 is the next multiple of 8 from 13 + } + + #[test] + fn should_start_first_pointer_at_offset() { + let start_offset = 40; + let heap_size = BLOCK_SIZE * 4; + let mut heap = super::Heap::new(start_offset, heap_size); + + let ptr = heap.allocate(BLOCK_SIZE - 1); + assert_eq!(ptr, start_offset); + } + + #[test] + fn should_start_second_pointer_at_second_block() { + let start_offset = 40; + let heap_size = BLOCK_SIZE * 4; + let mut heap = super::Heap::new(start_offset, heap_size); + + let _ptr1 = heap.allocate(BLOCK_SIZE - 1); + let ptr2 = heap.allocate(BLOCK_SIZE - 1); + assert_eq!(ptr2, start_offset + BLOCK_SIZE); + } + + #[test] + fn should_not_panic_on_deallocation_of_nonexistent_pointer() { + let heap_size = BLOCK_SIZE * 4; + let mut heap = super::Heap::new(1, heap_size); + let ret = heap.deallocate(heap_size + 1); + assert_eq!(ret, ()); + } + + #[test] + fn should_calculate_tree_size_from_heap_size() { + let heap_size = BLOCK_SIZE * 4; + let heap = super::Heap::new(1, heap_size); + + assert_eq!(heap.levels, 2); + } + + #[test] + fn should_round_tree_size_to_nearest_possible() { + let heap_size = BLOCK_SIZE * 4 + 1; + let heap = super::Heap::new(1, heap_size); + + assert_eq!(heap.levels, 2); + } + + #[test] + fn heap_size_should_stay_zero_in_total() { + let heap_size = BLOCK_SIZE * 4; + let mut heap = super::Heap::new(1, heap_size); + assert_eq!(heap.total_size, 0); + + let ptr = heap.allocate(42); + assert_eq!(heap.total_size, 42); + + heap.deallocate(ptr); + assert_eq!(heap.total_size, 0); + } + + #[test] + fn heap_size_should_stay_constant() { + let heap_size = BLOCK_SIZE * 4; + let mut heap = super::Heap::new(9, heap_size); + for _ in 1..10 { + assert_eq!(heap.total_size, 0); + + let ptr = heap.allocate(42); + assert_eq!(ptr, 16); + assert_eq!(heap.total_size, 42); + + heap.deallocate(ptr); + assert_eq!(heap.total_size, 0); + } + + assert_eq!(heap.total_size, 0); + } + + #[test] + fn should_allocate_exactly_entire_tree() { + let blocks = 16; + let heap_size = BLOCK_SIZE * blocks; + let mut heap = super::Heap::new(0, heap_size); + + for i in 0..16 { + let ptr = heap.allocate(BLOCK_SIZE); + assert_eq!(ptr, i * BLOCK_SIZE); + assert_eq!(heap.total_size, (i+1) * BLOCK_SIZE); + } + + let ptr = heap.allocate(BLOCK_SIZE); + assert_eq!(ptr, 0); + } + + #[test] + fn should_deallocate_entire_tree_exactly() { + let blocks = 12; + let heap_size = BLOCK_SIZE * blocks; + let mut heap = super::Heap::new(0, heap_size); + for i in 0..blocks { + let ptr = heap.allocate(BLOCK_SIZE); + assert_eq!(ptr, i * BLOCK_SIZE); + assert_eq!(heap.total_size, (i+1) * BLOCK_SIZE); + } + + for i in 0..blocks { + let ptr = i * BLOCK_SIZE; + heap.deallocate(ptr); + assert_eq!(heap.total_size, blocks * BLOCK_SIZE - (i+1) * BLOCK_SIZE); + } + + assert_eq!(heap.total_size, 0); + } + + #[test] + fn should_allocate_pointers_with_odd_blocks_properly() { + let blocks = 6; + let heap_size = BLOCK_SIZE * blocks; + let mut heap = super::Heap::new(0, heap_size); + + let ptr = heap.allocate(3 * BLOCK_SIZE); + assert_eq!(ptr, 0); + + let ptr = heap.allocate(BLOCK_SIZE); + assert_eq!(ptr, 4 * BLOCK_SIZE); + } + + #[test] + fn should_handle_odd_blocks_properly() { + let blocks = 8; + let heap_size = BLOCK_SIZE * blocks; + let mut heap = super::Heap::new(0, heap_size); + + let ptr = heap.allocate(3 * BLOCK_SIZE); + assert_eq!(ptr, 0); + + let ptr = heap.allocate(3 * BLOCK_SIZE); + assert_eq!(ptr, 4 * BLOCK_SIZE); + } + + #[test] + fn should_calculate_zero_tree_levels_for_zero_blocks() { + let count_blocks = 0; + let levels = Heap::get_necessary_tree_levels(count_blocks); + assert_eq!(levels, 0); + } + + #[test] + fn should_calculate_necessary_tree_levels_correctly() { + let count_blocks = 1; + let levels = Heap::get_necessary_tree_levels(count_blocks); + assert_eq!(levels, 0); + + let count_blocks = 2; + let levels = Heap::get_necessary_tree_levels(count_blocks); + assert_eq!(levels, 1); + + let count_blocks = 3; + let levels = Heap::get_necessary_tree_levels(count_blocks); + assert_eq!(levels, 2); + + let count_blocks = 4; + let levels = Heap::get_necessary_tree_levels(count_blocks); + assert_eq!(levels, 2); + + let count_blocks = 5; + let levels = Heap::get_necessary_tree_levels(count_blocks); + assert_eq!(levels, 3); + } + +} diff --git a/core/executor/src/lib.rs b/core/executor/src/lib.rs index 64442b7f8e2b6e33e356681afa96fbefbddbf56f..8ce1c775fb9f941b95e0482345e2cfc73ad54baf 100644 --- a/core/executor/src/lib.rs +++ b/core/executor/src/lib.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Temporary crate for contracts implementations. //! //! This will be replaced with WASM contracts stored on-chain. @@ -25,7 +24,6 @@ //! - init_block(PrevBlock?) -> InProgressBlock //! - add_transaction(InProgressBlock) -> InProgressBlock //! It is left as is for now as it might be removed before this is ever done. -// end::description[] #![warn(missing_docs)] #![recursion_limit="128"] @@ -46,9 +44,6 @@ extern crate parking_lot; #[macro_use] extern crate log; -#[macro_use] -extern crate lazy_static; - #[macro_use] extern crate error_chain; @@ -68,6 +63,7 @@ mod wasm_executor; #[macro_use] mod native_executor; mod sandbox; +mod heap; pub mod error; pub use wasm_executor::WasmExecutor; @@ -86,7 +82,5 @@ pub trait RuntimeInfo { fn runtime_version> ( &self, ext: &mut E, - heap_pages: usize, - code: &[u8] ) -> Option; } diff --git a/core/executor/src/native_executor.rs b/core/executor/src/native_executor.rs index b51b43e14dd1976607b5fc3431ae527cef402fc6..fcba9c5914772c2112fba501ed8e4a035bdaa228 100644 --- a/core/executor/src/native_executor.rs +++ b/core/executor/src/native_executor.rs @@ -14,38 +14,34 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use std::borrow::BorrowMut; +use std::cell::{RefMut, RefCell}; use error::{Error, ErrorKind, Result}; use state_machine::{CodeExecutor, Externalities}; use wasm_executor::WasmExecutor; -use wasmi::Module as WasmModule; +use wasmi::{Module as WasmModule, ModuleRef as WasmModuleInstanceRef}; use runtime_version::{NativeVersion, RuntimeVersion}; -use std::collections::HashMap; -use codec::Decode; -use primitives::hashing::blake2_256; -use parking_lot::{Mutex, MutexGuard}; +use std::{collections::HashMap, panic::UnwindSafe}; +use codec::{Decode, Encode}; use RuntimeInfo; -use primitives::Blake2Hasher; +use primitives::{Blake2Hasher, NativeOrEncoded}; +use primitives::storage::well_known_keys; + +/// Default num of pages for the heap +const DEFAULT_HEAP_PAGES: u64 = 1024; // For the internal Runtime Cache: // Is it compatible enough to run this natively or do we need to fall back on the WasmModule enum RuntimePreproc { InvalidCode, - ValidCode(WasmModule, Option), + ValidCode(WasmModuleInstanceRef, Option), } type CacheType = HashMap<[u8; 32], RuntimePreproc>; -lazy_static! { - static ref RUNTIMES_CACHE: Mutex = Mutex::new(HashMap::new()); -} - -// helper function to generate low-over-head caching_keys -// it is asserted that part of the audit process that any potential on-chain code change -// will have done is to ensure that the two-x hash is different to that of any other -// :code value from the same chain -fn gen_cache_key(code: &[u8]) -> [u8; 32] { - blake2_256(code) +thread_local! { + static RUNTIMES_CACHE: RefCell = RefCell::new(HashMap::new()); } /// fetch a runtime version from the cache or if there is no cached version yet, create @@ -53,32 +49,53 @@ fn gen_cache_key(code: &[u8]) -> [u8; 32] { /// can be used by comparing returned RuntimeVersion to `ref_version` fn fetch_cached_runtime_version<'a, E: Externalities>( wasm_executor: &WasmExecutor, - cache: &'a mut MutexGuard, + cache: &'a mut RefMut, ext: &mut E, - heap_pages: usize, - code: &[u8] -) -> Result<(&'a WasmModule, &'a Option)> { - let maybe_runtime_preproc = cache.entry(gen_cache_key(code)) - .or_insert_with(|| match WasmModule::from_buffer(code) { - Ok(module) => { - let version = wasm_executor.call_in_wasm_module(ext, heap_pages, &module, "version", &[]) - .ok() - .and_then(|v| RuntimeVersion::decode(&mut v.as_slice())); - RuntimePreproc::ValidCode(module, version) - } - Err(e) => { - trace!(target: "executor", "Invalid code presented to executor ({:?})", e); - RuntimePreproc::InvalidCode +) -> Result<(&'a WasmModuleInstanceRef, &'a Option)> { + + let code_hash = match ext.storage_hash(well_known_keys::CODE) { + Some(code_hash) => code_hash, + None => return Err(ErrorKind::InvalidCode(vec![]).into()), + }; + let maybe_runtime_preproc = cache.borrow_mut().entry(code_hash.into()) + .or_insert_with(|| { + let code = match ext.storage(well_known_keys::CODE) { + Some(code) => code, + None => return RuntimePreproc::InvalidCode, + }; + let heap_pages = match ext.storage(well_known_keys::HEAP_PAGES) { + Some(pages) => u64::decode(&mut &pages[..]).unwrap_or(DEFAULT_HEAP_PAGES), + None => DEFAULT_HEAP_PAGES, + }; + match WasmModule::from_buffer(code) + .map_err(|_| ErrorKind::InvalidCode(vec![]).into()) + .and_then(|module| wasm_executor.prepare_module(ext, heap_pages as usize, &module)) + { + Ok(module) => { + let version = wasm_executor.call_in_wasm_module(ext, &module, "Core_version", &[]) + .ok() + .and_then(|v| RuntimeVersion::decode(&mut v.as_slice())); + RuntimePreproc::ValidCode(module, version) + } + Err(e) => { + trace!(target: "executor", "Invalid code presented to executor ({:?})", e); + RuntimePreproc::InvalidCode + } } }); match maybe_runtime_preproc { - RuntimePreproc::InvalidCode => Err(ErrorKind::InvalidCode(code.into()).into()), - RuntimePreproc::ValidCode(m, v) => Ok((m, v)), + RuntimePreproc::InvalidCode => { + let code = ext.storage(well_known_keys::CODE).unwrap_or(vec![]); + Err(ErrorKind::InvalidCode(code).into()) + }, + RuntimePreproc::ValidCode(m, v) => { + Ok((m, v)) + } } } fn safe_call(f: F) -> Result - where F: ::std::panic::UnwindSafe + FnOnce() -> U + where F: UnwindSafe + FnOnce() -> U { // Substrate uses custom panic hook that terminates process on panic. Disable it for the native call. let hook = ::std::panic::take_hook(); @@ -91,7 +108,7 @@ fn safe_call(f: F) -> Result /// /// If the inner closure panics, it will be caught and return an error. pub fn with_native_environment(ext: &mut Externalities, f: F) -> Result -where F: ::std::panic::UnwindSafe + FnOnce() -> U +where F: UnwindSafe + FnOnce() -> U { ::runtime_io::with_externalities(ext, move || safe_call(f)) } @@ -154,43 +171,91 @@ impl RuntimeInfo for NativeExecutor { fn runtime_version>( &self, ext: &mut E, - heap_pages: usize, - code: &[u8], ) -> Option { - fetch_cached_runtime_version(&self.fallback, &mut RUNTIMES_CACHE.lock(), ext, heap_pages, code).ok()?.1.clone() + RUNTIMES_CACHE.with(|c| + fetch_cached_runtime_version(&self.fallback, &mut c.borrow_mut(), ext).ok()?.1.clone() + ) } } impl CodeExecutor for NativeExecutor { type Error = Error; - fn call>( + fn call + < + E: Externalities, + R:Decode + Encode + PartialEq, + NC: FnOnce() -> R + UnwindSafe + >( &self, ext: &mut E, - heap_pages: usize, - code: &[u8], method: &str, data: &[u8], use_native: bool, - ) -> (Result>, bool) { - let mut c = RUNTIMES_CACHE.lock(); - let (module, onchain_version) = match fetch_cached_runtime_version(&self.fallback, &mut c, ext, heap_pages, code) { - Ok((module, onchain_version)) => (module, onchain_version), - Err(_) => return (Err(ErrorKind::InvalidCode(code.into()).into()), false), - }; - match (use_native, onchain_version.as_ref().map_or(false, |v| v.can_call_with(&self.native_version.runtime_version))) { - (_, false) => { - trace!(target: "executor", "Request for native execution failed (native: {}, chain: {})", self.native_version.runtime_version, onchain_version.as_ref().map_or_else(||"".into(), |v| format!("{}", v))); - (self.fallback.call_in_wasm_module(ext, heap_pages, module, method, data), false) - } - (false, _) => { - (self.fallback.call_in_wasm_module(ext, heap_pages, module, method, data), false) + native_call: Option, + ) -> (Result>, bool) { + RUNTIMES_CACHE.with(|c| { + let mut c = c.borrow_mut(); + let (module, onchain_version) = match fetch_cached_runtime_version(&self.fallback, &mut c, ext) { + Ok((module, onchain_version)) => (module, onchain_version), + Err(e) => return (Err(e), false), + }; + match ( + use_native, + onchain_version + .as_ref() + .map_or(false, |v| v.can_call_with(&self.native_version.runtime_version)), + native_call, + ) { + (_, false, _) => { + trace!( + target: "executor", + "Request for native execution failed (native: {}, chain: {})", + self.native_version.runtime_version, + onchain_version + .as_ref() + .map_or_else(||"".into(), |v| format!("{}", v)) + ); + ( + self.fallback + .call_in_wasm_module(ext, module, method, data) + .map(NativeOrEncoded::Encoded), + false + ) + } + (false, _, _) => { + ( + self.fallback + .call_in_wasm_module(ext, module, method, data) + .map(NativeOrEncoded::Encoded), + false + ) + } + (true, true, Some(call)) => { + trace!( + target: "executor", + "Request for native execution with native call succeeded (native: {}, chain: {}).", + self.native_version.runtime_version, + onchain_version + .as_ref() + .map_or_else(||"".into(), |v| format!("{}", v)) + ); + ( + with_native_environment(ext, move || (call)()).map(NativeOrEncoded::Native), + true + ) + } + _ => { + trace!( + target: "executor", + "Request for native execution succeeded (native: {}, chain: {})", + self.native_version.runtime_version, + onchain_version.as_ref().map_or_else(||"".into(), |v| format!("{}", v)) + ); + (D::dispatch(ext, method, data).map(NativeOrEncoded::Encoded), true) + } } - _ => { - trace!(target: "executor", "Request for native execution succeeded (native: {}, chain: {})", self.native_version.runtime_version, onchain_version.as_ref().map_or_else(||"".into(), |v| format!("{}", v))); - (D::dispatch(ext, method, data), true) - } - } + }) } } diff --git a/core/executor/src/wasm_executor.rs b/core/executor/src/wasm_executor.rs index 90d6db600151aeee74d8d1e7514760c56708e6eb..87704805c1e4c0a96024185fff2fdcdb19bdcdc8 100644 --- a/core/executor/src/wasm_executor.rs +++ b/core/executor/src/wasm_executor.rs @@ -19,50 +19,20 @@ use std::collections::HashMap; use wasmi::{ - Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder + Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef, }; use wasmi::RuntimeValue::{I32, I64}; -use wasmi::memory_units::{Pages, Bytes}; +use wasmi::memory_units::{Bytes, Pages}; use state_machine::Externalities; use error::{Error, ErrorKind, Result}; use wasm_utils::UserError; use primitives::{blake2_256, twox_128, twox_256, ed25519}; use primitives::hexdisplay::HexDisplay; use primitives::sandbox as sandbox_primitives; -use primitives::Blake2Hasher; +use primitives::{H256, Blake2Hasher}; use trie::ordered_trie_root; use sandbox; - - -struct Heap { - end: u32, -} - -impl Heap { - /// Construct new `Heap` struct with a given number of pages. - /// - /// Returns `Err` if the heap couldn't allocate required - /// number of pages. - /// - /// This could mean that wasm binary specifies memory - /// limit and we are trying to allocate beyond that limit. - fn new(memory: &MemoryRef, pages: usize) -> Result { - let prev_page_count = memory.initial(); - memory.grow(Pages(pages)).map_err(|_| Error::from(ErrorKind::Runtime))?; - Ok(Heap { - end: Bytes::from(prev_page_count).0 as u32, - }) - } - - fn allocate(&mut self, size: u32) -> u32 { - let r = self.end; - self.end += size; - r - } - - fn deallocate(&mut self, _offset: u32) { - } -} +use heap; #[cfg(feature="wasm-extern-trace")] macro_rules! debug_trace { @@ -75,7 +45,7 @@ macro_rules! debug_trace { struct FunctionExecutor<'e, E: Externalities + 'e> { sandbox_store: sandbox::Store, - heap: Heap, + heap: heap::Heap, memory: MemoryRef, table: Option, ext: &'e mut E, @@ -83,10 +53,15 @@ struct FunctionExecutor<'e, E: Externalities + 'e> { } impl<'e, E: Externalities> FunctionExecutor<'e, E> { - fn new(m: MemoryRef, heap_pages: usize, t: Option, e: &'e mut E) -> Result { + fn new(m: MemoryRef, t: Option, e: &'e mut E) -> Result { + let current_size: Bytes = m.current_size().into(); + let current_size = current_size.0 as u32; + let used_size = m.used_size().0 as u32; + let heap_size = current_size - used_size; + Ok(FunctionExecutor { sandbox_store: sandbox::Store::new(), - heap: Heap::new(&m, heap_pages)?, + heap: heap::Heap::new(used_size, heap_size), memory: m, table: t, ext: e, @@ -412,8 +387,15 @@ impl_function_executor!(this: FunctionExecutor<'e, E>, Ok(0) } }, - ext_storage_changes_root(block: u64, result: *mut u8) -> u32 => { - let r = this.ext.storage_changes_root(block); + ext_storage_changes_root(parent_hash_data: *const u8, parent_hash_len: u32, parent_number: u64, result: *mut u8) -> u32 => { + let mut parent_hash = H256::default(); + if parent_hash_len != parent_hash.as_ref().len() as u32 { + return Err(UserError("Invalid parent_hash_len in ext_storage_changes_root").into()); + } + let raw_parent_hash = this.memory.get(parent_hash_data, parent_hash_len as usize) + .map_err(|_| UserError("Invalid attempt to get parent_hash in ext_storage_changes_root"))?; + parent_hash.as_mut().copy_from_slice(&raw_parent_hash[..]); + let r = this.ext.storage_changes_root(parent_hash, parent_number); if let Some(ref r) = r { this.memory.set(result, &r[..]).map_err(|_| UserError("Invalid attempt to set memory in ext_storage_changes_root"))?; } @@ -631,51 +613,43 @@ impl WasmExecutor { method: &str, data: &[u8], ) -> Result> { - let module = ::wasmi::Module::from_buffer(code).expect("all modules compiled with rustc are valid wasm code; qed"); - self.call_in_wasm_module(ext, heap_pages, &module, method, data) + let module = ::wasmi::Module::from_buffer(code)?; + let module = self.prepare_module(ext, heap_pages, &module)?; + self.call_in_wasm_module(ext, &module, method, data) + } + + fn get_mem_instance(module: &ModuleRef) -> Result { + Ok(module + .export_by_name("memory") + .ok_or_else(|| Error::from(ErrorKind::InvalidMemoryReference))? + .as_memory() + .ok_or_else(|| Error::from(ErrorKind::InvalidMemoryReference))? + .clone()) } /// Call a given method in the given wasm-module runtime. pub fn call_in_wasm_module>( &self, ext: &mut E, - heap_pages: usize, - module: &Module, + module_instance: &ModuleRef, method: &str, data: &[u8], ) -> Result> { - // start module instantiation. Don't run 'start' function yet. - let intermediate_instance = ModuleInstance::new( - module, - &ImportsBuilder::new() - .with_resolver("env", FunctionExecutor::::resolver()) - )?; - // extract a reference to a linear memory, optional reference to a table // and then initialize FunctionExecutor. - let memory = intermediate_instance - .not_started_instance() - .export_by_name("memory") - // TODO: with code coming from the blockchain it isn't strictly been compiled with rustc anymore. - // these assumptions are probably not true anymore - .expect("all modules compiled with rustc should have an export named 'memory'; qed") - .as_memory() - .expect("in module generated by rustc export named 'memory' should be a memory; qed") - .clone(); - let table: Option = intermediate_instance - .not_started_instance() + let memory = Self::get_mem_instance(module_instance)?; + let table: Option = module_instance .export_by_name("__indirect_function_table") .and_then(|e| e.as_table().cloned()); - let mut fec = FunctionExecutor::new(memory.clone(), heap_pages, table, ext)?; - - // finish instantiation by running 'start' function (if any). - let instance = intermediate_instance.run_start(&mut fec)?; + let low = memory.lowest_used(); + let used_mem = memory.used_size(); + let mut fec = FunctionExecutor::new(memory.clone(), table, ext)?; let size = data.len() as u32; let offset = fec.heap.allocate(size); memory.set(offset, &data)?; - let result = instance.invoke_export( + let result = module_instance.invoke_export( method, &[ I32(offset as i32), @@ -683,22 +657,57 @@ impl WasmExecutor { ], &mut fec ); - let returned = match result { - Ok(x) => x, + let result = match result { + Ok(Some(I64(r))) => { + let offset = r as u32; + let length = (r >> 32) as u32 as usize; + memory.get(offset, length) + .map_err(|_| ErrorKind::Runtime.into()) + }, + Ok(_) => Err(ErrorKind::InvalidReturn.into()), Err(e) => { - trace!(target: "wasm-executor", "Failed to execute code with {} pages", heap_pages); - return Err(e.into()) + trace!(target: "wasm-executor", "Failed to execute code with {} pages", memory.current_size().0); + Err(e.into()) }, }; - if let Some(I64(r)) = returned { - let offset = r as u32; - let length = (r >> 32) as u32 as usize; - memory.get(offset, length) - .map_err(|_| ErrorKind::Runtime.into()) - } else { - Err(ErrorKind::InvalidReturn.into()) + // cleanup module instance for next use + let new_low = memory.lowest_used(); + if new_low < low { + memory.zero(new_low as usize, (low - new_low) as usize)?; + memory.reset_lowest_used(low); } + memory.with_direct_access_mut(|buf| buf.resize(used_mem.0, 0)); + result + } + + /// Prepare module instance + pub fn prepare_module>( + &self, + ext: &mut E, + heap_pages: usize, + module: &Module, + ) -> Result + { + // start module instantiation. Don't run 'start' function yet. + let intermediate_instance = ModuleInstance::new( + module, + &ImportsBuilder::new() + .with_resolver("env", FunctionExecutor::::resolver()) + )?; + + // extract a reference to a linear memory, optional reference to a table + // and then initialize FunctionExecutor. + let memory = Self::get_mem_instance(intermediate_instance.not_started_instance())?; + memory.grow(Pages(heap_pages)).map_err(|_| Error::from(ErrorKind::Runtime))?; + let table: Option = intermediate_instance + .not_started_instance() + .export_by_name("__indirect_function_table") + .and_then(|e| e.as_table().cloned()); + let mut fec = FunctionExecutor::new(memory.clone(), table, ext)?; + + // finish instantiation by running 'start' function (if any). + Ok(intermediate_instance.run_start(&mut fec)?) } } @@ -726,6 +735,9 @@ mod tests { let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_panic", &[]); assert!(output.is_err()); + let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[]); + assert_eq!(output.unwrap(), vec![0u8; 0]); + let output = WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_conditional_panic", &[2]); assert!(output.is_err()); } diff --git a/core/executor/wasm/Cargo.lock b/core/executor/wasm/Cargo.lock index dcd65c107b8212c07f0888a4e4bb868e25089c95..933a8fc20ec090f5020a51a25a9964fd2793f2b3 100644 --- a/core/executor/wasm/Cargo.lock +++ b/core/executor/wasm/Cargo.lock @@ -23,7 +23,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "fixed-hash" -version = "0.3.0-beta.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -32,16 +32,24 @@ dependencies = [ [[package]] name = "hash-db" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#e61df32342920f602a9d8d71caa5117c779d3ff1" [[package]] name = "hash256-std-hasher" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#e61df32342920f602a9d8d71caa5117c779d3ff1" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "impl-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "nodrop" version = "0.1.12" @@ -49,7 +57,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "parity-codec" -version = "2.1.5" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -65,6 +73,17 @@ dependencies = [ "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "primitive-types" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro2" version = "0.4.19" @@ -126,7 +145,7 @@ name = "sr-io" version = "0.1.0" dependencies = [ "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 0.1.0", "substrate-primitives 0.1.0", @@ -136,7 +155,7 @@ dependencies = [ name = "sr-sandbox" version = "0.1.0" dependencies = [ - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 0.1.0", "substrate-primitives 0.1.0", @@ -159,16 +178,14 @@ name = "substrate-primitives" version = "0.1.0" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fixed-hash 0.3.0-beta.3 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", "hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 0.1.0", - "uint 0.5.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -183,7 +200,7 @@ dependencies = [ [[package]] name = "uint" -version = "0.5.0-beta.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -201,12 +218,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2" -"checksum fixed-hash 0.3.0-beta.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e71c99c903a9fe54baed1bc701b43daba8c6dc6d4aec89a32f667ab6b3094c4" +"checksum fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a557e80084b05c32b455963ff565a9de6f2866da023d6671705c6aff6f65e01c" "checksum hash-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)" = "" +"checksum impl-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c88568d828291c50eed30cd7fb9f8e688ad0013620186fa3e777b9f206c79f2" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dca389ea5e1632c89b2ce54f7e2b4a8a8c9d278042222a91e0bf95451218cb4c" +"checksum parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7b6a1290fe78aa6bbb5f3338ecede3062687a98b9e40cd1dbcaa47261d44097" "checksum parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa42c2cb493b60b12c75b26e8c94cb734af4df4d7f2cc229dc04c1953dac189" +"checksum primitive-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f47c18b4601125931d69fcf7b000c2c16a304e4f84d58218d6470b4502e00b58" "checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901" "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" @@ -216,5 +235,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9" "checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum uint 0.5.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4630460173a57c0af94b8306091e018025d988473f641a4af754b6cde980e1e3" +"checksum uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "082df6964410f6aa929a61ddfafc997e4f32c62c22490e439ac351cec827f436" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" diff --git a/core/finality-grandpa/Cargo.toml b/core/finality-grandpa/Cargo.toml index b507ffd6d7c15671bc1a24fdd14f1ca81ea5354d..896b1dbf8d236d9b077ca558891b6b9cfaa77874 100644 --- a/core/finality-grandpa/Cargo.toml +++ b/core/finality-grandpa/Cargo.toml @@ -4,19 +4,31 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -futures = "0.1.17" -parity-codec = "2.1" +futures = "0.1" +parity-codec = "2.2" +parity-codec-derive = "2.0" sr-primitives = { path = "../sr-primitives" } +substrate-consensus-common = { path = "../consensus/common" } substrate-primitives = { path = "../primitives" } substrate-client = { path = "../client" } +substrate-network = { path = "../network" } +substrate-service = { path = "../service", optional = true } log = "0.4" +parking_lot = "0.7.1" tokio = "0.1.7" +substrate-finality-grandpa-primitives = { path = "primitives" } +rand = "0.6" [dependencies.finality-grandpa] -version = "0.2.0" +version = "0.5.1" features = ["derive-codec"] [dev-dependencies] substrate-network = { path = "../network", features = ["test-helpers"] } -parking_lot = "0.4" substrate-keyring = { path = "../keyring" } +substrate-test-client = { path = "../test-client"} +env_logger = "0.5" + +[features] +default = ["service-integration"] +service-integration = ["substrate-service"] diff --git a/core/finality-grandpa/README.adoc b/core/finality-grandpa/README.adoc deleted file mode 100644 index 5338cf9e8cc715c589c2e812a9f65c92426b1eb5..0000000000000000000000000000000000000000 --- a/core/finality-grandpa/README.adoc +++ /dev/null @@ -1,12 +0,0 @@ -= Finality GRANDPA (aka SHAFT) - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/finality-grandpa/primitives/Cargo.toml b/core/finality-grandpa/primitives/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..78a0f05d2c0c3bff4a3b90b59ef9358b14b5b0e6 --- /dev/null +++ b/core/finality-grandpa/primitives/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "substrate-finality-grandpa-primitives" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +substrate-client = { path = "../../client", default-features = false } +substrate-primitives = { path = "../../primitives", default-features = false } +parity-codec = { version = "2.2", default-features = false } +parity-codec-derive = { version = "2.1", default-features = false } +sr-primitives = { path = "../../sr-primitives", default-features = false } +sr-std = { path = "../../sr-std", default-features = false } + +[features] +default = ["std"] +std = [ + "substrate-primitives/std", + "substrate-client/std", + "parity-codec/std", + "parity-codec-derive/std", + "sr-primitives/std", + "sr-std/std", +] diff --git a/core/finality-grandpa/primitives/src/lib.rs b/core/finality-grandpa/primitives/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..6e8c10da3198323b53f8374b67ebb0598f07f7ce --- /dev/null +++ b/core/finality-grandpa/primitives/src/lib.rs @@ -0,0 +1,98 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Primitives for GRANDPA integration, suitable for WASM compilation. + +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(not(feature = "std"), feature(alloc))] + +#[cfg(not(feature = "std"))] +extern crate alloc; + +extern crate substrate_primitives; +extern crate sr_primitives; +extern crate parity_codec; + +#[macro_use] +extern crate parity_codec_derive; + +#[macro_use] +extern crate substrate_client as client; + +extern crate sr_std as rstd; + +use substrate_primitives::Ed25519AuthorityId; +use sr_primitives::traits::{DigestFor, NumberFor}; +use rstd::vec::Vec; + +/// A scheduled change of authority set. +#[cfg_attr(feature = "std", derive(Debug, PartialEq))] +#[derive(Clone, Encode, Decode)] +pub struct ScheduledChange { + /// The new authorities after the change, along with their respective weights. + pub next_authorities: Vec<(Ed25519AuthorityId, u64)>, + /// The number of blocks to delay. + pub delay: N, +} + +/// WASM function call to check for pending changes. +pub const PENDING_CHANGE_CALL: &str = "grandpa_pending_change"; +/// WASM function call to get current GRANDPA authorities. +pub const AUTHORITIES_CALL: &str = "grandpa_authorities"; + +/// Well-known storage keys for GRANDPA. +pub mod well_known_keys { + /// The key for the authorities and weights vector in storage. + pub const AUTHORITY_PREFIX: &[u8] = b":grandpa:auth:"; + /// The key for the authorities count. + pub const AUTHORITY_COUNT: &[u8] = b":grandpa:auth:len"; +} + +decl_runtime_apis! { + /// APIs for integrating the GRANDPA finality gadget into runtimes. + /// This should be implemented on the runtime side. + /// + /// This is primarily used for negotiating authority-set changes for the + /// gadget. GRANDPA uses a signalling model of changing authority sets: + /// changes should be signalled with a delay of N blocks, and then automatically + /// applied in the runtime after those N blocks have passed. + /// + /// The consensus protocol will coordinate the handoff externally. + pub trait GrandpaApi { + /// Check a digest for pending changes. + /// Return `None` if there are no pending changes. + /// + /// Precedence towards earlier or later digest items can be given + /// based on the rules of the chain. + /// + /// No change should be scheduled if one is already and the delay has not + /// passed completely. + /// + /// This should be a pure function: i.e. as long as the runtime can interpret + /// the digest type it should return the same result regardless of the current + /// state. + fn grandpa_pending_change(digest: &DigestFor) + -> Option>>; + + /// Get the current GRANDPA authorities and weights. This should not change except + /// for when changes are scheduled and the corresponding delay has passed. + /// + /// When called at block B, it will return the set of authorities that should be + /// used to finalize descendants of this block (B+1, B+2, ...). The block B itself + /// is finalized by the authorities from block B-1. + fn grandpa_authorities() -> Vec<(Ed25519AuthorityId, u64)>; + } +} diff --git a/core/finality-grandpa/src/authorities.rs b/core/finality-grandpa/src/authorities.rs new file mode 100644 index 0000000000000000000000000000000000000000..d470ee82e3dafcf4eec31870410c2fb4af90ea6c --- /dev/null +++ b/core/finality-grandpa/src/authorities.rs @@ -0,0 +1,433 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Utilities for dealing with authorities, authority sets, and handoffs. + +use parking_lot::RwLock; +use substrate_primitives::Ed25519AuthorityId; + +use std::cmp::Ord; +use std::collections::HashMap; +use std::fmt::Debug; +use std::ops::Add; +use std::sync::Arc; + +/// A shared authority set. +pub(crate) struct SharedAuthoritySet { + inner: Arc>>, +} + +impl Clone for SharedAuthoritySet { + fn clone(&self) -> Self { + SharedAuthoritySet { inner: self.inner.clone() } + } +} + +impl SharedAuthoritySet { + /// The genesis authority set. + pub(crate) fn genesis(initial: Vec<(Ed25519AuthorityId, u64)>) -> Self { + SharedAuthoritySet { + inner: Arc::new(RwLock::new(AuthoritySet::genesis(initial))) + } + } + + /// Acquire a reference to the inner read-write lock. + pub(crate) fn inner(&self) -> &RwLock> { + &*self.inner + } +} + +impl SharedAuthoritySet +where + N: Add + Ord + Clone + Debug, + H: Debug +{ + /// Get the earliest limit-block number, if any. + pub(crate) fn current_limit(&self) -> Option { + self.inner.read().current_limit() + } + + /// Get the current set ID. This is incremented every time the set changes. + pub(crate) fn set_id(&self) -> u64 { + self.inner.read().set_id + } + + /// Get the current authorities and their weights (for the current set ID). + pub(crate) fn current_authorities(&self) -> HashMap { + self.inner.read().current_authorities.iter().cloned().collect() + } +} + +impl From> for SharedAuthoritySet { + fn from(set: AuthoritySet) -> Self { + SharedAuthoritySet { inner: Arc::new(RwLock::new(set)) } + } +} + +/// Status of the set after changes were applied. +pub(crate) struct Status { + /// Whether internal changes were made. + pub(crate) changed: bool, + /// `Some` when underlying authority set has changed, containing the + /// block where that set changed. + pub(crate) new_set_block: Option<(H, N)>, +} + +/// A set of authorities. +#[derive(Debug, Clone, Encode, Decode)] +pub(crate) struct AuthoritySet { + current_authorities: Vec<(Ed25519AuthorityId, u64)>, + set_id: u64, + pending_changes: Vec>, +} + +impl AuthoritySet { + /// Get a genesis set with given authorities. + pub(crate) fn genesis(initial: Vec<(Ed25519AuthorityId, u64)>) -> Self { + AuthoritySet { + current_authorities: initial, + set_id: 0, + pending_changes: Vec::new(), + } + } + + /// Get the current set id and a reference to the current authority set. + pub(crate) fn current(&self) -> (u64, &[(Ed25519AuthorityId, u64)]) { + (self.set_id, &self.current_authorities[..]) + } +} + +impl AuthoritySet +where + N: Add + Ord + Clone + Debug, + H: Debug +{ + /// Note an upcoming pending transition. This makes sure that there isn't + /// already any pending change for the same chain. Multiple pending changes + /// are allowed but they must be signalled in different forks. The closure + /// should return an error if the pending change block is equal to or a + /// descendent of the given block. + pub(crate) fn add_pending_change( + &mut self, + pending: PendingChange, + is_equal_or_descendent_of: F, + ) -> Result<(), E> where + F: Fn(&H) -> Result<(), E>, + { + for change in self.pending_changes.iter() { + is_equal_or_descendent_of(&change.canon_hash)?; + } + + // ordered first by effective number and then by signal-block number. + let key = (pending.effective_number(), pending.canon_height.clone()); + let idx = self.pending_changes + .binary_search_by_key(&key, |change| ( + change.effective_number(), + change.canon_height.clone(), + )) + .unwrap_or_else(|i| i); + + self.pending_changes.insert(idx, pending); + + Ok(()) + } + + /// Inspect pending changes. + pub(crate) fn pending_changes(&self) -> &[PendingChange] { + &self.pending_changes + } + + /// Get the earliest limit-block number, if any. + pub(crate) fn current_limit(&self) -> Option { + self.pending_changes.get(0).map(|change| change.effective_number().clone()) + } + + /// Apply or prune any pending transitions. Provide a closure that can be used to check for the + /// finalized block with given number. + /// + /// When the set has changed, the return value will be `Ok(Some((H, N)))` which is the canonical + /// block where the set last changed. + pub(crate) fn apply_changes(&mut self, just_finalized: N, mut canonical: F) + -> Result, E> + where F: FnMut(N) -> Result, E> + { + let mut status = Status { + changed: false, + new_set_block: None, + }; + loop { + let remove_up_to = match self.pending_changes.first() { + None => break, + Some(change) => { + let effective_number = change.effective_number(); + if effective_number > just_finalized { break } + + // check if the block that signalled the change is canonical in + // our chain. + let canonical_hash = canonical(change.canon_height.clone())?; + let effective_hash = canonical(effective_number.clone())?; + + debug!(target: "afg", "Evaluating potential set change at block {:?}. Our canonical hash is {:?}", + (&change.canon_height, &change.canon_hash), canonical_hash); + + match (canonical_hash, effective_hash) { + (Some(canonical_hash), Some(effective_hash)) => { + if canonical_hash == change.canon_hash { + // apply this change: make the set canonical + info!(target: "finality", "Applying authority set change scheduled at block #{:?}", + change.canon_height); + + self.current_authorities = change.next_authorities.clone(); + self.set_id += 1; + + status.new_set_block = Some(( + effective_hash, + effective_number.clone(), + )); + + // discard all signalled changes since they're + // necessarily from other forks + self.pending_changes.len() + } else { + 1 // prune out this entry; it's no longer relevant. + } + }, + _ => 1, // prune out this entry; it's no longer relevant. + } + } + }; + + let remove_up_to = ::std::cmp::min(remove_up_to, self.pending_changes.len()); + self.pending_changes.drain(..remove_up_to); + status.changed = true; // always changed because we strip at least the first change. + } + + Ok(status) + } + + /// Check whether the given finalized block number enacts any authority set + /// change (without triggering it). Provide a closure that can be used to + /// check for the canonical block with a given number. + pub fn enacts_change(&self, just_finalized: N, mut canonical: F) + -> Result + where F: FnMut(N) -> Result, E> + { + for change in self.pending_changes.iter() { + if change.effective_number() > just_finalized { break }; + + // check if the block that signalled the change is canonical in + // our chain. + match canonical(change.canon_height.clone())? { + Some(ref canonical_hash) if *canonical_hash == change.canon_hash => + return Ok(true), + _ => (), + } + } + + Ok(false) + } +} + +/// A pending change to the authority set. +/// +/// This will be applied when the announcing block is at some depth within +/// the finalized chain. +#[derive(Debug, Clone, Encode, Decode, PartialEq)] +pub(crate) struct PendingChange { + /// The new authorities and weights to apply. + pub(crate) next_authorities: Vec<(Ed25519AuthorityId, u64)>, + /// How deep in the finalized chain the announcing block must be + /// before the change is applied. + pub(crate) finalization_depth: N, + /// The announcing block's height. + pub(crate) canon_height: N, + /// The announcing block's hash. + pub(crate) canon_hash: H, +} + +impl + Clone> PendingChange { + /// Returns the effective number this change will be applied at. + pub fn effective_number(&self) -> N { + self.canon_height.clone() + self.finalization_depth.clone() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn ignore_existing_changes(_a: &A) -> Result<(), ::Error> { + Ok(()) + } + + #[test] + fn changes_sorted_in_correct_order() { + let mut authorities = AuthoritySet { + current_authorities: Vec::new(), + set_id: 0, + pending_changes: Vec::new(), + }; + + let change_a = PendingChange { + next_authorities: Vec::new(), + finalization_depth: 10, + canon_height: 5, + canon_hash: "hash_a", + }; + + let change_b = PendingChange { + next_authorities: Vec::new(), + finalization_depth: 0, + canon_height: 16, + canon_hash: "hash_b", + }; + + let change_c = PendingChange { + next_authorities: Vec::new(), + finalization_depth: 5, + canon_height: 10, + canon_hash: "hash_c", + }; + + authorities.add_pending_change(change_a.clone(), ignore_existing_changes).unwrap(); + authorities.add_pending_change(change_b.clone(), ignore_existing_changes).unwrap(); + authorities.add_pending_change(change_c.clone(), ignore_existing_changes).unwrap(); + + assert_eq!(authorities.pending_changes, vec![change_a, change_c, change_b]); + } + + #[test] + fn apply_change() { + let mut authorities = AuthoritySet { + current_authorities: Vec::new(), + set_id: 0, + pending_changes: Vec::new(), + }; + + let set_a = vec![([1; 32].into(), 5)]; + let set_b = vec![([2; 32].into(), 5)]; + + let change_a = PendingChange { + next_authorities: set_a.clone(), + finalization_depth: 10, + canon_height: 5, + canon_hash: "hash_a", + }; + + let change_b = PendingChange { + next_authorities: set_b.clone(), + finalization_depth: 10, + canon_height: 5, + canon_hash: "hash_b", + }; + + authorities.add_pending_change(change_a.clone(), ignore_existing_changes).unwrap(); + authorities.add_pending_change(change_b.clone(), ignore_existing_changes).unwrap(); + + authorities.apply_changes(10, |_| Err(())).unwrap(); + assert!(authorities.current_authorities.is_empty()); + + authorities.apply_changes(15, |n| match n { + 5 => Ok(Some("hash_a")), + 15 => Ok(Some("hash_15_canon")), + _ => Err(()), + }).unwrap(); + + assert_eq!(authorities.current_authorities, set_a); + assert_eq!(authorities.set_id, 1); + assert!(authorities.pending_changes.is_empty()); + } + + #[test] + fn disallow_multiple_changes_on_same_fork() { + let mut authorities = AuthoritySet { + current_authorities: Vec::new(), + set_id: 0, + pending_changes: Vec::new(), + }; + + let set_a = vec![([1; 32].into(), 5)]; + let set_b = vec![([2; 32].into(), 5)]; + let set_c = vec![([3; 32].into(), 5)]; + + let change_a = PendingChange { + next_authorities: set_a.clone(), + finalization_depth: 10, + canon_height: 5, + canon_hash: "hash_a", + }; + + let change_b = PendingChange { + next_authorities: set_b.clone(), + finalization_depth: 10, + canon_height: 16, + canon_hash: "hash_b", + }; + + let change_c = PendingChange { + next_authorities: set_c.clone(), + finalization_depth: 10, + canon_height: 16, + canon_hash: "hash_c", + }; + + let is_equal_or_descendent_of = |base, block| -> Result<(), ()> { + match (base, block) { + ("hash_a", "hash_b") => return Err(()), + ("hash_a", "hash_c") => return Ok(()), + ("hash_c", "hash_b") => return Ok(()), + _ => unreachable!(), + } + }; + + authorities.add_pending_change( + change_a.clone(), + |base| is_equal_or_descendent_of(base, change_a.canon_hash), + ).unwrap(); + + // change b is on the same chain has the unfinalized change a so it should error + assert!( + authorities.add_pending_change( + change_b.clone(), + |base| is_equal_or_descendent_of(base, change_b.canon_hash), + ).is_err() + ); + + // change c is accepted because it's on a different fork + authorities.add_pending_change( + change_c.clone(), + |base| is_equal_or_descendent_of(base, change_c.canon_hash) + ).unwrap(); + + authorities.apply_changes(15, |n| match n { + 5 => Ok(Some("hash_a")), + 15 => Ok(Some("hash_a15")), + _ => Err(()), + }).unwrap(); + + assert_eq!(authorities.current_authorities, set_a); + + // pending change c has been removed since it was on a different fork + // and can no longer be enacted + assert!(authorities.pending_changes.is_empty()); + + // pending change b can now be added + authorities.add_pending_change( + change_b.clone(), + |base| is_equal_or_descendent_of(base, change_b.canon_hash), + ).unwrap(); + } +} diff --git a/core/finality-grandpa/src/communication.rs b/core/finality-grandpa/src/communication.rs new file mode 100644 index 0000000000000000000000000000000000000000..32b2cc3a7605b4edc1020a08c53dd72009a168b6 --- /dev/null +++ b/core/finality-grandpa/src/communication.rs @@ -0,0 +1,435 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Incoming message streams that verify signatures, and outgoing message streams +//! that sign or re-shape. + +use futures::prelude::*; +use futures::sync::mpsc; +use codec::{Encode, Decode}; +use substrate_primitives::{ed25519, Ed25519AuthorityId}; +use runtime_primitives::traits::Block as BlockT; +use tokio::timer::Interval; +use {Error, Network, Message, SignedMessage, Commit, CompactCommit}; + +use std::collections::HashMap; +use std::sync::Arc; + +fn localized_payload(round: u64, set_id: u64, message: &E) -> Vec { + (message, round, set_id).encode() +} + +enum Broadcast { + // set_id, round, encoded commit. + Commit(u64, u64, Vec), + // set_id, round, encoded signed message. + Message(u64, u64, Vec), +} + +impl Broadcast { + fn set_id(&self) -> u64 { + match *self { + Broadcast::Commit(s, _, _) => s, + Broadcast::Message(s, _, _) => s, + } + } +} + +/// Produces a future that should be run in the background and proxies +/// and rebroadcasts messages. +pub(crate) fn rebroadcasting_network(network: N) -> (BroadcastWorker, BroadcastHandle) { + use std::time::Duration; + const REBROADCAST_PERIOD: Duration = Duration::from_secs(60); + + let (tx, rx) = mpsc::unbounded(); + + ( + BroadcastWorker { + interval: Interval::new_interval(REBROADCAST_PERIOD), + set_id: 0, // will be overwritten on first item to broadcast. + last_commit: None, + round_messages: (0, Vec::new()), + network: network.clone(), + incoming_broadcast: rx, + }, + BroadcastHandle { + relay: tx, + network, + }, + ) +} + +// A worker which broadcasts messages to the background, potentially +// rebroadcasting. +#[must_use = "network rebroadcast future must be driven to completion"] +pub(crate) struct BroadcastWorker { + interval: Interval, + set_id: u64, + last_commit: Option<(u64, Vec)>, + round_messages: (u64, Vec>), + network: N, + incoming_broadcast: mpsc::UnboundedReceiver, +} + +/// A handle used by communication work to broadcast to network. +#[derive(Clone)] +pub(crate) struct BroadcastHandle { + relay: mpsc::UnboundedSender, + network: N, +} + +impl Future for BroadcastWorker { + type Item = (); + type Error = Error; + + fn poll(&mut self) -> Poll<(), Error> { + { + let mut rebroadcast = false; + loop { + match self.interval.poll().map_err(Error::Timer)? { + Async::NotReady => break, + Async::Ready(_) => { rebroadcast = true; } + } + } + + if rebroadcast { + if let Some((c_round, ref c_commit)) = self.last_commit { + self.network.send_commit(c_round, self.set_id, c_commit.clone()); + } + + let round = self.round_messages.0; + for message in self.round_messages.1.iter().cloned() { + self.network.send_message(round, self.set_id, message); + } + } + } + loop { + match self.incoming_broadcast.poll().expect("UnboundedReceiver does not yield errors; qed") { + Async::NotReady => return Ok(Async::NotReady), + Async::Ready(None) => return Err(Error::Network( + "all broadcast handles dropped, connection to network severed".into() + )), + Async::Ready(Some(item)) => { + if item.set_id() > self.set_id { + self.set_id = item.set_id(); + self.last_commit = None; + self.round_messages = (0, Vec::new()); + } + + match item { + Broadcast::Commit(set_id, round, commit) => { + if self.set_id == set_id { + if round >= self.last_commit.as_ref().map_or(0, |&(r, _)| r) { + self.last_commit = Some((round, commit.clone())); + } + } + + // always send out to network. + self.network.send_commit(round, self.set_id, commit); + } + Broadcast::Message(set_id, round, message) => { + if self.set_id == set_id { + if round > self.round_messages.0 { + self.round_messages = (round, vec![message.clone()]); + } else if round == self.round_messages.0 { + self.round_messages.1.push(message.clone()); + }; + + // ignore messages from earlier rounds. + } + + // always send out to network. + self.network.send_message(round, set_id, message); + } + } + } + } + } + } +} + +impl Network for BroadcastHandle { + type In = N::In; + + fn messages_for(&self, round: u64, set_id: u64) -> Self::In { + self.network.messages_for(round, set_id) + } + + fn send_message(&self, round: u64, set_id: u64, message: Vec) { + let _ = self.relay.unbounded_send(Broadcast::Message(set_id, round, message)); + } + + fn drop_messages(&self, round: u64, set_id: u64) { + self.network.drop_messages(round, set_id); + } + + fn commit_messages(&self, set_id: u64) -> Self::In { + self.network.commit_messages(set_id) + } + + fn send_commit(&self, round: u64, set_id: u64, message: Vec) { + let _ = self.relay.unbounded_send(Broadcast::Commit(round, set_id, message)); + } +} + +// check a message. +pub(crate) fn check_message_sig( + message: &Message, + id: &Ed25519AuthorityId, + signature: &ed25519::Signature, + round: u64, + set_id: u64, +) -> Result<(), ()> { + let as_public = ::ed25519::Public::from_raw(id.0); + let encoded_raw = localized_payload(round, set_id, message); + if ::ed25519::verify_strong(signature, &encoded_raw, as_public) { + Ok(()) + } else { + debug!(target: "afg", "Bad signature on message from {:?}", id); + Err(()) + } +} + +/// converts a message stream into a stream of signed messages. +/// the output stream checks signatures also. +pub(crate) fn checked_message_stream( + round: u64, + set_id: u64, + inner: S, + voters: Arc>, +) + -> impl Stream,Error=Error> where + S: Stream,Error=()> +{ + inner + .filter_map(|raw| { + let decoded = SignedMessage::::decode(&mut &raw[..]); + if decoded.is_none() { + debug!(target: "afg", "Skipping malformed message {:?}", raw); + } + decoded + }) + .and_then(move |msg| { + // check signature. + if !voters.contains_key(&msg.id) { + debug!(target: "afg", "Skipping message from unknown voter {}", msg.id); + return Ok(None); + } + + // we ignore messages where the signature doesn't check out. + let res = check_message_sig::( + &msg.message, + &msg.id, + &msg.signature, + round, + set_id + ); + Ok(res.map(move |()| msg).ok()) + }) + .filter_map(|x| x) + .map_err(|()| Error::Network(format!("Failed to receive message on unbounded stream"))) +} + +struct OutgoingMessages { + round: u64, + set_id: u64, + locals: Option<(Arc, Ed25519AuthorityId)>, + sender: mpsc::UnboundedSender>, + network: N, +} + +impl Sink for OutgoingMessages { + type SinkItem = Message; + type SinkError = Error; + + fn start_send(&mut self, msg: Message) -> StartSend, Error> { + // when locals exist, sign messages on import + if let Some((ref pair, local_id)) = self.locals { + let encoded = localized_payload(self.round, self.set_id, &msg); + let signature = pair.sign(&encoded[..]); + let signed = SignedMessage:: { + message: msg, + signature, + id: local_id, + }; + + // forward to network and to inner sender. + self.network.send_message(self.round, self.set_id, signed.encode()); + let _ = self.sender.unbounded_send(signed); + } + + Ok(AsyncSink::Ready) + } + + fn poll_complete(&mut self) -> Poll<(), Error> { Ok(Async::Ready(())) } + + fn close(&mut self) -> Poll<(), Error> { + // ignore errors since we allow this inner sender to be closed already. + self.sender.close().or_else(|_| Ok(Async::Ready(()))) + } +} + +impl Drop for OutgoingMessages { + fn drop(&mut self) { + self.network.drop_messages(self.round, self.set_id); + } +} + +/// A sink for outgoing messages. This signs the messages with the key, +/// if we are an authority. A stream for the signed messages is also returned. +/// +/// A future can push unsigned messages into the sink. They will be automatically +/// broadcast to the network. The returned stream should be combined with other input. +pub(crate) fn outgoing_messages( + round: u64, + set_id: u64, + local_key: Option>, + voters: Arc>, + network: N, +) -> ( + impl Stream,Error=Error>, + impl Sink,SinkError=Error>, +) { + let locals = local_key.and_then(|pair| { + let public = pair.public(); + let id = Ed25519AuthorityId(public.0); + if voters.contains_key(&id) { + Some((pair, id)) + } else { + None + } + }); + + let (tx, rx) = mpsc::unbounded(); + let outgoing = OutgoingMessages:: { + round, + set_id, + network, + locals, + sender: tx, + }; + + let rx = rx.map_err(move |()| Error::Network( + format!("Failed to receive on unbounded receiver for round {}", round) + )); + + (rx, outgoing) +} + +fn check_compact_commit( + msg: CompactCommit, + voters: &HashMap, + round: u64, + set_id: u64, +) -> Option> { + use grandpa::Message as GrandpaMessage; + if msg.precommits.len() != msg.auth_data.len() || msg.precommits.is_empty() { + debug!(target: "afg", "Skipping malformed compact commit"); + return None; + } + + // check signatures on all contained precommits. + for (precommit, &(ref sig, ref id)) in msg.precommits.iter().zip(&msg.auth_data) { + if !voters.contains_key(id) { + debug!(target: "afg", "Skipping commit containing unknown voter {}", id); + return None; + } + + let res = check_message_sig::( + &GrandpaMessage::Precommit(precommit.clone()), + id, + sig, + round, + set_id, + ); + + if let Err(()) = res { + debug!(target: "afg", "Skipping commit containing bad message"); + return None; + } + } + + Some(msg) +} + +/// A stream for incoming commit messages. This checks all the signatures on the +/// messages. +pub(crate) fn checked_commit_stream( + set_id: u64, + inner: S, + voters: Arc>, +) + -> impl Stream),Error=Error> where + S: Stream,Error=()> +{ + inner + .filter_map(|raw| { + // this could be optimized by decoding piecewise. + let decoded = <(u64, CompactCommit)>::decode(&mut &raw[..]); + if decoded.is_none() { + trace!(target: "afg", "Skipping malformed commit message {:?}", raw); + } + decoded + }) + .filter_map(move |(round, msg)| { + check_compact_commit::(msg, &*voters, round, set_id).map(move |c| (round, c)) + }) + .map_err(|()| Error::Network(format!("Failed to receive message on unbounded stream"))) +} + +/// An output sink for commit messages. +pub(crate) struct CommitsOut { + network: N, + set_id: u64, + _marker: ::std::marker::PhantomData, +} + +impl CommitsOut { + /// Create a new commit output stream. + pub(crate) fn new(network: N, set_id: u64) -> Self { + CommitsOut { + network, + set_id, + _marker: Default::default(), + } + } +} + +impl Sink for CommitsOut { + type SinkItem = (u64, Commit); + type SinkError = Error; + + fn start_send(&mut self, input: (u64, Commit)) -> StartSend { + let (round, commit) = input; + let (precommits, auth_data) = commit.precommits.into_iter() + .map(|signed| (signed.precommit, (signed.signature, signed.id))) + .unzip(); + + let compact_commit = CompactCommit:: { + target_hash: commit.target_hash, + target_number: commit.target_number, + precommits, + auth_data + }; + + self.network.send_commit(round, self.set_id, Encode::encode(&(round, compact_commit))); + + Ok(AsyncSink::Ready) + } + + fn close(&mut self) -> Poll<(), Error> { Ok(Async::Ready(())) } + fn poll_complete(&mut self) -> Poll<(), Error> { Ok(Async::Ready(())) } +} diff --git a/core/finality-grandpa/src/finality_proof.rs b/core/finality-grandpa/src/finality_proof.rs new file mode 100644 index 0000000000000000000000000000000000000000..c927aa68a08e95997453644b20807e1bb90dedb8 --- /dev/null +++ b/core/finality-grandpa/src/finality_proof.rs @@ -0,0 +1,428 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! GRANDPA block finality proof generation and check. +//! +//! Finality of block B is proved by providing: +//! 1) valid headers sub-chain from the block B to the block F; +//! 2) valid (with respect to proved authorities) GRANDPA justification of the block F; +//! 3) proof-of-execution of the `grandpa_authorities` call at the block F. +//! +//! Since earliest possible justification is returned, the GRANDPA authorities set +//! at the block F is guaranteed to be the same as in the block B (this is because block +//! that enacts new GRANDPA authorities set always comes with justification). It also +//! means that the `set_id` is the same at blocks B and F. +//! +//! The caller should track the `set_id`. The most straightforward way is to fetch finality +//! proofs ONLY for blocks on the tip of the chain and track the latest known `set_id`. + +use std::collections::HashMap; + +use client::{ + blockchain::Backend as BlockchainBackend, + error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult}, + light::fetcher::RemoteCallRequest, +}; +use codec::{Encode, Decode}; +use grandpa::BlockNumberOps; +use runtime_primitives::generic::BlockId; +use runtime_primitives::traits::{ + NumberFor, Block as BlockT, Header as HeaderT, One, +}; +use substrate_primitives::{Ed25519AuthorityId, H256}; + +use GrandpaJustification; + +/// Prepare proof-of-finality for the given block. +/// +/// The proof is the serialized `FinalityProof` constructed using earliest known +/// justification of the block. None is returned if there's no known justification atm. +pub fn prove_finality( + blockchain: &B, + generate_execution_proof: G, + block: Block::Hash, +) -> ::client::error::Result>> + where + B: BlockchainBackend, + G: Fn(&BlockId, &str, &[u8]) -> ClientResult>>, +{ + let block_id = BlockId::Hash(block); + let mut block_number = blockchain.expect_block_number_from_id(&block_id)?; + + // early-return if we sure that the block isn't finalized yet + let info = blockchain.info()?; + if info.finalized_number < block_number { + return Ok(None); + } + + // early-return if we sure that the block is NOT a part of canonical chain + let canonical_block = blockchain.expect_block_hash_from_id(&BlockId::Number(block_number))?; + if block != canonical_block { + return Err(ClientErrorKind::Backend( + "Cannot generate finality proof for non-canonical block".into() + ).into()); + } + + // now that we know that the block is finalized, we can generate finalization proof + + // we need to prove grandpa authorities set that has generated justification + // BUT since `GrandpaApi::grandpa_authorities` call returns the set that becames actual + // at the next block, the proof-of execution is generated using parent block' state + // (this will fail if we're trying to prove genesis finality, but such the call itself is redundant) + let mut current_header = blockchain.expect_header(BlockId::Hash(block))?; + let parent_block_id = BlockId::Hash(*current_header.parent_hash()); + let authorities_proof = generate_execution_proof( + &parent_block_id, + "GrandpaApi_grandpa_authorities", + &[], + )?; + + // search for earliest post-block (inclusive) justification + let mut finalization_path = Vec::new(); + loop { + finalization_path.push(current_header); + + match blockchain.justification(BlockId::Number(block_number))? { + Some(justification) => return Ok(Some(FinalityProof { + finalization_path, + justification, + authorities_proof, + }.encode())), + None if block_number == info.finalized_number => break, + None => { + block_number = block_number + One::one(); + current_header = blockchain.expect_header(BlockId::Number(block_number))?; + }, + } + } + + Err(ClientErrorKind::Backend( + "cannot find justification for finalized block".into() + ).into()) +} + +/// Check proof-of-finality for the given block. +/// +/// Returns the vector of headers (including `block` header, ordered by ASC block number) that MUST be +/// validated + imported at once (i.e. within single db transaction). If at least one of those headers +/// is invalid, all other MUST be considered invalid. +pub fn check_finality_proof, C>( + check_execution_proof: C, + parent_header: Block::Header, + block: (NumberFor, Block::Hash), + set_id: u64, + remote_proof: Vec, +) -> ClientResult> + where + NumberFor: grandpa::BlockNumberOps, + C: Fn(&RemoteCallRequest) -> ClientResult>, +{ + do_check_finality_proof::>( + check_execution_proof, + parent_header, + block, + set_id, + remote_proof, + ) +} + +/// Check proof-of-finality using given justification type. +fn do_check_finality_proof, C, J>( + check_execution_proof: C, + parent_header: Block::Header, + block: (NumberFor, Block::Hash), + set_id: u64, + remote_proof: Vec, +) -> ClientResult> + where + NumberFor: grandpa::BlockNumberOps, + C: Fn(&RemoteCallRequest) -> ClientResult>, + J: ProvableJustification, +{ + // decode finality proof + let proof = FinalityProof::::decode(&mut &remote_proof[..]) + .ok_or_else(|| ClientErrorKind::BadJustification("failed to decode finality proof".into()))?; + + // check that the first header in finalization path is the block itself + { + let finalized_header = proof.finalization_path.first() + .ok_or_else(|| ClientError::from(ClientErrorKind::BadJustification( + "finality proof: finalized path is empty".into() + )))?; + if *finalized_header.number() != block.0 || finalized_header.hash() != block.1 { + return Err(ClientErrorKind::BadJustification( + "finality proof: block is not a part of finalized path".into() + ).into()); + } + } + + // check that the last header in finalization path is the jsutification target block + let just_block = proof.justification.target_block(); + { + let finalized_header = proof.finalization_path.last() + .expect("checked above that proof.finalization_path is not empty; qed"); + if *finalized_header.number() != just_block.0 || finalized_header.hash() != just_block.1 { + return Err(ClientErrorKind::BadJustification( + "finality proof: target jsutification block is not a part of finalized path".into() + ).into()); + } + } + + // check authorities set proof && get grandpa authorities that should have signed justification + let grandpa_authorities = check_execution_proof(&RemoteCallRequest { + block: just_block.1, + header: parent_header, + method: "GrandpaApi_grandpa_authorities".into(), + call_data: vec![], + retry_count: None, + })?; + let grandpa_authorities: Vec<(Ed25519AuthorityId, u64)> = Decode::decode(&mut &grandpa_authorities[..]) + .ok_or_else(|| ClientErrorKind::BadJustification("failed to decode GRANDPA authorities set proof".into()))?; + + // and now check justification + proof.justification.verify(set_id, &grandpa_authorities.into_iter().collect())?; + + Ok(proof.finalization_path) +} + +/// Proof of finality. +/// +/// Finality of block B is proved by providing: +/// 1) valid headers sub-chain from the block B to the block F; +/// 2) proof of `GrandpaApi::grandpa_authorities()` call at the block F; +/// 3) valid (with respect to proved authorities) GRANDPA justification of the block F. +#[derive(Debug, PartialEq, Encode, Decode)] +struct FinalityProof { + /// Headers-path (ordered by block number, ascending) from the block we're gathering proof for + /// (inclusive) to the target block of the justification (inclusive). + pub finalization_path: Vec
, + /// Justification (finalization) of the last block from the `finalization_path`. + pub justification: Justification, + /// Proof of `GrandpaApi::grandpa_authorities` call execution at the + /// justification' target block. + pub authorities_proof: Vec>, +} + +/// Justification used to prove block finality. +trait ProvableJustification: Encode + Decode { + /// Get target block of this justification. + fn target_block(&self) -> (Header::Number, Header::Hash); + + /// Verify justification with respect to authorities set and authorities set id. + fn verify(&self, set_id: u64, authorities: &HashMap) -> ClientResult<()>; +} + +impl> ProvableJustification for GrandpaJustification + where + NumberFor: BlockNumberOps, +{ + fn target_block(&self) -> (NumberFor, Block::Hash) { + (self.commit.target_number, self.commit.target_hash) + } + + fn verify(&self, set_id: u64, authorities: &HashMap) -> ClientResult<()> { + GrandpaJustification::verify(self, set_id, authorities) + } +} + +#[cfg(test)] +mod tests { + use test_client::runtime::{Block, Header}; + use test_client::client::backend::NewBlockState; + use test_client::client::in_mem::Blockchain as InMemoryBlockchain; + use super::*; + + type FinalityProof = super::FinalityProof>; + + #[derive(Encode, Decode)] + struct ValidFinalityProof(Vec); + + impl ProvableJustification
for ValidFinalityProof { + fn target_block(&self) -> (u64, H256) { (3, header(3).hash()) } + + fn verify(&self, set_id: u64, authorities: &HashMap) -> ClientResult<()> { + assert_eq!(set_id, 1); + assert_eq!(authorities, &vec![ + (Ed25519AuthorityId([1u8; 32]), 1), + (Ed25519AuthorityId([2u8; 32]), 2), + (Ed25519AuthorityId([3u8; 32]), 3), + ].into_iter().collect()); + Ok(()) + } + } + + fn header(number: u64) -> Header { + let parent_hash = match number { + 0 => Default::default(), + _ => header(number - 1).hash(), + }; + Header::new(number, 0.into(), 0.into(), parent_hash, Default::default()) + } + + fn side_header(number: u64) -> Header { + Header::new(number, 0.into(), 1.into(), header(number - 1).hash(), Default::default()) + } + + fn test_blockchain() -> InMemoryBlockchain { + let blockchain = InMemoryBlockchain::::new(); + blockchain.insert(header(0).hash(), header(0), Some(vec![0]), None, NewBlockState::Final).unwrap(); + blockchain.insert(header(1).hash(), header(1), Some(vec![1]), None, NewBlockState::Final).unwrap(); + blockchain.insert(header(2).hash(), header(2), None, None, NewBlockState::Best).unwrap(); + blockchain.insert(header(3).hash(), header(3), Some(vec![3]), None, NewBlockState::Final).unwrap(); + blockchain + } + + #[test] + fn finality_proof_is_not_generated_for_non_final_block() { + let blockchain = test_blockchain(); + blockchain.insert(header(4).hash(), header(4), None, None, NewBlockState::Best).unwrap(); + + // when asking for finality of block 4, None is returned + let proof_of_4 = prove_finality(&blockchain, |_, _, _| Ok(vec![vec![42]]), header(4).hash()) + .unwrap(); + assert_eq!(proof_of_4, None); + } + + #[test] + fn finality_proof_fails_for_non_canonical_block() { + let blockchain = test_blockchain(); + blockchain.insert(header(4).hash(), header(4), None, None, NewBlockState::Best).unwrap(); + blockchain.insert(side_header(4).hash(), side_header(4), None, None, NewBlockState::Best).unwrap(); + blockchain.insert(header(5).hash(), header(5), Some(vec![5]), None, NewBlockState::Final).unwrap(); + + // when asking for finality of side-block 42, None is returned + let proof_of_side_4_fails = prove_finality(&blockchain, |_, _, _| Ok(vec![vec![42]]), 42.into()).is_err(); + assert_eq!(proof_of_side_4_fails, true); + } + + #[test] + fn finality_proof_fails_if_no_justification_known() { + let blockchain = test_blockchain(); + blockchain.insert(header(4).hash(), header(4), None, None, NewBlockState::Final).unwrap(); + + // when asking for finality of block 4, search for justification failing + let proof_of_4_fails = prove_finality(&blockchain, |_, _, _| Ok(vec![vec![42]]), 42.into()).is_err(); + assert_eq!(proof_of_4_fails, true); + } + + #[test] + fn prove_finality_is_generated() { + let blockchain = test_blockchain(); + + // when asking for finality of block 2, justification of 3 is returned + let proof_of_2: FinalityProof = prove_finality(&blockchain, |_, _, _| Ok(vec![vec![42]]), header(2).hash()) + .unwrap().and_then(|p| Decode::decode(&mut &p[..])).unwrap(); + assert_eq!(proof_of_2, FinalityProof { + finalization_path: vec![header(2), header(3)], + justification: vec![3], + authorities_proof: vec![vec![42]], + }); + + // when asking for finality of block 3, justification of 3 is returned + let proof_of_3: FinalityProof = prove_finality(&blockchain, |_, _, _| Ok(vec![vec![42]]), header(3).hash()) + .unwrap().and_then(|p| Decode::decode(&mut &p[..])).unwrap(); + assert_eq!(proof_of_3, FinalityProof { + finalization_path: vec![header(3)], + justification: vec![3], + authorities_proof: vec![vec![42]], + }); + } + + #[test] + fn finality_proof_check_fails_when_block_is_not_included() { + let mut proof_of_2: FinalityProof = prove_finality( + &test_blockchain(), + |_, _, _| Ok(vec![vec![42]]), + header(2).hash(), + ).unwrap().and_then(|p| Decode::decode(&mut &p[..])).unwrap(); + proof_of_2.finalization_path.remove(0); + + // block for which we're trying to request finality proof is missing from finalization_path + assert_eq!(do_check_finality_proof::( + |_| Ok(Vec::::new().encode()), + header(1), + (2, header(2).hash()), + 1, + proof_of_2.encode(), + ).is_err(), true); + } + + #[test] + fn finality_proof_check_fails_when_justified_block_is_not_included() { + let mut proof_of_2: FinalityProof = prove_finality( + &test_blockchain(), + |_, _, _| Ok(vec![vec![42]]), + header(2).hash(), + ).unwrap().and_then(|p| Decode::decode(&mut &p[..])).unwrap(); + proof_of_2.finalization_path.remove(1); + + // justified block is missing from finalization_path + assert_eq!(do_check_finality_proof::( + |_| Ok(Vec::::new().encode()), + header(1), + (2, header(2).hash()), + 1, + proof_of_2.encode(), + ).is_err(), true); + } + + #[test] + fn finality_proof_check_fails_when_justification_verification_fails() { + #[derive(Encode, Decode)] + struct InvalidFinalityProof(Vec); + + impl ProvableJustification
for InvalidFinalityProof { + fn target_block(&self) -> (u64, H256) { (3, header(3).hash()) } + + fn verify(&self, _set_id: u64, _authorities: &HashMap) -> ClientResult<()> { + Err(ClientErrorKind::Backend("test error".into()).into()) + } + } + + let mut proof_of_2: FinalityProof = prove_finality( + &test_blockchain(), + |_, _, _| Ok(vec![vec![42]]), + header(2).hash(), + ).unwrap().and_then(|p| Decode::decode(&mut &p[..])).unwrap(); + proof_of_2.finalization_path.remove(1); + + // justification is not valid + assert_eq!(do_check_finality_proof::( + |_| Ok(Vec::::new().encode()), + header(1), + (2, header(2).hash()), + 1, + proof_of_2.encode(), + ).is_err(), true); + } + + #[test] + fn finality_proof_check_works() { + let proof_of_2 = prove_finality(&test_blockchain(), |_, _, _| Ok(vec![vec![42]]), header(2).hash()) + .unwrap().unwrap(); + assert_eq!(do_check_finality_proof::( + |_| Ok(vec![ + (Ed25519AuthorityId([1u8; 32]), 1u64), + (Ed25519AuthorityId([2u8; 32]), 2u64), + (Ed25519AuthorityId([3u8; 32]), 3u64), + ].encode()), + header(1), + (2, header(2).hash()), + 1, + proof_of_2, + ).unwrap(), vec![header(2), header(3)]); + } +} diff --git a/core/finality-grandpa/src/lib.rs b/core/finality-grandpa/src/lib.rs index d3fc1bf1eeac8633a0ce3c8c1796444f72d15036..ba7888e0d7343ad5e0b20fa99ab0f4e3bc2a91a9 100644 --- a/core/finality-grandpa/src/lib.rs +++ b/core/finality-grandpa/src/lib.rs @@ -14,65 +14,178 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Integration of the GRANDPA finality gadget into substrate. //! -//! This is a long-running future that produces finality notifications. -// end::description[] +//! 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`. 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, +//! 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. extern crate finality_grandpa as grandpa; extern crate futures; extern crate substrate_client as client; extern crate sr_primitives as runtime_primitives; +extern crate substrate_consensus_common as consensus_common; +extern crate substrate_network as network; extern crate substrate_primitives; extern crate tokio; +extern crate parking_lot; extern crate parity_codec as codec; +extern crate substrate_finality_grandpa_primitives as fg_primitives; +extern crate rand; #[macro_use] extern crate log; +#[cfg(feature="service-integration")] +extern crate substrate_service as service; + #[cfg(test)] -extern crate substrate_network as network; +extern crate substrate_keyring as keyring; #[cfg(test)] -extern crate parking_lot; +extern crate substrate_test_client as test_client; #[cfg(test)] -extern crate substrate_keyring as keyring; +extern crate env_logger; + +#[macro_use] +extern crate parity_codec_derive; use futures::prelude::*; -use futures::stream::Fuse; use futures::sync::mpsc; -use client::{Client, ImportNotifications, backend::Backend, CallExecutor}; +use client::{ + BlockchainEvents, CallExecutor, Client, backend::Backend, + error::Error as ClientError, error::ErrorKind as ClientErrorKind, +}; +use client::blockchain::HeaderBackend; use codec::{Encode, Decode}; -use runtime_primitives::traits::{As, NumberFor, Block as BlockT, Header as HeaderT}; +use consensus_common::{BlockImport, Error as ConsensusError, ErrorKind as ConsensusErrorKind, ImportBlock, ImportResult, Authorities}; +use runtime_primitives::Justification; +use runtime_primitives::traits::{ + NumberFor, Block as BlockT, Header as HeaderT, DigestFor, ProvideRuntimeApi, Hash as HashT, + DigestItemFor, DigestItem, As, Zero, +}; +use fg_primitives::GrandpaApi; use runtime_primitives::generic::BlockId; -use substrate_primitives::{ed25519, H256, AuthorityId, Blake2Hasher}; -use tokio::timer::Interval; +use substrate_primitives::{ed25519, H256, Ed25519AuthorityId, Blake2Hasher}; +use tokio::timer::Delay; use grandpa::Error as GrandpaError; -use grandpa::{voter, round::State as RoundState, Prevote, Precommit, Equivocation}; +use grandpa::{voter, round::State as RoundState, Equivocation, BlockNumberOps}; -use std::collections::{VecDeque, HashMap}; +use network::{Service as NetworkService, ExHashT}; +use network::consensus_gossip::{ConsensusMessage}; +use std::collections::{HashMap, HashSet}; +use std::fmt; use std::sync::Arc; use std::time::{Instant, Duration}; +use authorities::SharedAuthoritySet; +use until_imported::{UntilCommitBlocksImported, UntilVoteTargetImported}; + +pub use fg_primitives::ScheduledChange; + +mod authorities; +mod communication; +mod finality_proof; +mod until_imported; + +#[cfg(feature="service-integration")] +mod service_integration; +#[cfg(feature="service-integration")] +pub use service_integration::{LinkHalfForService, BlockImportForService}; + +pub use finality_proof::{prove_finality, check_finality_proof}; + +#[cfg(test)] +mod tests; + const LAST_COMPLETED_KEY: &[u8] = b"grandpa_completed_round"; +const AUTHORITY_SET_KEY: &[u8] = b"grandpa_voters"; +const CONSENSUS_CHANGES_KEY: &[u8] = b"grandpa_consensus_changes"; + +/// round-number, round-state +type LastCompleted = (u64, RoundState); /// A GRANDPA message for a substrate chain. -pub type Message = grandpa::Message<::Hash>; +pub type Message = grandpa::Message<::Hash, NumberFor>; /// A signed message. -pub type SignedMessage = grandpa::SignedMessage<::Hash, ed25519::Signature, AuthorityId>; +pub type SignedMessage = grandpa::SignedMessage< + ::Hash, + NumberFor, + ed25519::Signature, + Ed25519AuthorityId, +>; +/// A prevote message for this chain's block type. +pub type Prevote = grandpa::Prevote<::Hash, NumberFor>; +/// A precommit message for this chain's block type. +pub type Precommit = grandpa::Precommit<::Hash, NumberFor>; +/// A commit message for this chain's block type. +pub type Commit = grandpa::Commit< + ::Hash, + NumberFor, + ed25519::Signature, + Ed25519AuthorityId +>; +/// A compact commit message for this chain's block type. +pub type CompactCommit = grandpa::CompactCommit< + ::Hash, + NumberFor, + ed25519::Signature, + Ed25519AuthorityId +>; /// Configuration for the GRANDPA service. +#[derive(Clone)] pub struct Config { /// The expected duration for a message to be gossiped across the network. pub gossip_duration: Duration, - /// The voters. - // TODO: make dynamic - pub voters: Vec, + /// Justification generation period (in blocks). GRANDPA will try to generate justifications + /// at least every justification_period blocks. There are some other events which might cause + /// justification generation. + pub justification_period: u64, /// The local signing key. pub local_key: Option>, + /// Some local identifier of the voter. + pub name: Option, +} + +impl Config { + fn name(&self) -> &str { + self.name.as_ref().map(|s| s.as_str()).unwrap_or("") + } } /// Errors that can occur while voting in GRANDPA. @@ -85,7 +198,7 @@ pub enum Error { /// A blockchain error. Blockchain(String), /// Could not complete a round on disk. - CouldNotCompleteRound(::client::error::Error), + Client(ClientError), /// A timer failed to fire. Timer(::tokio::timer::Error), } @@ -96,6 +209,12 @@ impl From for Error { } } +impl From for Error { + fn from(e: ClientError) -> Self { + Error::Client(e) + } +} + /// A handle to the network. This is generally implemented by providing some /// handle to a gossip service or similar. /// @@ -106,294 +225,170 @@ pub trait Network: Clone { /// Get a stream of messages for a specific round. This stream should /// never logically conclude. - fn messages_for(&self, round: u64) -> Self::In; + fn messages_for(&self, round: u64, set_id: u64) -> Self::In; /// Send a message at a specific round out. - fn send_message(&self, round: u64, message: Vec); + fn send_message(&self, round: u64, set_id: u64, message: Vec); /// Clean up messages for a round. - fn drop_messages(&self, round: u64); -} + fn drop_messages(&self, round: u64, set_id: u64); -/// Something which can determine if a block is known. -pub trait BlockStatus { - /// Return `Ok(Some(number))` or `Ok(None)` depending on whether the block - /// is definitely known and has been imported. - /// If an unexpected error occurs, return that. - fn block_number(&self, hash: Block::Hash) -> Result, Error>; + /// Get a stream of commit messages for a specific set-id. This stream + /// should never logically conclude. + fn commit_messages(&self, set_id: u64) -> Self::In; + + /// Send message over the commit channel. + fn send_commit(&self, round: u64, set_id: u64, message: Vec); } -impl> BlockStatus for Arc> where - B: Backend, - E: CallExecutor, - NumberFor: As, -{ - fn block_number(&self, hash: Block::Hash) -> Result, Error> { - self.block_number_from_id(&BlockId::Hash(hash)) - .map_err(|e| Error::Blockchain(format!("{:?}", e))) - .map(|num| num.map(|n| n.as_())) - } -} - -/// Buffering imported messages until blocks with given hashes are imported. -pub struct UntilImported { - import_notifications: Fuse>, - status_check: Status, - inner: Fuse, - ready: VecDeque>, - check_pending: Interval, - pending: HashMap>>, -} - -impl, I: Stream> UntilImported { - fn new( - import_notifications: ImportNotifications, - status_check: Status, - stream: I, - ) -> Self { - // how often to check if pending messages that are waiting for blocks to be - // imported can be checked. - // - // the import notifications interval takes care of most of this; this is - // used in the event of missed import notifications - const CHECK_PENDING_INTERVAL: Duration = Duration::from_secs(5); - let now = Instant::now(); +/// Bridge between NetworkService, gossiping consensus messages and Grandpa +pub struct NetworkBridge, H: ExHashT> { + service: Arc> +} - let check_pending = Interval::new(now + CHECK_PENDING_INTERVAL, CHECK_PENDING_INTERVAL); - UntilImported { - import_notifications: import_notifications.fuse(), - status_check, - inner: stream.fuse(), - ready: VecDeque::new(), - check_pending, - pending: HashMap::new(), - } +impl, H: ExHashT> NetworkBridge { + /// Create a new NetworkBridge to the given NetworkService + pub fn new(service: Arc>) -> Self { + NetworkBridge { service } } } -impl, I> Stream for UntilImported - where I: Stream,Error=Error> -{ - type Item = SignedMessage; - type Error = Error; - - fn poll(&mut self) -> Poll>, Error> { - loop { - match self.inner.poll() { - Err(e) => return Err(e), - Ok(Async::Ready(None)) => return Ok(Async::Ready(None)), - Ok(Async::Ready(Some(signed_message))) => { - let (&target_hash, target_number) = signed_message.target(); - - // new message: hold it until the block is known. - if let Some(number) = self.status_check.block_number(target_hash)? { - if number != target_number { - warn!( - target: "afg", - "Authority {:?} signed GRANDPA message with \ - wrong block number for hash {}", - signed_message.id, - target_hash - ); - } else { - self.ready.push_back(signed_message) - } - } else { - self.pending.entry(target_hash) - .or_insert_with(Vec::new) - .push(signed_message); - } - } - Ok(Async::NotReady) => break, - } - } - - loop { - match self.import_notifications.poll() { - Err(_) => return Err(Error::Network(format!("Failed to get new message"))), - Ok(Async::Ready(None)) => return Ok(Async::Ready(None)), - Ok(Async::Ready(Some(notification))) => { - // new block imported. queue up all messages tied to that hash. - if let Some(messages) = self.pending.remove(¬ification.hash) { - self.ready.extend(messages); - } - } - Ok(Async::NotReady) => break, - } - } - - let mut update_interval = false; - while let Async::Ready(Some(_)) = self.check_pending.poll().map_err(Error::Timer)? { - update_interval = true; - } - - if update_interval { - let mut known_keys = Vec::new(); - for &block_hash in self.pending.keys() { - if let Some(number) = self.status_check.block_number(block_hash)? { - known_keys.push((block_hash, number)); - } - } - - for (known_hash, canon_number) in known_keys { - if let Some(mut pending_messages) = self.pending.remove(&known_hash) { - // verify canonicality of pending messages. - pending_messages.retain(|msg| { - let number_correct = msg.target().1 == canon_number; - if !number_correct { - warn!( - target: "afg", - "Authority {:?} signed GRANDPA message with \ - wrong block number for hash {}", - msg.id, - known_hash, - ); - } - number_correct - }); - self.ready.extend(pending_messages); - } - } - } - - if let Some(ready) = self.ready.pop_front() { - return Ok(Async::Ready(Some(ready))) - } - - if self.import_notifications.is_done() && self.inner.is_done() { - Ok(Async::Ready(None)) - } else { - Ok(Async::NotReady) +impl, H: ExHashT> Clone for NetworkBridge { + fn clone(&self) -> Self { + NetworkBridge { + service: Arc::clone(&self.service) } } } -// clears the network messages for inner round on drop. -struct ClearOnDrop { - round: u64, - inner: I, - network: N, +fn message_topic(round: u64, set_id: u64) -> B::Hash { + <::Hashing as HashT>::hash(format!("{}-{}", set_id, round).as_bytes()) } -impl Sink for ClearOnDrop { - type SinkItem = I::SinkItem; - type SinkError = I::SinkError; +fn commit_topic(set_id: u64) -> B::Hash { + <::Hashing as HashT>::hash(format!("{}-COMMITS", set_id).as_bytes()) +} - fn start_send(&mut self, item: Self::SinkItem) -> StartSend { - self.inner.start_send(item) +impl, H: ExHashT> Network for NetworkBridge { + type In = mpsc::UnboundedReceiver; + fn messages_for(&self, round: u64, set_id: u64) -> Self::In { + self.service.consensus_gossip().write().messages_for(message_topic::(round, set_id)) } - fn poll_complete(&mut self) -> Poll<(), Self::SinkError> { - self.inner.poll_complete() + fn send_message(&self, round: u64, set_id: u64, message: Vec) { + let topic = message_topic::(round, set_id); + self.service.gossip_consensus_message(topic, message, false); } - fn close(&mut self) -> Poll<(), Self::SinkError> { - self.inner.close() + fn drop_messages(&self, round: u64, set_id: u64) { + let topic = message_topic::(round, set_id); + self.service.consensus_gossip().write().collect_garbage(|t| t == &topic); } -} -impl Drop for ClearOnDrop { - fn drop(&mut self) { - self.network.drop_messages(self.round); + fn commit_messages(&self, set_id: u64) -> Self::In { + self.service.consensus_gossip().write().messages_for(commit_topic::(set_id)) + } + + fn send_commit(&self, _round: u64, set_id: u64, message: Vec) { + let topic = commit_topic::(set_id); + self.service.gossip_consensus_message(topic, message, true); } } -// converts a message stream into a stream of signed messages. -// the output stream checks signatures also. -fn checked_message_stream(inner: S, voters: Vec) - -> impl Stream,Error=Error> where - S: Stream,Error=()> -{ - inner - .filter_map(|raw| { - let decoded = SignedMessage::::decode(&mut &raw[..]); - if decoded.is_none() { - debug!(target: "afg", "Skipping malformed message {:?}", raw); - } - decoded - }) - .and_then(move |msg| { - // check signature. - if !voters.contains(&msg.id) { - debug!(target: "afg", "Skipping message from unknown voter {}", msg.id); - return Ok(None); - } +/// Something which can determine if a block is known. +pub trait BlockStatus { + /// Return `Ok(Some(number))` or `Ok(None)` depending on whether the block + /// is definitely known and has been imported. + /// If an unexpected error occurs, return that. + fn block_number(&self, hash: Block::Hash) -> Result>, Error>; +} - let as_public = ::ed25519::Public::from_raw(msg.id.0); - let encoded_raw = msg.message.encode(); - if ::ed25519::verify_strong(&msg.signature, &encoded_raw, as_public) { - Ok(Some(msg)) - } else { - debug!(target: "afg", "Skipping message with bad signature"); - Ok(None) - } - }) - .filter_map(|x| x) - .map_err(|()| Error::Network(format!("Failed to receive message on unbounded stream"))) +impl, RA> BlockStatus for Arc> where + B: Backend, + E: CallExecutor + Send + Sync, + RA: Send + Sync, + NumberFor: BlockNumberOps, +{ + fn block_number(&self, hash: Block::Hash) -> Result>, Error> { + self.block_number_from_id(&BlockId::Hash(hash)) + .map_err(|e| Error::Blockchain(format!("{:?}", e))) + } } -fn outgoing_messages( - local_key: Option>, - voters: Vec, - round: u64, - network: N, -) -> ( - impl Stream,Error=Error>, - impl Sink,SinkError=Error>, -) { - let locals = local_key.and_then(|pair| { - let public = pair.public(); - voters.iter().find(|id| id.0 == public.0).map(move |id| (pair, id.clone())) - }); +/// Consensus-related data changes tracker. +#[derive(Clone, Debug, Encode, Decode)] +struct ConsensusChanges { + pending_changes: Vec<(N, H)>, +} - let (tx, rx) = mpsc::unbounded(); - let rx = rx - .map(move |msg: Message| { - // when locals exist. sign messages on import - if let Some((ref pair, local_id)) = locals { - let encoded = msg.encode(); - let signature = pair.sign(&encoded[..]); - let signed = SignedMessage:: { - message: msg, - signature, - id: local_id, - }; +impl ConsensusChanges { + /// Create empty consensus changes. + pub fn empty() -> Self { + ConsensusChanges { pending_changes: Vec::new(), } + } - // forward to network. - network.send_message(round, signed.encode()); - Some(signed) - } else { - None - } - }) - .filter_map(|x| x) - .map_err(move |()| Error::Network( - format!("Failed to receive on unbounded receiver for round {}", round) - )); + /// Note unfinalized change of consensus-related data. + pub fn note_change(&mut self, at: (N, H)) { + let idx = self.pending_changes + .binary_search_by_key(&at.0, |change| change.0) + .unwrap_or_else(|i| i); + self.pending_changes.insert(idx, at); + } - let tx = tx.sink_map_err(move |e| Error::Network(format!("Failed to broadcast message \ - to network in round {}: {:?}", round, e))); + /// Finalize all pending consensus changes that are finalized by given block. + /// Returns true if there any changes were finalized. + pub fn finalize ::client::error::Result>>( + &mut self, + block: (N, H), + canonical_at_height: F, + ) -> ::client::error::Result<(bool, bool)> { + let (split_idx, has_finalized_changes) = self.pending_changes.iter() + .enumerate() + .take_while(|(_, &(at_height, _))| at_height <= block.0) + .fold((None, Ok(false)), |(_, has_finalized_changes), (idx, ref at)| + ( + Some(idx), + has_finalized_changes + .and_then(|has_finalized_changes| if has_finalized_changes { + Ok(has_finalized_changes) + } else { + canonical_at_height(at.0).map(|can_hash| Some(at.1) == can_hash) + }), + )); - (rx, tx) + let altered_changes = split_idx.is_some(); + if let Some(split_idx) = split_idx { + self.pending_changes = self.pending_changes.split_off(split_idx + 1); + } + has_finalized_changes.map(|has_finalized_changes| (altered_changes, has_finalized_changes)) + } } +/// Thread-safe consensus changes tracker reference. +type SharedConsensusChanges = Arc>>; + /// The environment we run GRANDPA in. -pub struct Environment { - inner: Arc>, - voters: HashMap, +struct Environment { + inner: Arc>, + voters: Arc>, config: Config, + authority_set: SharedAuthoritySet>, + consensus_changes: SharedConsensusChanges>, network: N, + set_id: u64, } -impl, B, E, N> grandpa::Chain for Environment where +impl, B, E, N, RA> grandpa::Chain> for Environment where Block: 'static, B: Backend + 'static, E: CallExecutor + 'static, N: Network + 'static, N::In: 'static, - NumberFor: As, + NumberFor: BlockNumberOps, { fn ancestry(&self, base: Block::Hash, block: Block::Hash) -> Result, GrandpaError> { + if base == block { return Err(GrandpaError::NotDescendent) } + let tree_route_res = ::client::blockchain::tree_route( self.inner.backend().blockchain(), BlockId::Hash(block), @@ -419,14 +414,23 @@ impl, B, E, N> grandpa::Chain for Environm Ok(tree_route.retracted().iter().skip(1).map(|e| e.hash).collect()) } - fn best_chain_containing(&self, block: Block::Hash) -> Option<(Block::Hash, u32)> { - match self.inner.best_containing(block, None) { + fn best_chain_containing(&self, block: Block::Hash) -> Option<(Block::Hash, NumberFor)> { + // we refuse to vote beyond the current limit number where transitions are scheduled to + // occur. + // once blocks are finalized that make that transition irrelevant or activate it, + // we will proceed onwards. most of the time there will be no pending transition. + let limit = self.authority_set.current_limit(); + debug!(target: "afg", "Finding best chain containing block {:?} with number limit {:?}", block, limit); + + match self.inner.best_containing(block, limit) { Ok(Some(hash)) => { let header = self.inner.header(&BlockId::Hash(hash)).ok()? .expect("Header known to exist after `best_containing` call; qed"); - Some((hash, header.number().as_())) + Some((hash, header.number().clone())) } + // Ok(None) can be returned when `block` is after `limit`. That might cause issues. + // might be better to return the header itself in this (rare) case. Ok(None) => None, Err(e) => { debug!(target: "afg", "Encountered error finding best chain containing {:?}: {:?}", block, e); @@ -436,99 +440,170 @@ impl, B, E, N> grandpa::Chain for Environm } } -impl, N> voter::Environment for Environment where +/// A new authority set along with the canonical block it changed at. +#[derive(Debug)] +struct NewAuthoritySet { + canon_number: N, + canon_hash: H, + set_id: u64, + authorities: Vec<(Ed25519AuthorityId, u64)>, +} + +/// Signals either an early exit of a voter or an error. +#[derive(Debug)] +enum ExitOrError { + /// An error occurred. + Error(Error), + /// Early exit of the voter: the new set ID and the new authorities along with respective weights. + AuthoritiesChanged(NewAuthoritySet), +} + +impl From for ExitOrError { + fn from(e: Error) -> Self { + ExitOrError::Error(e) + } +} + +impl From for ExitOrError { + fn from(e: ClientError) -> Self { + ExitOrError::Error(Error::Client(e)) + } +} + +impl From for ExitOrError { + fn from(e: grandpa::Error) -> Self { + ExitOrError::Error(Error::from(e)) + } +} + +impl ::std::error::Error for ExitOrError { } + +impl fmt::Display for ExitOrError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ExitOrError::Error(ref e) => write!(f, "{:?}", e), + ExitOrError::AuthoritiesChanged(_) => write!(f, "restarting voter on new authorities"), + } + } +} + +impl, N, RA> voter::Environment> for Environment where Block: 'static, B: Backend + 'static, - E: CallExecutor + 'static, - N: Network + 'static, - N::In: 'static, - NumberFor: As, + E: CallExecutor + 'static + Send + Sync, + N: Network + 'static + Send, + N::In: 'static + Send, + RA: 'static + Send + Sync, + NumberFor: BlockNumberOps, { - type Timer = Box>; - type Id = AuthorityId; + type Timer = Box + Send>; + type Id = Ed25519AuthorityId; type Signature = ed25519::Signature; - type In = Box, Error = Self::Error>>; - type Out = Box, SinkError = Self::Error>>; - type Error = Error; + + // regular round message streams + type In = Box, Self::Signature, Self::Id>, + Error = Self::Error, + > + Send>; + type Out = Box>, + SinkError = Self::Error, + > + Send>; + + type Error = ExitOrError>; fn round_data( &self, round: u64 - ) -> voter::RoundData { - use client::BlockchainEvents; - use tokio::timer::Delay; - + ) -> voter::RoundData { let now = Instant::now(); let prevote_timer = Delay::new(now + self.config.gossip_duration * 2); let precommit_timer = Delay::new(now + self.config.gossip_duration * 4); // TODO: dispatch this with `mpsc::spawn`. - let incoming = checked_message_stream::( - self.network.messages_for(round), - self.config.voters.clone(), + let incoming = ::communication::checked_message_stream::( + round, + self.set_id, + self.network.messages_for(round, self.set_id), + self.voters.clone(), ); - let (out_rx, outgoing) = outgoing_messages::( - self.config.local_key.clone(), - self.config.voters.clone(), + let (out_rx, outgoing) = ::communication::outgoing_messages::( round, + self.set_id, + self.config.local_key.clone(), + self.voters.clone(), self.network.clone(), ); // schedule incoming messages from the network to be held until // corresponding blocks are imported. - let incoming = UntilImported::new( + let incoming = UntilVoteTargetImported::new( self.inner.import_notification_stream(), self.inner.clone(), incoming, ); // join incoming network messages with locally originating ones. - let incoming = Box::new(incoming.select(out_rx)); + let incoming = Box::new(out_rx.select(incoming).map_err(Into::into)); // schedule network message cleanup when sink drops. - let outgoing = Box::new(ClearOnDrop { - round, - network: self.network.clone(), - inner: outgoing, - }); + let outgoing = Box::new(outgoing.sink_map_err(Into::into)); voter::RoundData { - prevote_timer: Box::new(prevote_timer.map_err(Error::Timer)), - precommit_timer: Box::new(precommit_timer.map_err(Error::Timer)), - voters: self.voters.clone(), + prevote_timer: Box::new(prevote_timer.map_err(|e| Error::Timer(e).into())), + precommit_timer: Box::new(precommit_timer.map_err(|e| Error::Timer(e).into())), incoming, outgoing, } } - fn completed(&self, round: u64, state: RoundState) -> Result<(), Self::Error> { + fn completed(&self, round: u64, state: RoundState>) -> Result<(), Self::Error> { + debug!( + target: "afg", "Voter {} completed round {} in set {}. Estimate = {:?}, Finalized in round = {:?}", + self.config.name(), + round, + self.set_id, + state.estimate.as_ref().map(|e| e.1), + state.finalized.as_ref().map(|e| e.1), + ); + let encoded_state = (round, state).encode(); - if let Err(e) = self.inner.backend() - .insert_aux(&[(LAST_COMPLETED_KEY, &encoded_state[..])], &[]) - { + let res = Backend::insert_aux(&**self.inner.backend(), &[(LAST_COMPLETED_KEY, &encoded_state[..])], &[]); + if let Err(e) = res { warn!(target: "afg", "Shutting down voter due to error bookkeeping last completed round in DB: {:?}", e); - Err(Error::CouldNotCompleteRound(e)) + Err(Error::Client(e).into()) } else { Ok(()) } } - fn finalize_block(&self, hash: Block::Hash, number: u32) -> Result<(), Self::Error> { - // TODO: don't unconditionally notify. - if let Err(e) = self.inner.finalize_block(BlockId::Hash(hash), true) { - warn!(target: "afg", "Error applying finality to block {:?}: {:?}", (hash, number), e); - } + fn finalize_block(&self, hash: Block::Hash, number: NumberFor, round: u64, commit: Commit) -> Result<(), Self::Error> { + finalize_block( + &*self.inner, + &self.authority_set, + &self.consensus_changes, + Some(As::sa(self.config.justification_period)), + hash, + number, + (round, commit).into(), + ) + } - // we return without error in all cases because not being able to finalize is - // non-fatal. - Ok(()) + fn round_commit_timer(&self) -> Self::Timer { + use rand::{thread_rng, Rng}; + + //random between 0-1 seconds. + let delay: u64 = thread_rng().gen_range(0, 1000); + Box::new(Delay::new( + Instant::now() + Duration::from_millis(delay) + ).map_err(|e| Error::Timer(e).into())) } fn prevote_equivocation( &self, _round: u64, - equivocation: ::grandpa::Equivocation, Self::Signature> + equivocation: ::grandpa::Equivocation, Self::Signature> ) { warn!(target: "afg", "Detected prevote equivocation in the finality worker: {:?}", equivocation); // nothing yet; this could craft misbehavior reports of some kind. @@ -537,232 +612,1005 @@ impl, N> voter::Environment for Envi fn precommit_equivocation( &self, _round: u64, - equivocation: Equivocation, Self::Signature> + equivocation: Equivocation, Self::Signature> ) { warn!(target: "afg", "Detected precommit equivocation in the finality worker: {:?}", equivocation); // nothing yet } } -/// Run a GRANDPA voter as a task. The returned future should be executed in a tokio runtime. -pub fn run_grandpa, N>( - config: Config, - client: Arc>, - voters: HashMap, - network: N, -) -> Result,client::error::Error> where - Block::Hash: Ord, - B: Backend + 'static, - E: CallExecutor + 'static, - N: Network + 'static, - N::In: 'static, - NumberFor: As, -{ - let chain_info = client.info()?; - let genesis_hash = chain_info.chain.genesis_hash; - let last_finalized = ( - chain_info.chain.finalized_hash, - chain_info.chain.finalized_number.as_() - ); - - let (last_round_number, last_state) = match client.backend().get_aux(LAST_COMPLETED_KEY)? { - None => (0, RoundState::genesis((genesis_hash, 0))), - Some(raw) => <(u64, RoundState)>::decode(&mut &raw[..]) - .ok_or_else(|| ::client::error::ErrorKind::Backend( - format!("Last GRANDPA round state kept in invalid format") - ))? - }; +/// A GRANDPA justification for block finality, it includes a commit message and +/// an ancestry proof including all headers routing all precommit target blocks +/// to the commit target block. Due to the current voting strategy the precommit +/// targets should be the same as the commit target, since honest voters don't +/// vote past authority set change blocks. +/// +/// 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)] +struct GrandpaJustification { + round: u64, + commit: Commit, + votes_ancestries: Vec, +} - let environment = Arc::new(Environment { - inner: client, - config, - voters, - network, - }); +impl> GrandpaJustification { + /// Create a GRANDPA justification from the given commit. This method + /// assumes the commit is valid and well-formed. + fn from_commit( + client: &Client, + round: u64, + commit: Commit, + ) -> Result, Error> where + B: Backend, + E: CallExecutor + Send + Sync, + RA: Send + Sync, + { + let mut votes_ancestries_hashes = HashSet::new(); + let mut votes_ancestries = Vec::new(); + + let error = || { + let msg = "invalid precommits for target commit".to_string(); + Err(Error::Client(ClientErrorKind::BadJustification(msg).into())) + }; - let voter = voter::Voter::new( - environment, - last_round_number, - last_state, - last_finalized, - ); + for signed in commit.precommits.iter() { + let mut current_hash = signed.precommit.target_hash.clone(); + loop { + if current_hash == commit.target_hash { break; } - Ok(voter.map_err(|e| warn!("GRANDPA Voter failed: {:?}", e))) -} + match client.backend().blockchain().header(BlockId::Hash(current_hash))? { + Some(current_header) => { + if *current_header.number() <= commit.target_number { + return error(); + } -#[cfg(test)] -mod tests { - use super::*; - use network::test::*; - use parking_lot::Mutex; - use tokio::runtime::current_thread; - use keyring::Keyring; - use client::BlockchainEvents; - - #[derive(Clone)] - struct TestGrandpaNetwork { - inner: Arc>, - peer_id: usize, - } - - impl TestGrandpaNetwork { - fn new(inner: Arc>, peer_id: usize,) -> Self { - TestGrandpaNetwork { - inner, - peer_id, + let parent_hash = current_header.parent_hash().clone(); + if votes_ancestries_hashes.insert(current_hash) { + votes_ancestries.push(current_header); + } + current_hash = parent_hash; + }, + _ => return error(), + } } } + + Ok(GrandpaJustification { round, commit, votes_ancestries }) } - fn round_to_topic(round: u64) -> Hash { - let mut hash = Hash::default(); - round.using_encoded(|s| { - let raw = hash.as_mut(); - raw[..8].copy_from_slice(s); - }); - hash + /// Decode a GRANDPA justification and validate the commit and the votes' + /// ancestry proofs. + fn decode_and_verify( + encoded: Vec, + set_id: u64, + voters: &HashMap, + ) -> Result, ClientError> where + NumberFor: grandpa::BlockNumberOps, + { + GrandpaJustification::::decode(&mut &*encoded).ok_or_else(|| { + let msg = "failed to decode grandpa justification".to_string(); + ClientErrorKind::BadJustification(msg).into() + }).and_then(|just| just.verify(set_id, voters).map(|_| just)) } - impl Network for TestGrandpaNetwork { - type In = Box,Error=()>>; + /// Validate the commit and the votes' ancestry proofs. + fn verify(&self, set_id: u64, voters: &HashMap) -> Result<(), ClientError> + where + NumberFor: grandpa::BlockNumberOps, + { + use grandpa::Chain; + + let ancestry_chain = AncestryChain::::new(&self.votes_ancestries); + + match grandpa::validate_commit( + &self.commit, + voters, + None, + &ancestry_chain, + ) { + Ok(Some(_)) => {}, + _ => { + let msg = "invalid commit in grandpa justification".to_string(); + return Err(ClientErrorKind::BadJustification(msg).into()); + } + } + + let mut visited_hashes = HashSet::new(); + for signed in self.commit.precommits.iter() { + if let Err(_) = communication::check_message_sig::( + &grandpa::Message::Precommit(signed.precommit.clone()), + &signed.id, + &signed.signature, + self.round, + set_id, + ) { + return Err(ClientErrorKind::BadJustification( + "invalid signature for precommit in grandpa justification".to_string()).into()); + } - fn messages_for(&self, round: u64) -> Self::In { - let messages = self.inner.lock().peer(self.peer_id) - .with_spec(|spec, _| spec.gossip.messages_for(round_to_topic(round))); + if self.commit.target_hash == signed.precommit.target_hash { + continue; + } - let messages = messages.map_err( - move |_| panic!("Messages for round {} dropped too early", round) - ); + match ancestry_chain.ancestry(self.commit.target_hash, signed.precommit.target_hash) { + Ok(route) => { + // ancestry starts from parent hash but the precommit target hash has been visited + visited_hashes.insert(signed.precommit.target_hash); + for hash in route { + visited_hashes.insert(hash); + } + }, + _ => { + return Err(ClientErrorKind::BadJustification( + "invalid precommit ancestry proof in grandpa justification".to_string()).into()); + }, + } + } - Box::new(messages) + let ancestry_hashes = self.votes_ancestries + .iter() + .map(|h: &Block::Header| h.hash()) + .collect(); + + if visited_hashes != ancestry_hashes { + return Err(ClientErrorKind::BadJustification( + "invalid precommit ancestries in grandpa justification with unused headers".to_string()).into()); } - fn send_message(&self, round: u64, message: Vec) { - let mut inner = self.inner.lock(); - inner.peer(self.peer_id).gossip_message(round_to_topic(round), message); - inner.route(); + Ok(()) + } +} + +enum JustificationOrCommit { + Justification(GrandpaJustification), + Commit((u64, Commit)), +} + +impl From<(u64, Commit)> for JustificationOrCommit { + fn from(commit: (u64, Commit)) -> JustificationOrCommit { + JustificationOrCommit::Commit(commit) + } +} + +impl From> for JustificationOrCommit { + fn from(justification: GrandpaJustification) -> JustificationOrCommit { + JustificationOrCommit::Justification(justification) + } +} + +/// Finalize the given block and apply any authority set changes. If an +/// authority set change is enacted then a justification is created (if not +/// given) and stored with the block when finalizing it. +fn finalize_block, E, RA>( + client: &Client, + authority_set: &SharedAuthoritySet>, + consensus_changes: &SharedConsensusChanges>, + justification_period: Option>, + hash: Block::Hash, + number: NumberFor, + justification_or_commit: JustificationOrCommit, +) -> Result<(), ExitOrError>> where + B: Backend, + E: CallExecutor + Send + Sync, + RA: Send + Sync, +{ + // lock must be held through writing to DB to avoid race + let mut authority_set = authority_set.inner().write(); + + // TODO [andre]: clone only when changed (#1483) + let old_authority_set = authority_set.clone(); + // needed in case there is an authority set change, used for reverting in + // case of error + let mut old_last_completed = None; + + let mut consensus_changes = consensus_changes.lock(); + let status = authority_set.apply_changes(number, |canon_number| { + canonical_at_height(client, (hash, number), canon_number) + })?; + + if status.changed { + // write new authority set state to disk. + let encoded_set = authority_set.encode(); + + let write_result = if let Some((ref canon_hash, ref canon_number)) = status.new_set_block { + // we also overwrite the "last completed round" entry with a blank slate + // because from the perspective of the finality gadget, the chain has + // reset. + let round_state = RoundState::genesis((*canon_hash, *canon_number)); + let last_completed: LastCompleted<_, _> = (0, round_state); + let encoded = last_completed.encode(); + + old_last_completed = Backend::get_aux(&**client.backend(), LAST_COMPLETED_KEY)?; + + Backend::insert_aux( + &**client.backend(), + &[ + (AUTHORITY_SET_KEY, &encoded_set[..]), + (LAST_COMPLETED_KEY, &encoded[..]), + ], + &[] + ) + } else { + Backend::insert_aux(&**client.backend(), &[(AUTHORITY_SET_KEY, &encoded_set[..])], &[]) + }; + + if let Err(e) = write_result { + warn!(target: "finality", "Failed to write updated authority set to disk. Bailing."); + warn!(target: "finality", "Node is in a potentially inconsistent state."); + + return Err(e.into()); } + } + + // check if this is this is the first finalization of some consensus changes + let (alters_consensus_changes, finalizes_consensus_changes) = consensus_changes + .finalize((number, hash), |at_height| canonical_at_height(client, (hash, number), at_height))?; - fn drop_messages(&self, round: u64) { - let topic = round_to_topic(round); - self.inner.lock().peer(self.peer_id) - .with_spec(|spec, _| spec.gossip.collect_garbage(|t| t == &topic)); + // holds the old consensus changes in case it is changed below, needed for + // reverting in case of failure + let mut old_consensus_changes = None; + if alters_consensus_changes { + old_consensus_changes = Some(consensus_changes.clone()); + + let encoded = consensus_changes.encode(); + let write_result = Backend::insert_aux(&**client.backend(), &[(CONSENSUS_CHANGES_KEY, &encoded[..])], &[]); + if let Err(e) = write_result { + warn!(target: "finality", "Failed to write updated consensus changes to disk. Bailing."); + warn!(target: "finality", "Node is in a potentially inconsistent state."); + + return Err(e.into()); } } - const TEST_GOSSIP_DURATION: Duration = Duration::from_millis(500); - const TEST_ROUTING_INTERVAL: Duration = Duration::from_millis(50); + let aux = |authority_set: &authorities::AuthoritySet>| { + // NOTE: this code assumes that honest voters will never vote past a + // transition block, thus we don't have to worry about the case where + // we have a transition with `effective_block = N`, but we finalize + // `N+1`. this assumption is required to make sure we store + // justifications for transition blocks which will be requested by + // syncing clients. + let justification = match justification_or_commit { + JustificationOrCommit::Justification(justification) => Some(justification.encode()), + JustificationOrCommit::Commit((round_number, commit)) => { + let mut justification_required = + // justification is always required when block that enacts new authorities + // set is finalized + status.new_set_block.is_some() || + // justification is required when consensus changes are finalized + finalizes_consensus_changes; + + // justification is required every N blocks to be able to prove blocks + // finalization to remote nodes + if !justification_required { + if let Some(justification_period) = justification_period { + let last_finalized_number = client.info()?.chain.finalized_number; + justification_required = + (!last_finalized_number.is_zero() || number - last_finalized_number == justification_period) && + (last_finalized_number / justification_period != number / justification_period); + } + } + + if justification_required { + let justification = GrandpaJustification::from_commit( + client, + round_number, + commit, + )?; + + Some(justification.encode()) + } else { + None + } + }, + }; - #[test] - fn finalize_20_unanimous_3_peers() { - let mut net = TestNet::new(3); - net.peer(0).push_blocks(20, false); - net.sync(); + debug!(target: "afg", "Finalizing blocks up to ({:?}, {})", number, hash); - let net = Arc::new(Mutex::new(net)); - let peers = &[ - (0, Keyring::Alice), - (1, Keyring::Bob), - (2, Keyring::Charlie), - ]; + // ideally some handle to a synchronization oracle would be used + // to avoid unconditionally notifying. + client.finalize_block(BlockId::Hash(hash), justification, true).map_err(|e| { + warn!(target: "finality", "Error applying finality to block {:?}: {:?}", (hash, number), e); + e + })?; - let voters: Vec<_> = peers.iter() - .map(|&(_, ref key)| AuthorityId(key.to_raw_public())) - .collect(); + if let Some((canon_hash, canon_number)) = status.new_set_block { + // the authority set has changed. + let (new_id, set_ref) = authority_set.current(); - let mut finality_notifications = Vec::new(); + if set_ref.len() > 16 { + info!("Applying GRANDPA set change to new set with {} authorities", set_ref.len()); + } else { + info!("Applying GRANDPA set change to new set {:?}", set_ref); + } - let mut runtime = current_thread::Runtime::new().unwrap(); - for (peer_id, key) in peers { - let client = net.lock().peer(*peer_id).client().clone(); - finality_notifications.push( - client.finality_notification_stream() - .take_while(|n| Ok(n.header.number() < &20)) - .for_each(move |_| Ok(())) + Err(ExitOrError::AuthoritiesChanged(NewAuthoritySet { + canon_hash, + canon_number, + set_id: new_id, + authorities: set_ref.to_vec(), + })) + } else { + Ok(()) + } + }; + + match aux(&authority_set) { + Err(ExitOrError::Error(err)) => { + debug!(target: "afg", "Reverting authority set and/or consensus changes after block finalization error: {:?}", err); + + let mut revert_aux = Vec::new(); + + if status.changed { + revert_aux.push((AUTHORITY_SET_KEY, old_authority_set.encode())); + if let Some(old_last_completed) = old_last_completed { + revert_aux.push((LAST_COMPLETED_KEY, old_last_completed)); + } + + *authority_set = old_authority_set.clone(); + } + + if let Some(old_consensus_changes) = old_consensus_changes { + revert_aux.push((CONSENSUS_CHANGES_KEY, old_consensus_changes.encode())); + + *consensus_changes = old_consensus_changes; + } + + let write_result = Backend::insert_aux( + &**client.backend(), + revert_aux.iter().map(|(k, v)| (*k, &**v)).collect::>().iter(), + &[], ); - let voter = run_grandpa( - Config { - gossip_duration: TEST_GOSSIP_DURATION, - voters: voters.clone(), - local_key: Some(Arc::new(key.clone().into())), + + if let Err(e) = write_result { + warn!(target: "finality", "Failed to revert consensus changes to disk. Bailing."); + warn!(target: "finality", "Node is in a potentially inconsistent state."); + + return Err(e.into()); + } + + Err(ExitOrError::Error(err)) + }, + res => res, + } +} + +/// A block-import handler for GRANDPA. +/// +/// This scans each imported block for signals of changing authority set. +/// If the block being imported enacts an authority set change then: +/// - If the current authority set is still live: we import the block +/// - Otherwise, the block must include a valid justification. +/// +/// When using GRANDPA, the block import worker should be using this block import +/// object. +pub struct GrandpaBlockImport, RA, PRA> { + inner: Arc>, + authority_set: SharedAuthoritySet>, + authority_set_change: mpsc::UnboundedSender>>, + consensus_changes: SharedConsensusChanges>, + api: Arc, +} + +impl, RA, PRA> BlockImport + for GrandpaBlockImport where + NumberFor: grandpa::BlockNumberOps, + B: Backend + 'static, + E: CallExecutor + 'static + Clone + Send + Sync, + DigestFor: Encode, + DigestItemFor: DigestItem, + RA: Send + Sync, + PRA: ProvideRuntimeApi, + PRA::Api: GrandpaApi, +{ + type Error = ConsensusError; + + fn on_start(&self, link: &::consensus_common::import_queue::Link) { + let chain_info = match self.inner.info() { + Ok(info) => info.chain, + _ => return, + }; + + // request justifications for all pending changes for which change blocks have already been imported + for pending_change in self.authority_set.inner().read().pending_changes() { + if pending_change.effective_number() > chain_info.finalized_number && + pending_change.effective_number() <= chain_info.best_number + { + let effective_block_hash = self.inner.best_containing( + pending_change.canon_hash, + Some(pending_change.effective_number()), + ); + + if let Ok(Some(hash)) = effective_block_hash { + if let Ok(Some(header)) = self.inner.header(&BlockId::Hash(hash)) { + if *header.number() == pending_change.effective_number() { + link.request_justification(&header.hash(), *header.number()); + } + } + } + } + } + } + + fn import_block(&self, mut block: ImportBlock, new_authorities: Option>) + -> Result + { + use authorities::PendingChange; + + let hash = block.post_header().hash(); + let number = block.header.number().clone(); + + let maybe_change = self.api.runtime_api().grandpa_pending_change( + &BlockId::hash(*block.header.parent_hash()), + &block.header.digest().clone(), + ); + + let maybe_change = match maybe_change { + Err(e) => return Err(ConsensusErrorKind::ClientImport(e.to_string()).into()), + Ok(maybe) => maybe, + }; + + // when we update the authorities, we need to hold the lock + // until the block is written to prevent a race if we need to restore + // the old authority set on error. + let just_in_case = if let Some(change) = maybe_change { + let parent_hash = *block.header.parent_hash(); + + let mut authorities = self.authority_set.inner().write(); + let old_set = authorities.clone(); + + let is_equal_or_descendent_of = |base: &Block::Hash| -> Result<(), ConsensusError> { + let error = || { + Err(ConsensusErrorKind::ClientImport("Incorrect base hash".to_string()).into()) + }; + + if *base == hash { return error(); } + if *base == parent_hash { return error(); } + + let tree_route = ::client::blockchain::tree_route( + self.inner.backend().blockchain(), + BlockId::Hash(parent_hash), + BlockId::Hash(*base), + ); + + let tree_route = match tree_route { + Err(e) => return Err(ConsensusErrorKind::ClientImport(e.to_string()).into()), + Ok(route) => route, + }; + + if tree_route.common_block().hash == *base { + return error(); + } + + Ok(()) + }; + + authorities.add_pending_change( + PendingChange { + next_authorities: change.next_authorities, + finalization_depth: change.delay, + canon_height: number, + canon_hash: hash, }, - client, - voters.iter().map(|&id| (id, 1)).collect(), - TestGrandpaNetwork::new(net.clone(), *peer_id), - ).expect("all in order with client and network"); + is_equal_or_descendent_of, + )?; - runtime.spawn(voter); + block.auxiliary.push((AUTHORITY_SET_KEY.to_vec(), Some(authorities.encode()))); + Some((old_set, authorities)) + } else { + None + }; + + // we don't want to finalize on `inner.import_block` + let justification = block.justification.take(); + let enacts_consensus_change = new_authorities.is_some(); + let import_result = self.inner.import_block(block, new_authorities); + + let import_result = { + // we scope this so that `just_in_case` is dropped eagerly and releases the authorities lock + let revert_authorities = || if let Some((old_set, mut authorities)) = just_in_case { + *authorities = old_set; + }; + + match import_result { + Ok(ImportResult::Queued) => ImportResult::Queued, + Ok(r) => { + debug!(target: "afg", "Restoring old authority set after block import result: {:?}", r); + revert_authorities(); + return Ok(r); + }, + Err(e) => { + debug!(target: "afg", "Restoring old authority set after block import error: {:?}", e); + revert_authorities(); + return Err(ConsensusErrorKind::ClientImport(e.to_string()).into()); + }, + } + }; + + let enacts_change = self.authority_set.inner().read().enacts_change(number, |canon_number| { + canonical_at_height(&self.inner, (hash, number), canon_number) + }).map_err(|e| ConsensusError::from(ConsensusErrorKind::ClientImport(e.to_string())))?; + + if !enacts_change && !enacts_consensus_change { + return Ok(import_result); } - // wait for all finalized on each. - let wait_for = ::futures::future::join_all(finality_notifications) - .map(|_| ()) - .map_err(|_| ()); + match justification { + Some(justification) => { + self.import_justification(hash, number, justification, enacts_change)?; + }, + None => { + if enacts_change { + trace!( + target: "finality", + "Imported unjustified block #{} that enacts authority set change, waiting for finality for enactment.", + number, + ); + } - let drive_to_completion = ::tokio::timer::Interval::new_interval(TEST_ROUTING_INTERVAL) - .for_each(move |_| { net.lock().route_until_complete(); Ok(()) }) - .map(|_| ()) - .map_err(|_| ()); + // we have imported block with consensus data changes, but without justification + // => remember to create justification when next block will be finalized + if enacts_consensus_change { + self.consensus_changes.lock().note_change((number, hash)); + } - runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap(); + return Ok(ImportResult::NeedsJustification); + } + } + + Ok(import_result) } - #[test] - fn observer_can_finalize() { - let mut net = TestNet::new(4); - net.peer(0).push_blocks(20, false); - net.sync(); + fn import_justification( + &self, + hash: Block::Hash, + number: NumberFor, + justification: Justification, + ) -> Result<(), Self::Error> { + self.import_justification(hash, number, justification, false) + } +} - let net = Arc::new(Mutex::new(net)); - let peers = &[ - (0, Keyring::Alice), - (1, Keyring::Bob), - (2, Keyring::Charlie), - ]; +impl, RA, PRA> + GrandpaBlockImport where + NumberFor: grandpa::BlockNumberOps, + B: Backend + 'static, + E: CallExecutor + 'static + Clone + Send + Sync, + RA: Send + Sync, +{ - let voters: HashMap<_, _> = peers.iter() - .map(|&(_, ref key)| (AuthorityId(key.to_raw_public()), 1)) - .collect(); + /// Import a block justification and finalize the block. + /// + /// If `enacts_change` is set to true, then finalizing this block *must* + /// enact an authority set change, the function will panic otherwise. + fn import_justification( + &self, + hash: Block::Hash, + number: NumberFor, + justification: Justification, + enacts_change: bool, + ) -> Result<(), ConsensusError> { + let justification = GrandpaJustification::decode_and_verify( + justification, + self.authority_set.set_id(), + &self.authority_set.current_authorities(), + ); + + let justification = match justification { + Err(e) => return Err(ConsensusErrorKind::ClientImport(e.to_string()).into()), + Ok(justification) => justification, + }; + + let result = finalize_block( + &*self.inner, + &self.authority_set, + &self.consensus_changes, + None, + hash, + number, + justification.into(), + ); - let mut finality_notifications = Vec::new(); + match result { + Err(ExitOrError::AuthoritiesChanged(new)) => { + info!(target: "finality", "Imported justification for block #{} that enacts authority set change, signalling voter.", number); + if let Err(e) = self.authority_set_change.unbounded_send(new) { + return Err(ConsensusErrorKind::ClientImport(e.to_string()).into()); + } + }, + Err(ExitOrError::Error(e)) => { + return Err(match e { + Error::Grandpa(error) => ConsensusErrorKind::ClientImport(error.to_string()), + Error::Network(error) => ConsensusErrorKind::ClientImport(error), + Error::Blockchain(error) => ConsensusErrorKind::ClientImport(error), + Error::Client(error) => ConsensusErrorKind::ClientImport(error.to_string()), + Error::Timer(error) => ConsensusErrorKind::ClientImport(error.to_string()), + }.into()); + }, + Ok(_) => { + assert!(!enacts_change, "returns Ok when no authority set change should be enacted; qed;"); + }, + } + + Ok(()) + } +} - let mut runtime = current_thread::Runtime::new().unwrap(); - let all_peers = peers.iter() +/// Using the given base get the block at the given height on this chain. The +/// target block must be an ancestor of base, therefore `height <= base.height`. +fn canonical_at_height, RA>( + client: &Client, + base: (Block::Hash, NumberFor), + height: NumberFor, +) -> Result, ClientError> where + B: Backend, + E: CallExecutor + Send + Sync, +{ + use runtime_primitives::traits::{One, Zero}; + + if height > base.1 { + return Ok(None); + } + + if height == base.1 { + return Ok(Some(base.0)); + } + + let mut current = match client.header(&BlockId::Hash(base.0))? { + Some(header) => header, + _ => return Ok(None), + }; + + let mut steps = base.1 - height; + + while steps > NumberFor::::zero() { + current = match client.header(&BlockId::Hash(*current.parent_hash()))? { + Some(header) => header, + _ => return Ok(None), + }; + + steps -= NumberFor::::one(); + } + + Ok(Some(current.hash())) +} + +impl, RA, PRA> Authorities for GrandpaBlockImport +where + B: Backend + 'static, + E: CallExecutor + 'static + Clone + Send + Sync, + DigestItemFor: DigestItem, +{ + + type Error = as Authorities>::Error; + fn authorities(&self, at: &BlockId) -> Result, Self::Error> { + self.inner.authorities_at(at) + } +} + +impl, RA, PRA> ProvideRuntimeApi for GrandpaBlockImport +where + B: Backend + 'static, + E: CallExecutor + 'static + Clone + Send + Sync, + PRA: ProvideRuntimeApi, +{ + type Api = PRA::Api; + + fn runtime_api<'a>(&'a self) -> ::runtime_primitives::traits::ApiRef<'a, Self::Api> { + self.api.runtime_api() + } +} + +/// Half of a link between a block-import worker and a the background voter. +// This should remain non-clone. +pub struct LinkHalf, RA> { + client: Arc>, + authority_set: SharedAuthoritySet>, + authority_set_change: mpsc::UnboundedReceiver>>, + consensus_changes: SharedConsensusChanges>, +} + +struct AncestryChain { + ancestry: HashMap, +} + +impl AncestryChain { + fn new(ancestry: &[Block::Header]) -> AncestryChain { + let ancestry: HashMap<_, _> = ancestry + .iter() .cloned() - .map(|(id, key)| (id, Some(Arc::new(key.into())))) - .chain(::std::iter::once((3, None))); - - for (peer_id, local_key) in all_peers { - let client = net.lock().peer(peer_id).client().clone(); - finality_notifications.push( - client.finality_notification_stream() - .take_while(|n| Ok(n.header.number() < &20)) - .for_each(move |_| Ok(())) - ); - let voter = run_grandpa( - Config { - gossip_duration: TEST_GOSSIP_DURATION, - voters: voters.keys().cloned().collect(), - local_key, + .map(|h: Block::Header| (h.hash(), h)) + .collect(); + + AncestryChain { ancestry } + } +} + +impl grandpa::Chain> for AncestryChain where + NumberFor: grandpa::BlockNumberOps +{ + fn ancestry(&self, base: Block::Hash, block: Block::Hash) -> Result, GrandpaError> { + let mut route = Vec::new(); + let mut current_hash = block; + loop { + if current_hash == base { break; } + match self.ancestry.get(¤t_hash) { + Some(current_header) => { + current_hash = *current_header.parent_hash(); + route.push(current_hash); }, - client, - voters.clone(), - TestGrandpaNetwork::new(net.clone(), peer_id), - ).expect("all in order with client and network"); + _ => return Err(GrandpaError::NotDescendent), + } + } + route.pop(); // remove the base + + Ok(route) + } - runtime.spawn(voter); + fn best_chain_containing(&self, _block: Block::Hash) -> Option<(Block::Hash, NumberFor)> { + None + } +} + +/// Make block importer and link half necessary to tie the background voter +/// to it. +pub fn block_import, RA, PRA>( + client: Arc>, + api: Arc +) -> Result<(GrandpaBlockImport, LinkHalf), ClientError> + where + B: Backend + 'static, + E: CallExecutor + 'static + Clone + Send + Sync, + RA: Send + Sync, + PRA: ProvideRuntimeApi, + PRA::Api: GrandpaApi +{ + use runtime_primitives::traits::Zero; + let authority_set = match Backend::get_aux(&**client.backend(), AUTHORITY_SET_KEY)? { + None => { + info!(target: "afg", "Loading GRANDPA authorities \ + from genesis on what appears to be first startup."); + + // no authority set on disk: fetch authorities from genesis state. + // if genesis state is not available, we may be a light client, but these + // are unsupported for following GRANDPA directly. + let genesis_authorities = api.runtime_api() + .grandpa_authorities(&BlockId::number(Zero::zero()))?; + + let authority_set = SharedAuthoritySet::genesis(genesis_authorities); + let encoded = authority_set.inner().read().encode(); + Backend::insert_aux(&**client.backend(), &[(AUTHORITY_SET_KEY, &encoded[..])], &[])?; + + authority_set } + Some(raw) => ::authorities::AuthoritySet::decode(&mut &raw[..]) + .ok_or_else(|| ::client::error::ErrorKind::Backend( + format!("GRANDPA authority set kept in invalid format") + ))? + .into(), + }; - // wait for all finalized on each. - let wait_for = ::futures::future::join_all(finality_notifications) - .map(|_| ()) - .map_err(|_| ()); + let consensus_changes = Backend::get_aux(&**client.backend(), CONSENSUS_CHANGES_KEY)?; + let consensus_changes = Arc::new(parking_lot::Mutex::new(match consensus_changes { + Some(raw) => ConsensusChanges::decode(&mut &raw[..]) + .ok_or_else(|| ::client::error::ErrorKind::Backend( + format!("GRANDPA consensus changes kept in invalid format") + ))?, + None => ConsensusChanges::empty(), + })); + + let (authority_set_change_tx, authority_set_change_rx) = mpsc::unbounded(); + + Ok(( + GrandpaBlockImport { + inner: client.clone(), + authority_set: authority_set.clone(), + authority_set_change: authority_set_change_tx, + consensus_changes: consensus_changes.clone(), + api + }, + LinkHalf { + client, + authority_set, + authority_set_change: authority_set_change_rx, + consensus_changes, + }, + )) +} - let drive_to_completion = ::tokio::timer::Interval::new_interval(TEST_ROUTING_INTERVAL) - .for_each(move |_| { net.lock().route_until_complete(); Ok(()) }) - .map(|_| ()) - .map_err(|_| ()); +fn committer_communication, B, E, N, RA>( + set_id: u64, + voters: &Arc>, + client: &Arc>, + network: &N, +) -> ( + impl Stream< + Item = (u64, ::grandpa::CompactCommit, ed25519::Signature, Ed25519AuthorityId>), + Error = ExitOrError>, + >, + impl Sink< + SinkItem = (u64, ::grandpa::Commit, ed25519::Signature, Ed25519AuthorityId>), + SinkError = ExitOrError>, + >, +) where + B: Backend, + E: CallExecutor + Send + Sync, + N: Network, + RA: Send + Sync, + NumberFor: BlockNumberOps, + DigestItemFor: DigestItem, +{ + // verification stream + let commit_in = ::communication::checked_commit_stream::( + set_id, + network.commit_messages(set_id), + voters.clone(), + ); - runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap(); - } + // block commit messages until relevant blocks are imported. + let commit_in = UntilCommitBlocksImported::new( + client.import_notification_stream(), + client.clone(), + commit_in, + ); + + let commit_out = ::communication::CommitsOut::::new( + network.clone(), + set_id, + ); + + let commit_in = commit_in.map_err(Into::into); + let commit_out = commit_out.sink_map_err(Into::into); + + (commit_in, commit_out) +} + +/// Run a GRANDPA voter as a task. Provide configuration and a link to a +/// block import worker that has already been instantiated with `block_import`. +pub fn run_grandpa, N, RA>( + config: Config, + link: LinkHalf, + network: N, + on_exit: impl Future + Send + 'static, +) -> ::client::error::Result + Send + 'static> where + Block::Hash: Ord, + B: Backend + 'static, + E: CallExecutor + Send + Sync + 'static, + N: Network + Send + Sync + 'static, + N::In: Send + 'static, + NumberFor: BlockNumberOps, + DigestFor: Encode, + DigestItemFor: DigestItem, + RA: Send + Sync + 'static, +{ + use futures::future::{self, Loop as FutureLoop}; + use runtime_primitives::traits::Zero; + + let LinkHalf { + client, + authority_set, + authority_set_change, + consensus_changes, + } = link; + + let chain_info = client.info()?; + let genesis_hash = chain_info.chain.genesis_hash; + + // we shadow network with the wrapping/rebroadcasting network to avoid + // accidental reuse. + let (broadcast_worker, network) = communication::rebroadcasting_network(network); + + let (last_round_number, last_state) = match Backend::get_aux(&**client.backend(), LAST_COMPLETED_KEY)? { + None => (0, RoundState::genesis((genesis_hash, >::zero()))), + Some(raw) => LastCompleted::decode(&mut &raw[..]) + .ok_or_else(|| ::client::error::ErrorKind::Backend( + format!("Last GRANDPA round state kept in invalid format") + ))? + }; + + let voters = authority_set.current_authorities(); + + let initial_environment = Arc::new(Environment { + inner: client.clone(), + config: config.clone(), + voters: Arc::new(voters), + network: network.clone(), + set_id: authority_set.set_id(), + authority_set: authority_set.clone(), + consensus_changes: consensus_changes.clone(), + }); + + let initial_state = (initial_environment, last_round_number, last_state, authority_set_change.into_future()); + let voter_work = future::loop_fn(initial_state, move |params| { + let (env, last_round_number, last_state, authority_set_change) = params; + debug!(target: "afg", "{}: Starting new voter with set ID {}", config.name(), env.set_id); + + let chain_info = match client.info() { + Ok(i) => i, + Err(e) => return future::Either::B(future::err(Error::Client(e))), + }; + + let last_finalized = ( + chain_info.chain.finalized_hash, + chain_info.chain.finalized_number, + ); + + let committer_data = committer_communication( + env.set_id, + &env.voters, + &client, + &network, + ); + + let voters = (*env.voters).clone(); + + let voter = voter::Voter::new( + env, + voters, + committer_data, + last_round_number, + last_state, + last_finalized, + ); + let client = client.clone(); + let config = config.clone(); + let network = network.clone(); + let authority_set = authority_set.clone(); + let consensus_changes = consensus_changes.clone(); + + let trigger_authority_set_change = |new: NewAuthoritySet<_, _>, authority_set_change| { + let env = Arc::new(Environment { + inner: client, + config, + voters: Arc::new(new.authorities.into_iter().collect()), + set_id: new.set_id, + network, + authority_set, + consensus_changes, + }); + + // start the new authority set using the block where the + // set changed (not where the signal happened!) as the base. + Ok(FutureLoop::Continue(( + env, + 0, // always start at round 0 when changing sets. + RoundState::genesis((new.canon_hash, new.canon_number)), + authority_set_change, + ))) + }; + + future::Either::A(voter.select2(authority_set_change).then(move |res| match res { + Ok(future::Either::A(((), _))) => { + // voters don't conclude naturally; this could reasonably be an error. + Ok(FutureLoop::Break(())) + }, + Err(future::Either::B(_)) => { + // the `authority_set_change` stream should not fail. + Ok(FutureLoop::Break(())) + }, + Ok(future::Either::B(((None, _), _))) => { + // the `authority_set_change` stream should never conclude since it's never closed. + Ok(FutureLoop::Break(())) + }, + Err(future::Either::A((ExitOrError::Error(e), _))) => { + // return inner voter error + Err(e) + } + Ok(future::Either::B(((Some(new), authority_set_change), _))) => { + // authority set change triggered externally through the channel + trigger_authority_set_change(new, authority_set_change.into_future()) + } + Err(future::Either::A((ExitOrError::AuthoritiesChanged(new), authority_set_change))) => { + // authority set change triggered internally by finalizing a change block + trigger_authority_set_change(new, authority_set_change) + }, + })) + }); + + let voter_work = voter_work + .join(broadcast_worker) + .map(|((), ())| ()) + .map_err(|e| warn!("GRANDPA Voter failed: {:?}", e)); + + Ok(voter_work.select(on_exit).then(|_| Ok(()))) } diff --git a/core/finality-grandpa/src/service_integration.rs b/core/finality-grandpa/src/service_integration.rs new file mode 100644 index 0000000000000000000000000000000000000000..c4f5398312663c1f114bbc5e14814d388b212291 --- /dev/null +++ b/core/finality-grandpa/src/service_integration.rs @@ -0,0 +1,40 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +/// Integrate grandpa finality with substrate service + +use client; +use service::{FullBackend, FullExecutor, ServiceFactory}; + +pub type BlockImportForService = ::GrandpaBlockImport< + FullBackend, + FullExecutor, + ::Block, + ::RuntimeApi, + client::Client< + FullBackend, + FullExecutor, + ::Block, + ::RuntimeApi + >, +>; + +pub type LinkHalfForService = ::LinkHalf< + FullBackend, + FullExecutor, + ::Block, + ::RuntimeApi +>; \ No newline at end of file diff --git a/core/finality-grandpa/src/tests.rs b/core/finality-grandpa/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..b3f1d1e11c8651bad0cab98fc129f8534c6d6772 --- /dev/null +++ b/core/finality-grandpa/src/tests.rs @@ -0,0 +1,731 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Tests and test helpers for GRANDPA. + +use super::*; +use network::test::{Block, Hash, TestNetFactory, Peer, PeersClient}; +use network::test::{PassThroughVerifier}; +use network::config::{ProtocolConfig, Roles}; +use parking_lot::Mutex; +use tokio::runtime::current_thread; +use keyring::Keyring; +use client::{ + BlockchainEvents, error::Result, + blockchain::Backend as BlockchainBackend, + runtime_api::{Core, RuntimeVersion, ApiExt}, +}; +use test_client::{self, runtime::BlockNumber}; +use codec::Decode; +use consensus_common::{BlockOrigin, Error as ConsensusError}; +use std::{collections::HashSet, result}; +use runtime_primitives::traits::{ApiRef, ProvideRuntimeApi, RuntimeApiInfo}; +use runtime_primitives::generic::BlockId; + +use authorities::AuthoritySet; + +type PeerData = + Mutex< + Option< + LinkHalf< + test_client::Backend, + test_client::Executor, + Block, + test_client::runtime::RuntimeApi, + > + > + >; +type GrandpaPeer = Peer; + +struct GrandpaTestNet { + peers: Vec>, + test_config: TestApi, + started: bool +} + +impl GrandpaTestNet { + fn new(test_config: TestApi, n_peers: usize) -> Self { + let mut net = GrandpaTestNet { + peers: Vec::with_capacity(n_peers), + started: false, + test_config, + }; + let config = Self::default_config(); + + for _ in 0..n_peers { + net.add_peer(&config); + } + + net + } +} + +impl TestNetFactory for GrandpaTestNet { + type Verifier = PassThroughVerifier; + type PeerData = PeerData; + + /// Create new test network with peers and given config. + fn from_config(_config: &ProtocolConfig) -> Self { + GrandpaTestNet { + peers: Vec::new(), + test_config: Default::default(), + started: false + } + } + + fn default_config() -> ProtocolConfig { + // the authority role ensures gossip hits all nodes here. + ProtocolConfig { + roles: Roles::AUTHORITY, + } + } + + fn make_verifier(&self, _client: Arc, _cfg: &ProtocolConfig) + -> Arc + { + Arc::new(PassThroughVerifier(false)) // use non-instant finality. + } + + fn make_block_import(&self, client: Arc) + -> (Arc + Send + Sync>, PeerData) + { + let (import, link) = block_import( + client, + Arc::new(self.test_config.clone()) + ).expect("Could not create block import for fresh peer."); + (Arc::new(import), Mutex::new(Some(link))) + } + + fn peer(&self, i: usize) -> &GrandpaPeer { + &self.peers[i] + } + + fn peers(&self) -> &Vec> { + &self.peers + } + + fn mut_peers>)>(&mut self, closure: F) { + closure(&mut self.peers); + } + + fn started(&self) -> bool { + self.started + } + + fn set_started(&mut self, new: bool) { + self.started = new; + } +} + +#[derive(Clone)] +struct MessageRouting { + inner: Arc>, + peer_id: usize, +} + +impl MessageRouting { + fn new(inner: Arc>, peer_id: usize,) -> Self { + MessageRouting { + inner, + peer_id, + } + } +} + +fn make_topic(round: u64, set_id: u64) -> Hash { + let mut hash = Hash::default(); + round.using_encoded(|s| { + let raw = hash.as_mut(); + raw[..8].copy_from_slice(s); + }); + set_id.using_encoded(|s| { + let raw = hash.as_mut(); + raw[8..16].copy_from_slice(s); + }); + hash +} + +fn make_commit_topic(set_id: u64) -> Hash { + let mut hash = Hash::default(); + + { + let raw = hash.as_mut(); + raw[16..22].copy_from_slice(b"commit"); + } + set_id.using_encoded(|s| { + let raw = hash.as_mut(); + raw[24..].copy_from_slice(s); + }); + + hash +} + +impl Network for MessageRouting { + type In = Box,Error=()> + Send>; + + fn messages_for(&self, round: u64, set_id: u64) -> Self::In { + let inner = self.inner.lock(); + let peer = inner.peer(self.peer_id); + let mut gossip = peer.consensus_gossip().write(); + let messages = peer.with_spec(move |_, _| { + gossip.messages_for(make_topic(round, set_id)) + }); + + let messages = messages.map_err( + move |_| panic!("Messages for round {} dropped too early", round) + ); + + Box::new(messages) + } + + fn send_message(&self, round: u64, set_id: u64, message: Vec) { + let mut inner = self.inner.lock(); + inner.peer(self.peer_id).gossip_message(make_topic(round, set_id), message, false); + inner.route_until_complete(); + } + + fn drop_messages(&self, round: u64, set_id: u64) { + let topic = make_topic(round, set_id); + let inner = self.inner.lock(); + let peer = inner.peer(self.peer_id); + let mut gossip = peer.consensus_gossip().write(); + peer.with_spec(move |_, _| { + gossip.collect_garbage(|t| t == &topic) + }); + } + + fn commit_messages(&self, set_id: u64) -> Self::In { + let inner = self.inner.lock(); + let peer = inner.peer(self.peer_id); + let mut gossip = peer.consensus_gossip().write(); + let messages = peer.with_spec(move |_, _| { + gossip.messages_for(make_commit_topic(set_id)) + }); + + let messages = messages.map_err( + move |_| panic!("Commit messages for set {} dropped too early", set_id) + ); + + Box::new(messages) + } + + fn send_commit(&self, _round: u64, set_id: u64, message: Vec) { + let mut inner = self.inner.lock(); + inner.peer(self.peer_id).gossip_message(make_commit_topic(set_id), message, true); + inner.route_until_complete(); + } +} + +#[derive(Default, Clone)] +struct TestApi { + genesis_authorities: Vec<(Ed25519AuthorityId, u64)>, + scheduled_changes: Arc>>>, +} + +impl TestApi { + fn new(genesis_authorities: Vec<(Ed25519AuthorityId, u64)>) -> Self { + TestApi { + genesis_authorities, + scheduled_changes: Arc::new(Mutex::new(HashMap::new())), + } + } +} + +struct RuntimeApi { + inner: TestApi, +} + +impl ProvideRuntimeApi for TestApi { + type Api = RuntimeApi; + + fn runtime_api<'a>(&'a self) -> ApiRef<'a, Self::Api> { + RuntimeApi { inner: self.clone() }.into() + } +} + +impl Core for RuntimeApi { + fn version(&self, _: &BlockId) -> Result { + unimplemented!("Not required for testing!") + } + + fn authorities(&self, _: &BlockId) -> Result> { + unimplemented!("Not required for testing!") + } + + fn execute_block(&self, _: &BlockId, _: Block) -> Result<()> { + unimplemented!("Not required for testing!") + } + + fn initialise_block( + &self, + _: &BlockId, + _: &::Header + ) -> Result<()> { + unimplemented!("Not required for testing!") + } +} + +impl ApiExt for RuntimeApi { + fn map_api_result result::Result, R, E>( + &self, + _: F + ) -> result::Result { + unimplemented!("Not required for testing!") + } + + fn has_api(&self, _: &BlockId) -> Result { + unimplemented!("Not required for testing!") + } +} + +impl GrandpaApi for RuntimeApi { + fn grandpa_authorities( + &self, + at: &BlockId + ) -> Result> { + if at == &BlockId::Number(0) { + Ok(self.inner.genesis_authorities.clone()) + } else { + panic!("should generally only request genesis authorities") + } + } + + fn grandpa_pending_change(&self, at: &BlockId, _: &DigestFor) + -> Result>>> + { + let parent_hash = match at { + &BlockId::Hash(at) => at, + _ => panic!("not requested by block hash!!"), + }; + + // we take only scheduled changes at given block number where there are no + // extrinsics. + Ok(self.inner.scheduled_changes.lock().get(&parent_hash).map(|c| c.clone())) + } +} + +const TEST_GOSSIP_DURATION: Duration = Duration::from_millis(500); +const TEST_ROUTING_INTERVAL: Duration = Duration::from_millis(50); + +fn make_ids(keys: &[Keyring]) -> Vec<(Ed25519AuthorityId, u64)> { + keys.iter() + .map(|key| Ed25519AuthorityId(key.to_raw_public())) + .map(|id| (id, 1)) + .collect() +} + +fn run_to_completion(blocks: u64, net: Arc>, peers: &[Keyring]) { + let mut finality_notifications = Vec::new(); + let mut runtime = current_thread::Runtime::new().unwrap(); + + for (peer_id, key) in peers.iter().enumerate() { + let (client, link) = { + let mut net = net.lock(); + // temporary needed for some reason + let link = net.peers[peer_id].data.lock().take().expect("link initialized at startup; qed"); + ( + net.peers[peer_id].client().clone(), + link, + ) + }; + finality_notifications.push( + client.finality_notification_stream() + .take_while(|n| Ok(n.header.number() < &blocks)) + .for_each(|_| Ok(())) + ); + fn assert_send(_: &T) { } + + let voter = run_grandpa( + Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + local_key: Some(Arc::new(key.clone().into())), + name: Some(format!("peer#{}", peer_id)), + }, + link, + MessageRouting::new(net.clone(), peer_id), + futures::empty(), + ).expect("all in order with client and network"); + + assert_send(&voter); + + runtime.spawn(voter); + } + + // wait for all finalized on each. + let wait_for = ::futures::future::join_all(finality_notifications) + .map(|_| ()) + .map_err(|_| ()); + + let drive_to_completion = ::tokio::timer::Interval::new_interval(TEST_ROUTING_INTERVAL) + .for_each(move |_| { net.lock().route_until_complete(); Ok(()) }) + .map(|_| ()) + .map_err(|_| ()); + + runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap(); +} + +#[test] +fn finalize_3_voters_no_observers() { + let peers = &[Keyring::Alice, Keyring::Bob, Keyring::Charlie]; + let voters = make_ids(peers); + + let mut net = GrandpaTestNet::new(TestApi::new(voters), 3); + net.peer(0).push_blocks(20, false); + net.sync(); + + for i in 0..3 { + assert_eq!(net.peer(i).client().info().unwrap().chain.best_number, 20, + "Peer #{} failed to sync", i); + } + + let net = Arc::new(Mutex::new(net)); + run_to_completion(20, net.clone(), peers); + + // normally there's no justification for finalized blocks + assert!(net.lock().peer(0).client().backend().blockchain().justification(BlockId::Number(20)).unwrap().is_none(), + "Extra justification for block#1"); +} + +#[test] +fn finalize_3_voters_1_observer() { + let peers = &[Keyring::Alice, Keyring::Bob, Keyring::Charlie]; + let voters = make_ids(peers); + + let mut net = GrandpaTestNet::new(TestApi::new(voters), 4); + net.peer(0).push_blocks(20, false); + net.sync(); + + let net = Arc::new(Mutex::new(net)); + let mut finality_notifications = Vec::new(); + + let mut runtime = current_thread::Runtime::new().unwrap(); + let all_peers = peers.iter() + .cloned() + .map(|key| Some(Arc::new(key.into()))) + .chain(::std::iter::once(None)); + + for (peer_id, local_key) in all_peers.enumerate() { + let (client, link) = { + let mut net = net.lock(); + let link = net.peers[peer_id].data.lock().take().expect("link initialized at startup; qed"); + ( + net.peers[peer_id].client().clone(), + link, + ) + }; + finality_notifications.push( + client.finality_notification_stream() + .take_while(|n| Ok(n.header.number() < &20)) + .for_each(move |_| Ok(())) + ); + let voter = run_grandpa( + Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + local_key, + name: Some(format!("peer#{}", peer_id)), + }, + link, + MessageRouting::new(net.clone(), peer_id), + futures::empty(), + ).expect("all in order with client and network"); + + runtime.spawn(voter); + } + + // wait for all finalized on each. + let wait_for = ::futures::future::join_all(finality_notifications) + .map(|_| ()) + .map_err(|_| ()); + + let drive_to_completion = ::tokio::timer::Interval::new_interval(TEST_ROUTING_INTERVAL) + .for_each(move |_| { net.lock().route_until_complete(); Ok(()) }) + .map(|_| ()) + .map_err(|_| ()); + + runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap(); +} + +#[test] +fn transition_3_voters_twice_1_observer() { + let peers_a = &[ + Keyring::Alice, + Keyring::Bob, + Keyring::Charlie, + ]; + + let peers_b = &[ + Keyring::Dave, + Keyring::Eve, + Keyring::Ferdie, + ]; + + let peers_c = &[ + Keyring::Alice, + Keyring::Eve, + Keyring::Two, + ]; + + let observer = &[Keyring::One]; + + let genesis_voters = make_ids(peers_a); + + let api = TestApi::new(genesis_voters); + let transitions = api.scheduled_changes.clone(); + let net = Arc::new(Mutex::new(GrandpaTestNet::new(api, 8))); + + let mut runtime = current_thread::Runtime::new().unwrap(); + + net.lock().peer(0).push_blocks(1, false); + net.lock().sync(); + + for (i, peer) in net.lock().peers().iter().enumerate() { + assert_eq!(peer.client().info().unwrap().chain.best_number, 1, + "Peer #{} failed to sync", i); + + let set_raw = peer.client().backend().get_aux(::AUTHORITY_SET_KEY).unwrap().unwrap(); + let set = AuthoritySet::::decode(&mut &set_raw[..]).unwrap(); + + assert_eq!(set.current(), (0, make_ids(peers_a).as_slice())); + assert_eq!(set.pending_changes().len(), 0); + } + + { + let net = net.clone(); + let client = net.lock().peers[0].client().clone(); + let transitions = transitions.clone(); + let add_transition = move |parent_hash, change| { + transitions.lock().insert(parent_hash, change); + }; + let peers_c = peers_c.clone(); + + // wait for blocks to be finalized before generating new ones + let block_production = client.finality_notification_stream() + .take_while(|n| Ok(n.header.number() < &30)) + .for_each(move |n| { + match n.header.number() { + 1 => { + // first 14 blocks. + net.lock().peer(0).push_blocks(13, false); + }, + 14 => { + // generate transition at block 15, applied at 20. + net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { + let block = builder.bake().unwrap(); + add_transition(*block.header.parent_hash(), ScheduledChange { + next_authorities: make_ids(peers_b), + delay: 4, + }); + + block + }); + net.lock().peer(0).push_blocks(5, false); + }, + 20 => { + // at block 21 we do another transition, but this time instant. + // add more until we have 30. + net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| { + let block = builder.bake().unwrap(); + add_transition(*block.header.parent_hash(), ScheduledChange { + next_authorities: make_ids(&peers_c), + delay: 0, + }); + + block + }); + net.lock().peer(0).push_blocks(9, false); + }, + _ => {}, + } + + Ok(()) + }); + + runtime.spawn(block_production); + } + + let mut finality_notifications = Vec::new(); + let all_peers = peers_a.iter() + .chain(peers_b) + .chain(peers_c) + .chain(observer) + .cloned() + .collect::>() // deduplicate + .into_iter() + .map(|key| Some(Arc::new(key.into()))) + .enumerate(); + + for (peer_id, local_key) in all_peers { + let (client, link) = { + let mut net = net.lock(); + let link = net.peers[peer_id].data.lock().take().expect("link initialized at startup; qed"); + ( + net.peers[peer_id].client().clone(), + link, + ) + }; + finality_notifications.push( + client.finality_notification_stream() + .take_while(|n| Ok(n.header.number() < &30)) + .for_each(move |_| Ok(())) + .map(move |()| { + let set_raw = client.backend().get_aux(::AUTHORITY_SET_KEY).unwrap().unwrap(); + let set = AuthoritySet::::decode(&mut &set_raw[..]).unwrap(); + + assert_eq!(set.current(), (2, make_ids(peers_c).as_slice())); + assert!(set.pending_changes().is_empty()); + }) + ); + let voter = run_grandpa( + Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + local_key, + name: Some(format!("peer#{}", peer_id)), + }, + link, + MessageRouting::new(net.clone(), peer_id), + futures::empty(), + ).expect("all in order with client and network"); + + runtime.spawn(voter); + } + + // wait for all finalized on each. + let wait_for = ::futures::future::join_all(finality_notifications) + .map(|_| ()) + .map_err(|_| ()); + + let drive_to_completion = ::tokio::timer::Interval::new_interval(TEST_ROUTING_INTERVAL) + .for_each(move |_| { + net.lock().send_import_notifications(); + net.lock().send_finality_notifications(); + net.lock().sync(); + Ok(()) + }) + .map(|_| ()) + .map_err(|_| ()); + + runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap(); +} + +#[test] +fn justification_is_emitted_when_consensus_data_changes() { + let peers = &[Keyring::Alice, Keyring::Bob, Keyring::Charlie]; + let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 3); + + // import block#1 WITH consensus data change + let new_authorities = vec![Ed25519AuthorityId::from([42; 32])]; + net.peer(0).push_authorities_change_block(new_authorities); + net.sync(); + let net = Arc::new(Mutex::new(net)); + run_to_completion(1, net.clone(), peers); + + // ... and check that there's no justification for block#1 + assert!(net.lock().peer(0).client().backend().blockchain().justification(BlockId::Number(1)).unwrap().is_some(), + "Missing justification for block#1"); +} + +#[test] +fn justification_is_generated_periodically() { + let peers = &[Keyring::Alice, Keyring::Bob, Keyring::Charlie]; + let voters = make_ids(peers); + + let mut net = GrandpaTestNet::new(TestApi::new(voters), 3); + net.peer(0).push_blocks(32, false); + net.sync(); + + let net = Arc::new(Mutex::new(net)); + run_to_completion(32, net.clone(), peers); + + // when block#32 (justification_period) is finalized, justification + // is required => generated + for i in 0..3 { + assert!(net.lock().peer(i).client().backend().blockchain() + .justification(BlockId::Number(32)).unwrap().is_some()); + } +} + +#[test] +fn consensus_changes_works() { + let mut changes = ConsensusChanges::::empty(); + + // pending changes are not finalized + changes.note_change((10, 1.into())); + assert_eq!(changes.finalize((5, 5.into()), |_| Ok(None)).unwrap(), (false, false)); + + // no change is selected from competing pending changes + changes.note_change((1, 1.into())); + changes.note_change((1, 101.into())); + assert_eq!(changes.finalize((10, 10.into()), |_| Ok(Some(1001.into()))).unwrap(), (true, false)); + + // change is selected from competing pending changes + changes.note_change((1, 1.into())); + changes.note_change((1, 101.into())); + assert_eq!(changes.finalize((10, 10.into()), |_| Ok(Some(1.into()))).unwrap(), (true, true)); +} + +#[test] +fn sync_justifications_on_change_blocks() { + ::env_logger::init(); + + let peers_a = &[Keyring::Alice, Keyring::Bob, Keyring::Charlie]; + let peers_b = &[Keyring::Alice, Keyring::Bob]; + let voters = make_ids(peers_b); + + // 4 peers, 3 of them are authorities and participate in grandpa + let api = TestApi::new(voters); + let transitions = api.scheduled_changes.clone(); + let mut net = GrandpaTestNet::new(api, 4); + + // add 20 blocks + net.peer(0).push_blocks(20, false); + + // at block 21 we do add a transition which is instant + net.peer(0).generate_blocks(1, BlockOrigin::File, |builder| { + let block = builder.bake().unwrap(); + transitions.lock().insert(*block.header.parent_hash(), ScheduledChange { + next_authorities: make_ids(peers_b), + delay: 0, + }); + block + }); + + // add more blocks on top of it (until we have 25) + net.peer(0).push_blocks(4, false); + net.sync(); + + for i in 0..4 { + assert_eq!(net.peer(i).client().info().unwrap().chain.best_number, 25, + "Peer #{} failed to sync", i); + } + + let net = Arc::new(Mutex::new(net)); + run_to_completion(25, net.clone(), peers_a); + + // the first 3 peers are grandpa voters and therefore have already finalized + // block 21 and stored a justification + for i in 0..3 { + assert!(net.lock().peer(i).client().justification(&BlockId::Number(21)).unwrap().is_some()); + } + + // the last peer should get the justification by syncing from other peers + assert!(net.lock().peer(3).client().justification(&BlockId::Number(21)).unwrap().is_none()); + while net.lock().peer(3).client().justification(&BlockId::Number(21)).unwrap().is_none() { + net.lock().sync_steps(100); + } +} diff --git a/core/finality-grandpa/src/until_imported.rs b/core/finality-grandpa/src/until_imported.rs new file mode 100644 index 0000000000000000000000000000000000000000..8cb825ac84c3b56b6b5ceb7028ae4eb50c8b7478 --- /dev/null +++ b/core/finality-grandpa/src/until_imported.rs @@ -0,0 +1,559 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 stream for waiting until one or more blocks are imported before +//! passing through inner items. This is done in a generic way to support +//! many different kinds of items. +//! +//! This is used for votes and commit messages currently. + +use super::{BlockStatus, Error, SignedMessage, CompactCommit}; + +use client::ImportNotifications; +use futures::prelude::*; +use futures::stream::Fuse; +use parking_lot::Mutex; +use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; +use substrate_primitives::Ed25519AuthorityId; +use tokio::timer::Interval; + +use std::collections::{HashMap, VecDeque}; +use std::sync::{atomic::{AtomicUsize, Ordering}, Arc}; +use std::time::{Duration, Instant}; + +// something which will block until imported. +pub(crate) trait BlockUntilImported: Sized { + // the type that is blocked on. + type Blocked; + + /// new incoming item. For all internal items, + /// check if they require to be waited for. + /// if so, call the `Wait` closure. + /// if they are ready, call the `Ready` closure. + fn schedule_wait( + input: Self::Blocked, + status_check: &S, + wait: Wait, + ready: Ready, + ) -> Result<(), Error> where + S: BlockStatus, + Wait: FnMut(Block::Hash, Self), + Ready: FnMut(Self::Blocked); + + /// called when the wait has completed. The canonical number is passed through + /// for further checks. + fn wait_completed(self, canon_number: NumberFor) -> Option; +} + +/// Buffering imported messages until blocks with given hashes are imported. +pub(crate) struct UntilImported> { + import_notifications: Fuse>, + status_check: Status, + inner: Fuse, + ready: VecDeque, + check_pending: Interval, + pending: HashMap>, +} + +impl UntilImported + where Status: BlockStatus, M: BlockUntilImported +{ + /// Create a new `UntilImported` wrapper. + pub(crate) fn new( + import_notifications: ImportNotifications, + status_check: Status, + stream: I, + ) -> Self { + // how often to check if pending messages that are waiting for blocks to be + // imported can be checked. + // + // the import notifications interval takes care of most of this; this is + // used in the event of missed import notifications + const CHECK_PENDING_INTERVAL: Duration = Duration::from_secs(5); + let now = Instant::now(); + + let check_pending = Interval::new(now + CHECK_PENDING_INTERVAL, CHECK_PENDING_INTERVAL); + UntilImported { + import_notifications: import_notifications.fuse(), + status_check, + inner: stream.fuse(), + ready: VecDeque::new(), + check_pending, + pending: HashMap::new(), + } + } +} + +impl Stream for UntilImported where + Status: BlockStatus, + I: Stream, + M: BlockUntilImported, +{ + type Item = M::Blocked; + type Error = Error; + + fn poll(&mut self) -> Poll, Error> { + loop { + match self.inner.poll()? { + Async::Ready(None) => return Ok(Async::Ready(None)), + Async::Ready(Some(input)) => { + // new input: schedule wait of any parts which require + // blocks to be known. + let mut ready = &mut self.ready; + let mut pending = &mut self.pending; + M::schedule_wait( + input, + &self.status_check, + |target_hash, wait| pending + .entry(target_hash) + .or_insert_with(Vec::new) + .push(wait), + |ready_item| ready.push_back(ready_item), + )?; + } + Async::NotReady => break, + } + } + + loop { + match self.import_notifications.poll() { + Err(_) => return Err(Error::Network(format!("Failed to get new message"))), + Ok(Async::Ready(None)) => return Ok(Async::Ready(None)), + Ok(Async::Ready(Some(notification))) => { + // new block imported. queue up all messages tied to that hash. + if let Some(messages) = self.pending.remove(¬ification.hash) { + let canon_number = notification.header.number().clone(); + let ready_messages = messages.into_iter() + .filter_map(|m| m.wait_completed(canon_number)); + + self.ready.extend(ready_messages); + } + } + Ok(Async::NotReady) => break, + } + } + + let mut update_interval = false; + while let Async::Ready(Some(_)) = self.check_pending.poll().map_err(Error::Timer)? { + update_interval = true; + } + + if update_interval { + let mut known_keys = Vec::new(); + for &block_hash in self.pending.keys() { + if let Some(number) = self.status_check.block_number(block_hash)? { + known_keys.push((block_hash, number)); + } + } + + for (known_hash, canon_number) in known_keys { + if let Some(pending_messages) = self.pending.remove(&known_hash) { + let ready_messages = pending_messages.into_iter() + .filter_map(|m| m.wait_completed(canon_number)); + + self.ready.extend(ready_messages); + } + } + } + + if let Some(ready) = self.ready.pop_front() { + return Ok(Async::Ready(Some(ready))) + } + + if self.import_notifications.is_done() && self.inner.is_done() { + Ok(Async::Ready(None)) + } else { + Ok(Async::NotReady) + } + } +} + +fn warn_authority_wrong_target(hash: H, id: Ed25519AuthorityId) { + warn!( + target: "afg", + "Authority {:?} signed GRANDPA message with \ + wrong block number for hash {}", + id, + hash, + ); +} + +impl BlockUntilImported for SignedMessage { + type Blocked = Self; + + fn schedule_wait( + msg: Self::Blocked, + status_check: &S, + mut wait: Wait, + mut ready: Ready, + ) -> Result<(), Error> where + S: BlockStatus, + Wait: FnMut(Block::Hash, Self), + Ready: FnMut(Self::Blocked), + { + let (&target_hash, target_number) = msg.target(); + + if let Some(number) = status_check.block_number(target_hash)? { + if number != target_number { + warn_authority_wrong_target(target_hash, msg.id); + } else { + ready(msg); + } + } else { + wait(target_hash, msg) + } + + Ok(()) + } + + fn wait_completed(self, canon_number: NumberFor) -> Option { + let (&target_hash, target_number) = self.target(); + if canon_number != target_number { + warn_authority_wrong_target(target_hash, self.id); + + None + } else { + Some(self) + } + } +} + +/// Helper type definition for the stream which waits until vote targets for +/// signed messages are imported. +pub(crate) type UntilVoteTargetImported = UntilImported>; + +/// This blocks a commit message's import until all blocks +/// referenced in its votes are known. +/// +/// This is used for compact commits which have already been checked for +/// structural soundness. +pub(crate) struct BlockCommitMessage { + inner: Arc<(AtomicUsize, Mutex)>>)>, + target_number: NumberFor, +} + +impl BlockUntilImported for BlockCommitMessage { + type Blocked = (u64, CompactCommit); + + fn schedule_wait( + input: Self::Blocked, + status_check: &S, + mut wait: Wait, + mut ready: Ready, + ) -> Result<(), Error> where + S: BlockStatus, + Wait: FnMut(Block::Hash, Self), + Ready: FnMut(Self::Blocked), + { + use std::collections::hash_map::Entry; + + enum KnownOrUnknown { + Known(N), + Unknown(N), + } + + impl KnownOrUnknown { + fn number(&self) -> &N { + match *self { + KnownOrUnknown::Known(ref n) => n, + KnownOrUnknown::Unknown(ref n) => n, + } + } + } + + let mut checked_hashes: HashMap<_, KnownOrUnknown>> = HashMap::new(); + let mut unknown_count = 0; + + { + // returns false when should early exit. + let mut query_known = |target_hash, perceived_number| -> Result { + // check integrity: all precommits for same hash have same number. + let canon_number = match checked_hashes.entry(target_hash) { + Entry::Occupied(entry) => entry.get().number().clone(), + Entry::Vacant(mut entry) => { + if let Some(number) = status_check.block_number(target_hash)? { + entry.insert(KnownOrUnknown::Known(number)); + number + + } else { + entry.insert(KnownOrUnknown::Unknown(perceived_number)); + unknown_count += 1; + perceived_number + } + } + }; + + if canon_number != perceived_number { + // invalid commit: messages targeting wrong number or + // at least different from other vote. in same commit. + return Ok(false); + } + + Ok(true) + }; + + let commit = &input.1; + + // add known hashes from the precommits. + for precommit in &commit.precommits { + let target_number = precommit.target_number; + let target_hash = precommit.target_hash; + + if !query_known(target_hash, target_number)? { + return Ok(()) + } + } + + // see if commit target hash is known. + if !query_known(commit.target_hash, commit.target_number)? { + return Ok(()) + } + } + + // none of the hashes in the commit message were unknown. + // we can just return the commit directly. + if unknown_count == 0 { + ready(input); + return Ok(()) + } + + let locked_commit = Arc::new((AtomicUsize::new(unknown_count), Mutex::new(Some(input)))); + + // schedule waits for all unknown messages. + // when the last one of these has `wait_completed` called on it, + // the commit will be returned. + // + // in the future, we may want to issue sync requests to the network + // if this is taking a long time. + for (hash, is_known) in checked_hashes { + if let KnownOrUnknown::Unknown(target_number) = is_known { + wait(hash, BlockCommitMessage { + inner: locked_commit.clone(), + target_number, + }) + } + } + + Ok(()) + } + + fn wait_completed(self, canon_number: NumberFor) -> Option { + if self.target_number != canon_number { + // if we return without deducting the counter, then none of the other + // handles can return the commit message. + return None; + } + + let mut last_count = self.inner.0.load(Ordering::Acquire); + + // CAS loop to ensure that we always have a last reader. + loop { + if last_count == 1 { // we are the last one left. + return self.inner.1.lock().take(); + } + + let prev_value = self.inner.0.compare_and_swap( + last_count, + last_count - 1, + Ordering::SeqCst, + ); + + if prev_value == last_count { + return None; + } else { + last_count = prev_value; + } + } + } +} + +/// A stream which gates off incoming commit messages until all referenced +/// block hashes have been imported. +pub(crate) type UntilCommitBlocksImported = UntilImported< + Block, + Status, + I, + BlockCommitMessage, +>; + +#[cfg(test)] +mod tests { + use super::*; + use tokio::runtime::current_thread::Runtime; + use tokio::timer::Delay; + use test_client::runtime::{Block, Hash, Header}; + use consensus_common::BlockOrigin; + use client::BlockImportNotification; + use futures::future::Either; + use futures::sync::mpsc; + use grandpa::Precommit; + + #[derive(Clone)] + struct TestChainState { + sender: mpsc::UnboundedSender>, + known_blocks: Arc>>, + } + + impl TestChainState { + fn new() -> (Self, ImportNotifications) { + let (tx, rx) = mpsc::unbounded(); + let state = TestChainState { + sender: tx, + known_blocks: Arc::new(Mutex::new(HashMap::new())), + }; + + (state, rx) + } + + fn block_status(&self) -> TestBlockStatus { + TestBlockStatus { inner: self.known_blocks.clone() } + } + + fn import_header(&self, header: Header) { + let hash = header.hash(); + let number = header.number().clone(); + + self.known_blocks.lock().insert(hash, number); + self.sender.unbounded_send(BlockImportNotification { + hash, + origin: BlockOrigin::File, + header, + is_new_best: false, + }).unwrap(); + } + } + + struct TestBlockStatus { + inner: Arc>>, + } + + impl BlockStatus for TestBlockStatus { + fn block_number(&self, hash: Hash) -> Result, Error> { + Ok(self.inner.lock().get(&hash).map(|x| x.clone())) + } + } + + fn make_header(number: u64) -> Header { + Header::new( + number, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ) + } + + #[test] + fn blocking_commit_message() { + let h1 = make_header(5); + let h2 = make_header(6); + let h3 = make_header(7); + + let (chain_state, import_notifications) = TestChainState::new(); + let block_status = chain_state.block_status(); + + let unknown_commit = CompactCommit:: { + target_hash: h1.hash(), + target_number: 5, + precommits: vec![ + Precommit { + target_hash: h2.hash(), + target_number: 6, + }, + Precommit { + target_hash: h3.hash(), + target_number: 7, + }, + ], + auth_data: Vec::new(), // not used + }; + + let (commit_tx, commit_rx) = mpsc::unbounded(); + + let until_imported = UntilCommitBlocksImported::new( + import_notifications, + block_status, + commit_rx.map_err(|_| panic!("should never error")), + ); + + commit_tx.unbounded_send((0, unknown_commit.clone())).unwrap(); + + let inner_chain_state = chain_state.clone(); + let work = until_imported + .into_future() + .select2(Delay::new(Instant::now() + Duration::from_millis(100))) + .then(move |res| match res { + Err(_) => panic!("neither should have had error"), + Ok(Either::A(_)) => panic!("timeout should have fired first"), + Ok(Either::B((_, until_imported))) => { + // timeout fired. push in the headers. + inner_chain_state.import_header(h1); + inner_chain_state.import_header(h2); + inner_chain_state.import_header(h3); + + until_imported + } + }); + + let mut runtime = Runtime::new().unwrap(); + assert_eq!(runtime.block_on(work).map_err(|(e, _)| e).unwrap().0, Some((0, unknown_commit))); + } + + #[test] + fn commit_message_all_known() { + let h1 = make_header(5); + let h2 = make_header(6); + let h3 = make_header(7); + + let (chain_state, import_notifications) = TestChainState::new(); + let block_status = chain_state.block_status(); + + let known_commit = CompactCommit:: { + target_hash: h1.hash(), + target_number: 5, + precommits: vec![ + Precommit { + target_hash: h2.hash(), + target_number: 6, + }, + Precommit { + target_hash: h3.hash(), + target_number: 7, + }, + ], + auth_data: Vec::new(), // not used + }; + + chain_state.import_header(h1); + chain_state.import_header(h2); + chain_state.import_header(h3); + + let (commit_tx, commit_rx) = mpsc::unbounded(); + + let until_imported = UntilCommitBlocksImported::new( + import_notifications, + block_status, + commit_rx.map_err(|_| panic!("should never error")), + ); + + commit_tx.unbounded_send((0, known_commit.clone())).unwrap(); + + let work = until_imported.into_future(); + + let mut runtime = Runtime::new().unwrap(); + assert_eq!(runtime.block_on(work).map_err(|(e, _)| e).unwrap().0, Some((0, known_commit))); + } +} diff --git a/core/keyring/README.adoc b/core/keyring/README.adoc deleted file mode 100644 index 0118fe883d1a6af336eefecb215dbad60c6c4158..0000000000000000000000000000000000000000 --- a/core/keyring/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Keyring - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/keyring/src/lib.rs b/core/keyring/src/lib.rs index 6ba79d146cd920c79c72410629803206a0e112ad..d2970c54c6b24de9d426e35490418b053b1dcb5e 100644 --- a/core/keyring/src/lib.rs +++ b/core/keyring/src/lib.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Support code for the runtime. A set of test accounts. -// end::description[] #[macro_use] extern crate hex_literal; #[macro_use] extern crate lazy_static; diff --git a/core/keystore/Cargo.toml b/core/keystore/Cargo.toml index 760e064158ac200b259b96556aa768c599130f15..9d31557b420d7a18fa0068398f5af2250273bceb 100644 --- a/core/keystore/Cargo.toml +++ b/core/keystore/Cargo.toml @@ -5,14 +5,14 @@ authors = ["Parity Technologies "] [dependencies] substrate-primitives = { path = "../primitives" } -parity-crypto = { version = "0.1", default-features = false } +parity-crypto = { version = "0.2", default-features = false } error-chain = "0.12" hex = "0.3" rand = "0.4" serde_json = "1.0" serde = "1.0" serde_derive = "1.0" -subtle = "0.5" +subtle = "2.0" [dev-dependencies] tempdir = "0.3" diff --git a/core/keystore/README.adoc b/core/keystore/README.adoc deleted file mode 100644 index 5a66a882ff098c37bc1dfa4633d9bc0aff2d3d1c..0000000000000000000000000000000000000000 --- a/core/keystore/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Keystore - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/keystore/src/lib.rs b/core/keystore/src/lib.rs index aeb9c508865bd15fee713897858a4f55846ece99..baeeab27556d702a0315fe6d04cee6b7ac8b80ac 100644 --- a/core/keystore/src/lib.rs +++ b/core/keystore/src/lib.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Keystore (and session key management) for ed25519 based chains like Polkadot. -// end::description[] extern crate substrate_primitives; extern crate parity_crypto as crypto; @@ -112,7 +110,7 @@ impl EncryptedKey { let mac = blake2_256(&crypto::derive_mac(&derived_right_bits, &self.ciphertext)); - if subtle::slices_equal(&mac[..], &self.mac[..]) != 1 { + if subtle::ConstantTimeEq::ct_eq(&mac[..], &self.mac[..]).unwrap_u8() != 1 { return Err(ErrorKind::InvalidPassword.into()); } @@ -131,6 +129,24 @@ pub struct Store { additional: HashMap, } +pub fn pad_seed(seed: &str) -> Seed { + let mut s: [u8; 32] = [' ' as u8; 32]; + + let was_hex = if seed.len() == 66 && &seed[0..2] == "0x" { + if let Ok(d) = hex::decode(&seed[2..]) { + s.copy_from_slice(&d); + true + } else { false } + } else { false }; + + if !was_hex { + let len = ::std::cmp::min(32, seed.len()); + &mut s[..len].copy_from_slice(&seed.as_bytes()[..len]); + } + + s +} + impl Store { /// Create a new store at the given path. pub fn open(path: PathBuf) -> Result { @@ -153,24 +169,11 @@ impl Store { /// Create a new key from seed. Do not place it into the store. /// Only the first 32 bytes of the sead are used. This is meant to be used for testing only. - // TODO: Remove this + // FIXME: remove this - https://github.com/paritytech/substrate/issues/1063 pub fn generate_from_seed(&mut self, seed: &str) -> Result { - let mut s: [u8; 32] = [' ' as u8; 32]; - - let was_hex = if seed.len() == 66 && &seed[0..2] == "0x" { - if let Ok(d) = hex::decode(&seed[2..]) { - s.copy_from_slice(&d); - true - } else { false } - } else { false }; - - if !was_hex { - let len = ::std::cmp::min(32, seed.len()); - &mut s[..len].copy_from_slice(&seed.as_bytes()[..len]); - } - - let pair = Pair::from_seed(&s); - self.additional.insert(pair.public(), s); + let padded_seed = pad_seed(seed); + let pair = Pair::from_seed(&padded_seed); + self.additional.insert(pair.public(), padded_seed); Ok(pair) } diff --git a/core/network-libp2p/Cargo.toml b/core/network-libp2p/Cargo.toml index 6b0fb9af40177bbb232bd24c4de52d203b4d0c86..4b2ad770e038c98c9cfdbc235bc042f131101ce5 100644 --- a/core/network-libp2p/Cargo.toml +++ b/core/network-libp2p/Cargo.toml @@ -1,5 +1,6 @@ [package] description = "libp2p implementation of the ethcore network library" +edition = "2018" homepage = "http://parity.io" license = "GPL-3.0" name = "substrate-network-libp2p" @@ -11,19 +12,16 @@ bytes = "0.4" error-chain = { version = "0.12", default-features = false } fnv = "1.0" futures = "0.1" -libp2p = { git = "https://github.com/libp2p/rust-libp2p", rev = "d961e656a74d1bab5366d371a06f9e10d5f4a6c5", default-features = false, features = ["secio-rsa", "secio-secp256k1"] } -parking_lot = "0.5" -libc = "0.2" +libp2p = { version = "0.2", default-features = false, features = ["secio-rsa", "secio-secp256k1", "libp2p-websocket"] } +parking_lot = "0.7.1" log = "0.4" rand = "0.5.0" serde = "1.0.70" serde_derive = "1.0.70" serde_json = "1.0.24" +smallvec = "0.6" tokio = "0.1" tokio-io = "0.1" tokio-timer = "0.2" unsigned-varint = { version = "0.2.1", features = ["codec"] } - -[dev-dependencies] -assert_matches = "1.2" -parity-bytes = "0.1" +void = "1.0" diff --git a/core/network-libp2p/README.adoc b/core/network-libp2p/README.adoc deleted file mode 100644 index 2f340aa397e7325db0c069dc04546f1a07c680d3..0000000000000000000000000000000000000000 --- a/core/network-libp2p/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Network libp2p - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/network-libp2p/src/behaviour.rs b/core/network-libp2p/src/behaviour.rs new file mode 100644 index 0000000000000000000000000000000000000000..74d62040100a4b3f079e9ecd3d6431a9c1e56abb --- /dev/null +++ b/core/network-libp2p/src/behaviour.rs @@ -0,0 +1,342 @@ +// 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 . + +use crate::custom_proto::{CustomProtos, CustomProtosOut, RegisteredProtocols}; +use crate::{NetworkConfiguration, ProtocolId}; +use bytes::Bytes; +use futures::prelude::*; +use libp2p::NetworkBehaviour; +use libp2p::core::{PeerId, ProtocolsHandler}; +use libp2p::core::swarm::{ConnectedPoint, NetworkBehaviour, NetworkBehaviourAction}; +use libp2p::core::swarm::{NetworkBehaviourEventProcess, PollParameters}; +use libp2p::identify::{Identify, IdentifyEvent, protocol::IdentifyInfo}; +use libp2p::kad::{Kademlia, KademliaOut, KademliaTopology}; +use libp2p::ping::{Ping, PingEvent}; +use log::{debug, trace, warn}; +use std::{cmp, io, time::Duration, time::Instant}; +use tokio_io::{AsyncRead, AsyncWrite}; +use tokio_timer::Delay; +use void; + +/// General behaviour of the network. +#[derive(NetworkBehaviour)] +#[behaviour(out_event = "BehaviourOut", poll_method = "poll")] +pub struct Behaviour { + /// Periodically ping nodes, and close the connection if it's unresponsive. + ping: Ping, + /// Custom protocols (dot, bbq, sub, etc.). + custom_protocols: CustomProtos, + /// Discovers nodes of the network. Defined below. + discovery: DiscoveryBehaviour, + /// Periodically identifies the remote and responds to incoming requests. + identify: Identify, + + /// Queue of events to produce for the outside. + #[behaviour(ignore)] + events: Vec, +} + +impl Behaviour { + /// Builds a new `Behaviour`. + // TODO: redundancy between config and local_peer_id (https://github.com/libp2p/rust-libp2p/issues/745) + pub fn new(config: &NetworkConfiguration, local_peer_id: PeerId, protocols: RegisteredProtocols) -> Self { + let identify = { + let proto_version = "/substrate/1.0".to_string(); + let user_agent = format!("{} ({})", config.client_version, config.node_name); + Identify::new(proto_version, user_agent) + }; + + Behaviour { + ping: Ping::new(), + custom_protocols: CustomProtos::new(config, protocols), + discovery: DiscoveryBehaviour::new(local_peer_id), + identify, + events: Vec::new(), + } + } + + /// Sends a message to a peer using the given custom protocol. + /// + /// Has no effect if the custom protocol is not open with the given peer. + /// + /// 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. + #[inline] + pub fn send_custom_message(&mut self, target: &PeerId, protocol_id: ProtocolId, data: impl Into) { + self.custom_protocols.send_packet(target, protocol_id, data) + } + + /// Try to add a reserved peer. + pub fn add_reserved_peer(&mut self, peer_id: PeerId) { + self.custom_protocols.add_reserved_peer(peer_id) + } + + /// Try to remove a reserved peer. + /// + /// If we are in reserved mode and we were connected to a node with this peer ID, then this + /// method will disconnect it and return its index. + pub fn remove_reserved_peer(&mut self, peer_id: PeerId) { + self.custom_protocols.remove_reserved_peer(peer_id) + } + + /// Start accepting all peers again if we weren't. + pub fn accept_unreserved_peers(&mut self) { + self.custom_protocols.accept_unreserved_peers() + } + + /// Start refusing non-reserved nodes. Returns the list of nodes that have been disconnected. + pub fn deny_unreserved_peers(&mut self) { + self.custom_protocols.deny_unreserved_peers() + } + + /// Disconnects a peer and bans it for a little while. + /// + /// Same as `drop_node`, except that the same peer will not be able to reconnect later. + #[inline] + pub fn ban_node(&mut self, peer_id: PeerId) { + self.custom_protocols.ban_peer(peer_id) + } + + /// Disconnects the custom protocols from a peer. + /// + /// The peer will still be able to use Kademlia or other protocols, but will get disconnected + /// after a few seconds of inactivity. + /// + /// This is asynchronous and does not instantly close the custom protocols. + /// Corresponding closing events will be generated once the closing actually happens. + /// + /// Has no effect if we're not connected to the `PeerId`. + #[inline] + pub fn drop_node(&mut self, peer_id: &PeerId) { + self.custom_protocols.disconnect_peer(peer_id) + } +} + +/// Event that can be emitted by the behaviour. +#[derive(Debug)] +pub enum BehaviourOut { + /// Opened a custom protocol with the remote. + CustomProtocolOpen { + /// Identifier of the protocol. + protocol_id: ProtocolId, + /// Version of the protocol that has been opened. + version: u8, + /// Id of the node we have opened a connection with. + peer_id: PeerId, + /// Endpoint used for this custom protocol. + endpoint: ConnectedPoint, + }, + + /// Closed a custom protocol with the remote. + CustomProtocolClosed { + /// Id of the peer we were connected to. + peer_id: PeerId, + /// Identifier of the protocol. + protocol_id: ProtocolId, + /// Reason why the substream closed. If `Ok`, then it's a graceful exit (EOF). + result: io::Result<()>, + }, + + /// Receives a message on a custom protocol substream. + CustomMessage { + /// Id of the peer the message came from. + peer_id: PeerId, + /// Protocol which generated the message. + protocol_id: ProtocolId, + /// Data that has been received. + data: Bytes, + }, + + /// We have obtained debug information from a peer. + Identified { + /// Id of the peer that has been identified. + peer_id: PeerId, + /// Information about the peer. + info: IdentifyInfo, + }, +} + +impl From for BehaviourOut { + fn from(other: CustomProtosOut) -> BehaviourOut { + match other { + CustomProtosOut::CustomProtocolOpen { protocol_id, version, peer_id, endpoint } => { + BehaviourOut::CustomProtocolOpen { protocol_id, version, peer_id, endpoint } + }, + CustomProtosOut::CustomProtocolClosed { protocol_id, peer_id, result } => { + BehaviourOut::CustomProtocolClosed { protocol_id, peer_id, result } + }, + CustomProtosOut::CustomMessage { protocol_id, peer_id, data } => { + BehaviourOut::CustomMessage { protocol_id, peer_id, data } + }, + } + } +} + +impl NetworkBehaviourEventProcess for Behaviour { + fn inject_event(&mut self, event: void::Void) { + void::unreachable(event) + } +} + +impl NetworkBehaviourEventProcess for Behaviour { + fn inject_event(&mut self, event: CustomProtosOut) { + self.events.push(event.into()); + } +} + +impl NetworkBehaviourEventProcess for Behaviour { + fn inject_event(&mut self, event: IdentifyEvent) { + match event { + IdentifyEvent::Identified { peer_id, info, .. } => { + trace!(target: "sub-libp2p", "Identified {:?} => {:?}", peer_id, info); + // TODO: ideally we would delay the first identification to when we open the custom + // protocol, so that we only report id info to the service about the nodes we + // care about (https://github.com/libp2p/rust-libp2p/issues/876) + self.events.push(BehaviourOut::Identified { peer_id, info }); + } + IdentifyEvent::Error { .. } => {} + } + } +} + +impl NetworkBehaviourEventProcess for Behaviour { + fn inject_event(&mut self, out: KademliaOut) { + // We only ever use Kademlia for discovering nodes, and nodes discovered by Kademlia are + // automatically added to the topology. Therefore we don't need to perform any further + // action. + match out { + KademliaOut::FindNodeResult { key, closer_peers } => { + trace!(target: "sub-libp2p", "Kademlia query for {:?} yielded {:?} results", + key, closer_peers.len()); + if closer_peers.is_empty() { + warn!(target: "sub-libp2p", "Kademlia random query has yielded empty results"); + } + } + // We never start any GET_PROVIDERS query. + KademliaOut::GetProvidersResult { .. } => () + } + } +} + +impl NetworkBehaviourEventProcess for Behaviour { + fn inject_event(&mut self, event: PingEvent) { + match event { + PingEvent::PingSuccess { peer, time } => { + trace!(target: "sub-libp2p", "Ping time with {:?}: {:?}", peer, time); + } + } + } +} + +impl Behaviour { + fn poll(&mut self) -> Async> { + if !self.events.is_empty() { + return Async::Ready(NetworkBehaviourAction::GenerateEvent(self.events.remove(0))) + } + + Async::NotReady + } +} + +/// Implementation of `NetworkBehaviour` that discovers the nodes on the network. +pub struct DiscoveryBehaviour { + /// Kademlia requests and answers. + kademlia: Kademlia, + /// Stream that fires when we need to perform the next random Kademlia query. + next_kad_random_query: Delay, + /// After `next_kad_random_query` triggers, the next one triggers after this duration. + duration_to_next_kad: Duration, +} + +impl DiscoveryBehaviour { + fn new(local_peer_id: PeerId) -> Self { + DiscoveryBehaviour { + kademlia: Kademlia::without_init(local_peer_id), + next_kad_random_query: Delay::new(Instant::now()), + duration_to_next_kad: Duration::from_secs(1), + } + } +} + +impl NetworkBehaviour for DiscoveryBehaviour +where + TSubstream: AsyncRead + AsyncWrite, + TTopology: KademliaTopology, +{ + type ProtocolsHandler = as NetworkBehaviour>::ProtocolsHandler; + type OutEvent = as NetworkBehaviour>::OutEvent; + + fn new_handler(&mut self) -> Self::ProtocolsHandler { + NetworkBehaviour::::new_handler(&mut self.kademlia) + } + + fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) { + NetworkBehaviour::::inject_connected(&mut self.kademlia, peer_id, endpoint) + } + + fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint) { + NetworkBehaviour::::inject_disconnected(&mut self.kademlia, peer_id, endpoint) + } + + fn inject_node_event( + &mut self, + peer_id: PeerId, + event: ::OutEvent, + ) { + NetworkBehaviour::::inject_node_event(&mut self.kademlia, peer_id, event) + } + + fn poll( + &mut self, + params: &mut PollParameters, + ) -> Async< + NetworkBehaviourAction< + ::InEvent, + Self::OutEvent, + >, + > { + // Poll Kademlia. + match self.kademlia.poll(params) { + Async::Ready(action) => return Async::Ready(action), + Async::NotReady => (), + } + + // Poll the stream that fires when we need to start a random Kademlia query. + loop { + match self.next_kad_random_query.poll() { + Ok(Async::NotReady) => break, + Ok(Async::Ready(_)) => { + let random_peer_id = PeerId::random(); + debug!(target: "sub-libp2p", "Starting random Kademlia request for {:?}", + random_peer_id); + self.kademlia.find_node(random_peer_id); + + // Reset the `Delay` to the next random. + self.next_kad_random_query.reset(Instant::now() + self.duration_to_next_kad); + self.duration_to_next_kad = cmp::min(self.duration_to_next_kad * 2, + Duration::from_secs(60)); + }, + Err(err) => { + warn!(target: "sub-libp2p", "Kad query timer errored: {:?}", err); + break + } + } + } + + Async::NotReady + } +} + diff --git a/core/network-libp2p/src/custom_proto/behaviour.rs b/core/network-libp2p/src/custom_proto/behaviour.rs new file mode 100644 index 0000000000000000000000000000000000000000..679f44853aa0dbe71d734425d95343fde7a0ca24 --- /dev/null +++ b/core/network-libp2p/src/custom_proto/behaviour.rs @@ -0,0 +1,472 @@ +// 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 . + +use crate::custom_proto::handler::{CustomProtosHandler, CustomProtosHandlerOut, CustomProtosHandlerIn}; +use crate::custom_proto::upgrade::RegisteredProtocols; +use crate::{NetworkConfiguration, NonReservedPeerMode, ProtocolId, topology::NetTopology}; +use bytes::Bytes; +use fnv::{FnvHashMap, FnvHashSet}; +use futures::prelude::*; +use libp2p::core::swarm::{ConnectedPoint, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use libp2p::core::{protocols_handler::ProtocolsHandler, PeerId}; +use log::{debug, trace, warn}; +use smallvec::SmallVec; +use std::{io, marker::PhantomData, time::Duration, time::Instant}; +use tokio_io::{AsyncRead, AsyncWrite}; +use tokio_timer::Delay; + +// Duration during which a peer is disabled. +const PEER_DISABLE_DURATION: Duration = Duration::from_secs(5 * 60); + +/// Network behaviour that handles opening substreams for custom protocols with other nodes. +pub struct CustomProtos { + /// List of protocols to open with peers. Never modified. + registered_protocols: RegisteredProtocols, + + /// List of custom protocols that we have open with remotes. + open_protocols: Vec<(PeerId, ProtocolId)>, + + /// List of peer handlers that were enabled, and whether we're dialing or listening. + /// + /// Note that it is possible for a peer to be in the shutdown process, in which case it will + /// not be in this list but will be present in `open_protocols`. + /// It is also possible that we have *just* enabled a peer, in which case it will be in this + /// list but not in `open_protocols`. + enabled_peers: FnvHashMap, + + /// Maximum number of incoming non-reserved connections, taken from the config. Never modified. + max_incoming_connections: usize, + + /// Maximum number of outgoing non-reserved connections, taken from the config. Never modified. + max_outgoing_connections: usize, + + /// If true, only reserved peers can connect. + reserved_only: bool, + + /// List of the IDs of the reserved peers. We always try to maintain a connection these peers. + reserved_peers: FnvHashSet, + + /// List of the IDs of peers that are forbidden, and the moment their ban expires. + banned_peers: Vec<(PeerId, Instant)>, + + /// When this delay expires, we need to synchronize our active connectons with the + /// network topology. + next_connect_to_nodes: Delay, + + /// Events to produce from `poll()`. + events: SmallVec<[NetworkBehaviourAction; 4]>, + + /// Marker to pin the generics. + marker: PhantomData, +} + +/// Event that can be emitted by the `CustomProtos`. +#[derive(Debug)] +pub enum CustomProtosOut { + /// Opened a custom protocol with the remote. + CustomProtocolOpen { + /// Identifier of the protocol. + protocol_id: ProtocolId, + /// Version of the protocol that has been opened. + version: u8, + /// Id of the node we have opened a connection with. + peer_id: PeerId, + /// Endpoint used for this custom protocol. + endpoint: ConnectedPoint, + }, + + /// Closed a custom protocol with the remote. + CustomProtocolClosed { + /// Id of the peer we were connected to. + peer_id: PeerId, + /// Identifier of the protocol. + protocol_id: ProtocolId, + /// Reason why the substream closed. If `Ok`, then it's a graceful exit (EOF). + result: io::Result<()>, + }, + + /// Receives a message on a custom protocol substream. + CustomMessage { + /// Id of the peer the message came from. + peer_id: PeerId, + /// Protocol which generated the message. + protocol_id: ProtocolId, + /// Data that has been received. + data: Bytes, + }, +} + +impl CustomProtos { + /// Creates a `CustomProtos`. + pub fn new(config: &NetworkConfiguration, registered_protocols: RegisteredProtocols) -> Self { + let max_incoming_connections = config.in_peers as usize; + let max_outgoing_connections = config.out_peers as usize; + + // Expected maximum number of connections. + let connec_cap = max_incoming_connections + .saturating_add(max_outgoing_connections) + .saturating_add(4); // We add an arbitrary number for reserved peers slots + + // Expected maximum number of substreams. + let open_protos_cap = connec_cap.saturating_mul(registered_protocols.len()); + + CustomProtos { + registered_protocols, + max_incoming_connections, + max_outgoing_connections, + reserved_only: config.non_reserved_mode == NonReservedPeerMode::Deny, + reserved_peers: Default::default(), + banned_peers: Vec::new(), + open_protocols: Vec::with_capacity(open_protos_cap), + enabled_peers: FnvHashMap::with_capacity_and_hasher(connec_cap, Default::default()), + next_connect_to_nodes: Delay::new(Instant::now()), + events: SmallVec::new(), + marker: PhantomData, + } + } + + /// Adds a reserved peer. + pub fn add_reserved_peer(&mut self, peer_id: PeerId) { + self.reserved_peers.insert(peer_id); + + // Trigger a `connect_to_nodes` round. + self.next_connect_to_nodes = Delay::new(Instant::now()); + } + + /// Removes a reserved peer. + /// + /// If we are in reserved mode and we were connected to a node with this peer ID, then this + /// method will disconnect it and return its index. + pub fn remove_reserved_peer(&mut self, peer_id: PeerId) { + self.reserved_peers.remove(&peer_id); + } + + /// Start accepting all peers again if we weren't. + pub fn accept_unreserved_peers(&mut self) { + if !self.reserved_only { + return + } + + self.reserved_only = false; + // Trigger a `connect_to_nodes` round. + self.next_connect_to_nodes = Delay::new(Instant::now()); + } + + /// Start refusing non-reserved nodes. + pub fn deny_unreserved_peers(&mut self) { + if self.reserved_only { + return + } + + self.reserved_only = true; + + // Disconnecting nodes that are connected to us and that aren't reserved + let reserved_peers = &mut self.reserved_peers; + let events = &mut self.events; + self.enabled_peers.retain(move |peer_id, _| { + if reserved_peers.contains(peer_id) { + return true + } + events.push(NetworkBehaviourAction::SendEvent { + peer_id: peer_id.clone(), + event: CustomProtosHandlerIn::Disable, + }); + false + }) + } + + /// Disconnects the given peer if we are connected to it. + pub fn disconnect_peer(&mut self, peer: &PeerId) { + if self.enabled_peers.remove(peer).is_some() { + self.events.push(NetworkBehaviourAction::SendEvent { + peer_id: peer.clone(), + event: CustomProtosHandlerIn::Disable, + }); + } + } + + /// Disconnects the given peer if we are connected to it and disables it for a little while. + pub fn ban_peer(&mut self, peer_id: PeerId) { + // Peer is already banned + if self.banned_peers.iter().any(|(p, _)| p == &peer_id) { + return + } + self.banned_peers.push((peer_id.clone(), Instant::now() + PEER_DISABLE_DURATION)); + if self.enabled_peers.remove(&peer_id).is_some() { + self.events.push(NetworkBehaviourAction::SendEvent { + peer_id, + event: CustomProtosHandlerIn::Disable, + }); + } + } + + /// Sends a message to a peer using the given custom protocol. + /// + /// Has no effect if the custom protocol is not open with the given peer. + /// + /// 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, protocol_id: ProtocolId, data: impl Into) { + self.events.push(NetworkBehaviourAction::SendEvent { + peer_id: target.clone(), + event: CustomProtosHandlerIn::SendCustomMessage { + protocol: protocol_id, + data: data.into(), + } + }); + } + + /// Updates the attempted connections to nodes. + /// + /// Also updates `next_connect_to_nodes` with the earliest known moment when we need to + /// update connections again. + fn connect_to_nodes(&mut self, params: &mut PollParameters) { + // Make sure we are connected or connecting to all the reserved nodes. + for reserved in self.reserved_peers.iter() { + // TODO: don't generate an event if we're already in a pending connection (https://github.com/libp2p/rust-libp2p/issues/697) + if !self.enabled_peers.contains_key(&reserved) { + self.events.push(NetworkBehaviourAction::DialPeer { peer_id: reserved.clone() }); + } + } + + // We're done with reserved node; return early if there's nothing more to do. + if self.reserved_only { + return + } + + // Counter of number of connections to open, decreased when we open one. + let mut num_to_open = { + let num_outgoing_connections = self.enabled_peers + .iter() + .filter(|(_, endpoint)| endpoint.is_dialer()) + .filter(|(p, _)| !self.reserved_peers.contains(p)) + .count(); + self.max_outgoing_connections - num_outgoing_connections + }; + + trace!(target: "sub-libp2p", "Connect-to-nodes round; attempting to fill {:?} slots", + num_to_open); + + let local_peer_id = params.local_peer_id().clone(); + let (to_try, will_change) = params.topology().addrs_to_attempt(); + for (peer_id, _) in to_try { + if num_to_open == 0 { + break + } + + if peer_id == &local_peer_id { + continue + } + + if let Some((_, ban_end)) = self.banned_peers.iter().find(|(p, _)| p == peer_id) { + if *ban_end > Instant::now() { + continue + } + } + + num_to_open -= 1; + self.events.push(NetworkBehaviourAction::DialPeer { peer_id: peer_id.clone() }); + } + + // Next round is when we expect the topology will change. + self.next_connect_to_nodes.reset(will_change); + } +} + +impl NetworkBehaviour for CustomProtos +where + TSubstream: AsyncRead + AsyncWrite, +{ + type ProtocolsHandler = CustomProtosHandler; + type OutEvent = CustomProtosOut; + + fn new_handler(&mut self) -> Self::ProtocolsHandler { + CustomProtosHandler::new(self.registered_protocols.clone()) + } + + fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) { + // When a peer connects, its handler is initially in the disabled state. We make sure that + // the peer is allowed, and if so we put it in the enabled state. + + let is_reserved = self.reserved_peers.contains(&peer_id); + if self.reserved_only && !is_reserved { + debug!(target: "sub-libp2p", "Ignoring {:?} because we're in reserved mode", peer_id); + return + } + + // Check whether peer is banned. + if !is_reserved { + if let Some((_, expire)) = self.banned_peers.iter().find(|(p, _)| p == &peer_id) { + if *expire >= Instant::now() { + debug!(target: "sub-libp2p", "Ignoring banned peer {:?}", peer_id); + return + } + } + } + + // Check the limits on the ingoing and outgoing connections. + match endpoint { + ConnectedPoint::Dialer { .. } => { + let num_outgoing = self.enabled_peers.iter() + .filter(|(_, e)| e.is_dialer()) + .filter(|(p, _)| !self.reserved_peers.contains(p)) + .count(); + + debug_assert!(num_outgoing <= self.max_outgoing_connections); + if num_outgoing == self.max_outgoing_connections { + return + } + } + ConnectedPoint::Listener { .. } => { + let num_ingoing = self.enabled_peers.iter() + .filter(|(_, e)| e.is_listener()) + .filter(|(p, _)| !self.reserved_peers.contains(p)) + .count(); + + debug_assert!(num_ingoing <= self.max_incoming_connections); + if num_ingoing == self.max_incoming_connections { + debug!(target: "sub-libp2p", "Ignoring incoming connection from {:?} because \ + we're full", peer_id); + return + } + } + } + + // If everything is fine, enable the node. + debug_assert!(!self.enabled_peers.contains_key(&peer_id)); + // We ask the handler to actively open substreams only if we are the dialer; otherwise + // the two nodes will race to be the first to open the unique allowed substream. + if endpoint.is_dialer() { + trace!(target: "sub-libp2p", "Enabling custom protocols with {:?} (active)", peer_id); + self.events.push(NetworkBehaviourAction::SendEvent { + peer_id: peer_id.clone(), + event: CustomProtosHandlerIn::EnableActive, + }); + } else { + trace!(target: "sub-libp2p", "Enabling custom protocols with {:?} (passive)", peer_id); + self.events.push(NetworkBehaviourAction::SendEvent { + peer_id: peer_id.clone(), + event: CustomProtosHandlerIn::EnablePassive, + }); + } + + self.enabled_peers.insert(peer_id, endpoint); + } + + fn inject_disconnected(&mut self, peer_id: &PeerId, _: ConnectedPoint) { + while let Some(pos) = self.open_protocols.iter().position(|(p, _)| p == peer_id) { + let (_, protocol_id) = self.open_protocols.remove(pos); + + let event = CustomProtosOut::CustomProtocolClosed { + protocol_id, + peer_id: peer_id.clone(), + result: Ok(()), + }; + + self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + + // Trigger a `connect_to_nodes` round. + self.next_connect_to_nodes = Delay::new(Instant::now()); + } + + self.enabled_peers.remove(peer_id); + } + + fn inject_node_event( + &mut self, + source: PeerId, + event: ::OutEvent, + ) { + match event { + CustomProtosHandlerOut::CustomProtocolClosed { protocol_id, result } => { + let pos = self.open_protocols.iter().position(|(s, p)| + s == &source && p == &protocol_id + ); + + if let Some(pos) = pos { + self.open_protocols.remove(pos); + } else { + debug_assert!(false, "Couldn't find protocol in open_protocols"); + } + + let event = CustomProtosOut::CustomProtocolClosed { + protocol_id, + result, + peer_id: source, + }; + + self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + } + CustomProtosHandlerOut::CustomProtocolOpen { protocol_id, version } => { + debug_assert!(!self.open_protocols.iter().any(|(s, p)| + s == &source && p == &protocol_id + )); + self.open_protocols.push((source.clone(), protocol_id)); + + if let Some(address) = self.enabled_peers.get(&source) { + let event = CustomProtosOut::CustomProtocolOpen { + protocol_id, + version, + peer_id: source, + endpoint: address.clone() + }; + + self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + } + } + CustomProtosHandlerOut::CustomMessage { protocol_id, data } => { + let event = CustomProtosOut::CustomMessage { + peer_id: source, + protocol_id, + data, + }; + + self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + } + } + } + + fn poll( + &mut self, + params: &mut PollParameters, + ) -> Async< + NetworkBehaviourAction< + ::InEvent, + Self::OutEvent, + >, + > { + loop { + match self.next_connect_to_nodes.poll() { + Ok(Async::Ready(())) => self.connect_to_nodes(params), + Ok(Async::NotReady) => break, + Err(err) => { + warn!(target: "sub-libp2p", "Connect-to-nodes timer errored: {:?}", err); + break + } + } + } + + // Clean up `banned_peers` + self.banned_peers.retain(|(_, end)| *end < Instant::now()); + self.banned_peers.shrink_to_fit(); + + if !self.events.is_empty() { + return Async::Ready(self.events.remove(0)) + } + + Async::NotReady + } +} diff --git a/core/network-libp2p/src/custom_proto/handler.rs b/core/network-libp2p/src/custom_proto/handler.rs new file mode 100644 index 0000000000000000000000000000000000000000..45a9a6f273729de1e862dbfc66369740d388a46d --- /dev/null +++ b/core/network-libp2p/src/custom_proto/handler.rs @@ -0,0 +1,328 @@ +// 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 . + +use crate::ProtocolId; +use crate::custom_proto::upgrade::{RegisteredProtocol, RegisteredProtocols, RegisteredProtocolSubstream}; +use bytes::Bytes; +use futures::prelude::*; +use libp2p::core::{ + Endpoint, ProtocolsHandler, ProtocolsHandlerEvent, + protocols_handler::ProtocolsHandlerUpgrErr, + upgrade::{InboundUpgrade, OutboundUpgrade} +}; +use log::{trace, warn}; +use smallvec::SmallVec; +use std::{fmt, io}; +use tokio_io::{AsyncRead, AsyncWrite}; +use void::Void; + +/// Protocol handler that tries to maintain one substream per registered custom protocol. +/// +/// The handler initially starts in the "Disable" state. It can then be enabled by sending an +/// `Enable` message. +/// The handler can then be enabled and disabled at any time with the `Enable` and `Disable` +/// messages. +pub struct CustomProtosHandler { + /// List of all the protocols we support. + protocols: RegisteredProtocols, + + /// See the documentation of `State`. + state: State, + + /// The active substreams. There should always ever be only one substream per protocol. + substreams: SmallVec<[RegisteredProtocolSubstream; 6]>, + + /// Queue of events to send to the outside. + events_queue: SmallVec<[ProtocolsHandlerEvent; 16]>, +} + +/// State of the handler. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +enum State { + /// Normal functionning. + Normal, + + /// We are disabled. We close existing substreams and refuse incoming connections, but don't + /// shut down the entire handler. + Disabled, + + /// We are trying to shut down the existing node and thus should refuse any incoming + /// connection. + ShuttingDown, +} + +/// Event that can be received by a `CustomProtosHandler`. +#[derive(Debug)] +pub enum CustomProtosHandlerIn { + /// The node should start using custom protocols and actively open substreams. + EnableActive, + + /// The node should listen to custom protocols but not open substreams. + EnablePassive, + + /// The node should stop using custom protocols. + Disable, + + /// Sends a message through a custom protocol substream. + SendCustomMessage { + /// The protocol to use. + protocol: ProtocolId, + /// The data to send. + data: Bytes, + }, +} + +/// Event that can be emitted by a `CustomProtosHandler`. +#[derive(Debug)] +pub enum CustomProtosHandlerOut { + /// Opened a custom protocol with the remote. + CustomProtocolOpen { + /// Identifier of the protocol. + protocol_id: ProtocolId, + /// Version of the protocol that has been opened. + version: u8, + }, + + /// Closed a custom protocol with the remote. + CustomProtocolClosed { + /// Identifier of the protocol. + protocol_id: ProtocolId, + /// Reason why the substream closed. If `Ok`, then it's a graceful exit (EOF). + result: io::Result<()>, + }, + + /// Receives a message on a custom protocol substream. + CustomMessage { + /// Protocol which generated the message. + protocol_id: ProtocolId, + /// Data that has been received. + data: Bytes, + }, +} + +impl CustomProtosHandler +where + TSubstream: AsyncRead + AsyncWrite, +{ + /// Builds a new `CustomProtosHandler`. + pub fn new(protocols: RegisteredProtocols) -> Self { + CustomProtosHandler { + protocols, + state: State::Disabled, + substreams: SmallVec::new(), + events_queue: SmallVec::new(), + } + } + + /// Called by `inject_fully_negotiated_inbound` and `inject_fully_negotiated_outbound`. + fn inject_fully_negotiated( + &mut self, + proto: RegisteredProtocolSubstream, + _: Endpoint, + ) { + match self.state { + State::Disabled | State::ShuttingDown => return, + State::Normal => () + } + + if self.substreams.iter().any(|p| p.protocol_id() == proto.protocol_id()) { + // Skipping protocol that's already open. + return + } + + let event = CustomProtosHandlerOut::CustomProtocolOpen { + protocol_id: proto.protocol_id(), + version: proto.protocol_version(), + }; + + self.substreams.push(proto); + self.events_queue.push(ProtocolsHandlerEvent::Custom(event)); + } +} + +impl ProtocolsHandler for CustomProtosHandler +where + TSubstream: AsyncRead + AsyncWrite, +{ + type InEvent = CustomProtosHandlerIn; + type OutEvent = CustomProtosHandlerOut; + type Substream = TSubstream; + type Error = Void; + type InboundProtocol = RegisteredProtocols; + type OutboundProtocol = RegisteredProtocol; + type OutboundOpenInfo = (); + + #[inline] + fn listen_protocol(&self) -> Self::InboundProtocol { + self.protocols.clone() + } + + fn inject_fully_negotiated_inbound( + &mut self, + proto: >::Output + ) { + self.inject_fully_negotiated(proto, Endpoint::Listener); + } + + #[inline] + fn inject_fully_negotiated_outbound( + &mut self, + proto: >::Output, + _: Self::OutboundOpenInfo + ) { + self.inject_fully_negotiated(proto, Endpoint::Dialer); + } + + fn inject_event(&mut self, message: CustomProtosHandlerIn) { + match message { + CustomProtosHandlerIn::Disable => { + match self.state { + State::Normal => self.state = State::Disabled, + State::Disabled | State::ShuttingDown => (), + } + + for substream in self.substreams.iter_mut() { + substream.shutdown(); + } + }, + CustomProtosHandlerIn::EnableActive | CustomProtosHandlerIn::EnablePassive => { + match self.state { + State::Disabled => self.state = State::Normal, + State::Normal | State::ShuttingDown => (), + } + + // Try open one substream for each registered protocol. + if let CustomProtosHandlerIn::EnableActive = message { + for protocol in self.protocols.0.iter() { + if self.substreams.iter().any(|p| p.protocol_id() == protocol.id()) { + // Skipping protocol that's already open. + continue + } + + self.events_queue.push(ProtocolsHandlerEvent::OutboundSubstreamRequest { + upgrade: protocol.clone(), + info: (), + }); + } + } + }, + CustomProtosHandlerIn::SendCustomMessage { protocol, data } => { + debug_assert!(self.protocols.has_protocol(protocol), + "invalid protocol id requested in the API of the libp2p networking"); + let proto = match self.substreams.iter_mut().find(|p| p.protocol_id() == protocol) { + Some(proto) => proto, + None => { + // We are processing a message event before we could report to the outside + // that we disconnected from the protocol. This is not an error. + trace!(target: "sub-libp2p", "Tried to send message through closed \ + protocol"); + return + }, + }; + + proto.send_message(data); + }, + } + } + + #[inline] + fn inject_inbound_closed(&mut self) {} + + #[inline] + fn inject_dial_upgrade_error(&mut self, _: Self::OutboundOpenInfo, err: ProtocolsHandlerUpgrErr) { + warn!(target: "sub-libp2p", "Error while opening custom protocol: {:?}", err); + } + + #[inline] + fn connection_keep_alive(&self) -> bool { + // Right now if the remote doesn't support one of the custom protocols, we shut down the + // entire connection. This is a hack-ish solution to the problem where we connect to nodes + // that support libp2p but not the testnet that we want. + self.substreams.len() == self.protocols.len() + } + + fn shutdown(&mut self) { + match self.state { + State::Normal | State::Disabled => self.state = State::ShuttingDown, + State::ShuttingDown => (), + } + + for substream in self.substreams.iter_mut() { + substream.shutdown(); + } + } + + fn poll( + &mut self, + ) -> Poll< + ProtocolsHandlerEvent, + Self::Error, + > { + if !self.events_queue.is_empty() { + let event = self.events_queue.remove(0); + return Ok(Async::Ready(event)) + } + + if self.state == State::ShuttingDown && self.substreams.is_empty() { + return Ok(Async::Ready(ProtocolsHandlerEvent::Shutdown)) + } + + for n in (0..self.substreams.len()).rev() { + let mut substream = self.substreams.swap_remove(n); + match substream.poll() { + Ok(Async::Ready(Some(data))) => { + let event = CustomProtosHandlerOut::CustomMessage { + protocol_id: substream.protocol_id(), + data + }; + self.substreams.push(substream); + return Ok(Async::Ready(ProtocolsHandlerEvent::Custom(event))) + }, + Ok(Async::NotReady) => + self.substreams.push(substream), + Ok(Async::Ready(None)) => { + let event = CustomProtosHandlerOut::CustomProtocolClosed { + protocol_id: substream.protocol_id(), + result: Ok(()) + }; + return Ok(Async::Ready(ProtocolsHandlerEvent::Custom(event))) + }, + Err(err) => { + let event = CustomProtosHandlerOut::CustomProtocolClosed { + protocol_id: substream.protocol_id(), + result: Err(err) + }; + return Ok(Async::Ready(ProtocolsHandlerEvent::Custom(event))) + }, + } + } + + Ok(Async::NotReady) + } +} + +impl fmt::Debug for CustomProtosHandler +where + TSubstream: AsyncRead + AsyncWrite, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + f.debug_struct("CustomProtosHandler") + .field("protocols", &self.protocols.len()) + .field("state", &self.state) + .field("substreams", &self.substreams.len()) + .finish() + } +} diff --git a/core/network-libp2p/src/custom_proto/mod.rs b/core/network-libp2p/src/custom_proto/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..f8b7e8edc5b2a059859a8655193cce433a9dd98a --- /dev/null +++ b/core/network-libp2p/src/custom_proto/mod.rs @@ -0,0 +1,22 @@ +// 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 . + +pub use self::behaviour::{CustomProtos, CustomProtosOut}; +pub use self::upgrade::{RegisteredProtocol, RegisteredProtocols}; + +mod behaviour; +mod handler; +mod upgrade; diff --git a/core/network-libp2p/src/custom_proto.rs b/core/network-libp2p/src/custom_proto/upgrade.rs similarity index 62% rename from core/network-libp2p/src/custom_proto.rs rename to core/network-libp2p/src/custom_proto/upgrade.rs index 863e2d68b33aafa0c16fc179bdc1179d5a800381..70eb517023b594d58aa74b6f658e20469a3a99ca 100644 --- a/core/network-libp2p/src/custom_proto.rs +++ b/core/network-libp2p/src/custom_proto/upgrade.rs @@ -14,14 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use crate::ProtocolId; use bytes::Bytes; -use libp2p::core::{ConnectionUpgrade, Endpoint}; +use libp2p::core::{UpgradeInfo, InboundUpgrade, OutboundUpgrade, upgrade::ProtocolName}; use libp2p::tokio_codec::Framed; +use log::debug; use std::{collections::VecDeque, io, vec::IntoIter as VecIntoIter}; -use futures::{prelude::*, future, stream, task}; +use futures::{prelude::*, future, stream}; use tokio_io::{AsyncRead, AsyncWrite}; use unsigned_varint::codec::UviBytes; -use ProtocolId; /// Connection upgrade for a single protocol. /// @@ -80,8 +81,6 @@ pub struct RegisteredProtocolSubstream { protocol_id: ProtocolId, /// Version of the protocol that was negotiated. protocol_version: u8, - /// Task to notify when something is changed and we need to be polled. - to_notify: Option, } impl RegisteredProtocolSubstream { @@ -105,25 +104,24 @@ impl RegisteredProtocolSubstream { /// After calling this, the stream is guaranteed to finish soon-ish. pub fn shutdown(&mut self) { self.is_closing = true; - if let Some(task) = self.to_notify.take() { - task.notify(); - } + self.send_queue.clear(); } /// Sends a message to the substream. pub fn send_message(&mut self, data: Bytes) { + if self.is_closing { + return + } + self.send_queue.push_back(data); // If the length of the queue goes over a certain arbitrary threshold, we print a warning. - // TODO: figure out a good threshold if self.send_queue.len() >= 2048 { - warn!(target: "sub-libp2p", "Queue of packets to send over substream is pretty \ + // TODO: this used to be a warning, but is now a `debug` in order to avoid too much + // noise in the logs; see https://github.com/paritytech/substrate/issues/1414 + debug!(target: "sub-libp2p", "Queue of packets to send over substream is pretty \ large: {}", self.send_queue.len()); } - - if let Some(task) = self.to_notify.take() { - task.notify(); - } } } @@ -136,7 +134,7 @@ where TSubstream: AsyncRead + AsyncWrite, fn poll(&mut self) -> Poll, Self::Error> { // If we are closing, close as soon as the Sink is closed. if self.is_closing { - return Ok(self.inner.close()?.map(|()| None)); + return Ok(self.inner.close()?.map(|()| None)) } // Flushing the local queue. @@ -144,7 +142,7 @@ where TSubstream: AsyncRead + AsyncWrite, match self.inner.start_send(packet)? { AsyncSink::NotReady(packet) => { self.send_queue.push_front(packet); - break; + break }, AsyncSink::Ready => self.requires_poll_complete = true, } @@ -159,51 +157,64 @@ where TSubstream: AsyncRead + AsyncWrite, // Receiving incoming packets. // Note that `inner` is wrapped in a `Fuse`, therefore we can poll it forever. - loop { - match self.inner.poll()? { - Async::Ready(Some(data)) => - return Ok(Async::Ready(Some(data.freeze()))), - Async::Ready(None) => - if !self.requires_poll_complete && self.send_queue.is_empty() { - return Ok(Async::Ready(None)) - } else { - break - }, - Async::NotReady => break, - } + match self.inner.poll()? { + Async::Ready(Some(data)) => Ok(Async::Ready(Some(data.freeze()))), + Async::Ready(None) => + if !self.requires_poll_complete && self.send_queue.is_empty() { + Ok(Async::Ready(None)) + } else { + Ok(Async::NotReady) + }, + Async::NotReady => Ok(Async::NotReady), } - - self.to_notify = Some(task::current()); - Ok(Async::NotReady) } } -impl ConnectionUpgrade for RegisteredProtocol -where TSubstream: AsyncRead + AsyncWrite, -{ - type NamesIter = VecIntoIter<(Bytes, Self::UpgradeIdentifier)>; - type UpgradeIdentifier = u8; // Protocol version +impl UpgradeInfo for RegisteredProtocol { + type Info = RegisteredProtocolName; + type InfoIter = VecIntoIter; #[inline] - fn protocol_names(&self) -> Self::NamesIter { + fn protocol_info(&self) -> Self::InfoIter { // Report each version as an individual protocol. - self.supported_versions.iter().map(|&ver| { - let num = ver.to_string(); + self.supported_versions.iter().map(|&version| { + let num = version.to_string(); let mut name = self.base_name.clone(); name.extend_from_slice(num.as_bytes()); - (name, ver) + RegisteredProtocolName { + name, + version, + } }).collect::>().into_iter() } +} +/// Implementation of `ProtocolName` for a custom protocol. +#[derive(Debug, Clone)] +pub struct RegisteredProtocolName { + /// Protocol name, as advertised on the wire. + name: Bytes, + /// Version number. Stored in string form in `name`, but duplicated here for easier retrieval. + version: u8, +} + +impl ProtocolName for RegisteredProtocolName { + fn protocol_name(&self) -> &[u8] { + &self.name + } +} + +impl InboundUpgrade for RegisteredProtocol +where TSubstream: AsyncRead + AsyncWrite, +{ type Output = RegisteredProtocolSubstream; type Future = future::FutureResult; + type Error = io::Error; - #[allow(deprecated)] - fn upgrade( + fn upgrade_inbound( self, socket: TSubstream, - protocol_version: Self::UpgradeIdentifier, - _: Endpoint + info: Self::Info, ) -> Self::Future { let framed = Framed::new(socket, UviBytes::default()); @@ -213,12 +224,28 @@ where TSubstream: AsyncRead + AsyncWrite, requires_poll_complete: false, inner: framed.fuse(), protocol_id: self.id, - protocol_version, - to_notify: None, + protocol_version: info.version, }) } } +impl OutboundUpgrade for RegisteredProtocol +where TSubstream: AsyncRead + AsyncWrite, +{ + type Output = >::Output; + type Future = >::Future; + type Error = >::Error; + + fn upgrade_outbound( + self, + socket: TSubstream, + info: Self::Info, + ) -> Self::Future { + // Upgrades are symmetrical. + self.upgrade_inbound(socket, info) + } +} + // Connection upgrade for all the protocols contained in it. #[derive(Clone)] pub struct RegisteredProtocols(pub Vec); @@ -230,12 +257,6 @@ impl RegisteredProtocols { self.0.len() } - /// Finds a protocol in the list by its id. - pub fn find_protocol(&self, protocol: ProtocolId) - -> Option<&RegisteredProtocol> { - self.0.iter().find(|p| p.id == protocol) - } - /// Returns true if the given protocol is in the list. pub fn has_protocol(&self, protocol: ProtocolId) -> bool { self.0.iter().any(|p| p.id == protocol) @@ -248,36 +269,75 @@ impl Default for RegisteredProtocols { } } -impl ConnectionUpgrade for RegisteredProtocols -where TSubstream: AsyncRead + AsyncWrite, -{ - type NamesIter = VecIntoIter<(Bytes, Self::UpgradeIdentifier)>; - type UpgradeIdentifier = (usize, - >::UpgradeIdentifier); +impl UpgradeInfo for RegisteredProtocols { + type Info = RegisteredProtocolsName; + type InfoIter = VecIntoIter; - fn protocol_names(&self) -> Self::NamesIter { + #[inline] + fn protocol_info(&self) -> Self::InfoIter { // We concat the lists of `RegisteredProtocol::protocol_names` for // each protocol. self.0.iter().enumerate().flat_map(|(n, proto)| - ConnectionUpgrade::::protocol_names(proto) - .map(move |(name, id)| (name, (n, id))) + UpgradeInfo::protocol_info(proto) + .map(move |inner| { + RegisteredProtocolsName { + inner, + index: n, + } + }) ).collect::>().into_iter() } +} - type Output = >::Output; - type Future = >::Future; +/// Implementation of `ProtocolName` for several custom protocols. +#[derive(Debug, Clone)] +pub struct RegisteredProtocolsName { + /// Inner registered protocol. + inner: RegisteredProtocolName, + /// Index of the protocol in the list of registered custom protocols. + index: usize, +} + +impl ProtocolName for RegisteredProtocolsName { + fn protocol_name(&self) -> &[u8] { + self.inner.protocol_name() + } +} + +impl InboundUpgrade for RegisteredProtocols +where TSubstream: AsyncRead + AsyncWrite, +{ + type Output = >::Output; + type Future = >::Future; + type Error = io::Error; #[inline] - fn upgrade( + fn upgrade_inbound( self, socket: TSubstream, - upgrade_identifier: Self::UpgradeIdentifier, - endpoint: Endpoint + info: Self::Info, ) -> Self::Future { - let (protocol_index, inner_proto_id) = upgrade_identifier; self.0.into_iter() - .nth(protocol_index) + .nth(info.index) .expect("invalid protocol index ; programmer logic error") - .upgrade(socket, inner_proto_id, endpoint) + .upgrade_inbound(socket, info.inner) + } +} + +impl OutboundUpgrade for RegisteredProtocols +where TSubstream: AsyncRead + AsyncWrite, +{ + type Output = >::Output; + type Future = >::Future; + type Error = >::Error; + + #[inline] + fn upgrade_outbound( + self, + socket: TSubstream, + info: Self::Info, + ) -> Self::Future { + // Upgrades are symmetrical. + self.upgrade_inbound(socket, info) } } diff --git a/core/network-libp2p/src/error.rs b/core/network-libp2p/src/error.rs index 9de1b9d43fee0c2af2fd75c16a53ed3cdd94fa0e..5466ce2a26966b9abba7abdd39735e229a38d1b3 100644 --- a/core/network-libp2p/src/error.rs +++ b/core/network-libp2p/src/error.rs @@ -14,12 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use error_chain::*; use std::{io, net, fmt}; -use libc::{ENFILE, EMFILE}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum DisconnectReason -{ +pub enum DisconnectReason { DisconnectRequested, TCPError, BadProtocol, @@ -135,18 +134,6 @@ error_chain! { display("Packet is too large"), } - #[doc = "Reached system resource limits for this process"] - ProcessTooManyFiles { - description("Too many open files in process."), - display("Too many open files in this process. Check your resource limits and restart parity"), - } - - #[doc = "Reached system wide resource limits"] - SystemTooManyFiles { - description("Too many open files on system."), - display("Too many open files on system. Consider closing some processes/release some file handlers or increas the system-wide resource limits and restart parity."), - } - #[doc = "An unknown IO error occurred."] Io(err: io::Error) { description("IO Error"), @@ -157,15 +144,10 @@ error_chain! { impl From for Error { fn from(err: io::Error) -> Self { - match err.raw_os_error() { - Some(ENFILE) => ErrorKind::ProcessTooManyFiles.into(), - Some(EMFILE) => ErrorKind::SystemTooManyFiles.into(), - _ => Error::from_kind(ErrorKind::Io(err)) - } + Error::from_kind(ErrorKind::Io(err)) } } - impl From for Error { fn from(_err: net::AddrParseError) -> Self { ErrorKind::AddressParse.into() } } @@ -179,26 +161,3 @@ fn test_errors() { } assert_eq!(DisconnectReason::Unknown, r); } - -#[test] -fn test_io_errors() { - use libc::{EMFILE, ENFILE}; - - assert_matches!( - >::from( - io::Error::from_raw_os_error(ENFILE) - ).kind(), - ErrorKind::ProcessTooManyFiles); - - assert_matches!( - >::from( - io::Error::from_raw_os_error(EMFILE) - ).kind(), - ErrorKind::SystemTooManyFiles); - - assert_matches!( - >::from( - io::Error::from_raw_os_error(0) - ).kind(), - ErrorKind::Io(_)); -} diff --git a/core/network-libp2p/src/lib.rs b/core/network-libp2p/src/lib.rs index 9d53b01b01e925b4a23338eb1a6a086c8885fc3b..5204e38949b1ed24dee64ab3e06ecebea1223f29 100644 --- a/core/network-libp2p/src/lib.rs +++ b/core/network-libp2p/src/lib.rs @@ -14,51 +14,24 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] -//! TODO: Missing doc -// end::description[] - -#![recursion_limit="128"] -#![type_length_limit = "268435456"] - -extern crate parking_lot; -extern crate fnv; -extern crate futures; -extern crate tokio; -extern crate tokio_io; -extern crate tokio_timer; -extern crate libc; -#[macro_use] -extern crate libp2p; -extern crate rand; -#[macro_use] -extern crate serde_derive; -extern crate serde_json; -extern crate bytes; -extern crate unsigned_varint; - -#[macro_use] -extern crate error_chain; -#[macro_use] -extern crate log; -#[cfg(test)] #[macro_use] -extern crate assert_matches; +//! Networking layer of Substrate. +mod behaviour; mod custom_proto; mod error; -mod node_handler; mod secret; mod service_task; -mod swarm; mod topology; mod traits; mod transport; -pub use custom_proto::RegisteredProtocol; -pub use error::{Error, ErrorKind, DisconnectReason}; -pub use libp2p::{Multiaddr, multiaddr::Protocol, PeerId}; -pub use service_task::{start_service, Service, ServiceEvent}; -pub use traits::*; // TODO: expand to actual items +pub use crate::custom_proto::RegisteredProtocol; +pub use crate::error::{Error, ErrorKind, DisconnectReason}; +pub use crate::secret::obtain_private_key; +pub use crate::service_task::{start_service, Service, ServiceEvent}; +pub use crate::traits::{NetworkConfiguration, NodeIndex, NodeId, NonReservedPeerMode}; +pub use crate::traits::{ProtocolId, Secret, Severity}; +pub use libp2p::{Multiaddr, multiaddr::{Protocol}, multiaddr, PeerId, core::PublicKey}; /// Check if node url is valid pub fn validate_node_url(url: &str) -> Result<(), Error> { diff --git a/core/network-libp2p/src/node_handler.rs b/core/network-libp2p/src/node_handler.rs deleted file mode 100644 index ad1f4b7504a6288b689110c8edaf3d931dabb1ce..0000000000000000000000000000000000000000 --- a/core/network-libp2p/src/node_handler.rs +++ /dev/null @@ -1,863 +0,0 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU 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 bytes::Bytes; -use custom_proto::{RegisteredProtocols, RegisteredProtocolSubstream}; -use futures::{prelude::*, task}; -use libp2p::core::{ConnectionUpgrade, Endpoint, PeerId, PublicKey, upgrade}; -use libp2p::core::nodes::handled_node::{NodeHandler, NodeHandlerEndpoint, NodeHandlerEvent}; -use libp2p::kad::{KadConnecConfig, KadFindNodeRespond, KadIncomingRequest, KadConnecController}; -use libp2p::{identify, ping}; -use parking_lot::Mutex; -use std::io::{Error as IoError, ErrorKind as IoErrorKind}; -use std::sync::Arc; -use std::time::{Duration, Instant}; -use tokio_io::{AsyncRead, AsyncWrite}; -use tokio_timer::{Delay, Interval}; -use {Multiaddr, ProtocolId}; - -/// Duration after which we consider that a ping failed. -const PING_TIMEOUT: Duration = Duration::from_secs(30); -/// After a ping succeeded, wait this long before the next ping. -const DELAY_TO_NEXT_PING: Duration = Duration::from_secs(15); -/// Period at which we identify the remote. -const PERIOD_IDENTIFY: Duration = Duration::from_secs(5 * 60); -/// Delay between the moment we connect and the first time we ping. -const DELAY_TO_FIRST_PING: Duration = Duration::from_secs(5); -/// Delay between the moment we connect and the first time we identify. -const DELAY_TO_FIRST_IDENTIFY: Duration = Duration::from_secs(2); - -/// This struct handles the open substreams of a specific node. -/// -/// It doesn't handle opening the substreams, but only what to do with substreams that have been -/// opened. -/// -/// The node will be pinged at a regular interval to determine whether it's still alive. We will -/// also regularly query the remote for identification information, for statistics purposes. -pub struct SubstrateNodeHandler { - /// List of registered custom protocols. - registered_custom: Arc, - /// Substreams open for "custom" protocols (eg. dot). - custom_protocols_substreams: Vec>, - - /// Substream open for Kademlia, if any. - kademlia_substream: Option<(KadConnecController, Box + Send>)>, - /// If true, we need to send back a `KadOpen` event on the stream (if Kademlia is open). - need_report_kad_open: bool, - - /// Substream open for sending pings, if any. - ping_out_substream: Option>, - /// Active pinging attempt with the moment it expires. - active_ping_out: Option, - /// Substreams open for receiving pings. - ping_in_substreams: Vec>, - /// Future that fires when we need to ping the node again. - /// - /// Every time we receive a pong, we reset the timer to the next time. - next_ping: Delay, - - /// Substreams for sending back our identify info to the remote. - /// - /// This is in an `Arc` in order to avoid borrowing issues with the future. - identify_send_back: Arc + Send>>>>, - /// Stream that fires when we need to identify the node again. - next_identify: Interval, - - /// Substreams being upgraded on the listening side. - upgrades_in_progress_listen: Vec, Error = IoError> + Send>>, - /// Substreams being upgraded on the dialing side. Contrary to `upgrades_in_progress_listen`, - /// these have a known purpose. - upgrades_in_progress_dial: Vec<(UpgradePurpose, Box, Error = IoError> + Send>)>, - /// The substreams we want to open. - queued_dial_upgrades: Vec, - /// Number of outbound substreams the outside should open for us. - num_out_user_must_open: usize, - - /// The node has started its shutdown process. - is_shutting_down: bool, - - /// Task to notify if we add an element to one of the lists from the public API. - to_notify: Option, -} - -/// Purpose of an upgrade in progress on the dialing side. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -enum UpgradePurpose { - Custom(ProtocolId), - Kad, - Identify, - Ping, -} - -/// Event that can happen on the `SubstrateNodeHandler`. -pub enum SubstrateOutEvent { - /// The node has been determined to be unresponsive. - Unresponsive, - - /// The node works but we can't do anything useful with it. - Useless, - - /// Started pinging the remote. This can be used to print a diagnostic message in the logs. - PingStart, - - /// The node has successfully responded to a ping. - PingSuccess(Duration), - - /// Opened a custom protocol with the remote. - CustomProtocolOpen { - /// Identifier of the protocol. - protocol_id: ProtocolId, - /// Version of the protocol that has been opened. - version: u8, - }, - - /// Closed a custom protocol with the remote. - CustomProtocolClosed { - /// Identifier of the protocol. - protocol_id: ProtocolId, - /// Reason why the substream closed. If `Ok`, then it's a graceful exit (EOF). - result: Result<(), IoError>, - }, - - /// Receives a message on a custom protocol substream. - CustomMessage { - /// Protocol which generated the message. - protocol_id: ProtocolId, - /// Data that has been received. - data: Bytes, - }, - - /// We obtained identification information from the remote - Identified { - /// Information of the remote. - info: identify::IdentifyInfo, - /// Address the remote observes us as. - observed_addr: Multiaddr, - }, - - /// The remote wants us to send back identification information. - /// - /// The `IdentificationRequest` object should be used to send the information. - IdentificationRequest(IdentificationRequest), - - /// Opened a Kademlia substream with the node. - KadOpen(KadConnecController), - - /// The remote wants us to answer a Kademlia `FIND_NODE` request. - /// - /// The `responder` should be used to answer that query. - // TODO: this API with the "responder" is bad, but changing it requires modifications in libp2p - KadFindNode { - /// The value being searched. - searched: PeerId, - /// Object to use to respond to the request. - responder: KadFindNodeRespond, - }, - - /// The Kademlia substream has been closed. - /// - /// The parameter contains the reason why it has been closed. `Ok` means that it's been closed - /// gracefully. - KadClosed(Result<(), IoError>), - - /// An error happened while upgrading a substream. - /// - /// This can be used to print a diagnostic message. - SubstreamUpgradeFail(IoError), -} - -/// The remote wants us to send back information. -pub struct IdentificationRequest { - /// Where to store the future that sends back the information. - identify_send_back: Arc + Send>>>>, - /// Object that sends back the information. - sender: identify::IdentifySender, - /// Protocol names that we support, to send back. - protocols: Vec, -} - -impl IdentificationRequest { - /// Responds to the request. - /// - /// - `local_key` must contain our local public key. - /// - `listen_addrs` must contain the list of addresses we're listening on (preferably after - /// NAT traversal). - /// - `remote_addr` must be the address of the remote from our local point of view. - /// - pub fn respond( - self, - local_key: PublicKey, - listen_addrs: Vec, - remote_addr: &Multiaddr - ) where TSubstream: AsyncRead + AsyncWrite + Send + 'static { - // TODO: what to return for `protocol_version` and `agent_version`? - let sender = self.sender.send( - identify::IdentifyInfo { - public_key: local_key, - protocol_version: concat!("substrate/", env!("CARGO_PKG_VERSION")).to_owned(), - agent_version: concat!("substrate/", env!("CARGO_PKG_VERSION")).to_owned(), - listen_addrs, - protocols: self.protocols, - }, - remote_addr - ); - - self.identify_send_back.lock().push(sender); - } -} - -/// Event that can be received by a `SubstrateNodeHandler`. -#[derive(Debug, Clone)] -pub enum SubstrateInEvent { - /// Before anything happens on the node, we wait for an `Accept` event. This is used to deny - /// nodes based on their peer ID. - Accept, - - /// Sends a message through a custom protocol substream. - SendCustomMessage { - protocol: ProtocolId, - data: Vec, - }, - - /// Requests to open a Kademlia substream. - // TODO: document better - OpenKademlia, -} - -/// Ideally we would have a method on `SubstrateNodeHandler` that builds this type, but in practice it's a -/// bit tedious to express, even with the `impl Trait` syntax. -/// Therefore we simply use a macro instead. -macro_rules! listener_upgrade { - ($self:expr) => ( - upgrade::or(upgrade::or(upgrade::or( - upgrade::map((*$self.registered_custom).clone(), move |c| FinalUpgrade::Custom(c)), - upgrade::map(KadConnecConfig::new(), move |(c, s)| FinalUpgrade::Kad(c, s))), - upgrade::map(ping::protocol::Ping::default(), move |p| FinalUpgrade::from(p))), - upgrade::map(identify::IdentifyProtocolConfig, move |i| FinalUpgrade::from(i))) - // TODO: meh for cloning a Vec here - ) -} - -impl SubstrateNodeHandler -where TSubstream: AsyncRead + AsyncWrite + Send + 'static, -{ - /// Creates a new node handler. - #[inline] - pub fn new(registered_custom: Arc) -> Self { - let registered_custom_len = registered_custom.len(); - let queued_dial_upgrades = registered_custom.0 - .iter() - .map(|proto| UpgradePurpose::Custom(proto.id())) - .collect(); - - SubstrateNodeHandler { - custom_protocols_substreams: Vec::with_capacity(registered_custom_len), - kademlia_substream: None, - need_report_kad_open: false, - identify_send_back: Arc::new(Mutex::new(Vec::with_capacity(1))), - ping_in_substreams: Vec::with_capacity(1), - ping_out_substream: None, - active_ping_out: None, - registered_custom, - upgrades_in_progress_listen: Vec::with_capacity(registered_custom_len + 3), - upgrades_in_progress_dial: Vec::with_capacity(registered_custom_len + 3), - next_ping: Delay::new(Instant::now() + DELAY_TO_FIRST_PING), - next_identify: Interval::new(Instant::now() + DELAY_TO_FIRST_IDENTIFY, PERIOD_IDENTIFY), - queued_dial_upgrades, - num_out_user_must_open: registered_custom_len, - is_shutting_down: false, - to_notify: None, - } - } -} - -impl NodeHandler for SubstrateNodeHandler -where TSubstream: AsyncRead + AsyncWrite + Send + 'static, -{ - type InEvent = SubstrateInEvent; - type OutEvent = SubstrateOutEvent; - type OutboundOpenInfo = (); - type Substream = TSubstream; - - fn inject_substream(&mut self, substream: TSubstream, endpoint: NodeHandlerEndpoint) { - // For listeners, propose all the possible upgrades. - if endpoint == NodeHandlerEndpoint::Listener { - let listener_upgrade = listener_upgrade!(self); - let upgrade = upgrade::apply(substream, listener_upgrade, Endpoint::Listener); - self.upgrades_in_progress_listen.push(Box::new(upgrade) as Box<_>); - // Since we pushed to `upgrades_in_progress_listen`, we have to notify the task. - if let Some(task) = self.to_notify.take() { - task.notify(); - } - return; - } - - // If we're the dialer, we have to decide which upgrade we want. - let purpose = if self.queued_dial_upgrades.is_empty() { - // Since we sometimes remove elements from `queued_dial_upgrades` before they succeed - // but after the outbound substream has started opening, it is possible that the queue - // is empty when we receive a substream. This is not an error. - // Example: we want to open a Kademlia substream, we start opening one, but in the - // meanwhile the remote opens a Kademlia substream. When we receive the new substream, - // we don't need it anymore. - return; - } else { - self.queued_dial_upgrades.remove(0) - }; - - match purpose { - UpgradePurpose::Custom(id) => { - let wanted = if let Some(proto) = self.registered_custom.find_protocol(id) { - // TODO: meh for cloning - upgrade::map(proto.clone(), move |c| FinalUpgrade::Custom(c)) - } else { - error!(target: "sub-libp2p", "Logic error: wrong custom protocol id for \ - opened substream"); - return; - }; - - let upgrade = upgrade::apply(substream, wanted, Endpoint::Dialer); - self.upgrades_in_progress_dial.push((purpose, Box::new(upgrade) as Box<_>)); - } - UpgradePurpose::Kad => { - let wanted = upgrade::map(KadConnecConfig::new(), move |(c, s)| FinalUpgrade::Kad(c, s)); - let upgrade = upgrade::apply(substream, wanted, Endpoint::Dialer); - self.upgrades_in_progress_dial.push((purpose, Box::new(upgrade) as Box<_>)); - } - UpgradePurpose::Identify => { - let wanted = upgrade::map(identify::IdentifyProtocolConfig, move |i| FinalUpgrade::from(i)); - let upgrade = upgrade::apply(substream, wanted, Endpoint::Dialer); - self.upgrades_in_progress_dial.push((purpose, Box::new(upgrade) as Box<_>)); - } - UpgradePurpose::Ping => { - let wanted = upgrade::map(ping::protocol::Ping::default(), move |p| FinalUpgrade::from(p)); - let upgrade = upgrade::apply(substream, wanted, Endpoint::Dialer); - self.upgrades_in_progress_dial.push((purpose, Box::new(upgrade) as Box<_>)); - } - }; - - // Since we pushed to `upgrades_in_progress_dial`, we have to notify the task. - if let Some(task) = self.to_notify.take() { - task.notify(); - } - } - - #[inline] - fn inject_inbound_closed(&mut self) { - } - - #[inline] - fn inject_outbound_closed(&mut self, _: Self::OutboundOpenInfo) { - } - - fn inject_event(&mut self, event: Self::InEvent) { - match event { - SubstrateInEvent::SendCustomMessage { protocol, data } => { - self.send_custom_message(protocol, data); - }, - SubstrateInEvent::OpenKademlia => self.open_kademlia(), - SubstrateInEvent::Accept => { - // TODO: implement - }, - } - } - - fn shutdown(&mut self) { - // TODO: close gracefully - self.is_shutting_down = true; - - for custom_proto in &mut self.custom_protocols_substreams { - custom_proto.shutdown(); - } - - if let Some(to_notify) = self.to_notify.take() { - to_notify.notify(); - } - } - - fn poll(&mut self) -> Poll>, IoError> { - if self.is_shutting_down { - // TODO: finish only when everything is closed - return Ok(Async::Ready(None)); - } - - match self.poll_upgrades_in_progress()? { - Async::Ready(value) => return Ok(Async::Ready(value.map(NodeHandlerEvent::Custom))), - Async::NotReady => (), - }; - - match self.poll_custom_protocols()? { - Async::Ready(value) => return Ok(Async::Ready(value.map(NodeHandlerEvent::Custom))), - Async::NotReady => (), - }; - - match self.poll_kademlia()? { - Async::Ready(value) => return Ok(Async::Ready(value.map(NodeHandlerEvent::Custom))), - Async::NotReady => (), - }; - - match self.poll_ping()? { - Async::Ready(value) => return Ok(Async::Ready(value.map(NodeHandlerEvent::Custom))), - Async::NotReady => (), - }; - - match self.poll_identify()? { - Async::Ready(value) => return Ok(Async::Ready(value.map(NodeHandlerEvent::Custom))), - Async::NotReady => (), - }; - - // Request new outbound substreams from the user if necessary. - if self.num_out_user_must_open >= 1 { - self.num_out_user_must_open -= 1; - return Ok(Async::Ready(Some(NodeHandlerEvent::OutboundSubstreamRequest(())))); - } - - // Nothing happened. Register our task to be notified and return. - self.to_notify = Some(task::current()); - Ok(Async::NotReady) - } -} - -impl SubstrateNodeHandler -where TSubstream: AsyncRead + AsyncWrite + Send + 'static, -{ - /// Sends a message on a custom protocol substream. - fn send_custom_message( - &mut self, - protocol: ProtocolId, - data: Vec, - ) { - debug_assert!(self.registered_custom.has_protocol(protocol), - "invalid protocol id requested in the API of the libp2p networking"); - let proto = match self.custom_protocols_substreams.iter_mut().find(|p| p.protocol_id() == protocol) { - Some(proto) => proto, - None => { - // We are processing a message event before we could report to the outside that - // we disconnected from the protocol. This is not an error. - return - }, - }; - - proto.send_message(data.into()); - } - - /// The node will try to open a Kademlia substream and produce a `KadOpen` event containing the - /// controller. If a Kademlia substream is already open, produces the event immediately. - fn open_kademlia(&mut self) { - if self.kademlia_substream.is_some() { - self.need_report_kad_open = true; - if let Some(to_notify) = self.to_notify.take() { - to_notify.notify(); - } - } else if self.has_upgrade_purpose(&UpgradePurpose::Kad) { - // We are currently upgrading a substream to Kademlia ; nothing more to do except wait. - } else { - // Opening a new substream for Kademlia. - self.queued_dial_upgrades.push(UpgradePurpose::Kad); - self.num_out_user_must_open += 1; - if let Some(to_notify) = self.to_notify.take() { - to_notify.notify(); - } - } - } - - /// Returns true if we are currently upgrading to the given protocol. - fn has_upgrade_purpose(&self, purpose: &UpgradePurpose) -> bool { - self.upgrades_in_progress_dial.iter().any(|&(ref p, _)| p == purpose) || - self.queued_dial_upgrades.iter().any(|p| p == purpose) - } - - /// Cancels a dialing upgrade in progress. - /// - /// Useful when the listener opened the protocol we wanted. - fn cancel_dial_upgrade(&mut self, purpose: &UpgradePurpose) { - self.upgrades_in_progress_dial.retain(|&(purp, _)| &purp != purpose); - self.queued_dial_upgrades.retain(|u| u != purpose); - } - - /// Returns the names of the protocols that we supporitt. - fn supported_protocol_names(&self) -> Vec { - let list = listener_upgrade!(self); - ConnectionUpgrade::::protocol_names(&list) - .filter_map(|(n, _)| String::from_utf8(n.to_vec()).ok()) - .collect() - } - - /// Inject a fully negotiated substream into the state. - /// - /// Optionally produces an event to dispatch. - fn inject_fully_negotiated( - &mut self, - upgrade: FinalUpgrade - ) -> Option> { - match upgrade { - FinalUpgrade::IdentifyListener(sender) => - Some(SubstrateOutEvent::IdentificationRequest(IdentificationRequest { - sender, - identify_send_back: self.identify_send_back.clone(), - protocols: self.supported_protocol_names(), - })), - FinalUpgrade::IdentifyDialer(info, observed_addr) => { - self.cancel_dial_upgrade(&UpgradePurpose::Identify); - Some(SubstrateOutEvent::Identified { info, observed_addr }) - }, - FinalUpgrade::PingDialer(ping_dialer) => { - self.cancel_dial_upgrade(&UpgradePurpose::Ping); - // We always open the ping substream for a reason, which is to immediately ping. - self.ping_out_substream = Some(ping_dialer); - self.active_ping_out = None; - if self.ping_remote() { - Some(SubstrateOutEvent::PingStart) - } else { - None - } - }, - FinalUpgrade::PingListener(ping_listener) => { - self.ping_in_substreams.push(ping_listener); - None - }, - FinalUpgrade::Kad(controller, stream) => { - // Remove all upgrades in the progress for Kademlia. - self.cancel_dial_upgrade(&UpgradePurpose::Kad); - // Refuse the substream if we already have Kademlia substream open. - if self.kademlia_substream.is_none() { - self.kademlia_substream = Some((controller.clone(), stream)); - Some(SubstrateOutEvent::KadOpen(controller)) - } else { - None - } - }, - FinalUpgrade::Custom(proto) => { - self.cancel_dial_upgrade(&UpgradePurpose::Custom(proto.protocol_id())); - if self.custom_protocols_substreams.iter().any(|p| p.protocol_id() == proto.protocol_id()) { - // Skipping protocol that's already open. - return None; - } - - let event = SubstrateOutEvent::CustomProtocolOpen { - protocol_id: proto.protocol_id(), - version: proto.protocol_version(), - }; - - self.custom_protocols_substreams.push(proto); - Some(event) - }, - } - } - - /// Start the process of identifying the remote. - fn identify_remote(&mut self) { - if !self.has_upgrade_purpose(&UpgradePurpose::Identify) { - self.queued_dial_upgrades.push(UpgradePurpose::Identify); - self.num_out_user_must_open += 1; - if let Some(to_notify) = self.to_notify.take() { - to_notify.notify(); - } - } - } - - /// Start the process of pinging the remote. - /// - /// Doesn't do anything if a ping attempt is already in progress. - /// - /// Returns true if this actually starts a ping, false is this just opens a substream or does - /// nothing. - fn ping_remote(&mut self) -> bool { - // Ignore if we are already actively pinging. - if self.active_ping_out.is_some() { - return false; - } - - // If we have a ping open, ping it! - if let Some(ref mut pinger) = self.ping_out_substream { - let now = Instant::now(); - pinger.ping(now); - let future = Delay::new(now + PING_TIMEOUT); - self.active_ping_out = Some(future); - if let Some(to_notify) = self.to_notify.take() { - to_notify.notify(); - } - return true; - } - - // Otherwise, ensure we have an upgrade for a ping substream in queue. - if !self.has_upgrade_purpose(&UpgradePurpose::Ping) { - self.queued_dial_upgrades.push(UpgradePurpose::Ping); - self.num_out_user_must_open += 1; - // We also start the unresponsiveness counter when opening the substream, as a - // peer may not respond to our opening request. - let future = Delay::new(Instant::now() + PING_TIMEOUT); - self.active_ping_out = Some(future); - if let Some(to_notify) = self.to_notify.take() { - to_notify.notify(); - } - } - - false - } - - /// Polls the upgrades in progress. - fn poll_upgrades_in_progress(&mut self) -> Poll>, IoError> { - // Continue negotiation of newly-opened substreams on the listening side. - // We remove each element from `upgrades_in_progress_listen` one by one and add them back - // if not ready. - for n in (0 .. self.upgrades_in_progress_listen.len()).rev() { - let mut in_progress = self.upgrades_in_progress_listen.swap_remove(n); - match in_progress.poll() { - Ok(Async::Ready(upgrade)) => { - if let Some(event) = self.inject_fully_negotiated(upgrade) { - return Ok(Async::Ready(Some(event))); - } - }, - Ok(Async::NotReady) => { - self.upgrades_in_progress_listen.push(in_progress); - }, - Err(err) => { - return Ok(Async::Ready(Some(SubstrateOutEvent::SubstreamUpgradeFail(err)))); - }, - } - } - - // Continue negotiation of newly-opened substreams. - // We remove each element from `upgrades_in_progress_dial` one by one and add them back if - // not ready. - for n in (0 .. self.upgrades_in_progress_dial.len()).rev() { - let (purpose, mut in_progress) = self.upgrades_in_progress_dial.swap_remove(n); - match in_progress.poll() { - Ok(Async::Ready(upgrade)) => { - if let Some(event) = self.inject_fully_negotiated(upgrade) { - return Ok(Async::Ready(Some(event))); - } - }, - Ok(Async::NotReady) => - self.upgrades_in_progress_dial.push((purpose, in_progress)), - Err(err) => { - // TODO: dispatch depending on actual error ; right now we assume that - // error == not supported, which is not necessarily true in theory - if let UpgradePurpose::Custom(_) = purpose { - return Ok(Async::Ready(Some(SubstrateOutEvent::Useless))); - } else { - let msg = format!("While upgrading to {:?}: {:?}", purpose, err); - let err = IoError::new(IoErrorKind::Other, msg); - return Ok(Async::Ready(Some(SubstrateOutEvent::SubstreamUpgradeFail(err)))); - } - }, - } - } - - Ok(Async::NotReady) - } - - /// Polls the upgrades in progress. - fn poll_custom_protocols(&mut self) -> Poll>, IoError> { - // Poll for messages on the custom protocol stream. - for n in (0 .. self.custom_protocols_substreams.len()).rev() { - let mut custom_proto = self.custom_protocols_substreams.swap_remove(n); - match custom_proto.poll() { - Ok(Async::NotReady) => self.custom_protocols_substreams.push(custom_proto), - Ok(Async::Ready(Some(data))) => { - let protocol_id = custom_proto.protocol_id(); - self.custom_protocols_substreams.push(custom_proto); - return Ok(Async::Ready(Some(SubstrateOutEvent::CustomMessage { - protocol_id, - data, - }))); - }, - Ok(Async::Ready(None)) => { - // Trying to reopen the protocol. - self.queued_dial_upgrades.push(UpgradePurpose::Custom(custom_proto.protocol_id())); - self.num_out_user_must_open += 1; - return Ok(Async::Ready(Some(SubstrateOutEvent::CustomProtocolClosed { - protocol_id: custom_proto.protocol_id(), - result: Ok(()), - }))) - }, - Err(err) => { - // Trying to reopen the protocol. - self.queued_dial_upgrades.push(UpgradePurpose::Custom(custom_proto.protocol_id())); - self.num_out_user_must_open += 1; - return Ok(Async::Ready(Some(SubstrateOutEvent::CustomProtocolClosed { - protocol_id: custom_proto.protocol_id(), - result: Err(err), - }))) - }, - } - } - - Ok(Async::NotReady) - } - - /// Polls the open Kademlia substream, if any. - fn poll_kademlia(&mut self) -> Poll>, IoError> { - // Produce a `KadOpen` event if necessary. - if self.need_report_kad_open { - self.need_report_kad_open = false; - if let Some((ref kad_ctrl, _)) = self.kademlia_substream { - return Ok(Async::Ready(Some(SubstrateOutEvent::KadOpen(kad_ctrl.clone())))); - } - } - - // Poll for Kademlia events. - if let Some((controller, mut stream)) = self.kademlia_substream.take() { - loop { - match stream.poll() { - Ok(Async::Ready(Some(KadIncomingRequest::FindNode { searched, responder }))) => { - self.kademlia_substream = Some((controller, stream)); - return Ok(Async::Ready(Some(SubstrateOutEvent::KadFindNode { searched, responder }))); - }, - // We don't care about Kademlia pings, they are unused. - Ok(Async::Ready(Some(KadIncomingRequest::PingPong))) => {}, - // Other Kademlia messages are unimplemented. - Ok(Async::Ready(Some(KadIncomingRequest::GetProviders { .. }))) => {}, - Ok(Async::Ready(Some(KadIncomingRequest::AddProvider { .. }))) => {}, - Ok(Async::NotReady) => { - self.kademlia_substream = Some((controller, stream)); - break; - }, - Ok(Async::Ready(None)) => return Ok(Async::Ready(Some(SubstrateOutEvent::KadClosed(Ok(()))))), - Err(err) => return Ok(Async::Ready(Some(SubstrateOutEvent::KadClosed(Err(err))))), - } - } - } - - Ok(Async::NotReady) - } - - /// Polls the ping substreams. - fn poll_ping(&mut self) -> Poll>, IoError> { - // Poll the future that fires when we need to ping the node again. - match self.next_ping.poll() { - Ok(Async::NotReady) => {}, - Ok(Async::Ready(())) => { - // We reset `next_ping` to a very long time in the future so that we can poll - // it again without having an accident. - self.next_ping.reset(Instant::now() + Duration::from_secs(5 * 60)); - if self.ping_remote() { - return Ok(Async::Ready(Some(SubstrateOutEvent::PingStart))); - } - }, - Err(err) => { - warn!(target: "sub-libp2p", "Ping timer errored: {:?}", err); - return Err(IoError::new(IoErrorKind::Other, err)); - } - } - - // Poll for answering pings. - for n in (0 .. self.ping_in_substreams.len()).rev() { - let mut ping = self.ping_in_substreams.swap_remove(n); - match ping.poll() { - Ok(Async::Ready(())) => {}, - Ok(Async::NotReady) => self.ping_in_substreams.push(ping), - Err(err) => warn!(target: "sub-libp2p", "Remote ping substream errored: {:?}", err), - } - } - - // Poll the ping substream. - if let Some(mut ping_dialer) = self.ping_out_substream.take() { - match ping_dialer.poll() { - Ok(Async::Ready(Some(started))) => { - self.active_ping_out = None; - self.next_ping.reset(Instant::now() + DELAY_TO_NEXT_PING); - return Ok(Async::Ready(Some(SubstrateOutEvent::PingSuccess(started.elapsed())))); - }, - Ok(Async::Ready(None)) => { - // Try re-open ping if it got closed. - self.queued_dial_upgrades.push(UpgradePurpose::Ping); - self.num_out_user_must_open += 1; - }, - Ok(Async::NotReady) => self.ping_out_substream = Some(ping_dialer), - Err(_) => {}, - } - } - - // Poll the active ping attempt. - if let Some(mut deadline) = self.active_ping_out.take() { - match deadline.poll() { - Ok(Async::Ready(())) => - return Ok(Async::Ready(Some(SubstrateOutEvent::Unresponsive))), - Ok(Async::NotReady) => self.active_ping_out = Some(deadline), - Err(err) => { - warn!(target: "sub-libp2p", "Active ping deadline errored: {:?}", err); - return Err(IoError::new(IoErrorKind::Other, err)); - }, - } - } - - Ok(Async::NotReady) - } - - /// Polls the identify substreams. - fn poll_identify(&mut self) -> Poll>, IoError> { - // Poll the future that fires when we need to identify the node again. - loop { - match self.next_identify.poll() { - Ok(Async::NotReady) => break, - Ok(Async::Ready(Some(_))) => self.identify_remote(), - Ok(Async::Ready(None)) => { - warn!(target: "sub-libp2p", "Identify timer closed unexpectedly"); - return Ok(Async::Ready(None)); - } - Err(err) => { - warn!(target: "sub-libp2p", "Identify timer errored: {:?}", err); - return Err(IoError::new(IoErrorKind::Other, err)); - } - } - } - - // Poll for sending identify information to the remote. - let mut identify_send_back = self.identify_send_back.lock(); - for n in (0 .. identify_send_back.len()).rev() { - let mut id_send_back = identify_send_back.swap_remove(n); - match id_send_back.poll() { - Ok(Async::Ready(())) => {}, - Ok(Async::NotReady) => identify_send_back.push(id_send_back), - Err(err) => warn!(target: "sub-libp2p", "Sending back identify info errored: {:?}", err), - } - } - - Ok(Async::NotReady) - } -} - -/// Enum of all the possible protocols our service handles. -enum FinalUpgrade { - Kad(KadConnecController, Box + Send>), - IdentifyListener(identify::IdentifySender), - IdentifyDialer(identify::IdentifyInfo, Multiaddr), - PingDialer(ping::protocol::PingDialer), - PingListener(ping::protocol::PingListener), - Custom(RegisteredProtocolSubstream), -} - -impl From> for FinalUpgrade { - fn from(out: ping::protocol::PingOutput) -> Self { - match out { - ping::protocol::PingOutput::Ponger(ponger) => FinalUpgrade::PingListener(ponger), - ping::protocol::PingOutput::Pinger(pinger) => FinalUpgrade::PingDialer(pinger), - } - } -} - -impl From> for FinalUpgrade { - fn from(out: identify::IdentifyOutput) -> Self { - match out { - identify::IdentifyOutput::RemoteInfo { info, observed_addr } => - FinalUpgrade::IdentifyDialer(info, observed_addr), - identify::IdentifyOutput::Sender { sender } => - FinalUpgrade::IdentifyListener(sender), - } - } -} diff --git a/core/network-libp2p/src/secret.rs b/core/network-libp2p/src/secret.rs index 26d800bdf919a90dd73ade34607c7adbf023cb08..e185dc1a7862f37304942e4af372b6f205a0e42a 100644 --- a/core/network-libp2p/src/secret.rs +++ b/core/network-libp2p/src/secret.rs @@ -14,18 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use crate::NetworkConfiguration; use libp2p::secio; -use rand::{self, Rng}; -use std::fs; +use log::{trace, warn}; +use rand::Rng; use std::io::{Error as IoError, ErrorKind as IoErrorKind, Read, Write}; -use std::path::Path; -use NetworkConfiguration; +use std::{fs, path::Path}; // File where the private key is stored. const SECRET_FILE: &str = "secret"; /// Obtains or generates the local private key using the configuration. -pub(crate) fn obtain_private_key( +pub fn obtain_private_key( config: &NetworkConfiguration ) -> Result { if let Some(ref secret) = config.use_secret { @@ -35,8 +35,6 @@ pub(crate) fn obtain_private_key( } else { if let Some(ref path) = config.net_config_path { - fs::create_dir_all(Path::new(path))?; - // Try fetch the key from a the file containing the secret. let secret_path = Path::new(path).join(SECRET_FILE); match load_private_key_from_file(&secret_path) { diff --git a/core/network-libp2p/src/service_task.rs b/core/network-libp2p/src/service_task.rs index e370a68c381eca5d6c18103aa85d6f33042805d6..64f2ead99be9aed48c82403d12ab266f979a7f63 100644 --- a/core/network-libp2p/src/service_task.rs +++ b/core/network-libp2p/src/service_task.rs @@ -14,35 +14,27 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use crate::{behaviour::Behaviour, behaviour::BehaviourOut, secret::obtain_private_key, transport}; +use crate::custom_proto::{RegisteredProtocol, RegisteredProtocols}; +use crate::topology::NetTopology; +use crate::{Error, NetworkConfiguration, NodeIndex, ProtocolId, parse_str_addr}; use bytes::Bytes; -use custom_proto::{RegisteredProtocol, RegisteredProtocols}; -use fnv::{FnvHashMap, FnvHashSet}; -use futures::{prelude::*, task, Stream}; -use futures::sync::{oneshot, mpsc}; -use libp2p::{Multiaddr, PeerId}; -use libp2p::core::{Endpoint, PublicKey}; +use fnv::FnvHashMap; +use futures::{prelude::*, Stream}; +use libp2p::{Multiaddr, PeerId, multiaddr}; +use libp2p::core::{Swarm, nodes::Substream, transport::boxed::Boxed, muxing::StreamMuxerBox}; use libp2p::core::nodes::ConnectedPoint; -use libp2p::kad::{KadSystem, KadSystemConfig, KadConnecController, KadPeer}; -use libp2p::kad::{KadConnectionType, KadQueryEvent}; -use parking_lot::Mutex; -use rand; -use secret::obtain_private_key; +use log::{debug, info, warn}; +use std::collections::hash_map::Entry; +use std::fs; use std::io::{Error as IoError, ErrorKind as IoErrorKind}; -use std::iter; use std::net::SocketAddr; use std::path::Path; -use std::sync::Arc; -use std::time::{Duration, Instant}; -use swarm::{self, Swarm, SwarmEvent}; -use topology::{DisconnectReason, NetTopology}; -use tokio_timer::{Delay, Interval}; -use {Error, ErrorKind, NetworkConfiguration, NodeIndex, parse_str_addr}; -use {NonReservedPeerMode, ProtocolId}; +use std::time::Duration; +use tokio_timer::Interval; // File where the network topology is stored. const NODES_FILE: &str = "nodes.json"; -// Duration during which a peer is disabled. -const PEER_DISABLE_DURATION: Duration = Duration::from_secs(5 * 60); /// Starts the substrate libp2p service. /// @@ -52,137 +44,100 @@ pub fn start_service( registered_custom: TProtos, ) -> Result where TProtos: IntoIterator { + + if let Some(ref path) = config.net_config_path { + fs::create_dir_all(Path::new(path))?; + } + // Private and public keys configuration. let local_private_key = obtain_private_key(&config)?; let local_public_key = local_private_key.to_public_key(); let local_peer_id = local_public_key.clone().into_peer_id(); - // Build the swarm. - let registered_custom = RegisteredProtocols(registered_custom.into_iter().collect()); - let mut swarm = swarm::start_swarm(registered_custom, local_private_key)?; - - // Listen on multiaddresses. - for addr in &config.listen_addresses { - match swarm.listen_on(addr.clone()) { - Ok(new_addr) => debug!(target: "sub-libp2p", "Libp2p listening on {}", new_addr), - Err(_) => { - warn!(target: "sub-libp2p", "Can't listen on {}, protocol not supported", addr); - return Err(ErrorKind::BadProtocol.into()) - }, - } - } - - // Register the external addresses provided by the user. - for addr in &config.public_addresses { - swarm.add_external_address(addr.clone()); - } - // Initialize the topology of the network. let mut topology = if let Some(ref path) = config.net_config_path { let path = Path::new(path).join(NODES_FILE); debug!(target: "sub-libp2p", "Initializing peer store for JSON file {:?}", path); - NetTopology::from_file(path) + NetTopology::from_file(local_public_key, path) } else { debug!(target: "sub-libp2p", "No peers file configured ; peers won't be saved"); - NetTopology::memory() + NetTopology::memory(local_public_key) + }; + + // Register the external addresses provided by the user as our own. + topology.add_external_addrs(config.public_addresses.clone().into_iter()); + + // Build the swarm. + let mut swarm = { + let registered_custom = RegisteredProtocols(registered_custom.into_iter().collect()); + let behaviour = Behaviour::new(&config, local_peer_id.clone(), registered_custom); + let transport = transport::build_transport(local_private_key); + Swarm::new(transport, behaviour, topology) }; - // Create the Kademlia system, containing the kbuckets. - let kad_system = KadSystem::without_init(KadSystemConfig { - parallelism: 3, - local_peer_id, - kbuckets_timeout: Duration::from_secs(600), - request_timeout: Duration::from_secs(10), - known_initial_peers: iter::empty(), - }); + // Listen on multiaddresses. + for addr in &config.listen_addresses { + match Swarm::listen_on(&mut swarm, addr.clone()) { + Ok(new_addr) => debug!(target: "sub-libp2p", "Libp2p listening on {}", new_addr), + Err(err) => warn!(target: "sub-libp2p", "Can't listen on {} because: {:?}", addr, err) + } + } // Add the bootstrap nodes to the topology and connect to them. for bootnode in config.boot_nodes.iter() { match parse_str_addr(bootnode) { Ok((peer_id, addr)) => { - topology.add_bootstrap_addr(&peer_id, addr.clone()); - kad_system.update_kbuckets(peer_id.clone()); - if let Err(_) = swarm.ensure_connection(peer_id, addr) { - warn!(target: "sub-libp2p", "Failed to dial boot node: {}", bootnode); - } + Swarm::topology_mut(&mut swarm).add_bootstrap_addr(&peer_id, addr.clone()); + Swarm::dial(&mut swarm, peer_id); }, Err(_) => { // If the format of the bootstrap node is not a multiaddr, try to parse it as // a `SocketAddr`. This corresponds to the format `IP:PORT`. - let addr = match bootnode.parse::() { + let addr = match bootnode.parse::() { Ok(SocketAddr::V4(socket)) => multiaddr![Ip4(*socket.ip()), Tcp(socket.port())], Ok(SocketAddr::V6(socket)) => multiaddr![Ip6(*socket.ip()), Tcp(socket.port())], _ => { warn!(target: "sub-libp2p", "Not a valid bootnode address: {}", bootnode); - continue; + continue } }; - debug!(target: "sub-libp2p", "Dialing {} with no peer id", addr); - if let Err(addr) = swarm.dial(addr) { - warn!(target: "sub-libp2p", "Bootstrap address not supported: {}", addr); + info!(target: "sub-libp2p", "Dialing {} with no peer id. Keep in mind that doing \ + so is vulnerable to man-in-the-middle attacks.", addr); + if let Err(addr) = Swarm::dial_addr(&mut swarm, addr) { + warn!(target: "sub-libp2p", "Bootstrap address not supported: {}", addr) } }, } } // Initialize the reserved peers. - let mut reserved_peers = FnvHashSet::default(); for reserved in config.reserved_nodes.iter() { - match parse_str_addr(reserved) { - Ok((peer_id, addr)) => { - reserved_peers.insert(peer_id.clone()); - topology.add_bootstrap_addr(&peer_id, addr.clone()); - if let Err(_) = swarm.ensure_connection(peer_id, addr) { - warn!(target: "sub-libp2p", "Failed to dial reserved node: {}", reserved); - } - }, - Err(_) => - // TODO: also handle the `IP:PORT` format ; however we need to somehow add the - // reserved ID to `reserved_peers` at some point - warn!(target: "sub-libp2p", "Not a valid reserved node address: {}", reserved), + if let Ok((peer_id, addr)) = parse_str_addr(reserved) { + Swarm::topology_mut(&mut swarm).add_bootstrap_addr(&peer_id, addr); + swarm.add_reserved_peer(peer_id.clone()); + Swarm::dial(&mut swarm, peer_id); + } else { + warn!(target: "sub-libp2p", "Not a valid reserved node address: {}", reserved); } } - debug!(target: "sub-libp2p", "Topology started with {} entries", topology.num_peers()); - - let (kad_new_ctrl_req_tx, kad_new_ctrl_req_rx) = mpsc::unbounded(); + debug!(target: "sub-libp2p", "Topology started with {} entries", + Swarm::topology_mut(&mut swarm).num_peers()); Ok(Service { swarm, - max_incoming_connections: config.in_peers as usize, - max_outgoing_connections: config.out_peers as usize, - topology, - nodes_addresses: Default::default(), - disabled_peers: Default::default(), - reserved_peers, - reserved_only: config.non_reserved_mode == NonReservedPeerMode::Deny, - kad_system, - kad_pending_ctrls: Default::default(), - kad_new_ctrl_req_tx, - kad_new_ctrl_req_rx, - kad_queries: Vec::with_capacity(1), - next_connect_to_nodes: Delay::new(Instant::now()), - next_kad_random_query: Interval::new(Instant::now() + Duration::from_secs(5), Duration::from_secs(45)), + nodes_info: Default::default(), + index_by_id: Default::default(), + next_node_id: 1, cleanup: Interval::new_interval(Duration::from_secs(60)), injected_events: Vec::new(), - to_notify: None, }) } /// Event produced by the service. +#[derive(Debug)] pub enum ServiceEvent { - /// Closed connection to a node. - /// - /// It is guaranteed that this node has been opened with a `NewNode` event beforehand. However - /// not all `ClosedCustomProtocol` events have been dispatched. - NodeClosed { - /// Index of the node. - node_index: NodeIndex, - /// List of custom protocols that were still open. - closed_custom_protocols: Vec, - }, - /// A custom protocol substream has been opened with a node. OpenedCustomProtocol { /// Index of the node. @@ -225,53 +180,16 @@ pub enum ServiceEvent { /// Network service. Must be polled regularly in order for the networking to work. pub struct Service { /// Stream of events of the swarm. - swarm: Swarm, - - /// Maximum number of incoming non-reserved connections, taken from the config. - max_incoming_connections: usize, - - /// Maximum number of outgoing non-reserved connections, taken from the config. - max_outgoing_connections: usize, - - /// For each node we're connected to, how we're connected to it. - nodes_addresses: FnvHashMap, + swarm: Swarm, Behaviour>, NetTopology>, - /// If true, only reserved peers can connect. - reserved_only: bool, + /// Information about all the nodes we're connected to. + nodes_info: FnvHashMap, - /// List of the IDs of the reserved peers. - reserved_peers: FnvHashSet, + /// Opposite of `nodes_info`. + index_by_id: FnvHashMap, - /// List of the IDs of disabled peers, and when the ban expires. - /// Purged at a regular interval. - disabled_peers: FnvHashMap, - - /// Topology of the network. - topology: NetTopology, - - /// Handles the Kademlia queries. - // TODO: put the kbuckets in the topology instead - kad_system: KadSystem, - - /// List of Kademlia controller we want to open. - /// - /// A clone of tihs `Arc` is stored in each Kademlia query stream. - // TODO: use a better container? - kad_pending_ctrls: Arc>>>>, - - /// Sender whenever we inserted an entry in `kad_pending_ctrls`, so that we can process it. - kad_new_ctrl_req_tx: mpsc::UnboundedSender, - /// Receiver side of `kad_new_ctrl_req_tx`. - kad_new_ctrl_req_rx: mpsc::UnboundedReceiver, - - /// Active Kademlia queries. - kad_queries: Vec>, Error = IoError> + Send>>, - - /// Future that will fire when we need to connect to new nodes. - next_connect_to_nodes: Delay, - - /// Stream that fires when we need to perform the next Kademlia query. - next_kad_random_query: Interval, + /// Next index to assign to a node. + next_node_id: NodeIndex, /// Stream that fires when we need to cleanup and flush the topology, and cleanup the disabled /// peers. @@ -279,102 +197,97 @@ pub struct Service { /// Events to produce on the Stream. injected_events: Vec, +} - /// Task to notify when elements are added to `injected_events`. - to_notify: Option, +/// Information about a node we're connected to. +#[derive(Debug)] +struct NodeInfo { + /// Hash of the public key of the node. + peer_id: PeerId, + /// How we're connected to the node. + endpoint: ConnectedPoint, + /// Version reported by the remote, or `None` if unknown. + client_version: Option, } impl Service { - /// Returns an iterator that produces the list of addresses we're listening on. + /// Returns an iterator that produces the list of addresses we're listening on. #[inline] pub fn listeners(&self) -> impl Iterator { - self.swarm.listeners() + Swarm::listeners(&self.swarm) } /// Returns the peer id of the local node. #[inline] pub fn peer_id(&self) -> &PeerId { - self.kad_system.local_peer_id() + Swarm::local_peer_id(&self.swarm) } /// Returns the list of all the peers we are connected to. #[inline] pub fn connected_peers<'a>(&'a self) -> impl Iterator + 'a { - self.nodes_addresses.keys().cloned() + self.nodes_info.keys().cloned() } /// Try to add a reserved peer. pub fn add_reserved_peer(&mut self, peer_id: PeerId, addr: Multiaddr) { - self.reserved_peers.insert(peer_id.clone()); - self.topology.add_bootstrap_addr(&peer_id, addr.clone()); - let _ = self.swarm.ensure_connection(peer_id, addr); + Swarm::topology_mut(&mut self.swarm).add_bootstrap_addr(&peer_id, addr); + self.swarm.add_reserved_peer(peer_id); } /// Try to remove a reserved peer. /// /// If we are in reserved mode and we were connected to a node with this peer ID, then this - /// method will disconnect it and return its index. - pub fn remove_reserved_peer(&mut self, peer_id: PeerId) -> Option { - self.reserved_peers.remove(&peer_id); - if self.reserved_only { - if let Some(node_index) = self.swarm.latest_node_by_peer_id(&peer_id) { - self.drop_node_inner(node_index, DisconnectReason::NoSlot, None); - return Some(node_index); - } - } - None + /// method will disconnect it. + pub fn remove_reserved_peer(&mut self, peer_id: PeerId) { + self.swarm.remove_reserved_peer(peer_id); } /// Start accepting all peers again if we weren't. + #[inline] pub fn accept_unreserved_peers(&mut self) { - if self.reserved_only { - self.reserved_only = false; - self.connect_to_nodes(); - } + self.swarm.accept_unreserved_peers(); } - /// Start refusing non-reserved nodes. Returns the list of nodes that have been disconnected. - pub fn deny_unreserved_peers(&mut self) -> Vec { - self.reserved_only = true; - - // Disconnect the nodes that are not reserved. - let to_disconnect: Vec = self.swarm - .nodes() - .filter(|&n| { - let peer_id = self.swarm.peer_id_of_node(n) - .expect("swarm.nodes() always returns valid node indices"); - !self.reserved_peers.contains(peer_id) - }) - .collect(); - - for &node_index in &to_disconnect { - self.drop_node_inner(node_index, DisconnectReason::NoSlot, None); - } - - to_disconnect + /// Start refusing non-reserved nodes. Disconnects the nodes that we are connected to that + /// aren't reserved. + pub fn deny_unreserved_peers(&mut self) { + self.swarm.deny_unreserved_peers(); } /// Returns the `PeerId` of a node. #[inline] pub fn peer_id_of_node(&self, node_index: NodeIndex) -> Option<&PeerId> { - self.swarm.peer_id_of_node(node_index) + self.nodes_info.get(&node_index).map(|info| &info.peer_id) } /// Returns the way we are connected to a node. #[inline] pub fn node_endpoint(&self, node_index: NodeIndex) -> Option<&ConnectedPoint> { - self.nodes_addresses.get(&node_index) + self.nodes_info.get(&node_index).map(|info| &info.endpoint) + } + + /// Returns the client version reported by a node. + pub fn node_client_version(&self, node_index: NodeIndex) -> Option<&str> { + self.nodes_info.get(&node_index) + .and_then(|info| info.client_version.as_ref().map(|s| &s[..])) } /// Sends a message to a peer using the custom protocol. - // TODO: report invalid node index or protocol? + /// + /// Has no effect if the connection to the node has been closed, or if the node index is + /// invalid. pub fn send_custom_message( &mut self, node_index: NodeIndex, protocol: ProtocolId, data: Vec ) { - self.swarm.send_custom_message(node_index, protocol, data) + if let Some(peer_id) = self.nodes_info.get(&node_index).map(|info| &info.peer_id) { + self.swarm.send_custom_message(peer_id, protocol, data); + } else { + warn!(target: "sub-libp2p", "Tried to send message to unknown node: {:}", node_index); + } } /// Disconnects a peer and bans it for a little while. @@ -382,11 +295,11 @@ impl Service { /// Same as `drop_node`, except that the same peer will not be able to reconnect later. #[inline] pub fn ban_node(&mut self, node_index: NodeIndex) { - if let Some(peer_id) = self.swarm.peer_id_of_node(node_index) { - info!(target: "sub-libp2p", "Banned {:?}", peer_id); + if let Some(info) = self.nodes_info.get(&node_index) { + info!(target: "sub-libp2p", "Banned {:?} (#{:?}, {:?}, {:?})", info.peer_id, + node_index, info.endpoint, info.client_version); + self.swarm.ban_node(info.peer_id.clone()); } - - self.drop_node_inner(node_index, DisconnectReason::Banned, Some(PEER_DISABLE_DURATION)); } /// Disconnects a peer. @@ -395,519 +308,81 @@ impl Service { /// Corresponding closing events will be generated once the closing actually happens. #[inline] pub fn drop_node(&mut self, node_index: NodeIndex) { - if let Some(peer_id) = self.swarm.peer_id_of_node(node_index) { - info!(target: "sub-libp2p", "Dropped {:?}", peer_id); - } - - self.drop_node_inner(node_index, DisconnectReason::Useless, None); - } - - /// Common implementation of `drop_node` and `ban_node`. - fn drop_node_inner( - &mut self, - node_index: NodeIndex, - reason: DisconnectReason, - disable_duration: Option - ) { - let peer_id = match self.swarm.peer_id_of_node(node_index) { - Some(pid) => pid.clone(), - None => return, // TODO: report? - }; - - // Kill the node from the swarm, and inject an event about it. - let closed_custom_protocols = self.swarm.drop_node(node_index) - .expect("we checked right above that node is valid"); - self.injected_events.push(ServiceEvent::NodeClosed { - node_index, - closed_custom_protocols, - }); - - if let Some(to_notify) = self.to_notify.take() { - to_notify.notify(); - } - - if let Some(ConnectedPoint::Dialer { address }) = self.nodes_addresses.remove(&node_index) { - self.topology.report_disconnected(&address, reason); - } - - if let Some(disable_duration) = disable_duration { - let timeout = Instant::now() + disable_duration; - self.disabled_peers.insert(peer_id, timeout); - } - - self.connect_to_nodes(); - } - - /// Counts the number of non-reserved ingoing connections. - fn num_ingoing_connections(&self) -> usize { - self.swarm.nodes() - .filter(|&i| self.swarm.node_endpoint(i) == Some(Endpoint::Listener) && - !self.reserved_peers.contains(&self.swarm.peer_id_of_node(i).unwrap())) - .count() - } - - /// Counts the number of non-reserved outgoing connections. - fn num_outgoing_connections(&self) -> usize { - self.swarm.nodes() - .filter(|&i| self.swarm.node_endpoint(i) == Some(Endpoint::Dialer) && - !self.reserved_peers.contains(&self.swarm.peer_id_of_node(i).unwrap())) - .count() - } - - /// Updates the attempted connections to nodes. - /// - /// Also updates `next_connect_to_nodes` with the earliest known moment when we need to - /// update connections again. - fn connect_to_nodes(&mut self) { - // Make sure we are connected or connecting to all the reserved nodes. - for reserved in self.reserved_peers.iter() { - let addrs = self.topology.addrs_of_peer(&reserved); - for (addr, _) in addrs { - let _ = self.swarm.ensure_connection(reserved.clone(), addr.clone()); - } - } - - // Counter of number of connections to open, decreased when we open one. - let mut num_to_open = self.max_outgoing_connections - self.num_outgoing_connections(); - - let (to_try, will_change) = self.topology.addrs_to_attempt(); - for (peer_id, addr) in to_try { - if num_to_open == 0 { - break; - } - - if peer_id == self.kad_system.local_peer_id() { - continue; - } - - if self.disabled_peers.contains_key(&peer_id) { - continue; - } - - // It is possible that we are connected to this peer, but the topology doesn't know - // about that because it is an incoming connection. - match self.swarm.ensure_connection(peer_id.clone(), addr.clone()) { - Ok(true) => (), - Ok(false) => num_to_open -= 1, - Err(_) => () - } - } - - self.next_connect_to_nodes.reset(will_change); - } - - /// Starts a random Kademlia query in order to fill the topology. - /// - /// Query the node IDs that are closest to a random ID. - /// Note that the randomness doesn't have to be secure, as this only influences which nodes we - /// end up being connected to. - fn perform_kad_random_query(&mut self) { - let random_key = PublicKey::Ed25519((0 .. 32) - .map(|_| -> u8 { rand::random() }).collect()); - let random_peer_id = random_key.into_peer_id(); - debug!(target: "sub-libp2p", "Start random Kademlia query for {:?}", random_peer_id); - - let kad_pending_ctrls = self.kad_pending_ctrls.clone(); - let kad_new_ctrl_req_tx = self.kad_new_ctrl_req_tx.clone(); - let stream = self.kad_system - .find_node(random_peer_id, move |who| { - let (tx, rx) = oneshot::channel(); - let mut kad_pending_ctrls = kad_pending_ctrls.lock(); - kad_pending_ctrls.entry(who.clone()).or_insert(Vec::new()).push(tx); - let _ = kad_new_ctrl_req_tx.unbounded_send(who.clone()); - rx.map_err(|_| IoError::new(IoErrorKind::Other, "Couldn't reach peer")) - }); - - self.kad_queries.push(Box::new(stream)); - } - - /// If a remote performs a `FIND_NODE` Kademlia request for `searched`, this function builds - /// the response to send back. - fn build_kademlia_response(&self, searched: &PeerId) -> Vec { - self.kad_system - .known_closest_peers(searched) - .map(|who| { - if who == *self.kad_system.local_peer_id() { - KadPeer { - node_id: who.clone(), - multiaddrs: self.swarm.external_addresses().cloned().collect(), - connection_ty: KadConnectionType::Connected, - } - } else { - let mut addrs = self.topology.addrs_of_peer(&who) - .map(|(a, c)| (a.clone(), c)) - .collect::>(); - let connected = addrs.iter().any(|&(_, conn)| conn); - // The Kademlia protocol of libp2p doesn't allow specifying which address is valid - // and which is outdated, therefore in order to stay honest towards the network - // we only report the addresses we're connected to if we're connected to any. - if connected { - addrs.retain(|&(_, connected)| connected); - } - - KadPeer { - node_id: who.clone(), - multiaddrs: addrs.into_iter().map(|(a, _)| a).collect(), - connection_ty: if connected { - KadConnectionType::Connected - } else { - KadConnectionType::NotConnected - }, - } - } - }) - // TODO: we really want to remove nodes with no multiaddress from - // the results, but a flaw in the Kad protocol of libp2p makes it - // impossible to return empty results ; therefore we must at least - // return ourselves - .filter(|p| p.node_id == *self.kad_system.local_peer_id() || !p.multiaddrs.is_empty()) - .take(20) - .collect::>() - } - - /// Adds a list of peers to the network topology. - fn add_discovered_peers(&mut self, list: impl IntoIterator) { - for peer in list { - let connected = match peer.connection_ty { - KadConnectionType::NotConnected => false, - KadConnectionType::Connected => true, - KadConnectionType::CanConnect => true, - KadConnectionType::CannotConnect => continue, - }; - - self.topology.add_kademlia_discovered_addrs( - &peer.node_id, - peer.multiaddrs.iter().map(|a| (a.clone(), connected)) - ); - } - - // Potentially connect to the newly-discovered nodes. - // TODO: only do so if the topology reports that something new has been added - self.connect_to_nodes(); - } - - /// Handles the swarm opening a connection to the given peer. - /// - /// > **Note**: Must be called from inside `poll()`, otherwise it will panic. - fn handle_connection( - &mut self, - node_index: NodeIndex, - peer_id: PeerId, - endpoint: ConnectedPoint - ) { - // Reject connections to our own node, which can happen if the DHT contains `127.0.0.1` - // for example. - if &peer_id == self.kad_system.local_peer_id() { - debug!(target: "sub-libp2p", "Rejected connection to/from ourself: {:?}", endpoint); - assert_eq!(self.swarm.drop_node(node_index), Ok(Vec::new())); - if let ConnectedPoint::Dialer { ref address } = endpoint { - self.topology.report_failed_to_connect(address); - } - return; - } - - // Reject non-reserved nodes if we're in reserved mode. - let is_reserved = self.reserved_peers.contains(&peer_id); - if self.reserved_only && !is_reserved { - debug!(target: "sub-libp2p", "Rejected non-reserved peer {:?}", peer_id); - assert_eq!(self.swarm.drop_node(node_index), Ok(Vec::new())); - if let ConnectedPoint::Dialer { ref address } = endpoint { - self.topology.report_failed_to_connect(address); - } - return; - } - - // Reject connections from disabled peers. - if let Some(expires) = self.disabled_peers.get(&peer_id) { - if expires > &Instant::now() { - info!(target: "sub-libp2p", "Rejected connection from disabled peer: {:?}", peer_id); - assert_eq!(self.swarm.drop_node(node_index), Ok(Vec::new())); - if let ConnectedPoint::Dialer { ref address } = endpoint { - self.topology.report_failed_to_connect(address); - } - return; - } - } - - match endpoint { - ConnectedPoint::Listener { ref listen_addr, ref send_back_addr } => { - if is_reserved || self.num_ingoing_connections() < self.max_incoming_connections { - debug!(target: "sub-libp2p", "Connected to {:?} through {} on listener {}", - peer_id, send_back_addr, listen_addr); - } else { - info!(target: "sub-libp2p", "Rejected incoming peer {:?} because we are full", peer_id); - assert_eq!(self.swarm.drop_node(node_index), Ok(Vec::new())); - return; - } + if let Some(info) = self.nodes_info.get(&node_index) { + debug!(target: "sub-libp2p", "Dropping {:?} on purpose (#{:?}, {:?}, {:?})", + info.peer_id, node_index, info.endpoint, info.client_version); + self.swarm.drop_node(&info.peer_id); + } + } + + /// Returns the `NodeIndex` of a peer, or assigns one if none exists. + fn index_of_peer_or_assign(&mut self, peer: PeerId, endpoint: ConnectedPoint) -> NodeIndex { + match self.index_by_id.entry(peer) { + Entry::Occupied(entry) => { + let id = *entry.get(); + self.nodes_info.insert(id, NodeInfo { + peer_id: entry.key().clone(), + endpoint, + client_version: None, + }); + id }, - ConnectedPoint::Dialer { ref address } => { - if is_reserved || self.num_outgoing_connections() < self.max_outgoing_connections { - debug!(target: "sub-libp2p", "Connected to {:?} through {}", peer_id, address); - self.topology.report_connected(address, &peer_id); - } else { - debug!(target: "sub-libp2p", "Rejected dialed peer {:?} because we are full", peer_id); - assert_eq!(self.swarm.drop_node(node_index), Ok(Vec::new())); - return; - } + Entry::Vacant(entry) => { + let id = self.next_node_id; + self.next_node_id += 1; + self.nodes_info.insert(id, NodeInfo { + peer_id: entry.key().clone(), + endpoint, + client_version: None, + }); + entry.insert(id); + id }, - }; - - if let Err(_) = self.swarm.accept_node(node_index) { - error!(target: "sub-libp2p", "accept_node returned an error"); - } - - // We are finally sure that we're connected. - - if let ConnectedPoint::Dialer { ref address } = endpoint { - self.topology.report_connected(address, &peer_id); - } - self.nodes_addresses.insert(node_index, endpoint.clone()); - - // If we're waiting for a Kademlia substream for this peer id, open one. - let kad_pending_ctrls = self.kad_pending_ctrls.lock(); - if kad_pending_ctrls.contains_key(&peer_id) { - let res = self.swarm.open_kademlia(node_index); - debug_assert!(res.is_ok()); } } - /// Processes an event received by the swarm. - /// - /// Optionally returns an event to report back to the outside. - /// - /// > **Note**: Must be called from inside `poll()`, otherwise it will panic. - fn process_network_event( - &mut self, - event: SwarmEvent - ) -> Option { - match event { - SwarmEvent::NodePending { node_index, peer_id, endpoint } => { - self.handle_connection(node_index, peer_id, endpoint); - None - }, - SwarmEvent::Reconnected { node_index, endpoint, closed_custom_protocols } => { - if let Some(ConnectedPoint::Dialer { address }) = self.nodes_addresses.remove(&node_index) { - self.topology.report_disconnected(&address, DisconnectReason::FoundBetterAddr); - } - if let ConnectedPoint::Dialer { ref address } = endpoint { - let peer_id = self.swarm.peer_id_of_node(node_index) - .expect("the swarm always produces events containing valid node indices"); - self.topology.report_connected(address, peer_id); - } - self.nodes_addresses.insert(node_index, endpoint); - Some(ServiceEvent::ClosedCustomProtocols { - node_index, - protocols: closed_custom_protocols, - }) - }, - SwarmEvent::NodeClosed { node_index, peer_id, closed_custom_protocols } => { - debug!(target: "sub-libp2p", "Connection to {:?} closed gracefully", peer_id); - if let Some(ConnectedPoint::Dialer { ref address }) = self.nodes_addresses.get(&node_index) { - self.topology.report_disconnected(address, DisconnectReason::RemoteClosed); - } - self.connect_to_nodes(); - Some(ServiceEvent::NodeClosed { - node_index, - closed_custom_protocols, - }) - }, - SwarmEvent::DialFail { address, error } => { - debug!(target: "sub-libp2p", "Failed to dial address {}: {:?}", address, error); - self.topology.report_failed_to_connect(&address); - self.connect_to_nodes(); - None - }, - SwarmEvent::UnresponsiveNode { node_index } => { - let closed_custom_protocols = self.swarm.drop_node(node_index) - .expect("the swarm always produces events containing valid node indices"); - if let Some(ConnectedPoint::Dialer { address }) = self.nodes_addresses.remove(&node_index) { - self.topology.report_disconnected(&address, DisconnectReason::Useless); - } - Some(ServiceEvent::NodeClosed { - node_index, - closed_custom_protocols, - }) - }, - SwarmEvent::UselessNode { node_index } => { - let peer_id = self.swarm.peer_id_of_node(node_index) - .expect("the swarm always produces events containing valid node indices") - .clone(); - let closed_custom_protocols = self.swarm.drop_node(node_index) - .expect("the swarm always produces events containing valid node indices"); - self.topology.report_useless(&peer_id); - if let Some(ConnectedPoint::Dialer { address }) = self.nodes_addresses.remove(&node_index) { - self.topology.report_disconnected(&address, DisconnectReason::Useless); - } - Some(ServiceEvent::NodeClosed { - node_index, - closed_custom_protocols, - }) - }, - SwarmEvent::NodeInfos { node_index, listen_addrs, .. } => { - let peer_id = self.swarm.peer_id_of_node(node_index) - .expect("the swarm always produces events containing valid node indices"); - self.topology.add_self_reported_listen_addrs( - peer_id, - listen_addrs.into_iter() - ); - None - }, - SwarmEvent::KadFindNode { searched, responder, .. } => { - let response = self.build_kademlia_response(&searched); - responder.respond(response); - None - }, - SwarmEvent::KadOpen { node_index, controller } => { - let peer_id = self.swarm.peer_id_of_node(node_index) - .expect("the swarm always produces events containing valid node indices"); - trace!(target: "sub-libp2p", "Opened Kademlia substream with {:?}", peer_id); - if let Some(list) = self.kad_pending_ctrls.lock().remove(&peer_id) { - for tx in list { - let _ = tx.send(controller.clone()); - } - } - None - }, - SwarmEvent::KadClosed { .. } => { - None - }, - SwarmEvent::OpenedCustomProtocol { node_index, protocol, version } => { - let peer_id = self.swarm.peer_id_of_node(node_index) - .expect("the swarm always produces events containing valid node indices"); - self.kad_system.update_kbuckets(peer_id.clone()); - Some(ServiceEvent::OpenedCustomProtocol { - node_index, - protocol, - version, - }) - }, - SwarmEvent::ClosedCustomProtocol { node_index, protocol } => - Some(ServiceEvent::ClosedCustomProtocol { - node_index, - protocol, - }), - SwarmEvent::CustomMessage { node_index, protocol_id, data } => { - let peer_id = self.swarm.peer_id_of_node(node_index) - .expect("the swarm always produces events containing valid node indices"); - self.kad_system.update_kbuckets(peer_id.clone()); - Some(ServiceEvent::CustomMessage { - node_index, - protocol_id, - data, - }) - }, - } - } - - /// Handles a Kademlia query requesting a Kademlia controller with the given peer. - fn handle_kad_ctrl_request(&mut self, peer_id: PeerId) { - if let Some(node_index) = self.swarm.latest_node_by_peer_id(&peer_id) { - if let Err(_) = self.swarm.open_kademlia(node_index) { - self.kad_pending_ctrls.lock().remove(&peer_id); - } - } else { - let addrs = self.topology.addrs_of_peer(&peer_id); - let mut one_worked = false; - for (addr, _) in addrs { - if let Ok(_) = self.swarm.ensure_connection(peer_id.clone(), addr.clone()) { - one_worked = true; - } - } - if !one_worked { - debug!(target: "sub-libp2p", "Couldn't open Kad substream with {:?} \ - because no address is known", peer_id); - // Closing the senders in order to generate errors on the Kad query. - self.kad_pending_ctrls.lock().remove(&peer_id); - } - } - } - - /// Polls for what happened on the main network side. + /// Polls for what happened on the network. fn poll_swarm(&mut self) -> Poll, IoError> { loop { match self.swarm.poll() { - Ok(Async::Ready(Some(event))) => - if let Some(event) = self.process_network_event(event) { - return Ok(Async::Ready(Some(event))); - } - Ok(Async::NotReady) => return Ok(Async::NotReady), - Ok(Async::Ready(None)) => unreachable!("The Swarm stream never ends"), - // TODO: this `Err` contains a `Void` ; remove variant when Rust allows that - Err(_) => unreachable!("The Swarm stream never errors"), - } - } - } - - /// Polls the Kademlia system. - fn poll_kademlia(&mut self) -> Poll, IoError> { - // Polls the active Kademlia queries. - // We remove each element from `kad_queries` one by one and add them back if not ready. - for n in (0 .. self.kad_queries.len()).rev() { - let mut query = self.kad_queries.swap_remove(n); - loop { - match query.poll() { - Ok(Async::Ready(Some(KadQueryEvent::PeersReported(list)))) => - self.add_discovered_peers(list), - // We don't actually care about the results - Ok(Async::Ready(Some(KadQueryEvent::Finished(_out)))) => { - if _out.is_empty() { - warn!(target: "sub-libp2p", "Random Kademlia request has yielded \ - empty results"); - } - break - }, - Ok(Async::Ready(None)) => break, - Ok(Async::NotReady) => { - self.kad_queries.push(query); - break; - }, - Err(err) => { - warn!(target: "sub-libp2p", "Kademlia query failed: {:?}", err); - break; - }, + Ok(Async::Ready(Some(BehaviourOut::CustomProtocolOpen { protocol_id, peer_id, version, endpoint }))) => { + debug!(target: "sub-libp2p", "Opened custom protocol with {:?}", peer_id); + let node_index = self.index_of_peer_or_assign(peer_id, endpoint); + break Ok(Async::Ready(Some(ServiceEvent::OpenedCustomProtocol { + node_index, + protocol: protocol_id, + version, + }))) } - } - } - - // Poll the future that fires when we need to reply to a Kademlia query. - loop { - match self.kad_new_ctrl_req_rx.poll() { - Ok(Async::NotReady) => break, - Ok(Async::Ready(Some(peer_id))) => self.handle_kad_ctrl_request(peer_id), - Ok(Async::Ready(None)) => unreachable!("The tx is in self"), - Err(()) => unreachable!("An UnboundedReceiver never errors"), - } - } - - // Poll the future that fires when we need to perform a random Kademlia query. - loop { - match self.next_kad_random_query.poll() { - Ok(Async::NotReady) => break, - Ok(Async::Ready(Some(_))) => self.perform_kad_random_query(), - Ok(Async::Ready(None)) => { - warn!(target: "sub-libp2p", "Kad query timer closed unexpectedly"); - return Ok(Async::Ready(None)); + Ok(Async::Ready(Some(BehaviourOut::CustomProtocolClosed { protocol_id, peer_id, result }))) => { + debug!(target: "sub-libp2p", "Custom protocol with {:?} closed: {:?}", peer_id, result); + let node_index = *self.index_by_id.get(&peer_id).expect("index_by_id is always kept in sync with the state of the behaviour"); + break Ok(Async::Ready(Some(ServiceEvent::ClosedCustomProtocol { + node_index, + protocol: protocol_id, + }))) } - Err(err) => { - warn!(target: "sub-libp2p", "Kad query timer errored: {:?}", err); - return Err(IoError::new(IoErrorKind::Other, err)); + Ok(Async::Ready(Some(BehaviourOut::CustomMessage { protocol_id, peer_id, data }))) => { + let node_index = *self.index_by_id.get(&peer_id).expect("index_by_id is always kept in sync with the state of the behaviour"); + break Ok(Async::Ready(Some(ServiceEvent::CustomMessage { + node_index, + protocol_id, + data, + }))) } - } - } - - Ok(Async::NotReady) - } - - // Polls the future that fires when we need to refresh our connections. - fn poll_next_connect_refresh(&mut self) -> Poll, IoError> { - loop { - match self.next_connect_to_nodes.poll() { - Ok(Async::Ready(())) => self.connect_to_nodes(), - Ok(Async::NotReady) => return Ok(Async::NotReady), - Err(err) => { - warn!(target: "sub-libp2p", "Connect to nodes timer errored: {:?}", err); - return Err(IoError::new(IoErrorKind::Other, err)); + Ok(Async::Ready(Some(BehaviourOut::Identified { peer_id, info }))) => { + // Contrary to the other events, this one can happen even on nodes which don't + // have any open custom protocol slot. Therefore it is not necessarily in the + // list. + if let Some(id) = self.index_by_id.get(&peer_id) { + self.nodes_info.get_mut(id) + .expect("index_by_id and nodes_info are always kept in sync; QED") + .client_version = Some(info.agent_version); + } } + Ok(Async::NotReady) => break Ok(Async::NotReady), + Ok(Async::Ready(None)) => unreachable!("The Swarm stream never ends"), + Err(_) => unreachable!("The Swarm never errors"), } } } @@ -919,22 +394,20 @@ impl Service { Ok(Async::NotReady) => return Ok(Async::NotReady), Ok(Async::Ready(Some(_))) => { debug!(target: "sub-libp2p", "Cleaning and flushing topology"); - self.topology.cleanup(); - if let Err(err) = self.topology.flush_to_disk() { + Swarm::topology_mut(&mut self.swarm).cleanup(); + if let Err(err) = Swarm::topology_mut(&mut self.swarm).flush_to_disk() { warn!(target: "sub-libp2p", "Failed to flush topology: {:?}", err); } - let now = Instant::now(); - self.disabled_peers.retain(move |_, v| *v < now); debug!(target: "sub-libp2p", "Topology now contains {} nodes", - self.topology.num_peers()); + Swarm::topology_mut(&mut self.swarm).num_peers()); }, Ok(Async::Ready(None)) => { warn!(target: "sub-libp2p", "Topology flush stream ended unexpectedly"); - return Ok(Async::Ready(None)); + return Ok(Async::Ready(None)) } Err(err) => { warn!(target: "sub-libp2p", "Topology flush stream errored: {:?}", err); - return Err(IoError::new(IoErrorKind::Other, err)); + return Err(IoError::new(IoErrorKind::Other, err)) } } } @@ -943,7 +416,7 @@ impl Service { impl Drop for Service { fn drop(&mut self) { - if let Err(err) = self.topology.flush_to_disk() { + if let Err(err) = Swarm::topology_mut(&mut self.swarm).flush_to_disk() { warn!(target: "sub-libp2p", "Failed to flush topology: {:?}", err); } } @@ -963,16 +436,6 @@ impl Stream for Service { Async::NotReady => (), } - match self.poll_kademlia()? { - Async::Ready(value) => return Ok(Async::Ready(value)), - Async::NotReady => (), - } - - match self.poll_next_connect_refresh()? { - Async::Ready(value) => return Ok(Async::Ready(value)), - Async::NotReady => (), - } - match self.poll_cleanup()? { Async::Ready(value) => return Ok(Async::Ready(value)), Async::NotReady => (), @@ -980,7 +443,6 @@ impl Stream for Service { // The only way we reach this is if we went through all the `NotReady` paths above, // ensuring the current task is registered everywhere. - self.to_notify = Some(task::current()); Ok(Async::NotReady) } } diff --git a/core/network-libp2p/src/swarm.rs b/core/network-libp2p/src/swarm.rs deleted file mode 100644 index 0a6bfaa9949389379e85eb569176cd3495f70f0f..0000000000000000000000000000000000000000 --- a/core/network-libp2p/src/swarm.rs +++ /dev/null @@ -1,672 +0,0 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU 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 bytes::Bytes; -use custom_proto::RegisteredProtocols; -use fnv::FnvHashMap; -use futures::{prelude::*, Stream}; -use libp2p::{Multiaddr, multiaddr::Protocol, PeerId}; -use libp2p::core::{muxing, Endpoint, PublicKey}; -use libp2p::core::nodes::{ConnectedPoint, RawSwarm, RawSwarmEvent, Peer as SwarmPeer, Substream}; -use libp2p::core::transport::boxed::Boxed; -use libp2p::kad::{KadConnecController, KadFindNodeRespond}; -use libp2p::secio; -use node_handler::{SubstrateOutEvent, SubstrateNodeHandler, SubstrateInEvent, IdentificationRequest}; -use std::{io, mem, sync::Arc}; -use transport; -use {Error, NodeIndex, ProtocolId}; - -/// Starts a swarm. -/// -/// Returns a stream that must be polled regularly in order for the networking to function. -pub fn start_swarm( - registered_custom: RegisteredProtocols, - local_private_key: secio::SecioKeyPair, -) -> Result { - // Private and public keys. - let local_public_key = local_private_key.to_public_key(); - let local_peer_id = local_public_key.clone().into_peer_id(); - - // Build the transport layer. This is what allows us to listen or to reach nodes. - let transport = transport::build_transport(local_private_key); - - // Build the underlying libp2p swarm. - let swarm = RawSwarm::new(transport); - - Ok(Swarm { - swarm, - registered_custom: Arc::new(registered_custom), - local_public_key, - local_peer_id, - listening_addrs: Vec::new(), - node_by_peer: Default::default(), - nodes_info: Default::default(), - next_node_index: 0, - }) -} - -/// Event produced by the swarm. -pub enum SwarmEvent { - /// We have successfully connected to a node. - /// - /// The node is in pending node, and should be accepted by calling `accept_node(node_index)` - /// or denied by calling `drop_node(node_index)`. - NodePending { - /// Index of the node. - node_index: NodeIndex, - /// Public key of the node as a peer id. - peer_id: PeerId, - /// Whether we dialed the node or if it came to us. - endpoint: ConnectedPoint, - }, - - /// The connection to a peer has changed. - Reconnected { - /// Index of the node. - node_index: NodeIndex, - /// The new endpoint. - endpoint: ConnectedPoint, - /// List of custom protocols that were closed in the process. - closed_custom_protocols: Vec, - }, - - /// Closed connection to a node, either gracefully or because of an error. - /// - /// It is guaranteed that this node has been opened with a `NewNode` event beforehand. However - /// not all `ClosedCustomProtocol` events have been dispatched. - NodeClosed { - /// Index of the node. - node_index: NodeIndex, - /// Peer id we were connected to. - peer_id: PeerId, - /// List of custom protocols that were still open. - closed_custom_protocols: Vec, - }, - - /// Failed to dial an address. - DialFail { - /// Address that failed. - address: Multiaddr, - /// Reason why we failed. - error: io::Error, - }, - - /// Report information about the node. - NodeInfos { - /// Index of the node. - node_index: NodeIndex, - /// The client version. Note that it can be anything and should not be trusted. - client_version: String, - /// Multiaddresses the node is listening on. - listen_addrs: Vec, - }, - - /// A custom protocol substream has been opened with a node. - OpenedCustomProtocol { - /// Index of the node. - node_index: NodeIndex, - /// Protocol that has been opened. - protocol: ProtocolId, - /// Version of the protocol that was opened. - version: u8, - }, - - /// A custom protocol substream has been closed. - ClosedCustomProtocol { - /// Index of the node. - node_index: NodeIndex, - /// Protocol that has been closed. - protocol: ProtocolId, - }, - - /// Receives a message on a custom protocol stream. - CustomMessage { - /// Index of the node. - node_index: NodeIndex, - /// Protocol which generated the message. - protocol_id: ProtocolId, - /// Data that has been received. - data: Bytes, - }, - - /// The node has been determined to be unresponsive. - UnresponsiveNode { - /// Index of the node. - node_index: NodeIndex, - }, - - /// The node works but we can't do anything useful with it. - UselessNode { - /// Index of the node. - node_index: NodeIndex, - }, - - /// Opened a Kademlia substream with the node. - // TODO: the controller API is bad, but we need to make changes in libp2p to improve that - KadOpen { - /// Index of the node. - node_index: NodeIndex, - /// The Kademlia controller. Allows making queries. - controller: KadConnecController, - }, - - /// The remote wants us to answer a Kademlia `FIND_NODE` request. - /// - /// The `responder` should be used to answer that query. - // TODO: this API with the "responder" is bad, but changing it requires modifications in libp2p - KadFindNode { - /// Index of the node that wants an answer. - node_index: NodeIndex, - /// The value being searched. - searched: PeerId, - /// Object to use to respond to the request. - responder: KadFindNodeRespond, - }, - - /// A Kademlia substream has been closed. - KadClosed { - /// Index of the node. - node_index: NodeIndex, - /// Reason why it has been closed. `Ok` means that it's been closed gracefully. - result: Result<(), io::Error>, - }, -} - -/// Network swarm. Must be polled regularly in order for the networking to work. -pub struct Swarm { - /// Stream of events of the swarm. - swarm: RawSwarm< - Boxed<(PeerId, Muxer)>, - SubstrateInEvent, - SubstrateOutEvent>, - SubstrateNodeHandler> - >, - - /// List of registered protocols. Used when we open or receive a new connection. - registered_custom: Arc, - - /// Public key of the local node. - local_public_key: PublicKey, - - /// Peer id of the local node. - local_peer_id: PeerId, - - /// Addresses we know we're listening on. Only includes NAT traversed addresses. - listening_addrs: Vec, - - /// For each peer id, the corresponding node index. - node_by_peer: FnvHashMap, - - /// All the nodes tasks. Must be maintained consistent with `node_by_peer`. - nodes_info: FnvHashMap, - - /// Next key to use when we insert a new entry in `nodes_info`. - next_node_index: NodeIndex, -} - -/// Local information about a peer. -struct NodeInfo { - /// The peer id. Must be maintained consistent with the rest of the state. - peer_id: PeerId, - - /// Whether we opened the connection or the remote opened it. - endpoint: Endpoint, - - /// List of custom protocol substreams that are open. - open_protocols: Vec, -} - -/// The muxer used by the transport. -type Muxer = muxing::StreamMuxerBox; - -impl Swarm { - /// Start listening on a multiaddr. - #[inline] - pub fn listen_on(&mut self, addr: Multiaddr) -> Result { - match self.swarm.listen_on(addr) { - Ok(mut addr) => { - addr.append(Protocol::P2p(self.local_peer_id.clone().into())); - info!(target: "sub-libp2p", "Local node address is: {}", addr); - Ok(addr) - }, - Err(addr) => Err(addr) - } - } - - /// Returns an iterator that produces the list of addresses we're listening on. - #[inline] - pub fn listeners(&self) -> impl Iterator { - self.swarm.listeners() - } - - /// Adds an external address. Sent to other nodes when they query it. - #[inline] - pub fn add_external_address(&mut self, addr: Multiaddr) { - self.listening_addrs.push(addr); - } - - /// Returns an iterator to our known external addresses. - #[inline] - pub fn external_addresses(&self) -> impl Iterator { - self.listening_addrs.iter() - } - - /// Returns all the nodes that are currently active. - #[inline] - pub fn nodes<'a>(&'a self) -> impl Iterator + 'a { - self.nodes_info.keys().cloned() - } - - /// Returns the latest node connected to this peer ID. - #[inline] - pub fn latest_node_by_peer_id(&self, peer_id: &PeerId) -> Option { - self.node_by_peer.get(peer_id).map(|&i| i) - } - - /// Endpoint of the node. - /// - /// Returns `None` if the index is invalid. - #[inline] - pub fn node_endpoint(&self, node_index: NodeIndex) -> Option { - self.nodes_info.get(&node_index).map(|i| i.endpoint) - } - - /// Sends a message to a peer using the custom protocol. - // TODO: report invalid node index or protocol? - pub fn send_custom_message( - &mut self, - node_index: NodeIndex, - protocol: ProtocolId, - data: Vec - ) { - if let Some(info) = self.nodes_info.get_mut(&node_index) { - if let Some(mut connected) = self.swarm.peer(info.peer_id.clone()).as_connected() { - connected.send_event(SubstrateInEvent::SendCustomMessage { protocol, data }); - } else { - error!(target: "sub-libp2p", "Tried to send message to {:?}, but we're not \ - connected to it", info.peer_id); - } - } else { - error!(target: "sub-libp2p", "Tried to send message to invalid node index {:?}", - node_index); - } - } - - /// Returns the peer id of a node we're connected to. - #[inline] - pub fn peer_id_of_node(&self, node_index: NodeIndex) -> Option<&PeerId> { - self.nodes_info.get(&node_index).map(|i| &i.peer_id) - } - - /// If we're not already dialing the given peer, start dialing it and return false. - /// If we're dialing, adds the address to the queue of addresses to try (if not already) and - /// return false. - /// If we're already connected, do nothing and return true. - /// - /// Returns an error if the address is not supported. - pub fn ensure_connection(&mut self, peer_id: PeerId, addr: Multiaddr) -> Result { - match self.swarm.peer(peer_id.clone()) { - SwarmPeer::Connected(_) => Ok(true), - SwarmPeer::PendingConnect(mut peer) => { - peer.append_multiaddr_attempt(addr); - Ok(false) - }, - SwarmPeer::NotConnected(peer) => { - trace!(target: "sub-libp2p", "Starting to connect to {:?} through {}", - peer_id, addr); - match peer.connect(addr, SubstrateNodeHandler::new(self.registered_custom.clone())) { - Ok(_) => Ok(false), - Err(_) => Err(()), - } - }, - } - } - - /// Start dialing an address, not knowing which peer ID to expect. - #[inline] - pub fn dial(&mut self, addr: Multiaddr) -> Result<(), Multiaddr> { - self.swarm.dial(addr, SubstrateNodeHandler::new(self.registered_custom.clone())) - } - - /// After receiving a `NodePending` event, you should call either `accept_node` or `drop_node` - /// with the specified index. - /// - /// Returns an error if the node index is invalid, or if it was already accepted. - pub fn accept_node(&mut self, node_index: NodeIndex) -> Result<(), ()> { - // TODO: detect if already accepted? - let peer_id = match self.nodes_info.get(&node_index) { - Some(info) => &info.peer_id, - None => return Err(()) - }; - - match self.swarm.peer(peer_id.clone()) { - SwarmPeer::Connected(mut peer) => { - peer.send_event(SubstrateInEvent::Accept); - Ok(()) - }, - SwarmPeer::PendingConnect(_) | SwarmPeer::NotConnected(_) => { - error!(target: "sub-libp2p", "State inconsistency detected in accept_node ; \ - nodes_info is not in sync with the underlying swarm"); - Err(()) - }, - } - } - - /// Disconnects a peer. - /// - /// If the peer is connected, this disconnects it. - /// If the peer hasn't been accepted yet, this immediately drops it. - /// - /// Returns the list of custom protocol substreams that were opened. - #[inline] - pub fn drop_node(&mut self, node_index: NodeIndex) -> Result, ()> { - let info = match self.nodes_info.remove(&node_index) { - Some(i) => i, - None => { - error!(target: "sub-libp2p", "Trying to close non-existing node #{}", node_index); - return Err(()); - }, - }; - - let idx_in_hashmap = self.node_by_peer.remove(&info.peer_id); - debug_assert_eq!(idx_in_hashmap, Some(node_index)); - - if let Some(connected) = self.swarm.peer(info.peer_id.clone()).as_connected() { - connected.close(); - } else { - error!(target: "sub-libp2p", "State inconsistency: node_by_peer and nodes_info are \ - not in sync with the underlying swarm"); - } - - Ok(info.open_protocols) - } - - /// Opens a Kademlia substream with the given node. A `KadOpen` event will later be produced - /// for the given node. - /// - /// If a Kademlia substream is already open, also produces a `KadOpen` event. - /// - /// Returns an error if the node index is invalid. - pub fn open_kademlia(&mut self, node_index: NodeIndex) -> Result<(), ()> { - if let Some(info) = self.nodes_info.get_mut(&node_index) { - if let Some(mut connected) = self.swarm.peer(info.peer_id.clone()).as_connected() { - connected.send_event(SubstrateInEvent::OpenKademlia); - Ok(()) - } else { - error!(target: "sub-libp2p", "Tried to open Kademlia with {:?}, but we're not \ - connected to it", info.peer_id); - Err(()) - } - } else { - error!(target: "sub-libp2p", "Tried to open Kademlia with invalid node index {:?}", - node_index); - Err(()) - } - } - - /// Adds an address the given peer observes us as. - fn add_observed_addr(&mut self, peer_id: &PeerId, observed_addr: &Multiaddr) { - for mut addr in self.swarm.nat_traversal(observed_addr) { - // Ignore addresses we already know about. - if self.listening_addrs.iter().any(|a| a == &addr) { - continue; - } - - debug!(target: "sub-libp2p", - "NAT traversal: {:?} observes us as {}; registering {} as one of our own addresses", - peer_id, - observed_addr, - addr - ); - - self.listening_addrs.push(addr.clone()); - addr.append(Protocol::P2p(self.local_peer_id.clone().into())); - info!(target: "sub-libp2p", "New external node address: {}", addr); - } - } - - /// Responds to an answer to send back identification information. - fn respond_to_identify_request( - &mut self, - requester: &PeerId, - responder: IdentificationRequest> - ) { - let peer = match self.swarm.peer(requester.clone()).as_connected() { - Some(p) => p, - None => { - debug!(target: "sub-libp2p", "Ignoring identify request from {:?} because we are \ - disconnected", requester); - return; - } - }; - - let observed_addr = match peer.endpoint() { - &ConnectedPoint::Dialer { ref address } => address, - &ConnectedPoint::Listener { ref send_back_addr, .. } => send_back_addr, - }; - - trace!(target: "sub-libp2p", "Responding to identify request from {:?}", requester); - responder.respond( - self.local_public_key.clone(), - self.listening_addrs.clone(), - &observed_addr, - ); - } - - /// Processes an event obtained by a node in the swarm. - /// - /// Optionally returns an event that the service must emit. - /// - /// > **Note**: The event **must** have been produced by the swarm, otherwise state - /// > inconsistencies will likely happen. - fn handle_node_event( - &mut self, - peer_id: PeerId, - event: SubstrateOutEvent> - ) -> Option { - // Obtain the peer id and whether the node has been closed earlier. - // If the node has been closed, do not generate any additional event about it. - let node_index = *self.node_by_peer.get(&peer_id) - .expect("node_by_peer is always kept in sync with the underlying swarm"); - - match event { - SubstrateOutEvent::Unresponsive => { - debug!(target: "sub-libp2p", "Node {:?} is unresponsive", peer_id); - Some(SwarmEvent::UnresponsiveNode { node_index }) - }, - SubstrateOutEvent::Useless => { - debug!(target: "sub-libp2p", "Node {:?} is useless", peer_id); - Some(SwarmEvent::UselessNode { node_index }) - }, - SubstrateOutEvent::PingStart => { - trace!(target: "sub-libp2p", "Pinging {:?}", peer_id); - None - }, - SubstrateOutEvent::PingSuccess(ping) => { - trace!(target: "sub-libp2p", "Pong from {:?} in {:?}", peer_id, ping); - None - }, - SubstrateOutEvent::Identified { info, observed_addr } => { - self.add_observed_addr(&peer_id, &observed_addr); - trace!(target: "sub-libp2p", "Client version of {:?}: {:?}", peer_id, info.agent_version); - if !info.agent_version.contains("substrate") { - info!(target: "sub-libp2p", "Connected to non-substrate node {:?}: {}", - peer_id, info.agent_version); - } - - Some(SwarmEvent::NodeInfos { - node_index, - client_version: info.agent_version, - listen_addrs: info.listen_addrs, - }) - }, - SubstrateOutEvent::IdentificationRequest(request) => { - self.respond_to_identify_request(&peer_id, request); - None - }, - SubstrateOutEvent::KadFindNode { searched, responder } => { - Some(SwarmEvent::KadFindNode { node_index, searched, responder }) - }, - SubstrateOutEvent::KadOpen(ctrl) => { - trace!(target: "sub-libp2p", "Opened Kademlia substream with {:?}", peer_id); - Some(SwarmEvent::KadOpen { node_index, controller: ctrl }) - }, - SubstrateOutEvent::KadClosed(result) => { - trace!(target: "sub-libp2p", "Closed Kademlia substream with {:?}: {:?}", peer_id, result); - Some(SwarmEvent::KadClosed { node_index, result }) - }, - SubstrateOutEvent::CustomProtocolOpen { protocol_id, version } => { - trace!(target: "sub-libp2p", "Opened custom protocol with {:?}", peer_id); - self.nodes_info.get_mut(&node_index) - .expect("nodes_info is kept in sync with the underlying swarm") - .open_protocols.push(protocol_id); - Some(SwarmEvent::OpenedCustomProtocol { - node_index, - protocol: protocol_id, - version, - }) - }, - SubstrateOutEvent::CustomProtocolClosed { protocol_id, result } => { - trace!(target: "sub-libp2p", "Closed custom protocol with {:?}: {:?}", peer_id, result); - self.nodes_info.get_mut(&node_index) - .expect("nodes_info is kept in sync with the underlying swarm") - .open_protocols.retain(|p| p != &protocol_id); - Some(SwarmEvent::ClosedCustomProtocol { - node_index, - protocol: protocol_id, - }) - }, - SubstrateOutEvent::CustomMessage { protocol_id, data } => { - Some(SwarmEvent::CustomMessage { - node_index, - protocol_id, - data, - }) - }, - SubstrateOutEvent::SubstreamUpgradeFail(err) => { - debug!(target: "sub-libp2p", "Error while negotiating final protocol \ - with {:?}: {:?}", peer_id, err); - None - }, - } - } -} - -impl Stream for Swarm { - type Item = SwarmEvent; - type Error = io::Error; - - fn poll(&mut self) -> Poll, Self::Error> { - loop { - let (peer_id, node_event) = match self.swarm.poll() { - Async::Ready(RawSwarmEvent::Connected { peer_id, endpoint }) => { - let node_index = self.next_node_index.clone(); - self.next_node_index += 1; - self.node_by_peer.insert(peer_id.clone(), node_index); - self.nodes_info.insert(node_index, NodeInfo { - peer_id: peer_id.clone(), - endpoint: match endpoint { - ConnectedPoint::Listener { .. } => Endpoint::Listener, - ConnectedPoint::Dialer { .. } => Endpoint::Dialer, - }, - open_protocols: Vec::new(), - }); - - return Ok(Async::Ready(Some(SwarmEvent::NodePending { - node_index, - peer_id, - endpoint - }))); - } - Async::Ready(RawSwarmEvent::Replaced { peer_id, endpoint, .. }) => { - let node_index = *self.node_by_peer.get(&peer_id) - .expect("node_by_peer is always kept in sync with the inner swarm"); - let infos = self.nodes_info.get_mut(&node_index) - .expect("nodes_info is always kept in sync with the swarm"); - debug_assert_eq!(infos.peer_id, peer_id); - infos.endpoint = match endpoint { - ConnectedPoint::Listener { .. } => Endpoint::Listener, - ConnectedPoint::Dialer { .. } => Endpoint::Dialer, - }; - let closed_custom_protocols = mem::replace(&mut infos.open_protocols, Vec::new()); - - return Ok(Async::Ready(Some(SwarmEvent::Reconnected { - node_index, - endpoint, - closed_custom_protocols, - }))); - }, - Async::Ready(RawSwarmEvent::NodeClosed { peer_id, .. }) => { - debug!(target: "sub-libp2p", "Connection to {:?} closed gracefully", peer_id); - let node_index = self.node_by_peer.remove(&peer_id) - .expect("node_by_peer is always kept in sync with the inner swarm"); - let infos = self.nodes_info.remove(&node_index) - .expect("nodes_info is always kept in sync with the inner swarm"); - debug_assert_eq!(infos.peer_id, peer_id); - return Ok(Async::Ready(Some(SwarmEvent::NodeClosed { - node_index, - peer_id, - closed_custom_protocols: infos.open_protocols, - }))); - }, - Async::Ready(RawSwarmEvent::NodeError { peer_id, error, .. }) => { - debug!(target: "sub-libp2p", "Closing {:?} because of error: {:?}", peer_id, error); - let node_index = self.node_by_peer.remove(&peer_id) - .expect("node_by_peer is always kept in sync with the inner swarm"); - let infos = self.nodes_info.remove(&node_index) - .expect("nodes_info is always kept in sync with the inner swarm"); - debug_assert_eq!(infos.peer_id, peer_id); - return Ok(Async::Ready(Some(SwarmEvent::NodeClosed { - node_index, - peer_id, - closed_custom_protocols: infos.open_protocols, - }))); - }, - Async::Ready(RawSwarmEvent::DialError { multiaddr, error, .. }) => - return Ok(Async::Ready(Some(SwarmEvent::DialFail { - address: multiaddr, - error, - }))), - Async::Ready(RawSwarmEvent::UnknownPeerDialError { multiaddr, error, .. }) => - return Ok(Async::Ready(Some(SwarmEvent::DialFail { - address: multiaddr, - error, - }))), - Async::Ready(RawSwarmEvent::ListenerClosed { listen_addr, result, .. }) => { - warn!(target: "sub-libp2p", "Listener closed for {}: {:?}", listen_addr, result); - continue; - }, - Async::Ready(RawSwarmEvent::NodeEvent { peer_id, event }) => (peer_id, event), - Async::Ready(RawSwarmEvent::IncomingConnection(incoming)) => { - trace!(target: "sub-libp2p", "Incoming connection with {} on listener {}", - incoming.send_back_addr(), incoming.listen_addr()); - incoming.accept(SubstrateNodeHandler::new(self.registered_custom.clone())); - continue; - }, - Async::Ready(RawSwarmEvent::IncomingConnectionError { listen_addr, send_back_addr, error }) => { - trace!(target: "sub-libp2p", "Incoming connection with {} on listener {} \ - errored: {:?}", send_back_addr, listen_addr, error); - continue; - }, - Async::NotReady => return Ok(Async::NotReady), - }; - - if let Some(event) = self.handle_node_event(peer_id, node_event) { - return Ok(Async::Ready(Some(event))); - } - } - } -} diff --git a/core/network-libp2p/src/topology.rs b/core/network-libp2p/src/topology.rs index ad92448c6af8a20587cd75f4227e2821d52ac4ea..6689caf4b031865b36367e0ef8b8044823b6c22c 100644 --- a/core/network-libp2p/src/topology.rs +++ b/core/network-libp2p/src/topology.rs @@ -15,10 +15,12 @@ // along with Substrate. If not, see .? use fnv::FnvHashMap; -use parking_lot::Mutex; -use libp2p::{Multiaddr, PeerId}; -use serde_json; -use std::{cmp, fs}; +use libp2p::{Multiaddr, PeerId, identify::IdentifyTopology, multihash::Multihash}; +use libp2p::core::{PublicKey, swarm::ConnectedPoint, topology::DisconnectReason, topology::Topology}; +use libp2p::kad::{KBucketsPeerId, KadConnectionType, KademliaTopology}; +use log::{debug, info, trace, warn}; +use serde_derive::{Serialize, Deserialize}; +use std::{cmp, fs, iter, vec}; use std::io::{Read, Cursor, Error as IoError, ErrorKind as IoErrorKind, Write, BufReader, BufWriter}; use std::path::{Path, PathBuf}; use std::time::{Duration, Instant, SystemTime}; @@ -46,8 +48,6 @@ const KADEMLIA_DISCOVERY_EXPIRATION: Duration = Duration::from_secs(2 * 3600); const EXPIRATION_PUSH_BACK_CONNEC: Duration = Duration::from_secs(2 * 3600); /// Initial score that a bootstrap node receives when registered. const BOOTSTRAP_NODE_SCORE: u32 = 100; -/// Score modifier to apply on a peer that has been determined to be useless. -const USELESS_PEER_SCORE_CHANGE: i32 = -9; /// Time to live of a boostrap node. This only applies if you start the node later *without* /// that bootstrap node configured anymore. const BOOTSTRAP_NODE_EXPIRATION: Duration = Duration::from_secs(24 * 3600); @@ -63,15 +63,16 @@ const MAX_BACKOFF: Duration = Duration::from_secs(30 * 60); /// Stores information about the topology of the network. #[derive(Debug)] pub struct NetTopology { + /// The actual storage. Never contains a key for `local_peer_id`. store: FnvHashMap, + /// Optional path to the file that caches the serialized version of `store`. cache_path: Option, -} - -impl Default for NetTopology { - #[inline] - fn default() -> NetTopology { - NetTopology::memory() - } + /// Public key of the local node. + local_public_key: PublicKey, + /// PeerId of the local node. Derived from `local_public_key`. + local_peer_id: PeerId, + /// Known addresses for the local node to report to the network. + external_addresses: Vec, } impl NetTopology { @@ -79,10 +80,14 @@ impl NetTopology { /// /// `flush_to_disk()` will be a no-op. #[inline] - pub fn memory() -> NetTopology { + pub fn memory(local_public_key: PublicKey) -> NetTopology { + let local_peer_id = local_public_key.clone().into_peer_id(); NetTopology { store: Default::default(), cache_path: None, + local_peer_id, + local_public_key, + external_addresses: Vec::new(), } } @@ -92,19 +97,24 @@ impl NetTopology { /// or contains garbage data, the execution still continues. /// /// Calling `flush_to_disk()` in the future writes to the given path. - pub fn from_file>(path: P) -> NetTopology { + pub fn from_file>(local_public_key: PublicKey, path: P) -> NetTopology { let path = path.as_ref(); + let local_peer_id = local_public_key.clone().into_peer_id(); debug!(target: "sub-libp2p", "Initializing peer store for JSON file {:?}", path); + let store = try_load(path, &local_peer_id); NetTopology { - store: try_load(path), + store, cache_path: Some(path.to_owned()), + local_peer_id, + local_public_key, + external_addresses: Vec::new(), } } /// Writes the topology into the path passed to `from_file`. /// /// No-op if the object was created with `memory()`. - pub fn flush_to_disk(&self) -> Result<(), IoError> { + pub fn flush_to_disk(&mut self) -> Result<(), IoError> { let path = match self.cache_path { Some(ref p) => p, None => return Ok(()) @@ -112,10 +122,10 @@ impl NetTopology { let file = fs::File::create(path)?; // TODO: the capacity of the BufWriter is kind of arbitrary ; decide better - serialize(BufWriter::with_capacity(1024 * 1024, file), &self.store) + serialize(BufWriter::with_capacity(1024 * 1024, file), &mut self.store) } - /// Returns the number of peers in the topology. + /// Returns the number of peers in the topology, excluding the local peer. #[inline] pub fn num_peers(&self) -> usize { self.store.len() @@ -127,40 +137,19 @@ impl NetTopology { pub fn cleanup(&mut self) { let now_systime = SystemTime::now(); self.store.retain(|_, peer| { - peer.addrs.retain(|a| { - a.expires > now_systime || a.is_connected() - }); + let new_addrs = peer.addrs + .drain(..) + .filter(|a| a.expires > now_systime || a.is_connected()) + .collect(); + peer.addrs = new_addrs; !peer.addrs.is_empty() }); } - /// Returns the known potential addresses of a peer, ordered by score. Excludes backed-off - /// addresses. - /// - /// The boolean associated to each address indicates whether we're connected to it. - pub fn addrs_of_peer(&self, peer: &PeerId) -> impl Iterator { - let peer = if let Some(peer) = self.store.get(peer) { - peer - } else { - // TODO: use an EitherIterator or something - return Vec::new().into_iter(); - }; - - let now_st = SystemTime::now(); - let now_is = Instant::now(); - - let mut list = peer.addrs.iter().filter_map(move |addr| { - let (score, connected) = addr.score_and_is_connected(); - if (addr.expires >= now_st && score > 0 && addr.back_off_until < now_is) || connected { - Some((score, connected, &addr.addr)) - } else { - None - } - }).collect::>(); - list.sort_by(|a, b| a.0.cmp(&b.0)); - // TODO: meh, optimize - let l = list.into_iter().map(|(_, connec, addr)| (addr, connec)).collect::>(); - l.into_iter() + /// Add the external addresses that are known for the local node. + pub fn add_external_addrs(&mut self, addrs: TIter) + where TIter: Iterator { + self.external_addresses.extend(addrs); } /// Returns a list of all the known addresses of peers, ordered by the @@ -170,7 +159,7 @@ impl NetTopology { /// by itself over time. The `Instant` that is returned corresponds to /// the earlier known time when a new entry will be added automatically to /// the list. - pub fn addrs_to_attempt(&self) -> (impl Iterator, Instant) { + pub fn addrs_to_attempt(&mut self) -> (impl Iterator, Instant) { // TODO: optimize let now = Instant::now(); let now_systime = SystemTime::now(); @@ -179,20 +168,20 @@ impl NetTopology { let mut peer_addrs = Vec::new(); - 'peer_loop: for (peer, info) in &self.store { + 'peer_loop: for (peer, info) in &mut self.store { peer_addrs.clear(); - for addr in &info.addrs { + for addr in &mut info.addrs { let (score, is_connected) = addr.score_and_is_connected(); if is_connected { - continue 'peer_loop; + continue 'peer_loop } if score == 0 || addr.expires < now_systime { - continue; + continue } if addr.back_off_until > now { instant = cmp::min(instant, addr.back_off_until); - continue; + continue } peer_addrs.push(((peer, &addr.addr), score)); @@ -217,15 +206,19 @@ impl NetTopology { let peer = peer_access(&mut self.store, peer); let mut found = false; - peer.addrs.retain(|a| { - if a.expires < now_systime && !a.is_connected() { - return false; - } - if a.addr == addr { - found = true; - } - true - }); + let new_addrs = peer.addrs + .drain(..) + .filter_map(|a| { + if a.expires < now_systime && !a.is_connected() { + return None + } + if a.addr == addr { + found = true; + } + Some(a) + }) + .collect(); + peer.addrs = new_addrs; if !found { peer.addrs.push(Addr { @@ -233,63 +226,45 @@ impl NetTopology { expires: now_systime + BOOTSTRAP_NODE_EXPIRATION, back_off_until: now, next_back_off: FIRST_CONNECT_FAIL_BACKOFF, - score: Mutex::new(AddrScore { + score: AddrScore { connected_since: None, score: BOOTSTRAP_NODE_SCORE, latest_score_update: now, - }), + }, }); } } - /// Adds addresses that a node says it is listening on. - /// - /// The addresses are most likely to be valid. - #[inline] - pub fn add_self_reported_listen_addrs( - &mut self, - peer_id: &PeerId, - addrs: I, - ) where I: Iterator { - self.add_discovered_addrs(peer_id, addrs.map(|a| (a, true))) - } - - /// Adds addresses discovered through the Kademlia DHT. - /// - /// The addresses are not necessarily valid and should expire after a TTL. - /// - /// For each address, incorporates a boolean. If true, that means we have some sort of hint - /// that this address can be reached. - #[inline] - pub fn add_kademlia_discovered_addrs( - &mut self, - peer_id: &PeerId, - addrs: I, - ) where I: Iterator { - self.add_discovered_addrs(peer_id, addrs) - } - - /// Inner implementaiton of the `add_*_discovered_addrs`. + /// Inner implementaiton of the `add_*_discovered_addrs` methods. + /// Returns `true` if the topology has changed in some way. Returns `false` if calling this + /// method was a no-op. fn add_discovered_addrs( &mut self, peer_id: &PeerId, addrs: I, - ) where I: Iterator { + ) -> bool + where I: Iterator { let mut addrs: Vec<_> = addrs.collect(); let now_systime = SystemTime::now(); let now = Instant::now(); let peer = peer_access(&mut self.store, peer_id); - peer.addrs.retain(|a| { - if a.expires < now_systime && !a.is_connected() { - return false; - } - if let Some(pos) = addrs.iter().position(|&(ref addr, _)| addr == &a.addr) { - addrs.remove(pos); - } - true - }); + let new_addrs = peer.addrs + .drain(..) + .filter_map(|a| { + if a.expires < now_systime && !a.is_connected() { + return None + } + if let Some(pos) = addrs.iter().position(|&(ref addr, _)| addr == &a.addr) { + addrs.remove(pos); + } + Some(a) + }) + .collect(); + peer.addrs = new_addrs; + + let mut anything_changed = false; if !addrs.is_empty() { trace!( @@ -309,7 +284,7 @@ impl NetTopology { // Enforce `MAX_ADDRESSES_PER_PEER` before inserting, or skip this entry. while peer.addrs.len() >= MAX_ADDRESSES_PER_PEER { - let pos = peer.addrs.iter().position(|addr| addr.score() <= initial_score); + let pos = peer.addrs.iter_mut().position(|addr| addr.score() <= initial_score); if let Some(pos) = pos { let _ = peer.addrs.remove(pos); } else { @@ -317,26 +292,115 @@ impl NetTopology { } } + anything_changed = true; peer.addrs.push(Addr { addr, expires: now_systime + KADEMLIA_DISCOVERY_EXPIRATION, back_off_until: now, next_back_off: FIRST_CONNECT_FAIL_BACKOFF, - score: Mutex::new(AddrScore { + score: AddrScore { connected_since: None, score: initial_score, latest_score_update: now, - }), + }, }); } + + anything_changed } +} + +impl KademliaTopology for NetTopology { + type ClosestPeersIter = vec::IntoIter; + type GetProvidersIter = iter::Empty; + + fn add_kad_discovered_address(&mut self, peer: PeerId, addr: Multiaddr, ty: KadConnectionType) { + self.add_discovered_addrs(&peer, iter::once((addr, ty == KadConnectionType::Connected))); + } + + fn closest_peers(&mut self, target: &Multihash, _max: usize) -> Self::ClosestPeersIter { + // TODO: very inefficient + let mut peers = self.store.keys().cloned().collect::>(); + peers.push(self.local_peer_id.clone()); + peers.sort_by(|a, b| { + b.as_ref().distance_with(target).cmp(&a.as_ref().distance_with(target)) + }); + peers.into_iter() + } + + fn add_provider(&mut self, _: Multihash, _: PeerId) { + // We don't implement ADD_PROVIDER/GET_PROVIDERS + } + + fn get_providers(&mut self, _: &Multihash) -> Self::GetProvidersIter { + // We don't implement ADD_PROVIDER/GET_PROVIDERS + iter::empty() + } +} + +impl IdentifyTopology for NetTopology { + #[inline] + fn add_identify_discovered_addrs(&mut self, peer: &PeerId, addrs: TIter) + where + TIter: Iterator + { + // These are addresses that peers indicate for themselves. + // The typical use case is: + // - A peer connects to one of our listening points. + // - We send an identify request to it, and it answers with a list of addresses. + // - If later it disconnects, we can try to dial it back through one of these addresses. + self.add_discovered_addrs(peer, addrs.map(move |a| (a, true))); + } +} + +impl Topology for NetTopology { + #[inline] + fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { + if peer == &self.local_peer_id { + return self.external_addresses.clone() + } + + let peer = if let Some(peer) = self.store.get_mut(peer) { + peer + } else { + return Vec::new() + }; + + let now_st = SystemTime::now(); + let now_is = Instant::now(); + + let mut list = peer.addrs.iter_mut().filter_map(move |addr| { + let (score, connected) = addr.score_and_is_connected(); + if (addr.expires >= now_st && score > 0 && addr.back_off_until < now_is) || connected { + Some((score, &addr.addr)) + } else { + None + } + }).collect::>(); + list.sort_by(|a, b| a.0.cmp(&b.0)); + // TODO: meh, optimize + list.into_iter().map(|(_, addr)| addr.clone()).collect::>() + } + + fn add_local_external_addrs(&mut self, addrs: TIter) + where TIter: Iterator { + self.add_external_addrs(addrs) + } + + fn local_peer_id(&self) -> &PeerId { + &self.local_peer_id + } + + fn local_public_key(&self) -> &PublicKey { + &self.local_public_key + } + + fn set_connected(&mut self, peer: &PeerId, endpoint: &ConnectedPoint) { + let addr = match endpoint { + ConnectedPoint::Dialer { address } => address, + ConnectedPoint::Listener { .. } => return + }; - /// Indicates the peer store that we're connected to this given address. - /// - /// This increases the score of the address that we connected to. Since we assume that only - /// one peer can be reached with any specific address, we also remove all addresses from other - /// peers that match the one we connected to. - pub fn report_connected(&mut self, addr: &Multiaddr, peer: &PeerId) { let now = Instant::now(); // Just making sure that we have an entry for this peer in `store`, but don't use it. @@ -348,20 +412,19 @@ impl NetTopology { addr.connected_now(CONNECTED_MINIMUM_SCORE); addr.back_off_until = now; addr.next_back_off = FIRST_CONNECT_FAIL_BACKOFF; - continue; + continue } - // TODO: a else block would be better, but we get borrowck errors info_in_store.addrs.push(Addr { addr: addr.clone(), expires: SystemTime::now() + EXPIRATION_PUSH_BACK_CONNEC, back_off_until: now, next_back_off: FIRST_CONNECT_FAIL_BACKOFF, - score: Mutex::new(AddrScore { + score: AddrScore { connected_since: Some(now), latest_score_update: now, score: CONNECTED_MINIMUM_SCORE, - }), + }, }); } else { @@ -375,17 +438,16 @@ impl NetTopology { } } - /// Indicates the peer store that we're disconnected from an address. - /// - /// There's no need to indicate a peer ID, as each address can only have one peer ID. - /// If we were indeed connected to this addr, then we can find out which peer ID it is. - pub fn report_disconnected(&mut self, addr: &Multiaddr, reason: DisconnectReason) { + fn set_disconnected(&mut self, _: &PeerId, endpoint: &ConnectedPoint, reason: DisconnectReason) { + let addr = match endpoint { + ConnectedPoint::Dialer { address } => address, + ConnectedPoint::Listener { .. } => return + }; + let score_diff = match reason { - DisconnectReason::NoSlot => -1, - DisconnectReason::FoundBetterAddr => -5, - DisconnectReason::RemoteClosed => -5, - DisconnectReason::Useless => -5, - DisconnectReason::Banned => -5, + DisconnectReason::Replaced => -3, + DisconnectReason::Graceful => -1, + DisconnectReason::Error => -5, }; for info in self.store.values_mut() { @@ -398,60 +460,28 @@ impl NetTopology { if a.expires < expires_push_back { a.expires = expires_push_back; } - return; + return } } } } - /// Indicates the peer store that we failed to connect to an address. - /// - /// We don't care about which peer is supposed to be behind that address. If we failed to dial - /// it for a specific peer, we would also fail to dial it for all peers that have this - /// address. - pub fn report_failed_to_connect(&mut self, addr: &Multiaddr) { + fn set_unreachable(&mut self, addr: &Multiaddr) { for info in self.store.values_mut() { for a in info.addrs.iter_mut() { - if &a.addr == addr { - a.adjust_score(SCORE_DIFF_ON_FAILED_TO_CONNECT); - trace!(target: "sub-libp2p", "Back off for {} = {:?}", addr, a.next_back_off); - a.back_off_until = Instant::now() + a.next_back_off; - a.next_back_off = cmp::min(a.next_back_off * FAIL_BACKOFF_MULTIPLIER, MAX_BACKOFF); + if &a.addr != addr { + continue } - } - } - } - /// Indicates the peer store that the given peer is useless. - /// - /// This decreases the scores of the addresses of that peer. - pub fn report_useless(&mut self, peer: &PeerId) { - for (peer_in_store, info_in_store) in self.store.iter_mut() { - if peer == peer_in_store { - for addr in info_in_store.addrs.iter_mut() { - addr.adjust_score(USELESS_PEER_SCORE_CHANGE); - } + a.adjust_score(SCORE_DIFF_ON_FAILED_TO_CONNECT); + trace!(target: "sub-libp2p", "Back off for {} = {:?}", addr, a.next_back_off); + a.back_off_until = Instant::now() + a.next_back_off; + a.next_back_off = cmp::min(a.next_back_off * FAIL_BACKOFF_MULTIPLIER, MAX_BACKOFF); } } } } -/// Reason why we disconnected from a peer. -#[derive(Debug)] -pub enum DisconnectReason { - /// No slot available locally anymore for this peer. - NoSlot, - /// A better way to connect to this peer has been found, therefore we disconnect from - /// the old one. - FoundBetterAddr, - /// The remote closed the connection. - RemoteClosed, - /// This node is considered useless for our needs. This includes time outs. - Useless, - /// The peer has been banned. - Banned, -} - fn peer_access<'a>(store: &'a mut FnvHashMap, peer: &PeerId) -> &'a mut PeerInfo { // TODO: should be optimizable if HashMap gets a better API store.entry(peer.clone()).or_insert_with(Default::default) @@ -472,17 +502,17 @@ struct Addr { next_back_off: Duration, /// Don't try to connect to this node until `Instant`. back_off_until: Instant, - score: Mutex, + score: AddrScore, } impl Clone for Addr { fn clone(&self) -> Addr { Addr { addr: self.addr.clone(), - expires: self.expires.clone(), - next_back_off: self.next_back_off.clone(), - back_off_until: self.back_off_until.clone(), - score: Mutex::new(self.score.lock().clone()), + expires: self.expires, + next_back_off: self.next_back_off, + back_off_until: self.back_off_until, + score: self.score.clone(), } } } @@ -500,58 +530,52 @@ struct AddrScore { impl Addr { /// Sets the addr to connected. If the score is lower than the given value, raises it to this /// value. - fn connected_now(&self, raise_to_min: u32) { - let mut score = self.score.lock(); + fn connected_now(&mut self, raise_to_min: u32) { let now = Instant::now(); - Addr::flush(&mut score, now); - score.connected_since = Some(now); - if score.score < raise_to_min { - score.score = raise_to_min; + Addr::flush(&mut self.score, now); + self.score.connected_since = Some(now); + if self.score.score < raise_to_min { + self.score.score = raise_to_min; } } /// Applies a modification to the score. - fn adjust_score(&self, score_diff: i32) { - let mut score = self.score.lock(); - Addr::flush(&mut score, Instant::now()); + fn adjust_score(&mut self, score_diff: i32) { + Addr::flush(&mut self.score, Instant::now()); if score_diff >= 0 { - score.score = cmp::min(MAX_SCORE, score.score + score_diff as u32); + self.score.score = cmp::min(MAX_SCORE, self.score.score + score_diff as u32); } else { - score.score = score.score.saturating_sub(-score_diff as u32); + self.score.score = self.score.score.saturating_sub(-score_diff as u32); } } /// Sets the addr to disconnected and applies a modification to the score. - fn disconnected_now(&self, score_diff: i32) { - let mut score = self.score.lock(); - Addr::flush(&mut score, Instant::now()); - score.connected_since = None; + fn disconnected_now(&mut self, score_diff: i32) { + Addr::flush(&mut self.score, Instant::now()); + self.score.connected_since = None; if score_diff >= 0 { - score.score = cmp::min(MAX_SCORE, score.score + score_diff as u32); + self.score.score = cmp::min(MAX_SCORE, self.score.score + score_diff as u32); } else { - score.score = score.score.saturating_sub(-score_diff as u32); + self.score.score = self.score.score.saturating_sub(-score_diff as u32); } } /// Returns true if we are connected to this addr. fn is_connected(&self) -> bool { - let score = self.score.lock(); - score.connected_since.is_some() + self.score.connected_since.is_some() } /// Returns the score, and true if we are connected to this addr. - fn score_and_is_connected(&self) -> (u32, bool) { - let mut score = self.score.lock(); - Addr::flush(&mut score, Instant::now()); - let is_connected = score.connected_since.is_some(); - (score.score, is_connected) + fn score_and_is_connected(&mut self) -> (u32, bool) { + Addr::flush(&mut self.score, Instant::now()); + let is_connected = self.score.connected_since.is_some(); + (self.score.score, is_connected) } /// Updates `score` and `latest_score_update`, and returns the score. - fn score(&self) -> u32 { - let mut score = self.score.lock(); - Addr::flush(&mut score, Instant::now()); - score.score + fn score(&mut self) -> u32 { + Addr::flush(&mut self.score, Instant::now()); + self.score.score } fn flush(score: &mut AddrScore, now: Instant) { @@ -572,8 +596,8 @@ impl Addr { /// Divides a `Duration` with a `Duration`. This exists in the stdlib but isn't stable yet. // TODO: remove this function once stable fn div_dur_with_dur(a: Duration, b: Duration) -> u32 { - let a_ms = a.as_secs() * 1_000_000 + (a.subsec_nanos() / 1_000) as u64; - let b_ms = b.as_secs() * 1_000_000 + (b.subsec_nanos() / 1_000) as u64; + let a_ms = a.as_secs() * 1_000_000 + u64::from(a.subsec_micros()); + let b_ms = b.as_secs() * 1_000_000 + u64::from(b.subsec_micros()); (a_ms / b_ms) as u32 } @@ -591,8 +615,8 @@ struct SerializedAddr { score: u32, } -impl<'a> From<&'a Addr> for SerializedAddr { - fn from(addr: &'a Addr) -> SerializedAddr { +impl<'a> From<&'a mut Addr> for SerializedAddr { + fn from(addr: &'a mut Addr) -> SerializedAddr { SerializedAddr { addr: addr.addr.to_string(), expires: addr.expires, @@ -602,9 +626,10 @@ impl<'a> From<&'a Addr> for SerializedAddr { } /// Attempts to load storage from a file. +/// Ignores any entry equal to `local_peer_id`. /// Deletes the file and returns an empty map if the file doesn't exist, cannot be opened /// or is corrupted. -fn try_load(path: impl AsRef) -> FnvHashMap { +fn try_load(path: impl AsRef, local_peer_id: &PeerId) -> FnvHashMap { let path = path.as_ref(); if !path.exists() { debug!(target: "sub-libp2p", "Peer storage file {:?} doesn't exist", path); @@ -648,7 +673,8 @@ fn try_load(path: impl AsRef) -> FnvHashMap { let data = Cursor::new(first_byte).chain(file); match serde_json::from_reader::<_, serde_json::Value>(data) { Ok(serde_json::Value::Null) => Default::default(), - Ok(serde_json::Value::Object(map)) => deserialize_tolerant(map.into_iter()), + Ok(serde_json::Value::Object(map)) => + deserialize_tolerant(map.into_iter(), local_peer_id), Ok(_) | Err(_) => { // The `Ok(_)` case means that the file doesn't contain a map. let _ = fs::remove_file(path); @@ -660,9 +686,10 @@ fn try_load(path: impl AsRef) -> FnvHashMap { /// Attempts to turn a deserialized version of the storage into the final version. /// -/// Skips entries that are invalid. +/// Skips entries that are invalid or equal to `local_peer_id`. fn deserialize_tolerant( - iter: impl Iterator + iter: impl Iterator, + local_peer_id: &PeerId ) -> FnvHashMap { let now = Instant::now(); let now_systime = SystemTime::now(); @@ -674,6 +701,10 @@ fn deserialize_tolerant( Err(_) => continue, }; + if &peer == local_peer_id { + continue + } + let info: SerializedPeerInfo = match serde_json::from_value(info) { Ok(i) => i, Err(_) => continue, @@ -695,16 +726,16 @@ fn deserialize_tolerant( expires: addr.expires, next_back_off: FIRST_CONNECT_FAIL_BACKOFF, back_off_until: now, - score: Mutex::new(AddrScore { + score: AddrScore { connected_since: None, score: addr.score, latest_score_update: now, - }), + }, }); } if addrs.is_empty() { - continue; + continue } out.insert(peer, PeerInfo { addrs }); @@ -716,18 +747,21 @@ fn deserialize_tolerant( /// Attempts to turn a deserialized version of the storage into the final version. /// /// Skips entries that are invalid or expired. -fn serialize(out: W, map: &FnvHashMap) -> Result<(), IoError> { +fn serialize(out: W, map: &mut FnvHashMap) -> Result<(), IoError> { let now = SystemTime::now(); - let array: FnvHashMap<_, _> = map.iter().filter_map(|(peer, info)| { + let array: FnvHashMap<_, _> = map.iter_mut().filter_map(|(peer, info)| { if info.addrs.is_empty() { return None } let peer = peer.to_base58(); let info = SerializedPeerInfo { - addrs: info.addrs.iter() - .filter(|a| a.expires > now || a.is_connected()) - .map(Into::into) + addrs: info.addrs.iter_mut() + .filter_map(|a| if a.expires > now || a.is_connected() { + Some(a.into()) + } else { + None + }) .collect(), }; diff --git a/core/network-libp2p/src/traits.rs b/core/network-libp2p/src/traits.rs index 7e87ec130138cdbbdec90170fdc295b6b34849cc..75bee4a87cc4bcaf8e6439eea7b2140658761b44 100644 --- a/core/network-libp2p/src/traits.rs +++ b/core/network-libp2p/src/traits.rs @@ -52,8 +52,10 @@ pub struct NetworkConfiguration { pub reserved_nodes: Vec, /// The non-reserved peer mode. pub non_reserved_mode: NonReservedPeerMode, - /// Client identifier + /// Client identifier. Sent over the wire for debugging purposes. pub client_version: String, + /// Name of the node. Sent over the wire for debugging purposes. + pub node_name: String, } impl Default for NetworkConfiguration { @@ -80,7 +82,8 @@ impl NetworkConfiguration { out_peers: 75, reserved_nodes: Vec::new(), non_reserved_mode: NonReservedPeerMode::Accept, - client_version: "Parity-network".into(), // TODO: meh + client_version: "unknown".into(), + node_name: "unknown".into(), } } diff --git a/core/network-libp2p/src/transport.rs b/core/network-libp2p/src/transport.rs index 89c6757bbcf9fa3784782e5f4c61c72a65678853..b7fd915e50edeeb6ae985d653b163918287dd9dc 100644 --- a/core/network-libp2p/src/transport.rs +++ b/core/network-libp2p/src/transport.rs @@ -14,33 +14,37 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use libp2p::{self, PeerId, Transport, mplex, secio, yamux}; -use libp2p::core::{either, upgrade, transport::boxed::Boxed, muxing::StreamMuxerBox}; -use libp2p::transport_timeout::TransportTimeout; -use std::time::Duration; -use std::usize; +use futures::prelude::*; +use libp2p::{InboundUpgradeExt, OutboundUpgradeExt, PeerId, Transport, mplex, secio, yamux, tcp, dns, websocket}; +use libp2p::core::{self, transport::boxed::Boxed, muxing::StreamMuxerBox}; +use std::{io, time::Duration, usize}; /// Builds the transport that serves as a common ground for all connections. pub fn build_transport( local_private_key: secio::SecioKeyPair -) -> Boxed<(PeerId, StreamMuxerBox)> { +) -> Boxed<(PeerId, StreamMuxerBox), io::Error> { let mut mplex_config = mplex::MplexConfig::new(); mplex_config.max_buffer_len_behaviour(mplex::MaxBufferBehaviour::Block); mplex_config.max_buffer_len(usize::MAX); - let base = libp2p::CommonTransport::new() + let transport = tcp::TcpConfig::new(); + let transport = websocket::WsConfig::new(transport.clone()).or_transport(transport); + let transport = dns::DnsConfig::new(transport); + + // TODO: rework the transport creation (https://github.com/libp2p/rust-libp2p/issues/783) + transport .with_upgrade(secio::SecioConfig::new(local_private_key)) .and_then(move |out, endpoint| { - let upgrade = upgrade::or( - upgrade::map(yamux::Config::default(), either::EitherOutput::First), - upgrade::map(mplex_config, either::EitherOutput::Second), - ); let peer_id = out.remote_key.into_peer_id(); - let upgrade = upgrade::map(upgrade, move |muxer| (peer_id, muxer)); - upgrade::apply(out.stream, upgrade, endpoint.into()) - }) - .map(|(id, muxer), _| (id, StreamMuxerBox::new(muxer))); + let peer_id2 = peer_id.clone(); + let upgrade = core::upgrade::SelectUpgrade::new(yamux::Config::default(), mplex_config) + .map_inbound(move |muxer| (peer_id, muxer)) + .map_outbound(move |muxer| (peer_id2, muxer)); - TransportTimeout::new(base, Duration::from_secs(20)) + core::upgrade::apply(out.stream, upgrade, endpoint) + .map(|(id, muxer)| (id, core::muxing::StreamMuxerBox::new(muxer))) + }) + .with_timeout(Duration::from_secs(20)) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) .boxed() } diff --git a/core/network-libp2p/tests/test.rs b/core/network-libp2p/tests/test.rs new file mode 100644 index 0000000000000000000000000000000000000000..5ff4255965274b6e7d4b647ee93b7fbed871f708 --- /dev/null +++ b/core/network-libp2p/tests/test.rs @@ -0,0 +1,180 @@ +// 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 . + +use futures::{future, stream, prelude::*, try_ready}; +use std::{io, iter}; +use substrate_network_libp2p::{ServiceEvent, multiaddr}; + +/// Builds two services. The second one and further have the first one as its bootstrap node. +/// This is to be used only for testing, and a panic will happen if something goes wrong. +fn build_nodes(num: usize) -> Vec { + let mut result: Vec = Vec::with_capacity(num); + + for _ in 0 .. num { + let mut boot_nodes = Vec::new(); + if !result.is_empty() { + let mut bootnode = result[0].listeners().next().unwrap().clone(); + bootnode.append(libp2p::multiaddr::Protocol::P2p(result[0].peer_id().clone().into())); + boot_nodes.push(bootnode.to_string()); + } + + let config = substrate_network_libp2p::NetworkConfiguration { + listen_addresses: vec![multiaddr![Ip4([127, 0, 0, 1]), Tcp(0u16)]], + boot_nodes, + ..substrate_network_libp2p::NetworkConfiguration::default() + }; + + let proto = substrate_network_libp2p::RegisteredProtocol::new(*b"tst", &[1]); + result.push(substrate_network_libp2p::start_service(config, iter::once(proto)).unwrap()); + } + + result +} + +#[test] +fn basic_two_nodes_connectivity() { + let (mut service1, mut service2) = { + let mut l = build_nodes(2).into_iter(); + let a = l.next().unwrap(); + let b = l.next().unwrap(); + (a, b) + }; + + let fut1 = future::poll_fn(move || -> io::Result<_> { + match try_ready!(service1.poll()) { + Some(ServiceEvent::OpenedCustomProtocol { protocol, version, .. }) => { + assert_eq!(protocol, *b"tst"); + assert_eq!(version, 1); + Ok(Async::Ready(())) + }, + _ => panic!(), + } + }); + + let fut2 = future::poll_fn(move || -> io::Result<_> { + match try_ready!(service2.poll()) { + Some(ServiceEvent::OpenedCustomProtocol { protocol, version, .. }) => { + assert_eq!(protocol, *b"tst"); + assert_eq!(version, 1); + Ok(Async::Ready(())) + }, + _ => panic!(), + } + }); + + let combined = fut1.select(fut2).map_err(|(err, _)| err); + tokio::runtime::Runtime::new().unwrap().block_on_all(combined).unwrap(); +} + +#[test] +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. + const NUM_PACKETS: u32 = 20000; + + let (mut service1, mut service2) = { + let mut l = build_nodes(2).into_iter(); + let a = l.next().unwrap(); + let b = l.next().unwrap(); + (a, b) + }; + + let fut1 = future::poll_fn(move || -> io::Result<_> { + loop { + match try_ready!(service1.poll()) { + Some(ServiceEvent::OpenedCustomProtocol { node_index, protocol, .. }) => { + for n in 0 .. NUM_PACKETS { + service1.send_custom_message(node_index, protocol, vec![(n % 256) as u8]); + } + }, + _ => panic!(), + } + } + }); + + let mut packet_counter = 0u32; + let fut2 = future::poll_fn(move || -> io::Result<_> { + loop { + match try_ready!(service2.poll()) { + Some(ServiceEvent::OpenedCustomProtocol { .. }) => {}, + Some(ServiceEvent::CustomMessage { data, .. }) => { + assert_eq!(data.len(), 1); + assert_eq!(u32::from(data[0]), packet_counter % 256); + packet_counter += 1; + if packet_counter == NUM_PACKETS { + return Ok(Async::Ready(())) + } + } + _ => panic!(), + } + } + }); + + let combined = fut1.select(fut2).map_err(|(err, _)| err); + tokio::runtime::Runtime::new().unwrap().block_on_all(combined).unwrap(); +} + +#[test] +fn many_nodes_connectivity() { + // Creates many nodes, then make sure that they are all connected to each other. + // Note: if you increase this number, keep in mind that there's a limit to the number of + // simultaneous connections which will make the test fail if it is reached. This can be + // increased in the `NetworkConfiguration`. + const NUM_NODES: usize = 25; + + let mut futures = build_nodes(NUM_NODES) + .into_iter() + .map(move |mut node| { + let mut num_connecs = 0; + stream::poll_fn(move || -> io::Result<_> { + loop { + match try_ready!(node.poll()) { + Some(ServiceEvent::OpenedCustomProtocol { .. }) => { + num_connecs += 1; + if num_connecs == NUM_NODES - 1 { + return Ok(Async::Ready(Some(()))) + } + } + // TODO: we sometimes receive a closed connection event; maybe this is + // benign, but it would be nice to figure out why + // (https://github.com/libp2p/rust-libp2p/issues/844) + Some(ServiceEvent::ClosedCustomProtocol { .. }) => {} + _ => panic!(), + } + } + }) + }) + .collect::>(); + + let mut successes = 0; + let combined = future::poll_fn(move || -> io::Result<_> { + for node in futures.iter_mut() { + match node.poll()? { + Async::Ready(Some(_)) => successes += 1, + Async::Ready(None) => unreachable!(), + Async::NotReady => () + } + } + + if successes == NUM_NODES { + Ok(Async::Ready(())) + } else { + Ok(Async::NotReady) + } + }); + + tokio::runtime::Runtime::new().unwrap().block_on(combined).unwrap(); +} diff --git a/core/network/Cargo.toml b/core/network/Cargo.toml index 7eadefb3637f3ec2607f2534a6ba108e60cc3cdb..c38d3695c93cda1d549bee81117a234490d0dec8 100644 --- a/core/network/Cargo.toml +++ b/core/network/Cargo.toml @@ -9,7 +9,7 @@ authors = ["Parity Technologies "] [dependencies] log = "0.4" -parking_lot = "0.4" +parking_lot = "0.7.1" error-chain = "0.12" bitflags = "1.0" futures = "0.1.17" @@ -20,7 +20,7 @@ substrate-primitives = { path = "../../core/primitives" } substrate-consensus-common = { path = "../../core/consensus/common" } substrate-client = { path = "../../core/client" } sr-primitives = { path = "../../core/sr-primitives" } -parity-codec = "2.1" +parity-codec = "2.2" parity-codec-derive = "2.1" substrate-network-libp2p = { path = "../../core/network-libp2p" } tokio = "0.1.11" diff --git a/core/network/README.adoc b/core/network/README.adoc deleted file mode 100644 index ac29b0cd0bfbc4aba2ff7f2a7631cd69d43461f6..0000000000000000000000000000000000000000 --- a/core/network/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Network - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/network/src/chain.rs b/core/network/src/chain.rs index 6e4ec75cde6bc0954157c4aa06cc28fb74f7e971..40edbfbadb9fe256e0c149deb23d97164842791a 100644 --- a/core/network/src/chain.rs +++ b/core/network/src/chain.rs @@ -18,18 +18,19 @@ use client::{self, Client as SubstrateClient, ClientInfo, BlockStatus, CallExecutor}; use client::error::Error; -use consensus::BlockImport; -use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; +use client::light::fetcher::ChangesProof; +use consensus::{BlockImport, Error as ConsensusError}; +use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, AuthorityIdFor}; use runtime_primitives::generic::{BlockId}; use consensus::{ImportBlock, ImportResult}; use runtime_primitives::Justification; -use primitives::{H256, Blake2Hasher, AuthorityId}; +use primitives::{H256, Blake2Hasher, storage::StorageKey}; /// Local client abstraction for the network. pub trait Client: Send + Sync { /// Import a new block. Parent is supposed to be existing in the blockchain. - fn import(&self, block: ImportBlock, new_authorities: Option>) - -> Result; + fn import(&self, block: ImportBlock, new_authorities: Option>>) + -> Result; /// Get blockchain info. fn info(&self) -> Result, Error>; @@ -63,66 +64,69 @@ pub trait Client: Send + Sync { &self, first: Block::Hash, last: Block::Hash, + min: Block::Hash, max: Block::Hash, - key: &[u8] - ) -> Result<(NumberFor, Vec>), Error>; + key: &StorageKey + ) -> Result, Error>; } -impl Client for SubstrateClient where +impl Client for SubstrateClient where B: client::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + 'static, - Self: BlockImport, + Self: BlockImport, Block: BlockT, + RA: Send + Sync { - fn import(&self, block: ImportBlock, new_authorities: Option>) - -> Result + fn import(&self, block: ImportBlock, new_authorities: Option>>) + -> Result { - (self as &SubstrateClient).import_block(block, new_authorities) + (self as &SubstrateClient).import_block(block, new_authorities) } fn info(&self) -> Result, Error> { - (self as &SubstrateClient).info() + (self as &SubstrateClient).info() } fn block_status(&self, id: &BlockId) -> Result { - (self as &SubstrateClient).block_status(id) + (self as &SubstrateClient).block_status(id) } fn block_hash(&self, block_number: ::Number) -> Result, Error> { - (self as &SubstrateClient).block_hash(block_number) + (self as &SubstrateClient).block_hash(block_number) } fn header(&self, id: &BlockId) -> Result, Error> { - (self as &SubstrateClient).header(id) + (self as &SubstrateClient).header(id) } fn body(&self, id: &BlockId) -> Result>, Error> { - (self as &SubstrateClient).body(id) + (self as &SubstrateClient).body(id) } fn justification(&self, id: &BlockId) -> Result, Error> { - (self as &SubstrateClient).justification(id) + (self as &SubstrateClient).justification(id) } fn header_proof(&self, block_number: ::Number) -> Result<(Block::Header, Vec>), Error> { - (self as &SubstrateClient).header_proof(&BlockId::Number(block_number)) + (self as &SubstrateClient).header_proof(&BlockId::Number(block_number)) } fn read_proof(&self, block: &Block::Hash, key: &[u8]) -> Result>, Error> { - (self as &SubstrateClient).read_proof(&BlockId::Hash(block.clone()), key) + (self as &SubstrateClient).read_proof(&BlockId::Hash(block.clone()), key) } fn execution_proof(&self, block: &Block::Hash, method: &str, data: &[u8]) -> Result<(Vec, Vec>), Error> { - (self as &SubstrateClient).execution_proof(&BlockId::Hash(block.clone()), method, data) + (self as &SubstrateClient).execution_proof(&BlockId::Hash(block.clone()), method, data) } fn key_changes_proof( &self, first: Block::Hash, last: Block::Hash, + min: Block::Hash, max: Block::Hash, - key: &[u8] - ) -> Result<(NumberFor, Vec>), Error> { - (self as &SubstrateClient).key_changes_proof(first, last, max, key) + key: &StorageKey + ) -> Result, Error> { + (self as &SubstrateClient).key_changes_proof(first, last, min, max, key) } } diff --git a/core/network/src/config.rs b/core/network/src/config.rs index fc6a1e374b77d567f76f081d20b83b4ecf214449..a7936ce4915ab34455f86c2c67981e8abc778f7d 100644 --- a/core/network/src/config.rs +++ b/core/network/src/config.rs @@ -14,9 +14,34 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -pub use service::Roles; +//! Configuration for the networking layer of Substrate. -/// Protocol configuration +pub use network_libp2p::{NonReservedPeerMode, NetworkConfiguration}; + +use chain::Client; +use codec; +use on_demand::OnDemandService; +use runtime_primitives::traits::{Block as BlockT}; +use service::{ExHashT, TransactionPool}; +use std::sync::Arc; + +/// Service initialization parameters. +pub struct Params { + /// Configuration. + pub config: ProtocolConfig, + /// Network layer configuration. + pub network_config: NetworkConfiguration, + /// Substrate relay chain access point. + pub chain: Arc>, + /// On-demand service reference. + pub on_demand: Option>>, + /// Transaction pool. + pub transaction_pool: Arc>, + /// Protocol specialization. + pub specialization: S, +} + +/// Configuration for the Substrate-specific part of the networking layer. #[derive(Clone)] pub struct ProtocolConfig { /// Assigned roles. @@ -30,3 +55,29 @@ impl Default for ProtocolConfig { } } } + +bitflags! { + /// Bitmask of the roles that a node fulfills. + pub struct Roles: u8 { + /// No network. + const NONE = 0b00000000; + /// Full node, does not participate in consensus. + const FULL = 0b00000001; + /// Light client node. + const LIGHT = 0b00000010; + /// Act as an authority + const AUTHORITY = 0b00000100; + } +} + +impl codec::Encode for Roles { + fn encode_to(&self, dest: &mut T) { + dest.push_byte(self.bits()) + } +} + +impl codec::Decode for Roles { + fn decode(input: &mut I) -> Option { + Self::from_bits(input.read_byte()?) + } +} diff --git a/core/network/src/consensus_gossip.rs b/core/network/src/consensus_gossip.rs index 0ecb0e5e68bde9359a90547f39dd428676813a4f..b9eec32b30cd1f95108ffa0d755d1c80b72e8aa7 100644 --- a/core/network/src/consensus_gossip.rs +++ b/core/network/src/consensus_gossip.rs @@ -24,14 +24,11 @@ use rand::{self, Rng}; use network_libp2p::NodeIndex; use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, Hash, HashFor}; use runtime_primitives::generic::BlockId; -use message::generic::{Message, ConsensusMessage}; +pub use message::generic::{Message, ConsensusMessage}; use protocol::Context; -use service::Roles; -use specialization::Specialization; -use StatusMessage; -use generic_message; +use config::Roles; -// TODO: Add additional spam/DoS attack protection. +// FIXME: Add additional spam/DoS attack protection: https://github.com/paritytech/substrate/issues/1115 const MESSAGE_LIFETIME: Duration = Duration::from_secs(600); struct PeerConsensus { @@ -43,22 +40,20 @@ struct MessageEntry { topic: B::Hash, message_hash: B::Hash, message: ConsensusMessage, + broadcast: bool, instant: Instant, } /// Consensus network protocol handler. Manages statements and candidate requests. pub struct ConsensusGossip { peers: HashMap>, - live_message_sinks: HashMap>, + live_message_sinks: HashMap>>, messages: Vec>, known_messages: HashSet<(B::Hash, B::Hash)>, session_start: Option, } -impl ConsensusGossip -where - B::Header: HeaderT -{ +impl ConsensusGossip { /// Create a new instance. pub fn new() -> Self { ConsensusGossip { @@ -84,7 +79,7 @@ where let mut known_messages = HashSet::new(); for entry in self.messages.iter() { known_messages.insert((entry.topic, entry.message_hash)); - protocol.send_message(who, Message::Consensus(entry.topic.clone(), entry.message.clone())); + protocol.send_message(who, Message::Consensus(entry.topic.clone(), entry.message.clone(), entry.broadcast)); } self.peers.insert(who, PeerConsensus { known_messages, @@ -104,10 +99,27 @@ where protocol: &mut Context, message_hash: B::Hash, topic: B::Hash, + broadcast: bool, get_message: F, ) where F: Fn() -> ConsensusMessage, { + if broadcast { + for (id, ref mut peer) in self.peers.iter_mut() { + if peer.known_messages.insert((topic.clone(), message_hash.clone())) { + let message = get_message(); + if peer.is_authority { + trace!(target:"gossip", "Propagating to authority {}: {:?}", id, message); + } else { + trace!(target:"gossip", "Propagating to {}: {:?}", id, message); + } + protocol.send_message(*id, Message::Consensus(topic, message, broadcast)); + } + } + + return; + } + let mut non_authorities: Vec<_> = self.peers.iter() .filter_map(|(id, ref peer)| if !peer.is_authority && !peer.known_messages.contains(&(topic, message_hash)) { Some(*id) } else { None }) .collect(); @@ -124,24 +136,25 @@ where if peer.known_messages.insert((topic.clone(), message_hash.clone())) { let message = get_message(); trace!(target:"gossip", "Propagating to authority {}: {:?}", id, message); - protocol.send_message(*id, Message::Consensus(topic, message)); + protocol.send_message(*id, Message::Consensus(topic, message, broadcast)); } } else if non_authorities.contains(&id) { let message = get_message(); trace!(target:"gossip", "Propagating to {}: {:?}", id, message); peer.known_messages.insert((topic.clone(), message_hash.clone())); - protocol.send_message(*id, Message::Consensus(topic, message)); + protocol.send_message(*id, Message::Consensus(topic, message, broadcast)); } } } - fn register_message(&mut self, message_hash: B::Hash, topic: B::Hash, get_message: F) + fn register_message(&mut self, message_hash: B::Hash, topic: B::Hash, broadcast: bool, get_message: F) where F: Fn() -> ConsensusMessage { if self.known_messages.insert((topic, message_hash)) { self.messages.push(MessageEntry { topic, message_hash, + broadcast, instant: Instant::now(), message: get_message(), }); @@ -156,7 +169,10 @@ where /// Prune old or no longer relevant consensus messages. Provide a predicate /// for pruning, which returns `false` when the items with a given topic should be pruned. pub fn collect_garbage bool>(&mut self, predicate: P) { - self.live_message_sinks.retain(|_, sink| !sink.is_closed()); + self.live_message_sinks.retain(|_, sinks| { + sinks.retain(|sink| !sink.is_closed()); + !sinks.is_empty() + }); let hashes = &mut self.known_messages; let before = self.messages.len(); @@ -181,7 +197,7 @@ where for entry in self.messages.iter().filter(|e| e.topic == topic) { tx.unbounded_send(entry.message.clone()).expect("receiver known to be live; qed"); } - self.live_message_sinks.insert(topic, tx); + self.live_message_sinks.entry(topic).or_default().push(tx); rx } @@ -196,6 +212,7 @@ where who: NodeIndex, topic: B::Hash, message: ConsensusMessage, + broadcast: bool, ) -> Option<(B::Hash, ConsensusMessage)> { let message_hash = HashFor::::hash(&message[..]); @@ -223,12 +240,14 @@ where use std::collections::hash_map::Entry; peer.known_messages.insert((topic, message_hash)); if let Entry::Occupied(mut entry) = self.live_message_sinks.entry(topic) { - debug!(target: "gossip", "Pushing consensus message to sink for {}.", topic); - if let Err(e) = entry.get().unbounded_send(message.clone()) { - trace!(target:"gossip", "Error broadcasting message notification: {:?}", e); - } - - if entry.get().is_closed() { + debug!(target: "gossip", "Pushing consensus message to sinks for {}.", topic); + entry.get_mut().retain(|sink| { + if let Err(e) = sink.unbounded_send(message.clone()) { + trace!(target:"gossip", "Error broadcasting message notification: {:?}", e); + } + !sink.is_closed() + }); + if entry.get().is_empty() { entry.remove_entry(); } } @@ -237,21 +256,34 @@ where return None; } - self.multicast_inner(protocol, message_hash, topic, || message.clone()); + self.multicast_inner(protocol, message_hash, topic, broadcast, || message.clone()); Some((topic, message)) } /// Multicast a message to all peers. - pub fn multicast(&mut self, protocol: &mut Context, topic: B::Hash, message: ConsensusMessage) { + pub fn multicast( + &mut self, + protocol: &mut Context, + topic: B::Hash, + message: ConsensusMessage, + broadcast: bool, + ) { let message_hash = HashFor::::hash(&message); - self.multicast_inner(protocol, message_hash, topic, || message.clone()); + self.multicast_inner(protocol, message_hash, topic, broadcast, || message.clone()); } - fn multicast_inner(&mut self, protocol: &mut Context, message_hash: B::Hash, topic: B::Hash, get_message: F) + fn multicast_inner( + &mut self, + protocol: &mut Context, + message_hash: B::Hash, + topic: B::Hash, + broadcast: bool, + get_message: F, + ) where F: Fn() -> ConsensusMessage { - self.register_message(message_hash, topic, &get_message); - self.propagate(protocol, message_hash, topic, get_message); + self.register_message(message_hash, topic, broadcast, &get_message); + self.propagate(protocol, message_hash, topic, broadcast, get_message); } /// Note new consensus session. @@ -262,52 +294,6 @@ where } } -impl Specialization for ConsensusGossip where - Block::Header: HeaderT -{ - fn status(&self) -> Vec { - Vec::new() - } - - fn on_connect(&mut self, ctx: &mut Context, who: NodeIndex, status: StatusMessage) { - self.new_peer(ctx, who, status.roles); - } - - fn on_disconnect(&mut self, ctx: &mut Context, who: NodeIndex) { - self.peer_disconnected(ctx, who); - } - - fn on_message( - &mut self, - ctx: &mut Context, - who: NodeIndex, - message: &mut Option<::message::Message> - ) { - match message.take() { - Some(generic_message::Message::Consensus(topic, msg)) => { - trace!(target: "gossip", "Consensus message from {}: {:?}", who, msg); - self.on_incoming(ctx, who, topic, msg); - } - r => *message = r, - } - } - - fn on_abort(&mut self) { - self.abort(); - } - - fn maintain_peers(&mut self, _ctx: &mut Context) { - self.collect_garbage(|_| true); - } - - fn on_block_imported( - &mut self, - _ctx: &mut Context, - _hash: ::Hash, - _header: &::Header) - {} -} - #[cfg(test)] mod tests { use runtime_primitives::testing::{H256, Block as RawBlock, ExtrinsicWrapper}; @@ -334,6 +320,7 @@ mod tests { message_hash: $hash, instant: $now, message: $m, + broadcast: false, }) } } @@ -378,7 +365,7 @@ mod tests { let message_hash = HashFor::::hash(&message); let topic = HashFor::::hash(&[1,2,3]); - consensus.register_message(message_hash, topic, || message.clone()); + consensus.register_message(message_hash, topic, false, || message.clone()); let stream = consensus.messages_for(topic); assert_eq!(stream.wait().next(), Some(Ok(message))); @@ -392,9 +379,29 @@ mod tests { let msg_a = vec![1, 2, 3]; let msg_b = vec![4, 5, 6]; - consensus.register_message(HashFor::::hash(&msg_a), topic, || msg_a.clone()); - consensus.register_message(HashFor::::hash(&msg_b), topic, || msg_b.clone()); + consensus.register_message(HashFor::::hash(&msg_a), topic, false, || msg_a.clone()); + consensus.register_message(HashFor::::hash(&msg_b), topic, false, || msg_b.clone()); assert_eq!(consensus.messages.len(), 2); } + + #[test] + fn can_keep_multiple_subscribers_per_topic() { + use futures::Stream; + + let mut consensus = ConsensusGossip::::new(); + + let message = vec![1, 2, 3]; + + let message_hash = HashFor::::hash(&message); + let topic = HashFor::::hash(&[1,2,3]); + + consensus.register_message(message_hash, topic, false, || message.clone()); + + let stream1 = consensus.messages_for(topic); + let stream2 = consensus.messages_for(topic); + + assert_eq!(stream1.wait().next(), Some(Ok(message.clone()))); + assert_eq!(stream2.wait().next(), Some(Ok(message))); + } } diff --git a/core/network/src/import_queue.rs b/core/network/src/import_queue.rs deleted file mode 100644 index b31dee6310999571c92356e7832a5ce547a2ed26..0000000000000000000000000000000000000000 --- a/core/network/src/import_queue.rs +++ /dev/null @@ -1,799 +0,0 @@ -// Copyright 2017-2018 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Import Queue primitive: something which can verify and import blocks. -//! -//! This serves as an intermediate and abstracted step between synchronization -//! and import. Each mode of consensus will have its own requirements for block verification. -//! Some algorithms can verify in parallel, while others only sequentially. -//! -//! The `ImportQueue` trait allows such verification strategies to be instantiated. -//! The `BasicQueue` and `BasicVerifier` traits allow serial queues to be -//! instantiated simply. - -use std::collections::{HashSet, VecDeque}; -use std::sync::{Arc, Weak}; -use std::sync::atomic::{AtomicBool, Ordering}; -use parking_lot::{Condvar, Mutex, RwLock}; -use network_libp2p::{NodeIndex, Severity}; -use primitives::AuthorityId; - -use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; - -pub use blocks::BlockData; -use chain::Client; -use error::{ErrorKind, Error}; -use protocol::Context; -use service::ExecuteInContext; -use sync::ChainSync; - -pub use consensus::{ImportBlock, ImportResult, BlockOrigin}; - - -#[cfg(any(test, feature = "test-helpers"))] -use std::cell::RefCell; - -/// Verify a justification of a block -pub trait Verifier: Send + Sync + Sized { - /// Verify the given data and return the ImportBlock and an optional - /// new set of validators to import. If not, err with an Error-Message - /// presented to the User in the logs. - fn verify( - &self, - origin: BlockOrigin, - header: B::Header, - justification: Vec, - body: Option> - ) -> Result<(ImportBlock, Option>), String>; -} - -/// Blocks import queue API. -pub trait ImportQueue: Send + Sync { - /// Start background work for the queue as necessary. - /// - /// This is called automatically by the network service when synchronization - /// begins. - fn start( - &self, - _sync: Weak>>, - _service: Weak, - _chain: Weak> - ) -> Result<(), Error> where - Self: Sized, - E: 'static + ExecuteInContext, - { - Ok(()) - } - /// Clear the queue when sync is restarting. - fn clear(&self); - /// Clears the import queue and stops importing. - fn stop(&self); - /// Get queue status. - fn status(&self) -> ImportQueueStatus; - /// Is block with given hash currently in the queue. - fn is_importing(&self, hash: &B::Hash) -> bool; - /// Import bunch of blocks. - fn import_blocks(&self, origin: BlockOrigin, blocks: Vec>); -} - -/// Import queue status. It isn't completely accurate. -pub struct ImportQueueStatus { - /// Number of blocks that are currently in the queue. - pub importing_count: usize, - /// The number of the best block that was ever in the queue since start/last failure. - pub best_importing_number: <::Header as HeaderT>::Number, -} - -/// Basic block import queue that is importing blocks sequentially in a separate thread, -/// with pluggable verification. -pub struct BasicQueue> { - handle: Mutex>>, - data: Arc>, - verifier: Arc, -} - -/// Locks order: queue, queue_blocks, best_importing_number -struct AsyncImportQueueData { - signal: Condvar, - queue: Mutex>)>>, - queue_blocks: RwLock>, - best_importing_number: RwLock<<::Header as HeaderT>::Number>, - is_stopping: AtomicBool, -} - -impl> BasicQueue { - /// Instantiate a new basic queue, with given verifier. - pub fn new(verifier: Arc) -> Self { - Self { - handle: Mutex::new(None), - data: Arc::new(AsyncImportQueueData::new()), - verifier, - } - } -} - -impl AsyncImportQueueData { - fn new() -> Self { - Self { - signal: Default::default(), - queue: Mutex::new(VecDeque::new()), - queue_blocks: RwLock::new(HashSet::new()), - best_importing_number: RwLock::new(Zero::zero()), - is_stopping: Default::default(), - } - } -} - -impl> ImportQueue for BasicQueue { - fn start>( - &self, - sync: Weak>>, - service: Weak, - chain: Weak> - ) -> Result<(), Error> { - debug_assert!(self.handle.lock().is_none()); - - let qdata = self.data.clone(); - let verifier = self.verifier.clone(); - *self.handle.lock() = Some(::std::thread::Builder::new().name("ImportQueue".into()).spawn(move || { - import_thread(sync, service, chain, qdata, verifier) - }).map_err(|err| Error::from(ErrorKind::Io(err)))?); - Ok(()) - } - - fn clear(&self) { - let mut queue = self.data.queue.lock(); - let mut queue_blocks = self.data.queue_blocks.write(); - let mut best_importing_number = self.data.best_importing_number.write(); - queue_blocks.clear(); - queue.clear(); - *best_importing_number = Zero::zero(); - } - - fn stop(&self) { - self.clear(); - if let Some(handle) = self.handle.lock().take() { - { - // Perform storing the stop flag and signalling under a single lock. - let _queue_lock = self.data.queue.lock(); - self.data.is_stopping.store(true, Ordering::SeqCst); - self.data.signal.notify_one(); - } - - let _ = handle.join(); - } - } - - fn status(&self) -> ImportQueueStatus { - ImportQueueStatus { - importing_count: self.data.queue_blocks.read().len(), - best_importing_number: *self.data.best_importing_number.read(), - } - } - - fn is_importing(&self, hash: &B::Hash) -> bool { - self.data.queue_blocks.read().contains(hash) - } - - fn import_blocks(&self, origin: BlockOrigin, blocks: Vec>) { - if blocks.is_empty() { - return; - } - - trace!(target:"sync", "Scheduling {} blocks for import", blocks.len()); - - let mut queue = self.data.queue.lock(); - let mut queue_blocks = self.data.queue_blocks.write(); - let mut best_importing_number = self.data.best_importing_number.write(); - let new_best_importing_number = blocks.last().and_then(|b| b.block.header.as_ref().map(|h| h.number().clone())).unwrap_or_else(|| Zero::zero()); - queue_blocks.extend(blocks.iter().map(|b| b.block.hash.clone())); - if new_best_importing_number > *best_importing_number { - *best_importing_number = new_best_importing_number; - } - queue.push_back((origin, blocks)); - self.data.signal.notify_one(); - } -} - -impl> Drop for BasicQueue { - fn drop(&mut self) { - self.stop(); - } -} - -/// Blocks import thread. -fn import_thread, V: Verifier>( - sync: Weak>>, - service: Weak, - chain: Weak>, - qdata: Arc>, - verifier: Arc -) { - trace!(target: "sync", "Starting import thread"); - loop { - let new_blocks = { - let mut queue_lock = qdata.queue.lock(); - - // We are holding the same lock that `stop` takes so here we either see that stop flag - // is active or wait for the signal. The latter one unlocks the mutex and this gives a chance - // to `stop` to generate the signal. - if qdata.is_stopping.load(Ordering::SeqCst) { - break; - } - if queue_lock.is_empty() { - qdata.signal.wait(&mut queue_lock); - } - - match queue_lock.pop_front() { - Some(new_blocks) => new_blocks, - None => break, - } - }; - - match (sync.upgrade(), service.upgrade(), chain.upgrade()) { - (Some(sync), Some(service), Some(chain)) => { - let blocks_hashes: Vec = new_blocks.1.iter().map(|b| b.block.hash.clone()).collect(); - if !import_many_blocks( - &mut SyncLink{chain: &sync, client: &*chain, context: &*service}, - Some(&*qdata), - new_blocks, - verifier.clone(), - ) { - break; - } - - let mut queue_blocks = qdata.queue_blocks.write(); - for blocks_hash in blocks_hashes { - queue_blocks.remove(&blocks_hash); - } - }, - _ => break, - } - } - - trace!(target: "sync", "Stopping import thread"); -} -/// ChainSync link trait. -trait SyncLinkApi { - /// Get chain reference. - fn chain(&self) -> &Client; - /// Block imported. - fn block_imported(&mut self, hash: &B::Hash, number: NumberFor); - /// Maintain sync. - fn maintain_sync(&mut self); - /// Disconnect from peer. - fn useless_peer(&mut self, who: NodeIndex, reason: &str); - /// Disconnect from peer and restart sync. - fn note_useless_and_restart_sync(&mut self, who: NodeIndex, reason: &str); - /// Restart sync. - fn restart(&mut self); -} - - -/// Link with the ChainSync service. -struct SyncLink<'a, B: 'a + BlockT, E: 'a + ExecuteInContext> { - pub chain: &'a RwLock>, - pub client: &'a Client, - pub context: &'a E, -} - -impl<'a, B: 'static + BlockT, E: 'a + ExecuteInContext> SyncLink<'a, B, E> { - /// Execute closure with locked ChainSync. - fn with_sync, &mut Context)>(&mut self, closure: F) { - let service = self.context; - let sync = self.chain; - service.execute_in_context(move |protocol| { - let mut sync = sync.write(); - closure(&mut *sync, protocol) - }); - } -} - -impl<'a, B: 'static + BlockT, E: 'a + ExecuteInContext> SyncLinkApi for SyncLink<'a, B, E> { - - fn chain(&self) -> &Client { - self.client - } - - fn block_imported(&mut self, hash: &B::Hash, number: NumberFor) { - self.with_sync(|sync, _| sync.block_imported(&hash, number)) - } - - fn maintain_sync(&mut self) { - self.with_sync(|sync, protocol| sync.maintain_sync(protocol)) - } - - fn useless_peer(&mut self, who: NodeIndex, reason: &str) { - self.with_sync(|_, protocol| protocol.report_peer(who, Severity::Useless(reason))) - } - - fn note_useless_and_restart_sync(&mut self, who: NodeIndex, reason: &str) { - self.with_sync(|sync, protocol| { - protocol.report_peer(who, Severity::Useless(reason)); // is this actually malign or just useless? - sync.restart(protocol); - }) - } - - fn restart(&mut self) { - self.with_sync(|sync, protocol| sync.restart(protocol)) - } -} - -/// Block import successful result. -#[derive(Debug, PartialEq)] -enum BlockImportResult { - /// Imported known block. - ImportedKnown(H, N), - /// Imported unknown block. - ImportedUnknown(H, N), -} - -/// Block import error. -#[derive(Debug, PartialEq)] -enum BlockImportError { - /// Block missed header, can't be imported - IncompleteHeader(Option), - /// Block missed justification, can't be imported - IncompleteJustification(Option), - /// Block verification failed, can't be imported - VerificationFailed(Option, String), - /// Block is known to be Bad - BadBlock(Option), - /// Block has an unknown parent - UnknownParent, - /// Other Error. - Error, -} - -/// Import a bunch of blocks. -fn import_many_blocks<'a, B: BlockT, V: Verifier>( - link: &mut SyncLinkApi, - qdata: Option<&AsyncImportQueueData>, - blocks: (BlockOrigin, Vec>), - verifier: Arc -) -> bool -{ - let (blocks_origin, blocks) = blocks; - let count = blocks.len(); - let mut imported = 0; - - let blocks_range = match ( - blocks.first().and_then(|b| b.block.header.as_ref().map(|h| h.number())), - blocks.last().and_then(|b| b.block.header.as_ref().map(|h| h.number())), - ) { - (Some(first), Some(last)) if first != last => format!(" ({}..{})", first, last), - (Some(first), Some(_)) => format!(" ({})", first), - _ => Default::default(), - }; - trace!(target:"sync", "Starting import of {} blocks {}", count, blocks_range); - - // Blocks in the response/drain should be in ascending order. - for block in blocks { - let import_result = import_single_block( - link.chain(), - blocks_origin.clone(), - block, - verifier.clone(), - ); - let is_import_failed = import_result.is_err(); - imported += process_import_result(link, import_result); - if is_import_failed { - qdata.map(|qdata| *qdata.best_importing_number.write() = Zero::zero()); - return true; - } - - if qdata.map(|qdata| qdata.is_stopping.load(Ordering::SeqCst)).unwrap_or_default() { - return false; - } - } - - trace!(target: "sync", "Imported {} of {}", imported, count); - link.maintain_sync(); - true -} - -/// Single block import function. -fn import_single_block>( - chain: &Client, - block_origin: BlockOrigin, - block: BlockData, - verifier: Arc -) -> Result::Header as HeaderT>::Number>, BlockImportError> -{ - let peer = block.origin; - let block = block.block; - - let (header, justification) = match (block.header, block.justification) { - (Some(header), Some(justification)) => (header, justification), - (None, _) => { - if let Some(peer) = peer { - debug!(target: "sync", "Header {} was not provided by {} ", block.hash, peer); - } else { - debug!(target: "sync", "Header {} was not provided ", block.hash); - } - return Err(BlockImportError::IncompleteHeader(peer)) //TODO: use persistent ID - }, - (_, None) => { - if let Some(peer) = peer { - debug!(target: "sync", "Justification set for block {} was not provided by {} ", block.hash, peer); - } else { - debug!(target: "sync", "Justification set for block {} was not provided", block.hash); - } - return Err(BlockImportError::IncompleteJustification(peer)) //TODO: use persistent ID - } - }; - - let number = header.number().clone(); - let hash = header.hash(); - let parent = header.parent_hash().clone(); - let (import_block, new_authorities) = verifier.verify(block_origin, header, justification, block.body) - .map_err(|msg| { - if let Some(peer) = peer { - trace!(target: "sync", "Verifying {}({}) from {} failed: {}", number, hash, peer, msg); - } else { - trace!(target: "sync", "Verifying {}({}) failed: {}", number, hash, msg); - } - BlockImportError::VerificationFailed(peer, msg) - })?; - - match chain.import(import_block, new_authorities) { - Ok(ImportResult::AlreadyInChain) => { - trace!(target: "sync", "Block already in chain {}: {:?}", number, hash); - Ok(BlockImportResult::ImportedKnown(hash, number)) - }, - Ok(ImportResult::AlreadyQueued) => { - trace!(target: "sync", "Block already queued {}: {:?}", number, hash); - Ok(BlockImportResult::ImportedKnown(hash, number)) - }, - Ok(ImportResult::Queued) => { - trace!(target: "sync", "Block queued {}: {:?}", number, hash); - Ok(BlockImportResult::ImportedUnknown(hash, number)) - }, - Ok(ImportResult::UnknownParent) => { - debug!(target: "sync", "Block with unknown parent {}: {:?}, parent: {:?}", number, hash, parent); - Err(BlockImportError::UnknownParent) - }, - Ok(ImportResult::KnownBad) => { - debug!(target: "sync", "Peer gave us a bad block {}: {:?}", number, hash); - Err(BlockImportError::BadBlock(peer)) //TODO: use persistent ID - } - Err(e) => { - debug!(target: "sync", "Error importing block {}: {:?}: {:?}", number, hash, e); - Err(BlockImportError::Error) - } - } -} - -/// Process single block import result. -fn process_import_result<'a, B: BlockT>( - link: &mut SyncLinkApi, - result: Result::Header as HeaderT>::Number>, BlockImportError> -) -> usize -{ - match result { - Ok(BlockImportResult::ImportedKnown(hash, number)) => { - link.block_imported(&hash, number); - 1 - }, - Ok(BlockImportResult::ImportedUnknown(hash, number)) => { - link.block_imported(&hash, number); - 1 - }, - Err(BlockImportError::IncompleteJustification(who)) => { - if let Some(peer) = who { - link.useless_peer(peer, "Sent block with incomplete justification to import"); - } - 0 - }, - Err(BlockImportError::IncompleteHeader(who)) => { - if let Some(peer) = who { - link.useless_peer(peer, "Sent block with incomplete header to import"); - } - 0 - }, - Err(BlockImportError::VerificationFailed(who, e)) => { - if let Some(peer) = who { - link.useless_peer(peer, &format!("Verification failed: {}", e)); - } - 0 - }, - Err(BlockImportError::BadBlock(who)) => { - if let Some(peer) = who { - link.note_useless_and_restart_sync(peer, "Sent us a bad block"); - } - 0 - }, - Err(BlockImportError::UnknownParent) | Err(BlockImportError::Error) => { - link.restart(); - 0 - }, - } -} - - -#[cfg(any(test, feature = "test-helpers"))] -struct ImportCB(RefCell>) -> bool>>>); - -#[cfg(any(test, feature = "test-helpers"))] -impl ImportCB { - fn new() -> Self { - ImportCB(RefCell::new(None)) - } - fn set(&self, cb: Box) - where F: 'static + Fn(BlockOrigin, Vec>) -> bool - { - *self.0.borrow_mut() = Some(cb); - } - fn call(&self, origin: BlockOrigin, data: Vec>) -> bool { - let b = self.0.borrow(); - b.as_ref().expect("The Callback has been set before. qed.")(origin, data) - } -} - -#[cfg(any(test, feature = "test-helpers"))] -unsafe impl Send for ImportCB {} -#[cfg(any(test, feature = "test-helpers"))] -unsafe impl Sync for ImportCB {} - - -#[cfg(any(test, feature = "test-helpers"))] -/// A Verifier that accepts all blocks and passes them on with the configured -/// finality to be imported. -pub struct PassThroughVerifier(pub bool); - -#[cfg(any(test, feature = "test-helpers"))] -/// This Verifiyer accepts all data as valid -impl Verifier for PassThroughVerifier { - fn verify( - &self, - origin: BlockOrigin, - header: B::Header, - justification: Vec, - body: Option> - ) -> Result<(ImportBlock, Option>), String> { - Ok((ImportBlock { - origin, - header, - body, - finalized: self.0, - external_justification: justification, - post_runtime_digests: vec![], - auxiliary: Vec::new(), - }, None)) - } -} - -#[cfg(any(test, feature = "test-helpers"))] -/// Blocks import queue that is importing blocks in the same thread. -/// The boolean value indicates whether blocks should be imported without instant finality. -pub struct SyncImportQueue>(Arc, ImportCB); -#[cfg(any(test, feature = "test-helpers"))] -impl> SyncImportQueue { - /// Create a new SyncImportQueue wrapping the given Verifier - pub fn new(verifier: Arc) -> Self { - SyncImportQueue(verifier, ImportCB::new()) - } -} - -#[cfg(any(test, feature = "test-helpers"))] -impl> ImportQueue for SyncImportQueue -{ - fn start>( - &self, - sync: Weak>>, - service: Weak, - chain: Weak> - ) -> Result<(), Error> { - let v = self.0.clone(); - self.1.set(Box::new(move | origin, new_blocks | { - let verifier = v.clone(); - match (sync.upgrade(), service.upgrade(), chain.upgrade()) { - (Some(sync), Some(service), Some(chain)) => - import_many_blocks( - &mut SyncLink{chain: &sync, client: &*chain, context: &*service}, - None, - (origin, new_blocks), - verifier, - ), - _ => false - } - })); - Ok(()) - } - fn clear(&self) { } - - fn stop(&self) { } - - fn status(&self) -> ImportQueueStatus { - ImportQueueStatus { - importing_count: 0, - best_importing_number: Zero::zero(), - } - } - - fn is_importing(&self, _hash: &B::Hash) -> bool { - false - } - - fn import_blocks(&self, origin: BlockOrigin, blocks: Vec>) { - self.1.call(origin, blocks); - } -} - -#[cfg(test)] -pub mod tests { - use client; - use message; - use test_client::{self, TestClient}; - use test_client::runtime::{Block, Hash}; - use on_demand::tests::DummyExecutor; - use runtime_primitives::generic::BlockId; - use super::*; - - - struct TestLink { - chain: Arc>, - imported: usize, - maintains: usize, - disconnects: usize, - restarts: usize, - } - - impl TestLink { - fn new() -> TestLink { - TestLink { - chain: Arc::new(test_client::new()), - imported: 0, - maintains: 0, - disconnects: 0, - restarts: 0, - } - } - - fn total(&self) -> usize { - self.imported + self.maintains + self.disconnects + self.restarts - } - } - - impl SyncLinkApi for TestLink { - fn chain(&self) -> &Client { &*self.chain } - fn block_imported(&mut self, _hash: &Hash, _number: NumberFor) { self.imported += 1; } - fn maintain_sync(&mut self) { self.maintains += 1; } - fn useless_peer(&mut self, _: NodeIndex, _: &str) { self.disconnects += 1; } - fn note_useless_and_restart_sync(&mut self, _: NodeIndex, _: &str) { self.disconnects += 1; self.restarts += 1; } - fn restart(&mut self) { self.restarts += 1; } - } - - fn prepare_good_block() -> (client::Client, Hash, u64, BlockData) { - let client = test_client::new(); - let block = client.new_block().unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::File, block).unwrap(); - - let (hash, number) = (client.block_hash(1).unwrap().unwrap(), 1); - let block = message::BlockData:: { - hash: client.block_hash(1).unwrap().unwrap(), - header: client.header(&BlockId::Number(1)).unwrap(), - body: None, - receipt: None, - message_queue: None, - justification: client.justification(&BlockId::Number(1)).unwrap(), - }; - - (client, hash, number, BlockData { block, origin: Some(0) }) - } - - #[test] - fn import_single_good_block_works() { - let (_, hash, number, block) = prepare_good_block(); - assert_eq!( - import_single_block(&test_client::new(), BlockOrigin::File, block, Arc::new(PassThroughVerifier(true))), - Ok(BlockImportResult::ImportedUnknown(hash, number)) - ); - } - - #[test] - fn import_single_good_known_block_is_ignored() { - let (client, hash, number, block) = prepare_good_block(); - assert_eq!( - import_single_block(&client, BlockOrigin::File, block, Arc::new(PassThroughVerifier(true))), - Ok(BlockImportResult::ImportedKnown(hash, number)) - ); - } - - #[test] - fn import_single_good_block_without_header_fails() { - let (_, _, _, mut block) = prepare_good_block(); - block.block.header = None; - assert_eq!( - import_single_block(&test_client::new(), BlockOrigin::File, block, Arc::new(PassThroughVerifier(true))), - Err(BlockImportError::IncompleteHeader(Some(0))) - ); - } - - #[test] - fn import_single_good_block_without_justification_fails() { - let (_, _, _, mut block) = prepare_good_block(); - block.block.justification = None; - assert_eq!( - import_single_block(&test_client::new(), BlockOrigin::File, block, Arc::new(PassThroughVerifier(true))), - Err(BlockImportError::IncompleteJustification(Some(0))) - ); - } - - #[test] - fn process_import_result_works() { - let mut link = TestLink::new(); - assert_eq!(process_import_result::(&mut link, Ok(BlockImportResult::ImportedKnown(Default::default(), 0))), 1); - assert_eq!(link.total(), 1); - - let mut link = TestLink::new(); - assert_eq!(process_import_result::(&mut link, Ok(BlockImportResult::ImportedKnown(Default::default(), 0))), 1); - assert_eq!(link.total(), 1); - assert_eq!(link.imported, 1); - - let mut link = TestLink::new(); - assert_eq!(process_import_result::(&mut link, Ok(BlockImportResult::ImportedUnknown(Default::default(), 0))), 1); - assert_eq!(link.total(), 1); - assert_eq!(link.imported, 1); - - let mut link = TestLink::new(); - assert_eq!(process_import_result::(&mut link, Err(BlockImportError::IncompleteHeader(Some(0)))), 0); - assert_eq!(link.total(), 1); - assert_eq!(link.disconnects, 1); - - let mut link = TestLink::new(); - assert_eq!(process_import_result::(&mut link, Err(BlockImportError::IncompleteJustification(Some(0)))), 0); - assert_eq!(link.total(), 1); - assert_eq!(link.disconnects, 1); - - let mut link = TestLink::new(); - assert_eq!(process_import_result::(&mut link, Err(BlockImportError::UnknownParent)), 0); - assert_eq!(link.total(), 1); - assert_eq!(link.restarts, 1); - - let mut link = TestLink::new(); - assert_eq!(process_import_result::(&mut link, Err(BlockImportError::Error)), 0); - assert_eq!(link.total(), 1); - assert_eq!(link.restarts, 1); - } - - #[test] - fn import_many_blocks_stops_when_stopping() { - let (_, _, _, block) = prepare_good_block(); - let qdata = AsyncImportQueueData::new(); - let verifier = Arc::new(PassThroughVerifier(true)); - qdata.is_stopping.store(true, Ordering::SeqCst); - assert!(!import_many_blocks( - &mut TestLink::new(), - Some(&qdata), - (BlockOrigin::File, vec![block.clone(), block]), - verifier - )); - } - - #[test] - fn async_import_queue_drops() { - // Perform this test multiple times since it exhibits non-deterministic behavior. - for _ in 0..100 { - let verifier = Arc::new(PassThroughVerifier(true)); - let queue = BasicQueue::new(verifier); - let service = Arc::new(DummyExecutor); - let chain = Arc::new(test_client::new()); - queue.start(Weak::new(), Arc::downgrade(&service), Arc::downgrade(&chain) as Weak>).unwrap(); - drop(queue); - } - } -} diff --git a/core/network/src/lib.rs b/core/network/src/lib.rs index 4a441dcc6fed0f84dd3dc0570005ae5b88f1d8de..95b6d68113d4a30e4b75c6e90adf66848b45b04d 100644 --- a/core/network/src/lib.rs +++ b/core/network/src/lib.rs @@ -17,10 +17,8 @@ #![warn(unused_extern_crates)] #![warn(missing_docs)] -// tag::description[] //! Substrate-specific P2P networking: synchronizing blocks, propagating BFT messages. //! Allows attachment of an optional subprotocol for chain-specific requests. -// end::description[] extern crate linked_hash_map; extern crate parking_lot; @@ -53,11 +51,10 @@ mod sync; #[macro_use] mod protocol; mod io; -mod config; mod chain; mod blocks; mod on_demand; -pub mod import_queue; +pub mod config; pub mod consensus_gossip; pub mod error; pub mod message; @@ -67,13 +64,15 @@ pub mod specialization; pub mod test; pub use chain::Client as ClientHandle; -pub use service::{Service, FetchFuture, TransactionPool, Params, ManageNetwork, SyncProvider}; +pub use service::{Service, FetchFuture, TransactionPool, ManageNetwork, SyncProvider, ExHashT}; pub use protocol::{ProtocolStatus, PeerInfo, Context}; pub use sync::{Status as SyncStatus, SyncState}; -pub use network_libp2p::{NonReservedPeerMode, NetworkConfiguration, NodeIndex, ProtocolId, Severity, Protocol}; +pub use network_libp2p::{ + NodeIndex, ProtocolId, Severity, Protocol, Multiaddr, + obtain_private_key, multiaddr, PeerId, PublicKey +}; pub use message::{generic as generic_message, RequestId, Status as StatusMessage}; pub use error::Error; -pub use config::{Roles, ProtocolConfig}; pub use on_demand::{OnDemand, OnDemandService, RemoteResponse}; #[doc(hidden)] pub use runtime_primitives::traits::Block as BlockT; diff --git a/core/network/src/message.rs b/core/network/src/message.rs index f08fce336858651cb9225459c4ec8d47fd22ae30..3a7238f9b59f45ad94ba3e1ae5b97ca296b6c47e 100644 --- a/core/network/src/message.rs +++ b/core/network/src/message.rs @@ -48,7 +48,6 @@ pub type BlockRequest = generic::BlockRequest< <::Header as HeaderT>::Number, >; - /// Type alias for using the BlockData type using block type parameters. pub type BlockData = generic::BlockData< ::Header, @@ -125,7 +124,7 @@ pub struct RemoteReadResponse { /// Generic types. pub mod generic { use runtime_primitives::Justification; - use service::Roles; + use config::Roles; use super::{ BlockAttributes, RemoteCallResponse, RemoteReadResponse, RequestId, Transactions, Direction @@ -173,7 +172,7 @@ pub mod generic { /// Transactions. Transactions(Transactions), /// Consensus protocol message. - Consensus(Hash, ConsensusMessage), // topic, opaque Vec + Consensus(Hash, ConsensusMessage, bool), // topic, opaque Vec, broadcast /// Remote method call request. RemoteCallRequest(RemoteCallRequest), /// Remote method call response. @@ -189,7 +188,7 @@ pub mod generic { /// Remote changes request. RemoteChangesRequest(RemoteChangesRequest), /// Remote changes reponse. - RemoteChangesResponse(RemoteChangesResponse), + RemoteChangesResponse(RemoteChangesResponse), /// Chain-specific message #[codec(index = "255")] ChainSpecific(Vec), @@ -298,6 +297,9 @@ pub mod generic { pub first: H, /// Hash of the last block of the range (including last) where changes are requested. pub last: H, + /// Hash of the first block for which the requester has the changes trie root. All other + /// affected roots must be proved. + pub min: H, /// Hash of the last block that we can use when querying changes. pub max: H, /// Storage key which changes are requested. @@ -306,7 +308,7 @@ pub mod generic { #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Remote changes response. - pub struct RemoteChangesResponse { + pub struct RemoteChangesResponse { /// Id of a request this response was made for. pub id: RequestId, /// Proof has been generated using block with this number as a max block. Should be @@ -314,5 +316,9 @@ pub mod generic { pub max: N, /// Changes proof. pub proof: Vec>, + /// Changes tries roots missing on the requester' node. + pub roots: Vec<(N, H)>, + /// Missing changes tries roots proof. + pub roots_proof: Vec>, } } diff --git a/core/network/src/on_demand.rs b/core/network/src/on_demand.rs index bc0f3aec9c0dabade2f51502ed5fdf2942f4d932..d71352e86ea48b822fb75434870bc6e81530a997 100644 --- a/core/network/src/on_demand.rs +++ b/core/network/src/on_demand.rs @@ -24,12 +24,13 @@ use futures::sync::oneshot::{channel, Receiver, Sender}; use linked_hash_map::LinkedHashMap; use linked_hash_map::Entry; use parking_lot::Mutex; -use client::{self, error::{Error as ClientError, ErrorKind as ClientErrorKind}}; +use client::{error::{Error as ClientError, ErrorKind as ClientErrorKind}}; use client::light::fetcher::{Fetcher, FetchChecker, RemoteHeaderRequest, - RemoteCallRequest, RemoteReadRequest, RemoteChangesRequest}; + RemoteCallRequest, RemoteReadRequest, RemoteChangesRequest, ChangesProof}; use io::SyncIo; use message; use network_libp2p::{Severity, NodeIndex}; +use config::Roles; use service; use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor}; @@ -41,7 +42,7 @@ const RETRY_COUNT: usize = 1; /// On-demand service API. pub trait OnDemandService: Send + Sync { /// When new node is connected. - fn on_connect(&self, peer: NodeIndex, role: service::Roles, best_number: NumberFor); + fn on_connect(&self, peer: NodeIndex, role: Roles, best_number: NumberFor); /// When block is announced by the peer. fn on_block_announce(&self, peer: NodeIndex, best_number: NumberFor); @@ -71,7 +72,7 @@ pub trait OnDemandService: Send + Sync { &self, io: &mut SyncIo, peer: NodeIndex, - response: message::RemoteChangesResponse> + response: message::RemoteChangesResponse, Block::Hash> ); } @@ -106,7 +107,7 @@ struct Request { enum RequestData { RemoteHeader(RemoteHeaderRequest, Sender>), RemoteRead(RemoteReadRequest, Sender>, ClientError>>), - RemoteCall(RemoteCallRequest, Sender>), + RemoteCall(RemoteCallRequest, Sender, ClientError>>), RemoteChanges(RemoteChangesRequest, Sender, u32)>, ClientError>>), } @@ -211,8 +212,8 @@ impl OnDemandService for OnDemand where E: service::ExecuteInContext, B::Header: HeaderT, { - fn on_connect(&self, peer: NodeIndex, role: service::Roles, best_number: NumberFor) { - if !role.intersects(service::Roles::FULL | service::Roles::AUTHORITY) { // TODO: correct? + fn on_connect(&self, peer: NodeIndex, role: Roles, best_number: NumberFor) { + if !role.intersects(Roles::FULL | Roles::AUTHORITY) { // TODO: correct? return; } @@ -283,11 +284,15 @@ impl OnDemandService for OnDemand where }) } - fn on_remote_changes_response(&self, io: &mut SyncIo, peer: NodeIndex, response: message::RemoteChangesResponse>) { + fn on_remote_changes_response(&self, io: &mut SyncIo, peer: NodeIndex, response: message::RemoteChangesResponse, B::Hash>) { self.accept_response("changes", io, peer, response.id, |request| match request.data { RequestData::RemoteChanges(request, sender) => match self.checker.check_changes_proof( - &request, response.max, response.proof - ) { + &request, ChangesProof { + max_block: response.max, + proof: response.proof, + roots: response.roots.into_iter().collect(), + roots_proof: response.roots_proof, + }) { Ok(response) => { // we do not bother if receiver has been dropped already let _ = sender.send(Ok(response)); @@ -307,7 +312,7 @@ impl Fetcher for OnDemand where { type RemoteHeaderResult = RemoteResponse; type RemoteReadResult = RemoteResponse>>; - type RemoteCallResult = RemoteResponse; + type RemoteCallResult = RemoteResponse>; type RemoteChangesResult = RemoteResponse, u32)>>; fn remote_header(&self, request: RemoteHeaderRequest) -> Self::RemoteHeaderResult { @@ -408,16 +413,24 @@ impl OnDemandCore where None => return, }; - let last_peer = self.idle_peers.back().cloned(); - while !self.pending_requests.is_empty() { + let mut last_peer = self.idle_peers.back().cloned(); + let mut unhandled_requests = VecDeque::new(); + + loop { let peer = match self.idle_peers.pop_front() { Some(peer) => peer, - None => return, + None => break, }; // check if request can (optimistically) be processed by the peer let can_be_processed_by_peer = { - let request = self.pending_requests.front().expect("checked in loop condition; qed"); + let request = match self.pending_requests.front() { + Some(r) => r, + None => { + self.idle_peers.push_front(peer); + break; + }, + }; let peer_best_block = self.best_blocks.get(&peer) .expect("entries are inserted into best_blocks when peer is connected; entries are removed from best_blocks when peer is disconnected; @@ -431,12 +444,16 @@ impl OnDemandCore where // we have enumerated all peers and noone can handle request if Some(peer) == last_peer { - break; + let request = self.pending_requests.pop_front().expect("checked in loop condition; qed"); + unhandled_requests.push_back(request); + last_peer = self.idle_peers.back().cloned(); } continue; } + last_peer = self.idle_peers.back().cloned(); + let mut request = self.pending_requests.pop_front().expect("checked in loop condition; qed"); request.timestamp = Instant::now(); trace!(target: "sync", "Dispatching remote request {} to peer {}", request.id, peer); @@ -444,6 +461,8 @@ impl OnDemandCore where service.execute_in_context(|ctx| ctx.send_message(peer, request.message())); self.active_peers.insert(peer, request); } + + self.pending_requests.append(&mut unhandled_requests); } } @@ -482,6 +501,7 @@ impl Request { id: self.id, first: data.first_block.1.clone(), last: data.last_block.1.clone(), + min: data.tries_roots.1.clone(), max: data.max_block.1.clone(), key: data.key.clone(), }), @@ -508,12 +528,14 @@ pub mod tests { use std::time::Instant; use futures::Future; use parking_lot::RwLock; - use client::{self, error::{ErrorKind as ClientErrorKind, Result as ClientResult}}; + use runtime_primitives::traits::NumberFor; + use client::{error::{ErrorKind as ClientErrorKind, Result as ClientResult}}; use client::light::fetcher::{Fetcher, FetchChecker, RemoteHeaderRequest, - RemoteCallRequest, RemoteReadRequest, RemoteChangesRequest}; + RemoteCallRequest, RemoteReadRequest, RemoteChangesRequest, ChangesProof}; + use config::Roles; use message; use network_libp2p::NodeIndex; - use service::{Roles, ExecuteInContext}; + use service::ExecuteInContext; use test::TestIo; use super::{REQUEST_TIMEOUT, OnDemand, OnDemandService}; use test_client::runtime::{changes_trie_config, Block, Header}; @@ -545,17 +567,14 @@ pub mod tests { } } - fn check_execution_proof(&self, _: &RemoteCallRequest
, _: Vec>) -> ClientResult { + fn check_execution_proof(&self, _: &RemoteCallRequest
, _: Vec>) -> ClientResult> { match self.ok { - true => Ok(client::CallResult { - return_data: vec![42], - changes: Default::default(), - }), + true => Ok(vec![42]), false => Err(ClientErrorKind::Backend("Test error".into()).into()), } } - fn check_changes_proof(&self, _: &RemoteChangesRequest
, _: u64, _: Vec>) -> ClientResult> { + fn check_changes_proof(&self, _: &RemoteChangesRequest
, _: ChangesProof
) -> ClientResult, u32)>> { match self.ok { true => Ok(vec![(100, 2)]), false => Err(ClientErrorKind::Backend("Test error".into()).into()), @@ -774,7 +793,7 @@ pub mod tests { }); let thread = ::std::thread::spawn(move || { let result = response.wait().unwrap(); - assert_eq!(result.return_data, vec![42]); + assert_eq!(result, vec![42]); }); receive_call_response(&*on_demand, &mut network, 0, 0); @@ -853,7 +872,7 @@ pub mod tests { first_block: (1, Default::default()), last_block: (100, Default::default()), max_block: (100, Default::default()), - tries_roots: vec![], + tries_roots: (1, Default::default(), vec![]), key: vec![], retry_count: None, }); @@ -866,6 +885,8 @@ pub mod tests { id: 0, max: 1000, proof: vec![vec![2]], + roots: vec![], + roots_proof: vec![], }); thread.join().unwrap(); } @@ -918,4 +939,55 @@ pub mod tests { assert!(!on_demand.core.lock().idle_peers.iter().any(|_| true)); assert_eq!(on_demand.core.lock().pending_requests.len(), 0); } + + #[test] + fn does_not_loop_forever_after_dispatching_request_to_last_peer() { + // this test is a regression for a bug where the dispatch function would + // loop forever after dispatching a request to the last peer, since the + // last peer was not updated + let (_x, on_demand) = dummy(true); + let queue = RwLock::new(VecDeque::new()); + let _network = TestIo::new(&queue, None); + + on_demand.remote_header(RemoteHeaderRequest { + cht_root: Default::default(), + block: 250, + retry_count: None, + }); + on_demand.remote_header(RemoteHeaderRequest { + cht_root: Default::default(), + block: 250, + retry_count: None, + }); + + on_demand.on_connect(1, Roles::FULL, 200); + on_demand.on_connect(2, Roles::FULL, 200); + on_demand.on_connect(3, Roles::FULL, 250); + + assert_eq!(vec![1, 2], on_demand.core.lock().idle_peers.iter().cloned().collect::>()); + assert_eq!(on_demand.core.lock().pending_requests.len(), 1); + } + + #[test] + fn tries_to_send_all_pending_requests() { + let (_x, on_demand) = dummy(true); + let queue = RwLock::new(VecDeque::new()); + let _network = TestIo::new(&queue, None); + + on_demand.remote_header(RemoteHeaderRequest { + cht_root: Default::default(), + block: 300, + retry_count: None, + }); + on_demand.remote_header(RemoteHeaderRequest { + cht_root: Default::default(), + block: 250, + retry_count: None, + }); + + on_demand.on_connect(1, Roles::FULL, 250); + + assert!(on_demand.core.lock().idle_peers.iter().cloned().collect::>().is_empty()); + assert_eq!(on_demand.core.lock().pending_requests.len(), 1); + } } diff --git a/core/network/src/protocol.rs b/core/network/src/protocol.rs index 4e98ee8f80f24712176dd9e6035ed826bf1bb3a9..7184bd6d4e0b16b503e0a0706d46afb23cd54b98 100644 --- a/core/network/src/protocol.rs +++ b/core/network/src/protocol.rs @@ -14,25 +14,27 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::collections::{HashMap, HashSet}; -use std::{mem, cmp}; +use std::collections::{HashMap, HashSet, BTreeMap}; +use std::cmp; use std::sync::Arc; use std::time; use parking_lot::RwLock; use rustc_hex::ToHex; use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, As, Zero}; use runtime_primitives::generic::BlockId; +use primitives::storage::StorageKey; use network_libp2p::{NodeIndex, Severity}; use codec::{Encode, Decode}; - +use consensus::import_queue::ImportQueue; use message::{self, Message}; use message::generic::Message as GenericMessage; -use specialization::Specialization; +use consensus_gossip::ConsensusGossip; +use specialization::NetworkSpecialization; use sync::{ChainSync, Status as SyncStatus, SyncState}; -use service::{Roles, TransactionPool, ExHashT}; -use import_queue::ImportQueue; -use config::ProtocolConfig; +use service::{TransactionPool, ExHashT}; +use config::{ProtocolConfig, Roles}; use chain::Client; +use client::light::fetcher::ChangesProof; use on_demand::OnDemandService; use io::SyncIo; use error; @@ -50,12 +52,13 @@ const MAX_BLOCK_DATA_RESPONSE: u32 = 128; const LIGHT_MAXIMAL_BLOCKS_DIFFERENCE: u64 = 8192; // Lock must always be taken in order declared here. -pub struct Protocol, H: ExHashT> { +pub struct Protocol, H: ExHashT> { config: ProtocolConfig, on_demand: Option>>, genesis_hash: B::Hash, sync: Arc>>, specialization: RwLock, + consensus_gossip: RwLock>, context_data: ContextData, // Connected peers pending Status message. handshaking_peers: RwLock>, @@ -184,7 +187,7 @@ pub(crate) struct ContextData { pub chain: Arc>, } -impl, H: ExHashT> Protocol { +impl, H: ExHashT> Protocol { /// Create a new instance. pub fn new>( config: ProtocolConfig, @@ -193,7 +196,9 @@ impl, H: ExHashT> Protocol { on_demand: Option>>, transaction_pool: Arc>, specialization: S, - ) -> error::Result { + ) -> error::Result + where I: ImportQueue + { let info = chain.info()?; let sync = ChainSync::new(config.roles, &info, import_queue); let protocol = Protocol { @@ -206,6 +211,7 @@ impl, H: ExHashT> Protocol { genesis_hash: info.chain.genesis_hash, sync: Arc::new(RwLock::new(sync)), specialization: RwLock::new(specialization), + consensus_gossip: RwLock::new(ConsensusGossip::new()), handshaking_peers: RwLock::new(HashMap::new()), transaction_pool: transaction_pool, }; @@ -220,6 +226,10 @@ impl, H: ExHashT> Protocol { &self.sync } + pub(crate) fn consensus_gossip<'a>(&'a self) -> &'a RwLock> { + &self.consensus_gossip + } + /// Returns protocol status pub fn status(&self) -> ProtocolStatus { let sync = self.sync.read(); @@ -231,6 +241,20 @@ impl, H: ExHashT> Protocol { } } + pub fn peers(&self) -> Vec<(NodeIndex, PeerInfo)> { + self.context_data.peers.read().iter().map(|(idx, p)| { + ( + *idx, + PeerInfo { + roles: p.roles, + protocol_version: p.protocol_version, + best_hash: p.best_hash, + best_number: p.best_number, + } + ) + }).collect() + } + pub fn handle_packet(&self, io: &mut SyncIo, who: NodeIndex, mut data: &[u8]) { let message: Message = match Decode::decode(&mut data) { Some(m) => m, @@ -249,7 +273,7 @@ impl, H: ExHashT> Protocol { let mut peers = self.context_data.peers.write(); if let Some(ref mut peer) = peers.get_mut(&who) { peer.request_timestamp = None; - match mem::replace(&mut peer.block_request, None) { + match peer.block_request.take() { Some(r) => r, None => { io.report_peer(who, Severity::Bad("Unexpected response packet received from peer")); @@ -261,10 +285,12 @@ impl, H: ExHashT> Protocol { return; } }; + if request.id != r.id { trace!(target: "sync", "Ignoring mismatched response packet from {} (expected {} got {})", who, request.id, r.id); return; } + self.on_block_response(io, who, request, r); }, GenericMessage::BlockAnnounce(announce) => self.on_block_announce(io, who, announce), @@ -277,6 +303,9 @@ impl, H: ExHashT> Protocol { GenericMessage::RemoteHeaderResponse(response) => self.on_remote_header_response(io, who, response), GenericMessage::RemoteChangesRequest(request) => self.on_remote_changes_request(io, who, request), GenericMessage::RemoteChangesResponse(response) => self.on_remote_changes_response(io, who, response), + GenericMessage::Consensus(topic, msg, broadcast) => { + self.consensus_gossip.write().on_incoming(&mut ProtocolContext::new(&self.context_data, io), who, topic, msg, broadcast); + }, other => self.specialization.write().on_message(&mut ProtocolContext::new(&self.context_data, io), who, &mut Some(other)), } } @@ -285,6 +314,13 @@ impl, H: ExHashT> Protocol { send_message::(&self.context_data.peers, io, who, message) } + pub fn gossip_consensus_message(&self, io: &mut SyncIo, topic: B::Hash, message: Vec, broadcast: bool) { + let gossip = self.consensus_gossip(); + self.with_spec(io, move |_s, context|{ + gossip.write().multicast(context, topic, message, broadcast); + }); + } + /// Called when a new peer is connected pub fn on_peer_connected(&self, io: &mut SyncIo, who: NodeIndex) { trace!(target: "sync", "Connected {}: {}", who, io.peer_debug_info(who)); @@ -308,6 +344,7 @@ impl, H: ExHashT> Protocol { }; if removed { let mut context = ProtocolContext::new(&self.context_data, io); + self.consensus_gossip.write().peer_disconnected(&mut context, peer); sync.peer_disconnected(&mut context, peer); spec.on_disconnect(&mut context, peer); self.on_demand.as_ref().map(|s| s.on_disconnect(peer)); @@ -315,7 +352,15 @@ impl, H: ExHashT> Protocol { } fn on_block_request(&self, io: &mut SyncIo, peer: NodeIndex, request: message::BlockRequest) { - trace!(target: "sync", "BlockRequest {} from {}: from {:?} to {:?} max {:?}", request.id, peer, request.from, request.to, request.max); + trace!(target: "sync", "BlockRequest {} from {} with fields {:?}: from {:?} to {:?} max {:?}", + request.id, + peer, + request.fields, + request.from, + request.to, + request.max, + ); + let mut blocks = Vec::new(); let mut id = match request.from { message::FromBlock::Hash(h) => BlockId::Hash(h), @@ -373,24 +418,36 @@ impl, H: ExHashT> Protocol { trace!(target: "sync", "BlockResponse {} from {} with {} blocks{}", response.id, peer, response.blocks.len(), blocks_range); - // import_queue.import_blocks also acquires sync.write(); - // Break the cycle by doing these separately from the outside; - let new_blocks = { + // TODO [andre]: move this logic to the import queue so that + // justifications are imported asynchronously (#1482) + if request.fields == message::BlockAttributes::JUSTIFICATION { let mut sync = self.sync.write(); - sync.on_block_data(&mut ProtocolContext::new(&self.context_data, io), peer, request, response) - }; + sync.on_block_justification_data( + &mut ProtocolContext::new(&self.context_data, io), + peer, + request, + response, + ); + } else { + // import_queue.import_blocks also acquires sync.write(); + // Break the cycle by doing these separately from the outside; + let new_blocks = { + let mut sync = self.sync.write(); + sync.on_block_data(&mut ProtocolContext::new(&self.context_data, io), peer, request, response) + }; - if let Some((origin, new_blocks)) = new_blocks { - let import_queue = self.sync.read().import_queue(); - import_queue.import_blocks(origin, new_blocks); + if let Some((origin, new_blocks)) = new_blocks { + let import_queue = self.sync.read().import_queue(); + import_queue.import_blocks(origin, new_blocks); + } } - - } /// Perform time based maintenance. pub fn tick(&self, io: &mut SyncIo) { + self.consensus_gossip.write().collect_garbage(|_| true); self.maintain_peers(io); + self.sync.write().tick(&mut ProtocolContext::new(&self.context_data, io)); self.on_demand.as_ref().map(|s| s.maintain_peers(io)); } @@ -402,7 +459,8 @@ impl, H: ExHashT> Protocol { let handshaking_peers = self.handshaking_peers.read(); for (who, timestamp) in peers.iter() .filter_map(|(id, peer)| peer.request_timestamp.as_ref().map(|r| (id, r))) - .chain(handshaking_peers.iter()) { + .chain(handshaking_peers.iter()) + { if (tick - *timestamp).as_secs() > REQUEST_TIMEOUT_SEC { trace!(target: "sync", "Timeout {}", who); aborting.push(*who); @@ -477,6 +535,7 @@ impl, H: ExHashT> Protocol { let mut context = ProtocolContext::new(&self.context_data, io); self.on_demand.as_ref().map(|s| s.on_connect(who, status.roles, status.best_number)); self.sync.write().new_peer(&mut context, who); + self.consensus_gossip.write().new_peer(&mut context, who, status.roles); self.specialization.write().on_connect(&mut context, who, status); } @@ -554,10 +613,12 @@ impl, H: ExHashT> Protocol { let mut spec = self.specialization.write(); let mut peers = self.context_data.peers.write(); let mut handshaking_peers = self.handshaking_peers.write(); + let mut consensus_gossip = self.consensus_gossip.write(); sync.clear(); spec.on_abort(); peers.clear(); handshaking_peers.clear(); + consensus_gossip.abort(); } pub fn stop(&self) { @@ -608,6 +669,10 @@ impl, H: ExHashT> Protocol { } } + pub fn on_block_finalized(&self, _io: &mut SyncIo, hash: B::Hash, header: &B::Header) { + self.sync.write().block_finalized(&hash, *header.number()); + } + fn on_remote_call_request(&self, io: &mut SyncIo, who: NodeIndex, 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(&request.block, &request.method, &request.data) { @@ -673,20 +738,30 @@ impl, H: ExHashT> Protocol { fn on_remote_changes_request(&self, io: &mut SyncIo, who: NodeIndex, request: message::RemoteChangesRequest) { trace!(target: "sync", "Remote changes proof request {} from {} for key {} ({}..{})", request.id, who, request.key.to_hex(), request.first, request.last); - let (max, proof) = match self.context_data.chain.key_changes_proof(request.first, request.last, request.max, &request.key) { - Ok((max, proof)) => (max, proof), + let key = StorageKey(request.key); + let proof = match self.context_data.chain.key_changes_proof(request.first, request.last, request.min, request.max, &key) { + Ok(proof) => proof, Err(error) => { trace!(target: "sync", "Remote changes proof request {} from {} for key {} ({}..{}) failed with: {}", - request.id, who, request.key.to_hex(), request.first, request.last, error); - (Zero::zero(), Default::default()) + request.id, who, key.0.to_hex(), request.first, request.last, error); + ChangesProof:: { + max_block: Zero::zero(), + proof: vec![], + roots: BTreeMap::new(), + roots_proof: vec![], + } }, }; self.send_message(io, who, GenericMessage::RemoteChangesResponse(message::RemoteChangesResponse { - id: request.id, max, proof, + id: request.id, + max: proof.max_block, + proof: proof.proof, + roots: proof.roots.into_iter().collect(), + roots_proof: proof.roots_proof, })); } - fn on_remote_changes_response(&self, io: &mut SyncIo, who: NodeIndex, response: message::RemoteChangesResponse>) { + fn on_remote_changes_response(&self, io: &mut SyncIo, who: NodeIndex, response: message::RemoteChangesResponse, B::Hash>) { trace!(target: "sync", "Remote changes proof response {} from {} (max={})", response.id, who, response.max); self.on_demand.as_ref().map(|s| s.on_remote_changes_response(io, who, response)); @@ -702,8 +777,8 @@ impl, H: ExHashT> Protocol { } fn send_message(peers: &RwLock>>, io: &mut SyncIo, who: NodeIndex, mut message: Message) { - match &mut message { - &mut GenericMessage::BlockRequest(ref mut r) => { + match message { + GenericMessage::BlockRequest(ref mut r) => { let mut peers = peers.write(); if let Some(ref mut peer) = peers.get_mut(&who) { r.id = peer.next_request_id; @@ -761,7 +836,7 @@ macro_rules! construct_simple_protocol { } } - impl $crate::specialization::Specialization<$block> for $protocol { + impl $crate::specialization::NetworkSpecialization<$block> for $protocol { fn status(&self) -> Vec { $( let status = self.$status_protocol_name.status(); diff --git a/core/network/src/service.rs b/core/network/src/service.rs index 6d38d4484f918f8e595a02f374c56edd7b715e93..4c531da1c97ed4a9193658ed516634d7784bef45 100644 --- a/core/network/src/service.rs +++ b/core/network/src/service.rs @@ -19,19 +19,20 @@ use std::sync::Arc; use std::{io, thread}; use std::time::Duration; use futures::{self, Future, Stream, stream, sync::oneshot}; -use parking_lot::Mutex; -use network_libp2p::{ProtocolId, PeerId, NetworkConfiguration, ErrorKind}; +use parking_lot::{Mutex, RwLock}; +use network_libp2p::{ProtocolId, PeerId, NetworkConfiguration, NodeIndex, ErrorKind, Severity}; use network_libp2p::{start_service, Service as NetworkService, ServiceEvent as NetworkServiceEvent}; use network_libp2p::{RegisteredProtocol, parse_str_addr, Protocol as Libp2pProtocol}; use io::NetSyncIo; -use protocol::{self, Protocol, ProtocolContext, Context, ProtocolStatus}; -use config::{ProtocolConfig}; +use consensus::import_queue::{ImportQueue, Link}; +use consensus_gossip::ConsensusGossip; +use protocol::{self, Protocol, ProtocolContext, Context, ProtocolStatus, PeerInfo}; +use config::Params; use error::Error; -use chain::Client; -use specialization::Specialization; -use on_demand::OnDemandService; -use import_queue::ImportQueue; -use runtime_primitives::traits::{Block as BlockT}; +use specialization::NetworkSpecialization; +use runtime_primitives::traits::{Block as BlockT, NumberFor}; +use sync::ChainSync; +use std::sync::Weak; use tokio::{runtime::Runtime, timer::Interval}; /// Type that represents fetch completion future. @@ -40,40 +41,15 @@ pub type FetchFuture = oneshot::Receiver>; const TICK_TIMEOUT: Duration = Duration::from_millis(1000); const PROPAGATE_TIMEOUT: Duration = Duration::from_millis(5000); -bitflags! { - /// Node roles bitmask. - pub struct Roles: u8 { - /// No network. - const NONE = 0b00000000; - /// Full node, does not participate in consensus. - const FULL = 0b00000001; - /// Light client node. - const LIGHT = 0b00000010; - /// Act as an authority - const AUTHORITY = 0b00000100; - } -} - -impl ::codec::Encode for Roles { - fn encode_to(&self, dest: &mut T) { - dest.push_byte(self.bits()) - } -} - -impl ::codec::Decode for Roles { - fn decode(input: &mut I) -> Option { - Self::from_bits(input.read_byte()?) - } -} - /// Sync status pub trait SyncProvider: Send + Sync { /// Get sync status fn status(&self) -> ProtocolStatus; - /// Get this node id if available. - fn node_id(&self) -> Option; + /// Get currently connected peers + fn peers(&self) -> Vec<(NodeIndex, Option, PeerInfo)>; } +/// Minimum Requirements for a Hash within Networking pub trait ExHashT: ::std::hash::Hash + Eq + ::std::fmt::Debug + Clone + Send + Sync + 'static {} impl ExHashT for T where T: ::std::hash::Hash + Eq + ::std::fmt::Debug + Clone + Send + Sync + 'static {} @@ -93,24 +69,59 @@ pub trait ExecuteInContext: Send + Sync { fn execute_in_context)>(&self, closure: F); } -/// Service initialization parameters. -pub struct Params { - /// Configuration. - pub config: ProtocolConfig, - /// Network layer configuration. - pub network_config: NetworkConfiguration, - /// Substrate relay chain access point. - pub chain: Arc>, - /// On-demand service reference. - pub on_demand: Option>>, - /// Transaction pool. - pub transaction_pool: Arc>, - /// Protocol specialization. - pub specialization: S, +/// A link implementation that connects to the network. +pub struct NetworkLink> { + /// The chain-sync handle + pub(crate) sync: Weak>>, + /// Network context. + pub(crate) context: Weak, +} + +impl> NetworkLink { + /// Execute closure with locked ChainSync. + fn with_sync, &mut Context)>(&self, closure: F) { + if let (Some(sync), Some(service)) = (self.sync.upgrade(), self.context.upgrade()) { + service.execute_in_context(move |protocol| { + let mut sync = sync.write(); + closure(&mut *sync, protocol) + }); + } + } +} + +impl> Link for NetworkLink { + fn block_imported(&self, hash: &B::Hash, number: NumberFor) { + self.with_sync(|sync, _| sync.block_imported(&hash, number)) + } + + fn request_justification(&self, hash: &B::Hash, number: NumberFor) { + self.with_sync(|sync, protocol| sync.request_justification(hash, number, protocol)) + } + + fn maintain_sync(&self) { + self.with_sync(|sync, protocol| sync.maintain_sync(protocol)) + } + + fn useless_peer(&self, who: NodeIndex, reason: &str) { + trace!(target:"sync", "Useless peer {}, {}", who, reason); + self.with_sync(|_, protocol| protocol.report_peer(who, Severity::Useless(reason))) + } + + fn note_useless_and_restart_sync(&self, who: NodeIndex, reason: &str) { + trace!(target:"sync", "Bad peer {}, {}", who, reason); + self.with_sync(|sync, protocol| { + protocol.report_peer(who, Severity::Useless(reason)); // is this actually malign or just useless? + sync.restart(protocol); + }) + } + + fn restart(&self) { + self.with_sync(|sync, protocol| sync.restart(protocol)) + } } /// Substrate network service. Handles network IO and manages connectivity. -pub struct Service, H: ExHashT> { +pub struct Service, H: ExHashT> { /// Network service network: Arc>, /// Protocol handler @@ -123,15 +134,15 @@ pub struct Service, H: ExHashT> { bg_thread: Option<(oneshot::Sender<()>, thread::JoinHandle<()>)>, } -impl, H: ExHashT> Service { +impl, H: ExHashT> Service { /// Creates and register protocol with the network service pub fn new>( params: Params, protocol_id: ProtocolId, - import_queue: I, - ) -> Result>, Error> { - let chain = params.chain.clone(); - let import_queue = Arc::new(import_queue); + import_queue: Arc, + ) -> Result>, Error> + where I: ImportQueue + { let handler = Arc::new(Protocol::new( params.config, params.chain, @@ -144,20 +155,22 @@ impl, H: ExHashT> Service { let registered = RegisteredProtocol::new(protocol_id, &versions[..]); let (thread, network) = start_thread(params.network_config, handler.clone(), registered)?; - let sync = Arc::new(Service { + let service = Arc::new(Service { network, protocol_id, handler, - bg_thread: Some(thread), + bg_thread: Some(thread) }); - import_queue.start( - Arc::downgrade(sync.handler.sync()), - Arc::downgrade(&sync), - Arc::downgrade(&chain) - )?; + // connect the import-queue to the network service. + let link = NetworkLink { + sync: Arc::downgrade(service.handler.sync()), + context: Arc::downgrade(&service), + }; + + import_queue.start(link)?; - Ok(sync) + Ok(service) } /// Called when a new block is imported by the client. @@ -165,26 +178,45 @@ impl, H: ExHashT> Service { self.handler.on_block_imported(&mut NetSyncIo::new(&self.network, self.protocol_id), hash, header) } + /// Called when a new block is finalized by the client. + pub fn on_block_finalized(&self, hash: B::Hash, header: &B::Header) { + self.handler.on_block_finalized(&mut NetSyncIo::new(&self.network, self.protocol_id), hash, header) + } + /// Called when new transactons are imported by the client. pub fn trigger_repropagate(&self) { self.handler.propagate_extrinsics(&mut NetSyncIo::new(&self.network, self.protocol_id)); } + /// Send a consensus message through the gossip + pub fn gossip_consensus_message(&self, topic: B::Hash, message: Vec, broadcast: bool) { + self.handler.gossip_consensus_message( + &mut NetSyncIo::new(&self.network, self.protocol_id), + topic, + message, + broadcast, + ) + } /// Execute a closure with the chain-specific network specialization. pub fn with_spec(&self, f: F) -> U where F: FnOnce(&mut S, &mut Context) -> U { self.handler.with_spec(&mut NetSyncIo::new(&self.network, self.protocol_id), f) } + + /// access the underlying consensus gossip handler + pub fn consensus_gossip<'a>(&'a self) -> &'a RwLock> { + self.handler.consensus_gossip() + } } -impl, H: ExHashT> ::consensus::SyncOracle for Service { +impl, H: ExHashT> ::consensus::SyncOracle for Service { fn is_major_syncing(&self) -> bool { self.handler.sync().read().status().is_major_syncing() } } -impl, H:ExHashT> Drop for Service { +impl, H:ExHashT> Drop for Service { fn drop(&mut self) { self.handler.stop(); if let Some((sender, join)) = self.bg_thread.take() { @@ -196,29 +228,24 @@ impl, H:ExHashT> Drop for Service, H: ExHashT> ExecuteInContext for Service { +impl, H: ExHashT> ExecuteInContext for Service { fn execute_in_context)>(&self, closure: F) { closure(&mut ProtocolContext::new(self.handler.context_data(), &mut NetSyncIo::new(&self.network, self.protocol_id))) } } -impl, H: ExHashT> SyncProvider for Service { +impl, H: ExHashT> SyncProvider for Service { /// Get sync status fn status(&self) -> ProtocolStatus { self.handler.status() } - fn node_id(&self) -> Option { + fn peers(&self) -> Vec<(NodeIndex, Option, PeerInfo)> { + let peers = self.handler.peers(); let network = self.network.lock(); - let ret = network - .listeners() - .next() - .map(|addr| { - let mut addr = addr.clone(); - addr.append(Libp2pProtocol::P2p(network.peer_id().clone().into())); - addr.to_string() - }); - ret + peers.into_iter().map(|(idx, info)| { + (idx, network.peer_id_of_node(idx).map(|p| p.clone()), info) + }).collect::>() } } @@ -232,31 +259,21 @@ pub trait ManageNetwork: Send + Sync { fn remove_reserved_peer(&self, peer: PeerId); /// Add reserved peer fn add_reserved_peer(&self, peer: String) -> Result<(), String>; + /// Returns a user-friendly identifier of our node. + fn node_id(&self) -> Option; } -impl, H: ExHashT> ManageNetwork for Service { +impl, H: ExHashT> ManageNetwork for Service { fn accept_unreserved_peers(&self) { self.network.lock().accept_unreserved_peers(); } fn deny_unreserved_peers(&self) { - // This method can disconnect nodes, in which case we have to properly close them in the - // protocol. - let disconnected = self.network.lock().deny_unreserved_peers(); - let mut net_sync = NetSyncIo::new(&self.network, self.protocol_id); - for node_index in disconnected { - self.handler.on_peer_disconnected(&mut net_sync, node_index) - } + self.network.lock().deny_unreserved_peers(); } fn remove_reserved_peer(&self, peer: PeerId) { - // This method can disconnect a node, in which case we have to properly close it in the - // protocol. - let disconnected = self.network.lock().remove_reserved_peer(peer); - if let Some(node_index) = disconnected { - let mut net_sync = NetSyncIo::new(&self.network, self.protocol_id); - self.handler.on_peer_disconnected(&mut net_sync, node_index) - } + self.network.lock().remove_reserved_peer(peer); } fn add_reserved_peer(&self, peer: String) -> Result<(), String> { @@ -264,10 +281,23 @@ impl, H: ExHashT> ManageNetwork for Se self.network.lock().add_reserved_peer(addr, peer_id); Ok(()) } + + fn node_id(&self) -> Option { + let network = self.network.lock(); + let ret = network + .listeners() + .next() + .map(|addr| { + let mut addr = addr.clone(); + addr.append(Libp2pProtocol::P2p(network.peer_id().clone().into())); + addr.to_string() + }); + ret + } } /// Starts the background thread that handles the networking. -fn start_thread, H: ExHashT>( +fn start_thread, H: ExHashT>( config: NetworkConfiguration, protocol: Arc>, registered: RegisteredProtocol, @@ -308,7 +338,7 @@ fn start_thread, H: ExHashT>( } /// Runs the background thread that handles the networking. -fn run_thread, H: ExHashT>( +fn run_thread, H: ExHashT>( network_service: Arc>, protocol: Arc>, protocol_id: ProtocolId, @@ -355,12 +385,6 @@ fn run_thread, H: ExHashT>( let mut net_sync = NetSyncIo::new(&network_service, protocol_id); match event { - NetworkServiceEvent::NodeClosed { node_index, closed_custom_protocols } => { - if !closed_custom_protocols.is_empty() { - debug_assert_eq!(closed_custom_protocols, &[protocol_id]); - protocol.on_peer_disconnected(&mut net_sync, node_index); - } - } NetworkServiceEvent::ClosedCustomProtocols { node_index, protocols } => { if !protocols.is_empty() { debug_assert_eq!(protocols, &[protocol_id]); diff --git a/core/network/src/specialization.rs b/core/network/src/specialization.rs index 70ad9e9b2e655fd88d9d585ac15eaed29834d643..d1cde8b33b110c79ba0cbaf7cb66636f6e7000e6 100644 --- a/core/network/src/specialization.rs +++ b/core/network/src/specialization.rs @@ -21,7 +21,7 @@ use runtime_primitives::traits::Block as BlockT; use protocol::Context; /// A specialization of the substrate network protocol. Handles events and sends messages. -pub trait Specialization: Send + Sync + 'static { +pub trait NetworkSpecialization: Send + Sync + 'static { /// Get the current specialization-status. fn status(&self) -> Vec; diff --git a/core/network/src/sync.rs b/core/network/src/sync.rs index e69b22fc578f148ebf2c936b602d38e65506e282..015c51046a83b57240f8908a674508004ecdadb4 100644 --- a/core/network/src/sync.rs +++ b/core/network/src/sync.rs @@ -14,27 +14,32 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::collections::HashMap; +use std::collections::{HashMap, HashSet, VecDeque}; use std::sync::Arc; +use std::time::{Duration, Instant}; use protocol::Context; use network_libp2p::{Severity, NodeIndex}; use client::{BlockStatus, ClientInfo}; use consensus::BlockOrigin; +use consensus::import_queue::{ImportQueue, IncomingBlock}; use client::error::Error as ClientError; -use blocks::{self, BlockCollection}; -use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberFor}; +use blocks::BlockCollection; +use runtime_primitives::Justification; +use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, As, NumberFor, Zero}; use runtime_primitives::generic::BlockId; use message::{self, generic::Message as GenericMessage}; -use service::Roles; -use import_queue::ImportQueue; +use config::Roles; // Maximum blocks to request in a single packet. const MAX_BLOCKS_TO_REQUEST: usize = 128; // Maximum blocks to store in the import queue. const MAX_IMPORTING_BLOCKS: usize = 2048; +// Number of blocks in the queue that prevents ancestry search. +const MAJOR_SYNC_BLOCKS: usize = 5; +// Time to wait before trying to get a justification from the same peer. +const JUSTIFICATION_RETRY_WAIT: Duration = Duration::from_secs(10); struct PeerSync { - pub common_hash: B::Hash, pub common_number: NumberFor, pub best_hash: B::Hash, pub best_number: NumberFor, @@ -47,6 +52,180 @@ enum PeerSyncState { Available, DownloadingNew(NumberFor), DownloadingStale(B::Hash), + DownloadingJustification(B::Hash), +} + +/// Pending justification request for the given block (hash and number). +type PendingJustification = (::Hash, NumberFor); + +/// Manages pending block justification requests. +struct PendingJustifications { + justifications: HashSet>, + pending_requests: VecDeque>, + peer_requests: HashMap>, + previous_requests: HashMap, Vec<(NodeIndex, Instant)>>, +} + +impl PendingJustifications { + fn new() -> PendingJustifications { + PendingJustifications { + justifications: HashSet::new(), + pending_requests: VecDeque::new(), + peer_requests: HashMap::new(), + previous_requests: HashMap::new(), + } + } + + /// Dispatches all possible pending requests to the given peers. Peers are + /// filtered according to the current known best block (i.e. we won't send a + /// justification request for block #10 to a peer at block #2), and we also + /// throttle requests to the same peer if a previous justification request + /// yielded no results. + fn dispatch(&mut self, peers: &mut HashMap>, protocol: &mut Context) { + if self.pending_requests.is_empty() { + return; + } + + // clean up previous failed requests so we can retry again + for (_, requests) in self.previous_requests.iter_mut() { + requests.retain(|(_, instant)| instant.elapsed() < JUSTIFICATION_RETRY_WAIT); + } + + let mut available_peers = peers.iter().filter_map(|(peer, sync)| { + // don't request to any peers that already have pending requests + if let PeerSyncState::Available = sync.state { + Some((*peer, sync.best_number)) + } else { + None + } + }).collect::>(); + + let mut last_peer = available_peers.back().map(|p| p.0); + let mut unhandled_requests = VecDeque::new(); + + loop { + let (peer, peer_best_number) = match available_peers.pop_front() { + Some(p) => p, + _ => break, + }; + + // only ask peers that have synced past the block number that we're + // asking the justification for and to whom we haven't already made + // the same request recently + let peer_eligible = { + let request = match self.pending_requests.front() { + Some(r) => r.clone(), + _ => break, + }; + + peer_best_number >= request.1 && + !self.previous_requests + .get(&request) + .map(|requests| requests.iter().any(|i| i.0 == peer)) + .unwrap_or(false) + }; + + if !peer_eligible { + available_peers.push_back((peer, peer_best_number)); + + // we tried all peers and none can answer this request + if Some(peer) == last_peer { + last_peer = available_peers.back().map(|p| p.0); + + let request = self.pending_requests.pop_front() + .expect("verified to be Some in the beginning of the loop; qed"); + + unhandled_requests.push_back(request); + } + + continue; + } + + last_peer = available_peers.back().map(|p| p.0); + + let request = self.pending_requests.pop_front() + .expect("verified to be Some in the beginning of the loop; qed"); + + self.peer_requests.insert(peer, request); + + peers.get_mut(&peer) + .expect("peer was is taken from available_peers; available_peers is a subset of peers; qed") + .state = PeerSyncState::DownloadingJustification(request.0); + + let request = message::generic::BlockRequest { + id: 0, + fields: message::BlockAttributes::JUSTIFICATION, + from: message::FromBlock::Hash(request.0), + to: None, + direction: message::Direction::Ascending, + max: Some(1), + }; + + protocol.send_message(peer, GenericMessage::BlockRequest(request)); + } + + self.pending_requests.append(&mut unhandled_requests); + } + + /// Queue a justification request (without dispatching it). + fn queue_request(&mut self, justification: &PendingJustification) { + if !self.justifications.insert(*justification) { + return; + } + self.pending_requests.push_back(*justification); + } + + /// Retry any pending request if a peer disconnected. + fn peer_disconnected(&mut self, who: NodeIndex) { + if let Some(request) = self.peer_requests.remove(&who) { + self.pending_requests.push_front(request); + } + } + + /// Processes the response for the request previously sent to the given + /// peer. Queues a retry in case the import fails or the given justification + /// was `None`. + fn on_response( + &mut self, + who: NodeIndex, + justification: Option, + protocol: &mut Context, + import_queue: &ImportQueue, + ) { + // we assume that the request maps to the given response, this is + // currently enforced by the outer network protocol before passing on + // messages to chain sync. + if let Some(request) = self.peer_requests.remove(&who) { + if let Some(justification) = justification { + if import_queue.import_justification(request.0, request.1, justification) { + self.justifications.remove(&request); + self.previous_requests.remove(&request); + return; + } else { + protocol.report_peer( + who, + Severity::Bad(&format!("Invalid justification provided for #{}", request.0)), + ); + } + } else { + self.previous_requests + .entry(request) + .or_insert(Vec::new()) + .push((who, Instant::now())); + } + + self.pending_requests.push_front(request); + } + } + + /// Removes any pending justification requests for blocks lower than the + /// given best finalized. + fn collect_garbage(&mut self, best_finalized: NumberFor) { + self.justifications.retain(|(_, n)| *n > best_finalized); + self.pending_requests.retain(|(_, n)| *n > best_finalized); + self.peer_requests.retain(|_, (_, n)| *n > best_finalized); + self.previous_requests.retain(|(_, n), _| *n > best_finalized); + } } /// Relay chain sync strategy. @@ -58,6 +237,7 @@ pub struct ChainSync { best_queued_hash: B::Hash, required_block_attributes: message::BlockAttributes, import_queue: Arc>, + justifications: PendingJustifications, } /// Reported sync state. @@ -103,6 +283,7 @@ impl ChainSync { blocks: BlockCollection::new(), best_queued_hash: info.best_queued_hash.unwrap_or(info.chain.best_hash), best_queued_number: info.best_queued_number.unwrap_or(info.chain.best_number), + justifications: PendingJustifications::new(), required_block_attributes, import_queue, } @@ -141,26 +322,35 @@ impl ChainSync { (Ok(BlockStatus::KnownBad), _) => { protocol.report_peer(who, Severity::Bad(&format!("New peer with known bad best block {} ({}).", info.best_hash, info.best_number))); }, - (Ok(BlockStatus::Unknown), b) if b == As::sa(0) => { + (Ok(BlockStatus::Unknown), b) if b.is_zero() => { protocol.report_peer(who, Severity::Bad(&format!("New peer with unknown genesis hash {} ({}).", info.best_hash, info.best_number))); }, + (Ok(BlockStatus::Unknown), _) if self.import_queue.status().importing_count > MAJOR_SYNC_BLOCKS => { + // when actively syncing the common point moves too fast. + debug!(target:"sync", "New peer with unknown best hash {} ({}), assuming common block.", self.best_queued_hash, self.best_queued_number); + self.peers.insert(who, PeerSync { + common_number: self.best_queued_number, + best_hash: info.best_hash, + best_number: info.best_number, + state: PeerSyncState::Available, + }); + } (Ok(BlockStatus::Unknown), _) => { let our_best = self.best_queued_number; if our_best > As::sa(0) { + let common_best = ::std::cmp::min(our_best, info.best_number); debug!(target:"sync", "New peer with unknown best hash {} ({}), searching for common ancestor.", info.best_hash, info.best_number); self.peers.insert(who, PeerSync { - common_hash: self.genesis_hash, common_number: As::sa(0), best_hash: info.best_hash, best_number: info.best_number, - state: PeerSyncState::AncestorSearch(our_best), + state: PeerSyncState::AncestorSearch(common_best), }); - Self::request_ancestry(protocol, who, our_best) + Self::request_ancestry(protocol, who, common_best) } else { // We are at genesis, just start downloading debug!(target:"sync", "New peer with best hash {} ({}).", info.best_hash, info.best_number); self.peers.insert(who, PeerSync { - common_hash: self.genesis_hash, common_number: As::sa(0), best_hash: info.best_hash, best_number: info.best_number, @@ -172,7 +362,6 @@ impl ChainSync { (Ok(BlockStatus::Queued), _) | (Ok(BlockStatus::InChain), _) => { debug!(target:"sync", "New peer with known best hash {} ({}).", info.best_hash, info.best_number); self.peers.insert(who, PeerSync { - common_hash: info.best_hash, common_number: info.best_number, best_hash: info.best_hash, best_number: info.best_number, @@ -183,27 +372,44 @@ impl ChainSync { } } + /// Handle new block data. pub(crate) fn on_block_data( &mut self, protocol: &mut Context, who: NodeIndex, _request: message::BlockRequest, response: message::BlockResponse - ) -> Option<(BlockOrigin, Vec>)> { - let new_blocks = if let Some(ref mut peer) = self.peers.get_mut(&who) { + ) -> Option<(BlockOrigin, Vec>)> { + let new_blocks: Vec> = if let Some(ref mut peer) = self.peers.get_mut(&who) { match peer.state { PeerSyncState::DownloadingNew(start_block) => { self.blocks.clear_peer_download(who); peer.state = PeerSyncState::Available; self.blocks.insert(start_block, response.blocks, who); - self.blocks.drain(self.best_queued_number + As::sa(1)) + self.blocks + .drain(self.best_queued_number + As::sa(1)) + .into_iter() + .map(|block_data| { + IncomingBlock { + hash: block_data.block.hash, + header: block_data.block.header, + body: block_data.block.body, + justification: block_data.block.justification, + origin: block_data.origin, + } + }).collect() }, PeerSyncState::DownloadingStale(_) => { peer.state = PeerSyncState::Available; - response.blocks.into_iter().map(|b| blocks::BlockData { - origin: Some(who), - block: b + response.blocks.into_iter().map(|b| { + IncomingBlock { + hash: b.hash, + header: b.header, + body: b.body, + justification: b.justification, + origin: Some(who), + } }).collect() }, PeerSyncState::AncestorSearch(n) => { @@ -213,7 +419,6 @@ impl ChainSync { match protocol.client().block_hash(n) { Ok(Some(block_hash)) if block_hash == block.hash => { if peer.common_number < n { - peer.common_hash = block.hash; peer.common_number = n; } peer.state = PeerSyncState::Available; @@ -245,72 +450,162 @@ impl ChainSync { } } }, - PeerSyncState::Available => Vec::new(), + PeerSyncState::Available | PeerSyncState::DownloadingJustification(..) => Vec::new(), } } else { - vec![] + Vec::new() }; let best_seen = self.best_seen_block(); - let is_best = new_blocks.first().and_then(|b| b.block.header.as_ref()).map(|h| best_seen.as_ref().map_or(false, |n| h.number() >= n)); + let is_best = new_blocks.first().and_then(|b| b.header.as_ref()).map(|h| best_seen.as_ref().map_or(false, |n| h.number() >= n)); let origin = if is_best.unwrap_or_default() { BlockOrigin::NetworkBroadcast } else { BlockOrigin::NetworkInitialSync }; + if let Some((hash, number)) = new_blocks.last() - .and_then(|b| b.block.header.as_ref().map(|h|(b.block.hash.clone(), *h.number()))) + .and_then(|b| b.header.as_ref().map(|h| (b.hash.clone(), *h.number()))) { - if number > self.best_queued_number { - self.best_queued_number = number; - self.best_queued_hash = hash; - } + self.block_queued(&hash, number); } self.maintain_sync(protocol); Some((origin, new_blocks)) } + /// Handle new justification data. + pub(crate) fn on_block_justification_data( + &mut self, + protocol: &mut Context, + who: NodeIndex, + _request: message::BlockRequest, + response: message::BlockResponse, + ) { + if let Some(ref mut peer) = self.peers.get_mut(&who) { + if let PeerSyncState::DownloadingJustification(hash) = peer.state { + peer.state = PeerSyncState::Available; + + // we only request one justification at a time + match response.blocks.into_iter().next() { + Some(response) => { + if hash != response.hash { + let msg = format!( + "Invalid block justification provided: requested: {:?} got: {:?}", + hash, + response.hash, + ); + + protocol.report_peer(who, Severity::Bad(&msg)); + return; + } + + self.justifications.on_response( + who, + response.justification, + protocol, + &*self.import_queue, + ); + }, + None => { + let msg = format!( + "Provided empty response for justification request {:?}", + hash, + ); + + protocol.report_peer(who, Severity::Useless(&msg)); + return; + }, + } + } + } + + self.maintain_sync(protocol); + } + + /// Maintain the sync process (download new blocks, fetch justifications). pub fn maintain_sync(&mut self, protocol: &mut Context) { let peers: Vec = self.peers.keys().map(|p| *p).collect(); for peer in peers { self.download_new(protocol, peer); } + self.justifications.dispatch(&mut self.peers, protocol); } + /// Called periodically to perform any time-based actions. + pub fn tick(&mut self, protocol: &mut Context) { + self.justifications.dispatch(&mut self.peers, protocol); + } + + /// Request a justification for the given block. + /// + /// Queues a new justification request and tries to dispatch all pending requests. + pub fn request_justification(&mut self, hash: &B::Hash, number: NumberFor, protocol: &mut Context) { + self.justifications.queue_request(&(*hash, number)); + self.justifications.dispatch(&mut self.peers, protocol); + } + + /// Notify about successful import of the given block. pub fn block_imported(&mut self, hash: &B::Hash, number: NumberFor) { + trace!(target: "sync", "Block imported successfully {} ({})", number, hash); + } + + /// Notify about finalization of the given block. + pub fn block_finalized(&mut self, _hash: &B::Hash, number: NumberFor) { + self.justifications.collect_garbage(number); + } + + fn block_queued(&mut self, hash: &B::Hash, number: NumberFor) { if number > self.best_queued_number { self.best_queued_number = number; self.best_queued_hash = *hash; } // Update common blocks - for (_, peer) in self.peers.iter_mut() { - trace!(target: "sync", "Updating peer info ours={}, theirs={}", number, peer.best_number); + for (n, peer) in self.peers.iter_mut() { + if let PeerSyncState::AncestorSearch(_) = peer.state { + // Abort search. + peer.state = PeerSyncState::Available; + } + trace!(target: "sync", "Updating peer {} info, ours={}, common={}, their best={}", n, number, peer.common_number, peer.best_number); if peer.best_number >= number { peer.common_number = number; - peer.common_hash = *hash; + } else { + peer.common_number = peer.best_number; } } } pub(crate) fn update_chain_info(&mut self, best_header: &B::Header) { let hash = best_header.hash(); - self.block_imported(&hash, best_header.number().clone()) + self.block_queued(&hash, best_header.number().clone()) } + /// Handle new block announcement. pub(crate) fn on_block_announce(&mut self, protocol: &mut Context, who: NodeIndex, hash: B::Hash, header: &B::Header) { let number = *header.number(); + if number <= As::sa(0) { + trace!(target: "sync", "Ignored invalid block announcement from {}: {}", who, hash); + return; + } + let known_parent = self.is_known(protocol, &header.parent_hash()); + let known = self.is_known(protocol, &hash); if let Some(ref mut peer) = self.peers.get_mut(&who) { if number > peer.best_number { + // update their best block peer.best_number = number; peer.best_hash = hash; } - if number <= self.best_queued_number && number > peer.common_number { + if let PeerSyncState::AncestorSearch(_) = peer.state { + return; + } + if header.parent_hash() == &self.best_queued_hash || known_parent { + peer.common_number = number - As::sa(1); + } else if known { peer.common_number = number } } else { return; } - if !self.is_known_or_already_downloading(protocol, &hash) { + if !(known || self.is_already_downloading(&hash)) { let stale = number <= self.best_queued_number; if stale { - if !self.is_known_or_already_downloading(protocol, header.parent_hash()) { + if !(known_parent || self.is_already_downloading(header.parent_hash())) { trace!(target: "sync", "Ignoring unknown stale block announce from {}: {} {:?}", who, hash, header); } else { trace!(target: "sync", "Considering new stale block announced from {}: {} {:?}", who, hash, header); @@ -325,28 +620,31 @@ impl ChainSync { } } - fn is_known_or_already_downloading(&self, protocol: &mut Context, hash: &B::Hash) -> bool { + fn is_already_downloading(&self, hash: &B::Hash) -> bool { self.peers.iter().any(|(_, p)| p.state == PeerSyncState::DownloadingStale(*hash)) - || block_status(&*protocol.client(), &*self.import_queue, *hash).ok().map_or(false, |s| s != BlockStatus::Unknown) } + fn is_known(&self, protocol: &mut Context, hash: &B::Hash) -> bool { + block_status(&*protocol.client(), &*self.import_queue, *hash).ok().map_or(false, |s| s != BlockStatus::Unknown) + } + + /// Handle disconnected peer. pub(crate) fn peer_disconnected(&mut self, protocol: &mut Context, who: NodeIndex) { self.blocks.clear_peer_download(who); self.peers.remove(&who); + self.justifications.peer_disconnected(who); self.maintain_sync(protocol); } + /// Restart the sync process. pub(crate) fn restart(&mut self, protocol: &mut Context) { self.import_queue.clear(); self.blocks.clear(); - let ids: Vec = self.peers.keys().map(|p| *p).collect(); - for id in ids { - self.new_peer(protocol, id); - } match protocol.client().info() { Ok(info) => { self.best_queued_hash = info.best_queued_hash.unwrap_or(info.chain.best_hash); self.best_queued_number = info.best_queued_number.unwrap_or(info.chain.best_number); + debug!(target:"sync", "Restarted with {} ({})", self.best_queued_number, self.best_queued_hash); }, Err(e) => { debug!(target:"sync", "Error reading blockchain: {:?}", e); @@ -354,8 +652,13 @@ impl ChainSync { self.best_queued_number = As::sa(0); } } + let ids: Vec = self.peers.drain().map(|(id, _)| id).collect(); + for id in ids { + self.new_peer(protocol, id); + } } + /// Clear all sync data. pub(crate) fn clear(&mut self) { self.blocks.clear(); self.peers.clear(); @@ -391,13 +694,10 @@ impl ChainSync { trace!(target: "sync", "Too many blocks in the queue."); return; } - // we should not download already queued blocks - let common_number = ::std::cmp::max(peer.common_number, import_status.best_importing_number); - - trace!(target: "sync", "Considering new block download from {}, common block is {}, best is {:?}", who, common_number, peer.best_number); match peer.state { PeerSyncState::Available => { - if let Some(range) = self.blocks.needed_blocks(who, MAX_BLOCKS_TO_REQUEST, peer.best_number, common_number) { + trace!(target: "sync", "Considering new block download from {}, common block is {}, best is {:?}", who, peer.common_number, peer.best_number); + if let Some(range) = self.blocks.needed_blocks(who, MAX_BLOCKS_TO_REQUEST, peer.best_number, peer.common_number) { trace!(target: "sync", "Requesting blocks from {}, ({} to {})", who, range.start, range.end); let request = message::generic::BlockRequest { id: 0, diff --git a/core/network/src/test/block_import.rs b/core/network/src/test/block_import.rs new file mode 100644 index 0000000000000000000000000000000000000000..6104be87f0e32b99b2035ebbae5c29837593a1fe --- /dev/null +++ b/core/network/src/test/block_import.rs @@ -0,0 +1,171 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Testing block import logic. + +use consensus::import_queue::{import_single_block, process_import_result}; +use consensus::import_queue::{AsyncImportQueueData, BasicQueue, BlockImportError, BlockImportResult}; +use test_client::{self, TestClient}; +use test_client::runtime::{Block, Hash}; +use runtime_primitives::generic::BlockId; +use runtime_primitives::traits::NumberFor; +use std::cell::Cell; +use super::*; + +struct TestLink { + imported: Cell, + maintains: Cell, + disconnects: Cell, + restarts: Cell, +} + +impl TestLink { + fn new() -> TestLink { + TestLink { + imported: Cell::new(0), + maintains: Cell::new(0), + disconnects: Cell::new(0), + restarts: Cell::new(0), + } + } + + fn total(&self) -> usize { + self.imported.get() + self.maintains.get() + self.disconnects.get() + self.restarts.get() + } +} + +impl Link for TestLink { + fn block_imported(&self, _hash: &Hash, _number: NumberFor) { + self.imported.set(self.imported.get() + 1); + } + fn maintain_sync(&self) { + self.maintains.set(self.maintains.get() + 1); + } + fn useless_peer(&self, _: NodeIndex, _: &str) { + self.disconnects.set(self.disconnects.get() + 1); + } + fn note_useless_and_restart_sync(&self, id: NodeIndex, r: &str) { + self.useless_peer(id, r); + self.restart(); + } + fn restart(&self) { + self.restarts.set(self.restarts.get() + 1); + } +} + +fn prepare_good_block() -> (client::Client, Hash, u64, IncomingBlock) { + let client = test_client::new(); + let block = client.new_block().unwrap().bake().unwrap(); + client.import(BlockOrigin::File, block).unwrap(); + + let (hash, number) = (client.block_hash(1).unwrap().unwrap(), 1); + let header = client.header(&BlockId::Number(1)).unwrap(); + let justification = client.justification(&BlockId::Number(1)).unwrap(); + (client, hash, number, IncomingBlock { + hash, + header, + body: None, + justification, + origin: Some(0) + }) +} + +#[test] +fn import_single_good_block_works() { + let (_, hash, number, block) = prepare_good_block(); + assert_eq!( + import_single_block(&test_client::new(), BlockOrigin::File, block, Arc::new(PassThroughVerifier(true))), + Ok(BlockImportResult::ImportedUnknown(hash, number)) + ); +} + +#[test] +fn import_single_good_known_block_is_ignored() { + let (client, hash, number, block) = prepare_good_block(); + assert_eq!( + import_single_block(&client, BlockOrigin::File, block, Arc::new(PassThroughVerifier(true))), + Ok(BlockImportResult::ImportedKnown(hash, number)) + ); +} + +#[test] +fn import_single_good_block_without_header_fails() { + let (_, _, _, mut block) = prepare_good_block(); + block.header = None; + assert_eq!( + import_single_block(&test_client::new(), BlockOrigin::File, block, Arc::new(PassThroughVerifier(true))), + Err(BlockImportError::IncompleteHeader(Some(0))) + ); +} + +#[test] +fn process_import_result_works() { + let link = TestLink::new(); + assert_eq!(process_import_result::(&link, Ok(BlockImportResult::ImportedKnown(Default::default(), 0))), 1); + assert_eq!(link.total(), 1); + + let link = TestLink::new(); + assert_eq!(process_import_result::(&link, Ok(BlockImportResult::ImportedKnown(Default::default(), 0))), 1); + assert_eq!(link.total(), 1); + assert_eq!(link.imported.get(), 1); + + let link = TestLink::new(); + assert_eq!(process_import_result::(&link, Ok(BlockImportResult::ImportedUnknown(Default::default(), 0))), 1); + assert_eq!(link.total(), 1); + assert_eq!(link.imported.get(), 1); + + let link = TestLink::new(); + assert_eq!(process_import_result::(&link, Err(BlockImportError::IncompleteHeader(Some(0)))), 0); + assert_eq!(link.total(), 1); + assert_eq!(link.disconnects.get(), 1); + + let link = TestLink::new(); + assert_eq!(process_import_result::(&link, Err(BlockImportError::UnknownParent)), 0); + assert_eq!(link.total(), 1); + assert_eq!(link.restarts.get(), 1); + + let link = TestLink::new(); + assert_eq!(process_import_result::(&link, Err(BlockImportError::Error)), 0); + assert_eq!(link.total(), 1); + assert_eq!(link.restarts.get(), 1); +} + +#[test] +fn import_many_blocks_stops_when_stopping() { + let (_, _, _, block) = prepare_good_block(); + let qdata = AsyncImportQueueData::new(); + let verifier = Arc::new(PassThroughVerifier(true)); + qdata.stop(); + let client = test_client::new(); + assert!(!import_many_blocks( + &client, + &mut TestLink::new(), + Some(&qdata), + (BlockOrigin::File, vec![block.clone(), block]), + verifier + )); +} + +#[test] +fn async_import_queue_drops() { + // Perform this test multiple times since it exhibits non-deterministic behavior. + for _ in 0..100 { + let verifier = Arc::new(PassThroughVerifier(true)); + let queue = BasicQueue::new(verifier, Arc::new(test_client::new())); + queue.start(TestLink::new()).unwrap(); + drop(queue); + } +} diff --git a/core/network/src/test/mod.rs b/core/network/src/test/mod.rs index 843ad836e0ba0a3cec687aa8129996fffd72db00..3e451885447c2feb5f7d29a34f1a744d3291f93a 100644 --- a/core/network/src/test/mod.rs +++ b/core/network/src/test/mod.rs @@ -18,6 +18,8 @@ #[cfg(test)] mod sync; +#[cfg(test)] +mod block_import; use std::collections::{VecDeque, HashSet, HashMap}; use std::sync::Arc; @@ -25,26 +27,180 @@ use std::sync::Arc; use parking_lot::RwLock; use client; use client::block_builder::BlockBuilder; +use primitives::Ed25519AuthorityId; +use runtime_primitives::Justification; use runtime_primitives::generic::BlockId; +use runtime_primitives::traits::{AuthorityIdFor, Block as BlockT, Digest, DigestItem, Header, NumberFor, Zero}; use io::SyncIo; use protocol::{Context, Protocol, ProtocolContext}; -use primitives::{Blake2Hasher}; use config::ProtocolConfig; -use service::TransactionPool; +use service::{NetworkLink, TransactionPool}; use network_libp2p::{NodeIndex, PeerId, Severity}; use keyring::Keyring; use codec::Encode; -use import_queue::{SyncImportQueue, PassThroughVerifier, Verifier}; -use consensus::BlockOrigin; -use specialization::Specialization; +use consensus::{BlockImport, BlockOrigin, ImportBlock, ForkChoiceStrategy}; +use consensus::Error as ConsensusError; +use consensus::import_queue::{import_many_blocks, ImportQueue, ImportQueueStatus, IncomingBlock}; +use consensus::import_queue::{Link, SharedBlockImport, Verifier}; +use specialization::NetworkSpecialization; use consensus_gossip::ConsensusGossip; -use import_queue::ImportQueue; use service::ExecuteInContext; use test_client; pub use test_client::runtime::{Block, Hash, Transfer, Extrinsic}; pub use test_client::TestClient; +#[cfg(any(test, feature = "test-helpers"))] +use std::cell::RefCell; + +#[cfg(any(test, feature = "test-helpers"))] +struct ImportCB(RefCell>) -> bool>>>); + +#[cfg(any(test, feature = "test-helpers"))] +impl ImportCB { + fn new() -> Self { + ImportCB(RefCell::new(None)) + } + fn set(&self, cb: Box) + where F: 'static + Fn(BlockOrigin, Vec>) -> bool + { + *self.0.borrow_mut() = Some(cb); + } + fn call(&self, origin: BlockOrigin, data: Vec>) -> bool { + let b = self.0.borrow(); + b.as_ref().expect("The Callback has been set before. qed.")(origin, data) + } +} + +#[cfg(any(test, feature = "test-helpers"))] +unsafe impl Send for ImportCB {} +#[cfg(any(test, feature = "test-helpers"))] +unsafe impl Sync for ImportCB {} + + +#[cfg(any(test, feature = "test-helpers"))] +/// A Verifier that accepts all blocks and passes them on with the configured +/// finality to be imported. +pub struct PassThroughVerifier(pub bool); + +#[cfg(any(test, feature = "test-helpers"))] +/// This Verifiyer accepts all data as valid +impl Verifier for PassThroughVerifier { + fn verify( + &self, + origin: BlockOrigin, + header: B::Header, + justification: Option, + body: Option> + ) -> Result<(ImportBlock, Option>>), String> { + let new_authorities = header.digest().log(DigestItem::as_authorities_change) + .map(|auth| auth.iter().cloned().collect()); + + Ok((ImportBlock { + origin, + header, + body, + finalized: self.0, + justification, + post_digests: vec![], + auxiliary: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, + }, new_authorities)) + } +} + +/// A link implementation that does nothing. +pub struct NoopLink; + +impl Link for NoopLink { } + +/// Blocks import queue that is importing blocks in the same thread. +/// The boolean value indicates whether blocks should be imported without instant finality. +#[cfg(any(test, feature = "test-helpers"))] +pub struct SyncImportQueue> { + verifier: Arc, + link: ImportCB, + block_import: SharedBlockImport, +} + +#[cfg(any(test, feature = "test-helpers"))] +impl> SyncImportQueue { + /// Create a new SyncImportQueue wrapping the given Verifier and block import + /// handle. + pub fn new(verifier: Arc, block_import: SharedBlockImport) -> Self { + let queue = SyncImportQueue { + verifier, + link: ImportCB::new(), + block_import, + }; + + let v = queue.verifier.clone(); + let import_handle = queue.block_import.clone(); + queue.link.set(Box::new(move |origin, new_blocks| { + let verifier = v.clone(); + import_many_blocks( + &*import_handle, + &NoopLink, + None, + (origin, new_blocks), + verifier, + ) + })); + + queue + } +} + +#[cfg(any(test, feature = "test-helpers"))] +impl> ImportQueue for SyncImportQueue +{ + fn start>( + &self, + link: L, + ) -> Result<(), std::io::Error> { + let v = self.verifier.clone(); + let import_handle = self.block_import.clone(); + self.link.set(Box::new(move |origin, new_blocks| { + let verifier = v.clone(); + import_many_blocks( + &*import_handle, + &link, + None, + (origin, new_blocks), + verifier, + ) + })); + Ok(()) + } + fn clear(&self) { } + + fn stop(&self) { } + + fn status(&self) -> ImportQueueStatus { + ImportQueueStatus { + importing_count: 0, + best_importing_number: Zero::zero(), + } + } + + fn is_importing(&self, _hash: &B::Hash) -> bool { + false + } + + fn import_blocks(&self, origin: BlockOrigin, blocks: Vec>) { + self.link.call(origin, blocks); + } + + fn import_justification( + &self, + hash: B::Hash, + number: NumberFor, + justification: Justification, + ) -> bool { + self.block_import.import_justification(hash, number, justification).is_ok() + } +} + struct DummyContextExecutor(Arc>, Arc>>); unsafe impl Send for DummyContextExecutor {} unsafe impl Sync for DummyContextExecutor {} @@ -58,31 +214,23 @@ impl ExecuteInContext for DummyContextExecutor { } /// The test specialization. -pub struct DummySpecialization { - /// Consensus gossip handle. - pub gossip: ConsensusGossip, -} +pub struct DummySpecialization { } -impl Specialization for DummySpecialization { +impl NetworkSpecialization for DummySpecialization { fn status(&self) -> Vec { vec![] } - fn on_connect(&mut self, ctx: &mut Context, peer_id: NodeIndex, status: ::message::Status) { - self.gossip.new_peer(ctx, peer_id, status.roles); + fn on_connect(&mut self, _ctx: &mut Context, _peer_id: NodeIndex, _status: ::message::Status) { } - fn on_disconnect(&mut self, ctx: &mut Context, peer_id: NodeIndex) { - self.gossip.peer_disconnected(ctx, peer_id); + fn on_disconnect(&mut self, _ctx: &mut Context, _peer_id: NodeIndex) { } fn on_message( &mut self, - ctx: &mut Context, - peer_id: NodeIndex, - message: &mut Option<::message::Message> + _ctx: &mut Context, + _peer_id: NodeIndex, + _message: &mut Option<::message::Message> ) { - if let Some(::message::generic::Message::Consensus(topic, data)) = message.take() { - self.gossip.on_incoming(ctx, peer_id, topic, data); - } } } @@ -137,35 +285,40 @@ pub struct TestPacket { recipient: NodeIndex, } -pub type PeersClient = client::Client; +pub type PeersClient = client::Client; -pub struct Peer> { +pub struct Peer, D> { client: Arc, pub sync: Arc>, pub queue: Arc>>, import_queue: Arc>, executor: Arc, + /// Some custom data set up at initialization time. + pub data: D, } -impl> Peer { +impl, D> Peer { fn new( client: Arc, sync: Arc>, queue: Arc>>, import_queue: Arc>, + data: D, ) -> Self { let executor = Arc::new(DummyContextExecutor(sync.clone(), queue.clone())); - Peer { client, sync, queue, import_queue, executor} + Peer { client, sync, queue, import_queue, executor, data } } /// Called after blockchain has been populated to updated current state. fn start(&self) { // Update the sync state to the latest chain state. let info = self.client.info().expect("In-mem client does not fail"); let header = self.client.header(&BlockId::Hash(info.chain.best_hash)).unwrap().unwrap(); - self.import_queue.start( - Arc::downgrade(&self.sync.sync()), - Arc::downgrade(&self.executor), - Arc::downgrade(&self.sync.context_data().chain)).expect("Test ImportQueue always starts"); + let network_link = NetworkLink { + sync: Arc::downgrade(self.sync.sync()), + context: Arc::downgrade(&self.executor), + }; + + self.import_queue.start(network_link).expect("Test ImportQueue always starts"); self.sync.on_block_imported(&mut TestIo::new(&self.queue, None), info.chain.best_hash, &header); } @@ -174,6 +327,10 @@ impl> Peer { self.sync.on_peer_connected(&mut TestIo::new(&self.queue, Some(other)), other); } + pub fn consensus_gossip(&self) -> &RwLock> { + self.sync.consensus_gossip() + } + /// Called on disconnect from other indicated peer. fn on_disconnect(&self, other: NodeIndex) { let mut io = TestIo::new(&self.queue, Some(other)); @@ -188,6 +345,12 @@ impl> Peer { io.to_disconnect.clone() } + #[cfg(test)] + fn with_io<'a, F, U>(&'a self, f: F) -> U where F: FnOnce(&mut TestIo<'a>) -> U { + let mut io = TestIo::new(&self.queue, None); + f(&mut io) + } + /// Produce the next pending message to send to another peer. fn pending_message(&self) -> Option { self.flush(); @@ -212,6 +375,13 @@ impl> Peer { self.sync.on_block_imported(&mut TestIo::new(&self.queue, None), info.chain.best_hash, &header); } + /// Send block finalization notifications. + pub fn send_finality_notifications(&self) { + let info = self.client.info().expect("In-mem client does not fail"); + let header = self.client.header(&BlockId::Hash(info.chain.finalized_hash)).unwrap().unwrap(); + self.sync.on_block_finalized(&mut TestIo::new(&self.queue, None), info.chain.finalized_hash, &header); + } + /// Restart sync for a peer. fn restart_sync(&self) { self.sync.abort(); @@ -222,33 +392,49 @@ impl> Peer { /// Push a message into the gossip network and relay to peers. /// `TestNet::sync_step` needs to be called to ensure it's propagated. - pub fn gossip_message(&self, topic: Hash, data: Vec) { - self.sync.with_spec(&mut TestIo::new(&self.queue, None), |spec, ctx| { - spec.gossip.multicast(ctx, topic, data); + pub fn gossip_message(&self, topic: Hash, data: Vec, broadcast: bool) { + self.sync.gossip_consensus_message(&mut TestIo::new(&self.queue, None), topic, data, broadcast); + } + + /// Request a justification for the given block. + #[cfg(test)] + fn request_justification(&self, hash: &::primitives::H256, number: NumberFor) { + self.executor.execute_in_context(|context| { + self.sync.sync().write().request_justification(hash, number, context); }) } /// Add blocks to the peer -- edit the block before adding pub fn generate_blocks(&self, count: usize, origin: BlockOrigin, mut edit_block: F) - where F: FnMut(&mut BlockBuilder) + where F: FnMut(BlockBuilder) -> Block { - for _ in 0 .. count { - let mut builder = self.client.new_block().unwrap(); - edit_block(&mut builder); - let block = builder.bake().unwrap(); + for _ in 0..count { + let builder = self.client.new_block().unwrap(); + let block = edit_block(builder); let hash = block.header.hash(); trace!("Generating {}, (#{}, parent={})", hash, block.header.number, block.header.parent_hash); let header = block.header.clone(); - self.client.justify_and_import(origin, block).unwrap(); - self.sync.on_block_imported(&mut TestIo::new(&self.queue, None), hash, &header); + + // NOTE: if we use a non-synchronous queue in the test-net in the future, + // this may not work. + self.import_queue.import_blocks(origin, vec![ + IncomingBlock { + origin: None, + hash, + header: Some(header), + body: Some(block.extrinsics), + justification: None, + }, + ]); } + } /// Push blocks to the peer (simplified: with or without a TX) pub fn push_blocks(&self, count: usize, with_tx: bool) { let mut nonce = 0; if with_tx { - self.generate_blocks(count, BlockOrigin::File, |builder| { + self.generate_blocks(count, BlockOrigin::File, |mut builder| { let transfer = Transfer { from: Keyring::Alice.to_raw_public().into(), to: Keyring::Alice.to_raw_public().into(), @@ -256,14 +442,22 @@ impl> Peer { nonce, }; let signature = Keyring::from_raw_public(transfer.from.to_fixed_bytes()).unwrap().sign(&transfer.encode()).into(); - builder.push(Extrinsic { transfer, signature }).unwrap(); + builder.push(Extrinsic::Transfer(transfer, signature)).unwrap(); nonce = nonce + 1; + builder.bake().unwrap() }); } else { - self.generate_blocks(count, BlockOrigin::File, |_| ()); + self.generate_blocks(count, BlockOrigin::File, |builder| builder.bake().unwrap()); } } + pub fn push_authorities_change_block(&self, new_authorities: Vec) { + self.generate_blocks(1, BlockOrigin::File, |mut builder| { + builder.push(Extrinsic::AuthoritiesChange(new_authorities.clone())).unwrap(); + builder.bake().unwrap() + }); + } + /// Execute a function with specialization for this peer. pub fn with_spec(&self, f: F) -> U where F: FnOnce(&mut DummySpecialization, &mut Context) -> U @@ -293,6 +487,7 @@ impl TransactionPool for EmptyTransactionPool { pub trait TestNetFactory: Sized { type Verifier: 'static + Verifier; + type PeerData: Default; /// These two need to be implemented! fn from_config(config: &ProtocolConfig) -> Self; @@ -300,12 +495,19 @@ pub trait TestNetFactory: Sized { /// Get reference to peer. - fn peer(&self, i: usize) -> &Peer; - fn peers(&self) -> &Vec>>; - fn mut_peers>>)>(&mut self, closure: F ); + fn peer(&self, i: usize) -> &Peer; + fn peers(&self) -> &Vec>>; + fn mut_peers>>)>(&mut self, closure: F); fn started(&self) -> bool; - fn set_started(&mut self, now: bool); + fn set_started(&mut self, now: bool); + + /// Get custom block import handle for fresh client, along with peer data. + fn make_block_import(&self, client: Arc) + -> (Arc + Send + Sync>, Self::PeerData) + { + (client, Default::default()) + } fn default_config() -> ProtocolConfig { ProtocolConfig::default() @@ -327,10 +529,10 @@ pub trait TestNetFactory: Sized { let client = Arc::new(test_client::new()); let tx_pool = Arc::new(EmptyTransactionPool); let verifier = self.make_verifier(client.clone(), config); - let import_queue = Arc::new(SyncImportQueue::new(verifier)); - let specialization = DummySpecialization { - gossip: ConsensusGossip::new(), - }; + let (block_import, data) = self.make_block_import(client.clone()); + + let import_queue = Arc::new(SyncImportQueue::new(verifier, block_import)); + let specialization = DummySpecialization { }; let sync = Protocol::new( config.clone(), client.clone(), @@ -344,7 +546,8 @@ pub trait TestNetFactory: Sized { client, Arc::new(sync), Arc::new(RwLock::new(VecDeque::new())), - import_queue + import_queue, + data, )); self.mut_peers(|peers| { @@ -422,6 +625,15 @@ pub trait TestNetFactory: Sized { }) } + /// Send block finalization notifications for all peers. + fn send_finality_notifications(&mut self) { + self.mut_peers(|peers| { + for peer in peers { + peer.send_finality_notifications(); + } + }) + } + /// Restart sync for a peer. fn restart_peer(&mut self, i: usize) { self.peers()[i].restart_sync(); @@ -454,12 +666,13 @@ pub trait TestNetFactory: Sized { } pub struct TestNet { - peers: Vec>>, + peers: Vec>>, started: bool } impl TestNetFactory for TestNet { type Verifier = PassThroughVerifier; + type PeerData = (); /// Create new test network with peers and given config. fn from_config(_config: &ProtocolConfig) -> Self { @@ -468,22 +681,22 @@ impl TestNetFactory for TestNet { started: false } } - + fn make_verifier(&self, _client: Arc, _config: &ProtocolConfig) -> Arc { Arc::new(PassThroughVerifier(false)) } - fn peer(&self, i: usize) -> &Peer { + fn peer(&self, i: usize) -> &Peer { &self.peers[i] } - fn peers(&self) -> &Vec>> { + fn peers(&self) -> &Vec>> { &self.peers } - fn mut_peers>>)>(&mut self, closure: F ) { + fn mut_peers>>)>(&mut self, closure: F ) { closure(&mut self.peers); } diff --git a/core/network/src/test/sync.rs b/core/network/src/test/sync.rs index 0f9e40782873b964cca30e80ba5423cef081e836..72d105a499e2c69f239f4ba02372fe177156495a 100644 --- a/core/network/src/test/sync.rs +++ b/core/network/src/test/sync.rs @@ -16,9 +16,9 @@ use client::backend::Backend; use client::blockchain::HeaderBackend as BlockchainHeaderBackend; +use config::Roles; use consensus::BlockOrigin; use sync::SyncState; -use Roles; use super::*; #[test] @@ -65,6 +65,27 @@ fn sync_no_common_longer_chain_fails() { assert!(!net.peer(0).client.backend().blockchain().canon_equals_to(net.peer(1).client.backend().blockchain())); } +#[test] +fn sync_justifications() { + ::env_logger::init().ok(); + let mut net = TestNet::new(3); + net.peer(0).push_blocks(20, false); + net.sync(); + + // there's currently no justification for block #10 + assert_eq!(net.peer(0).client().justification(&BlockId::Number(10)).unwrap(), None); + // we finalize block #10 for peer 0 with a justification + net.peer(0).client().finalize_block(BlockId::Number(10), Some(Vec::new()), true).unwrap(); + + let header = net.peer(1).client().header(&BlockId::Number(10)).unwrap().unwrap(); + net.peer(1).request_justification(&header.hash().into(), 10); + + net.sync(); + + assert_eq!(net.peer(0).client().justification(&BlockId::Number(10)).unwrap(), Some(Vec::new())); + assert_eq!(net.peer(1).client().justification(&BlockId::Number(10)).unwrap(), Some(Vec::new())); +} + #[test] fn sync_after_fork_works() { ::env_logger::init().ok(); @@ -94,7 +115,10 @@ fn own_blocks_are_announced() { ::env_logger::init().ok(); let mut net = TestNet::new(3); net.sync(); // connect'em - net.peer(0).generate_blocks(1, BlockOrigin::Own, |_| ()); + net.peer(0).generate_blocks(1, BlockOrigin::Own, |builder| builder.bake().unwrap()); + + let header = net.peer(0).client().header(&BlockId::Number(1)).unwrap().unwrap(); + net.peer(0).with_io(|io| net.peer(0).sync.on_block_imported(io, header.hash(), &header)); net.sync(); assert_eq!(net.peer(0).client.backend().blockchain().info().unwrap().best_number, 1); assert_eq!(net.peer(1).client.backend().blockchain().info().unwrap().best_number, 1); diff --git a/core/primitives/Cargo.toml b/core/primitives/Cargo.toml index 171841f1e2879c79bc587067466cdce3858f0482..af1d26c848b589cea31b4393c5b4136c4c5eed66 100644 --- a/core/primitives/Cargo.toml +++ b/core/primitives/Cargo.toml @@ -4,22 +4,21 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -crunchy = { version = "0.2", default-features = false } sr-std = { path = "../sr-std", default-features = false } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } -fixed-hash = { version = "0.3.0-beta", default-features = false } rustc-hex = { version = "2.0", default-features = false } serde = { version = "1.0", default-features = false } serde_derive = { version = "1.0", optional = true } -uint = { version = "0.5.0-beta", default-features = false } twox-hash = { version = "1.1.0", optional = true } byteorder = { version = "1.1", default-features = false } -wasmi = { version = "0.4.1", optional = true } -hash-db = { git = "https://github.com/paritytech/trie", default-features = false } -hash256-std-hasher = { git = "https://github.com/paritytech/trie", default-features = false } -ring = { version = "0.12", optional = true } -untrusted = { version = "0.5", optional = true } +primitive-types = { version = "0.1", default-features = false, features = ["codec"] } +impl-serde = { version = "0.1", optional = true } +wasmi = { version = "0.4.3", optional = true } +hash-db = { version = "0.9", default-features = false } +hash256-std-hasher = { version = "0.9", default-features = false } +ring = { version = "0.13", optional = true } +untrusted = { version = "0.6", optional = true } hex-literal = { version = "0.1", optional = true } base58 = { version = "0.1", optional = true } blake2-rfc = { version = "0.2.18", optional = true } @@ -32,14 +31,14 @@ heapsize = "0.4" [features] default = ["std"] std = [ - "crunchy/std", "wasmi", - "uint/std", - "fixed-hash/std", - "fixed-hash/heapsize", - "fixed-hash/byteorder", - "fixed-hash/rustc-hex", - "fixed-hash/libc", + "primitive-types/std", + "primitive-types/serde", + "primitive-types/heapsize", + "primitive-types/byteorder", + "primitive-types/rustc-hex", + "primitive-types/libc", + "impl-serde", "parity-codec/std", "hash256-std-hasher/std", "hash-db/std", diff --git a/core/primitives/README.adoc b/core/primitives/README.adoc deleted file mode 100644 index ed98cf12adf1faf04ef3df3201a2710cb8a11c89..0000000000000000000000000000000000000000 --- a/core/primitives/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Primitives - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/primitives/src/authority_id.rs b/core/primitives/src/authority_id.rs index d2094d417ae9aa93f3c951f763b0aa0012c9a4e7..7773e1a930711e6a7cb6782fca09011686f80f18 100644 --- a/core/primitives/src/authority_id.rs +++ b/core/primitives/src/authority_id.rs @@ -14,34 +14,23 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . - #[cfg(feature = "std")] use serde::{Serialize, Serializer, Deserialize, Deserializer}; use H256; /// An identifier for an authority in the consensus algorithm. The same size as ed25519::Public. #[derive(Clone, Copy, PartialEq, Eq, Default, Encode, Decode)] -pub struct AuthorityId(pub [u8; 32]); - -impl AuthorityId { - /// Create an id from a 32-byte slice. Panics with other lengths. - #[cfg(feature = "std")] - fn from_slice(data: &[u8]) -> Self { - let mut r = [0u8; 32]; - r.copy_from_slice(data); - AuthorityId(r) - } -} +pub struct Ed25519AuthorityId(pub [u8; 32]); #[cfg(feature = "std")] -impl ::std::fmt::Display for AuthorityId { +impl ::std::fmt::Display for Ed25519AuthorityId { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "{}", ::ed25519::Public(self.0).to_ss58check()) } } #[cfg(feature = "std")] -impl ::std::fmt::Debug for AuthorityId { +impl ::std::fmt::Debug for Ed25519AuthorityId { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { let h = format!("{}", ::hexdisplay::HexDisplay::from(&self.0)); write!(f, "{} ({}…{})", ::ed25519::Public(self.0).to_ss58check(), &h[0..8], &h[60..]) @@ -49,59 +38,58 @@ impl ::std::fmt::Debug for AuthorityId { } #[cfg(feature = "std")] -impl ::std::hash::Hash for AuthorityId { +impl ::std::hash::Hash for Ed25519AuthorityId { fn hash(&self, state: &mut H) { self.0.hash(state); } } -impl AsRef<[u8; 32]> for AuthorityId { +impl AsRef<[u8; 32]> for Ed25519AuthorityId { fn as_ref(&self) -> &[u8; 32] { &self.0 } } -impl AsRef<[u8]> for AuthorityId { +impl AsRef<[u8]> for Ed25519AuthorityId { fn as_ref(&self) -> &[u8] { &self.0[..] } } -impl Into<[u8; 32]> for AuthorityId { +impl Into<[u8; 32]> for Ed25519AuthorityId { fn into(self) -> [u8; 32] { self.0 } } -impl From<[u8; 32]> for AuthorityId { +impl From<[u8; 32]> for Ed25519AuthorityId { fn from(a: [u8; 32]) -> Self { - AuthorityId(a) + Ed25519AuthorityId(a) } } -impl AsRef for AuthorityId { - fn as_ref(&self) -> &AuthorityId { +impl AsRef for Ed25519AuthorityId { + fn as_ref(&self) -> &Ed25519AuthorityId { &self } } -impl Into for AuthorityId { +impl Into for Ed25519AuthorityId { fn into(self) -> H256 { self.0.into() } } #[cfg(feature = "std")] -impl Serialize for AuthorityId { +impl Serialize for Ed25519AuthorityId { fn serialize(&self, serializer: S) -> Result where S: Serializer { - ::bytes::serialize(&self.0, serializer) + ::ed25519::serialize(&self, serializer) } } #[cfg(feature = "std")] -impl<'de> Deserialize<'de> for AuthorityId { +impl<'de> Deserialize<'de> for Ed25519AuthorityId { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - ::bytes::deserialize_check_len(deserializer, ::bytes::ExpectedLen::Exact(32)) - .map(|x| AuthorityId::from_slice(&x)) + ::ed25519::deserialize(deserializer) } } diff --git a/core/primitives/src/bytes.rs b/core/primitives/src/bytes.rs deleted file mode 100644 index ea375a25300943df1e6d3cbe7472fa67819d4a67..0000000000000000000000000000000000000000 --- a/core/primitives/src/bytes.rs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2017-2018 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Simple type for representing Vec with regards to serde. - -use core::fmt; - -use serde::{de, Serializer, Deserializer}; - -#[cfg(not(feature = "std"))] -mod alloc_types { - pub use ::alloc::string::String; - pub use ::alloc::vec::Vec; -} - -#[cfg(feature = "std")] -mod alloc_types { - pub use ::std::vec::Vec; - pub use ::std::string::String; -} - -pub use self::alloc_types::*; - -/// Serializes a slice of bytes. -pub fn serialize(bytes: &[u8], serializer: S) -> Result where - S: Serializer, -{ - let hex: String = ::rustc_hex::ToHex::to_hex(bytes); - serializer.serialize_str(&format!("0x{}", hex)) -} - -/// Serialize a slice of bytes as uint. -/// -/// The representation will have all leading zeros trimmed. -pub fn serialize_uint(bytes: &[u8], serializer: S) -> Result where - S: Serializer, -{ - let non_zero = bytes.iter().take_while(|b| **b == 0).count(); - let bytes = &bytes[non_zero..]; - if bytes.is_empty() { - return serializer.serialize_str("0x0"); - } - - let hex: String = ::rustc_hex::ToHex::to_hex(bytes); - let has_leading_zero = !hex.is_empty() && &hex[0..1] == "0"; - serializer.serialize_str( - &format!("0x{}", if has_leading_zero { &hex[1..] } else { &hex }) - ) -} - -/// Expected length of bytes vector. -#[derive(PartialEq, Eq)] -#[cfg_attr(feature = "std", derive(Debug))] -pub enum ExpectedLen { - /// Any length in bytes. - #[cfg_attr(not(feature = "std"), allow(unused))] - Any, - /// Exact length in bytes. - Exact(usize), - /// A bytes length between (min; max]. - Between(usize, usize), -} - -impl fmt::Display for ExpectedLen { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - ExpectedLen::Any => write!(fmt, "even length"), - ExpectedLen::Exact(v) => write!(fmt, "length of {}", v * 2), - ExpectedLen::Between(min, max) => write!(fmt, "length between ({}; {}]", min * 2, max * 2), - } - } -} - -/// Deserialize into vector of bytes. -#[cfg(feature = "std")] -pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where - D: Deserializer<'de>, -{ - deserialize_check_len(deserializer, ExpectedLen::Any) -} - -/// Deserialize into vector of bytes with additional size check. -pub fn deserialize_check_len<'de, D>(deserializer: D, len: ExpectedLen) -> Result, D::Error> where - D: Deserializer<'de>, -{ - struct Visitor { - len: ExpectedLen, - } - - impl<'a> de::Visitor<'a> for Visitor { - type Value = Vec; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "a 0x-prefixed hex string with {}", self.len) - } - - fn visit_str(self, v: &str) -> Result { - if v.len() < 2 || &v[0..2] != "0x" { - return Err(E::custom("prefix is missing")) - } - - let is_len_valid = match self.len { - // just make sure that we have all nibbles - ExpectedLen::Any => v.len() % 2 == 0, - ExpectedLen::Exact(len) => v.len() == 2 * len + 2, - ExpectedLen::Between(min, max) => v.len() <= 2 * max + 2 && v.len() > 2 * min + 2, - }; - - if !is_len_valid { - return Err(E::invalid_length(v.len() - 2, &self)) - } - - let bytes = match self.len { - ExpectedLen::Between(..) if v.len() % 2 != 0 => { - ::rustc_hex::FromHex::from_hex(&*format!("0{}", &v[2..])) - }, - _ => ::rustc_hex::FromHex::from_hex(&v[2..]) - }; - - #[cfg(feature = "std")] - fn format_err(e: ::rustc_hex::FromHexError) -> String { - format!("invalid hex value: {:?}", e) - } - - #[cfg(not(feature = "std"))] - fn format_err(e: ::rustc_hex::FromHexError) -> String { - match e { - ::rustc_hex::InvalidHexLength => format!("invalid hex value: invalid length"), - ::rustc_hex::InvalidHexCharacter(c, p) => - format!("invalid hex value: invalid character {} at position {}", c, p), - } - } - - bytes.map_err(|e| E::custom(format_err(e))) - } - - #[cfg(feature = "std")] - fn visit_string(self, v: String) -> Result { - self.visit_str(&v) - } - } - // TODO [ToDr] Use raw bytes if we switch to RLP / binencoding - // (visit_bytes, visit_bytes_buf) - deserializer.deserialize_str(Visitor { len }) -} diff --git a/core/primitives/src/changes_trie.rs b/core/primitives/src/changes_trie.rs index 1bfde315ee9816269689c0a970c94c170f2274a3..0211b57236a32d6a89ce6976a64ff9fa9300beeb 100644 --- a/core/primitives/src/changes_trie.rs +++ b/core/primitives/src/changes_trie.rs @@ -42,6 +42,25 @@ impl ChangesTrieConfiguration { && block % self.digest_interval == 0 } + /// Returns max digest interval. One if digests are not created at all. + /// Returns ::std::u64::MAX instead of panic in the case of overflow. + pub fn max_digest_interval(&self) -> u64 { + if !self.is_digest_build_enabled() { + return 1; + } + + // TODO: use saturating_pow when available + let mut max_digest_interval = self.digest_interval; + for _ in 1..self.digest_levels { + max_digest_interval = match max_digest_interval.checked_mul(self.digest_interval) { + Some(max_digest_interval) => max_digest_interval, + None => return u64::max_value(), + } + } + + max_digest_interval + } + /// Returns Some if digest must be built at given block number. /// The tuple is: /// ( @@ -124,4 +143,12 @@ mod tests { assert_eq!(config(8, 4).digest_level_at_block(4096), Some((4, 4096, 512))); assert_eq!(config(8, 4).digest_level_at_block(4112), Some((1, 8, 1))); } + + #[test] + fn max_digest_interval_works() { + assert_eq!(config(0, 0).max_digest_interval(), 1); + assert_eq!(config(2, 2).max_digest_interval(), 4); + assert_eq!(config(8, 4).max_digest_interval(), 4096); + assert_eq!(config(::std::u64::MAX, 1024).max_digest_interval(), ::std::u64::MAX); + } } diff --git a/core/primitives/src/ed25519.rs b/core/primitives/src/ed25519.rs index 2e30653e8182f5126e22ca791d89123e34cd73a3..05077fbd37e80b504f85a0c1174d8f875e9c52ca 100644 --- a/core/primitives/src/ed25519.rs +++ b/core/primitives/src/ed25519.rs @@ -21,9 +21,12 @@ use untrusted; use blake2_rfc; use ring::{rand, signature}; -use {hash::H512, AuthorityId}; +use {hash::H512, Ed25519AuthorityId}; use base58::{ToBase58, FromBase58}; +#[cfg(feature = "std")] +use serde::{de, Serializer, Deserializer, Deserialize}; + /// Alias to 512-bit hash when used in the context of a signature on the relay chain. pub type Signature = H512; @@ -166,14 +169,14 @@ impl AsRef for Pair { } } -impl Into for Public { - fn into(self) -> AuthorityId { - AuthorityId(self.0) +impl Into for Public { + fn into(self) -> Ed25519AuthorityId { + Ed25519AuthorityId(self.0) } } -impl From for Public { - fn from(id: AuthorityId) -> Self { +impl From for Public { + fn from(id: Ed25519AuthorityId) -> Self { Public(id.0) } } @@ -278,6 +281,25 @@ impl Verifiable for LocalizedSignature { } } +/// Deserialize from `ss58` into something that can be constructed from `[u8; 32]`. +#[cfg(feature = "std")] +pub fn deserialize<'de, D, T: From<[u8; 32]>>(deserializer: D) -> Result where + D: Deserializer<'de>, +{ + let ss58 = String::deserialize(deserializer)?; + Public::from_ss58check(&ss58) + .map_err(|e| de::Error::custom(format!("{:?}", e))) + .map(|v| v.0.into()) +} + +/// Serializes something that implements `AsRef<[u8; 32]>` into `ss58`. +#[cfg(feature = "std")] +pub fn serialize>(data: &T, serializer: S) -> Result where + S: Serializer, +{ + serializer.serialize_str(&Public(*data.as_ref()).to_ss58check()) +} + #[cfg(test)] mod test { use super::*; diff --git a/core/primitives/src/hash.rs b/core/primitives/src/hash.rs index 5733a738c9b93627a07e375e5f6158d2b08fe6c3..98a906861fff5434d820556752cb6199d656caa5 100644 --- a/core/primitives/src/hash.rs +++ b/core/primitives/src/hash.rs @@ -16,65 +16,17 @@ //! A fixed hash type. -#[cfg(feature = "std")] -use serde::{Serialize, Serializer, Deserialize, Deserializer}; - -#[cfg(feature = "std")] -use bytes; - -macro_rules! impl_rest { - ($name: ident, $len: expr) => { - #[cfg(feature = "std")] - impl Serialize for $name { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - bytes::serialize(&self.0, serializer) - } - } - - #[cfg(feature = "std")] - impl<'de> Deserialize<'de> for $name { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - bytes::deserialize_check_len(deserializer, bytes::ExpectedLen::Exact($len)) - .map(|x| $name::from_slice(&x)) - } - } - - impl ::codec::Encode for $name { - fn using_encoded R>(&self, f: F) -> R { - self.0.using_encoded(f) - } - } - impl ::codec::Decode for $name { - fn decode(input: &mut I) -> Option { - <[u8; $len] as ::codec::Decode>::decode(input).map($name) - } - } - - #[cfg(feature = "std")] - impl From for $name { - fn from(val: u64) -> Self { - Self::from_low_u64_be(val) - } - } - } -} - -construct_fixed_hash!{ - /// Fixed-size uninterpreted hash type with 20 bytes (160 bits) size. - pub struct H160(20); -} -construct_fixed_hash!{ - /// Fixed-size uninterpreted hash type with 32 bytes (256 bits) size. - pub struct H256(32); +pub use primitive_types::{H160, H256, H512}; + +/// Hash conversion. Used to convert between unbound associated hash types in traits, +/// implemented by the same hash type. +/// Panics if used to convert between different hash types. +pub fn convert_hash, H2: AsRef<[u8]>>(src: &H2) -> H1 { + let mut dest = H1::default(); + assert_eq!(dest.as_mut().len(), src.as_ref().len()); + dest.as_mut().copy_from_slice(src.as_ref()); + dest } -construct_fixed_hash!{ - /// Fixed-size uninterpreted hash type with 64 bytes (512 bits) size. - pub struct H512(64); -} - -impl_rest!(H160, 20); -impl_rest!(H256, 32); -impl_rest!(H512, 64); #[cfg(test)] mod tests { diff --git a/core/primitives/src/hexdisplay.rs b/core/primitives/src/hexdisplay.rs index f02b0f19b705f72c4e7c40ba9a629277bbc0e3ed..b202fdf2e3fa955dfff43c7e355a30cb1a007ca9 100644 --- a/core/primitives/src/hexdisplay.rs +++ b/core/primitives/src/hexdisplay.rs @@ -57,7 +57,7 @@ impl AsBytesRef for [u8] { fn as_bytes_ref(&self) -> &[u8] { &self } } -impl AsBytesRef for ::bytes::Vec { +impl AsBytesRef for Vec { fn as_bytes_ref(&self) -> &[u8] { &self } } @@ -91,4 +91,3 @@ pub fn ascii_format(asciish: &[u8]) -> String { } r } - diff --git a/core/primitives/src/lib.rs b/core/primitives/src/lib.rs index affa1c5c00fe3a2589b61c17d326e0d3ea195901..c1f427f49671309927dece2278b6f34dbaaec363 100644 --- a/core/primitives/src/lib.rs +++ b/core/primitives/src/lib.rs @@ -14,21 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Shareable Substrate types. -// end::description[] #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(alloc))] -#[macro_use] -extern crate crunchy; -#[macro_use] -extern crate fixed_hash; -#[macro_use] -extern crate uint as uint_crate; +extern crate primitive_types; #[macro_use] extern crate parity_codec_derive; @@ -53,6 +46,10 @@ extern crate untrusted; #[macro_use] extern crate hex_literal; +#[cfg(feature = "std")] +#[macro_use] +extern crate impl_serde; + #[cfg(feature = "std")] #[macro_use] extern crate serde_derive; @@ -84,9 +81,12 @@ macro_rules! map { use rstd::prelude::*; use rstd::ops::Deref; +#[cfg(feature = "std")] +use std::borrow::Cow; #[cfg(feature = "std")] -pub mod bytes; +pub use impl_serde::serialize as bytes; + #[cfg(feature = "std")] pub mod hashing; #[cfg(feature = "std")] @@ -109,9 +109,9 @@ mod changes_trie; #[cfg(test)] mod tests; -pub use self::hash::{H160, H256, H512}; +pub use self::hash::{H160, H256, H512, convert_hash}; pub use self::uint::U256; -pub use authority_id::AuthorityId; +pub use authority_id::Ed25519AuthorityId; pub use changes_trie::ChangesTrieConfiguration; pub use hash_db::Hasher; @@ -131,7 +131,99 @@ impl From> for Bytes { fn from(s: Vec) -> Self { Bytes(s) } } +impl From for Bytes { + fn from(s: OpaqueMetadata) -> Self { Bytes(s.0) } +} + impl Deref for Bytes { type Target = [u8]; fn deref(&self) -> &[u8] { &self.0[..] } } + +/// Stores the encoded `RuntimeMetadata` for the native side as opaque type. +#[derive(Encode, Decode, PartialEq)] +pub struct OpaqueMetadata(Vec); + +impl OpaqueMetadata { + /// Creates a new instance with the given metadata blob. + pub fn new(metadata: Vec) -> Self { + OpaqueMetadata(metadata) + } +} + +impl rstd::ops::Deref for OpaqueMetadata { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +/// Something that is either a native or an encoded value. +#[cfg(feature = "std")] +pub enum NativeOrEncoded { + /// The native representation. + Native(R), + /// The encoded representation. + Encoded(Vec) +} + +#[cfg(feature = "std")] +impl ::std::fmt::Debug for NativeOrEncoded { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + self.as_encoded().as_ref().fmt(f) + } +} + +#[cfg(feature = "std")] +impl NativeOrEncoded { + /// Return the value as the encoded format. + pub fn as_encoded<'a>(&'a self) -> Cow<'a, [u8]> { + match self { + NativeOrEncoded::Encoded(e) => Cow::Borrowed(e.as_slice()), + NativeOrEncoded::Native(n) => Cow::Owned(n.encode()), + } + } + + /// Return the value as the encoded format. + pub fn into_encoded(self) -> Vec { + match self { + NativeOrEncoded::Encoded(e) => e, + NativeOrEncoded::Native(n) => n.encode(), + } + } +} + +#[cfg(feature = "std")] +impl PartialEq for NativeOrEncoded { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (NativeOrEncoded::Native(l), NativeOrEncoded::Native(r)) => l == r, + (NativeOrEncoded::Native(n), NativeOrEncoded::Encoded(e)) | + (NativeOrEncoded::Encoded(e), NativeOrEncoded::Native(n)) => + Some(n) == codec::Decode::decode(&mut &e[..]).as_ref(), + (NativeOrEncoded::Encoded(l), NativeOrEncoded::Encoded(r)) => l == r, + } + } +} + +/// A value that is never in a native representation. +/// This is type is useful in conjuction with `NativeOrEncoded`. +#[cfg(feature = "std")] +#[derive(PartialEq)] +pub enum NeverNativeValue {} + +#[cfg(feature = "std")] +impl codec::Encode for NeverNativeValue { + fn encode(&self) -> Vec { + // The enum is not constructable, so this function should never be callable! + unreachable!() + } +} + +#[cfg(feature = "std")] +impl codec::Decode for NeverNativeValue { + fn decode(_: &mut I) -> Option { + None + } +} diff --git a/core/primitives/src/storage.rs b/core/primitives/src/storage.rs index f3b22294bde1342fb48396447a687dcb4129a5b0..0a14b14756b1298c6e1828e4c656ea065d54f571 100644 --- a/core/primitives/src/storage.rs +++ b/core/primitives/src/storage.rs @@ -32,6 +32,7 @@ pub struct StorageData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec /// Storage change set #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, PartialEq, Eq))] +#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] pub struct StorageChangeSet { /// Block hash pub block: Hash, diff --git a/core/primitives/src/uint.rs b/core/primitives/src/uint.rs index 4727ed54bd0694199b6088d49b63fb358bd7fea1..0d46e81effc5524d806c71ca800f52310799f11f 100644 --- a/core/primitives/src/uint.rs +++ b/core/primitives/src/uint.rs @@ -16,55 +16,7 @@ //! An unsigned fixed-size integer. -#[cfg(feature = "std")] -use serde::{Serialize, Serializer, Deserialize, Deserializer}; - -#[cfg(feature = "std")] -use bytes; - -macro_rules! impl_serde { - ($name: ident, $len: expr) => { - #[cfg(feature = "std")] - impl Serialize for $name { - fn serialize(&self, serializer: S) -> Result where S: Serializer { - let mut bytes = [0u8; $len * 8]; - self.to_big_endian(&mut bytes); - bytes::serialize_uint(&bytes, serializer) - } - } - - #[cfg(feature = "std")] - impl<'de> Deserialize<'de> for $name { - fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - bytes::deserialize_check_len(deserializer, bytes::ExpectedLen::Between(0, $len * 8)) - .map(|x| (&*x).into()) - } - } - } -} - -macro_rules! impl_codec { - ($name: ident, $len: expr) => { - impl ::codec::Encode for $name { - fn using_encoded R>(&self, f: F) -> R { - let mut bytes = [0u8; $len * 8]; - self.to_little_endian(&mut bytes); - bytes.using_encoded(f) - } - } - - impl ::codec::Decode for $name { - fn decode(input: &mut I) -> Option { - <[u8; $len * 8] as ::codec::Decode>::decode(input) - .map(|b| $name::from_little_endian(&b)) - } - } - } -} - -construct_uint!(U256, 4); -impl_serde!(U256, 4); -impl_codec!(U256, 4); +pub use primitive_types::U256; #[cfg(test)] mod tests { diff --git a/core/rpc-servers/README.adoc b/core/rpc-servers/README.adoc deleted file mode 100644 index 18840be421fdd2a169d419b54348bd9e19352af9..0000000000000000000000000000000000000000 --- a/core/rpc-servers/README.adoc +++ /dev/null @@ -1,14 +0,0 @@ - -= RPC Server - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- - diff --git a/core/rpc-servers/src/lib.rs b/core/rpc-servers/src/lib.rs index 47934f805ad31802729f9dbac50139cb2b1e7069..fb09799ef5c6326159114a1d42f364d91cc2ab28 100644 --- a/core/rpc-servers/src/lib.rs +++ b/core/rpc-servers/src/lib.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Substrate RPC servers. -// end::description[] #[warn(missing_docs)] @@ -32,7 +30,10 @@ extern crate sr_primitives; extern crate log; use std::io; -use sr_primitives::traits::{Block as BlockT, NumberFor}; +use sr_primitives::{traits::{Block as BlockT, NumberFor}, generic::SignedBlock}; + +/// Maximal payload accepted by RPC servers +const MAX_PAYLOAD: usize = 15 * 1024 * 1024; type Metadata = apis::metadata::Metadata; type RpcHandler = pubsub::PubSubHandler; @@ -40,7 +41,7 @@ pub type HttpServer = http::Server; pub type WsServer = ws::Server; /// Construct rpc `IoHandler` -pub fn rpc_handler( +pub fn rpc_handler( state: S, chain: C, author: A, @@ -48,11 +49,10 @@ pub fn rpc_handler( ) -> RpcHandler where Block: BlockT + 'static, ExHash: Send + Sync + 'static + sr_primitives::Serialize + sr_primitives::DeserializeOwned, - PendingExtrinsics: serde::Serialize + serde::de::DeserializeOwned + Send + Sync + 'static, S: apis::state::StateApi, - C: apis::chain::ChainApi, Block::Extrinsic, Metadata=Metadata>, - A: apis::author::AuthorApi, - Y: apis::system::SystemApi, + C: apis::chain::ChainApi, Block::Hash, Block::Header, SignedBlock, Metadata=Metadata>, + A: apis::author::AuthorApi, + Y: apis::system::SystemApi>, { let mut io = pubsub::PubSubHandler::default(); io.extend_with(state.to_delegate()); @@ -69,8 +69,10 @@ pub fn start_http( ) -> io::Result { http::ServerBuilder::new(io) .threads(4) + .health_api(("/health", "system_health")) .rest_api(http::RestApi::Unsecure) .cors(http::DomainsValidation::Disabled) + .max_request_body_size(MAX_PAYLOAD) .start_http(addr) } @@ -80,6 +82,7 @@ pub fn start_ws( io: RpcHandler, ) -> io::Result { ws::ServerBuilder::with_meta_extractor(io, |context: &ws::RequestContext| Metadata::new(context.sender())) + .max_payload(MAX_PAYLOAD) .start(addr) .map_err(|err| match err { ws::Error(ws::ErrorKind::Io(io), _) => io, diff --git a/core/rpc/Cargo.toml b/core/rpc/Cargo.toml index 3f35394c9112928ed9d7176751fb6d089a2bd5b3..bf3e1aa5af346ade4c1f18c2e2a3076cdfc92aa1 100644 --- a/core/rpc/Cargo.toml +++ b/core/rpc/Cargo.toml @@ -9,12 +9,16 @@ jsonrpc-core = { git="https://github.com/paritytech/jsonrpc.git" } jsonrpc-macros = { git="https://github.com/paritytech/jsonrpc.git" } jsonrpc-pubsub = { git="https://github.com/paritytech/jsonrpc.git" } log = "0.4" -parking_lot = "0.4" -parity-codec = "2.1" +parking_lot = "0.7.1" +parity-codec = "2.2" +serde = "1.0" +serde_derive = "1.0" +serde_json = "1.0" substrate-client = { path = "../client" } substrate-executor = { path = "../executor" } -substrate-transaction-pool = { path = "../transaction-pool" } +substrate-network = { path = "../network" } substrate-primitives = { path = "../primitives" } +substrate-transaction-pool = { path = "../transaction-pool" } sr-primitives = { path = "../sr-primitives" } sr-version = { path = "../sr-version" } tokio = "0.1.7" diff --git a/core/rpc/README.adoc b/core/rpc/README.adoc deleted file mode 100644 index 5e4db4909976a24f2468967f05b68c3d900e3635..0000000000000000000000000000000000000000 --- a/core/rpc/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= RPC - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/rpc/src/author/mod.rs b/core/rpc/src/author/mod.rs index ff08c4c840e3cb1306ddb9b0723325f082f31018..be8648750994fb15f6f402ccd44c4817d19f2e9a 100644 --- a/core/rpc/src/author/mod.rs +++ b/core/rpc/src/author/mod.rs @@ -19,13 +19,12 @@ use std::sync::Arc; use client::{self, Client}; -use codec::Decode; +use codec::{Encode, Decode}; use transaction_pool::{ txpool::{ ChainApi as PoolChainApi, BlockHash, ExHash, - ExtrinsicFor, IntoPoolError, Pool, watcher::Status, @@ -47,19 +46,16 @@ use self::error::Result; build_rpc_trait! { /// Substrate authoring RPC API - pub trait AuthorApi { + pub trait AuthorApi { type Metadata; - /// Submit extrinsic for inclusion in block. - #[rpc(name = "author_submitRichExtrinsic")] - fn submit_rich_extrinsic(&self, Extrinsic) -> Result; /// Submit hex-encoded extrinsic for inclusion in block. #[rpc(name = "author_submitExtrinsic")] fn submit_extrinsic(&self, Bytes) -> Result; /// Returns all pending extrinsics, potentially grouped by sender. #[rpc(name = "author_pendingExtrinsics")] - fn pending_extrinsics(&self) -> Result; + fn pending_extrinsics(&self) -> Result>; #[pubsub(name = "author_extrinsicUpdate")] { /// Submit an extrinsic to watch. @@ -68,30 +64,26 @@ build_rpc_trait! { /// Unsubscribe from extrinsic watching. #[rpc(name = "author_unwatchExtrinsic")] - fn unwatch_extrinsic(&self, SubscriptionId) -> Result; + fn unwatch_extrinsic(&self, Option, SubscriptionId) -> Result; } } } /// Authoring API -pub struct Author where - P: PoolChainApi + Sync + Send + 'static, -{ +pub struct Author where P: PoolChainApi + Sync + Send + 'static { /// Substrate client - client: Arc::Block>>, + client: Arc::Block, RA>>, /// Extrinsic pool pool: Arc>, /// Subscriptions manager subscriptions: Subscriptions, } -impl Author where - P: PoolChainApi + Sync + Send + 'static, -{ +impl Author where P: PoolChainApi + Sync + Send + 'static { /// Create new instance of Authoring API. pub fn new( - client: Arc::Block>>, + client: Arc::Block, RA>>, pool: Arc>, subscriptions: Subscriptions, ) -> Self { @@ -103,21 +95,18 @@ impl Author where } } -impl AuthorApi, BlockHash

, ExtrinsicFor

, Vec>> for Author where +impl AuthorApi, BlockHash

> for Author where B: client::backend::Backend<

::Block, Blake2Hasher> + Send + Sync + 'static, E: client::CallExecutor<

::Block, Blake2Hasher> + Send + Sync + 'static, P: PoolChainApi + Sync + Send + 'static, P::Block: traits::Block, P::Error: 'static, + RA: Send + Sync + 'static { type Metadata = ::metadata::Metadata; - fn submit_extrinsic(&self, xt: Bytes) -> Result> { - let dxt = Decode::decode(&mut &xt[..]).ok_or(error::Error::from(error::ErrorKind::BadFormat))?; - self.submit_rich_extrinsic(dxt) - } - - fn submit_rich_extrinsic(&self, xt: <

::Block as traits::Block>::Extrinsic) -> Result> { + fn submit_extrinsic(&self, ext: Bytes) -> Result> { + let xt = Decode::decode(&mut &ext[..]).ok_or(error::Error::from(error::ErrorKind::BadFormat))?; let best_block_hash = self.client.info()?.chain.best_hash; self.pool .submit_one(&generic::BlockId::hash(best_block_hash), xt) @@ -127,8 +116,8 @@ impl AuthorApi, BlockHash

, ExtrinsicFor

, Vec Result>> { - Ok(self.pool.ready().map(|tx| tx.data.clone()).collect()) + fn pending_extrinsics(&self) -> Result> { + Ok(self.pool.ready().map(|tx| tx.data.encode().into()).collect()) } fn watch_extrinsic(&self, _metadata: Self::Metadata, subscriber: pubsub::Subscriber, BlockHash

>>, xt: Bytes) { @@ -160,7 +149,7 @@ impl AuthorApi, BlockHash

, ExtrinsicFor

, Vec Result { + fn unwatch_extrinsic(&self, _metadata: Option, id: SubscriptionId) -> Result { Ok(self.subscriptions.cancel(id)) } } diff --git a/core/rpc/src/author/tests.rs b/core/rpc/src/author/tests.rs index 7032355ef2468b977d98db0584fcfd0685b01541..d84fa72225d17dc4851be66b79b242b89c22f317 100644 --- a/core/rpc/src/author/tests.rs +++ b/core/rpc/src/author/tests.rs @@ -36,7 +36,7 @@ fn uxt(sender: Keyring, nonce: u64) -> Extrinsic { to: Default::default(), }; let signature = Keyring::from_raw_public(tx.from.to_fixed_bytes()).unwrap().sign(&tx.encode()).into(); - Extrinsic { transfer: tx, signature } + Extrinsic::Transfer(tx, signature) } #[test] @@ -48,7 +48,7 @@ fn submit_transaction_should_not_cause_error() { pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client))), subscriptions: Subscriptions::new(runtime.executor()), }; - let h: H256 = hex!("e10ad66bce51ef3e2a1167934ce3740d2d8c703810f9b314e89f2e783f75e826").into(); + let h: H256 = hex!("81897a4890fb7554e7f77c533a865846a11583a56a8ad5e307543188d55e64f1").into(); assert_matches!( AuthorApi::submit_extrinsic(&p, uxt(Keyring::Alice, 1).encode().into()), @@ -68,14 +68,14 @@ fn submit_rich_transaction_should_not_cause_error() { pool: Arc::new(Pool::new(Default::default(), ChainApi::new(client.clone()))), subscriptions: Subscriptions::new(runtime.executor()), }; - let h: H256 = hex!("fccc48291473c53746cd267cf848449edd7711ee6511fba96919d5f9f4859e4f").into(); + let h: H256 = hex!("9ec8469b5dcfe29cc274ac1d07ad73d80be57566ace0fcdbe51ebcf4b51e925b").into(); assert_matches!( - AuthorApi::submit_rich_extrinsic(&p, uxt(Keyring::Alice, 0)), + AuthorApi::submit_extrinsic(&p, uxt(Keyring::Alice, 0).encode().into()), Ok(h2) if h == h2 ); assert!( - AuthorApi::submit_rich_extrinsic(&p, uxt(Keyring::Alice, 0)).is_err() + AuthorApi::submit_extrinsic(&p, uxt(Keyring::Alice, 0).encode().into()).is_err() ); } @@ -106,9 +106,9 @@ fn should_watch_extrinsic() { to: Default::default(), }; let signature = Keyring::from_raw_public(tx.from.to_fixed_bytes()).unwrap().sign(&tx.encode()).into(); - Extrinsic { transfer: tx, signature } + Extrinsic::Transfer(tx, signature) }; - AuthorApi::submit_rich_extrinsic(&p, replacement).unwrap(); + AuthorApi::submit_extrinsic(&p, replacement.encode().into()).unwrap(); let (res, data) = runtime.block_on(data.into_future()).unwrap(); assert_eq!( res, @@ -116,7 +116,7 @@ fn should_watch_extrinsic() { ); assert_eq!( runtime.block_on(data.into_future()).unwrap().0, - Some(r#"{"jsonrpc":"2.0","method":"test","params":{"result":{"usurped":"0xed454dcee51431679c2559403187a56567fded1fc50b6ae3aada87c1d412df5c"},"subscription":1}}"#.into()) + Some(r#"{"jsonrpc":"2.0","method":"test","params":{"result":{"usurped":"0x53daed816610aa6b22dedbcee43aba44a7ca7155cc71f2919c5e79ebbc7de58c"},"subscription":1}}"#.into()) ); } @@ -131,9 +131,9 @@ fn should_return_pending_extrinsics() { subscriptions: Subscriptions::new(runtime.executor()), }; let ex = uxt(Keyring::Alice, 0); - AuthorApi::submit_rich_extrinsic(&p, ex.clone()).unwrap(); + AuthorApi::submit_extrinsic(&p, ex.encode().into()).unwrap(); assert_matches!( p.pending_extrinsics(), - Ok(ref expected) if expected == &vec![ex] + Ok(ref expected) if *expected == vec![Bytes(ex.encode())] ); } diff --git a/core/rpc/src/chain/mod.rs b/core/rpc/src/chain/mod.rs index 8542d2ff4cee85a6f6bf473f097c921521f92e53..ab6f0d710d1b89533a564394f235e851a0683f31 100644 --- a/core/rpc/src/chain/mod.rs +++ b/core/rpc/src/chain/mod.rs @@ -21,25 +21,28 @@ use std::sync::Arc; use client::{self, Client, BlockchainEvents}; use jsonrpc_macros::{pubsub, Trailing}; use jsonrpc_pubsub::SubscriptionId; +use primitives::{H256, Blake2Hasher}; use rpc::Result as RpcResult; use rpc::futures::{stream, Future, Sink, Stream}; -use primitives::H256; use runtime_primitives::generic::{BlockId, SignedBlock}; use runtime_primitives::traits::{Block as BlockT, Header, NumberFor}; -use runtime_version::RuntimeVersion; -use primitives::{Blake2Hasher, storage}; +use serde::Serialize; use subscriptions::Subscriptions; mod error; #[cfg(test)] mod tests; +mod number; use self::error::Result; build_rpc_trait! { /// Substrate blockchain API - pub trait ChainApi { + pub trait ChainApi where + Header: Serialize, + SignedBlock: Serialize, + { type Metadata; /// Get header of a relay chain block. @@ -48,22 +51,18 @@ build_rpc_trait! { /// Get header and body of a relay chain block. #[rpc(name = "chain_getBlock")] - fn block(&self, Trailing) -> Result>>; + fn block(&self, Trailing) -> Result>; /// Get hash of the n-th block in the canon chain. /// /// By default returns latest block hash. #[rpc(name = "chain_getBlockHash", alias = ["chain_getHead", ])] - fn block_hash(&self, Trailing) -> Result>; + fn block_hash(&self, Trailing>) -> Result>; /// Get hash of the last finalised block in the canon chain. #[rpc(name = "chain_getFinalisedHead")] fn finalised_head(&self) -> Result; - /// Get the runtime version. - #[rpc(name = "chain_getRuntimeVersion")] - fn runtime_version(&self, Trailing) -> Result; - #[pubsub(name = "chain_newHead")] { /// New head subscription #[rpc(name = "chain_subscribeNewHead", alias = ["subscribe_newHead", ])] @@ -71,7 +70,7 @@ build_rpc_trait! { /// Unsubscribe from new head subscription. #[rpc(name = "chain_unsubscribeNewHead", alias = ["unsubscribe_newHead", ])] - fn unsubscribe_new_head(&self, SubscriptionId) -> RpcResult; + fn unsubscribe_new_head(&self, Option, SubscriptionId) -> RpcResult; } #[pubsub(name = "chain_finalisedHead")] { @@ -81,32 +80,22 @@ build_rpc_trait! { /// Unsubscribe from new head subscription. #[rpc(name = "chain_unsubscribeFinalisedHeads")] - fn unsubscribe_finalised_heads(&self, SubscriptionId) -> RpcResult; - } - - #[pubsub(name = "chain_runtimeVersion")] { - /// New runtime version subscription - #[rpc(name = "chain_subscribeRuntimeVersion")] - fn subscribe_runtime_version(&self, Self::Metadata, pubsub::Subscriber); - - /// Unsubscribe from runtime version subscription - #[rpc(name = "chain_unsubscribeRuntimeVersion")] - fn unsubscribe_runtime_version(&self, SubscriptionId) -> RpcResult; + fn unsubscribe_finalised_heads(&self, Option, SubscriptionId) -> RpcResult; } } } /// Chain API with subscriptions support. -pub struct Chain { +pub struct Chain { /// Substrate client. - client: Arc>, + client: Arc>, /// Current subscriptions. subscriptions: Subscriptions, } -impl Chain { +impl Chain { /// Create new Chain API RPC handler. - pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { + pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { Self { client, subscriptions, @@ -114,10 +103,11 @@ impl Chain { } } -impl Chain where +impl Chain where Block: BlockT + 'static, B: client::backend::Backend + Send + Sync + 'static, E: client::CallExecutor + Send + Sync + 'static, + RA: Send + Sync + 'static { fn unwrap_or_best(&self, hash: Trailing) -> Result { Ok(match hash.into() { @@ -163,10 +153,11 @@ impl Chain where } } -impl ChainApi, Block::Extrinsic> for Chain where +impl ChainApi, Block::Hash, Block::Header, SignedBlock> for Chain where Block: BlockT + 'static, B: client::backend::Backend + Send + Sync + 'static, E: client::CallExecutor + Send + Sync + 'static, + RA: Send + Sync + 'static { type Metadata = ::metadata::Metadata; @@ -176,16 +167,17 @@ impl ChainApi, Block:: } fn block(&self, hash: Trailing) - -> Result>> + -> Result>> { let hash = self.unwrap_or_best(hash)?; Ok(self.client.block(&BlockId::Hash(hash))?) } - fn block_hash(&self, number: Trailing>) -> Result> { - Ok(match number.into() { + fn block_hash(&self, number: Trailing>>) -> Result> { + let number: Option>> = number.into(); + Ok(match number { None => Some(self.client.info()?.chain.best_hash), - Some(number) => self.client.header(&BlockId::number(number))?.map(|h| h.hash()), + Some(num_or_hex) => self.client.header(&BlockId::number(num_or_hex.to_number()?))?.map(|h| h.hash()), }) } @@ -193,11 +185,6 @@ impl ChainApi, Block:: Ok(self.client.info()?.chain.finalized_hash) } - fn runtime_version(&self, at: Trailing) -> Result { - let at = self.unwrap_or_best(at)?; - Ok(self.client.runtime_version_at(&BlockId::Hash(at))?) - } - fn subscribe_new_head(&self, _metadata: Self::Metadata, subscriber: pubsub::Subscriber) { self.subscribe_headers( subscriber, @@ -208,7 +195,7 @@ impl ChainApi, Block:: ) } - fn unsubscribe_new_head(&self, id: SubscriptionId) -> RpcResult { + fn unsubscribe_new_head(&self, _metadata: Option, id: SubscriptionId) -> RpcResult { Ok(self.subscriptions.cancel(id)) } @@ -221,55 +208,7 @@ impl ChainApi, Block:: ) } - fn unsubscribe_finalised_heads(&self, id: SubscriptionId) -> RpcResult { - Ok(self.subscriptions.cancel(id)) - } - - fn subscribe_runtime_version(&self, _meta: Self::Metadata, subscriber: pubsub::Subscriber) { - let stream = match self.client.storage_changes_notification_stream(Some(&[storage::StorageKey(storage::well_known_keys::CODE.to_vec())])) { - Ok(stream) => stream, - Err(err) => { - let _ = subscriber.reject(error::Error::from(err).into()); - return; - } - }; - - self.subscriptions.add(subscriber, |sink| { - let version = self.runtime_version(None.into()) - .map_err(Into::into); - - let client = self.client.clone(); - let mut previous_version = version.clone(); - - let stream = stream - .map_err(|e| warn!("Error creating storage notification stream: {:?}", e)) - .filter_map(move |_| { - let version = client.info().and_then(|info| { - client.runtime_version_at(&BlockId::hash(info.chain.best_hash)) - }) - .map_err(error::Error::from) - .map_err(Into::into); - if previous_version != version { - previous_version = version.clone(); - Some(version) - } else { - None - } - }); - - sink - .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) - .send_all( - stream::iter_result(vec![Ok(version)]) - .chain(stream) - ) - // we ignore the resulting Stream (if the first stream is over we are unsubscribed) - .map(|_| ()) - }); - } - - - fn unsubscribe_runtime_version(&self, id: SubscriptionId) -> RpcResult { + fn unsubscribe_finalised_heads(&self, _metadata: Option, id: SubscriptionId) -> RpcResult { Ok(self.subscriptions.cancel(id)) } } diff --git a/core/rpc/src/chain/number.rs b/core/rpc/src/chain/number.rs new file mode 100644 index 0000000000000000000000000000000000000000..7a300313e31d9d554d6f8f7e071482b8cb5f94d7 --- /dev/null +++ b/core/rpc/src/chain/number.rs @@ -0,0 +1,68 @@ +// Copyright 2017-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 . + +use primitives::U256; +use runtime_primitives::traits; + +/// RPC Block number type +/// +/// 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(Deserialize)] +#[serde(untagged)] +pub enum NumberOrHex { + /// The original header number type of block. + Number(Number), + /// Hex representation of the block number. + Hex(U256), +} + +impl> NumberOrHex { + /// Attempts to convert into concrete block number. + /// + /// Fails in case hex number is too big. + pub fn to_number(self) -> Result { + match self { + NumberOrHex::Number(n) => Ok(n), + NumberOrHex::Hex(h) => { + // TODO [ToDr] this only supports `u64` since `BlockNumber` is `As` we could possibly go with `u128`. (#1377) + let l = h.low_u64(); + if U256::from(l) != h { + Err(format!("`{}` does not fit into the block number type.", h)) + } else { + Ok(traits::As::sa(l)) + } + }, + } + } +} + +#[cfg(test)] +impl From for NumberOrHex { + fn from(n: u64) -> Self { + NumberOrHex::Number(n) + } +} + +#[cfg(test)] +impl From for NumberOrHex { + fn from(n: U256) -> Self { + NumberOrHex::Hex(n) + } +} diff --git a/core/rpc/src/chain/tests.rs b/core/rpc/src/chain/tests.rs index 172223b941ccd2d244c58e6ce2669e58dd1050be..5dcd2d0e21cfb1072800591bd46dd0812bc9fc6a 100644 --- a/core/rpc/src/chain/tests.rs +++ b/core/rpc/src/chain/tests.rs @@ -70,13 +70,12 @@ fn should_return_a_block() { let block = api.client.new_block().unwrap().bake().unwrap(); let block_hash = block.hash(); - api.client.justify_and_import(BlockOrigin::Own, block).unwrap(); + api.client.import(BlockOrigin::Own, block).unwrap(); - - // Genesis block is not justified, so we can't query it? + // Genesis block is not justified assert_matches!( api.block(Some(api.client.genesis_hash()).into()), - Ok(None) + Ok(Some(SignedBlock { justification: None, .. })) ); assert_matches!( @@ -130,24 +129,28 @@ fn should_return_block_hash() { assert_matches!( - client.block_hash(Some(0u64).into()), + client.block_hash(Some(0u64.into()).into()), Ok(Some(ref x)) if x == &client.client.genesis_hash() ); assert_matches!( - client.block_hash(Some(1u64).into()), + client.block_hash(Some(1u64.into()).into()), Ok(None) ); let block = client.client.new_block().unwrap().bake().unwrap(); - client.client.justify_and_import(BlockOrigin::Own, block.clone()).unwrap(); + client.client.import(BlockOrigin::Own, block.clone()).unwrap(); assert_matches!( - client.block_hash(Some(0u64).into()), + client.block_hash(Some(0u64.into()).into()), Ok(Some(ref x)) if x == &client.client.genesis_hash() ); assert_matches!( - client.block_hash(Some(1u64).into()), + client.block_hash(Some(1u64.into()).into()), + Ok(Some(ref x)) if x == &block.hash() + ); + assert_matches!( + client.block_hash(Some(::primitives::U256::from(1u64).into()).into()), Ok(Some(ref x)) if x == &block.hash() ); } @@ -170,7 +173,7 @@ fn should_return_finalised_hash() { // import new block let builder = client.client.new_block().unwrap(); - client.client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + client.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); // no finalisation yet assert_matches!( client.finalised_head(), @@ -178,7 +181,7 @@ fn should_return_finalised_hash() { ); // finalise - client.client.finalize_block(BlockId::number(1), true).unwrap(); + client.client.finalize_block(BlockId::number(1), None, true).unwrap(); assert_matches!( client.finalised_head(), Ok(ref x) if x == &client.client.block_hash(1).unwrap().unwrap() @@ -203,7 +206,7 @@ fn should_notify_about_latest_block() { assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); let builder = api.client.new_block().unwrap(); - api.client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); } // assert initial head sent. @@ -234,8 +237,8 @@ fn should_notify_about_finalised_block() { assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); let builder = api.client.new_block().unwrap(); - api.client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); - api.client.finalize_block(BlockId::number(1), true).unwrap(); + api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + api.client.finalize_block(BlockId::number(1), None, true).unwrap(); } // assert initial head sent. @@ -247,26 +250,3 @@ fn should_notify_about_finalised_block() { // no more notifications on this channel assert_eq!(core.block_on(next.into_future()).unwrap().0, None); } - -#[test] -fn should_return_runtime_version() { - let core = ::tokio::runtime::Runtime::new().unwrap(); - let remote = core.executor(); - - let client = Chain { - client: Arc::new(test_client::new()), - subscriptions: Subscriptions::new(remote), - }; - - assert_matches!( - client.runtime_version(None.into()), - Ok(ref ver) if ver == &RuntimeVersion { - spec_name: "test".into(), - impl_name: "parity-test".into(), - authoring_version: 1, - spec_version: 1, - impl_version: 1, - apis: (&[][..]).into() - } - ); -} diff --git a/core/rpc/src/lib.rs b/core/rpc/src/lib.rs index dbbc8e3a6ad4477fb5c90bb9829a3b62ddde41fa..91eef709a4e82fae10ab276494ef455986941502 100644 --- a/core/rpc/src/lib.rs +++ b/core/rpc/src/lib.rs @@ -14,21 +14,22 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Substrate RPC interfaces. -// end::description[] #![warn(missing_docs)] extern crate jsonrpc_core as rpc; extern crate jsonrpc_pubsub; -extern crate parking_lot; extern crate parity_codec as codec; -extern crate substrate_client as client; -extern crate substrate_transaction_pool as transaction_pool; -extern crate substrate_primitives as primitives; +extern crate parking_lot; +extern crate serde; +extern crate serde_json; extern crate sr_primitives as runtime_primitives; extern crate sr_version as runtime_version; +extern crate substrate_client as client; +extern crate substrate_network as network; +extern crate substrate_primitives as primitives; +extern crate substrate_transaction_pool as transaction_pool; extern crate tokio; #[macro_use] @@ -37,6 +38,8 @@ extern crate error_chain; extern crate jsonrpc_macros; #[macro_use] extern crate log; +#[macro_use] +extern crate serde_derive; #[cfg(test)] #[macro_use] diff --git a/core/rpc/src/state/mod.rs b/core/rpc/src/state/mod.rs index d94b8f3deece46f70e346e47ef5c0f6d4df17593..50849996799364d1d8c04a07f6b52b2aafe027f3 100644 --- a/core/rpc/src/state/mod.rs +++ b/core/rpc/src/state/mod.rs @@ -17,7 +17,8 @@ //! Substrate state API. use std::{ - collections::HashMap, + collections::{BTreeMap, HashMap}, + ops::Range, sync::Arc, }; @@ -25,14 +26,14 @@ use client::{self, Client, CallExecutor, BlockchainEvents, runtime_api::Metadata use jsonrpc_macros::Trailing; use jsonrpc_macros::pubsub; use jsonrpc_pubsub::SubscriptionId; -use primitives::H256; +use primitives::{H256, Blake2Hasher, Bytes}; use primitives::hexdisplay::HexDisplay; -use primitives::storage::{StorageKey, StorageData, StorageChangeSet}; -use primitives::{Blake2Hasher, Bytes}; +use primitives::storage::{self, StorageKey, StorageData, StorageChangeSet}; use rpc::Result as RpcResult; use rpc::futures::{stream, Future, Sink, Stream}; use runtime_primitives::generic::BlockId; -use runtime_primitives::traits::{Block as BlockT, Header}; +use runtime_primitives::traits::{Block as BlockT, Header, ProvideRuntimeApi, As, NumberFor}; +use runtime_version::RuntimeVersion; use subscriptions::Subscriptions; @@ -51,6 +52,10 @@ build_rpc_trait! { #[rpc(name = "state_call", alias = ["state_callAt", ])] fn call(&self, String, Bytes, Trailing) -> Result; + /// Returns the keys with prefix, leave empty to get all the keys + #[rpc(name = "state_getKeys")] + fn storage_keys(&self, StorageKey, Trailing) -> Result>; + /// Returns a storage entry at a specific block's state. #[rpc(name = "state_getStorage", alias = ["state_getStorageAt", ])] fn storage(&self, StorageKey, Trailing) -> Result>; @@ -67,6 +72,10 @@ build_rpc_trait! { #[rpc(name = "state_getMetadata")] fn metadata(&self, Trailing) -> Result; + /// Get the runtime version. + #[rpc(name = "state_getRuntimeVersion", alias = ["chain_getRuntimeVersion", ])] + fn runtime_version(&self, Trailing) -> Result; + /// Query historical storage entries (by key) starting from a block given as the second parameter. /// /// NOTE This first returned result contains the initial state of storage for all keys. @@ -74,6 +83,16 @@ build_rpc_trait! { #[rpc(name = "state_queryStorage")] fn query_storage(&self, Vec, Hash, Trailing) -> Result>>; + #[pubsub(name = "state_runtimeVersion")] { + /// New runtime version subscription + #[rpc(name = "state_subscribeRuntimeVersion", alias = ["chain_subscribeRuntimeVersion", ])] + fn subscribe_runtime_version(&self, Self::Metadata, pubsub::Subscriber); + + /// Unsubscribe from runtime version subscription + #[rpc(name = "state_unsubscribeRuntimeVersion", alias = ["chain_unsubscribeRuntimeVersion", ])] + fn unsubscribe_runtime_version(&self, Option, SubscriptionId) -> RpcResult; + } + #[pubsub(name = "state_storage")] { /// New storage subscription #[rpc(name = "state_subscribeStorage")] @@ -81,30 +100,170 @@ build_rpc_trait! { /// Unsubscribe from storage subscription #[rpc(name = "state_unsubscribeStorage")] - fn unsubscribe_storage(&self, SubscriptionId) -> RpcResult; + fn unsubscribe_storage(&self, Option, SubscriptionId) -> RpcResult; } } } /// State API with subscriptions support. -pub struct State { +pub struct State { /// Substrate client. - client: Arc>, + client: Arc>, /// Current subscriptions. subscriptions: Subscriptions, } -impl State { +/// Ranges to query in state_queryStorage. +struct QueryStorageRange { + /// Hashes of all the blocks in the range. + pub hashes: Vec, + /// Number of the first block in the range. + pub first_number: NumberFor, + /// Blocks subrange ([begin; end) indices within `hashes`) where we should read keys at + /// each state to get changes. + pub unfiltered_range: Range, + /// Blocks subrange ([begin; end) indices within `hashes`) where we could pre-filter + /// blocks-with-changes by using changes tries. + pub filtered_range: Option>, +} + +impl State where + Block: BlockT, + B: client::backend::Backend, + E: CallExecutor, +{ /// Create new State API RPC handler. - pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { + pub fn new(client: Arc>, subscriptions: Subscriptions) -> Self { Self { client, subscriptions, } } + + /// Splits the `query_storage` block range into 'filtered' and 'unfiltered' subranges. + /// Blocks that contain changes within filtered subrange could be filtered using changes tries. + /// Blocks that contain changes within unfiltered subrange must be filtered manually. + fn split_query_storage_range( + &self, + from: Block::Hash, + to: Trailing + ) -> Result> { + let to = self.unwrap_or_best(to)?; + let from_hdr = self.client.header(&BlockId::hash(from))?; + let to_hdr = self.client.header(&BlockId::hash(to))?; + match (from_hdr, to_hdr) { + (Some(ref from), Some(ref to)) if from.number() <= to.number() => { + // check if we can get from `to` to `from` by going through parent_hashes. + let from_number = *from.number(); + let blocks = { + let mut blocks = vec![to.hash()]; + let mut last = to.clone(); + while *last.number() > from_number { + if let Some(hdr) = self.client.header(&BlockId::hash(*last.parent_hash()))? { + blocks.push(hdr.hash()); + last = hdr; + } else { + bail!(invalid_block_range( + Some(from), + Some(to), + format!("Parent of {} ({}) not found", last.number(), last.hash()), + )) + } + } + if last.hash() != from.hash() { + bail!(invalid_block_range( + Some(from), + Some(to), + format!("Expected to reach `from`, got {} ({})", last.number(), last.hash()), + )) + } + blocks.reverse(); + blocks + }; + // check if we can filter blocks-with-changes from some (sub)range using changes tries + let changes_trie_range = self.client.max_key_changes_range(from_number, BlockId::Hash(to.hash()))?; + let filtered_range_begin = changes_trie_range.map(|(begin, _)| (begin - from_number).as_() as usize); + let (unfiltered_range, filtered_range) = split_range(blocks.len(), filtered_range_begin); + Ok(QueryStorageRange { + hashes: blocks, + first_number: from_number, + unfiltered_range, + filtered_range, + }) + }, + (from, to) => bail!( + invalid_block_range(from.as_ref(), to.as_ref(), "Invalid range or unknown block".into()) + ), + } + } + + /// Iterates through range.unfiltered_range and check each block for changes of keys' values. + fn query_storage_unfiltered( + &self, + range: &QueryStorageRange, + keys: &[StorageKey], + changes: &mut Vec>, + ) -> Result<()> { + let mut last_state: HashMap<_, Option<_>> = Default::default(); + for block in range.unfiltered_range.start..range.unfiltered_range.end { + let block_hash = range.hashes[block].clone(); + let mut block_changes = StorageChangeSet { block: block_hash.clone(), changes: Vec::new() }; + let id = BlockId::hash(block_hash); + for key in keys { + let (has_changed, data) = { + let curr_data = self.client.storage(&id, key)?; + let prev_data = last_state.get(key).and_then(|x| x.as_ref()); + (curr_data.as_ref() != prev_data, curr_data) + }; + if has_changed { + block_changes.changes.push((key.clone(), data.clone())); + } + last_state.insert(key.clone(), data); + } + changes.push(block_changes); + } + Ok(()) + } + + /// Iterates through all blocks that are changing keys within range.filtered_range and collects these changes. + fn query_storage_filtered( + &self, + range: &QueryStorageRange, + keys: &[StorageKey], + changes: &mut Vec>, + ) -> Result<()> { + let (begin, end) = match range.filtered_range { + Some(ref filtered_range) => ( + range.first_number + As::sa(filtered_range.start as u64), + BlockId::Hash(range.hashes[filtered_range.end - 1].clone()) + ), + None => return Ok(()), + }; + let mut changes_map: BTreeMap, StorageChangeSet> = BTreeMap::new(); + for key in keys { + let mut last_block = None; + for (block, _) in self.client.key_changes(begin, end, key)? { + if last_block == Some(block) { + continue; + } + let block_hash = range.hashes[(block - range.first_number).as_() as usize].clone(); + let id = BlockId::Hash(block_hash); + let value_at_block = self.client.storage(&id, key)?; + changes_map.entry(block) + .or_insert_with(|| StorageChangeSet { block: block_hash, changes: Vec::new() }) + .changes.push((key.clone(), value_at_block)); + last_block = Some(block); + } + } + if let Some(additional_capacity) = changes_map.len().checked_sub(changes.len()) { + changes.reserve(additional_capacity); + } + changes.extend(changes_map.into_iter().map(|(_, cs)| cs)); + Ok(()) + } } -impl State where +impl State where Block: BlockT, B: client::backend::Backend, E: CallExecutor, @@ -114,10 +273,13 @@ impl State where } } -impl StateApi for State where +impl StateApi for State where Block: BlockT + 'static, B: client::backend::Backend + Send + Sync + 'static, - E: CallExecutor + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: Metadata { type Metadata = ::metadata::Metadata; @@ -129,11 +291,16 @@ impl StateApi for State where .call( &BlockId::Hash(block), &method, &data.0 - )? - .return_data; + )?; Ok(Bytes(return_data)) } + fn storage_keys(&self, key_prefix: StorageKey, block: Trailing) -> Result> { + let block = self.unwrap_or_best(block)?; + trace!(target: "rpc", "Querying storage keys at {:?}", block); + Ok(self.client.storage_keys(&BlockId::Hash(block), &key_prefix)?) + } + fn storage(&self, key: StorageKey, block: Trailing) -> Result> { let block = self.unwrap_or_best(block)?; trace!(target: "rpc", "Querying storage at {:?} for key {}", block, HexDisplay::from(&key.0)); @@ -151,75 +318,20 @@ impl StateApi for State where fn metadata(&self, block: Trailing) -> Result { let block = self.unwrap_or_best(block)?; - self.client.metadata(&BlockId::Hash(block)).map(Bytes).map_err(Into::into) + self.client.runtime_api().metadata(&BlockId::Hash(block)).map(Into::into).map_err(Into::into) } - fn query_storage(&self, keys: Vec, from: Block::Hash, to: Trailing) -> Result>> { - let to = self.unwrap_or_best(to)?; - - let from_hdr = self.client.header(&BlockId::hash(from))?; - let to_hdr = self.client.header(&BlockId::hash(to))?; - - match (from_hdr, to_hdr) { - (Some(ref from), Some(ref to)) if from.number() <= to.number() => { - let from = from.clone(); - let to = to.clone(); - // check if we can get from `to` to `from` by going through parent_hashes. - let blocks = { - let mut blocks = vec![to.hash()]; - let mut last = to.clone(); - while last.number() > from.number() { - if let Some(hdr) = self.client.header(&BlockId::hash(*last.parent_hash()))? { - blocks.push(hdr.hash()); - last = hdr; - } else { - bail!(invalid_block_range( - Some(from), - Some(to), - format!("Parent of {} ({}) not found", last.number(), last.hash()), - )) - } - } - if last.hash() != from.hash() { - bail!(invalid_block_range( - Some(from), - Some(to), - format!("Expected to reach `from`, got {} ({})", last.number(), last.hash()), - )) - } - blocks.reverse(); - blocks - }; - let mut result = Vec::new(); - let mut last_state: HashMap<_, Option<_>> = Default::default(); - for block in blocks { - let mut changes = vec![]; - let id = BlockId::hash(block.clone()); - - for key in &keys { - let (has_changed, data) = { - let curr_data = self.client.storage(&id, key)?; - let prev_data = last_state.get(key).and_then(|x| x.as_ref()); - - (curr_data.as_ref() != prev_data, curr_data) - }; - - if has_changed { - changes.push((key.clone(), data.clone())); - } - - last_state.insert(key.clone(), data); - } - - result.push(StorageChangeSet { - block, - changes, - }); - } - Ok(result) - }, - (from, to) => bail!(invalid_block_range(from, to, "Invalid range or unknown block".into())), - } + fn query_storage( + &self, + keys: Vec, + from: Block::Hash, + to: Trailing + ) -> Result>> { + let range = self.split_query_storage_range(from, to)?; + let mut changes = Vec::new(); + self.query_storage_unfiltered(&range, &keys, &mut changes)?; + self.query_storage_filtered(&range, &keys, &mut changes)?; + Ok(changes) } fn subscribe_storage( @@ -267,13 +379,86 @@ impl StateApi for State where }) } - fn unsubscribe_storage(&self, id: SubscriptionId) -> RpcResult { + fn unsubscribe_storage(&self, _meta: Option, id: SubscriptionId) -> RpcResult { + Ok(self.subscriptions.cancel(id)) + } + + fn runtime_version(&self, at: Trailing) -> Result { + let at = self.unwrap_or_best(at)?; + Ok(self.client.runtime_version_at(&BlockId::Hash(at))?) + } + + fn subscribe_runtime_version(&self, _meta: Self::Metadata, subscriber: pubsub::Subscriber) { + let stream = match self.client.storage_changes_notification_stream(Some(&[StorageKey(storage::well_known_keys::CODE.to_vec())])) { + Ok(stream) => stream, + Err(err) => { + let _ = subscriber.reject(error::Error::from(err).into()); + return; + } + }; + + self.subscriptions.add(subscriber, |sink| { + let version = self.runtime_version(None.into()) + .map_err(Into::into); + + let client = self.client.clone(); + let mut previous_version = version.clone(); + + let stream = stream + .map_err(|e| warn!("Error creating storage notification stream: {:?}", e)) + .filter_map(move |_| { + let version = client.info().and_then(|info| { + client.runtime_version_at(&BlockId::hash(info.chain.best_hash)) + }) + .map_err(error::Error::from) + .map_err(Into::into); + if previous_version != version { + previous_version = version.clone(); + Some(version) + } else { + None + } + }); + + sink + .sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all( + stream::iter_result(vec![Ok(version)]) + .chain(stream) + ) + // we ignore the resulting Stream (if the first stream is over we are unsubscribed) + .map(|_| ()) + }); + } + + fn unsubscribe_runtime_version(&self, _meta: Option, id: SubscriptionId) -> RpcResult { Ok(self.subscriptions.cancel(id)) } } -fn invalid_block_range(from: Option, to: Option, reason: String) -> error::ErrorKind { - let to_string = |x: Option| match x { +/// Splits passed range into two subranges where: +/// - first range has at least one element in it; +/// - second range (optionally) starts at given `middle` element. +pub(crate) fn split_range(size: usize, middle: Option) -> (Range, Option>) { + // check if we can filter blocks-with-changes from some (sub)range using changes tries + let range2_begin = match middle { + // some of required changes tries are pruned => use available tries + Some(middle) if middle != 0 => Some(middle), + // all required changes tries are available, but we still want values at first block + // => do 'unfiltered' read for the first block and 'filtered' for the rest + Some(_) if size > 1 => Some(1), + // range contains single element => do not use changes tries + Some(_) => None, + // changes tries are not available => do 'unfiltered' read for the whole range + None => None, + }; + let range1 = 0..range2_begin.unwrap_or(size); + let range2 = range2_begin.map(|begin| begin..size); + (range1, range2) +} + +fn invalid_block_range(from: Option<&H>, to: Option<&H>, reason: String) -> error::ErrorKind { + let to_string = |x: Option<&H>| match x { None => "unknown hash".into(), Some(h) => format!("{} ({})", h.number(), h.hash()), }; diff --git a/core/rpc/src/state/tests.rs b/core/rpc/src/state/tests.rs index 71978f88ea57f793d14fd22347dc1874d9113820..9c860adef7f729c7063ac51328df0a4a46e938e0 100644 --- a/core/rpc/src/state/tests.rs +++ b/core/rpc/src/state/tests.rs @@ -69,7 +69,7 @@ fn should_notify_about_storage_changes() { amount: 42, nonce: 0, }).unwrap(); - api.client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); } // assert notification sent to transport @@ -102,7 +102,7 @@ fn should_send_initial_storage_changes_and_notifications() { amount: 42, nonce: 0, }).unwrap(); - api.client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); + api.client.import(BlockOrigin::Own, builder.bake().unwrap()).unwrap(); } // assert initial values sent to transport @@ -117,64 +117,134 @@ fn should_send_initial_storage_changes_and_notifications() { #[test] fn should_query_storage() { + type TestClient = test_client::client::Client< + test_client::Backend, + test_client::Executor, + runtime::Block, + runtime::RuntimeApi + >; + + fn run_tests(client: Arc) { + let core = ::tokio::runtime::Runtime::new().unwrap(); + let api = State::new(client.clone(), Subscriptions::new(core.executor())); + + let add_block = |nonce| { + let mut builder = client.new_block().unwrap(); + builder.push_transfer(runtime::Transfer { + from: Keyring::Alice.to_raw_public().into(), + to: Keyring::Ferdie.to_raw_public().into(), + amount: 42, + nonce, + }).unwrap(); + let block = builder.bake().unwrap(); + let hash = block.header.hash(); + client.import(BlockOrigin::Own, block).unwrap(); + hash + }; + let block1_hash = add_block(0); + let block2_hash = add_block(1); + let genesis_hash = client.genesis_hash(); + + + let mut expected = vec![ + StorageChangeSet { + block: genesis_hash, + changes: vec![ + ( + StorageKey("a52da2b7c269da1366b3ed1cdb7299ce".from_hex().unwrap()), + Some(StorageData(vec![232, 3, 0, 0, 0, 0, 0, 0])) + ), + ], + }, + StorageChangeSet { + block: block1_hash, + changes: vec![ + ( + StorageKey("a52da2b7c269da1366b3ed1cdb7299ce".from_hex().unwrap()), + Some(StorageData(vec![190, 3, 0, 0, 0, 0, 0, 0])) + ), + ], + }, + ]; + + // Query changes only up to block1 + let result = api.query_storage( + vec![StorageKey("a52da2b7c269da1366b3ed1cdb7299ce".from_hex().unwrap())], + genesis_hash, + Some(block1_hash).into(), + ); + + assert_eq!(result.unwrap(), expected); + + // Query all changes + let result = api.query_storage( + vec![StorageKey("a52da2b7c269da1366b3ed1cdb7299ce".from_hex().unwrap())], + genesis_hash, + None.into(), + ); + + expected.push(StorageChangeSet { + block: block2_hash, + changes: vec![ + ( + StorageKey("a52da2b7c269da1366b3ed1cdb7299ce".from_hex().unwrap()), + Some(StorageData(vec![148, 3, 0, 0, 0, 0, 0, 0])) + ), + ], + }); + assert_eq!(result.unwrap(), expected); + } + + run_tests(Arc::new(test_client::new())); + run_tests(Arc::new(test_client::new_with_changes_trie())); +} + +#[test] +fn should_split_ranges() { + assert_eq!(split_range(1, None), (0..1, None)); + assert_eq!(split_range(100, None), (0..100, None)); + assert_eq!(split_range(1, Some(0)), (0..1, None)); + assert_eq!(split_range(100, Some(50)), (0..50, Some(50..100))); + assert_eq!(split_range(100, Some(99)), (0..99, Some(99..100))); +} + + +#[test] +fn should_return_runtime_version() { let core = ::tokio::runtime::Runtime::new().unwrap(); + let client = Arc::new(test_client::new()); let api = State::new(client.clone(), Subscriptions::new(core.executor())); - let add_block = |nonce| { - let mut builder = client.new_block().unwrap(); - builder.push_transfer(runtime::Transfer { - from: Keyring::Alice.to_raw_public().into(), - to: Keyring::Ferdie.to_raw_public().into(), - amount: 42, - nonce, - }).unwrap(); - let block = builder.bake().unwrap(); - let hash = block.header.hash(); - client.justify_and_import(BlockOrigin::Own, block).unwrap(); - hash - }; - let block1_hash = add_block(0); - let block2_hash = add_block(1); - let genesis_hash = client.genesis_hash(); - + assert_matches!( + api.runtime_version(None.into()), + Ok(ref ver) if ver == &runtime::VERSION + ); - let mut expected = vec![ - StorageChangeSet { - block: genesis_hash, - changes: vec![ - (StorageKey("a52da2b7c269da1366b3ed1cdb7299ce".from_hex().unwrap()), Some(StorageData(vec![232, 3, 0, 0, 0, 0, 0, 0]))), - ], - }, - StorageChangeSet { - block: block1_hash, - changes: vec![ - (StorageKey("a52da2b7c269da1366b3ed1cdb7299ce".from_hex().unwrap()), Some(StorageData(vec![190, 3, 0, 0, 0, 0, 0, 0]))), - ], - }, - ]; - - // Query changes only up to block1 - let result = api.query_storage( - vec![StorageKey("a52da2b7c269da1366b3ed1cdb7299ce".from_hex().unwrap())], - genesis_hash, - Some(block1_hash).into(), + assert_eq!( + ::serde_json::to_string(&api.runtime_version(None.into()).unwrap()).unwrap(), + r#"{"specName":"test","implName":"parity-test","authoringVersion":1,"specVersion":1,"implVersion":1,"apis":[["0xdf6acb689907609b",1],["0x37e397fc7c91f5e4",1],["0xd2bc9897eed08f15",1],["0x40fe3ad401f8959a",1],["0xc6e9a76309f39b09",1],["0xdd718d5cc53262d4",1]]}"# ); +} - assert_eq!(result.unwrap(), expected); +#[test] +fn should_notify_on_runtime_version_initially() { + let mut core = ::tokio::runtime::Runtime::new().unwrap(); + let (subscriber, id, transport) = pubsub::Subscriber::new_test("test"); - // Query all changes - let result = api.query_storage( - vec![StorageKey("a52da2b7c269da1366b3ed1cdb7299ce".from_hex().unwrap())], - genesis_hash, - None.into(), - ); + { + let client = Arc::new(test_client::new()); + let api = State::new(client.clone(), Subscriptions::new(core.executor())); + + api.subscribe_runtime_version(Default::default(), subscriber); - expected.push(StorageChangeSet { - block: block2_hash, - changes: vec![ - (StorageKey("a52da2b7c269da1366b3ed1cdb7299ce".from_hex().unwrap()), Some(StorageData(vec![148, 3, 0, 0, 0, 0, 0, 0]))), - ], - }); - assert_eq!(result.unwrap(), expected); + // assert id assigned + assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); + } + + // assert initial version sent. + let (notification, next) = core.block_on(transport.into_future()).unwrap(); + assert!(notification.is_some()); + // no more notifications on this channel + assert_eq!(core.block_on(next.into_future()).unwrap().0, None); } diff --git a/core/rpc/src/system/error.rs b/core/rpc/src/system/error.rs index 067aa061f730075f8e34bacd7558e4e9bfeba907..844494d248a84c652227c5aac00d29e2703537d1 100644 --- a/core/rpc/src/system/error.rs +++ b/core/rpc/src/system/error.rs @@ -19,9 +19,16 @@ use rpc; use errors; +use system::helpers::Health; error_chain! { errors { + /// Node is not fully functional + NotHealthy(h: Health) { + description("node is not healthy"), + display("Node is not fully functional: {}", h) + } + /// Not implemented yet Unimplemented { description("not yet implemented"), @@ -30,10 +37,17 @@ error_chain! { } } +const ERROR: i64 = 2000; + impl From for rpc::Error { fn from(e: Error) -> Self { match e { Error(ErrorKind::Unimplemented, _) => errors::unimplemented(), + Error(ErrorKind::NotHealthy(h), _) => rpc::Error { + code: rpc::ErrorCode::ServerError(ERROR + 1), + message: "node is not healthy".into(), + data:serde_json::to_value(h).ok(), + }, e => errors::internal(e), } } diff --git a/core/rpc/src/system/helpers.rs b/core/rpc/src/system/helpers.rs new file mode 100644 index 0000000000000000000000000000000000000000..ba4d9c8f1671d2ab55da0c262899fd5817278134 --- /dev/null +++ b/core/rpc/src/system/helpers.rs @@ -0,0 +1,109 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Substrate system API helpers. + +use std::fmt; +use serde_derive::{Serialize}; +use serde_json::{Value, map::Map}; + +/// Node properties +pub type Properties = Map; + +/// Running node's static details. +#[derive(Clone, Debug)] +pub struct SystemInfo { + /// Implementation name. + pub impl_name: String, + /// Implementation version. + pub impl_version: String, + /// Chain name. + pub chain_name: String, + /// A custom set of properties defined in the chain spec. + pub properties: Properties, +} + +/// Health struct returned by the RPC +#[derive(Debug, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Health { + /// Number of connected peers + pub peers: usize, + /// Is the node syncing + pub is_syncing: bool, + /// Should this node have any peers + /// + /// Might be false for local chains or when running without discovery. + pub should_have_peers: bool, +} + +/// Network Peer information +#[derive(Debug, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct PeerInfo { + /// Peer Node Index + pub index: usize, + /// Peer ID + pub peer_id: String, + /// Roles + pub roles: String, + /// Protocol version + pub protocol_version: u32, + /// Peer best block hash + pub best_hash: Hash, + /// Peer best block number + pub best_number: Number, +} + +impl fmt::Display for Health { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{} peers ({})", self.peers, if self.is_syncing { + "syncing" + } else { "idle" }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn should_serialize_health() { + assert_eq!( + ::serde_json::to_string(&Health { + peers: 1, + is_syncing: false, + should_have_peers: true, + }).unwrap(), + r#"{"peers":1,"isSyncing":false,"shouldHavePeers":true}"#, + ); + } + + #[test] + fn should_serialize_peer_info() { + assert_eq!( + ::serde_json::to_string(&PeerInfo { + index: 1, + peer_id: "2".into(), + roles: "a".into(), + protocol_version: 2, + best_hash: 5u32, + best_number: 6u32, + }).unwrap(), + r#"{"index":1,"peerId":"2","roles":"a","protocolVersion":2,"bestHash":5,"bestNumber":6}"#, + ); + } +} diff --git a/core/rpc/src/system/mod.rs b/core/rpc/src/system/mod.rs index 78fd7dda87c60f133a3a7a4dc74dd336366eae06..a06aaaad2384bde355b5edf36619758650536fa6 100644 --- a/core/rpc/src/system/mod.rs +++ b/core/rpc/src/system/mod.rs @@ -18,14 +18,20 @@ pub mod error; +mod helpers; #[cfg(test)] mod tests; +use std::sync::Arc; +use network; +use runtime_primitives::traits::{self, Header as HeaderT}; + use self::error::Result; +pub use self::helpers::{Properties, SystemInfo, Health, PeerInfo}; build_rpc_trait! { /// Substrate system RPC API - pub trait SystemApi { + pub trait SystemApi { /// Get the node's implementation name. Plain old string. #[rpc(name = "system_name")] fn system_name(&self) -> Result; @@ -37,5 +43,81 @@ build_rpc_trait! { /// Get the chain's type. Given as a string identifier. #[rpc(name = "system_chain")] fn system_chain(&self) -> Result; + + /// Get a custom set of properties as a JSON object, defined in the chain spec. + #[rpc(name = "system_properties")] + fn system_properties(&self) -> Result; + + /// Return health status of the node. + /// + /// Node is considered healthy if it is: + /// - connected to some peers (unless running in dev mode) + /// - not performing a major sync + #[rpc(name = "system_health")] + fn system_health(&self) -> Result; + + /// Returns currently connected peers + #[rpc(name = "system_peers")] + fn system_peers(&self) -> Result>>; + } +} + +/// System API implementation +pub struct System { + info: SystemInfo, + sync: Arc>, + should_have_peers: bool, +} + +impl System { + /// Creates new `System` given the `SystemInfo`. + pub fn new( + info: SystemInfo, + sync: Arc>, + should_have_peers: bool, + ) -> Self { + System { + info, + should_have_peers, + sync, + } + } +} + +impl SystemApi::Number> for System { + fn system_name(&self) -> Result { + Ok(self.info.impl_name.clone()) + } + + fn system_version(&self) -> Result { + Ok(self.info.impl_version.clone()) + } + + fn system_chain(&self) -> Result { + Ok(self.info.chain_name.clone()) + } + + fn system_properties(&self) -> Result { + Ok(self.info.properties.clone()) + } + + fn system_health(&self) -> Result { + let status = self.sync.status(); + Ok(Health { + peers: status.num_peers, + is_syncing: status.sync.is_major_syncing(), + should_have_peers: self.should_have_peers, + }) + } + + fn system_peers(&self) -> Result::Number>>> { + Ok(self.sync.peers().into_iter().map(|(idx, peer_id, p)| PeerInfo { + index: idx, + peer_id: peer_id.map_or_else(Default::default, |p| p.to_base58()), + roles: format!("{:?}", p.roles), + protocol_version: p.protocol_version, + best_hash: p.best_hash, + best_number: p.best_number, + }).collect()) } } diff --git a/core/rpc/src/system/tests.rs b/core/rpc/src/system/tests.rs index 95f37e79c89c5f1557028df0ac2eb61d31bada2b..1f13abd7ec398d35ab5c1e29d9d4c089308ea3ff 100644 --- a/core/rpc/src/system/tests.rs +++ b/core/rpc/src/system/tests.rs @@ -15,24 +15,56 @@ // along with Substrate. If not, see . use super::*; -use super::error::*; -impl SystemApi for () { - fn system_name(&self) -> Result { - Ok("testclient".into()) - } - fn system_version(&self) -> Result { - Ok("0.2.0".into()) +use network::{self, SyncState, SyncStatus, ProtocolStatus, NodeIndex, PeerId, PeerInfo as NetworkPeerInfo, PublicKey}; +use network::config::Roles; +use test_client::runtime::Block; + +#[derive(Default)] +struct Status { + pub peers: usize, + pub is_syncing: bool, + pub is_dev: bool, +} + +impl network::SyncProvider for Status { + fn status(&self) -> ProtocolStatus { + ProtocolStatus { + sync: SyncStatus { + state: if self.is_syncing { SyncState::Downloading } else { SyncState::Idle }, + best_seen_block: None, + }, + num_peers: self.peers, + num_active_peers: 0, + } } - fn system_chain(&self) -> Result { - Ok("testchain".into()) + + fn peers(&self) -> Vec<(NodeIndex, Option, NetworkPeerInfo)> { + vec![(1, Some(PublicKey::Ed25519((0 .. 32).collect::>()).into()), NetworkPeerInfo { + roles: Roles::FULL, + protocol_version: 1, + best_hash: Default::default(), + best_number: 1 + })] } } + +fn api>>(sync: T) -> System { + let status = sync.into().unwrap_or_default(); + let should_have_peers = !status.is_dev; + System::new(SystemInfo { + impl_name: "testclient".into(), + impl_version: "0.2.0".into(), + chain_name: "testchain".into(), + properties: Default::default(), + }, Arc::new(status), should_have_peers) +} + #[test] fn system_name_works() { assert_eq!( - SystemApi::system_name(&()).unwrap(), + api(None).system_name().unwrap(), "testclient".to_owned() ); } @@ -40,7 +72,7 @@ fn system_name_works() { #[test] fn system_version_works() { assert_eq!( - SystemApi::system_version(&()).unwrap(), + api(None).system_version().unwrap(), "0.2.0".to_owned() ); } @@ -48,7 +80,81 @@ fn system_version_works() { #[test] fn system_chain_works() { assert_eq!( - SystemApi::system_chain(&()).unwrap(), + api(None).system_chain().unwrap(), "testchain".to_owned() ); } + +#[test] +fn system_properties_works() { + assert_eq!( + api(None).system_properties().unwrap(), + serde_json::map::Map::new() + ); +} + +#[test] +fn system_health() { + assert_matches!( + api(None).system_health().unwrap(), + Health { + peers: 0, + is_syncing: false, + should_have_peers: true, + } + ); + + assert_matches!( + api(Status { + peers: 5, + is_syncing: true, + is_dev: true, + }).system_health().unwrap(), + Health { + peers: 5, + is_syncing: true, + should_have_peers: false, + } + ); + + assert_eq!( + api(Status { + peers: 5, + is_syncing: false, + is_dev: false, + }).system_health().unwrap(), + Health { + peers: 5, + is_syncing: false, + should_have_peers: true, + } + ); + + assert_eq!( + api(Status { + peers: 0, + is_syncing: false, + is_dev: true, + }).system_health().unwrap(), + Health { + peers: 0, + is_syncing: false, + should_have_peers: false, + } + ); +} + +#[test] +fn system_peers() { + assert_eq!( + api(None).system_peers().unwrap(), + vec![PeerInfo { + index: 1, + peer_id: "QmS5oyTmdjwBowwAH1D9YQnoe2HyWpVemH8qHiU5RqWPh4".into(), + roles: "FULL".into(), + protocol_version: 1, + best_hash: Default::default(), + best_number: 1u64, + }] + ); +} diff --git a/core/serializer/README.adoc b/core/serializer/README.adoc deleted file mode 100644 index 7b780bae4367797f3258f934280ebaf6cf21de8e..0000000000000000000000000000000000000000 --- a/core/serializer/README.adoc +++ /dev/null @@ -1,14 +0,0 @@ - -= Serializer - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- - diff --git a/core/serializer/src/lib.rs b/core/serializer/src/lib.rs index 2ef799ed8e7d99f4a9a46453c98e68bb9a213b88..667c57eb8751dd7c5b15361c88895c1ace955e7d 100644 --- a/core/serializer/src/lib.rs +++ b/core/serializer/src/lib.rs @@ -14,12 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Substrate customizable serde serializer. //! //! The idea is that we can later change the implementation //! to something more compact, but for now we're using JSON. -// end::description[] #![warn(missing_docs)] diff --git a/core/service/Cargo.toml b/core/service/Cargo.toml index a15e010d5c477f8147a2acd36ccff77e651562b8..3824bb6a571e7d143947d197edcc37f350455638 100644 --- a/core/service/Cargo.toml +++ b/core/service/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] [dependencies] futures = "0.1.17" -parking_lot = "0.4" +parking_lot = "0.7.1" error-chain = "0.12" lazy_static = "1.0" log = "0.4" @@ -24,9 +24,11 @@ substrate-consensus-common = { path = "../../core/consensus/common" } substrate-network = { path = "../../core/network" } substrate-client = { path = "../../core/client" } substrate-client-db = { path = "../../core/client/db" } -parity-codec = "2.1" +parity-codec = "2.2" substrate-executor = { path = "../../core/executor" } substrate-transaction-pool = { path = "../../core/transaction-pool" } -substrate-rpc = { path = "../../core/rpc" } substrate-rpc-servers = { path = "../../core/rpc-servers" } substrate-telemetry = { path = "../../core/telemetry" } + +[dev-dependencies] +substrate-test-client = { path = "../test-client" } diff --git a/core/service/README.adoc b/core/service/README.adoc deleted file mode 100644 index 4d74c098b2e1717e16bdecf4511c0852888c8817..0000000000000000000000000000000000000000 --- a/core/service/README.adoc +++ /dev/null @@ -1,14 +0,0 @@ - -= Service - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- - diff --git a/core/service/src/chain_ops.rs b/core/service/src/chain_ops.rs index e94db8c6f0bda020317828a22d7472efdfa65c3b..75d4688669f76a497eabf6c5afbeecfc6096a0e9 100644 --- a/core/service/src/chain_ops.rs +++ b/core/service/src/chain_ops.rs @@ -18,11 +18,10 @@ use std::{self, io::{Read, Write}}; use futures::Future; -use serde_json; use runtime_primitives::generic::{SignedBlock, BlockId}; use runtime_primitives::traits::{As, Block, Header}; -use network::import_queue::{ImportQueue, BlockData}; +use consensus_common::import_queue::{ImportQueue, IncomingBlock, Link}; use network::message; use consensus_common::BlockOrigin; @@ -34,7 +33,10 @@ use chain_spec::ChainSpec; /// Export a range of blocks to a binary stream. pub fn export_blocks(config: FactoryFullConfiguration, exit: E, mut output: W, from: FactoryBlockNumber, to: Option>, json: bool) -> error::Result<()> - where F: ServiceFactory, E: Future + Send + 'static, W: Write, + where + F: ServiceFactory, + E: Future + Send + 'static, + W: Write, { let client = new_client::(&config)?; let mut block = from; @@ -85,11 +87,16 @@ pub fn export_blocks(config: FactoryFullConfiguration, exit: E, mut } /// Import blocks from a binary stream. -pub fn import_blocks(config: FactoryFullConfiguration, exit: E, mut input: R) -> error::Result<()> +pub fn import_blocks(mut config: FactoryFullConfiguration, exit: E, mut input: R) -> error::Result<()> where F: ServiceFactory, E: Future + Send + 'static, R: Read, { + struct DummyLink; + impl Link for DummyLink { } + let client = new_client::(&config)?; - let queue = components::FullComponents::::build_import_queue(&config, client.clone())?; + // FIXME: this shouldn't need a mutable config. https://github.com/paritytech/substrate/issues/1134 + let queue = components::FullComponents::::build_import_queue(&mut config, client.clone())?; + queue.start(DummyLink)?; let (exit_send, exit_recv) = std::sync::mpsc::channel(); ::std::thread::spawn(move || { @@ -99,24 +106,32 @@ pub fn import_blocks(config: FactoryFullConfiguration, exit: E, mut let count: u32 = Decode::decode(&mut input).ok_or("Error reading file")?; info!("Importing {} blocks", count); - let mut block_count = 0; + let mut block_count = 0; for b in 0 .. count { if exit_recv.try_recv().is_ok() { break; } - if let Some(signed) = SignedBlock::<::Header, ::Extrinsic>::decode(&mut input) { - let header = signed.block.header; + if let Some(signed) = SignedBlock::::decode(&mut input) { + let (header, extrinsics) = signed.block.deconstruct(); let hash = header.hash(); let block = message::BlockData:: { hash: hash, - justification: Some(signed.justification), + justification: signed.justification, header: Some(header), - body: Some(signed.block.extrinsics), + body: Some(extrinsics), receipt: None, message_queue: None }; // import queue handles verification and importing it into the client - queue.import_blocks(BlockOrigin::File, vec![BlockData:: { block, origin: None }]); + queue.import_blocks(BlockOrigin::File, vec![ + IncomingBlock::{ + hash: block.hash, + header: block.header, + body: block.body, + justification: block.justification, + origin: None, + } + ]); } else { warn!("Error reading block data at {}.", b); break; @@ -139,7 +154,12 @@ pub fn revert_chain(config: FactoryFullConfiguration, blocks: FactoryBlock let client = new_client::(&config)?; let reverted = client.revert(blocks)?; let info = client.info()?.chain; - info!("Reverted {} blocks. Best: #{} ({})", reverted, info.best_number, info.best_hash); + + if reverted.as_() == 0 { + info!("There aren't any non-finalized blocks to revert."); + } else { + info!("Reverted {} blocks. Best: #{} ({})", reverted, info.best_number, info.best_hash); + } Ok(()) } diff --git a/core/service/src/chain_spec.rs b/core/service/src/chain_spec.rs index 1b9cad490aeec7e8abe215304e673e8a6b7d6f59..dafae1501c6910f9146d5fbad1554f79ede5d770 100644 --- a/core/service/src/chain_spec.rs +++ b/core/service/src/chain_spec.rs @@ -23,6 +23,7 @@ use primitives::storage::{StorageKey, StorageData}; use runtime_primitives::{BuildStorage, StorageMap, ChildrenStorageMap}; use serde_json as json; use components::RuntimeGenesis; +use network::Multiaddr; enum GenesisSource { File(PathBuf), @@ -88,8 +89,12 @@ struct ChainSpecFile { pub telemetry_url: Option, pub protocol_id: Option, pub consensus_engine: Option, + pub properties: Option, } +/// Arbitrary properties defined in chain spec as a JSON object +pub type Properties = json::map::Map; + /// A configuration of a chain. Can be used to build a genesis block. pub struct ChainSpec { spec: ChainSpecFile, @@ -130,6 +135,15 @@ impl ChainSpec { self.spec.consensus_engine.as_ref().map(String::as_str) } + pub fn properties(&self) -> Properties { + // Return an empty JSON object if 'properties' not defined in config + self.spec.properties.as_ref().unwrap_or(&json::map::Map::new()).clone() + } + + pub fn add_boot_node(&mut self, addr: Multiaddr) { + self.spec.boot_nodes.push(addr.to_string()) + } + /// Parse json content into a `ChainSpec` pub fn from_embedded(json: &'static [u8]) -> Result { let spec = json::from_slice(json).map_err(|e| format!("Error parsing spec file: {}", e))?; @@ -158,6 +172,7 @@ impl ChainSpec { telemetry_url: Option<&str>, protocol_id: Option<&str>, consensus_engine: Option<&str>, + properties: Option, ) -> Self { let spec = ChainSpecFile { @@ -167,6 +182,7 @@ impl ChainSpec { telemetry_url: telemetry_url.map(str::to_owned), protocol_id: protocol_id.map(str::to_owned), consensus_engine: consensus_engine.map(str::to_owned), + properties, }; ChainSpec { spec, diff --git a/core/service/src/components.rs b/core/service/src/components.rs index a2b9225d3a35755ea70a90bb23eb0f95936ac4f2..8756f580091ef8def22909051e207a82976c871b 100644 --- a/core/service/src/components.rs +++ b/core/service/src/components.rs @@ -16,21 +16,22 @@ //! Substrate service components. -use std::sync::Arc; -use std::marker::PhantomData; -use std::ops::Deref; +use std::{sync::Arc, net::SocketAddr, marker::PhantomData, ops::Deref, ops::DerefMut}; use serde::{Serialize, de::DeserializeOwned}; use tokio::runtime::TaskExecutor; use chain_spec::ChainSpec; use client_db; -use client::{self, Client}; -use {error, Service}; -use network::{self, OnDemand, import_queue::ImportQueue}; +use client::{self, Client, runtime_api::{Metadata, TaggedTransactionQueue}}; +use {error, Service, maybe_start_server}; +use consensus_common::import_queue::ImportQueue; +use network::{self, OnDemand}; use substrate_executor::{NativeExecutor, NativeExecutionDispatch}; use transaction_pool::txpool::{self, Options as TransactionPoolOptions, Pool as TransactionPool}; -use runtime_primitives::{traits::Block as BlockT, traits::Header as HeaderT, BuildStorage}; +use runtime_primitives::{BuildStorage, traits::{Block as BlockT, Header as HeaderT, ProvideRuntimeApi}, generic::BlockId}; use config::Configuration; -use primitives::{H256, Blake2Hasher}; +use primitives::{Blake2Hasher, H256}; +use rpc::{self, apis::system::SystemInfo}; +use parking_lot::Mutex; // Type aliases. // These exist mainly to avoid typing `::Foo` all over the code. @@ -70,10 +71,10 @@ pub type LightExecutor = client::light::call_executor::RemoteCallExecutor< >; /// Full client type for a factory. -pub type FullClient = Client, FullExecutor, ::Block>; +pub type FullClient = Client, FullExecutor, ::Block, ::RuntimeApi>; /// Light client type for a factory. -pub type LightClient = Client, LightExecutor, ::Block>; +pub type LightClient = Client, LightExecutor, ::Block, ::RuntimeApi>; /// `ChainSpec` specialization for a factory. pub type FactoryChainSpec = ChainSpec<::Genesis>; @@ -97,7 +98,8 @@ pub type FactoryFullConfiguration = Configuration<::Conf pub type ComponentClient = Client< ::Backend, ::Executor, - FactoryBlock<::Factory> + FactoryBlock<::Factory>, + ::RuntimeApi, >; /// Block type for `Components` @@ -116,12 +118,153 @@ pub type PoolApi = ::TransactionPoolApi; pub trait RuntimeGenesis: Serialize + DeserializeOwned + BuildStorage {} impl RuntimeGenesis for T {} +/// Something that can start the RPC service. +pub trait StartRPC { + type ServersHandle: Send + Sync; + + fn start_rpc( + client: Arc>, + network: Arc>>, + should_have_peers: bool, + system_info: SystemInfo, + rpc_http: Option, + rpc_ws: Option, + task_executor: TaskExecutor, + transaction_pool: Arc>, + ) -> error::Result; +} + +impl StartRPC for C where + ComponentClient: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: Metadata>, +{ + type ServersHandle = (Option, Option>); + + fn start_rpc( + client: Arc>, + network: Arc>>, + should_have_peers: bool, + rpc_system_info: SystemInfo, + rpc_http: Option, + rpc_ws: Option, + task_executor: TaskExecutor, + transaction_pool: Arc>, + ) -> error::Result { + let handler = || { + let client = client.clone(); + let subscriptions = rpc::apis::Subscriptions::new(task_executor.clone()); + let chain = rpc::apis::chain::Chain::new(client.clone(), subscriptions.clone()); + let state = rpc::apis::state::State::new(client.clone(), subscriptions.clone()); + let author = rpc::apis::author::Author::new( + client.clone(), transaction_pool.clone(), subscriptions + ); + let system = rpc::apis::system::System::new( + rpc_system_info.clone(), network.clone(), should_have_peers + ); + rpc::rpc_handler::, ComponentExHash, _, _, _, _>( + state, + chain, + author, + system, + ) + }; + + Ok(( + maybe_start_server(rpc_http, |address| rpc::start_http(address, handler()))?, + maybe_start_server(rpc_ws, |address| rpc::start_ws(address, handler()))?.map(Mutex::new), + )) + } +} + +/// Something that can maintain transaction pool on every imported block. +pub trait MaintainTransactionPool { + fn on_block_imported( + id: &BlockId>, + client: &ComponentClient, + transaction_pool: &TransactionPool, + ) -> error::Result<()>; +} + +fn on_block_imported( + id: &BlockId, + client: &Client, + transaction_pool: &TransactionPool, +) -> error::Result<()> where + Block: BlockT::Out>, + Backend: client::backend::Backend, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: TaggedTransactionQueue, + Executor: client::CallExecutor, + PoolApi: txpool::ChainApi, +{ + use runtime_primitives::transaction_validity::TransactionValidity; + + // Avoid calling into runtime if there is nothing to prune from the pool anyway. + if transaction_pool.status().is_empty() { + return Ok(()) + } + + let block = client.block(id)?; + let tags = match block { + None => return Ok(()), + Some(block) => { + let parent_id = BlockId::hash(*block.block.header().parent_hash()); + let mut tags = vec![]; + for tx in block.block.extrinsics() { + let tx = client.runtime_api().validate_transaction(&parent_id, tx.clone())?; + match tx { + TransactionValidity::Valid { mut provides, .. } => { + tags.append(&mut provides); + }, + // silently ignore invalid extrinsics, + // cause they might just be inherent + _ => {} + } + + } + tags + } + }; + + transaction_pool.prune_tags(id, tags).map_err(|e| format!("{:?}", e))?; + Ok(()) +} + +impl MaintainTransactionPool for C where + ComponentClient: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: TaggedTransactionQueue>, +{ + // TODO [ToDr] Optimize and re-use tags from the pool. + fn on_block_imported( + id: &BlockId>, + client: &ComponentClient, + transaction_pool: &TransactionPool, + ) -> error::Result<()> { + on_block_imported(id, client, transaction_pool) + } +} + +/// The super trait that combines all required traits a `Service` needs to implement. +pub trait ServiceTrait: + Deref> + + Send + + Sync + + 'static + + StartRPC + + MaintainTransactionPool +{} +impl ServiceTrait for T where + T: Deref> + Send + Sync + 'static + StartRPC + MaintainTransactionPool +{} + /// A collection of types and methods to build a service on top of the substrate service. pub trait ServiceFactory: 'static + Sized { /// Block type. type Block: BlockT; + /// The type that implements the runtime API. + type RuntimeApi: Send + Sync; /// Network protocol extensions. - type NetworkProtocol: network::specialization::Specialization; + type NetworkProtocol: network::specialization::NetworkSpecialization; /// Chain runtime. type RuntimeDispatch: NativeExecutionDispatch + Send + Sync + 'static; /// Extrinsic pool backend type for the full client. @@ -133,15 +276,15 @@ pub trait ServiceFactory: 'static + Sized { /// Other configuration for service members. type Configuration: Default; /// Extended full service type. - type FullService: Deref>> + Send + Sync + 'static; + type FullService: ServiceTrait>; /// Extended light service type. - type LightService: Deref>> + Send + Sync + 'static; + type LightService: ServiceTrait>; /// ImportQueue for full client - type FullImportQueue: network::import_queue::ImportQueue + 'static; + type FullImportQueue: consensus_common::import_queue::ImportQueue + 'static; /// ImportQueue for light clients - type LightImportQueue: network::import_queue::ImportQueue + 'static; + type LightImportQueue: consensus_common::import_queue::ImportQueue + 'static; - //TODO: replace these with a constructor trait. that TransactionPool implements. + //TODO: replace these with a constructor trait. that TransactionPool implements. (#1242) /// Extrinsic pool constructor for the full client. fn build_full_transaction_pool(config: TransactionPoolOptions, client: Arc>) -> Result, error::Error>; @@ -162,7 +305,7 @@ pub trait ServiceFactory: 'static + Sized { /// ImportQueue for a full client fn build_full_import_queue( - config: &FactoryFullConfiguration, + config: &mut FactoryFullConfiguration, _client: Arc> ) -> Result { if let Some(name) = config.chain_spec.consensus_engine() { @@ -177,7 +320,7 @@ pub trait ServiceFactory: 'static + Sized { /// ImportQueue for a light client fn build_light_import_queue( - config: &FactoryFullConfiguration, + config: &mut FactoryFullConfiguration, _client: Arc> ) -> Result { if let Some(name) = config.chain_spec.consensus_engine() { @@ -192,16 +335,23 @@ pub trait ServiceFactory: 'static + Sized { } /// A collection of types and function to generalise over full / light client type. -pub trait Components: 'static { +pub trait Components: Sized + 'static { /// Associated service factory. type Factory: ServiceFactory; /// Client backend. type Backend: 'static + client::backend::Backend, Blake2Hasher>; /// Client executor. type Executor: 'static + client::CallExecutor, Blake2Hasher> + Send + Sync + Clone; + /// The type that implements the runtime API. + type RuntimeApi: Send + Sync; + /// A type that can start the RPC. + type RPC: StartRPC; + // TODO [ToDr] Traitify transaction pool and allow people to implement their own. (#1242) + /// A type that can maintain transaction pool. + type TransactionPool: MaintainTransactionPool; /// Extrinsic pool type. type TransactionPoolApi: 'static + txpool::ChainApi< - Hash = <::Block as BlockT>::Hash, + Hash = as BlockT>::Hash, Block = FactoryBlock >; @@ -212,11 +362,13 @@ pub trait Components: 'static { fn build_client( config: &FactoryFullConfiguration, executor: CodeExecutor, - ) - -> Result<( + ) -> Result< + ( Arc>, Option, NetworkService>>> - ), error::Error>; + ), + error::Error + >; /// Create extrinsic pool. fn build_transaction_pool(config: TransactionPoolOptions, client: Arc>) @@ -224,7 +376,7 @@ pub trait Components: 'static { /// instance of import queue for clients fn build_import_queue( - config: &FactoryFullConfiguration, + config: &mut FactoryFullConfiguration, client: Arc> ) -> Result; } @@ -232,6 +384,35 @@ pub trait Components: 'static { /// A struct that implement `Components` for the full client. pub struct FullComponents { _factory: PhantomData, + service: Service>, +} + +impl FullComponents { + pub fn new( + config: FactoryFullConfiguration, + task_executor: TaskExecutor + ) -> Result { + Ok( + Self { + _factory: Default::default(), + service: Service::new(config, task_executor)?, + } + ) + } +} + +impl Deref for FullComponents { + type Target = Service; + + fn deref(&self) -> &Self::Target { + &self.service + } +} + +impl DerefMut for FullComponents { + fn deref_mut(&mut self) -> &mut Service { + &mut self.service + } } impl Components for FullComponents { @@ -240,6 +421,9 @@ impl Components for FullComponents { type Backend = FullBackend; type TransactionPoolApi = ::FullTransactionPoolApi; type ImportQueue = Factory::FullImportQueue; + type RuntimeApi = Factory::RuntimeApi; + type RPC = Factory::FullService; + type TransactionPool = Factory::FullService; fn build_client( config: &FactoryFullConfiguration, @@ -251,7 +435,7 @@ impl Components for FullComponents { ), error::Error> { let db_settings = client_db::DatabaseSettings { - cache_size: None, + cache_size: config.database_cache_size.map(|u| u as usize), path: config.database_path.as_str().into(), pruning: config.pruning.clone(), }; @@ -271,7 +455,7 @@ impl Components for FullComponents { } fn build_import_queue( - config: &FactoryFullConfiguration, + config: &mut FactoryFullConfiguration, client: Arc> ) -> Result { Factory::build_full_import_queue(config, client) @@ -281,6 +465,29 @@ impl Components for FullComponents { /// A struct that implement `Components` for the light client. pub struct LightComponents { _factory: PhantomData, + service: Service>, +} + +impl LightComponents { + pub fn new( + config: FactoryFullConfiguration, + task_executor: TaskExecutor + ) -> Result { + Ok( + Self { + _factory: Default::default(), + service: Service::new(config, task_executor)?, + } + ) + } +} + +impl Deref for LightComponents { + type Target = Service; + + fn deref(&self) -> &Self::Target { + &self.service + } } impl Components for LightComponents { @@ -289,16 +496,19 @@ impl Components for LightComponents { type Backend = LightBackend; type TransactionPoolApi = ::LightTransactionPoolApi; type ImportQueue = ::LightImportQueue; + type RuntimeApi = Factory::RuntimeApi; + type RPC = Factory::LightService; + type TransactionPool = Factory::LightService; fn build_client( config: &FactoryFullConfiguration, executor: CodeExecutor, ) - -> Result<( - Arc>, - Option, - NetworkService>>> - ), error::Error> + -> Result< + ( + Arc>, + Option, NetworkService>>> + ), error::Error> { let db_settings = client_db::DatabaseSettings { cache_size: None, @@ -307,7 +517,7 @@ impl Components for LightComponents { }; let db_storage = client_db::light::LightStorage::new(db_settings)?; let light_blockchain = client::light::new_light_blockchain(db_storage); - let fetch_checker = Arc::new(client::light::new_fetch_checker::<_, Blake2Hasher>(executor)); + let fetch_checker = Arc::new(client::light::new_fetch_checker::<_, Blake2Hasher, _, _, _>(light_blockchain.clone(), executor)); let fetcher = Arc::new(network::OnDemand::new(fetch_checker)); let client_backend = client::light::new_light_backend(light_blockchain, fetcher.clone()); let client = client::light::new_light(client_backend, fetcher.clone(), &config.chain_spec)?; @@ -321,9 +531,59 @@ impl Components for LightComponents { } fn build_import_queue( - config: &FactoryFullConfiguration, + config: &mut FactoryFullConfiguration, client: Arc> ) -> Result { Factory::build_light_import_queue(config, client) } } + +#[cfg(test)] +mod tests { + use super::*; + use codec::Encode; + use consensus_common::BlockOrigin; + use substrate_test_client::{ + self, + TestClient, + keyring::Keyring, + runtime::{Extrinsic, Transfer}, + }; + + #[test] + fn should_remove_transactions_from_the_pool() { + let client = Arc::new(substrate_test_client::new()); + let pool = TransactionPool::new(Default::default(), ::transaction_pool::ChainApi::new(client.clone())); + let transaction = { + let transfer = Transfer { + amount: 5, + nonce: 0, + from: Keyring::Alice.to_raw_public().into(), + to: Default::default(), + }; + let signature = Keyring::from_raw_public(transfer.from.to_fixed_bytes()).unwrap().sign(&transfer.encode()).into(); + Extrinsic::Transfer(transfer, signature) + }; + // store the transaction in the pool + pool.submit_one(&BlockId::hash(client.best_block_header().unwrap().hash()), transaction.clone()).unwrap(); + + // import the block + let mut builder = client.new_block().unwrap(); + builder.push(transaction.clone()).unwrap(); + let block = builder.bake().unwrap(); + let id = BlockId::hash(block.header().hash()); + client.import(BlockOrigin::Own, block).unwrap(); + + // fire notification - this should clean up the queue + assert_eq!(pool.status().ready, 1); + on_block_imported( + &id, + &client, + &pool, + ).unwrap(); + + // then + assert_eq!(pool.status().ready, 0); + assert_eq!(pool.status().future, 0); + } +} diff --git a/core/service/src/config.rs b/core/service/src/config.rs index 00866d956320b03cc8ce9ceb9edaf9572d8fdf3c..636b555617bdfe618071f918f7b11ddff60966f1 100644 --- a/core/service/src/config.rs +++ b/core/service/src/config.rs @@ -20,9 +20,8 @@ use std::net::SocketAddr; use transaction_pool; use chain_spec::ChainSpec; pub use client::ExecutionStrategy; -pub use network::Roles; -pub use network::NetworkConfiguration; pub use client_db::PruningMode; +pub use network::config::{NetworkConfiguration, Roles}; use runtime_primitives::BuildStorage; use serde::{Serialize, de::DeserializeOwned}; use target_info::Target; @@ -46,6 +45,8 @@ pub struct Configuration { pub keystore_path: String, /// Path to the database. pub database_path: String, + /// Cache Size for internal database in MiB + pub database_cache_size: Option, /// Pruning settings. pub pruning: PruningMode, /// Additional key seeds. @@ -82,6 +83,7 @@ impl Configuration. -// tag::description[] //! Substrate service. Starts a thread that spins up the network, client, and extrinsic pool. //! Manages communication between them. -// end::description[] #![warn(unused_extern_crates)] @@ -36,7 +34,6 @@ extern crate substrate_client as client; extern crate substrate_client_db as client_db; extern crate parity_codec as codec; extern crate substrate_transaction_pool as transaction_pool; -extern crate substrate_rpc; extern crate substrate_rpc_servers as rpc; extern crate target_info; extern crate tokio; @@ -52,12 +49,14 @@ extern crate log; #[macro_use] extern crate serde_derive; +#[cfg(test)] +extern crate substrate_test_client; + mod components; mod error; mod chain_spec; pub mod config; pub mod chain_ops; -pub mod consensus; use std::io; use std::net::SocketAddr; @@ -65,11 +64,10 @@ use std::collections::HashMap; #[doc(hidden)] pub use std::{ops::Deref, result::Result, sync::Arc}; use futures::prelude::*; -use parking_lot::{Mutex, RwLock}; use keystore::Store as Keystore; use client::BlockchainEvents; -use runtime_primitives::traits::{Header, As}; use runtime_primitives::generic::BlockId; +use runtime_primitives::traits::{Header, As}; use exit_future::Signal; #[doc(hidden)] pub use tokio::runtime::TaskExecutor; @@ -78,19 +76,20 @@ use codec::{Encode, Decode}; pub use self::error::{ErrorKind, Error}; pub use config::{Configuration, Roles, PruningMode}; -pub use chain_spec::ChainSpec; +pub use chain_spec::{ChainSpec, Properties}; pub use transaction_pool::txpool::{self, Pool as TransactionPool, Options as TransactionPoolOptions, ChainApi, IntoPoolError}; -pub use client::ExecutionStrategy; +pub use client::{ExecutionStrategy, FinalityNotifications}; -use consensus_common::offline_tracker::OfflineTracker; -pub use consensus::ProposerFactory; pub use components::{ServiceFactory, FullBackend, FullExecutor, LightBackend, LightExecutor, Components, PoolApi, ComponentClient, ComponentBlock, FullClient, LightClient, FullComponents, LightComponents, CodeExecutor, NetworkService, FactoryChainSpec, FactoryBlock, FactoryFullConfiguration, RuntimeGenesis, FactoryGenesis, - ComponentExHash, ComponentExtrinsic, FactoryExtrinsic, + ComponentExHash, ComponentExtrinsic, FactoryExtrinsic }; +use components::{StartRPC, MaintainTransactionPool}; +#[doc(hidden)] +pub use network::OnDemand; const DEFAULT_PROTOCOL_ID: &'static str = "sup"; @@ -102,10 +101,10 @@ pub struct Service { keystore: Keystore, exit: ::exit_future::Exit, signal: Option, - proposer: Arc, Components::TransactionPoolApi>>, - _rpc_http: Option, - _rpc_ws: Option>, // WsServer is not `Sync`, but the service needs to be. - _telemetry: Option, + /// Configuration of this Service + pub config: FactoryFullConfiguration, + _rpc: Box<::std::any::Any + Send + Sync>, + _telemetry: Option>, } /// Creates bare client without any networking. @@ -120,16 +119,10 @@ pub fn new_client(config: &FactoryFullConfi Ok(client) } -impl Service - where - Components: components::Components, - ::Executor: std::clone::Clone, - txpool::ExHash: serde::de::DeserializeOwned + serde::Serialize, - txpool::ExtrinsicFor: serde::de::DeserializeOwned + serde::Serialize, -{ +impl Service { /// Creates a new service. pub fn new( - config: FactoryFullConfiguration, + mut config: FactoryFullConfiguration, task_executor: TaskExecutor, ) -> Result @@ -140,10 +133,12 @@ impl Service let executor = NativeExecutor::new(); let mut keystore = Keystore::open(config.keystore_path.as_str().into())?; + + // This is meant to be for testing only + // FIXME: remove this - https://github.com/paritytech/substrate/issues/1063 for seed in &config.keys { keystore.generate_from_seed(seed)?; } - // Keep the public key for telemetry let public_key = match keystore.contents()?.get(0) { Some(public_key) => public_key.clone(), @@ -157,7 +152,7 @@ impl Service }; let (client, on_demand) = Components::build_client(&config, executor)?; - let import_queue = Components::build_import_queue(&config, client.clone())?; + let import_queue = Arc::new(Components::build_import_queue(&mut config, client.clone())?); let best_header = client.best_block_header()?; let version = config.full_version(); @@ -166,53 +161,110 @@ impl Service let network_protocol = ::build_network_protocol(&config)?; let transaction_pool = Arc::new( - Components::build_transaction_pool(config.transaction_pool, client.clone())? + Components::build_transaction_pool(config.transaction_pool.clone(), client.clone())? ); - let transaction_pool_adapter = TransactionPoolAdapter:: { + let transaction_pool_adapter = Arc::new(TransactionPoolAdapter:: { imports_external_transactions: !(config.roles == Roles::LIGHT), pool: transaction_pool.clone(), client: client.clone(), - }; + }); - let network_params = network::Params { - config: network::ProtocolConfig { - roles: config.roles, - }, - network_config: config.network, + let network_params = network::config::Params { + config: network::config::ProtocolConfig { roles: config.roles }, + network_config: config.network.clone(), chain: client.clone(), - on_demand: on_demand.clone() - .map(|d| d as Arc>>), - transaction_pool: Arc::new(transaction_pool_adapter), + on_demand: on_demand.as_ref().map(|d| d.clone() as _), + transaction_pool: transaction_pool_adapter.clone() as _, specialization: network_protocol, }; - let mut protocol_id = network::ProtocolId::default(); - let protocol_id_full = config.chain_spec.protocol_id().unwrap_or(DEFAULT_PROTOCOL_ID).as_bytes(); - if protocol_id_full.len() > protocol_id.len() { - warn!("Protocol ID truncated to {} chars", protocol_id.len()); - } - let id_len = protocol_id_full.len().min(protocol_id.len()); - &mut protocol_id[0..id_len].copy_from_slice(&protocol_id_full[0..id_len]); + let protocol_id = { + let protocol_id_full = config.chain_spec.protocol_id().unwrap_or(DEFAULT_PROTOCOL_ID).as_bytes(); + let mut protocol_id = network::ProtocolId::default(); + if protocol_id_full.len() > protocol_id.len() { + warn!("Protocol ID truncated to {} chars", protocol_id.len()); + } + let id_len = protocol_id_full.len().min(protocol_id.len()); + &mut protocol_id[0..id_len].copy_from_slice(&protocol_id_full[0..id_len]); + protocol_id + }; - let network = network::Service::new(network_params, protocol_id, import_queue)?; + let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); + let network = network::Service::new( + network_params, + protocol_id, + import_queue + )?; on_demand.map(|on_demand| on_demand.set_service_link(Arc::downgrade(&network))); { // block notifications let network = Arc::downgrade(&network); - let txpool = transaction_pool.clone(); + let txpool = Arc::downgrade(&transaction_pool); + let wclient = Arc::downgrade(&client); let events = client.import_notification_stream() .for_each(move |notification| { if let Some(network) = network.upgrade() { network.on_block_imported(notification.hash, ¬ification.header); } - txpool.prune_tags(&BlockId::hash(notification.hash), notification.tags) - .map_err(|e| warn!("Error removing extrinsics: {:?}", e))?; + if let (Some(txpool), Some(client)) = (txpool.upgrade(), wclient.upgrade()) { + Components::TransactionPool::on_block_imported( + &BlockId::hash(notification.hash), + &*client, + &*txpool, + ).map_err(|e| warn!("Pool error processing new block: {:?}", e))?; + } + Ok(()) + }) + .select(exit.clone()) + .then(|_| Ok(())); + task_executor.spawn(events); + } + + { + // finality notifications + let network = Arc::downgrade(&network); + + // A utility stream that drops all ready items and only returns the last one. + // This is used to only keep the last finality notification and avoid + // overloading the sync module with notifications. + struct MostRecentNotification(futures::stream::Fuse>); + + impl Stream for MostRecentNotification { + type Item = as Stream>::Item; + type Error = as Stream>::Error; + + fn poll(&mut self) -> Poll, Self::Error> { + let mut last = None; + let last = loop { + match self.0.poll()? { + Async::Ready(Some(item)) => { last = Some(item) } + Async::Ready(None) => match last { + None => return Ok(Async::Ready(None)), + Some(last) => break last, + }, + Async::NotReady => match last { + None => return Ok(Async::NotReady), + Some(last) => break last, + }, + } + }; + + Ok(Async::Ready(Some(last))) + } + } + + let events = MostRecentNotification(client.finality_notification_stream().fuse()) + .for_each(move |notification| { + if let Some(network) = network.upgrade() { + network.on_block_finalized(notification.hash, ¬ification.header); + } Ok(()) }) .select(exit.clone()) .then(|_| Ok(())); + task_executor.spawn(events); } @@ -233,97 +285,79 @@ impl Service task_executor.spawn(events); } - // RPC - let rpc_config = RpcConfig { - chain_name: config.chain_spec.name().to_string(), - impl_name: config.impl_name, - impl_version: config.impl_version, - }; - let (rpc_http, rpc_ws) = { - let handler = || { - let client = client.clone(); - let subscriptions = rpc::apis::Subscriptions::new(task_executor.clone()); - let chain = rpc::apis::chain::Chain::new(client.clone(), subscriptions.clone()); - let state = rpc::apis::state::State::new(client.clone(), subscriptions.clone()); - let author = rpc::apis::author::Author::new(client.clone(), transaction_pool.clone(), subscriptions.clone()); - rpc::rpc_handler::, ComponentExHash, _, _, _, _, _>( - state, - chain, - author, - rpc_config.clone(), - ) - }; - ( - maybe_start_server(config.rpc_http, |address| rpc::start_http(address, handler()))?, - maybe_start_server(config.rpc_ws, |address| rpc::start_ws(address, handler()))?, - ) + // RPC + let system_info = rpc::apis::system::SystemInfo { + chain_name: config.chain_spec.name().into(), + impl_name: config.impl_name.into(), + impl_version: config.impl_version.into(), + properties: config.chain_spec.properties(), }; - - let proposer = Arc::new(ProposerFactory { - client: client.clone(), - transaction_pool: transaction_pool.clone(), - offline: Arc::new(RwLock::new(OfflineTracker::new())), - force_delay: 0 // FIXME: allow this to be configured - }); + let rpc = Components::RPC::start_rpc( + client.clone(), network.clone(), has_bootnodes, system_info, config.rpc_http, config.rpc_ws, task_executor.clone(), transaction_pool.clone(), + )?; // Telemetry - let telemetry = match config.telemetry_url { - Some(url) => { - let is_authority = config.roles == Roles::AUTHORITY; - let pubkey = format!("{}", public_key); - let name = config.name.clone(); - let impl_name = config.impl_name.to_owned(); - let version = version.clone(); - let chain_name = config.chain_spec.name().to_owned(); - Some(tel::init_telemetry(tel::TelemetryConfig { - url: url, - on_connect: Box::new(move || { - telemetry!("system.connected"; - "name" => name.clone(), - "implementation" => impl_name.clone(), - "version" => version.clone(), - "config" => "", - "chain" => chain_name.clone(), - "pubkey" => &pubkey, - "authority" => is_authority - ); - }), - })) - }, - None => None, - }; + let telemetry = config.telemetry_url.clone().map(|url| { + let is_authority = config.roles == Roles::AUTHORITY; + let pubkey = format!("{}", public_key); + let name = config.name.clone(); + let impl_name = config.impl_name.to_owned(); + let version = version.clone(); + let chain_name = config.chain_spec.name().to_owned(); + Arc::new(tel::init_telemetry(tel::TelemetryConfig { + url: url, + on_connect: Box::new(move || { + telemetry!("system.connected"; + "name" => name.clone(), + "implementation" => impl_name.clone(), + "version" => version.clone(), + "config" => "", + "chain" => chain_name.clone(), + "pubkey" => &pubkey, + "authority" => is_authority + ); + }), + })) + }); Ok(Service { - client: client, + client, network: Some(network), - transaction_pool: transaction_pool, + transaction_pool, signal: Some(signal), - keystore: keystore, - proposer, + keystore, + config, exit, - _rpc_http: rpc_http, - _rpc_ws: rpc_ws.map(Mutex::new), + _rpc: Box::new(rpc), _telemetry: telemetry, }) } + + /// give the authority key, if we are an authority and have a key + pub fn authority_key(&self) -> Option { + if self.config.roles != Roles::AUTHORITY { return None } + let keystore = &self.keystore; + if let Ok(Some(Ok(key))) = keystore.contents().map(|keys| keys.get(0) + .map(|k| keystore.load(k, ""))) + { + Some(key) + } else { + None + } + } + + pub fn telemetry(&self) -> Option> { + self._telemetry.as_ref().map(|t| t.clone()) + } } -impl Service where - Components: components::Components, -{ +impl Service where Components: components::Components { /// Get shared client instance. pub fn client(&self) -> Arc> { self.client.clone() } - /// Get shared proposer instance - pub fn proposer(&self) - -> Arc, Components::TransactionPoolApi>> - { - self.proposer.clone() - } - /// Get shared network instance. pub fn network(&self) -> Arc> { self.network.as_ref().expect("self.network always Some").clone() @@ -376,27 +410,6 @@ fn maybe_start_server(address: Option, start: F) -> Result substrate_rpc::system::error::Result { - Ok(self.impl_name.into()) - } - - fn system_version(&self) -> substrate_rpc::system::error::Result { - Ok(self.impl_version.into()) - } - - fn system_chain(&self) -> substrate_rpc::system::error::Result { - Ok(self.chain_name.clone()) - } -} - /// Transaction pool adapter. pub struct TransactionPoolAdapter { imports_external_transactions: bool, @@ -415,7 +428,7 @@ impl TransactionPoolAdapter { } } -impl network::TransactionPool, ComponentBlock> for TransactionPoolAdapter { +impl network::TransactionPool, ComponentBlock> for TransactionPoolAdapter where ::RuntimeApi: Send + Sync{ fn transactions(&self) -> Vec<(ComponentExHash, ComponentExtrinsic)> { self.pool.ready() .map(|t| { @@ -463,41 +476,6 @@ impl network::TransactionPool, ComponentBlock< } } -/// Creates a simple `Service` implementation. -/// This `Service` just holds an instance to a `service::Service` and implements `Deref`. -/// It also provides a `new` function that takes a `config` and a `TaskExecutor`. -#[macro_export] -macro_rules! construct_simple_service { - ( - $name: ident - ) => { - pub struct $name { - inner: $crate::Arc<$crate::Service>, - } - - impl $name { - fn new( - config: FactoryFullConfiguration, - executor: $crate::TaskExecutor - ) -> $crate::Result { - Ok( - Self { - inner: $crate::Arc::new($crate::Service::new(config, executor)?) - } - ) - } - } - - impl $crate::Deref for $name { - type Target = $crate::Service; - - fn deref(&self) -> &Self::Target { - &self.inner - } - } - } -} - /// Constructs a service factory with the given name that implements the `ServiceFactory` trait. /// The required parameters are required to be given in the exact order. Some parameters are followed /// by `{}` blocks. These blocks are required and used to initialize the given parameter. @@ -522,14 +500,17 @@ macro_rules! construct_simple_service { /// Configuration = (), /// FullService = Service> /// { |config, executor| Service::>::new(config, executor) }, +/// // Setup as Consensus Authority (if the role and key are given) +/// AuthoritySetup = { +/// |service: Self::FullService, executor: TaskExecutor, key: Arc| { Ok(service) }}, /// LightService = Service> /// { |config, executor| Service::>::new(config, executor) }, /// // Declare the import queue. The import queue is special as it takes two initializers. /// // The first one is for the initializing the full import queue and the second for the /// // light import queue. /// ImportQueue = BasicQueue -/// { |_, _| Ok(BasicQueue::new(Arc::new(NoneVerifier {}))) } -/// { |_, _| Ok(BasicQueue::new(Arc::new(NoneVerifier {}))) }, +/// { |_, client| Ok(BasicQueue::new(Arc::new(NoneVerifier {}, client))) } +/// { |_, client| Ok(BasicQueue::new(Arc::new(NoneVerifier {}, client))) }, /// } /// } /// ``` @@ -539,6 +520,7 @@ macro_rules! construct_service_factory { $(#[$attr:meta])* struct $name:ident { Block = $block:ty, + RuntimeApi = $runtime_api:ty, NetworkProtocol = $protocol:ty { $( $protocol_init:tt )* }, RuntimeDispatch = $dispatch:ty, FullTransactionPoolApi = $full_transaction:ty { $( $full_transaction_init:tt )* }, @@ -546,6 +528,7 @@ macro_rules! construct_service_factory { Genesis = $genesis:ty, Configuration = $config:ty, FullService = $full_service:ty { $( $full_service_init:tt )* }, + AuthoritySetup = { $( $authority_setup:tt )* }, LightService = $light_service:ty { $( $light_service_init:tt )* }, FullImportQueue = $full_import_queue:ty { $( $full_import_queue_init:tt )* }, @@ -559,6 +542,7 @@ macro_rules! construct_service_factory { #[allow(unused_variables)] impl $crate::ServiceFactory for $name { type Block = $block; + type RuntimeApi = $runtime_api; type NetworkProtocol = $protocol; type RuntimeDispatch = $dispatch; type FullTransactionPoolApi = $full_transaction; @@ -593,14 +577,14 @@ macro_rules! construct_service_factory { } fn build_full_import_queue( - config: &$crate::FactoryFullConfiguration, + config: &mut $crate::FactoryFullConfiguration, client: $crate::Arc<$crate::FullClient>, ) -> $crate::Result { ( $( $full_import_queue_init )* ) (config, client) } fn build_light_import_queue( - config: &FactoryFullConfiguration, + config: &mut FactoryFullConfiguration, client: Arc<$crate::LightClient>, ) -> Result { ( $( $light_import_queue_init )* ) (config, client) @@ -616,10 +600,13 @@ macro_rules! construct_service_factory { fn new_full( config: $crate::FactoryFullConfiguration, - executor: $crate::TaskExecutor + executor: $crate::TaskExecutor, ) -> Result { - ( $( $full_service_init )* ) (config, executor) + ( $( $full_service_init )* ) (config, executor.clone()).and_then(|service| { + let key = (&service).authority_key().map(Arc::new); + ($( $authority_setup )*)(service, executor, key) + }) } } } diff --git a/core/service/test/src/lib.rs b/core/service/test/src/lib.rs index 0a967e3cd6c8183c2e3d3176a6e773a7fda6340a..cc0947372cc2d87e76cd9d4c11951ccca44bba41 100644 --- a/core/service/test/src/lib.rs +++ b/core/service/test/src/lib.rs @@ -33,7 +33,7 @@ use std::iter; use std::sync::Arc; use std::net::Ipv4Addr; use std::time::Duration; -use futures::Stream; +use futures::{Future, Stream}; use tempdir::TempDir; use tokio::runtime::Runtime; use tokio::timer::Interval; @@ -47,7 +47,8 @@ use service::{ Roles, FactoryExtrinsic, }; -use network::{NetworkConfiguration, NonReservedPeerMode, Protocol, SyncProvider, ManageNetwork}; +use network::{Protocol, SyncProvider, ManageNetwork}; +use network::config::{NetworkConfiguration, NonReservedPeerMode}; use sr_primitives::traits::As; use sr_primitives::generic::BlockId; use consensus::{ImportBlock, BlockImport}; @@ -111,6 +112,7 @@ fn node_config ( reserved_nodes: vec![], non_reserved_mode: NonReservedPeerMode::Accept, client_version: "network/test/0.1".to_owned(), + node_name: "unknown".to_owned(), }; Configuration { @@ -122,6 +124,7 @@ fn node_config ( network: network_config, keystore_path: root.join("key").to_str().unwrap().into(), database_path: root.join("db").to_str().unwrap().into(), + database_cache_size: None, pruning: Default::default(), keys: keys, chain_spec: (*spec).clone(), @@ -179,11 +182,11 @@ impl TestNet { } } -pub fn connectivity(spec: FactoryChainSpec) { +pub fn connectivity(spec: FactoryChainSpec) { const NUM_NODES: u32 = 10; { let temp = TempDir::new("substrate-connectivity-test").expect("Error creating test dir"); - { + let runtime = { let mut network = TestNet::::new(&temp, spec.clone(), NUM_NODES, 0, vec![], 30400); info!("Checking star topology"); let first_address = network.full_nodes[0].1.network().node_id().expect("No node address"); @@ -193,13 +196,17 @@ pub fn connectivity(spec: FactoryChainSpec) { network.run_until_all_full(|_index, service| service.network().status().num_peers == NUM_NODES as usize - 1 ); - } + network.runtime + }; + + runtime.shutdown_on_idle().wait().expect("Error shutting down runtime"); + temp.close().expect("Error removing temp dir"); } { let temp = TempDir::new("substrate-connectivity-test").expect("Error creating test dir"); { - let mut network = TestNet::::new(&temp, spec, NUM_NODES as u32, 0, vec![], 30400); + let mut network = TestNet::::new(&temp, spec, NUM_NODES, 0, vec![], 30400); info!("Checking linked topology"); let mut address = network.full_nodes[0].1.network().node_id().expect("No node address"); for (_, service) in network.full_nodes.iter().skip(1) { @@ -253,8 +260,8 @@ where } pub fn consensus(spec: FactoryChainSpec, authorities: Vec) -where - F: ServiceFactory, + where + F: ServiceFactory, { const NUM_NODES: u32 = 20; const NUM_BLOCKS: u64 = 200; diff --git a/core/sr-api-macros/Cargo.toml b/core/sr-api-macros/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7cc414a7321b2bf4b9d20a63f7879ba8245b371d --- /dev/null +++ b/core/sr-api-macros/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "sr-api-macros" +version = "0.1.0" +authors = ["Parity Technologies "] + +[lib] +proc-macro = true + +[dependencies] +quote = "0.6" +syn = { version = "^0.15.22", features = [ "full", "fold", "extra-traits", "visit" ] } +proc-macro2 = "0.4" +blake2-rfc = "0.2" + +[dev-dependencies] +substrate-client = { path = "../client" } +substrate-test-client = { path = "../test-client" } +sr-primitives = { path = "../sr-primitives" } +sr-version = { path = "../sr-version" } +substrate-primitives = { path = "../primitives" } +criterion = "0.2" + +[[bench]] +name = "bench" +harness = false diff --git a/core/sr-api-macros/benches/bench.rs b/core/sr-api-macros/benches/bench.rs new file mode 100644 index 0000000000000000000000000000000000000000..54f8c8a3d103243bf3e2e39f8b14f75fa413a8f3 --- /dev/null +++ b/core/sr-api-macros/benches/bench.rs @@ -0,0 +1,62 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +#[macro_use] +extern crate criterion; +extern crate substrate_client; +extern crate substrate_test_client as test_client; +extern crate sr_primitives as runtime_primitives; + +use criterion::Criterion; +use test_client::runtime::TestAPI; +use runtime_primitives::{generic::BlockId, traits::ProvideRuntimeApi}; + +fn sr_api_benchmark(c: &mut Criterion) { + c.bench_function("add one with same runtime api", |b| { + let client = test_client::new(); + let runtime_api = client.runtime_api(); + let block_id = BlockId::Number(client.info().unwrap().chain.best_number); + + b.iter(|| runtime_api.benchmark_add_one(&block_id, &1)) + }); + + c.bench_function("add one with recreating runtime api", |b| { + let client = test_client::new(); + let block_id = BlockId::Number(client.info().unwrap().chain.best_number); + + b.iter(|| client.runtime_api().benchmark_add_one(&block_id, &1)) + }); + + c.bench_function("vector add one with same runtime api", |b| { + let client = test_client::new(); + let runtime_api = client.runtime_api(); + let block_id = BlockId::Number(client.info().unwrap().chain.best_number); + let data = vec![0; 1000]; + + b.iter_with_large_drop(|| runtime_api.benchmark_vector_add_one(&block_id, &data)) + }); + + c.bench_function("vector add one with recreating runtime api", |b| { + let client = test_client::new(); + let block_id = BlockId::Number(client.info().unwrap().chain.best_number); + let data = vec![0; 1000]; + + b.iter_with_large_drop(|| client.runtime_api().benchmark_vector_add_one(&block_id, &data)) + }); +} + +criterion_group!(benches, sr_api_benchmark); +criterion_main!(benches); diff --git a/core/sr-api-macros/src/compile_fail_tests.rs b/core/sr-api-macros/src/compile_fail_tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..7d7be065fa561fbd54140c5b430d4b854f9265ed --- /dev/null +++ b/core/sr-api-macros/src/compile_fail_tests.rs @@ -0,0 +1,380 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Compile fail tests. + +mod declaring_own_block { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate sr_primitives as runtime_primitives; + + use runtime_primitives::traits::Block as BlockT; + + decl_runtime_apis! { + pub trait Api { + fn test(); + } + } + + fn main() {} + ``` + */ +} + +mod declaring_own_block_with_different_name { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate sr_primitives as runtime_primitives; + + use runtime_primitives::traits::Block as BlockT; + + decl_runtime_apis! { + pub trait Api { + fn test(); + } + } + + fn main() {} + ``` + */ +} + +mod adding_self_parameter { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate sr_primitives as runtime_primitives; + + decl_runtime_apis! { + pub trait Api { + fn test(&self); + } + } + + fn main() {} + ``` + */ +} + +mod adding_at_parameter { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate sr_primitives as runtime_primitives; + + decl_runtime_apis! { + pub trait Api { + fn test(at: u64); + } + } + + fn main() {} + ``` + */ +} + +mod invalid_api_version { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate sr_primitives as runtime_primitives; + + decl_runtime_apis! { + #[api_version] + pub trait Api { + fn test(data: u64); + } + } + + fn main() {} + ``` + */ +} + +mod invalid_api_version_2 { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate sr_primitives as runtime_primitives; + + decl_runtime_apis! { + #[api_version("1")] + pub trait Api { + fn test(data: u64); + } + } + + fn main() {} + ``` + */ +} + +mod invalid_api_version_3 { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate sr_primitives as runtime_primitives; + + decl_runtime_apis! { + #[api_version()] + pub trait Api { + fn test(data: u64); + } + } + + fn main() {} + ``` + */ +} + +mod missing_block_generic_parameter { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate substrate_test_client as test_client; + extern crate sr_primitives as runtime_primitives; + extern crate substrate_primitives as primitives; + + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; + + /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` + /// trait are done by the `construct_runtime!` macro in a real runtime. + struct Runtime {} + impl GetNodeBlockType for Runtime { + type NodeBlock = Block; + } + + decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + } + } + + impl_runtime_apis! { + impl self::Api for Runtime { + fn test(data: u64) { + unimplemented!() + } + } + } + + fn main() {} + ``` + */ +} + +mod missing_path_for_trait { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate substrate_test_client as test_client; + extern crate sr_primitives as runtime_primitives; + extern crate substrate_primitives as primitives; + + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; + + /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` + /// trait are done by the `construct_runtime!` macro in a real runtime. + struct Runtime {} + impl GetNodeBlockType for Runtime { + type NodeBlock = Block; + } + + decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + } + } + + impl_runtime_apis! { + impl Api for Runtime { + fn test(data: u64) { + unimplemented!() + } + } + } + + fn main() {} + ``` + */ +} + +mod empty_impl_runtime_apis_call { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate substrate_test_client as test_client; + extern crate sr_primitives as runtime_primitives; + extern crate substrate_primitives as primitives; + + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; + + /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` + /// trait are done by the `construct_runtime!` macro in a real runtime. + struct Runtime {} + impl GetNodeBlockType for Runtime { + type NodeBlock = Block; + } + + decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + } + } + + impl_runtime_apis! {} + + fn main() {} + ``` + */ +} + +mod type_reference_in_impl_runtime_apis_call { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate substrate_test_client as test_client; + extern crate sr_primitives as runtime_primitives; + extern crate substrate_primitives as primitives; + + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; + + /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` + /// trait are done by the `construct_runtime!` macro in a real runtime. + struct Runtime {} + impl GetNodeBlockType for Runtime { + type NodeBlock = Block; + } + + decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + } + } + + impl_runtime_apis! { + impl self::Api for Runtime { + fn test(data: &u64) { + unimplemented!() + } + } + } + + fn main() {} + ``` + */ +} + +mod impl_incorrect_method_signature { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate substrate_test_client as test_client; + extern crate sr_primitives as runtime_primitives; + extern crate substrate_primitives as primitives; + + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; + + /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` + /// trait are done by the `construct_runtime!` macro in a real runtime. + struct Runtime {} + impl GetNodeBlockType for Runtime { + type NodeBlock = Block; + } + + decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + } + } + + impl_runtime_apis! { + impl self::Api for Runtime { + fn test(data: String) {} + } + } + + fn main() {} + ``` + */ +} + +mod impl_two_traits_with_same_name { + /*! + ```compile_fail + #[macro_use] + extern crate substrate_client; + extern crate substrate_test_client as test_client; + extern crate sr_primitives as runtime_primitives; + extern crate substrate_primitives as primitives; + + use runtime_primitives::traits::GetNodeBlockType; + use test_client::runtime::Block; + + /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` + /// trait are done by the `construct_runtime!` macro in a real runtime. + struct Runtime {} + impl GetNodeBlockType for Runtime { + type NodeBlock = Block; + } + + decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + } + } + + mod second { + decl_runtime_apis! { + pub trait Api { + fn test2(data: u64); + } + } + } + + impl_runtime_apis! { + impl self::Api for Runtime { + fn test(data: u64) {} + } + + impl second::Api for Runtime { + fn test2(data: u64) {} + } + } + + fn main() {} + ``` + */ +} diff --git a/core/sr-api-macros/src/decl_runtime_apis.rs b/core/sr-api-macros/src/decl_runtime_apis.rs new file mode 100644 index 0000000000000000000000000000000000000000..54f8d81bef03d4b71106bb2f40abd31759aef5ea --- /dev/null +++ b/core/sr-api-macros/src/decl_runtime_apis.rs @@ -0,0 +1,548 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 utils::{ + generate_crate_access, generate_hidden_includes, generate_runtime_mod_name_for_trait, + fold_fn_decl_for_client_side, unwrap_or_error, extract_parameter_names_types_and_borrows, + generate_native_call_generator_fn_name +}; + +use proc_macro; +use proc_macro2::{TokenStream, Span}; + +use quote::quote; + +use syn::{ + spanned::Spanned, parse_macro_input, parse::{Parse, ParseStream, Result, Error}, ReturnType, + fold::{self, Fold}, FnDecl, parse_quote, ItemTrait, Generics, GenericParam, Attribute, + visit::{Visit, self}, FnArg, Pat, TraitBound, Meta, NestedMeta, Lit, TraitItem, Ident, Type +}; + +use std::collections::HashMap; + +use blake2_rfc; + +/// The ident used for the block generic parameter. +const BLOCK_GENERIC_IDENT: &str = "Block"; + +/// Unique identifier used to make the hidden includes unique for this macro. +const HIDDEN_INCLUDES_ID: &str = "DECL_RUNTIME_APIS"; + +/// The `core_trait` attribute. +const CORE_TRAIT_ATTRIBUTE: &str = "core_trait"; +/// The `api_version` attribute. +const API_VERSION_ATTRIBUTE: &str = "api_version"; +/// All attributes that we support in the declaratio of a runtime api trait. +const SUPPORTED_ATTRIBUTE_NAMES: &[&str] = &[CORE_TRAIT_ATTRIBUTE, API_VERSION_ATTRIBUTE]; + +/// The structure used for parsing the runtime api declarations. +struct RuntimeApiDecls { + decls: Vec, +} + +impl Parse for RuntimeApiDecls { + fn parse(input: ParseStream) -> Result { + let mut decls = Vec::new(); + + while !input.is_empty() { + decls.push(ItemTrait::parse(input)?); + } + + Ok(Self { decls }) + } +} + +/// Extend the given generics with `Block: BlockT` as first generic parameter. +fn extend_generics_with_block(generics: &mut Generics) { + let c = generate_crate_access(HIDDEN_INCLUDES_ID); + + generics.lt_token = Some(parse_quote!(<)); + generics.params.insert(0, parse_quote!( Block: #c::runtime_api::BlockT )); + generics.gt_token = Some(parse_quote!(>)); +} + +/// Remove all attributes from the vector that are supported by us in the declaration of a runtime +/// api trait. The returned hashmap contains all found attribute names as keys and the rest of the +/// attribute body as `TokenStream`. +fn remove_supported_attributes(attrs: &mut Vec) -> HashMap<&'static str, Attribute> { + let mut result = HashMap::new(); + attrs.retain(|v| { + match SUPPORTED_ATTRIBUTE_NAMES.iter().filter(|a| v.path.is_ident(a)).next() { + Some(attribute) => { + result.insert(*attribute, v.clone()); + false + }, + None => true, + } + }); + + result +} + +/// Visits the ast and checks if `Block` ident is used somewhere. +struct IsUsingBlock { + result: bool, +} + +impl<'ast> Visit<'ast> for IsUsingBlock { + fn visit_ident(&mut self, i: &'ast Ident) { + if i == BLOCK_GENERIC_IDENT { + self.result = true; + } + } +} + +/// Visits the ast and checks if `Block` ident is used somewhere. +fn type_is_using_block(ty: &Type) -> bool { + let mut visitor = IsUsingBlock { result: false }; + visitor.visit_type(ty); + visitor.result +} + +/// Visits the ast and checks if `Block` ident is used somewhere. +fn return_type_is_using_block(ty: &ReturnType) -> bool { + let mut visitor = IsUsingBlock { result: false }; + visitor.visit_return_type(ty); + visitor.result +} + +/// Replace all occurences of `Block` with `NodeBlock` +struct ReplaceBlockWithNodeBlock {} + +impl Fold for ReplaceBlockWithNodeBlock { + fn fold_ident(&mut self, input: Ident) -> Ident { + if input == BLOCK_GENERIC_IDENT { + Ident::new("NodeBlock", Span::call_site()) + } else { + input + } + } +} + +/// Replace all occurences of `Block` with `NodeBlock` +fn fn_arg_replace_block_with_node_block(fn_arg: FnArg) -> FnArg { + let mut replace = ReplaceBlockWithNodeBlock {}; + fold::fold_fn_arg(&mut replace, fn_arg) +} + +/// Replace all occurences of `Block` with `NodeBlock` +fn return_type_replace_block_with_node_block(return_type: ReturnType) -> ReturnType { + let mut replace = ReplaceBlockWithNodeBlock {}; + fold::fold_return_type(&mut replace, return_type) +} + +fn generate_native_call_generators(decl: &ItemTrait) -> Result { + let fns = decl.items.iter().filter_map(|i| match i { + TraitItem::Method(ref m) => Some(&m.sig), + _ => None, + }); + + let mut result = Vec::new(); + let trait_ = &decl.ident; + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + + // Auxilariy function that is used to convert between types that use different block types. + // The function expects that both a convertable by encoding the one and decoding the other. + result.push(quote!( + fn convert_between_block_types + (input: &I) -> R + { + ::decode( + &mut &#crate_::runtime_api::Encode::encode(input)[..] + ).unwrap() + } + )); + + // Generate a native call generator for each function of the given trait. + for fn_ in fns { + let params = extract_parameter_names_types_and_borrows(&fn_.decl)?; + let trait_fn_name = &fn_.ident; + let fn_name = generate_native_call_generator_fn_name(&fn_.ident); + let output = return_type_replace_block_with_node_block(fn_.decl.output.clone()); + + // Every type that is using the `Block` generic parameter, we need to encode/decode, + // to make it compatible between the runtime/node. + let conversions = params.iter().filter(|v| type_is_using_block(&v.1)).map(|(n, t, _)| { + quote!( + let #n: #t = convert_between_block_types(&#n); + ) + }); + // Same as for the input types, we need to check if we also need to convert the output, + // before returning it. + let output_conversion = if return_type_is_using_block(&fn_.decl.output) { + quote!( convert_between_block_types(&res) ) + } else { + quote!( res ) + }; + + let input_names = params.iter().map(|v| &v.0); + // If the type is using the block generic type, we will encode/decode it to make it + // compatible. To ensure that we forward it by ref/value, we use the value given by the + // the user. Otherwise if it is not using the block, we don't need to add anything. + let input_borrows = params + .iter() + .map(|v| if type_is_using_block(&v.1) { v.2.clone() } else { quote!() }); + + // Replace all `Block` with `NodeBlock`, add `'a` lifetime to references and collect + // all the function inputs. + let fn_inputs = fn_ + .decl + .inputs + .iter() + .map(|v| fn_arg_replace_block_with_node_block(v.clone())) + .map(|v| match v { + FnArg::Captured(ref arg) => { + let mut arg = arg.clone(); + match arg.ty { + Type::Reference(ref mut r) => { + r.lifetime = Some(parse_quote!( 'a )); + }, + _ => {} + } + FnArg::Captured(arg) + }, + r => r.clone(), + }); + + let (impl_generics, ty_generics, where_clause) = decl.generics.split_for_impl(); + // We need to parse them again, to get an easy access to the actual parameters. + let mut impl_generics: Generics = parse_quote!(#impl_generics); + let impl_generics_params = impl_generics.params.iter().map(|p| { + match p { + GenericParam::Type(ref ty) => { + let mut ty = ty.clone(); + ty.bounds.push(parse_quote!( 'a )); + GenericParam::Type(ty) + }, + // We should not see anything different than type params here. + r => r.clone(), + } + }); + + // Generate the generator function + result.push(quote!( + #[cfg(any(feature = "std", test))] + pub fn #fn_name< + 'a, ApiImpl: #trait_ #ty_generics, NodeBlock: #crate_::runtime_api::BlockT + #(, #impl_generics_params)* + >( + #( #fn_inputs ),* + ) -> impl FnOnce() #output + 'a #where_clause { + move || { + #( #conversions )* + let res = ApiImpl::#trait_fn_name(#( #input_borrows #input_names ),*); + #output_conversion + } + } + )); + } + + Ok(quote!( #( #result )* )) +} + +/// Generate the decleration of the trait for the runtime. +fn generate_runtime_decls(decls: &[ItemTrait]) -> TokenStream { + let mut result = Vec::new(); + + for decl in decls { + let mut decl = decl.clone(); + extend_generics_with_block(&mut decl.generics); + let mod_name = generate_runtime_mod_name_for_trait(&decl.ident); + let found_attributes = remove_supported_attributes(&mut decl.attrs); + let api_version = unwrap_or_error(get_api_version(&found_attributes).map(|v| { + generate_runtime_api_version(v as u32) + })); + let id = generate_runtime_api_id(&decl.ident.to_string()); + let native_call_generators = unwrap_or_error(generate_native_call_generators(&decl)); + + result.push(quote!( + #[doc(hidden)] + #[allow(dead_code)] + pub mod #mod_name { + use super::*; + + #decl + + pub #api_version + + pub #id + + #native_call_generators + } + )); + } + + quote!( #( #result )* ) +} + +/// Modify the given runtime api declaration to be usable on the client side. +struct ToClientSideDecl<'a> { + block_id: &'a TokenStream, + crate_: &'a TokenStream, + found_attributes: &'a mut HashMap<&'static str, Attribute>, +} + +impl<'a> Fold for ToClientSideDecl<'a> { + fn fold_fn_decl(&mut self, input: FnDecl) -> FnDecl { + let input = fold_fn_decl_for_client_side( + input, + &self.block_id, + &self.crate_ + ); + + fold::fold_fn_decl(self, input) + } + + fn fold_item_trait(&mut self, mut input: ItemTrait) -> ItemTrait { + extend_generics_with_block(&mut input.generics); + + *self.found_attributes = remove_supported_attributes(&mut input.attrs); + // Check if this is the `Core` runtime api trait. + let is_core_trait = self.found_attributes.contains_key(CORE_TRAIT_ATTRIBUTE); + let block_ident = Ident::new(BLOCK_GENERIC_IDENT, Span::call_site()); + + if is_core_trait { + // Add all the supertraits we want to have for `Core`. + let crate_ = &self.crate_; + input.supertraits = parse_quote!( + 'static + + Send + + Sync + + #crate_::runtime_api::ApiExt<#block_ident> + ); + } else { + // Add the `Core` runtime api as super trait. + let crate_ = &self.crate_; + input.supertraits.push(parse_quote!( #crate_::runtime_api::Core<#block_ident> )); + } + + // The client side trait is only required when compiling with the feature `std` or `test`. + input.attrs.push(parse_quote!( #[cfg(any(feature = "std", test))] )); + + fold::fold_item_trait(self, input) + } +} + +/// Parse the given attribute as `API_VERSION_ATTRIBUTE`. +fn parse_runtime_api_version(version: &Attribute) -> Result { + let meta = version.parse_meta()?; + + let err = Err(Error::new( + meta.span(), + &format!( + "Unexpected `{api_version}` attribute. The supported format is `{api_version}(1)`", + api_version = API_VERSION_ATTRIBUTE + ) + ) + ); + + match meta { + Meta::List(list) => { + if list.nested.len() > 1 && list.nested.is_empty() { + err + } else { + match list.nested.first().as_ref().map(|v| v.value()) { + Some(NestedMeta::Literal(Lit::Int(i))) => { + Ok(i.value()) + }, + _ => err, + } + } + }, + _ => err, + } +} + +/// Generates the identifier as const variable for the given `trait_name` +/// by hashing the `trait_name`. +fn generate_runtime_api_id(trait_name: &str) -> TokenStream { + let mut res = [0; 8]; + res.copy_from_slice(blake2_rfc::blake2b::blake2b(8, &[], trait_name.as_bytes()).as_bytes()); + + quote!( const ID: [u8; 8] = [ #( #res ),* ]; ) +} + +/// Generates the const variable that holds the runtime api version. +fn generate_runtime_api_version(version: u32) -> TokenStream { + quote!( const VERSION: u32 = #version; ) +} + +/// Generates the implementation of `RuntimeApiInfo` for the given trait. +fn generate_runtime_info_impl(trait_: &ItemTrait, version: u64) -> TokenStream { + let trait_name = &trait_.ident; + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + let id = generate_runtime_api_id(&trait_name.to_string()); + let version = generate_runtime_api_version(version as u32); + let (impl_generics, ty_generics, where_clause) = trait_.generics.split_for_impl(); + + quote!( + #[cfg(any(feature = "std", test))] + impl #impl_generics #crate_::runtime_api::RuntimeApiInfo + for #trait_name #ty_generics #where_clause + { + #id + #version + } + ) +} + +/// Get the api version from the user given attribute or `Ok(1)`, if no attribute was given. +fn get_api_version(found_attributes: &HashMap<&'static str, Attribute>) -> Result { + match found_attributes.get(&API_VERSION_ATTRIBUTE) { + Some(attr) => parse_runtime_api_version(attr), + None => Ok(1), + } +} + +/// Generate the decleration of the trait for the client side. +fn generate_client_side_decls(decls: &[ItemTrait]) -> TokenStream { + let mut result = Vec::new(); + + for decl in decls { + let mut decl = decl.clone(); + + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + let block_id = quote!( #crate_::runtime_api::BlockId ); + let mut found_attributes = HashMap::new(); + + let decl = { + let mut to_client_side = ToClientSideDecl { + crate_: &crate_, + block_id: &block_id, + found_attributes: &mut found_attributes + }; + to_client_side.fold_item_trait(decl) + }; + + let api_version = get_api_version(&found_attributes); + + let runtime_info = unwrap_or_error( + api_version.map(|v| generate_runtime_info_impl(&decl, v)) + ); + + result.push(quote!( #decl #runtime_info )); + } + + quote!( #( #result )* ) +} + +/// Checks that a trait declaration is in the format we expect. +struct CheckTraitDecl { + errors: Vec, +} + +impl<'ast> Visit<'ast> for CheckTraitDecl { + fn visit_fn_arg(&mut self, input: &'ast FnArg) { + match input { + FnArg::Captured(ref arg) => { + match arg.pat { + Pat::Ident(ref pat) if pat.ident == "at" => { + self.errors.push( + Error::new( + pat.span(), + "`decl_runtime_apis!` adds automatically a parameter \ + `at: &BlockId`. Please rename/remove your parameter." + ) + ) + }, + _ => {} + } + }, + FnArg::SelfRef(_) | FnArg::SelfValue(_) => { + self.errors.push(Error::new(input.span(), "Self values are not supported.")) + } + _ => { + self.errors.push( + Error::new( + input.span(), + "Only function arguments in the form `pat: type` are supported." + ) + ) + } + } + + visit::visit_fn_arg(self, input); + } + + fn visit_generic_param(&mut self, input: &'ast GenericParam) { + match input { + GenericParam::Type(ty) if &ty.ident == BLOCK_GENERIC_IDENT => { + self.errors.push( + Error::new( + input.span(), + "`Block: BlockT` generic parameter will be added automatically by the \ + `decl_runtime_apis!` macro!" + ) + ) + }, + _ => {} + } + + visit::visit_generic_param(self, input); + } + + fn visit_trait_bound(&mut self, input: &'ast TraitBound) { + if let Some(last_ident) = input.path.segments.last().map(|v| &v.value().ident) { + if last_ident == "BlockT" || last_ident == BLOCK_GENERIC_IDENT { + self.errors.push( + Error::new( + input.span(), + "`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." + ) + ) + } + } + + visit::visit_trait_bound(self, input) + } +} + +/// Check that the trait declarations are in the format we expect. +fn check_trait_decls(decls: &[ItemTrait]) -> Option { + let mut checker = CheckTraitDecl { errors: Vec::new() }; + decls.iter().for_each(|decl| visit::visit_item_trait(&mut checker, &decl)); + + if checker.errors.is_empty() { + None + } else { + let errors = checker.errors.into_iter().map(|e| e.to_compile_error()); + Some(quote!( #( #errors )* )) + } +} + +/// The implementation of the `decl_runtime_apis!` macro. +pub fn decl_runtime_apis_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + // Parse all trait declarations + let RuntimeApiDecls { decls: api_decls } = parse_macro_input!(input as RuntimeApiDecls); + + if let Some(errors) = check_trait_decls(&api_decls) { + return errors.into(); + } + + let hidden_includes = generate_hidden_includes(HIDDEN_INCLUDES_ID); + let runtime_decls = generate_runtime_decls(&api_decls); + let client_side_decls = generate_client_side_decls(&api_decls); + + quote!( + #hidden_includes + + #runtime_decls + + #client_side_decls + ).into() +} diff --git a/core/sr-api-macros/src/impl_runtime_apis.rs b/core/sr-api-macros/src/impl_runtime_apis.rs new file mode 100644 index 0000000000000000000000000000000000000000..6663cae85fe5d9c2fd2f1c8a1dc995c9b75b6ef0 --- /dev/null +++ b/core/sr-api-macros/src/impl_runtime_apis.rs @@ -0,0 +1,636 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 utils::{ + unwrap_or_error, generate_crate_access, generate_hidden_includes, + generate_runtime_mod_name_for_trait, fold_fn_decl_for_client_side, generate_unique_pattern, + extract_parameter_names_types_and_borrows, generate_native_call_generator_fn_name +}; + +use proc_macro; +use proc_macro2::{Span, TokenStream}; + +use quote::quote; + +use syn::{ + spanned::Spanned, parse_macro_input, Ident, Type, ItemImpl, MethodSig, Path, + ImplItem, parse::{Parse, ParseStream, Result, Error}, PathArguments, GenericArgument, TypePath, + fold::{self, Fold}, FnDecl, parse_quote, FnArg +}; + +use std::{collections::HashSet, iter}; + +/// Unique identifier used to make the hidden includes unique for this macro. +const HIDDEN_INCLUDES_ID: &str = "IMPL_RUNTIME_APIS"; + +/// The structure used for parsing the runtime api implementations. +struct RuntimeApiImpls { + impls: Vec, +} + +impl Parse for RuntimeApiImpls { + fn parse(input: ParseStream) -> Result { + let mut impls = Vec::new(); + + while !input.is_empty() { + impls.push(ItemImpl::parse(input)?); + } + + Ok(Self { impls }) + } +} + +/// Generates the call to the implementation of the requested function. +/// The generated code includes decoding of the input arguments and encoding of the output. +fn generate_impl_call( + signature: &MethodSig, + runtime: &Type, + input: &Ident, + impl_trait: &Path +) -> Result { + let params = extract_parameter_names_types_and_borrows(&signature.decl)?; + + 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 pnames = params.iter().map(|v| &v.0); + let pnames2 = params.iter().map(|v| &v.0); + let ptypes = params.iter().map(|v| &v.1); + let pborrow = params.iter().map(|v| &v.2); + + Ok( + quote!( + #( + let #pnames : #ptypes = match #c_iter::runtime_api::Decode::decode(&mut #input) { + Some(input) => input, + None => panic!("Bad input data provided to {}", #fn_name_str), + }; + )* + + let output = <#runtime as #impl_trait>::#fn_name(#( #pborrow #pnames2 ),*); + #c::runtime_api::Encode::encode(&output) + ).into() + ) +} + +/// Extract the trait that is implemented in the given `ItemImpl`. +fn extract_impl_trait<'a>(impl_: &'a ItemImpl) -> Result<&'a Path> { + impl_.trait_.as_ref().map(|v| &v.1).ok_or_else( + || Error::new(impl_.span(), "Only implementation of traits are supported!") + ).and_then(|p| { + if p.segments.len() > 1 { + Ok(p) + } else { + Err( + Error::new( + p.span(), + "The implemented trait has to be referenced with a path, \ + e.g. `impl client::Core for Runtime`." + ) + ) + } + }) +} + +/// Extracts the runtime block identifier. +fn extract_runtime_block_ident(trait_: &Path) -> Result<&TypePath> { + let span = trait_.span(); + let segment = trait_ + .segments + .last() + .ok_or_else( + || Error::new(span, "Empty path not supported") + )?; + let generics = segment.value(); + + match &generics.arguments { + PathArguments::AngleBracketed(ref args) => { + args.args.first().and_then(|v| match v.value() { + GenericArgument::Type(Type::Path(block)) => Some(block), + _ => None + }).ok_or_else(|| Error::new(args.span(), "Missing `Block` generic parameter.")) + }, + PathArguments::None => { + let span = trait_.segments.last().as_ref().unwrap().value().span(); + Err(Error::new(span, "Missing `Block` generic parameter.")) + }, + PathArguments::Parenthesized(_) => { + Err(Error::new(generics.arguments.span(), "Unexpected parentheses in path!")) + } + } +} + +/// Generate all the implementation calls for the given functions. +fn generate_impl_calls( + impls: &[ItemImpl], + input: &Ident +) -> Result> { + let mut impl_calls = Vec::new(); + + for impl_ in impls { + let impl_trait_path = extract_impl_trait(impl_)?; + let impl_trait = extend_with_runtime_decl_path(impl_trait_path.clone()); + let impl_trait_ident = &impl_trait_path + .segments + .last() + .ok_or_else(|| Error::new(impl_trait_path.span(), "Empty trait path not possible!"))? + .value() + .ident; + + for item in &impl_.items { + match item { + ImplItem::Method(method) => { + let impl_call = generate_impl_call( + &method.sig, + &impl_.self_ty, + input, + &impl_trait + )?; + + impl_calls.push( + (impl_trait_ident.clone(), method.sig.ident.clone(), impl_call) + ); + }, + _ => {}, + } + } + } + + Ok(impl_calls) +} + +fn prefix_function_with_trait(trait_: &Ident, function: &Ident) -> String { + format!("{}_{}", trait_.to_string(), function.to_string()) +} + +/// 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 impl_calls = generate_impl_calls(impls, &data)? + .into_iter() + .map(|(trait_, fn_name, impl_)| { + let name = prefix_function_with_trait(&trait_, &fn_name); + quote!( #name => Some({ #impl_ }), ) + }); + + Ok(quote!( + #[cfg(feature = "std")] + pub fn dispatch(method: &str, mut #data: &[u8]) -> Option> { + match method { + #( #impl_calls )* + _ => None, + } + } + ).into()) +} + +/// Generate the interface functions that are used to call into the runtime in wasm. +fn generate_wasm_interface(impls: &[ItemImpl]) -> Result { + let input = Ident::new("input", Span::call_site()); + let c = generate_crate_access(HIDDEN_INCLUDES_ID); + let impl_calls = generate_impl_calls(impls, &input)? + .into_iter() + .map(|(trait_, fn_name, impl_)| { + let fn_name = Ident::new( + &prefix_function_with_trait(&trait_, &fn_name), + Span::call_site() + ); + + quote!( + #[cfg(not(feature = "std"))] + #[no_mangle] + pub fn #fn_name(input_data: *mut u8, input_len: usize) -> u64 { + let mut #input = if input_len == 0 { + &[0u8; 0] + } else { + unsafe { + #c::runtime_api::slice::from_raw_parts(input_data, input_len) + } + }; + + let output = { #impl_ }; + let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); + + // Leak the output vector to avoid it being freed. + // This is fine in a WASM context since the heap + // will be discarded after the call. + #c::runtime_api::mem::forget(output); + res + } + ) + }); + + Ok(quote!( #( #impl_calls )* )) +} + +fn generate_block_and_block_id_ty( + runtime: &Type, + trait_: &'static str, + assoc_type: &'static str, +) -> (TokenStream, TokenStream) { + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + let trait_ = Ident::new(trait_, Span::call_site()); + let assoc_type = Ident::new(assoc_type, Span::call_site()); + + let block = quote!( <#runtime as #crate_::runtime_api::#trait_>::#assoc_type ); + let block_id = quote!( #crate_::runtime_api::BlockId<#block> ); + + (block, block_id) +} + +fn generate_node_block_and_block_id_ty(runtime: &Type) -> (TokenStream, TokenStream) { + generate_block_and_block_id_ty(runtime, "GetNodeBlockType", "NodeBlock") +} + +fn generate_runtime_api_base_structures(impls: &[ItemImpl]) -> Result { + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + let runtime = &impls.get(0).ok_or_else(|| + Error::new(Span::call_site(), "No api implementation given!") + )?.self_ty; + let (block, block_id) = generate_node_block_and_block_id_ty(runtime); + + Ok(quote!( + pub struct RuntimeApi {} + /// Implements all runtime apis for the client side. + #[cfg(any(feature = "std", test))] + pub struct RuntimeApiImpl + 'static> { + call: &'static C, + commit_on_success: ::std::cell::RefCell, + initialised_block: ::std::cell::RefCell>, + changes: ::std::cell::RefCell<#crate_::runtime_api::OverlayedChanges>, + } + + // `RuntimeApi` itself is not threadsafe. However, an instance is only available in a + // `ApiRef` object and `ApiRef` also has an associated lifetime. This lifetimes makes it + // impossible to move `RuntimeApi` into another thread. + #[cfg(any(feature = "std", test))] + unsafe impl> Send for RuntimeApiImpl {} + #[cfg(any(feature = "std", test))] + unsafe impl> Sync for RuntimeApiImpl {} + + #[cfg(any(feature = "std", test))] + impl> #crate_::runtime_api::ApiExt<#block> + for RuntimeApiImpl + { + fn map_api_result ::std::result::Result, R, E>( + &self, + map_call: F + ) -> ::std::result::Result where Self: Sized { + *self.commit_on_success.borrow_mut() = false; + let res = map_call(self); + *self.commit_on_success.borrow_mut() = true; + + self.commit_on_ok(&res); + + res + } + + fn has_api( + &self, + at: &#block_id + ) -> #crate_::error::Result where Self: Sized { + self.call.runtime_version_at(at).map(|r| r.has_api::()) + } + } + + #[cfg(any(feature = "std", test))] + impl + 'static> + #crate_::runtime_api::ConstructRuntimeApi<#block, C> for RuntimeApi + { + type RuntimeApi = RuntimeApiImpl; + + fn construct_runtime_api<'a>( + call: &'a C, + ) -> #crate_::runtime_api::ApiRef<'a, Self::RuntimeApi> { + RuntimeApiImpl { + call: unsafe { ::std::mem::transmute(call) }, + commit_on_success: true.into(), + initialised_block: None.into(), + changes: Default::default(), + }.into() + } + } + + #[cfg(any(feature = "std", test))] + impl> RuntimeApiImpl { + fn call_api_at< + R: #crate_::runtime_api::Encode + #crate_::runtime_api::Decode + PartialEq, + NC: FnOnce() -> R + ::std::panic::UnwindSafe, + >( + &self, + at: &#block_id, + function: &'static str, + args: Vec, + native_call: NC, + ) -> #crate_::error::Result { + let res = unsafe { + self.call.call_api_at( + at, + function, + args, + &mut *self.changes.borrow_mut(), + &mut *self.initialised_block.borrow_mut(), + Some(native_call), + ).and_then(|r| + match r { + #crate_::runtime_api::NativeOrEncoded::Native(n) => { + Ok(n) + }, + #crate_::runtime_api::NativeOrEncoded::Encoded(r) => { + R::decode(&mut &r[..]) + .ok_or_else(|| + #crate_::error::ErrorKind::CallResultDecode( + function + ).into() + ) + } + } + ) + }; + + self.commit_on_ok(&res); + res + } + + fn commit_on_ok(&self, res: &::std::result::Result) { + if *self.commit_on_success.borrow() { + if res.is_err() { + self.changes.borrow_mut().discard_prospective(); + } else { + self.changes.borrow_mut().commit_prospective(); + } + } + } + } + )) +} + +/// Extend the given trait path with module that contains the declaration of the trait for the +/// runtime. +fn extend_with_runtime_decl_path(mut trait_: Path) -> Path { + let runtime = { + let trait_name = &trait_ + .segments + .last() + .as_ref() + .expect("Trait path should always contain at least one item; qed") + .value() + .ident; + + generate_runtime_mod_name_for_trait(trait_name) + }; + + let pos = trait_.segments.len() - 1; + trait_.segments.insert(pos, runtime.clone().into()); + trait_ +} + +/// Generates the implementations of the apis for the runtime. +fn generate_api_impl_for_runtime(impls: &[ItemImpl]) -> Result { + let mut impls_prepared = Vec::new(); + + // We put `runtime` before each trait to get the trait that is intended for the runtime and + // we put the `RuntimeBlock` as first argument for the trait generics. + for impl_ in impls.iter() { + let mut impl_ = impl_.clone(); + let trait_ = extract_impl_trait(&impl_)?.clone(); + let trait_ = extend_with_runtime_decl_path(trait_); + + impl_.trait_.as_mut().unwrap().1 = trait_; + impls_prepared.push(impl_); + } + + Ok(quote!( #( #impls_prepared )* )) +} + + +/// Auxilariy data structure that is used to convert `impl Api for Runtime` to +/// `impl Api for RuntimeApi`. +/// This requires us to replace the runtime `Block` with the node `Block`, +/// `impl Api for Runtime` with `impl Api for RuntimeApi` and replace the method implementations +/// with code that calls into the runtime. +struct ApiRuntimeImplToApiRuntimeApiImpl<'a> { + node_block: &'a TokenStream, + runtime_block: &'a TypePath, + node_block_id: &'a TokenStream, + impl_trait_ident: &'a Ident, + runtime_mod_path: &'a Path, + runtime_type: &'a Type, + trait_generic_arguments: &'a [GenericArgument] +} + +impl<'a> Fold for ApiRuntimeImplToApiRuntimeApiImpl<'a> { + fn fold_type_path(&mut self, input: TypePath) -> TypePath { + let new_ty_path = if input == *self.runtime_block { + let node_block = self.node_block; + parse_quote!( #node_block ) + } else { + input + }; + + fold::fold_type_path(self, new_ty_path) + } + + fn fold_fn_decl(&mut self, input: FnDecl) -> FnDecl { + let input = fold_fn_decl_for_client_side( + input, + &self.node_block_id, + &generate_crate_access(HIDDEN_INCLUDES_ID) + ); + + fold::fold_fn_decl(self, input) + } + + fn fold_impl_item_method(&mut self, mut input: syn::ImplItemMethod) -> syn::ImplItemMethod { + let block = { + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + let mut generated_name_counter = 0; + // Replace `_` with unique patterns and collect all patterns. + let arg_names = input.sig.decl.inputs.iter_mut().filter_map(|i| match i { + FnArg::Captured(ref mut arg) => Some(&mut arg.pat), + _ => None, + }).map(|p| { + *p = generate_unique_pattern(p.clone(), &mut generated_name_counter); + p.clone() + }).collect::>(); + + let runtime_mod_path = self.runtime_mod_path; + let runtime = self.runtime_type; + let arg_names2 = arg_names.clone(); + let fn_name = prefix_function_with_trait(self.impl_trait_ident, &input.sig.ident); + let native_call_generator_ident = + generate_native_call_generator_fn_name(&input.sig.ident); + let trait_generic_arguments = self.trait_generic_arguments; + let node_block = self.node_block; + + // Generate the new method implementation that calls into the runime. + parse_quote!( + { + let args = #crate_::runtime_api::Encode::encode(&( #( &#arg_names ),* )); + self.call_api_at( + at, + #fn_name, + args, + #runtime_mod_path #native_call_generator_ident :: + <#runtime, #node_block #(, #trait_generic_arguments )*> ( + #( #arg_names2 ),* + ) + ) + } + ) + }; + + let mut input = fold::fold_impl_item_method(self, input); + // We need to set the block, after we modified the rest of the ast, otherwise we would + // modify our generated block as well. + input.block = block; + input + } + + fn fold_item_impl(&mut self, mut input: ItemImpl) -> ItemImpl { + // Implement the trait for the `RuntimeApiImpl` + input.self_ty = Box::new(parse_quote!( RuntimeApiImpl )); + + let crate_ = generate_crate_access(HIDDEN_INCLUDES_ID); + let block = self.node_block; + input.generics.params.push( + parse_quote!( RuntimeApiImplCall: #crate_::runtime_api::CallRuntimeAt<#block> + 'static ) + ); + + // The implementation for the `RuntimeApiImpl` is only required when compiling with + // the feature `std` or `test`. + input.attrs.push(parse_quote!( #[cfg(any(feature = "std", test))] )); + + fold::fold_item_impl(self, input) + } +} + +/// Generate the implementations of the runtime apis for the `RuntimeApi` type. +fn generate_api_impl_for_runtime_api(impls: &[ItemImpl]) -> Result { + let mut result = Vec::with_capacity(impls.len()); + + for impl_ in impls { + let impl_trait_path = extract_impl_trait(&impl_)?; + let impl_trait = &impl_trait_path + .segments + .last() + .ok_or_else(|| Error::new(impl_trait_path.span(), "Empty trait path not possible!"))? + .into_value(); + let impl_trait_ident = &impl_trait.ident; + let runtime_block = extract_runtime_block_ident(impl_trait_path)?; + let (node_block, node_block_id) = generate_node_block_and_block_id_ty(&impl_.self_ty); + let runtime_type = &impl_.self_ty; + let mut runtime_mod_path = extend_with_runtime_decl_path(impl_trait_path.clone()); + // remove the trait to get just the module path + runtime_mod_path.segments.pop(); + + let trait_generic_arguments = match impl_trait.arguments { + PathArguments::Parenthesized(_) | PathArguments::None => vec![], + PathArguments::AngleBracketed(ref b) => b.args.iter().cloned().collect(), + }; + + let mut visitor = ApiRuntimeImplToApiRuntimeApiImpl { + runtime_block, + node_block: &node_block, + node_block_id: &node_block_id, + impl_trait_ident: &impl_trait_ident, + runtime_mod_path: &runtime_mod_path, + runtime_type: &*runtime_type, + trait_generic_arguments: &trait_generic_arguments, + }; + + result.push(visitor.fold_item_impl(impl_.clone())); + } + + Ok(quote!( #( #result )* )) +} + +/// Generates `RUNTIME_API_VERSIONS` that holds all version information about the implemented +/// runtime apis. +fn generate_runtime_api_versions(impls: &[ItemImpl]) -> Result { + let mut result = Vec::with_capacity(impls.len()); + let mut processed_traits = HashSet::new(); + + for impl_ in impls { + let mut path = extend_with_runtime_decl_path(extract_impl_trait(&impl_)?.clone()); + // Remove the trait + let trait_ = path + .segments + .pop() + .expect("extract_impl_trait already checks that this is valid; qed") + .into_value() + .ident; + + let span = trait_.span(); + if !processed_traits.insert(trait_) { + return Err( + Error::new( + span, + "Two traits with the same name detected! \ + The trait name is used to generate its ID. \ + Please rename one trait at the declaration!" + ) + ) + } + + let id: Path = parse_quote!( #path ID ); + let version: Path = parse_quote!( #path VERSION ); + + result.push(quote!( (#id, #version) )); + } + + let c = generate_crate_access(HIDDEN_INCLUDES_ID); + + Ok(quote!( + const RUNTIME_API_VERSIONS: #c::runtime_api::ApisVec = + #c::runtime_api::create_apis_vec!([ #( #result ),* ]); + )) +} + +/// The implementation of the `impl_runtime_apis!` macro. +pub fn impl_runtime_apis_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + // Parse all impl blocks + let RuntimeApiImpls { impls: api_impls } = parse_macro_input!(input as RuntimeApiImpls); + let dispatch_impl = unwrap_or_error(generate_dispatch_function(&api_impls)); + let wasm_interface = unwrap_or_error(generate_wasm_interface(&api_impls)); + let hidden_includes = generate_hidden_includes(HIDDEN_INCLUDES_ID); + let base_runtime_api = unwrap_or_error(generate_runtime_api_base_structures(&api_impls)); + let api_impls_for_runtime = unwrap_or_error(generate_api_impl_for_runtime(&api_impls)); + let api_impls_for_runtime_api = unwrap_or_error(generate_api_impl_for_runtime_api(&api_impls)); + let runtime_api_versions = unwrap_or_error(generate_runtime_api_versions(&api_impls)); + + quote!( + #hidden_includes + + #base_runtime_api + + #api_impls_for_runtime + + #api_impls_for_runtime_api + + #runtime_api_versions + + pub mod api { + use super::*; + + #dispatch_impl + + #wasm_interface + } + ).into() +} diff --git a/core/sr-api-macros/src/lib.rs b/core/sr-api-macros/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..3dfc26c442a14094f8035f908689d740834a4ce3 --- /dev/null +++ b/core/sr-api-macros/src/lib.rs @@ -0,0 +1,190 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Macros for declaring and implementing runtime apis. + +#![recursion_limit = "256"] +extern crate proc_macro; +extern crate proc_macro2; +extern crate quote; +extern crate syn; +extern crate blake2_rfc; + +use proc_macro::TokenStream; + +mod impl_runtime_apis; +mod decl_runtime_apis; +mod utils; +mod compile_fail_tests; + +/// Tags given trait implementations as runtime apis. +/// +/// All traits given to this macro, need to be declared with the `decl_runtime_apis!` macro. +/// The implementation of the trait should follow the declaration given to the `decl_runtime_apis!` +/// macro, besides the `Block` type that is required as first generic parameter for each runtime +/// api trait. When implementing a runtime api trait, it is required that the trait is referenced +/// by a path, e.g. `impl my_trait::MyTrait for Runtime`. The macro will use this path to access +/// the declaration of the trait for the runtime side. +/// +/// The macro also generates the api implementations for the client side and provides it through +/// the `RuntimeApi` type. The `RuntimeApi` is hidden behind a `feature` called `std`. +/// +/// To expose version information about all implemented api traits, the constant +/// `RUNTIME_API_VERSIONS` is generated. This constant should be used to instantiate the `apis` +/// field of `RuntimeVersion`. +/// +/// # Example +/// +/// ```rust +/// #[macro_use] +/// extern crate substrate_client; +/// extern crate sr_version as version; +/// +/// use version::create_runtime_str; +/// # extern crate substrate_test_client as test_client; +/// # extern crate sr_primitives as runtime_primitives; +/// # extern crate substrate_primitives as primitives; +/// # +/// # use runtime_primitives::traits::GetNodeBlockType; +/// # use test_client::runtime::Block; +/// # +/// # /// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` +/// # /// trait are done by the `construct_runtime!` macro in a real runtime. +/// # struct Runtime {} +/// # impl GetNodeBlockType for Runtime { +/// # type NodeBlock = Block; +/// # } +/// # +/// # decl_runtime_apis! { +/// # /// Declare the api trait. +/// # pub trait Balance { +/// # /// Get the balance. +/// # fn get_balance() -> u64; +/// # /// Set the balance. +/// # fn set_balance(val: u64); +/// # } +/// # pub trait BlockBuilder { +/// # fn build_block() -> Block; +/// # } +/// # } +/// +/// /// All runtime api implementations need to be done in one call of the macro! +/// impl_runtime_apis! { +/// impl self::Balance for Runtime { +/// fn get_balance() -> u64 { +/// 1 +/// } +/// fn set_balance(_bal: u64) { +/// // Store the balance +/// } +/// } +/// +/// impl self::BlockBuilder for Runtime { +/// fn build_block() -> Block { +/// unimplemented!("Please implement me!") +/// } +/// } +/// } +/// +/// /// Runtime version. This needs to be declared for each runtime. +/// pub const VERSION: version::RuntimeVersion = version::RuntimeVersion { +/// spec_name: create_runtime_str!("node"), +/// impl_name: create_runtime_str!("test-node"), +/// authoring_version: 1, +/// spec_version: 1, +/// impl_version: 0, +/// // Here we are exposing the runtime api versions. +/// apis: RUNTIME_API_VERSIONS, +/// }; +/// +/// # fn main() {} +/// ``` +#[proc_macro] +pub fn impl_runtime_apis(input: TokenStream) -> TokenStream { + impl_runtime_apis::impl_runtime_apis_impl(input) +} + +/// Declares given traits as runtime apis. +/// +/// The macro will create two declarations, one for using on the client side and one for using +/// on the runtime side. The declaration for the runtime side is hidden in its own module. +/// The client side declaration gets two extra parameters per function, +/// `&self` and `at: &BlockId`. The runtime side declaration will match the given trait +/// declaration. Besides one exception, the macro adds an extra generic parameter `Block: BlockT` +/// to the client side and the runtime side. This generic parameter is usable by the user. +/// +/// For implementing these macros you should use the `impl_runtime_apis!` macro. +/// +/// # Example +/// +/// ```rust +/// #[macro_use] +/// extern crate substrate_client; +/// +/// decl_runtime_apis! { +/// /// Declare the api trait. +/// pub trait Balance { +/// /// Get the balance. +/// fn get_balance() -> u64; +/// /// Set the balance. +/// fn set_balance(val: u64); +/// } +/// +/// /// You can declare multiple api traits in one macro call. +/// /// In one module you can call the macro at maximum one time. +/// pub trait BlockBuilder { +/// /// The macro adds an explicit `Block: BlockT` generic parameter for you. +/// /// You can use this generic parameter as you would defined it manually. +/// fn build_block() -> Block; +/// } +/// } +/// +/// # fn main() {} +/// ``` +/// +/// # Runtime api trait versioning +/// +/// To support versioning of the traits, the macro supports the attribute `#[api_version(1)]`. +/// The attribute supports any `u32` as version. By default, each trait is at version `1`, if no +/// version is provided. +/// +/// ```rust +/// #[macro_use] +/// extern crate substrate_client; +/// +/// decl_runtime_apis! { +/// /// Declare the api trait. +/// #[api_version(2)] +/// pub trait Balance { +/// /// Get the balance. +/// fn get_balance() -> u64; +/// /// Set the balance. +/// fn set_balance(val: u64); +/// /// In version 2, we added this new function. +/// fn increase_balance(val: u64); +/// } +/// } +/// +/// # fn main() {} +/// ``` +/// +/// To check if a given runtime implements a runtime api trait, the `RuntimeVersion` has the +/// function `has_api()`. Also the `ApiExt` provides a function `has_api(at: &BlockId)` to +/// check if the runtime at the given block id implements the requested runtime api trait. +#[proc_macro] +pub fn decl_runtime_apis(input: TokenStream) -> TokenStream { + decl_runtime_apis::decl_runtime_apis_impl(input) +} diff --git a/core/sr-api-macros/src/utils.rs b/core/sr-api-macros/src/utils.rs new file mode 100644 index 0000000000000000000000000000000000000000..e35ed520842990e4cbb6e51803d36c16a6e26d71 --- /dev/null +++ b/core/sr-api-macros/src/utils.rs @@ -0,0 +1,142 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 proc_macro2::{TokenStream, Span}; +use syn::{Result, Ident, FnDecl, parse_quote, Type, Pat, spanned::Spanned, FnArg, Error}; +use quote::quote; +use std::env; + +/// Unwrap the given result, if it is an error, `compile_error!` will be generated. +pub fn unwrap_or_error(res: Result) -> TokenStream { + res.unwrap_or_else(|e| e.to_compile_error()) +} + +fn generate_hidden_includes_mod_name(unique_id: &'static str) -> Ident { + Ident::new(&format!("sr_api_hidden_includes_{}", unique_id), Span::call_site()) +} + +/// Generates the hidden includes that are required to make the macro independent from its scope. +pub fn generate_hidden_includes(unique_id: &'static str) -> TokenStream { + if env::var("CARGO_PKG_NAME").unwrap() == "substrate-client" { + TokenStream::new() + } else { + let mod_name = generate_hidden_includes_mod_name(unique_id); + quote!( + #[doc(hidden)] + mod #mod_name { + pub extern crate substrate_client as sr_api_client; + } + ) + }.into() +} + +/// Generates the access to the `subtrate_client` crate. +pub fn generate_crate_access(unique_id: &'static str) -> TokenStream { + if env::var("CARGO_PKG_NAME").unwrap() == "substrate-client" { + quote!( crate ) + } else { + let mod_name = generate_hidden_includes_mod_name(unique_id); + quote!( self::#mod_name::sr_api_client ) + }.into() +} + +/// Generates the name of the module that contains the trait declaration for the runtime. +pub fn generate_runtime_mod_name_for_trait(trait_: &Ident) -> Ident { + Ident::new(&format!("runtime_decl_for_{}", trait_.to_string()), Span::call_site()) +} + +/// Fold the given `FnDecl` to make it usable on the client side. +pub fn fold_fn_decl_for_client_side( + mut input: FnDecl, + block_id: &TokenStream, + crate_: &TokenStream +) -> FnDecl { + // Add `&self, at:& BlockId` as parameters to each function at the beginning. + input.inputs.insert(0, parse_quote!( at: &#block_id )); + input.inputs.insert(0, parse_quote!( &self )); + + // Wrap the output in a `Result` + input.output = { + let generate_result = |ty: &Type| { + parse_quote!( -> ::std::result::Result<#ty, #crate_::error::Error> ) + }; + + match &input.output { + syn::ReturnType::Default => generate_result(&parse_quote!( () )), + syn::ReturnType::Type(_, ref ty) => generate_result(&ty), + } + }; + + input +} + +/// Generate an unique pattern based on the given counter, if the given pattern is a `_`. +pub fn generate_unique_pattern(pat: Pat, counter: &mut u32) -> Pat { + match pat { + Pat::Wild(_) => { + let generated_name = Ident::new( + &format!("runtime_api_generated_name_{}", counter), + pat.span() + ); + *counter += 1; + + parse_quote!( #generated_name ) + }, + _ => pat, + } +} + +/// Extracts the name, the type and `&` or ``(if it is a reference or not) +/// for each parameter in the given function declaration. +pub fn extract_parameter_names_types_and_borrows(fn_decl: &FnDecl) + -> Result> +{ + let mut result = Vec::new(); + let mut generated_pattern_counter = 0; + for input in fn_decl.inputs.iter() { + match input { + FnArg::Captured(arg) => { + let (ty, borrow) = match &arg.ty { + Type::Reference(t) => { + let ty = &t.elem; + (parse_quote!( #ty ), quote!( & )) + }, + t => { (t.clone(), quote!()) }, + }; + + let name = + generate_unique_pattern(arg.pat.clone(), &mut generated_pattern_counter); + result.push((name, ty, borrow)); + }, + _ => { + return Err( + Error::new( + input.span(), + "Only function arguments with the following \ + pattern are accepted: `name: type`!" + ) + ) + } + } + } + + Ok(result) +} + +/// Generates the name for the native call generator function. +pub fn generate_native_call_generator_fn_name(fn_name: &Ident) -> Ident { + Ident::new(&format!("{}_native_call_generator", fn_name.to_string()), Span::call_site()) +} diff --git a/core/sr-api-macros/tests/decl_and_impl.rs b/core/sr-api-macros/tests/decl_and_impl.rs new file mode 100644 index 0000000000000000000000000000000000000000..1d87a152018a20e15b3a3a22d54b3d2f4048b564 --- /dev/null +++ b/core/sr-api-macros/tests/decl_and_impl.rs @@ -0,0 +1,111 @@ +#[macro_use] +extern crate substrate_client as client; +extern crate sr_primitives as runtime_primitives; +extern crate substrate_primitives as primitives; +extern crate substrate_test_client as test_client; + +use runtime_primitives::traits::{GetNodeBlockType, Block as BlockT, AuthorityIdFor}; +use runtime_primitives::generic::BlockId; +use client::runtime_api::{self, RuntimeApiInfo}; +use client::error::Result; +use test_client::runtime::Block; + +/// The declaration of the `Runtime` type and the implementation of the `GetNodeBlockType` +/// trait are done by the `construct_runtime!` macro in a real runtime. +pub struct Runtime {} +impl GetNodeBlockType for Runtime { + type NodeBlock = Block; +} + +decl_runtime_apis! { + pub trait Api { + fn test(data: u64); + fn something_with_block(block: Block) -> Block; + fn function_with_two_args(data: u64, block: Block); + fn same_name(); + } + + #[api_version(2)] + pub trait ApiWithCustomVersion { + fn same_name(); + } +} + +impl_runtime_apis! { + impl self::Api for Runtime { + fn test(_: u64) { + unimplemented!() + } + + fn something_with_block(_: Block) -> Block { + unimplemented!() + } + + fn function_with_two_args(_: u64, _: Block) { + unimplemented!() + } + + fn same_name() {} + } + + impl self::ApiWithCustomVersion for Runtime { + fn same_name() {} + } + + impl runtime_api::Core for Runtime { + fn version() -> runtime_api::RuntimeVersion { + unimplemented!() + } + fn authorities() -> Vec> { + unimplemented!() + } + fn execute_block(_: Block) { + unimplemented!() + } + fn initialise_block(_: &::Header) { + unimplemented!() + } + } +} + +type TestClient = client::Client; + +#[test] +fn test_client_side_function_signature() { + let _test: fn(&RuntimeApiImpl, &BlockId, u64) -> Result<()> = + RuntimeApiImpl::::test; + let _something_with_block: + fn(&RuntimeApiImpl, &BlockId, Block) -> Result = + RuntimeApiImpl::::something_with_block; +} + +#[test] +fn test_runtime_side_function_signature() { + let _api_same_name: fn(input_data: *mut u8, input_len: usize) -> u64 = api::Api_same_name; + let _api_with_version_same_name: fn(input_data: *mut u8, input_len: usize) -> u64 = + api::ApiWithCustomVersion_same_name; +} + +#[test] +fn check_runtime_api_info() { + assert_eq!(&Api::::ID, &runtime_decl_for_Api::ID); + assert_eq!(Api::::VERSION, runtime_decl_for_Api::VERSION); + assert_eq!(Api::::VERSION, 1); + + assert_eq!( + ApiWithCustomVersion::::VERSION, runtime_decl_for_ApiWithCustomVersion::VERSION + ); + assert_eq!(&ApiWithCustomVersion::::ID, &runtime_decl_for_ApiWithCustomVersion::ID); + assert_eq!(ApiWithCustomVersion::::VERSION, 2); +} + +fn check_runtime_api_versions_contains() { + assert!(RUNTIME_API_VERSIONS.iter().any(|v| v == &(T::ID, T::VERSION))); +} + +#[test] +fn check_runtime_api_versions() { + check_runtime_api_versions_contains::>(); + check_runtime_api_versions_contains::>(); + check_runtime_api_versions_contains::>(); +} diff --git a/core/sr-api/Cargo.toml b/core/sr-api/Cargo.toml deleted file mode 100644 index 2877dfa9195565e895f79162b9c6dc6ff01dc1c2..0000000000000000000000000000000000000000 --- a/core/sr-api/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "sr-api" -version = "0.1.0" -authors = ["Parity Technologies "] - -[dependencies] -parity-codec = { version = "2.1", default-features = false } -sr-std = { path = "../sr-std", default-features = false } -sr-primitives = { path = "../sr-primitives", default-features = false } -sr-version = { path = "../sr-version", default-features = false } - -[features] -default = ["std"] -std = [ - "sr-std/std", - "parity-codec/std", - "sr-primitives/std", - "sr-version/std", -] diff --git a/core/sr-api/README.adoc b/core/sr-api/README.adoc deleted file mode 100644 index debd87e8ebddd4e47449271ae54c7b3c65b41269..0000000000000000000000000000000000000000 --- a/core/sr-api/README.adoc +++ /dev/null @@ -1,12 +0,0 @@ -= Runtime API - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/sr-api/src/lib.rs b/core/sr-api/src/lib.rs deleted file mode 100644 index 7fffc43590c78049cca3489c236338d90c6e022b..0000000000000000000000000000000000000000 --- a/core/sr-api/src/lib.rs +++ /dev/null @@ -1,655 +0,0 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -// tag::description[] -//! API's for interfacing with the runtime via native/wasm. -// end::description[] - -#![cfg_attr(not(feature = "std"), no_std)] - -extern crate sr_std as rstd; -extern crate sr_primitives as primitives; -#[doc(hidden)] -pub extern crate parity_codec as codec; -extern crate sr_version as runtime_version; - -#[doc(hidden)] -pub use primitives::{traits::Block as BlockT, generic::BlockId, transaction_validity::TransactionValidity, ApplyResult}; -use runtime_version::{ApiId, RuntimeVersion}; -use rstd::vec::Vec; -#[doc(hidden)] -pub use rstd::slice; -#[doc(hidden)] -pub use codec::{Encode, Decode}; - -/// Declare the given API traits. -/// -/// # Example: -/// -/// ```nocompile -/// decl_apis!{ -/// pub trait Test ExtraClientSide { -/// fn test(event: Event) -> AccountId; -/// -/// /// A function that will have the extra parameter `param` on the client side, -/// /// the runtime does not have any parameter. -/// fn testWithExtraParams() ExtraClientSide(param: &Self::ClientArg); -/// } -/// } -/// ``` -/// -/// Will result in the following declaration: -/// -/// ```nocompile -/// mod runtime { -/// pub trait Test { -/// fn test(event: Event) -> AccountId; -/// } -/// } -/// -/// pub trait Test { -/// type Error; -/// type ClientArg; -/// fn test(&self, at: &BlockId, event: Event) -> Result; -/// fn testWithExtraParams(&self, at: &BlockId, param: &Client) -> Result; -/// } -/// ``` -/// -/// The declarations generated in the `runtime` module will be used by `impl_apis!` for implementing -/// the traits for a runtime. The other declarations should be used for implementing the interface -/// in the client. -#[macro_export] -macro_rules! decl_apis { - ( - $( - $( #[$attr:meta] )* - pub trait $name:ident $(< $( $generic_param:ident $( : $generic_bound:ident )* ),* >)* - $( ExtraClientSide < $( $client_generic_param:ident $( : $client_generic_bound:ident )* ),+ > )* - { - $( - $( #[$fn_attr:meta] )* - fn $fn_name:ident $( < $( $fn_generic:ident ),* > )* ( - $( $param_name:ident : $param_type:ty ),* - ) - $( ExtraClientSide ( $( $client_param_name:ident : $client_param_type:ty ),+ ) )* - $( -> $return_ty:ty)*; - )* - } - )* - ) => { - $( - decl_apis!( - @ADD_BLOCK_GENERIC - $( #[$attr] )* - pub trait $name $(< $( $generic_param $( : $generic_bound )* ),* >)* { - $( $( type $client_generic_param $( : $client_generic_bound )*; )* )* - $( - $( #[$fn_attr] )* - fn $fn_name $( < $( $fn_generic ),* > )* ( - $( $( $client_param_name: $client_param_type, )* )* - $( $param_name : &$param_type, )* - ) $( -> $return_ty )*; - )* - }; - ; - ; - $( $( $generic_param $( : $generic_bound )* ),* )* - ); - )* - decl_apis! { - @GENERATE_RUNTIME_TRAITS - $( - $( #[$attr] )* - pub trait $name $(< $( $generic_param $( : $generic_bound )* ),* >)* { - $( - $( #[$fn_attr] )* - fn $fn_name $( < $( $fn_generic ),* > )* ($( $param_name : $param_type )* ) $( -> $return_ty )*; - )* - }; - )* - } - }; - (@ADD_BLOCK_GENERIC - $( #[$attr:meta] )* - pub trait $name:ident $(< $( $generic_param_orig:ident $( : $generic_bound_orig:ident )* ),* >)* { - $( type $client_generic_param:ident $( : $client_generic_bound:ident )*; )* - $( - $( #[$fn_attr:meta] )* - fn $fn_name:ident $( < $( $fn_generic:ident ),* > )* ( - $( $param_name:ident : $param_type:ty, )* - ) $( -> $return_ty:ty)*; - )* - }; - ; - $( $generic_param_parsed:ident $( : $generic_bound_parsed:ident )* ),*; - Block: BlockT - $(, $generic_param_rest:ident $( : $generic_bound_rest:ident )* )* - ) => { - decl_apis!( - @ADD_BLOCK_GENERIC - $( #[$attr] )* - pub trait $name $(< $( $generic_param_orig $( : $generic_bound_orig )* ),* >)* { - $( type $client_generic_param $( : $client_generic_bound )*; )* - $( - $( #[$fn_attr] )* - fn $fn_name $( < $( $fn_generic ),* > )* ( - $( $param_name : $param_type, )* - ) $( -> $return_ty )*; - )* - }; - Found; - $( $generic_param_parsed $( : $generic_bound_parsed )* , )* Block: $crate::BlockT; - $( $generic_param_rest $( : $generic_bound_rest )* ),* - ); - }; - (@ADD_BLOCK_GENERIC - $( #[$attr:meta] )* - pub trait $name:ident $(< $( $generic_param_orig:ident $( : $generic_bound_orig:ident )* ),* >)* { - $( type $client_generic_param:ident $( : $client_generic_bound:ident )*; )* - $( - $( #[$fn_attr:meta] )* - fn $fn_name:ident $( < $( $fn_generic:ident ),* > )* ( - $( $param_name:ident : $param_type:ty, )* - ) $( -> $return_ty:ty )*; - )* - }; - $( $block_found:ident )*; - $( $generic_param_parsed:ident $( : $generic_bound_parsed:path )* ),*; - $generic_param:ident $( : $generic_bound:ident )* - $(, $generic_param_rest:ident $( : $generic_bound_rest:ident )* )* - ) => { - decl_apis!( - @ADD_BLOCK_GENERIC - $( #[$attr] )* - pub trait $name $(< $( $generic_param_orig $( : $generic_bound_orig )* ),* >)* { - $( type $client_generic_param $( : $client_generic_bound )*; )* - $( - $( #[$fn_attr] )* - fn $fn_name $( < $( $fn_generic ),* > )* ( - $( $param_name : $param_type, )* - ) $( -> $return_ty )*; - )* - }; - $( $block_found )*; - $( $generic_param_parsed $( : $generic_bound_parsed )* , )* $generic_param $( : $generic_bound )*; - $( $generic_param_rest $( : $generic_bound_rest )* ),* - ); - }; - (@ADD_BLOCK_GENERIC - $( #[$attr:meta] )* - pub trait $name:ident $(< $( $generic_param_orig:ident $( : $generic_bound_orig:ident )* ),* >)* { - $( type $client_generic_param:ident $( : $client_generic_bound:ident )*; )* - $( - $( #[$fn_attr:meta] )* - fn $fn_name:ident $( < $( $fn_generic:ident ),* > )* ( - $( $param_name:ident : $param_type:ty, )* - ) $( -> $return_ty:ty )*; - )* - }; - Found; - $( $generic_param_parsed:ident $( : $generic_bound_parsed:path )* ),*; - ) => { - decl_apis!( - @GENERATE_RETURN_TYPES - $( #[$attr] )* - pub trait $name $(< $( $generic_param_orig $( : $generic_bound_orig )* ),* >)* { - $( type $client_generic_param $( : $client_generic_bound )*; )* - $( - $( #[$fn_attr] )* - fn $fn_name $( < $( $fn_generic ),* > )* ( - $( $param_name : $param_type, )* - ) $( -> $return_ty )*; - )* - }; - $( $generic_param_parsed $( : $generic_bound_parsed )* ),*; - {}; - $( $( $return_ty )*; )* - ); - }; - (@ADD_BLOCK_GENERIC - $( #[$attr:meta] )* - pub trait $name:ident $(< $( $generic_param_orig:ident $( : $generic_bound_orig:ident )* ),* >)* { - $( type $client_generic_param:ident $( : $client_generic_bound:ident )*; )* - $( - $( #[$fn_attr:meta] )* - fn $fn_name:ident $( < $( $fn_generic:ident ),* > )* ( - $( $param_name:ident : $param_type:ty, )* - ) $( -> $return_ty:ty )*; - )* - }; - ; - $( $generic_param_parsed:ident $( : $generic_bound_parsed:ident )* ),*; - ) => { - decl_apis!( - @GENERATE_RETURN_TYPES - $( #[$attr] )* - pub trait $name $(< $( $generic_param_orig $( : $generic_bound_orig )* ),* >)* { - $( type $client_generic_param $( : $client_generic_bound )*; )* - $( - $( #[$fn_attr] )* - fn $fn_name $( < $( $fn_generic ),* > )* ( - $( $param_name : $param_type, )* - ) $( -> $return_ty )*; - )* - }; - // We need to add the required generic Block parameter - Block: $crate::BlockT $(, $generic_param_parsed $( : $generic_bound_parsed )* )*; - {}; - $( $( $return_ty )*; )* - ); - }; - (@GENERATE_RETURN_TYPES - $( #[$attr:meta] )* - pub trait $name:ident $(< $( $generic_param_orig:ident $( : $generic_bound_orig:ident )* ),* >)* { - $( type $client_generic_param:ident $( : $client_generic_bound:ident )*; )* - $( - $( #[$fn_attr:meta] )* - fn $fn_name:ident $( < $( $fn_generic:ident ),* > )* ( - $( $param_name:ident : $param_type:ty, )* - ) $( -> $return_ty:ty)*; - )* - }; - $( $generic_param_parsed:ident $( : $generic_bound_parsed:path )* ),*; - { $( $result_return_ty:ty; )* }; - $return_ty_current:ty; - $( $( $return_ty_rest:ty )*; )* - ) => { - decl_apis!( - @GENERATE_RETURN_TYPES - $( #[$attr] )* - pub trait $name $(< $( $generic_param_orig $( : $generic_bound_orig )* ),* >)* { - $( type $client_generic_param $( : $client_generic_bound )*; )* - $( - $( #[$fn_attr] )* - fn $fn_name $( < $( $fn_generic ),* > )* ( - $( $param_name : $param_type, )* - ) $( -> $return_ty )*; - )* - }; - $( $generic_param_parsed $( : $generic_bound_parsed )* ),*; - { $( $result_return_ty; )* Result<$return_ty_current, Self::Error>; }; - $( $( $return_ty_rest )*; )* - ); - }; - (@GENERATE_RETURN_TYPES - $( #[$attr:meta] )* - pub trait $name:ident $(< $( $generic_param_orig:ident $( : $generic_bound_orig:ident )* ),* >)* { - $( type $client_generic_param:ident $( : $client_generic_bound:ident )*; )* - $( - $( #[$fn_attr:meta] )* - fn $fn_name:ident $( < $( $fn_generic:ident ),* > )* ( - $( $param_name:ident : $param_type:ty, )* - ) $( -> $return_ty:ty)*; - )* - }; - $( $generic_param_parsed:ident $( : $generic_bound_parsed:path )* ),*; - { $( $result_return_ty:ty; )* }; - ; - $( $( $return_ty_rest:ty )*; )* - ) => { - decl_apis!( - @GENERATE_RETURN_TYPES - $( #[$attr] )* - pub trait $name $(< $( $generic_param_orig $( : $generic_bound_orig )* ),* >)* { - $( type $client_generic_param $( : $client_generic_bound )*; )* - $( - $( #[$fn_attr] )* - fn $fn_name $( < $( $fn_generic ),* > )* ( - $( $param_name : $param_type, )* - ) $( -> $return_ty )*; - )* - }; - $( $generic_param_parsed $( : $generic_bound_parsed )* ),*; - { $( $result_return_ty; )* Result<(), Self::Error>; }; - $( $( $return_ty_rest )*; )* - ); - }; - (@GENERATE_RETURN_TYPES - $( #[$attr:meta] )* - pub trait $name:ident $(< $( $generic_param_orig:ident $( : $generic_bound_orig:ident )* ),* >)* { - $( type $client_generic_param:ident $( : $client_generic_bound:ident )*; )* - $( - $( #[$fn_attr:meta] )* - fn $fn_name:ident $( < $( $fn_generic:ident ),* > )* ( - $( $param_name:ident : $param_type:ty, )* - ) $( -> $return_ty:ty)*; - )* - }; - $( $generic_param_parsed:ident $( : $generic_bound_parsed:path )* ),*; - { $( $result_return_ty:ty; )* }; - ) => { - decl_apis!( - @GENERATE_CLIENT_TRAITS - $( #[$attr] )* - pub trait $name $(< $( $generic_param_orig $( : $generic_bound_orig )* ),* >)* { - $( type $client_generic_param $( : $client_generic_bound )*; )* - $( - $( #[$fn_attr] )* - fn $fn_name $( < $( $fn_generic ),* > )* ( - $( $param_name : $param_type, )* - ) $( -> $return_ty )*; - )* - }; - $( $generic_param_parsed $( : $generic_bound_parsed )* ),*; - { $( $result_return_ty; )* }; - ); - }; - (@GENERATE_CLIENT_TRAITS - $( #[$attr:meta] )* - pub trait $name:ident $(< $( $generic_param_orig:ident $( : $generic_bound_orig:ident )* ),* >)* { - $( type $client_generic_param:ident $( : $client_generic_bound:ident )*; )* - $( - $( #[$fn_attr:meta] )* - fn $fn_name:ident $( < $( $fn_generic:ident ),* > )* ( - $( $param_name:ident : $param_type:ty, )* - ) $( -> $return_ty:ty)*; - )* - }; - $( $generic_param_parsed:ident $( : $generic_bound_parsed:path )* ),*; - { $( $result_return_ty:ty; )* }; - ) => { - $( #[$attr] )* - pub trait $name < $( $generic_param_parsed $( : $generic_bound_parsed )* ),* > { - /// The Error type returned by this API. - type Error; - $( type $client_generic_param $( : $client_generic_bound )*; )* - - $( - $( #[$fn_attr] )* - fn $fn_name $( < $( $fn_generic: $crate::Encode + $crate::Decode ),* > )* ( - &self, at: &$crate::BlockId $(, $param_name: $param_type )* - ) -> $result_return_ty; - )* - } - }; - (@GENERATE_RUNTIME_TRAITS - $( - $( #[$attr:meta] )* - pub trait $name:ident $(< $( $generic_param:ident $( : $generic_bound:ident )* ),* >)* { - $( - $( #[$fn_attr:meta] )* - fn $fn_name:ident $( < $( $fn_generic:ident ),* > )* ( - $( $param_name:ident : $param_type:ty )* - ) $( -> $return_ty:ty)*; - )* - }; - )* - ) => { - decl_apis! { - @GENERATE_RUNTIME_TRAITS_WITH_JOINED_GENERICS - $( - $( #[$attr] )* - pub trait $name < $( $( $generic_param $( : $generic_bound )*, )* )* $( $( $( $fn_generic, )* )* )* > { - $( - $( #[$fn_attr] )* - fn $fn_name ($( $param_name: $param_type ),*) $( -> $return_ty )*; - )* - } - )* - } - }; - (@GENERATE_RUNTIME_TRAITS_WITH_JOINED_GENERICS - $( - $( #[$attr:meta] )* - pub trait $name:ident < $( $generic_param:ident $( : $generic_bound:ident )*, )* > { - $( - $( #[$fn_attr:meta] )* - fn $fn_name:ident($( $param_name:ident : $param_type:ty ),*) $( -> $return_ty:ty)*; - )* - } - )* - ) => { - /// The API traits to implement on the runtime side. - pub mod runtime { - use super::*; - - $( - $( #[$attr] )* - pub trait $name < $( $generic_param $( : $generic_bound )* ),* > { - $( - $( #[$fn_attr] )* - fn $fn_name ($( $param_name: $param_type ),*) $( -> $return_ty )*; - )* - } - )* - } - }; -} - -/// The ApiIds for the various standard runtime APIs. -pub mod id { - use super::ApiId; - - /// ApiId for the BlockBuilder trait. - pub const BLOCK_BUILDER: ApiId = *b"blkbuild"; - - /// ApiId for the TaggedTransactionQueue trait. - pub const TAGGED_TRANSACTION_QUEUE: ApiId = *b"validatx"; - - /// ApiId for the Metadata trait. - pub const METADATA: ApiId = *b"metadata"; -} - -decl_apis! { - /// The `Core` api trait that is mandantory for each runtime. - pub trait Core { - fn version() -> RuntimeVersion; - fn authorities() -> Vec; - fn execute_block(block: Block); - } - - /// The `Metadata` api trait that returns metadata for the runtime. - pub trait Metadata { - fn metadata() -> Data; - } - - /// The `OldTxQueue` api trait for interfering with the old transaction queue. - pub trait OldTxQueue { - fn account_nonce(account: AccountId) -> Index; - fn lookup_address(address: Address) -> Option; - } - - /// The `TaggedTransactionQueue` api trait for interfering with the new transaction queue. - pub trait TaggedTransactionQueue { - fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity; - } - - /// The `BlockBuilder` api trait that provides required functions for building a block for a runtime. - pub trait BlockBuilder ExtraClientSide { - /// Initialise a block with the given header. - fn initialise_block(header: ::Header) ExtraClientSide(changes: &mut Self::OverlayedChanges); - /// Apply the given extrinsics. - fn apply_extrinsic(extrinsic: ::Extrinsic) ExtraClientSide(changes: &mut Self::OverlayedChanges) -> ApplyResult; - /// Finish the current block. - fn finalise_block() ExtraClientSide(changes: &mut Self::OverlayedChanges) -> ::Header; - /// Generate inherent extrinsics. - fn inherent_extrinsics(inherent: InherentExtrinsic) -> Vec; - /// Check that the inherents are valid. - fn check_inherents(block: Block, data: InherentData) -> Result<(), Error>; - /// Generate a random seed. - fn random_seed() -> ::Hash; - } -} - -/// Implement the given API's for the given runtime. -/// All desired API's need to be implemented in one `impl_apis!` call. -/// Besides generating the implementation for the runtime, there will be also generated an -/// auxiliary module named `api` that contains function for inferring with the API in native/wasm. -/// It is important to use the traits from the `runtime` module with this macro. -/// -/// # Example: -/// -/// ```nocompile -/// #[macro_use] -/// extern crate sr_api as runtime_api; -/// -/// use runtime_api::runtime::{Core, TaggedTransactionQueue}; -/// -/// impl_apis! { -/// impl Core for Runtime { -/// fn version() -> RuntimeVersion { 1 } -/// fn authorities() -> Vec { vec![1] } -/// fn execute_block(block: Block) { -/// //comment -/// let block = call_arbitrary_code(block); -/// execute(block); -/// } -/// } -/// -/// impl TaggedTransactionQueue for Runtime { -/// fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity { -/// unimplemented!() -/// } -/// } -/// } -/// -/// fn main() {} -/// ``` -#[macro_export] -macro_rules! impl_apis { - ( - impl $trait_name:ident $( < $( $generic:ident ),* > )* for $runtime:ident { - $( - fn $fn_name:ident ( $( $arg_name:ident : $arg_ty:ty ),* ) $( -> $return_ty:ty )* { - $( $impl:tt )* - } - )* - } - $( $rest:tt )* - ) => { - impl $trait_name $( < $( $generic ),* > )* for $runtime { - $( - fn $fn_name ( $( $arg_name : $arg_ty ),* ) $( -> $return_ty )* { - $( $impl )* - } - )* - } - impl_apis! { - $runtime; - $( $fn_name ( $( $arg_name: $arg_ty ),* ); )*; - $( $rest )* - } - }; - ( - $runtime:ident; - $( $fn_name_parsed:ident ( $( $arg_name_parsed:ident : $arg_ty_parsed:ty ),* ); )*; - impl $trait_name:ident $( < $( $generic:ident ),* > )* for $runtime_ignore:ident { - $( - fn $fn_name:ident ( $( $arg_name:ident : $arg_ty:ty ),* ) $( -> $return_ty:ty )* { - $( $impl:tt )* - } - )* - } - $( $rest:tt )* - ) => { - impl $trait_name $( < $( $generic ),* > )* for $runtime { - $( - fn $fn_name ( $( $arg_name : $arg_ty ),* ) $( -> $return_ty )* { - $( $impl )* - } - )* - } - impl_apis! { - $runtime; - $( $fn_name_parsed ( $( $arg_name_parsed: $arg_ty_parsed ),* ); )* - $( $fn_name ( $( $arg_name: $arg_ty ),* ); )*; - $( $rest )* - } - }; - ( - $runtime:ident; - $( $fn_name:ident ( $( $arg_name:ident : $arg_ty:ty ),* ); )*; - ) => { - pub mod api { - use super::*; - - #[cfg(feature = "std")] - pub fn dispatch(method: &str, mut data: &[u8]) -> Option> { - match method { - $( - stringify!($fn_name) => { - Some({impl_apis! { - @GENERATE_IMPL_CALL - $runtime; - $fn_name; - $( $arg_name : $arg_ty ),*; - data; - }}) - } - )* - _ => None, - } - } - - $( - #[cfg(not(feature = "std"))] - #[no_mangle] - pub fn $fn_name(input_data: *mut u8, input_len: usize) -> u64 { - let mut input = if input_len == 0 { - &[0u8; 0] - } else { - unsafe { - $crate::slice::from_raw_parts(input_data, input_len) - } - }; - - let output = { impl_apis! { - @GENERATE_IMPL_CALL - $runtime; - $fn_name; - $( $arg_name : $arg_ty ),*; - input; - } }; - let res = output.as_ptr() as u64 + ((output.len() as u64) << 32); - - // Leak the output vector to avoid it being freed. - // This is fine in a WASM context since the heap - // will be discarded after the call. - ::core::mem::forget(output); - res - } - )* - } - }; - (@GENERATE_IMPL_CALL - $runtime:ident; - $fn_name:ident; - $arg_name:ident : $arg_ty:ty; - $input:ident; - ) => { - let $arg_name : $arg_ty = match $crate::codec::Decode::decode(&mut $input) { - Some(input) => input, - None => panic!("Bad input data provided to {}", stringify!($fn_name)), - }; - - let output = $runtime::$fn_name($arg_name); - $crate::codec::Encode::encode(&output) - }; - (@GENERATE_IMPL_CALL - $runtime:ident; - $fn_name:ident; - $( $arg_name:ident : $arg_ty:ty ),*; - $input:ident; - ) => { - let ( $( $arg_name ),* ) : ($( $arg_ty ),*) = match $crate::codec::Decode::decode(&mut $input) { - Some(input) => input, - None => panic!("Bad input data provided to {}", stringify!($fn_name)), - }; - - let output = $runtime::$fn_name($( $arg_name ),*); - $crate::codec::Encode::encode(&output) - }; -} diff --git a/core/sr-io/Cargo.toml b/core/sr-io/Cargo.toml index 39e62e7a2035d4e9041849b81b500a81ac4d4293..cf07a1acd68bdb7a9985c6b3f047edb9b11f3ca5 100644 --- a/core/sr-io/Cargo.toml +++ b/core/sr-io/Cargo.toml @@ -10,8 +10,8 @@ rustc_version = "0.2" [dependencies] sr-std = { path = "../sr-std", default-features = false } substrate-primitives = { path = "../primitives", default-features = false } -parity-codec = { version = "2.1", default-features = false } -hash-db = { git = "https://github.com/paritytech/trie", default-features = false } +parity-codec = { version = "2.2", default-features = false } +hash-db = { version = "0.9", default-features = false } environmental = { version = "~1.0", optional = true } substrate-state-machine = { path = "../state-machine", optional = true } diff --git a/core/sr-io/README.adoc b/core/sr-io/README.adoc deleted file mode 100644 index c035be146118832be0e2f4d5c65f28c1ecee7ef0..0000000000000000000000000000000000000000 --- a/core/sr-io/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Runtime io - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/sr-io/src/lib.rs b/core/sr-io/src/lib.rs index 12e09945d2704ba78a812230986fe1ce7dae43e2..3394265a847b55f8f6cd3fab0889f54b859197b0 100644 --- a/core/sr-io/src/lib.rs +++ b/core/sr-io/src/lib.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! This is part of the Substrate runtime. -// end::description[] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(lang_items))] diff --git a/core/sr-io/with_std.rs b/core/sr-io/with_std.rs index 72fa107469853f86eb9384264478a514ca5b14e8..a608a632fe136aeb2520d2361628d548bfcb9462 100644 --- a/core/sr-io/with_std.rs +++ b/core/sr-io/with_std.rs @@ -157,9 +157,9 @@ pub fn child_storage_root(storage_key: &[u8]) -> Option> { } /// "Commit" all existing operations and get the resultant storage change root. -pub fn storage_changes_root(block: u64) -> Option { +pub fn storage_changes_root(parent_hash: [u8; 32], parent_num: u64) -> Option { ext::with(|ext| - ext.storage_changes_root(block) + ext.storage_changes_root(parent_hash.into(), parent_num) ).unwrap_or(None) } diff --git a/core/sr-io/without_std.rs b/core/sr-io/without_std.rs index 5b892ecffe6bb7d61745b5eb467593024b91b366..c1bee278000e6f64d668fb25827f350db80ce625 100644 --- a/core/sr-io/without_std.rs +++ b/core/sr-io/without_std.rs @@ -53,11 +53,23 @@ pub extern fn oom(_: ::core::alloc::Layout) -> ! { } } +/// Host functions, provided by the executor. +/// A WebAssembly runtime module would "import" these to access the execution environment +/// (most importantly, storage) or perform heavy hash calculations. +/// See also "ext_" functions in sr-sandbox and sr-std extern "C" { + /// Most of the functions below return fixed-size arrays (e.g. hashes) by writing them into + /// memory regions that should be preallocated by module. + /// Functions that return variable-sized data use host-side allocations. These should be + /// manually freed by the module. fn ext_free(addr: *mut u8); + + /// Printing, useful for debugging fn ext_print_utf8(utf8_data: *const u8, utf8_len: u32); fn ext_print_hex(data: *const u8, len: u32); fn ext_print_num(value: u64); + + /// Host storage access and verification fn ext_set_storage(key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); fn ext_set_child_storage(storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, key_len: u32, value_data: *const u8, value_len: u32); fn ext_clear_storage(key_data: *const u8, key_len: u32); @@ -66,18 +78,26 @@ extern "C" { fn ext_exists_child_storage(storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, key_len: u32) -> u32; fn ext_clear_prefix(prefix_data: *const u8, prefix_len: u32); fn ext_kill_child_storage(storage_key_data: *const u8, storage_key_len: u32); + /// Host-side result allocation fn ext_get_allocated_storage(key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; + /// Host-side result allocation fn ext_get_allocated_child_storage(storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, key_len: u32, written_out: *mut u32) -> *mut u8; fn ext_get_storage_into(key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32; fn ext_get_child_storage_into(storage_key_data: *const u8, storage_key_len: u32, key_data: *const u8, key_len: u32, value_data: *mut u8, value_len: u32, value_offset: u32) -> u32; fn ext_storage_root(result: *mut u8); - fn ext_child_storage_root(storage_key_data: *const u8, storage_key_len: u32, written_out: *mut u32) -> *mut u8; - fn ext_storage_changes_root(block: u64, result: *mut u8) -> u32; - fn ext_blake2_256_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8); + /// Host-side result allocation + fn ext_child_storage_root(storage_key_data: *const u8, storage_key_len: u32, written_out: *mut u32) -> *mut u8; + fn ext_storage_changes_root(parent_hash_data: *const u8, parent_hash_len: u32, parent_num: u64, result: *mut u8) -> u32; + + /// The current relay chain identifier. fn ext_chain_id() -> u64; + + /// Hash calculation and verification + fn ext_blake2_256_enumerated_trie_root(values_data: *const u8, lens_data: *const u32, lens_len: u32, result: *mut u8); fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8); fn ext_twox_128(data: *const u8, len: u32, out: *mut u8); fn ext_twox_256(data: *const u8, len: u32, out: *mut u8); + /// Note: ext_ed25519_verify returns 0 if the signature is correct, nonzero otherwise. fn ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32; } @@ -112,9 +132,10 @@ pub fn storage(key: &[u8]) -> Option> { if length == u32::max_value() { None } else { - let ret = slice::from_raw_parts(ptr, length as usize).to_vec(); - ext_free(ptr); - Some(ret) + // Invariants required by Vec::from_raw_parts are not formally fulfilled. + // We don't allocate via String/Vec, but use a custom allocator instead. + // See #300 for more details. + Some(>::from_raw_parts(ptr, length as usize, length as usize)) } } } @@ -127,9 +148,10 @@ pub fn child_storage(storage_key: &[u8], key: &[u8]) -> Option> { if length == u32::max_value() { None } else { - let ret = slice::from_raw_parts(ptr, length as usize).to_vec(); - ext_free(ptr); - Some(ret) + // Invariants required by Vec::from_raw_parts are not formally fulfilled. + // We don't allocate via String/Vec, but use a custom allocator instead. + // See #300 for more details. + Some(>::from_raw_parts(ptr, length as usize, length as usize)) } } } @@ -261,18 +283,19 @@ pub fn child_storage_root(storage_key: &[u8]) -> Option> { if length == u32::max_value() { None } else { - let ret = slice::from_raw_parts(ptr, length as usize).to_vec(); - ext_free(ptr); - Some(ret) + // Invariants required by Vec::from_raw_parts are not formally fulfilled. + // We don't allocate via String/Vec, but use a custom allocator instead. + // See #300 for more details. + Some(>::from_raw_parts(ptr, length as usize, length as usize)) } } } /// The current storage' changes root. -pub fn storage_changes_root(block: u64) -> Option<[u8; 32]> { +pub fn storage_changes_root(parent_hash: [u8; 32], parent_num: u64) -> Option<[u8; 32]> { let mut result: [u8; 32] = Default::default(); let is_set = unsafe { - ext_storage_changes_root(block, result.as_mut_ptr()) + ext_storage_changes_root(parent_hash.as_ptr(), parent_hash.len() as u32, parent_num, result.as_mut_ptr()) }; if is_set != 0 { diff --git a/core/sr-primitives/Cargo.toml b/core/sr-primitives/Cargo.toml index 9dc3988681af32ed781f9b4c231136d5a743118e..81fb8eddff4fe0267e0f98de7117fefa6229868d 100644 --- a/core/sr-primitives/Cargo.toml +++ b/core/sr-primitives/Cargo.toml @@ -8,7 +8,7 @@ num-traits = { version = "0.2", default-features = false } integer-sqrt = { version = "0.1.2" } serde = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-primitives = { path = "../primitives", default-features = false } sr-std = { path = "../sr-std", default-features = false } diff --git a/core/sr-primitives/README.adoc b/core/sr-primitives/README.adoc deleted file mode 100644 index 0e9d6361112734dc4430a9dac3a1fa1fde5e3f0a..0000000000000000000000000000000000000000 --- a/core/sr-primitives/README.adoc +++ /dev/null @@ -1,12 +0,0 @@ -= Runtime Primitives - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/sr-primitives/src/generic/block.rs b/core/sr-primitives/src/generic/block.rs index 6cbb7929d8b24edc583e98f1978dfdd124536f5f..390bd22af59955dacd08544a8522c04bbc6ff890 100644 --- a/core/sr-primitives/src/generic/block.rs +++ b/core/sr-primitives/src/generic/block.rs @@ -21,7 +21,7 @@ use std::fmt; use rstd::prelude::*; use codec::Codec; -use traits::{self, Member, Block as BlockT, Header as HeaderT}; +use traits::{self, Member, Block as BlockT, Header as HeaderT, MaybeSerialize}; use ::Justification; /// Something to identify a block. @@ -59,17 +59,17 @@ impl fmt::Display for BlockId { /// Abstraction over a substrate block. #[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[cfg_attr(feature = "std", derive(Debug, Serialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] -pub struct Block { +pub struct Block { /// The block header. pub header: Header, /// The accompanying extrinsics. pub extrinsics: Vec, } -impl traits::Block for Block +impl traits::Block for Block where Header: HeaderT, Extrinsic: Member + Codec + traits::Extrinsic, @@ -94,12 +94,12 @@ where /// Abstraction over a substrate block and justification. #[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[cfg_attr(feature = "std", derive(Debug, Serialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] -pub struct SignedBlock { +pub struct SignedBlock { /// Full block. - pub block: Block, + pub block: Block, /// Block justification. - pub justification: Justification, + pub justification: Option, } diff --git a/core/sr-primitives/src/generic/checked_extrinsic.rs b/core/sr-primitives/src/generic/checked_extrinsic.rs index e69ce7733673e0543de4be7600a2b303901f43a5..749577cdd6c3b91110447a5872dd81a5cd4fdd71 100644 --- a/core/sr-primitives/src/generic/checked_extrinsic.rs +++ b/core/sr-primitives/src/generic/checked_extrinsic.rs @@ -23,7 +23,7 @@ use traits::{self, Member, SimpleArithmetic, MaybeDisplay}; /// existence implies that it has been checked and is good, particularly with /// regards to the signature. #[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +#[cfg_attr(feature = "std", derive(Debug))] pub struct CheckedExtrinsic { /// Who this purports to be from and the number of extrinsics have come before /// from the same signer, if anyone (note this is not a signature). @@ -37,7 +37,7 @@ impl traits::Applyable where AccountId: Member + MaybeDisplay, Index: Member + MaybeDisplay + SimpleArithmetic, - Call: Member + Call: Member, { type Index = Index; type AccountId = AccountId; diff --git a/core/sr-primitives/src/generic/digest.rs b/core/sr-primitives/src/generic/digest.rs index 41ffd6da0d179667da3fd10e1ae236bd0e0a978d..5d6aba3ab6120b4d14a93206bad5b126cbedf0de 100644 --- a/core/sr-primitives/src/generic/digest.rs +++ b/core/sr-primitives/src/generic/digest.rs @@ -19,12 +19,12 @@ use rstd::prelude::*; use codec::{Decode, Encode, Codec, Input}; -use traits::{self, Member, DigestItem as DigestItemT}; +use traits::{self, Member, DigestItem as DigestItemT, MaybeHash}; use substrate_primitives::hash::H512 as Signature; #[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[cfg_attr(feature = "std", derive(Debug, Serialize))] pub struct Digest { pub logs: Vec, } @@ -57,7 +57,7 @@ impl traits::Digest for Digest where /// Digest item that is able to encode/decode 'system' digest items and /// provide opaque access to other items. #[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[cfg_attr(feature = "std", derive(Debug))] pub enum DigestItem { /// System digest item announcing that authorities set has been changed /// in the block. Contains the new set of authorities. @@ -72,6 +72,15 @@ pub enum DigestItem { Other(Vec), } +#[cfg(feature = "std")] +impl ::serde::Serialize for DigestItem { + fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { + self.using_encoded(|bytes| { + ::substrate_primitives::bytes::serialize(bytes, seq) + }) + } +} + /// A 'referencing view' for digest item. Does not own its contents. Used by /// final runtime implementations for encoding/decoding its log items. @@ -122,7 +131,10 @@ impl DigestItem { } } -impl traits::DigestItem for DigestItem { +impl< + Hash: Codec + Member, + AuthorityId: Codec + Member + MaybeHash, +> traits::DigestItem for DigestItem { type Hash = Hash; type AuthorityId = AuthorityId; @@ -130,7 +142,7 @@ impl traits::DigestItem for D self.dref().as_authorities_change() } - fn as_changes_trie_root(&self) -> Option<&Hash> { + fn as_changes_trie_root(&self) -> Option<&Self::Hash> { self.dref().as_changes_trie_root() } } @@ -204,3 +216,25 @@ impl<'a, Hash: Encode, AuthorityId: Encode> Encode for DigestItemRef<'a, Hash, A v } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn should_serialize_digest() { + let digest = Digest { + logs: vec![ + DigestItem::AuthoritiesChange(vec![1]), + DigestItem::ChangesTrieRoot(4), + DigestItem::Seal(1, 15.into()), + DigestItem::Other(vec![1, 2, 3]), + ], + }; + + assert_eq!( + ::serde_json::to_string(&digest).unwrap(), + r#"{"logs":["0x010401000000","0x0204000000","0x0301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f","0x000c010203"]}"# + ); + } +} diff --git a/core/sr-primitives/src/generic/era.rs b/core/sr-primitives/src/generic/era.rs index 71ee8fa145431f657ae4257d2f869068c8d84883..bccee778be203986d9072125b0a860e837380572 100644 --- a/core/sr-primitives/src/generic/era.rs +++ b/core/sr-primitives/src/generic/era.rs @@ -61,7 +61,7 @@ impl Era { Era::Mortal(period, quantized_phase) } - /// Create an "immortal" transaction. + /// Create an "immortal" transaction. pub fn immortal() -> Self { Era::Immortal } @@ -75,7 +75,7 @@ impl Era { } /// Get the block number of the start of the era whose properties this object - /// describes that `current` belongs to. + /// describes that `current` belongs to. pub fn birth(self, current: u64) -> u64 { match self { Era::Immortal => 0, @@ -189,10 +189,10 @@ mod tests { assert_ne!(e.birth(10), 6); assert_ne!(e.birth(5), 6); } - + #[test] fn current_less_than_phase() { // should not panic Era::mortal(4, 3).birth(1); } -} \ No newline at end of file +} diff --git a/core/sr-primitives/src/generic/header.rs b/core/sr-primitives/src/generic/header.rs index fc6f73b5cf1b28a568477b4d8cd3296c0fbbadb6..863dc5a6a860f9598c9725f36d96bdec9ebe7b9b 100644 --- a/core/sr-primitives/src/generic/header.rs +++ b/core/sr-primitives/src/generic/header.rs @@ -16,12 +16,9 @@ //! Generic implementation of a block header. -#[cfg(feature = "std")] -use serde::{Deserialize, Deserializer}; - use codec::{Decode, Encode, Codec, Input, Output, HasCompact}; use traits::{self, Member, SimpleArithmetic, SimpleBitOps, MaybeDisplay, - Hash as HashT, DigestItem as DigestItemT}; + Hash as HashT, DigestItem as DigestItemT, MaybeSerializeDebug, MaybeSerializeDebugButNotDeserialize}; use generic::Digest; /// Abstraction over a block header for a substrate chain. @@ -29,10 +26,11 @@ use generic::Digest; #[cfg_attr(feature = "std", derive(Debug, Serialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] -pub struct Header { +pub struct Header, Hash: HashT, DigestItem> { /// The parent hash. pub parent_hash: ::Output, /// The block number. + #[cfg_attr(feature = "std", serde(serialize_with = "serialize_number"))] pub number: Number, /// The state trie merkle root pub state_root: ::Output, @@ -42,47 +40,17 @@ pub struct Header { pub digest: Digest, } -// Hack to work around the fact that deriving deserialize doesn't work nicely with -// the `hashing` trait used as a parameter. -// dummy struct that uses the hash type directly. -// https://github.com/serde-rs/serde/issues/1296 -#[cfg(feature = "std")] -#[serde(rename_all = "camelCase")] -#[derive(Deserialize)] -struct DeserializeHeader { - parent_hash: H, - number: N, - state_root: H, - extrinsics_root: H, - digest: Digest, -} - -#[cfg(feature = "std")] -impl From> for Header { - fn from(other: DeserializeHeader) -> Self { - Header { - parent_hash: other.parent_hash, - number: other.number, - state_root: other.state_root, - extrinsics_root: other.extrinsics_root, - digest: other.digest, - } - } -} - #[cfg(feature = "std")] -impl<'a, Number: 'a, Hash: 'a + HashT, DigestItem: 'a> Deserialize<'a> for Header where - Number: Deserialize<'a>, - Hash::Output: Deserialize<'a>, - DigestItem: Deserialize<'a>, -{ - fn deserialize>(de: D) -> Result { - DeserializeHeader::::deserialize(de).map(Into::into) - } +pub fn serialize_number>(val: &T, s: S) -> Result where S: ::serde::Serializer { + use substrate_primitives::uint::U256; + let v: u128 = (*val).into(); + let lower = U256::from(v as u64); + let upper = U256::from(v.rotate_left(64) as u64) << 64; + ::serde::Serialize::serialize(&(upper + lower), s) } impl Decode for Header where - Number: HasCompact, + Number: HasCompact + Copy + Into, Hash: HashT, Hash::Output: Decode, DigestItem: DigestItemT + Decode, @@ -99,7 +67,7 @@ impl Decode for Header where } impl Encode for Header where - Number: HasCompact + Copy, + Number: HasCompact + Copy + Into, Hash: HashT, Hash::Output: Encode, DigestItem: DigestItemT + Encode, @@ -114,11 +82,11 @@ impl Encode for Header where } impl traits::Header for Header where - Number: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec, + Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + MaybeDisplay + SimpleArithmetic + Codec + Copy + Into, Hash: HashT, DigestItem: DigestItemT + Codec, - Hash::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec, - { + Hash::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeSerializeDebugButNotDeserialize + MaybeDisplay + SimpleBitOps + Codec, +{ type Number = Number; type Hash = ::Output; type Hashing = Hash; @@ -158,7 +126,7 @@ impl traits::Header for Header Header where - Number: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec, + Number: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec + Into, Hash: HashT, DigestItem: DigestItemT + Codec, Hash::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec, @@ -169,3 +137,26 @@ impl Header where Hash::hash_of(self) } } + +#[cfg(all(test, feature = "std"))] +mod tests { + use super::*; + + #[test] + fn should_serialize_numbers() { + fn serialize(num: u128) -> String { + let mut v = vec![]; + { + let mut ser = ::serde_json::Serializer::new(::std::io::Cursor::new(&mut v)); + serialize_number(&num, &mut ser).unwrap(); + } + String::from_utf8(v).unwrap() + } + + assert_eq!(serialize(0), "\"0x0\"".to_owned()); + assert_eq!(serialize(1), "\"0x1\"".to_owned()); + assert_eq!(serialize(u64::max_value() as u128), "\"0xffffffffffffffff\"".to_owned()); + assert_eq!(serialize(u64::max_value() as u128 + 1), "\"0x10000000000000000\"".to_owned()); + } + +} diff --git a/core/sr-primitives/src/generic/mod.rs b/core/sr-primitives/src/generic/mod.rs index 69b317f6eeade4a83ea682b85773b80f0eef8d31..1e1778204ab16cf38e1a611c9b6f082663e02c0f 100644 --- a/core/sr-primitives/src/generic/mod.rs +++ b/core/sr-primitives/src/generic/mod.rs @@ -20,6 +20,7 @@ mod unchecked_extrinsic; mod unchecked_mortal_extrinsic; +mod unchecked_mortal_compact_extrinsic; mod era; mod checked_extrinsic; mod header; @@ -30,6 +31,7 @@ mod tests; pub use self::unchecked_extrinsic::UncheckedExtrinsic; pub use self::unchecked_mortal_extrinsic::UncheckedMortalExtrinsic; +pub use self::unchecked_mortal_compact_extrinsic::UncheckedMortalCompactExtrinsic; pub use self::era::Era; pub use self::checked_extrinsic::CheckedExtrinsic; pub use self::header::Header; diff --git a/core/sr-primitives/src/generic/tests.rs b/core/sr-primitives/src/generic/tests.rs index c095a2b45dc4cef70b3d4b52bf6777bc91c290d0..76896106170ea5eb5a88f65a22473f00778023ed 100644 --- a/core/sr-primitives/src/generic/tests.rs +++ b/core/sr-primitives/src/generic/tests.rs @@ -17,56 +17,8 @@ //! Tests for the generic implementations of Extrinsic/Header/Block. use codec::{Decode, Encode}; -use substrate_primitives::{H256, H512}; -use super::{Digest, Header, DigestItem, UncheckedExtrinsic}; - -type Block = super::Block< - Header>, - UncheckedExtrinsic, ->; - -#[test] -fn block_roundtrip_serialization() { - let block: Block = Block { - header: Header { - parent_hash: [0u8; 32].into(), - number: 100_000, - state_root: [1u8; 32].into(), - extrinsics_root: [2u8; 32].into(), - digest: Digest { logs: vec![ - DigestItem::Other::(vec![1, 2, 3]), - DigestItem::Other::(vec![4, 5, 6]), - ] }, - }, - extrinsics: vec![ - UncheckedExtrinsic::new_signed( - 0, - 100, - [255u8; 32].into(), - H512::from([0u8; 64]).into() - ), - UncheckedExtrinsic::new_signed( - 100, - 99, - [128u8; 32].into(), - H512::from([255u8; 64]).into() - ) - ] - }; - - { - let encoded = ::serde_json::to_vec(&block).unwrap(); - let decoded: Block = ::serde_json::from_slice(&encoded).unwrap(); - - assert_eq!(block, decoded); - } - { - let encoded = block.encode(); - let decoded = Block::decode(&mut &encoded[..]).unwrap(); - - assert_eq!(block, decoded); - } -} +use substrate_primitives::H256; +use super::DigestItem; #[test] fn system_digest_item_encoding() { diff --git a/core/sr-primitives/src/generic/unchecked_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_extrinsic.rs index a37affd9ca312a677e0f0775e563fc0ce5b81779..0cde5f42a3f22cc6028f2dbfd5ba73515b09d108 100644 --- a/core/sr-primitives/src/generic/unchecked_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_extrinsic.rs @@ -21,11 +21,10 @@ use std::fmt; use rstd::prelude::*; use codec::{Decode, Encode, Codec, Input, HasCompact}; -use traits::{self, Member, SimpleArithmetic, MaybeDisplay, Lookup}; +use traits::{self, Member, SimpleArithmetic, MaybeDisplay, Lookup, Extrinsic}; use super::CheckedExtrinsic; #[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct SignatureContent where Address: Codec, @@ -40,7 +39,6 @@ where /// A extrinsic right from the external world. This is unchecked and so /// can contain a signature. #[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct UncheckedExtrinsic where Address: Codec, @@ -75,11 +73,6 @@ where function, } } - - /// `true` if there is a signature. - pub fn is_signed(&self) -> bool { - self.signature.is_some() - } } impl traits::Checkable @@ -115,6 +108,17 @@ where } } +impl< + Address: Codec, + Index: HasCompact + Codec, + Signature: Codec, + Call, +> Extrinsic for UncheckedExtrinsic { + fn is_signed(&self) -> Option { + Some(self.signature.is_some()) + } +} + impl Decode for UncheckedExtrinsic { @@ -143,6 +147,15 @@ impl } } +#[cfg(feature = "std")] +impl serde::Serialize + for UncheckedExtrinsic +{ + fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { + self.using_encoded(|bytes| ::substrate_primitives::bytes::serialize(bytes, seq)) + } +} + /// TODO: use derive when possible. #[cfg(feature = "std")] impl fmt::Debug @@ -173,4 +186,14 @@ mod test { let as_vec: Vec = Decode::decode(&mut encoded.as_slice()).unwrap(); assert_eq!(as_vec.encode(), encoded); } + + + #[test] + #[cfg(feature = "std")] + fn serialization_of_unchecked_extrinsics() { + type Extrinsic = UncheckedExtrinsic; + let ex = Extrinsic::new_unsigned(42); + + assert_eq!(serde_json::to_string(&ex).unwrap(), "\"0x14002a000000\""); + } } diff --git a/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs new file mode 100644 index 0000000000000000000000000000000000000000..9ffac3d3f9a6cb4f1cdf7943b831386cf915801b --- /dev/null +++ b/core/sr-primitives/src/generic/unchecked_mortal_compact_extrinsic.rs @@ -0,0 +1,290 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Generic implementation of an unchecked (pre-verification) extrinsic. + +#[cfg(feature = "std")] +use std::fmt; + +use rstd::prelude::*; +use codec::{Decode, Encode, Input, Compact}; +use traits::{self, Member, SimpleArithmetic, MaybeDisplay, CurrentHeight, BlockNumberToHash, Lookup, + Checkable, Extrinsic}; +use super::{CheckedExtrinsic, Era}; + +const TRANSACTION_VERSION: u8 = 1; + +/// A extrinsic right from the external world. This is unchecked and so +/// can contain a signature. +#[derive(PartialEq, Eq, Clone)] +pub struct UncheckedMortalCompactExtrinsic { + /// The signature, address, number of extrinsics have come before from + /// the same signer and an era describing the longevity of this transaction, + /// if this is a signed extrinsic. + pub signature: Option<(Address, Signature, Compact, Era)>, + /// The function that should be called. + pub function: Call, +} + +impl UncheckedMortalCompactExtrinsic { + /// New instance of a signed extrinsic aka "transaction". + pub fn new_signed(index: Index, function: Call, signed: Address, signature: Signature, era: Era) -> Self { + UncheckedMortalCompactExtrinsic { + signature: Some((signed, signature, index.into(), era)), + function, + } + } + + /// New instance of an unsigned extrinsic aka "inherent". + pub fn new_unsigned(function: Call) -> Self { + UncheckedMortalCompactExtrinsic { + signature: None, + function, + } + } +} + +impl Extrinsic for UncheckedMortalCompactExtrinsic { + fn is_signed(&self) -> Option { + Some(self.signature.is_some()) + } +} + +impl Checkable + for UncheckedMortalCompactExtrinsic +where + Address: Member + MaybeDisplay, + Index: Member + MaybeDisplay + SimpleArithmetic, + Compact: Encode, + Call: Encode + Member, + Signature: Member + traits::Verify, + AccountId: Member + MaybeDisplay, + BlockNumber: SimpleArithmetic, + Hash: Encode, + Context: Lookup + + CurrentHeight + + BlockNumberToHash, +{ + type Checked = CheckedExtrinsic; + + fn check(self, context: &Context) -> Result { + Ok(match self.signature { + Some((signed, signature, index, era)) => { + let h = context.block_number_to_hash(BlockNumber::sa(era.birth(context.current_height().as_()))) + .ok_or("transaction birth block ancient")?; + let payload = (index, self.function, era, h); + let signed = context.lookup(signed)?; + if !::verify_encoded_lazy(&signature, &payload, &signed) { + return Err("bad signature in extrinsic") + } + CheckedExtrinsic { + signed: Some((signed, (payload.0).0)), + function: payload.1, + } + } + None => CheckedExtrinsic { + signed: None, + function: self.function, + }, + }) + } +} + +impl Decode + for UncheckedMortalCompactExtrinsic +where + Address: Decode, + Signature: Decode, + Compact: Decode, + Call: Decode, +{ + fn decode(input: &mut I) -> Option { + // This is a little more complicated than usual since the binary format must be compatible + // with substrate's generic `Vec` type. Basically this just means accepting that there + // will be a prefix of vector length (we don't need + // to use this). + let _length_do_not_remove_me_see_above: Vec<()> = Decode::decode(input)?; + + let version = input.read_byte()?; + + let is_signed = version & 0b1000_0000 != 0; + let version = version & 0b0111_1111; + if version != TRANSACTION_VERSION { + return None + } + + Some(UncheckedMortalCompactExtrinsic { + signature: if is_signed { Some(Decode::decode(input)?) } else { None }, + function: Decode::decode(input)?, + }) + } +} + +impl Encode + for UncheckedMortalCompactExtrinsic +where + Address: Encode, + Signature: Encode, + Compact: Encode, + Call: Encode, +{ + fn encode(&self) -> Vec { + super::encode_with_vec_prefix::(|v| { + // 1 byte version id. + match self.signature.as_ref() { + Some(s) => { + v.push(TRANSACTION_VERSION | 0b1000_0000); + s.encode_to(v); + } + None => { + v.push(TRANSACTION_VERSION & 0b0111_1111); + } + } + self.function.encode_to(v); + }) + } +} + +#[cfg(feature = "std")] +impl serde::Serialize + for UncheckedMortalCompactExtrinsic + where Compact: Encode +{ + fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { + self.using_encoded(|bytes| seq.serialize_bytes(bytes)) + } +} + +/// TODO: use derive when possible. +#[cfg(feature = "std")] +impl fmt::Debug for UncheckedMortalCompactExtrinsic where + Address: fmt::Debug, + Index: fmt::Debug, + Call: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "UncheckedMortalCompactExtrinsic({:?}, {:?})", self.signature.as_ref().map(|x| (&x.0, &x.2)), self.function) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + struct TestContext; + impl Lookup for TestContext { + type Source = u64; + type Target = u64; + fn lookup(&self, s: u64) -> Result { Ok(s) } + } + impl CurrentHeight for TestContext { + type BlockNumber = u64; + fn current_height(&self) -> u64 { 42 } + } + impl BlockNumberToHash for TestContext { + type BlockNumber = u64; + type Hash = u64; + fn block_number_to_hash(&self, n: u64) -> Option { Some(n) } + } + + #[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize, Encode, Decode)] + struct TestSig(u64, Vec); + impl traits::Verify for TestSig { + type Signer = u64; + fn verify>(&self, mut msg: L, signer: &Self::Signer) -> bool { + *signer == self.0 && msg.get() == &self.1[..] + } + } + + const DUMMY_FUNCTION: u64 = 0; + const DUMMY_ACCOUNTID: u64 = 0; + + type Ex = UncheckedMortalCompactExtrinsic; + type CEx = CheckedExtrinsic; + + #[test] + fn unsigned_codec_should_work() { + let ux = Ex::new_unsigned(DUMMY_FUNCTION); + let encoded = ux.encode(); + assert_eq!(Ex::decode(&mut &encoded[..]), Some(ux)); + } + + #[test] + fn signed_codec_should_work() { + let ux = Ex::new_signed(0, DUMMY_FUNCTION, DUMMY_ACCOUNTID, TestSig(DUMMY_ACCOUNTID, (DUMMY_ACCOUNTID, DUMMY_FUNCTION, Era::immortal(), 0u64).encode()), Era::immortal()); + let encoded = ux.encode(); + assert_eq!(Ex::decode(&mut &encoded[..]), Some(ux)); + } + + #[test] + fn unsigned_check_should_work() { + let ux = Ex::new_unsigned(DUMMY_FUNCTION); + assert!(!ux.is_signed().unwrap_or(false)); + assert!(>::check(ux, &TestContext).is_ok()); + } + + #[test] + fn badly_signed_check_should_fail() { + let ux = Ex::new_signed(0, DUMMY_FUNCTION, DUMMY_ACCOUNTID, TestSig(DUMMY_ACCOUNTID, vec![0u8]), Era::immortal()); + assert!(ux.is_signed().unwrap_or(false)); + assert_eq!(>::check(ux, &TestContext), Err("bad signature in extrinsic")); + } + + #[test] + fn immortal_signed_check_should_work() { + let ux = Ex::new_signed(0, DUMMY_FUNCTION, DUMMY_ACCOUNTID, TestSig(DUMMY_ACCOUNTID, (Compact::from(DUMMY_ACCOUNTID), DUMMY_FUNCTION, Era::immortal(), 0u64).encode()), Era::immortal()); + assert!(ux.is_signed().unwrap_or(false)); + assert_eq!(>::check(ux, &TestContext), Ok(CEx { signed: Some((DUMMY_ACCOUNTID, 0)), function: DUMMY_FUNCTION })); + } + + #[test] + fn mortal_signed_check_should_work() { + let ux = Ex::new_signed(0, DUMMY_FUNCTION, DUMMY_ACCOUNTID, TestSig(DUMMY_ACCOUNTID, (Compact::from(DUMMY_ACCOUNTID), DUMMY_FUNCTION, Era::mortal(32, 42), 42u64).encode()), Era::mortal(32, 42)); + assert!(ux.is_signed().unwrap_or(false)); + assert_eq!(>::check(ux, &TestContext), Ok(CEx { signed: Some((DUMMY_ACCOUNTID, 0)), function: DUMMY_FUNCTION })); + } + + #[test] + fn later_mortal_signed_check_should_work() { + let ux = Ex::new_signed(0, DUMMY_FUNCTION, DUMMY_ACCOUNTID, TestSig(DUMMY_ACCOUNTID, (Compact::from(DUMMY_ACCOUNTID), DUMMY_FUNCTION, Era::mortal(32, 11), 11u64).encode()), Era::mortal(32, 11)); + assert!(ux.is_signed().unwrap_or(false)); + assert_eq!(>::check(ux, &TestContext), Ok(CEx { signed: Some((DUMMY_ACCOUNTID, 0)), function: DUMMY_FUNCTION })); + } + + #[test] + fn too_late_mortal_signed_check_should_fail() { + let ux = Ex::new_signed(0, DUMMY_FUNCTION, DUMMY_ACCOUNTID, TestSig(DUMMY_ACCOUNTID, (DUMMY_ACCOUNTID, DUMMY_FUNCTION, Era::mortal(32, 10), 10u64).encode()), Era::mortal(32, 10)); + assert!(ux.is_signed().unwrap_or(false)); + assert_eq!(>::check(ux, &TestContext), Err("bad signature in extrinsic")); + } + + #[test] + fn too_early_mortal_signed_check_should_fail() { + let ux = Ex::new_signed(0, DUMMY_FUNCTION, DUMMY_ACCOUNTID, TestSig(DUMMY_ACCOUNTID, (DUMMY_ACCOUNTID, DUMMY_FUNCTION, Era::mortal(32, 43), 43u64).encode()), Era::mortal(32, 43)); + assert!(ux.is_signed().unwrap_or(false)); + assert_eq!(>::check(ux, &TestContext), Err("bad signature in extrinsic")); + } + + #[test] + fn encoding_matches_vec() { + let ex = Ex::new_unsigned(DUMMY_FUNCTION); + let encoded = ex.encode(); + let decoded = Ex::decode(&mut encoded.as_slice()).unwrap(); + assert_eq!(decoded, ex); + let as_vec: Vec = Decode::decode(&mut encoded.as_slice()).unwrap(); + assert_eq!(as_vec.encode(), encoded); + } +} diff --git a/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs b/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs index 5d91556d8ccfc95ef916da83ae55c007e13fb73a..e15a37c3bf01d852ad363908677d1d1cc4199bfd 100644 --- a/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs +++ b/core/sr-primitives/src/generic/unchecked_mortal_extrinsic.rs @@ -30,7 +30,6 @@ const TRANSACTION_VERSION: u8 = 1; /// A extrinsic right from the external world. This is unchecked and so /// can contain a signature. #[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct UncheckedMortalExtrinsic { /// The signature, address, number of extrinsics have come before from /// the same signer and an era describing the longevity of this transaction, @@ -58,7 +57,7 @@ impl UncheckedMortalExtrinsic Extrinsic for UncheckedMortalExtrinsic { +impl Extrinsic for UncheckedMortalExtrinsic { fn is_signed(&self) -> Option { Some(self.signature.is_some()) } @@ -158,6 +157,15 @@ where } } +#[cfg(feature = "std")] +impl serde::Serialize + for UncheckedMortalExtrinsic +{ + fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { + self.using_encoded(|bytes| seq.serialize_bytes(bytes)) + } +} + /// TODO: use derive when possible. #[cfg(feature = "std")] impl fmt::Debug for UncheckedMortalExtrinsic where diff --git a/core/sr-primitives/src/lib.rs b/core/sr-primitives/src/lib.rs index a8759a489069c2a7814ae6fdf0d022f480971492..01ef2f171f0c4c5ee36d47138c829bb23d06af15 100644 --- a/core/sr-primitives/src/lib.rs +++ b/core/sr-primitives/src/lib.rs @@ -14,10 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! System manager: Handles all of the top-level stuff; executing block/transaction, setting code //! and depositing logs. -// end::description[] #![cfg_attr(not(feature = "std"), no_std)] @@ -66,11 +64,23 @@ pub type Justification = Vec; use traits::{Verify, Lazy}; -/// A String that is a `&'static str` on `no_std` and a `String` on `std`. +/// A String that is a `&'static str` on `no_std` and a `Cow<'static, str>` on `std`. +#[cfg(feature = "std")] +pub type RuntimeString = ::std::borrow::Cow<'static, str>; #[cfg(not(feature = "std"))] pub type RuntimeString = &'static str; + +/// Create a const [RuntimeString]. #[cfg(feature = "std")] -pub type RuntimeString = ::std::borrow::Cow<'static, str>; +#[macro_export] +macro_rules! create_runtime_str { + ( $y:expr ) => {{ ::std::borrow::Cow::Borrowed($y) }} +} +#[cfg(not(feature = "std"))] +#[macro_export] +macro_rules! create_runtime_str { + ( $y:expr ) => {{ $y }} +} #[cfg(feature = "std")] pub use serde::{Serialize, de::DeserializeOwned}; @@ -135,6 +145,22 @@ impl From for Permill { } } +impl codec::CompactAs for Permill { + type As = u32; + fn encode_as(&self) -> &u32 { + &self.0 + } + fn decode_from(x: u32) -> Permill { + Permill(x) + } +} + +impl From> for Permill { + fn from(x: codec::Compact) -> Permill { + x.0 + } +} + /// Perbill is parts-per-billion. It stores a value between 0 and 1 in fixed point and /// provides a means to multiply some other value by that. #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] @@ -190,6 +216,22 @@ impl From for Perbill { } } +impl codec::CompactAs for Perbill { + type As = u32; + fn encode_as(&self) -> &u32 { + &self.0 + } + fn decode_from(x: u32) -> Perbill { + Perbill(x) + } +} + +impl From> for Perbill { + fn from(x: codec::Compact) -> Perbill { + x.0 + } +} + /// Ed25519 signature verify. #[derive(Eq, PartialEq, Clone, Default, Encode, Decode)] #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] @@ -292,8 +334,13 @@ macro_rules! __impl_outer_config_types { ($concrete:ident) => () } +/// Implement the output "meta" module configuration struct, +/// which is basically: +/// pub struct GenesisConfig { +/// rust_module_one: Option, +/// ... +/// } #[macro_export] -/// Implement the output "meta" module configuration struct. macro_rules! impl_outer_config { ( pub struct $main:ident for $concrete:ident { @@ -356,7 +403,7 @@ macro_rules! impl_outer_log { /// Wrapper for all possible log entries for the `$trait` runtime. Provides binary-compatible /// `Encode`/`Decode` implementations with the corresponding `generic::DigestItem`. #[derive(Clone, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] + #[cfg_attr(feature = "std", derive(Debug, Serialize))] $(#[$attr])* #[allow(non_camel_case_types)] pub struct $name($internal); @@ -364,7 +411,7 @@ macro_rules! impl_outer_log { /// All possible log entries for the `$trait` runtime. `Encode`/`Decode` implementations /// are auto-generated => it is not binary-compatible with `generic::DigestItem`. #[derive(Clone, PartialEq, Eq, Encode, Decode)] - #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] + #[cfg_attr(feature = "std", derive(Debug, Serialize))] $(#[$attr])* #[allow(non_camel_case_types)] pub enum InternalLog { @@ -464,6 +511,76 @@ macro_rules! impl_outer_log { }; } +//TODO: https://github.com/paritytech/substrate/issues/1022 +/// Basic Inherent data to include in a block; used by simple runtimes. +#[derive(Encode, Decode)] +pub struct BasicInherentData { + /// Current timestamp. + pub timestamp: u64, + /// Blank report. + pub consensus: (), + /// Aura expected slot. Can take any value during block construction. + pub aura_expected_slot: u64, +} + +impl BasicInherentData { + /// Create a new `BasicInherentData` instance. + pub fn new(timestamp: u64, expected_slot: u64) -> Self { + Self { + timestamp, + consensus: (), + aura_expected_slot: expected_slot, + } + } +} + +//TODO: https://github.com/paritytech/substrate/issues/1022 +/// Error type used while checking inherents. +#[derive(Encode, PartialEq)] +#[cfg_attr(feature = "std", derive(Decode))] +pub enum CheckInherentError { + /// The inherents are generally valid but a delay until the given timestamp + /// is required. + ValidAtTimestamp(u64), + /// Some other error has occurred. + Other(RuntimeString), +} + +impl CheckInherentError { + /// Combine two results, taking the "worse" of the two. + pub fn combine_results Result<(), Self>>(this: Result<(), Self>, other: F) -> Result<(), Self> { + match this { + Ok(()) => other(), + Err(CheckInherentError::Other(s)) => Err(CheckInherentError::Other(s)), + Err(CheckInherentError::ValidAtTimestamp(x)) => match other() { + Ok(()) => Err(CheckInherentError::ValidAtTimestamp(x)), + Err(CheckInherentError::ValidAtTimestamp(y)) + => Err(CheckInherentError::ValidAtTimestamp(rstd::cmp::max(x, y))), + Err(CheckInherentError::Other(s)) => Err(CheckInherentError::Other(s)), + } + } + } +} + +/// Simple blob to hold an extrinsic without commiting to its format and ensure it is serialized +/// correctly. +#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct OpaqueExtrinsic(pub Vec); + +#[cfg(feature = "std")] +impl ::serde::Serialize for OpaqueExtrinsic { + fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { + ::codec::Encode::using_encoded(&self.0, |bytes| ::substrate_primitives::bytes::serialize(bytes, seq)) + } +} + +impl traits::Extrinsic for OpaqueExtrinsic { + fn is_signed(&self) -> Option { + None + } +} + #[cfg(test)] mod tests { use substrate_primitives::hash::H256; @@ -484,7 +601,7 @@ mod tests { use super::RuntimeT; pub type Log = RawLog<::AuthorityId>; - #[derive(Serialize, Deserialize, Debug, Encode, Decode, PartialEq, Eq, Clone)] + #[derive(Serialize, Debug, Encode, Decode, PartialEq, Eq, Clone)] pub enum RawLog { A1(AuthorityId), AuthoritiesChange(Vec), A3(AuthorityId) } } @@ -492,7 +609,7 @@ mod tests { use super::RuntimeT; pub type Log = RawLog<::AuthorityId>; - #[derive(Serialize, Deserialize, Debug, Encode, Decode, PartialEq, Eq, Clone)] + #[derive(Serialize, Debug, Encode, Decode, PartialEq, Eq, Clone)] pub enum RawLog { B1(AuthorityId), B2(AuthorityId) } } @@ -537,4 +654,49 @@ mod tests { // check that as-style methods are not working with regular items assert!(b1.as_authorities_change().is_none()); } + + #[test] + fn opaque_extrinsic_serialization() { + let ex = super::OpaqueExtrinsic(vec![1, 2, 3, 4]); + assert_eq!(serde_json::to_string(&ex).unwrap(), "\"0x1001020304\"".to_owned()); + } + + #[test] + fn compact_permill_perbill_encoding() { + let tests = [(0u32, 1usize), (63, 1), (64, 2), (16383, 2), (16384, 4), (1073741823, 4), (1073741824, 5), (u32::max_value(), 5)]; + for &(n, l) in &tests { + let compact: codec::Compact = super::Permill(n).into(); + let encoded = compact.encode(); + assert_eq!(encoded.len(), l); + let decoded = >::decode(&mut & encoded[..]).unwrap(); + let permill: super::Permill = decoded.into(); + assert_eq!(permill, super::Permill(n)); + + let compact: codec::Compact = super::Perbill(n).into(); + let encoded = compact.encode(); + assert_eq!(encoded.len(), l); + let decoded = >::decode(&mut & encoded[..]).unwrap(); + let perbill: super::Perbill = decoded.into(); + assert_eq!(perbill, super::Perbill(n)); + } + } + + #[derive(Encode, Decode, PartialEq, Eq, Debug)] + struct WithCompact { + data: T, + } + + #[test] + fn test_has_compact_permill() { + let data = WithCompact { data: super::Permill(1) }; + let encoded = data.encode(); + assert_eq!(data, WithCompact::::decode(&mut &encoded[..]).unwrap()); + } + + #[test] + fn test_has_compact_perbill() { + let data = WithCompact { data: super::Perbill(1) }; + let encoded = data.encode(); + assert_eq!(data, WithCompact::::decode(&mut &encoded[..]).unwrap()); + } } diff --git a/core/sr-primitives/src/testing.rs b/core/sr-primitives/src/testing.rs index 847af9a3c2ec4ec344733fa86e3504bfb97bdbd5..f552600de910080a748a2fc90e318e7ce6586fbf 100644 --- a/core/sr-primitives/src/testing.rs +++ b/core/sr-primitives/src/testing.rs @@ -16,17 +16,35 @@ //! Testing utilities. -use serde::{Serialize, de::DeserializeOwned}; -use std::{fmt::Debug, ops::Deref}; -use codec::Codec; -use traits::{self, Checkable, Applyable, BlakeTwo256}; +use serde::{Serialize, Serializer, Deserialize, de::Error as DeError, Deserializer}; +use std::{fmt::Debug, ops::Deref, fmt}; +use codec::{Codec, Encode, Decode}; +use traits::{self, Checkable, Applyable, BlakeTwo256, Convert}; use generic::DigestItem as GenDigestItem; -pub use substrate_primitives::{H256, AuthorityId}; +pub use substrate_primitives::{H256, Ed25519AuthorityId}; +use substrate_primitives::U256; -pub type DigestItem = GenDigestItem; +#[derive(Default, PartialEq, Eq, Clone, Decode, Encode, Debug)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct UintAuthorityId(pub u64); +impl Into for UintAuthorityId { + fn into(self) -> Ed25519AuthorityId { + let bytes: [u8; 32] = U256::from(self.0).into(); + Ed25519AuthorityId(bytes) + } +} + +pub struct ConvertUintAuthorityId; +impl Convert for ConvertUintAuthorityId { + fn convert(a: u64) -> UintAuthorityId { + UintAuthorityId(a) + } +} + +pub type DigestItem = GenDigestItem; -#[derive(Default, PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)] +#[derive(Default, PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode)] pub struct Digest { pub logs: Vec, } @@ -48,7 +66,7 @@ impl traits::Digest for Digest { } } -#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)] +#[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode)] #[serde(rename_all = "camelCase")] #[serde(deny_unknown_fields)] pub struct Header { @@ -98,7 +116,14 @@ impl traits::Header for Header { } } -#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)] +impl<'a> Deserialize<'a> for Header { + fn deserialize>(de: D) -> Result { + let r = >::deserialize(de)?; + Decode::decode(&mut &r[..]).ok_or(DeError::custom("Invalid value passed into decode")) + } +} + +#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode)] pub struct ExtrinsicWrapper(Xt); impl traits::Extrinsic for ExtrinsicWrapper { @@ -107,6 +132,13 @@ impl traits::Extrinsic for ExtrinsicWrapper { } } +impl serde::Serialize for ExtrinsicWrapper +{ + fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { + self.using_encoded(|bytes| seq.serialize_bytes(bytes)) + } +} + impl From for ExtrinsicWrapper { fn from(xt: Xt) -> Self { ExtrinsicWrapper(xt) @@ -121,13 +153,13 @@ impl Deref for ExtrinsicWrapper { } } -#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)] +#[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode)] pub struct Block { pub header: Header, pub extrinsics: Vec, } -impl traits::Block for Block { +impl traits::Block for Block { type Extrinsic = Xt; type Header = Header; type Hash =

::Hash; @@ -146,20 +178,40 @@ impl Deserialize<'a> for Block where Block: Decode { + fn deserialize>(de: D) -> Result { + let r = >::deserialize(de)?; + Decode::decode(&mut &r[..]).ok_or(DeError::custom("Invalid value passed into decode")) + } +} + +#[derive(PartialEq, Eq, Clone, Encode, Decode)] pub struct TestXt(pub Option, pub u64, pub Call); -impl Checkable for TestXt { +impl Serialize for TestXt where TestXt: Encode +{ + fn serialize(&self, seq: S) -> Result where S: Serializer { + self.using_encoded(|bytes| seq.serialize_bytes(bytes)) + } +} + +impl Debug for TestXt { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "TestXt({:?}, {:?})", self.0, self.1) + } +} + +impl Checkable for TestXt { type Checked = Self; fn check(self, _: &Context) -> Result { Ok(self) } } -impl traits::Extrinsic for TestXt { +impl traits::Extrinsic for TestXt { fn is_signed(&self) -> Option { None } } impl Applyable for TestXt where - Call: 'static + Sized + Send + Sync + Clone + Eq + Codec + Debug + Serialize + DeserializeOwned, + Call: 'static + Sized + Send + Sync + Clone + Eq + Codec + Debug, { type AccountId = u64; type Index = u64; diff --git a/core/sr-primitives/src/traits.rs b/core/sr-primitives/src/traits.rs index 5c568460eec7b2836ce0a2ee71e4f6888affd5e3..8723dbec91ed77cc7e10eabf8b3d13897ad7171f 100644 --- a/core/sr-primitives/src/traits.rs +++ b/core/sr-primitives/src/traits.rs @@ -17,7 +17,7 @@ //! Primitives for the runtime modules. use rstd::prelude::*; -use rstd::{self, result}; +use rstd::{self, result, marker::PhantomData}; use runtime_io; #[cfg(feature = "std")] use std::fmt::{Debug, Display}; #[cfg(feature = "std")] use serde::{Serialize, de::DeserializeOwned}; @@ -26,9 +26,13 @@ use substrate_primitives::Blake2Hasher; use codec::{Codec, Encode, HasCompact}; pub use integer_sqrt::IntegerSquareRoot; pub use num_traits::{Zero, One, Bounded}; -pub use num_traits::ops::checked::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; -use rstd::ops::{Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, - RemAssign, Shl, Shr}; +pub use num_traits::ops::checked::{ + CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedShl, CheckedShr, +}; +use rstd::ops::{ + Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, + RemAssign, Shl, Shr +}; /// A lazy value. pub trait Lazy { @@ -50,7 +54,7 @@ pub trait Verify { /// Some sort of check on the origin is performed by this object. pub trait EnsureOrigin { type Success; - fn ensure_origin(o: OuterOrigin) -> Result; + fn ensure_origin(o: OuterOrigin) -> result::Result; } /// Means of changing one type into another in a manner dependent on the source type. @@ -63,6 +67,31 @@ pub trait Lookup { fn lookup(&self, s: Self::Source) -> result::Result; } +/// Means of changing one type into another in a manner dependent on the source type. +/// This variant is different to `Lookup` in that it doesn't (can cannot) require any +/// context. +pub trait StaticLookup { + /// Type to lookup from. + type Source: Codec + Clone + PartialEq + MaybeDebug; + /// Type to lookup into. + type Target; + /// Attempt a lookup. + fn lookup(s: Self::Source) -> result::Result; +} + +#[derive(Default)] +pub struct IdentityLookup(PhantomData); +impl StaticLookup for IdentityLookup { + type Source = T; + type Target = T; + fn lookup(x: T) -> result::Result { Ok(x) } +} +impl Lookup for IdentityLookup { + type Source = T; + type Target = T; + fn lookup(&self, x: T) -> result::Result { Ok(x) } +} + /// Get the "current" block number. pub trait CurrentHeight { /// The type of the block number. @@ -156,6 +185,8 @@ pub trait SimpleArithmetic: Div + DivAssign + Rem + RemAssign + Shl + Shr + + CheckedShl + + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + @@ -171,6 +202,8 @@ impl + DivAssign + Rem + RemAssign + Shl + Shr + + CheckedShl + + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + @@ -246,7 +279,7 @@ tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stupid bug in the Rust compiler believes derived // traits must be fulfilled by all type parameters. /// The hash type produced. - type Output: Member + AsRef<[u8]> + AsMut<[u8]>; + type Output: Member + MaybeSerializeDebug + AsRef<[u8]> + AsMut<[u8]>; /// Produce the hash of some byte-slice. fn hash(s: &[u8]) -> Self::Output; @@ -276,7 +309,7 @@ pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stup fn storage_root() -> Self::Output; /// Acquire the global storage changes root. - fn storage_changes_root(block: u64) -> Option; + fn storage_changes_root(parent_hash: Self::Output, parent_number: u64) -> Option; } /// Blake2-256 Hash implementation. @@ -308,8 +341,8 @@ impl Hash for BlakeTwo256 { fn storage_root() -> Self::Output { runtime_io::storage_root().into() } - fn storage_changes_root(block: u64) -> Option { - runtime_io::storage_changes_root(block).map(Into::into) + fn storage_changes_root(parent_hash: Self::Output, parent_number: u64) -> Option { + runtime_io::storage_changes_root(parent_hash.into(), parent_number).map(Into::into) } } @@ -365,6 +398,16 @@ pub trait MaybeSerializeDebugButNotDeserialize {} #[cfg(not(feature = "std"))] impl MaybeSerializeDebugButNotDeserialize for T {} +#[cfg(feature = "std")] +pub trait MaybeSerialize: Serialize {} +#[cfg(feature = "std")] +impl MaybeSerialize for T {} + +#[cfg(not(feature = "std"))] +pub trait MaybeSerialize {} +#[cfg(not(feature = "std"))] +impl MaybeSerialize for T {} + #[cfg(feature = "std")] pub trait MaybeSerializeDebug: Serialize + DeserializeOwned + Debug {} #[cfg(feature = "std")] @@ -375,6 +418,16 @@ pub trait MaybeSerializeDebug {} #[cfg(not(feature = "std"))] impl MaybeSerializeDebug for T {} +#[cfg(feature = "std")] +pub trait MaybeDebug: Debug {} +#[cfg(feature = "std")] +impl MaybeDebug for T {} + +#[cfg(not(feature = "std"))] +pub trait MaybeDebug {} +#[cfg(not(feature = "std"))] +impl MaybeDebug for T {} + #[cfg(feature = "std")] pub trait MaybeDisplay: Display {} #[cfg(feature = "std")] @@ -385,6 +438,16 @@ pub trait MaybeDisplay {} #[cfg(not(feature = "std"))] impl MaybeDisplay for T {} +#[cfg(feature = "std")] +pub trait MaybeHash: ::rstd::hash::Hash {} +#[cfg(feature = "std")] +impl MaybeHash for T {} + +#[cfg(not(feature = "std"))] +pub trait MaybeHash {} +#[cfg(not(feature = "std"))] +impl MaybeHash for T {} + #[cfg(feature = "std")] pub trait MaybeDecode: ::codec::Decode {} #[cfg(feature = "std")] @@ -395,20 +458,19 @@ pub trait MaybeDecode {} #[cfg(not(feature = "std"))] impl MaybeDecode for T {} - -pub trait Member: Send + Sync + Sized + MaybeSerializeDebug + Eq + PartialEq + Clone + 'static {} -impl Member for T {} +pub trait Member: Send + Sync + Sized + MaybeDebug + Eq + PartialEq + Clone + 'static {} +impl Member for T {} /// Something which fulfills the abstract idea of a Substrate header. It has types for a `Number`, /// a `Hash` and a `Digest`. It provides access to an `extrinsics_root`, `state_root` and /// `parent_hash`, as well as a `digest` and a block `number`. /// /// You can also create a `new` one from those fields. -pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'static { - type Number: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec; - type Hash: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; +pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDeserialize + 'static { + type Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec; + type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; type Hashing: Hash; - type Digest: Digest; + type Digest: Digest + Codec; fn new( number: Self::Number, @@ -444,10 +506,10 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'stat /// `Extrinsic` piece of information as well as a `Header`. /// /// You can get an iterator over each of the `extrinsics` and retrieve the `header`. -pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'static { - type Extrinsic: Member + Codec + Extrinsic; +pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebugButNotDeserialize + 'static { + type Extrinsic: Member + Codec + Extrinsic + MaybeSerialize; type Header: Header; - type Hash: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; + type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; fn header(&self) -> &Self::Header; fn extrinsics(&self) -> &[Self::Extrinsic]; @@ -458,6 +520,13 @@ pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'stati } } +/// Something that acts like an `Extrinsic`. +pub trait Extrinsic { + /// Is this `Extrinsic` signed? + /// If no information are available about signed/unsigned, `None` should be returned. + fn is_signed(&self) -> Option { None } +} + /// Extract the hashing type for a block. pub type HashFor = <::Header as Header>::Hashing; /// Extract the number type for a block. @@ -466,6 +535,8 @@ pub type NumberFor = <::Header as Header>::Number; pub type DigestFor = <::Header as Header>::Digest; /// Extract the digest item type for a block. pub type DigestItemFor = as Digest>::Item; +/// Extract the authority ID type for a block. +pub type AuthorityIdFor = as DigestItem>::AuthorityId; /// A "checkable" piece of information, used by the standard Substrate Executive in order to /// check the validity of a piece of extrinsic information, usually by verifying the signature. @@ -516,7 +587,7 @@ pub trait Applyable: Sized + Send + Sync { /// Something that acts like a `Digest` - it can have `Log`s `push`ed onto it and these `Log`s are /// each `Codec`. -pub trait Digest: Member + Default { +pub trait Digest: Member + MaybeSerializeDebugButNotDeserialize + Default { type Hash: Member; type Item: DigestItem; @@ -528,7 +599,7 @@ pub trait Digest: Member + Default { fn pop(&mut self) -> Option; /// Get reference to the first digest item that matches the passed predicate. - fn log Option<&T>>(&self, predicate: F) -> Option<&T> { + fn log Option<&T>>(&self, predicate: F) -> Option<&T> { self.logs().iter() .filter_map(predicate) .next() @@ -539,9 +610,9 @@ pub trait Digest: Member + Default { /// for casting member to 'system' log items, known to substrate. /// /// If the runtime does not supports some 'system' items, use `()` as a stub. -pub trait DigestItem: Codec + Member { +pub trait DigestItem: Codec + Member + MaybeSerializeDebugButNotDeserialize { type Hash: Member; - type AuthorityId: Member; + type AuthorityId: Member + MaybeHash + codec::Encode + codec::Decode; /// Returns Some if the entry is the `AuthoritiesChange` entry. fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]>; @@ -554,8 +625,6 @@ pub trait DigestItem: Codec + Member { pub trait ProvideInherent { /// The inherent that is provided. type Inherent: Encode + MaybeDecode; - /// The error used by this trait. - type Error: Encode + MaybeDecode; /// The call for setting the inherent. type Call: Encode + MaybeDecode; @@ -569,12 +638,55 @@ pub trait ProvideInherent { /// Check that the given inherent is valid. fn check_inherent Option<&Self::Call>>( block: &Block, data: Self::Inherent, extract_function: &F - ) -> Result<(), Self::Error>; + ) -> Result<(), super::CheckInherentError>; } -/// Something that acts like an `Extrinsic`. -pub trait Extrinsic { - /// Is this `Extrinsic` signed? - /// If no information are available about signed/unsigned, `None` should be returned. - fn is_signed(&self) -> Option { None } +/// Auxiliary wrapper that holds an api instance and binds it to the given lifetime. +pub struct ApiRef<'a, T>(T, rstd::marker::PhantomData<&'a ()>); + +impl<'a, T> From for ApiRef<'a, T> { + fn from(api: T) -> Self { + ApiRef(api, Default::default()) + } +} + +impl<'a, T> rstd::ops::Deref for ApiRef<'a, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +/// Something that provides a runtime api. +pub trait ProvideRuntimeApi { + /// The concrete type that provides the api. + type Api; + + /// Returns the runtime api. + /// The returned instance will keep track of modifications to the storage. Any successful + /// call to an api function, will `commit` its changes to an internal buffer. Otherwise, + /// the modifications will be `discarded`. The modifications will not be applied to the + /// storage, even on a `commit`. + fn runtime_api<'a>(&'a self) -> ApiRef<'a, Self::Api>; +} + +/// A marker trait for something that knows the type of the runtime block. +pub trait GetRuntimeBlockType { + /// The `RuntimeBlock` type. + type RuntimeBlock: self::Block; +} + +/// A marker trait for something that knows the type of the node block. +pub trait GetNodeBlockType { + /// The `NodeBlock` type. + type NodeBlock: self::Block; +} + +/// Something that provides information about a runtime api. +pub trait RuntimeApiInfo { + /// The identifier of the runtime api. + const ID: [u8; 8]; + /// The version of the runtime api. + const VERSION: u32; } diff --git a/core/sr-sandbox/Cargo.toml b/core/sr-sandbox/Cargo.toml index 8cb35aed797ba0f384036155b2aab9154a469896..c77dfecd967ced400c80aab310ebfc0751b57b97 100755 --- a/core/sr-sandbox/Cargo.toml +++ b/core/sr-sandbox/Cargo.toml @@ -8,13 +8,13 @@ build = "build.rs" rustc_version = "0.2" [dependencies] -wasmi = { version = "0.4.1", optional = true } +wasmi = { version = "0.4.3", optional = true } substrate-primitives = { path = "../primitives", default-features = false } sr-std = { path = "../sr-std", default-features = false } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } [dev-dependencies] -wabt = "0.4" +wabt = "~0.7.4" assert_matches = "1.1" [features] diff --git a/core/sr-sandbox/README.adoc b/core/sr-sandbox/README.adoc deleted file mode 100644 index 61a203708c8117a0907ccb29819d373595f7f6c2..0000000000000000000000000000000000000000 --- a/core/sr-sandbox/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Runtime Sandbox - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/sr-sandbox/src/lib.rs b/core/sr-sandbox/src/lib.rs index 6ed3243dc8bcbbf111a084d280039c94d93d48fb..09af04747df40e52e441ef0b18da7a3abda4ba92 100755 --- a/core/sr-sandbox/src/lib.rs +++ b/core/sr-sandbox/src/lib.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! This crate provides means to instantiate and execute wasm modules. //! //! It works even when the user of this library executes from @@ -30,12 +29,10 @@ //! When this crate is used in the `std` environment all these functions are implemented by directly //! calling the wasm VM. //! -//! Example of possible use-cases for this library are the following: +//! Examples of possible use-cases for this library are not limited to the following: //! //! - implementing smart-contract runtimes that use wasm for contract code //! - executing a wasm substrate runtime inside of a wasm parachain -//! - etc -// end::description[] #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] diff --git a/core/sr-std/README.adoc b/core/sr-std/README.adoc deleted file mode 100644 index 36ea8d99c22625de2277388a8edb6c972012096c..0000000000000000000000000000000000000000 --- a/core/sr-std/README.adoc +++ /dev/null @@ -1,14 +0,0 @@ - -= Runtime std - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- - diff --git a/core/sr-std/src/lib.rs b/core/sr-std/src/lib.rs index 87c39656465b725aa09990b125d1c69e5bd47249..416c91bc7f49b9832a87d4ff5d0d34040fdbe6cd 100644 --- a/core/sr-std/src/lib.rs +++ b/core/sr-std/src/lib.rs @@ -14,10 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Lowest-abstraction level for the Substrate runtime: just exports useful primitives from std //! or core/alloc to be used with any code that depends on the runtime. -// end::description[] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(core_intrinsics))] diff --git a/core/sr-version/Cargo.toml b/core/sr-version/Cargo.toml index 785eecdfa7c32c735e1f41e8d073e9e3ce411017..a166ac475bd51cc0e48018efaba874641330ff95 100644 --- a/core/sr-version/Cargo.toml +++ b/core/sr-version/Cargo.toml @@ -4,9 +4,10 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] +impl-serde = { version = "0.1", optional = true } serde = { version = "1.0", default-features = false } serde_derive = { version = "1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } sr-std = { path = "../sr-std", default-features = false } sr-primitives = { path = "../sr-primitives", default-features = false } @@ -14,6 +15,7 @@ sr-primitives = { path = "../sr-primitives", default-features = false } [features] default = ["std"] std = [ + "impl-serde", "serde/std", "serde_derive", "parity-codec/std", diff --git a/core/sr-version/README.adoc b/core/sr-version/README.adoc deleted file mode 100644 index 28db6c615d3b9f65607882768bd3c5bd326f5013..0000000000000000000000000000000000000000 --- a/core/sr-version/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Runtime Version - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/sr-version/src/lib.rs b/core/sr-version/src/lib.rs index 6f91692b8232d7ab12e23089985da944055b70e6..4a4c7174ba354b3465995b07ff117ec50384d29d 100644 --- a/core/sr-version/src/lib.rs +++ b/core/sr-version/src/lib.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Version module for the Substrate runtime; Provides a function that returns the runtime version. -// end::description[] #![cfg_attr(not(feature = "std"), no_std)] @@ -37,8 +35,11 @@ extern crate sr_primitives as runtime_primitives; use std::fmt; #[cfg(feature = "std")] use std::collections::HashSet; +#[cfg(feature = "std")] +use runtime_primitives::traits::RuntimeApiInfo; use runtime_primitives::RuntimeString; +pub use runtime_primitives::create_runtime_str; /// The identity of a particular API interface that the runtime might provide. pub type ApiId = [u8; 8]; @@ -52,22 +53,16 @@ pub type ApisVec = ::std::borrow::Cow<'static, [(ApiId, u32)]>; #[cfg(not(feature = "std"))] pub type ApisVec = &'static [(ApiId, u32)]; -#[cfg(feature = "std")] +/// Create a vector of Api declarations. #[macro_export] -macro_rules! ver_str { - ( $y:expr ) => {{ ::std::borrow::Cow::Borrowed($y) }} +#[cfg(feature = "std")] +macro_rules! create_apis_vec { + ( $y:expr ) => { ::std::borrow::Cow::Borrowed(& $y) } } - -#[cfg(not(feature = "std"))] #[macro_export] -macro_rules! ver_str { - ( $y:expr ) => {{ $y }} -} - -/// Create a vector of Api declarations. -#[macro_export] -macro_rules! apis_vec { - ( $y:expr ) => { ver_str!(& $y) } +#[cfg(not(feature = "std"))] +macro_rules! create_apis_vec { + ( $y:expr ) => { & $y } } /// Runtime version. @@ -76,7 +71,8 @@ macro_rules! apis_vec { /// In particular: bug fixes should result in an increment of `spec_version` and possibly `authoring_version`, /// absolutely not `impl_version` since they change the semantics of the runtime. #[derive(Clone, PartialEq, Eq, Encode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize, Decode))] +#[cfg_attr(feature = "std", derive(Debug, Serialize, Decode))] +#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] pub struct RuntimeVersion { /// Identifies the different Substrate runtimes. There'll be at least polkadot and node. /// A different on-chain spec_name to that of the native runtime would normally result @@ -108,13 +104,20 @@ pub struct RuntimeVersion { pub impl_version: u32, /// List of supported API "features" along with their versions. + #[cfg_attr(feature = "std", serde(serialize_with = "apis_serialize::serialize"))] pub apis: ApisVec, } #[cfg(feature = "std")] impl fmt::Display for RuntimeVersion { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}-{}:{}({}-{})", self.spec_name, self.spec_version, self.authoring_version, self.impl_name, self.impl_version) + write!(f, "{}-{}:{}({}-{})", + self.spec_name, + self.spec_version, + self.authoring_version, + self.impl_name, + self.impl_version + ) } } @@ -128,8 +131,10 @@ impl RuntimeVersion { } /// Check if this version supports a particular API. - pub fn has_api(&self, api: ApiId, version: u32) -> bool { - self.apis.iter().any(|&(ref s, v)| &api == s && version == v) + pub fn has_api(&self) -> bool { + self.apis.iter().any(|(s, v)| { + s == &A::ID && *v == A::VERSION + }) } } @@ -151,3 +156,36 @@ impl NativeVersion { self.can_author_with.contains(&other.authoring_version)) } } + +#[cfg(feature = "std")] +mod apis_serialize { + extern crate impl_serde; + extern crate serde; + + use super::*; + use self::impl_serde::serialize as bytes; + use self::serde::{Serializer, ser::SerializeTuple}; + + #[derive(Serialize)] + struct ApiId<'a>( + #[serde(serialize_with="serialize_bytesref")] &'a super::ApiId, + &'a u32, + ); + + pub fn serialize(apis: &ApisVec, ser: S) -> Result where + S: Serializer, + { + let len = apis.len(); + let mut seq = ser.serialize_tuple(len)?; + for (api, ver) in &**apis { + seq.serialize_element(&ApiId(api, ver))?; + } + seq.end() + } + + pub fn serialize_bytesref(apis: &&super::ApiId, ser: S) -> Result where + S: Serializer, + { + bytes::serialize(*apis, ser) + } +} diff --git a/core/state-db/Cargo.toml b/core/state-db/Cargo.toml index bef12d1ae6a61a539a9d1435fbe9ec3d41854eaf..a0d7e1b13729ef8a1988b9f9d223cbf0307b4c46 100644 --- a/core/state-db/Cargo.toml +++ b/core/state-db/Cargo.toml @@ -4,10 +4,10 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -parking_lot = "0.5" +parking_lot = "0.7.1" log = "0.4" substrate-primitives = { path = "../../core/primitives" } -parity-codec = "2.1" +parity-codec = "2.2" parity-codec-derive = "2.1" [dev-dependencies] diff --git a/core/state-db/README.adoc b/core/state-db/README.adoc deleted file mode 100644 index f9934ed8d9ac6a869779d620e26889f487887831..0000000000000000000000000000000000000000 --- a/core/state-db/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= State DB - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/state-db/src/lib.rs b/core/state-db/src/lib.rs index 261d768560c8a7b091d90121bb18944e8e37a7b6..51fffa1f2dce4ee72702142bf8bdf9524f2e039e 100644 --- a/core/state-db/src/lib.rs +++ b/core/state-db/src/lib.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! 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. @@ -29,8 +28,6 @@ //! # Pruning. //! See `RefWindow` for pruning algorithm details. `StateDb` prunes on each canonicalization until pruning //! constraints are satisfied. -//! -// end::description[] #[macro_use] extern crate log; #[macro_use] extern crate parity_codec_derive; diff --git a/core/state-machine/Cargo.toml b/core/state-machine/Cargo.toml index c0254116feee8924d0abf03f84cd69b1dcd98b34..3dc4f3e953866907ab9cfcb5c19734c6426bf308 100644 --- a/core/state-machine/Cargo.toml +++ b/core/state-machine/Cargo.toml @@ -7,11 +7,11 @@ description = "Substrate State Machine" [dependencies] hex-literal = "0.1.0" log = "0.4" -parking_lot = "0.4" +parking_lot = "0.7.1" heapsize = "0.4" -hash-db = { git = "https://github.com/paritytech/trie" } -trie-db = { git = "https://github.com/paritytech/trie" } -trie-root = { git = "https://github.com/paritytech/trie" } +hash-db = "0.9" +trie-db = "0.9" +trie-root = "0.9" substrate-trie = { path = "../trie" } substrate-primitives = { path = "../primitives" } -parity-codec = "2.1" +parity-codec = "2.2" diff --git a/core/state-machine/README.adoc b/core/state-machine/README.adoc deleted file mode 100644 index aad08bed989dbbe894b2452a28a4cedf7c3eb7a7..0000000000000000000000000000000000000000 --- a/core/state-machine/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= State Machine - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/state-machine/src/backend.rs b/core/state-machine/src/backend.rs index f9949deae9db1daa7928609b069e920a28398971..a032ab11957aa2de520e966fbb98b42f0635912c 100644 --- a/core/state-machine/src/backend.rs +++ b/core/state-machine/src/backend.rs @@ -40,10 +40,15 @@ pub trait Backend { /// Type of trie backend storage. type TrieBackendStorage: TrieBackendStorage; - /// Get keyed storage associated with specific address, or None if there is nothing associated. + /// Get keyed storage or None if there is nothing associated. fn storage(&self, key: &[u8]) -> Result>, Self::Error>; - /// Get keyed child storage associated with specific address, or None if there is nothing associated. + /// Get keyed storage value hash or None if there is nothing associated. + fn storage_hash(&self, key: &[u8]) -> Result, Self::Error> { + self.storage(key).map(|v| v.map(|v| H::hash(&v))) + } + + /// Get keyed child storage or None if there is nothing associated. fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Result>, Self::Error>; /// true if a key exists in storage. @@ -81,6 +86,9 @@ pub trait Backend { /// Get all key/value pairs into a Vec. fn pairs(&self) -> Vec<(Vec, Vec)>; + /// Get all keys with given prefix + fn keys(&self, prefix: &Vec) -> Vec>; + /// Try convert into trie backend. fn try_into_trie_backend(self) -> Option>; } @@ -278,6 +286,10 @@ impl Backend for InMemory where H::Out: HeapSizeOf { self.inner.get(&None).into_iter().flat_map(|map| map.iter().map(|(k, v)| (k.clone(), v.clone()))).collect() } + fn keys(&self, prefix: &Vec) -> Vec> { + self.inner.get(&None).into_iter().flat_map(|map| map.keys().filter(|k| k.starts_with(prefix)).cloned()).collect() + } + fn try_into_trie_backend(self) -> Option> { let mut mdb = MemoryDB::default(); // TODO: should be more correct and use ::new() let mut root = None; diff --git a/core/state-machine/src/changes_trie/build.rs b/core/state-machine/src/changes_trie/build.rs index 991b39593838a0aa019570e024b7e6b0cb58252b..c183f2b3cce23ca81f4b800dc32bf88cd29ad79e 100644 --- a/core/state-machine/src/changes_trie/build.rs +++ b/core/state-machine/src/changes_trie/build.rs @@ -25,7 +25,7 @@ use overlayed_changes::OverlayedChanges; use trie_backend_essence::{TrieBackendStorage, TrieBackendEssence}; use changes_trie::build_iterator::digest_build_iterator; use changes_trie::input::{InputKey, InputPair, DigestIndex, ExtrinsicIndex}; -use changes_trie::{Configuration, Storage}; +use changes_trie::{AnchorBlockId, Configuration, Storage}; /// Prepare input pairs for building a changes trie of given block. /// @@ -37,7 +37,7 @@ pub fn prepare_input<'a, B, S, H>( backend: &B, storage: Option<&'a S>, changes: &OverlayedChanges, - block: u64, + parent: &'a AnchorBlockId, ) -> Result>, String> where B: Backend, @@ -54,10 +54,10 @@ pub fn prepare_input<'a, B, S, H>( let mut input = Vec::new(); input.extend(prepare_extrinsics_input( backend, - block, + parent.number + 1, changes)?); input.extend(prepare_digest_input::<_, H>( - block, + parent, config, storage)?); @@ -73,7 +73,6 @@ fn prepare_extrinsics_input( where B: Backend, H: Hasher, - { let mut extrinsic_map = BTreeMap::, BTreeSet>::new(); for (key, val) in changes.prospective.top.iter().chain(changes.committed.top.iter()) { @@ -103,19 +102,19 @@ fn prepare_extrinsics_input( /// Prepare DigestIndex input pairs. fn prepare_digest_input<'a, S, H>( - block: u64, + parent: &'a AnchorBlockId, config: &Configuration, storage: &'a S -) -> Result, String> +) -> Result + 'a, String> where S: Storage, &'a S: TrieBackendStorage, H: Hasher, - H::Out: HeapSizeOf, + H::Out: 'a + HeapSizeOf, { let mut digest_map = BTreeMap::, BTreeSet>::new(); - for digest_build_block in digest_build_iterator(config, block) { - let trie_root = storage.root(digest_build_block)?; + for digest_build_block in digest_build_iterator(config, parent.number + 1) { + let trie_root = storage.root(parent, digest_build_block)?; let trie_root = trie_root.ok_or_else(|| format!("No changes trie root for block {}", digest_build_block))?; let trie_storage = TrieBackendEssence::<_, H>::new(storage, trie_root); @@ -136,7 +135,7 @@ fn prepare_digest_input<'a, S, H>( Ok(digest_map.into_iter() .map(move |(key, set)| InputPair::DigestIndex(DigestIndex { - block, + block: parent.number + 1, key }, set.into_iter().collect()))) } @@ -228,7 +227,7 @@ mod test { #[test] fn build_changes_trie_nodes_on_non_digest_block() { let (backend, storage, changes) = prepare_for_build(); - let changes_trie_nodes = prepare_input(&backend, Some(&storage), &changes, 5).unwrap(); + let changes_trie_nodes = prepare_input(&backend, Some(&storage), &changes, &AnchorBlockId { hash: Default::default(), number: 4 }).unwrap(); assert_eq!(changes_trie_nodes, Some(vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 5, key: vec![100] }, vec![0, 2, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 5, key: vec![101] }, vec![1]), @@ -239,7 +238,7 @@ mod test { #[test] fn build_changes_trie_nodes_on_digest_block_l1() { let (backend, storage, changes) = prepare_for_build(); - let changes_trie_nodes = prepare_input(&backend, Some(&storage), &changes, 4).unwrap(); + let changes_trie_nodes = prepare_input(&backend, Some(&storage), &changes, &AnchorBlockId { hash: Default::default(), number: 3 }).unwrap(); assert_eq!(changes_trie_nodes, Some(vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![100] }, vec![0, 2, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![101] }, vec![1]), @@ -255,7 +254,7 @@ mod test { #[test] fn build_changes_trie_nodes_on_digest_block_l2() { let (backend, storage, changes) = prepare_for_build(); - let changes_trie_nodes = prepare_input(&backend, Some(&storage), &changes, 16).unwrap(); + let changes_trie_nodes = prepare_input(&backend, Some(&storage), &changes, &AnchorBlockId { hash: Default::default(), number: 15 }).unwrap(); assert_eq!(changes_trie_nodes, Some(vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![100] }, vec![0, 2, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![101] }, vec![1]), @@ -279,7 +278,7 @@ mod test { extrinsics: Some(vec![1].into_iter().collect()) }); - let changes_trie_nodes = prepare_input(&backend, Some(&storage), &changes, 4).unwrap(); + let changes_trie_nodes = prepare_input(&backend, Some(&storage), &changes, &AnchorBlockId { hash: Default::default(), number: 3 }).unwrap(); assert_eq!(changes_trie_nodes, Some(vec![ InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![100] }, vec![0, 2, 3]), InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![101] }, vec![1]), diff --git a/core/state-machine/src/changes_trie/changes_iterator.rs b/core/state-machine/src/changes_trie/changes_iterator.rs index 8b4d2bd54070bd10c6d0808d02c1c4e1990b0e33..af844db2c86a85b2a5b08eedc7de9e41b78a7372 100644 --- a/core/state-machine/src/changes_trie/changes_iterator.rs +++ b/core/state-machine/src/changes_trie/changes_iterator.rs @@ -23,7 +23,7 @@ use codec::{Decode, Encode}; use hash_db::{HashDB, Hasher}; use heapsize::HeapSizeOf; use substrate_trie::{Recorder, MemoryDB}; -use changes_trie::{Configuration, RootsStorage, Storage}; +use changes_trie::{AnchorBlockId, Configuration, RootsStorage, Storage}; use changes_trie::input::{DigestIndex, ExtrinsicIndex, DigestIndexValue, ExtrinsicIndexValue}; use changes_trie::storage::{TrieBackendAdapter, InMemoryStorage}; use proving_backend::ProvingBackendEssence; @@ -31,29 +31,30 @@ use trie_backend_essence::{TrieBackendEssence}; /// Return changes of given key at given blocks range. /// `max` is the number of best known block. -pub fn key_changes, H: Hasher>( - config: &Configuration, - storage: &S, +/// Changes are returned in descending order (i.e. last block comes first). +pub fn key_changes<'a, S: Storage, H: Hasher>( + config: &'a Configuration, + storage: &'a S, begin: u64, - end: u64, + end: &'a AnchorBlockId, max: u64, - key: &[u8], -) -> Result, String> where H::Out: HeapSizeOf { - DrilldownIterator { + key: &'a [u8], +) -> Result, String> where H::Out: HeapSizeOf { + Ok(DrilldownIterator { essence: DrilldownIteratorEssence { key, roots_storage: storage, storage, begin, end, - surface: surface_iterator(config, max, begin, end)?, + surface: surface_iterator(config, max, begin, end.number)?, extrinsics: Default::default(), blocks: Default::default(), _hasher: ::std::marker::PhantomData::::default(), }, - }.collect() + }) } /// Returns proof of changes of given key at given blocks range. @@ -62,7 +63,7 @@ pub fn key_changes_proof, H: Hasher>( config: &Configuration, storage: &S, begin: u64, - end: u64, + end: &AnchorBlockId, max: u64, key: &[u8], ) -> Result>, String> where H::Out: HeapSizeOf { @@ -73,7 +74,7 @@ pub fn key_changes_proof, H: Hasher>( storage, begin, end, - surface: surface_iterator(config, max, begin, end)?, + surface: surface_iterator(config, max, begin, end.number)?, extrinsics: Default::default(), blocks: Default::default(), @@ -93,12 +94,13 @@ pub fn key_changes_proof, H: Hasher>( /// Check key changes proog and return changes of the key at given blocks range. /// `max` is the number of best known block. +/// Changes are returned in descending order (i.e. last block comes first). pub fn key_changes_proof_check, H: Hasher>( config: &Configuration, roots_storage: &S, proof: Vec>, begin: u64, - end: u64, + end: &AnchorBlockId, max: u64, key: &[u8] ) -> Result, String> where H::Out: HeapSizeOf { @@ -115,7 +117,7 @@ pub fn key_changes_proof_check, H: Hasher>( storage: &proof_db, begin, end, - surface: surface_iterator(config, max, begin, end)?, + surface: surface_iterator(config, max, begin, end.number)?, extrinsics: Default::default(), blocks: Default::default(), @@ -174,12 +176,12 @@ impl<'a> Iterator for SurfaceIterator<'a> { /// Drilldown iterator - receives 'digest points' from surface iterator and explores /// every point until extrinsic is found. -pub struct DrilldownIteratorEssence<'a, RS: 'a + RootsStorage, S: 'a + Storage, H: Hasher> { +pub struct DrilldownIteratorEssence<'a, RS: 'a + RootsStorage, S: 'a + Storage, H: Hasher> where H::Out: 'a { key: &'a [u8], roots_storage: &'a RS, storage: &'a S, begin: u64, - end: u64, + end: &'a AnchorBlockId, surface: SurfaceIterator<'a>, extrinsics: VecDeque<(u64, u32)>, @@ -213,14 +215,14 @@ impl<'a, RS: 'a + RootsStorage, S: Storage, H: Hasher> DrilldownIteratorEs // not having a changes trie root is an error because: // we never query roots for future blocks // AND trie roots for old blocks are known (both on full + light node) - let trie_root = self.roots_storage.root(block)? + let trie_root = self.roots_storage.root(&self.end, block)? .ok_or_else(|| format!("Changes trie root for block {} is not found", block))?; // only return extrinsics for blocks before self.max // most of blocks will be filtered out beore pushing to `self.blocks` // here we just throwing away changes at digest blocks we're processing debug_assert!(block >= self.begin, "We shall not touch digests earlier than a range' begin"); - if block <= self.end { + if block <= self.end.number { let extrinsics_key = ExtrinsicIndex { block, key: self.key.to_vec() }.encode(); let extrinsics = trie_reader(&self.storage, trie_root, &extrinsics_key); if let Some(extrinsics) = extrinsics? { @@ -239,7 +241,7 @@ impl<'a, RS: 'a + RootsStorage, S: Storage, H: Hasher> DrilldownIteratorEs // filter level0 blocks here because we tend to use digest blocks, // AND digest block changes could also include changes for out-of-range blocks let begin = self.begin; - let end = self.end; + let end = self.end.number; self.blocks.extend(blocks.into_iter() .rev() .filter(|b| level > 1 || (*b >= begin && *b <= end)) @@ -261,7 +263,7 @@ impl<'a, RS: 'a + RootsStorage, S: Storage, H: Hasher> DrilldownIteratorEs } /// Exploring drilldown operator. -struct DrilldownIterator<'a, RS: 'a + RootsStorage, S: 'a + Storage, H: Hasher> { +pub struct DrilldownIterator<'a, RS: 'a + RootsStorage, S: 'a + Storage, H: Hasher> where H::Out: 'a { essence: DrilldownIteratorEssence<'a, RS, S, H>, } @@ -278,7 +280,7 @@ impl<'a, RS: 'a + RootsStorage, S: Storage, H: Hasher> Iterator } /// Proving drilldown iterator. -struct ProvingDrilldownIterator<'a, RS: 'a + RootsStorage, S: 'a + Storage, H: Hasher> { +struct ProvingDrilldownIterator<'a, RS: 'a + RootsStorage, S: 'a + Storage, H: Hasher> where H::Out: 'a { essence: DrilldownIteratorEssence<'a, RS, S, H>, proof_recorder: RefCell>, } @@ -379,6 +381,7 @@ fn lower_bound_max_digest( #[cfg(test)] mod tests { + use std::iter::FromIterator; use primitives::Blake2Hasher; use changes_trie::input::InputPair; use changes_trie::storage::InMemoryStorage; @@ -427,23 +430,28 @@ mod tests { fn drilldown_iterator_works() { let (config, storage) = prepare_for_drilldown(); let drilldown_result = key_changes::, Blake2Hasher>( - &config, &storage, 0, 16, 16, &[42]); + &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]) + .and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)])); let drilldown_result = key_changes::, Blake2Hasher>( - &config, &storage, 0, 2, 4, &[42]); + &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 2 }, 4, &[42]) + .and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![])); let drilldown_result = key_changes::, Blake2Hasher>( - &config, &storage, 0, 3, 4, &[42]); + &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 3 }, 4, &[42]) + .and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(3, 0)])); let drilldown_result = key_changes::, Blake2Hasher>( - &config, &storage, 7, 8, 8, &[42]); + &config, &storage, 7, &AnchorBlockId { hash: Default::default(), number: 8 }, 8, &[42]) + .and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(8, 2), (8, 1)])); let drilldown_result = key_changes::, Blake2Hasher>( - &config, &storage, 5, 7, 8, &[42]); + &config, &storage, 5, &AnchorBlockId { hash: Default::default(), number: 7 }, 8, &[42]) + .and_then(Result::from_iter); assert_eq!(drilldown_result, Ok(vec![(6, 3)])); } @@ -453,16 +461,17 @@ mod tests { storage.clear_storage(); assert!(key_changes::, Blake2Hasher>( - &config, &storage, 0, 100, 1000, &[42]).is_err()); + &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 100 }, 1000, &[42]) + .and_then(|i| i.collect::, _>>()).is_err()); } #[test] fn drilldown_iterator_fails_when_range_is_invalid() { let (config, storage) = prepare_for_drilldown(); assert!(key_changes::, Blake2Hasher>( - &config, &storage, 0, 100, 50, &[42]).is_err()); + &config, &storage, 0, &AnchorBlockId { hash: Default::default(), number: 100 }, 50, &[42]).is_err()); assert!(key_changes::, Blake2Hasher>( - &config, &storage, 20, 10, 100, &[42]).is_err()); + &config, &storage, 20, &AnchorBlockId { hash: Default::default(), number: 10 }, 100, &[42]).is_err()); } @@ -474,7 +483,7 @@ mod tests { let (remote_config, remote_storage) = prepare_for_drilldown(); let remote_proof = key_changes_proof::, Blake2Hasher>( &remote_config, &remote_storage, - 0, 16, 16, &[42]).unwrap(); + 0, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]).unwrap(); // happens on local light node: @@ -483,7 +492,7 @@ mod tests { local_storage.clear_storage(); let local_result = key_changes_proof_check::, Blake2Hasher>( &local_config, &local_storage, remote_proof, - 0, 16, 16, &[42]); + 0, &AnchorBlockId { hash: Default::default(), number: 16 }, 16, &[42]); // check that drilldown result is the same as if it was happening at the full node assert_eq!(local_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)])); diff --git a/core/state-machine/src/changes_trie/mod.rs b/core/state-machine/src/changes_trie/mod.rs index fb16cb54d60c2715dc25fcebb0a8b37d9654797c..ffc43fb884fb8b4c515ff42a1e458bb1f8c3a1d8 100644 --- a/core/state-machine/src/changes_trie/mod.rs +++ b/core/state-machine/src/changes_trie/mod.rs @@ -44,7 +44,7 @@ mod storage; pub use self::storage::InMemoryStorage; pub use self::changes_iterator::{key_changes, key_changes_proof, key_changes_proof_check}; -pub use self::prune::prune; +pub use self::prune::{prune, oldest_non_pruned_trie}; use hash_db::Hasher; use heapsize::HeapSizeOf; @@ -58,10 +58,20 @@ use trie::{DBValue, trie_root}; /// Changes that are made outside of extrinsics are marked with this index; pub const NO_EXTRINSIC_INDEX: u32 = 0xffffffff; +/// Block identifier that could be used to determine fork of this block. +#[derive(Debug)] +pub struct AnchorBlockId { + /// Hash of this block. + pub hash: Hash, + /// Number of this block. + pub number: u64, +} + /// Changes trie storage. Provides access to trie roots and trie nodes. pub trait RootsStorage: Send + Sync { - /// Get changes trie root for given block. - fn root(&self, block: u64) -> Result, String>; + /// Get changes trie root for the block with given number which is an ancestor (or the block + /// itself) of the anchor_block (i.e. anchor_block.number >= block). + fn root(&self, anchor: &AnchorBlockId, block: u64) -> Result, String>; } /// Changes trie storage. Provides access to trie roots and trie nodes. @@ -79,13 +89,13 @@ pub fn compute_changes_trie_root<'a, B: Backend, S: Storage, H: Hasher>( backend: &B, storage: Option<&'a S>, changes: &OverlayedChanges, - block: u64, + parent: &'a AnchorBlockId, ) -> Option<(H::Out, Vec<(Vec, Vec)>)> where &'a S: TrieBackendStorage, H::Out: Ord + HeapSizeOf, { - let input_pairs = prepare_input::(backend, storage, changes, block) + let input_pairs = prepare_input::(backend, storage, changes, parent) .expect("storage is not allowed to fail within runtime")?; let transaction = input_pairs.into_iter() .map(Into::into) diff --git a/core/state-machine/src/changes_trie/prune.rs b/core/state-machine/src/changes_trie/prune.rs index 8168a0771d31579970f1f8cadb05473ea99bfe5c..76c746cb72e60414a42cdb3e1a5cdf0269a663f4 100644 --- a/core/state-machine/src/changes_trie/prune.rs +++ b/core/state-machine/src/changes_trie/prune.rs @@ -21,9 +21,25 @@ use heapsize::HeapSizeOf; use substrate_trie::Recorder; use proving_backend::ProvingBackendEssence; use trie_backend_essence::TrieBackendEssence; -use changes_trie::{Configuration, Storage}; +use changes_trie::{AnchorBlockId, Configuration, Storage}; use changes_trie::storage::TrieBackendAdapter; +/// Get number of oldest block for which changes trie is not pruned +/// given changes trie configuration, pruning parameter and number of +/// best finalized block. +pub fn oldest_non_pruned_trie( + config: &Configuration, + min_blocks_to_keep: u64, + best_finalized_block: u64, +) -> u64 { + let max_digest_interval = config.max_digest_interval(); + let max_digest_block = best_finalized_block - best_finalized_block % max_digest_interval; + match pruning_range(config, min_blocks_to_keep, max_digest_block) { + Some((_, last_pruned_block)) => last_pruned_block + 1, + None => 1, + } +} + /// Prune obslete changes tries. Puning happens at the same block, where highest /// level digest is created. Pruning guarantees to save changes tries for last /// `min_blocks_to_keep` blocks. We only prune changes tries at `max_digest_iterval` @@ -33,21 +49,14 @@ pub fn prune, H: Hasher, F: FnMut(H::Out)>( config: &Configuration, storage: &S, min_blocks_to_keep: u64, - current_block: u64, + current_block: &AnchorBlockId, mut remove_trie_node: F, ) where H::Out: HeapSizeOf, { - // we only CAN prune at block where max-level-digest is created - let digest_interval = match config.digest_level_at_block(current_block) { - Some((digest_level, digest_interval, _)) if digest_level == config.digest_levels => - digest_interval, - _ => return, - }; - // select range for pruning - let (first, last) = match pruning_range(min_blocks_to_keep, current_block, digest_interval) { + let (first, last) = match pruning_range(config, min_blocks_to_keep, current_block.number) { Some((first, last)) => (first, last), None => return, }; @@ -55,7 +64,7 @@ pub fn prune, H: Hasher, F: FnMut(H::Out)>( // delete changes trie for every block in range // TODO: limit `max_digest_interval` so that this cycle won't involve huge ranges for block in first..last+1 { - let root = match storage.root(block) { + let root = match storage.root(current_block, block) { Ok(Some(root)) => root, Ok(None) => continue, Err(error) => { @@ -85,16 +94,34 @@ pub fn prune, H: Hasher, F: FnMut(H::Out)>( } /// Select blocks range (inclusive from both ends) for pruning changes tries in. -fn pruning_range(min_blocks_to_keep: u64, block: u64, max_digest_interval: u64) -> Option<(u64, u64)> { - // compute maximal number of high-level digests to keep - let max_digest_intervals_to_keep = max_digest_intervals_to_keep(min_blocks_to_keep, max_digest_interval); +fn pruning_range(config: &Configuration, min_blocks_to_keep: u64, block: u64) -> Option<(u64, u64)> { + // compute number of changes tries we actually want to keep + let (prune_interval, blocks_to_keep) = if config.is_digest_build_enabled() { + // we only CAN prune at block where max-level-digest is created + let max_digest_interval = match config.digest_level_at_block(block) { + Some((digest_level, digest_interval, _)) if digest_level == config.digest_levels => + digest_interval, + _ => return None, + }; + + // compute maximal number of high-level digests to keep + let max_digest_intervals_to_keep = max_digest_intervals_to_keep(min_blocks_to_keep, max_digest_interval); - // number of blocks BEFORE current block where changes tries are not pruned - let blocks_to_keep = max_digest_intervals_to_keep.checked_mul(max_digest_interval); + // number of blocks BEFORE current block where changes tries are not pruned + ( + max_digest_interval, + max_digest_intervals_to_keep.checked_mul(max_digest_interval) + ) + } else { + ( + 1, + Some(min_blocks_to_keep) + ) + }; // last block for which changes trie is pruned let last_block_to_prune = blocks_to_keep.and_then(|b| block.checked_sub(b)); - let first_block_to_prune = last_block_to_prune.clone().and_then(|b| b.checked_sub(max_digest_interval)); + let first_block_to_prune = last_block_to_prune.clone().and_then(|b| b.checked_sub(prune_interval)); last_block_to_prune .and_then(|last| first_block_to_prune.map(|first| (first + 1, last))) @@ -129,6 +156,13 @@ mod tests { use changes_trie::storage::InMemoryStorage; use super::*; + fn config(interval: u64, levels: u32) -> Configuration { + Configuration { + digest_interval: interval, + digest_levels: levels, + } + } + fn prune_by_collect, H: Hasher>( config: &Configuration, storage: &S, @@ -139,12 +173,11 @@ mod tests { H::Out: HeapSizeOf, { let mut pruned_trie_nodes = HashSet::new(); - prune(config, storage, min_blocks_to_keep, current_block, + prune(config, storage, min_blocks_to_keep, &AnchorBlockId { hash: Default::default(), number: current_block }, |node| { pruned_trie_nodes.insert(node); }); pruned_trie_nodes } - #[test] fn prune_works() { fn prepare_storage() -> InMemoryStorage { @@ -213,24 +246,34 @@ mod tests { #[test] fn pruning_range_works() { - assert_eq!(pruning_range(2, 0, 100), None); - assert_eq!(pruning_range(2, 30, 100), None); - assert_eq!(pruning_range(::std::u64::MAX, 1024, 1), None); - assert_eq!(pruning_range(1, 1024, ::std::u64::MAX), None); - assert_eq!(pruning_range(::std::u64::MAX, 1024, ::std::u64::MAX), None); - assert_eq!(pruning_range(1024, 512, 512), None); - assert_eq!(pruning_range(1024, 1024, 512), None); + // DIGESTS ARE NOT CREATED + NO TRIES ARE PRUNED + assert_eq!(pruning_range(&config(10, 0), 2, 2), None); + + // DIGESTS ARE NOT CREATED + SOME TRIES ARE PRUNED + assert_eq!(pruning_range(&config(10, 0), 100, 110), Some((10, 10))); + assert_eq!(pruning_range(&config(10, 0), 100, 210), Some((110, 110))); + + // DIGESTS ARE CREATED + NO TRIES ARE PRUNED + + assert_eq!(pruning_range(&config(10, 2), 2, 0), None); + assert_eq!(pruning_range(&config(10, 2), 30, 100), None); + assert_eq!(pruning_range(&config(::std::u64::MAX, 2), 1, 1024), None); + assert_eq!(pruning_range(&config(::std::u64::MAX, 2), ::std::u64::MAX, 1024), None); + assert_eq!(pruning_range(&config(32, 2), 2048, 512), None); + assert_eq!(pruning_range(&config(32, 2), 2048, 1024), None); + + // DIGESTS ARE CREATED + SOME TRIES ARE PRUNED // when we do not want to keep any highest-level-digests // (system forces to keep at least one) - assert_eq!(pruning_range(0, 32, 16), Some((1, 16))); - assert_eq!(pruning_range(0, 64, 16), Some((33, 48))); + assert_eq!(pruning_range(&config(4, 2), 0, 32), Some((1, 16))); + assert_eq!(pruning_range(&config(4, 2), 0, 64), Some((33, 48))); // when we want to keep 1 (last) highest-level-digest - assert_eq!(pruning_range(16, 32, 16), Some((1, 16))); - assert_eq!(pruning_range(16, 64, 16), Some((33, 48))); + assert_eq!(pruning_range(&config(4, 2), 16, 32), Some((1, 16))); + assert_eq!(pruning_range(&config(4, 2), 16, 64), Some((33, 48))); // when we want to keep 1 (last) + 1 additional level digests - assert_eq!(pruning_range(1024, 1536, 512), Some((1, 512))); - assert_eq!(pruning_range(1024, 2048, 512), Some((513, 1024))); + assert_eq!(pruning_range(&config(32, 2), 4096, 5120), Some((1, 1024))); + assert_eq!(pruning_range(&config(32, 2), 4096, 6144), Some((1025, 2048))); } #[test] @@ -241,4 +284,23 @@ mod tests { assert_eq!(max_digest_intervals_to_keep(1024, 511), 2); assert_eq!(max_digest_intervals_to_keep(1024, 100), 10); } + + #[test] + fn oldest_non_pruned_trie_works() { + // when digests are not created at all + assert_eq!(oldest_non_pruned_trie(&config(0, 0), 100, 10), 1); + assert_eq!(oldest_non_pruned_trie(&config(0, 0), 100, 110), 11); + + // when only l1 digests are created + assert_eq!(oldest_non_pruned_trie(&config(100, 1), 100, 50), 1); + assert_eq!(oldest_non_pruned_trie(&config(100, 1), 100, 110), 1); + assert_eq!(oldest_non_pruned_trie(&config(100, 1), 100, 210), 101); + + // when l2 digests are created + assert_eq!(oldest_non_pruned_trie(&config(100, 2), 100, 50), 1); + assert_eq!(oldest_non_pruned_trie(&config(100, 2), 100, 110), 1); + assert_eq!(oldest_non_pruned_trie(&config(100, 2), 100, 210), 1); + assert_eq!(oldest_non_pruned_trie(&config(100, 2), 100, 10110), 1); + assert_eq!(oldest_non_pruned_trie(&config(100, 2), 100, 20110), 10001); + } } diff --git a/core/state-machine/src/changes_trie/storage.rs b/core/state-machine/src/changes_trie/storage.rs index 1cdd03841e1cf1e0fbf4d6e05818c3e18bde408c..088b605e9cc16a93f86565fb02599079c99b7f7a 100644 --- a/core/state-machine/src/changes_trie/storage.rs +++ b/core/state-machine/src/changes_trie/storage.rs @@ -22,7 +22,7 @@ use trie::DBValue; use heapsize::HeapSizeOf; use trie::MemoryDB; use parking_lot::RwLock; -use changes_trie::{RootsStorage, Storage}; +use changes_trie::{AnchorBlockId, RootsStorage, Storage}; use trie_backend_essence::TrieBackendStorage; #[cfg(test)] @@ -110,7 +110,7 @@ impl InMemoryStorage where H::Out: HeapSizeOf { } impl RootsStorage for InMemoryStorage where H::Out: HeapSizeOf { - fn root(&self, block: u64) -> Result, String> { + fn root(&self, _anchor_block: &AnchorBlockId, block: u64) -> Result, String> { Ok(self.data.read().roots.get(&block).cloned()) } } diff --git a/core/state-machine/src/ext.rs b/core/state-machine/src/ext.rs index b03ed282506088ac65eb3bb0816fdb36bb142620..6274eef720593844a96e20ed615332833ad5d7a3 100644 --- a/core/state-machine/src/ext.rs +++ b/core/state-machine/src/ext.rs @@ -18,7 +18,7 @@ use std::{error, fmt, cmp::Ord}; use backend::{Backend, Consolidate}; -use changes_trie::{Storage as ChangesTrieStorage, compute_changes_trie_root}; +use changes_trie::{AnchorBlockId, Storage as ChangesTrieStorage, compute_changes_trie_root}; use {Externalities, OverlayedChanges}; use hash_db::Hasher; use primitives::storage::well_known_keys::is_child_storage_key; @@ -184,6 +184,11 @@ where self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL)) } + fn storage_hash(&self, key: &[u8]) -> Option { + self.overlay.storage(key).map(|x| x.map(|x| H::hash(x))).unwrap_or_else(|| + self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL)) + } + fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Option> { self.overlay.child_storage(storage_key, key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(|| self.backend.child_storage(storage_key, key).expect(EXT_NOT_ALLOWED_TO_FAIL)) @@ -288,12 +293,12 @@ where Some(self.child_storage_root_transaction(storage_key).0) } - fn storage_changes_root(&mut self, block: u64) -> Option { + fn storage_changes_root(&mut self, parent: H::Out, parent_num: u64) -> Option { let root_and_tx = compute_changes_trie_root::<_, T, H>( self.backend, self.changes_trie_storage.clone(), self.overlay, - block, + &AnchorBlockId { hash: parent, number: parent_num }, ); let root_and_tx = root_and_tx.map(|(root, changes)| { let mut calculated_root = Default::default(); @@ -305,7 +310,7 @@ where } } - (block, mdb, root) + (parent_num + 1, mdb, root) }); let root = root_and_tx.as_ref().map(|(_, _, root)| root.clone()); self.changes_trie_transaction = root_and_tx; @@ -353,7 +358,7 @@ mod tests { let mut overlay = prepare_overlay_with_changes(); let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, None); - assert_eq!(ext.storage_changes_root(100), None); + assert_eq!(ext.storage_changes_root(Default::default(), 100), None); } #[test] @@ -363,7 +368,7 @@ mod tests { let storage = TestChangesTrieStorage::new(); let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage)); - assert_eq!(ext.storage_changes_root(100), None); + assert_eq!(ext.storage_changes_root(Default::default(), 100), None); } #[test] @@ -372,7 +377,7 @@ mod tests { let storage = TestChangesTrieStorage::new(); let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage)); - assert_eq!(ext.storage_changes_root(100), + assert_eq!(ext.storage_changes_root(Default::default(), 99), Some(hex!("5b829920b9c8d554a19ee2a1ba593c4f2ee6fc32822d083e04236d693e8358d5").into())); } @@ -383,7 +388,7 @@ mod tests { let storage = TestChangesTrieStorage::new(); let backend = TestBackend::default(); let mut ext = TestExt::new(&mut overlay, &backend, Some(&storage)); - assert_eq!(ext.storage_changes_root(100), + assert_eq!(ext.storage_changes_root(Default::default(), 99), Some(hex!("bcf494e41e29a15c9ae5caa053fe3cb8b446ee3e02a254efbdec7a19235b76e4").into())); } } diff --git a/core/state-machine/src/lib.rs b/core/state-machine/src/lib.rs index 9bb91108863192f73beda6ac309e5418661766a0..b10ae42bc8bfed8a429bfc9761a40976bd207712 100644 --- a/core/state-machine/src/lib.rs +++ b/core/state-machine/src/lib.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Substrate state machine implementation. -// end::description[] #![warn(missing_docs)] @@ -32,15 +30,16 @@ extern crate substrate_trie; extern crate parking_lot; extern crate heapsize; -#[cfg_attr(test, macro_use)] extern crate substrate_primitives as primitives; +#[cfg_attr(test, macro_use)] +extern crate substrate_primitives as primitives; extern crate parity_codec as codec; extern crate substrate_trie as trie; -use std::fmt; +use std::{fmt, panic::UnwindSafe}; use hash_db::Hasher; use heapsize::HeapSizeOf; -use codec::Decode; -use primitives::storage::well_known_keys; +use codec::{Decode, Encode}; +use primitives::{storage::well_known_keys, NativeOrEncoded, NeverNativeValue}; pub mod backend; mod changes_trie; @@ -55,18 +54,19 @@ pub use trie::{TrieMut, TrieDBMut, DBValue, MemoryDB}; pub use testing::TestExternalities; pub use ext::Ext; pub use backend::Backend; -pub use changes_trie::{Storage as ChangesTrieStorage, +pub use changes_trie::{ + AnchorBlockId as ChangesTrieAnchorBlockId, + Storage as ChangesTrieStorage, RootsStorage as ChangesTrieRootsStorage, InMemoryStorage as InMemoryChangesTrieStorage, key_changes, key_changes_proof, key_changes_proof_check, - prune as prune_changes_tries}; + prune as prune_changes_tries, + oldest_non_pruned_trie as oldest_non_pruned_changes_trie}; pub use overlayed_changes::OverlayedChanges; -pub use trie_backend_essence::Storage; +pub use proving_backend::{create_proof_check_backend, create_proof_check_backend_storage}; +pub use trie_backend_essence::{TrieBackendStorage, Storage}; pub use trie_backend::TrieBackend; -/// Default num of pages for the heap -const DEFAULT_HEAP_PAGES :u64 = 1024; - /// State Machine Error bound. /// /// This should reflect WASM error type bound for future compatibility. @@ -97,10 +97,15 @@ impl fmt::Display for ExecutionError { /// Externalities: pinned to specific active address. pub trait Externalities { - /// Read storage of current contract being called. + /// Read runtime storage. fn storage(&self, key: &[u8]) -> Option>; - /// Read child storage of current contract being called. + /// Get storage value hash. This may be optimized for large values. + fn storage_hash(&self, key: &[u8]) -> Option { + self.storage(key).map(|v| H::hash(&v)) + } + + /// Read child runtime storage. fn child_storage(&self, storage_key: &[u8], key: &[u8]) -> Option>; /// Set storage entry `key` of current contract being called (effective immediately). @@ -156,8 +161,8 @@ pub trait Externalities { /// Returns None if key provided is not a storage key. This can due to not being started with CHILD_STORAGE_KEY_PREFIX, or the trie implementation regards the key as invalid. fn child_storage_root(&mut self, storage_key: &[u8]) -> Option>; - /// Get the change trie root of the current storage overlay at given block. - fn storage_changes_root(&mut self, block: u64) -> Option where H::Out: Ord; + /// Get the change trie root of the current storage overlay at a block wth given parent. + fn storage_changes_root(&mut self, parent: H::Out, parent_num: u64) -> Option where H::Out: Ord; } /// Code execution engine. @@ -167,15 +172,14 @@ pub trait CodeExecutor: Sized + Send + Sync { /// Call a given method in the runtime. Returns a tuple of the result (either the output data /// or an execution error) together with a `bool`, which is true if native execution was used. - fn call>( + fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> R + UnwindSafe>( &self, ext: &mut E, - heap_pages: usize, - code: &[u8], method: &str, data: &[u8], - use_native: bool - ) -> (Result, Self::Error>, bool); + use_native: bool, + native_call: Option, + ) -> (Result, Self::Error>, bool); } /// Strategy for executing a call into the runtime. @@ -190,6 +194,7 @@ pub enum ExecutionStrategy { } /// Like `ExecutionStrategy` only it also stores a handler in case of consensus failure. +#[derive(Clone)] pub enum ExecutionManager { /// Execute with the native equivalent if it is compatible with the given wasm module; otherwise fall back to the wasm. NativeWhenPossible, @@ -210,12 +215,26 @@ impl<'a, F> From<&'a ExecutionManager> for ExecutionStrategy { } /// Evaluate to ExecutionManager::NativeWhenPossible, without having to figure out the type. -pub fn native_when_possible() -> ExecutionManager, E>, Result, E>)->Result, E>> { +pub fn native_when_possible() -> + ExecutionManager< + fn( + Result, E>, + Result, E> + ) -> Result, E> + > +{ ExecutionManager::NativeWhenPossible } /// Evaluate to ExecutionManager::NativeWhenPossible, without having to figure out the type. -pub fn always_wasm() -> ExecutionManager, E>, Result, E>)->Result, E>> { +pub fn always_wasm() -> + ExecutionManager< + fn( + Result, E>, + Result, E> + ) -> Result, E> + > +{ ExecutionManager::AlwaysWasm } @@ -243,7 +262,9 @@ where T: ChangesTrieStorage, H::Out: Ord + HeapSizeOf, { - execute_using_consensus_failure_handler( + // We are not giving a native call and thus we are sure that the result can never be a native + // value. + execute_using_consensus_failure_handler::<_, _, _, _, _, NeverNativeValue, fn() -> NeverNativeValue>( backend, changes_trie_storage, overlay, @@ -254,11 +275,22 @@ where ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm, ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible, ExecutionStrategy::Both => ExecutionManager::Both(|wasm_result, native_result| { - warn!("Consensus error between wasm {:?} and native {:?}. Using wasm.", wasm_result, native_result); + warn!( + "Consensus error between wasm {:?} and native {:?}. Using wasm.", + wasm_result, + native_result + ); wasm_result }), }, + true, + None, ) + .map(|(result, storage_tx, changes_tx)| ( + result.into_encoded(), + storage_tx.expect("storage_tx is always computed when compute_tx is true; qed"), + changes_tx, + )) } /// Execute a call using the given state backend, overlayed changes, and call executor. @@ -269,7 +301,9 @@ where /// /// Note: changes to code will be in place if this call is made again. For running partial /// blocks (e.g. a transaction at a time), ensure a different method is used. -pub fn execute_using_consensus_failure_handler( +pub fn execute_using_consensus_failure_handler< + H, B, T, Exec, Handler, R: Decode + Encode + PartialEq, NC: FnOnce() -> R + UnwindSafe +>( backend: &B, changes_trie_storage: Option<&T>, overlay: &mut OverlayedChanges, @@ -277,25 +311,22 @@ pub fn execute_using_consensus_failure_handler( method: &str, call_data: &[u8], manager: ExecutionManager, -) -> Result<(Vec, B::Transaction, Option>), Box> + compute_tx: bool, + mut native_call: Option, +) -> Result<(NativeOrEncoded, Option, Option>), Box> where H: Hasher, Exec: CodeExecutor, B: Backend, T: ChangesTrieStorage, H::Out: Ord + HeapSizeOf, - Handler: FnOnce(Result, Exec::Error>, Result, Exec::Error>) -> Result, Exec::Error> + Handler: FnOnce( + Result, Exec::Error>, + Result, Exec::Error> + ) -> Result, Exec::Error> { let strategy: ExecutionStrategy = (&manager).into(); - // make a copy. - let code = try_read_overlay_value(overlay, backend, well_known_keys::CODE)? - .ok_or_else(|| Box::new(ExecutionError::CodeEntryDoesNotExist) as Box)? - .to_vec(); - - let heap_pages = try_read_overlay_value(overlay, backend, well_known_keys::HEAP_PAGES)? - .and_then(|v| u64::decode(&mut &v[..])).unwrap_or(DEFAULT_HEAP_PAGES) as usize; - // read changes trie configuration. The reason why we're doing it here instead of the // `OverlayedChanges` constructor is that we need proofs for this read as a part of // proof-of-execution on light clients. And the proof is recorded by the backend which @@ -317,18 +348,21 @@ where let (result, was_native, storage_delta, changes_delta) = { let ((result, was_native), (storage_delta, changes_delta)) = { let mut externalities = ext::Ext::new(overlay, backend, changes_trie_storage); - ( - exec.call( - &mut externalities, - heap_pages, - &code, - method, - call_data, - // attempt to run native first, if we're not directed to run wasm only - strategy != ExecutionStrategy::AlwaysWasm, - ), - externalities.transaction() - ) + let retval = exec.call( + &mut externalities, + method, + call_data, + // attempt to run native first, if we're not directed to run wasm only + strategy != ExecutionStrategy::AlwaysWasm, + native_call.take(), + ); + let (storage_delta, changes_delta) = if compute_tx { + let (storage_delta, changes_delta) = externalities.transaction(); + (Some(storage_delta), changes_delta) + } else { + (None, None) + }; + (retval, (storage_delta, changes_delta)) }; (result, was_native, storage_delta, changes_delta) }; @@ -342,24 +376,27 @@ where let (wasm_result, wasm_storage_delta, wasm_changes_delta) = { let ((result, _), (storage_delta, changes_delta)) = { let mut externalities = ext::Ext::new(overlay, backend, changes_trie_storage); - ( - exec.call( - &mut externalities, - heap_pages, - &code, - method, - call_data, - false, - ), - externalities.transaction() - ) + let retval = exec.call( + &mut externalities, + method, + call_data, + false, + native_call, + ); + let (storage_delta, changes_delta) = if compute_tx { + let (storage_delta, changes_delta) = externalities.transaction(); + (Some(storage_delta), changes_delta) + } else { + (None, None) + }; + (retval, (storage_delta, changes_delta)) }; (result, storage_delta, changes_delta) }; - if (result.is_ok() && wasm_result.is_ok() && result.as_ref().unwrap() == wasm_result.as_ref().unwrap()/* && delta == wasm_delta*/) - || (result.is_err() && wasm_result.is_err()) - { + if (result.is_ok() && wasm_result.is_ok() + && result.as_ref().ok() == wasm_result.as_ref().ok()) + || result.is_err() && wasm_result.is_err() { (result, storage_delta, changes_delta) } else { // Consensus error. @@ -380,6 +417,25 @@ where } /// Prove execution using the given state backend, overlayed changes, and call executor. +pub fn prove_execution( + backend: B, + overlay: &mut OverlayedChanges, + exec: &Exec, + method: &str, + call_data: &[u8], +) -> Result<(Vec, Vec>), Box> +where + B: Backend, + H: Hasher, + Exec: CodeExecutor, + H::Out: Ord + HeapSizeOf, +{ + let trie_backend = backend.try_into_trie_backend() + .ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box)?; + prove_execution_on_trie_backend(&trie_backend, overlay, exec, method, call_data) +} + +/// Prove execution using the given trie backend, overlayed changes, and call executor. /// Produces a state-backend-specific "transaction" which can be used to apply the changes /// to the backing store, such as the disk. /// Execution proof is the set of all 'touched' storage DBValues from the backend. @@ -388,33 +444,35 @@ where /// /// Note: changes to code will be in place if this call is made again. For running partial /// blocks (e.g. a transaction at a time), ensure a different method is used. -pub fn prove_execution( - backend: B, +pub fn prove_execution_on_trie_backend( + trie_backend: &TrieBackend, overlay: &mut OverlayedChanges, exec: &Exec, method: &str, call_data: &[u8], ) -> Result<(Vec, Vec>), Box> where - B: Backend, + S: trie_backend_essence::TrieBackendStorage, H: Hasher, Exec: CodeExecutor, H::Out: Ord + HeapSizeOf, { - let trie_backend = backend.try_into_trie_backend() - .ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box)?; let proving_backend = proving_backend::ProvingBackend::new(trie_backend); - let (result, _, _) = execute::, _>( + let (result, _, _) = execute_using_consensus_failure_handler:: + , _, _, NeverNativeValue, fn() -> NeverNativeValue> + ( &proving_backend, None, overlay, exec, method, call_data, - ExecutionStrategy::NativeWhenPossible + native_when_possible(), + false, + None, )?; let proof = proving_backend.extract_proof(); - Ok((result, proof)) + Ok((result.into_encoded(), proof)) } /// Check execution proof, generated by `prove_execution` call. @@ -431,9 +489,36 @@ where Exec: CodeExecutor, H::Out: Ord + HeapSizeOf, { - let backend = proving_backend::create_proof_check_backend::(root.into(), proof)?; - execute::, _>(&backend, None, overlay, exec, method, call_data, ExecutionStrategy::NativeWhenPossible) - .map(|(result, _, _)| result) + let trie_backend = proving_backend::create_proof_check_backend::(root.into(), proof)?; + execution_proof_check_on_trie_backend(&trie_backend, overlay, exec, method, call_data) +} + +/// Check execution proof on proving backend, generated by `prove_execution` call. +pub fn execution_proof_check_on_trie_backend( + trie_backend: &TrieBackend, H>, + overlay: &mut OverlayedChanges, + exec: &Exec, + method: &str, + call_data: &[u8], +) -> Result, Box> +where + H: Hasher, + Exec: CodeExecutor, + H::Out: Ord + HeapSizeOf, +{ + execute_using_consensus_failure_handler:: + , _, _, NeverNativeValue, fn() -> NeverNativeValue> + ( + trie_backend, + None, + overlay, + exec, + method, + call_data, + native_when_possible(), + false, + None, + ).map(|(result, _, _)| result.into_encoded()) } /// Generate storage read proof. @@ -444,11 +529,23 @@ pub fn prove_read( where B: Backend, H: Hasher, - H::Out: Ord + HeapSizeOf { let trie_backend = backend.try_into_trie_backend() .ok_or_else(|| Box::new(ExecutionError::UnableToGenerateProof) as Box)?; + prove_read_on_trie_backend(&trie_backend, key) +} + +/// Generate storage read proof on pre-created trie backend. +pub fn prove_read_on_trie_backend( + trie_backend: &TrieBackend, + key: &[u8] +) -> Result<(Option>, Vec>), Box> +where + S: trie_backend_essence::TrieBackendStorage, + H: Hasher, + H::Out: Ord + HeapSizeOf +{ let proving_backend = proving_backend::ProvingBackend::<_, H>::new(trie_backend); let result = proving_backend.storage(key).map_err(|e| Box::new(e) as Box)?; Ok((result, proving_backend.extract_proof())) @@ -462,11 +559,22 @@ pub fn read_proof_check( ) -> Result>, Box> where H: Hasher, + H::Out: Ord + HeapSizeOf +{ + let proving_backend = proving_backend::create_proof_check_backend::(root, proof)?; + read_proof_check_on_proving_backend(&proving_backend, key) +} +/// Check storage read proof on pre-created proving backend. +pub fn read_proof_check_on_proving_backend( + proving_backend: &TrieBackend, H>, + key: &[u8], +) -> Result>, Box> +where + H: Hasher, H::Out: Ord + HeapSizeOf { - let backend = proving_backend::create_proof_check_backend::(root, proof)?; - backend.storage(key).map_err(|e| Box::new(e) as Box) + proving_backend.storage(key).map_err(|e| Box::new(e) as Box) } /// Sets overlayed changes' changes trie configuration. Returns error if configuration @@ -517,7 +625,7 @@ mod tests { InMemoryStorage as InMemoryChangesTrieStorage, Configuration as ChangesTrieConfig, }; - use primitives::{Blake2Hasher}; + use primitives::Blake2Hasher; struct DummyCodeExecutor { change_changes_trie_config: bool, @@ -529,26 +637,41 @@ mod tests { impl CodeExecutor for DummyCodeExecutor { type Error = u8; - fn call>( + fn call, R: Encode + Decode + PartialEq, NC: FnOnce() -> R>( &self, ext: &mut E, - _heap_pages: usize, - _code: &[u8], _method: &str, _data: &[u8], - use_native: bool - ) -> (Result, Self::Error>, bool) { + use_native: bool, + _native_call: Option, + ) -> (Result, Self::Error>, bool) { if self.change_changes_trie_config { - ext.place_storage(well_known_keys::CHANGES_TRIE_CONFIG.to_vec(), Some(ChangesTrieConfig { - digest_interval: 777, - digest_levels: 333, - }.encode())); + ext.place_storage( + well_known_keys::CHANGES_TRIE_CONFIG.to_vec(), + Some( + ChangesTrieConfig { + digest_interval: 777, + digest_levels: 333, + }.encode() + ) + ); } let using_native = use_native && self.native_available; match (using_native, self.native_succeeds, self.fallback_succeeds) { - (true, true, _) | (false, _, true) => - (Ok(vec![ext.storage(b"value1").unwrap()[0] + ext.storage(b"value2").unwrap()[0]]), using_native), + (true, true, _) | (false, _, true) => { + ( + Ok( + NativeOrEncoded::Encoded( + vec![ + ext.storage(b"value1").unwrap()[0] + + ext.storage(b"value2").unwrap()[0] + ] + ) + ), + using_native + ) + }, _ => (Err(0), using_native), } } @@ -577,7 +700,7 @@ mod tests { #[test] fn dual_execution_strategy_detects_consensus_failure() { let mut consensus_failed = false; - assert!(execute_using_consensus_failure_handler( + assert!(execute_using_consensus_failure_handler::<_, _, _, _, _, NeverNativeValue, fn() -> NeverNativeValue>( &trie_backend::tests::test_trie(), Some(&InMemoryChangesTrieStorage::new()), &mut Default::default(), @@ -594,6 +717,8 @@ mod tests { println!("HELLO!"); we }), + true, + None, ).is_err()); assert!(consensus_failed); } diff --git a/core/state-machine/src/overlayed_changes.rs b/core/state-machine/src/overlayed_changes.rs index 239dc0b43867c407b881fa6e9fc0c016e74e5fa7..3a208ad3e2c01477ec568ff3a9eba381274dac80 100644 --- a/core/state-machine/src/overlayed_changes.rs +++ b/core/state-machine/src/overlayed_changes.rs @@ -44,7 +44,7 @@ pub struct OverlayedValue { /// Current value. None if value has been deleted. pub value: Option>, /// The set of extinsic indices where the values has been changed. - /// Is filled only if runtime ahs announced changes trie support. + /// Is filled only if runtime has announced changes trie support. pub extrinsics: Option>, } @@ -82,6 +82,11 @@ impl OverlayedChangeSet { } impl OverlayedChanges { + /// Whether the overlayed changes are empty. + pub fn is_empty(&self) -> bool { + self.prospective.is_empty() && self.committed.is_empty() + } + /// Sets the changes trie configuration. /// /// Returns false if configuration has been set already and we now trying diff --git a/core/state-machine/src/proving_backend.rs b/core/state-machine/src/proving_backend.rs index fb782616facc2de23b0b3468d05822d5c0d97274..2ba2d886dbfbcde92fd1f3b2dd3a07c7ce79ea7c 100644 --- a/core/state-machine/src/proving_backend.rs +++ b/core/state-machine/src/proving_backend.rs @@ -84,14 +84,14 @@ impl<'a, S, H> ProvingBackendEssence<'a, S, H> /// Patricia trie-based backend which also tracks all touched storage trie values. /// These can be sent to remote node and used as a proof of execution. -pub struct ProvingBackend, H: Hasher> { - backend: TrieBackend, +pub struct ProvingBackend<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> { + backend: &'a TrieBackend, proof_recorder: RefCell>, } -impl, H: Hasher> ProvingBackend { +impl<'a, S: 'a + TrieBackendStorage, H: 'a + Hasher> ProvingBackend<'a, S, H> { /// Create new proving backend. - pub fn new(backend: TrieBackend) -> Self { + pub fn new(backend: &'a TrieBackend) -> Self { ProvingBackend { backend, proof_recorder: RefCell::new(Recorder::new()), @@ -108,10 +108,10 @@ impl, H: Hasher> ProvingBackend { } } -impl Backend for ProvingBackend +impl<'a, S, H> Backend for ProvingBackend<'a, S, H> where - S: TrieBackendStorage, - H: Hasher, + S: 'a + TrieBackendStorage, + H: 'a + Hasher, H::Out: Ord + HeapSizeOf, { type Error = String; @@ -146,6 +146,10 @@ impl Backend for ProvingBackend self.backend.pairs() } + fn keys(&self, prefix: &Vec) -> Vec> { + self.backend.keys(prefix) + } + fn storage_root(&self, delta: I) -> (H::Out, MemoryDB) where I: IntoIterator, Option>)> { @@ -174,10 +178,7 @@ where H: Hasher, H::Out: HeapSizeOf, { - let mut db = MemoryDB::default(); // TODO: use new for correctness - for item in proof { - db.insert(&item); - } + let db = create_proof_check_backend_storage(proof); if !db.contains(&root) { return Err(Box::new(ExecutionError::InvalidProof) as Box); @@ -186,6 +187,21 @@ where Ok(TrieBackend::new(db, root)) } +/// Create in-memory storage of proof check backend. +pub fn create_proof_check_backend_storage( + proof: Vec> +) -> MemoryDB +where + H: Hasher, + H::Out: HeapSizeOf, +{ + let mut db = MemoryDB::default(); // TODO: use new for correctness + for item in proof { + db.insert(&item); + } + db +} + #[cfg(test)] mod tests { use backend::{InMemory}; @@ -193,18 +209,20 @@ mod tests { use super::*; use primitives::{Blake2Hasher}; - fn test_proving() -> ProvingBackend, Blake2Hasher> { - ProvingBackend::new(test_trie()) + fn test_proving<'a>(trie_backend: &'a TrieBackend, Blake2Hasher>) -> ProvingBackend<'a, MemoryDB, Blake2Hasher> { + ProvingBackend::new(trie_backend) } #[test] fn proof_is_empty_until_value_is_read() { - assert!(test_proving().extract_proof().is_empty()); + let trie_backend = test_trie(); + assert!(test_proving(&trie_backend).extract_proof().is_empty()); } #[test] fn proof_is_non_empty_after_value_is_read() { - let backend = test_proving(); + let trie_backend = test_trie(); + let backend = test_proving(&trie_backend); assert_eq!(backend.storage(b"key").unwrap(), Some(b"value".to_vec())); assert!(!backend.extract_proof().is_empty()); } @@ -218,7 +236,7 @@ mod tests { #[test] fn passes_throgh_backend_calls() { let trie_backend = test_trie(); - let proving_backend = test_proving(); + let proving_backend = test_proving(&trie_backend); assert_eq!(trie_backend.storage(b"key").unwrap(), proving_backend.storage(b"key").unwrap()); assert_eq!(trie_backend.pairs(), proving_backend.pairs()); @@ -241,7 +259,7 @@ mod tests { assert_eq!(in_memory_root, trie_root); (0..64).for_each(|i| assert_eq!(trie.storage(&[i]).unwrap().unwrap(), vec![i])); - let proving = ProvingBackend::new(trie); + let proving = ProvingBackend::new(&trie); assert_eq!(proving.storage(&[42]).unwrap().unwrap(), vec![42]); let proof = proving.extract_proof(); diff --git a/core/state-machine/src/testing.rs b/core/state-machine/src/testing.rs index 75ad342b6bbc234237fc5c94fb0d3860272d0f4a..b9f14f18e5a0f38cf81859131395e611ed30d6cb 100644 --- a/core/state-machine/src/testing.rs +++ b/core/state-machine/src/testing.rs @@ -22,8 +22,9 @@ use hash_db::Hasher; use heapsize::HeapSizeOf; use trie::trie_root; use backend::InMemory; -use changes_trie::{compute_changes_trie_root, InMemoryStorage as ChangesTrieInMemoryStorage}; -use primitives::storage::well_known_keys::CHANGES_TRIE_CONFIG; +use changes_trie::{compute_changes_trie_root, InMemoryStorage as ChangesTrieInMemoryStorage, AnchorBlockId}; +use primitives::storage::well_known_keys::{CHANGES_TRIE_CONFIG, CODE, HEAP_PAGES}; +use codec::Encode; use super::{Externalities, OverlayedChanges}; /// Simple HashMap-based Externalities impl. @@ -31,11 +32,17 @@ pub struct TestExternalities where H::Out: HeapSizeOf { inner: HashMap, Vec>, changes_trie_storage: ChangesTrieInMemoryStorage, changes: OverlayedChanges, + code: Vec, } impl TestExternalities where H::Out: HeapSizeOf { /// Create a new instance of `TestExternalities` pub fn new(inner: HashMap, Vec>) -> Self { + Self::new_with_code(&[], inner) + } + + /// Create a new instance of `TestExternalities` + pub fn new_with_code(code: &[u8], inner: HashMap, Vec>) -> Self { let mut overlay = OverlayedChanges::default(); super::set_changes_trie_config( &mut overlay, @@ -47,6 +54,7 @@ impl TestExternalities where H::Out: HeapSizeOf { inner, changes_trie_storage: ChangesTrieInMemoryStorage::new(), changes: overlay, + code: code.to_vec(), } } @@ -94,13 +102,18 @@ impl From< HashMap, Vec> > for TestExternalities where inner: hashmap, changes_trie_storage: ChangesTrieInMemoryStorage::new(), changes: Default::default(), + code: Default::default(), } } } impl Externalities for TestExternalities where H::Out: Ord + HeapSizeOf { fn storage(&self, key: &[u8]) -> Option> { - self.inner.get(key).map(|x| x.to_vec()) + match key { + CODE => Some(self.code.clone()), + HEAP_PAGES => Some(8u64.encode()), + _ => self.inner.get(key).map(|x| x.to_vec()), + } } fn child_storage(&self, _storage_key: &[u8], _key: &[u8]) -> Option> { @@ -136,12 +149,12 @@ impl Externalities for TestExternalities where H::Out: Ord + He None } - fn storage_changes_root(&mut self, block: u64) -> Option { + fn storage_changes_root(&mut self, parent: H::Out, parent_num: u64) -> Option { compute_changes_trie_root::<_, _, H>( &InMemory::default(), Some(&self.changes_trie_storage), &self.changes, - block, + &AnchorBlockId { hash: parent, number: parent_num }, ).map(|(root, _)| root.clone()) } } diff --git a/core/state-machine/src/trie_backend.rs b/core/state-machine/src/trie_backend.rs index 883122859f1d1166589be8fd32bf0ebb113da43f..9d4383a96a8567d3b6bd949f910c6e362669e841 100644 --- a/core/state-machine/src/trie_backend.rs +++ b/core/state-machine/src/trie_backend.rs @@ -49,6 +49,11 @@ impl, H: Hasher> TrieBackend where H::Out: HeapSi pub fn root(&self) -> &H::Out { self.essence.root() } + + /// Consumes self and returns underlying storage. + pub fn into_storage(self) -> S { + self.essence.into_storage() + } } impl super::Error for String {} @@ -100,6 +105,26 @@ impl, H: Hasher> Backend for TrieBackend where } } + fn keys(&self, prefix: &Vec) -> Vec> { + let mut read_overlay = MemoryDB::default(); // TODO: use new for correctness + let eph = Ephemeral::new(self.essence.backend_storage(), &mut read_overlay); + + let collect_all = || -> Result<_, Box>> { + let trie = TrieDB::::new(&eph, self.essence.root())?; + let mut v = Vec::new(); + for x in trie.iter()? { + let (key, _) = x?; + if key.starts_with(prefix) { + v.push(key.to_vec()); + } + } + + Ok(v) + }; + + collect_all().map_err(|e| debug!(target: "trie", "Error extracting trie keys: {}", e)).unwrap_or_default() + } + fn storage_root(&self, delta: I) -> (H::Out, MemoryDB) where I: IntoIterator, Option>)> { diff --git a/core/state-machine/src/trie_backend_essence.rs b/core/state-machine/src/trie_backend_essence.rs index 74ac5e6e920784f36e5f1e5245591ac89c3845b6..7bb709926a79e0ca7fb005ed82fdb3b8c4f9c24c 100644 --- a/core/state-machine/src/trie_backend_essence.rs +++ b/core/state-machine/src/trie_backend_essence.rs @@ -55,6 +55,11 @@ impl, H: Hasher> TrieBackendEssence where H::Out: &self.root } + /// Consumes self and returns underlying storage. + pub fn into_storage(self) -> S { + self.storage + } + /// Get the value of storage at given key. pub fn storage(&self, key: &[u8]) -> Result>, String> { let mut read_overlay = MemoryDB::default(); @@ -269,6 +274,7 @@ impl<'a, /// Key-value pairs storage that is used by trie backend essence. pub trait TrieBackendStorage: Send + Sync { + /// Get the value stored at key. fn get(&self, key: &H::Out) -> Result, String>; } diff --git a/core/telemetry/Cargo.toml b/core/telemetry/Cargo.toml index c74cb956d7ed2d9185fea51d9688a8c2f60c13bb..7dda91279254c8d8b8fff57df67f3eab3edd5321 100644 --- a/core/telemetry/Cargo.toml +++ b/core/telemetry/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Parity Technologies "] description = "Telemetry utils" [dependencies] -parking_lot = "0.4" +parking_lot = "0.7.1" lazy_static = "1.0" log = "0.4" slog = "^2" diff --git a/core/telemetry/README.adoc b/core/telemetry/README.adoc deleted file mode 100644 index 9759c5bc50bdd83a8fa012fc5298e2a563735496..0000000000000000000000000000000000000000 --- a/core/telemetry/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Telemetry - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/telemetry/src/lib.rs b/core/telemetry/src/lib.rs index 8d0ddb1ac9076a25c59d36a7b4201609c3a2bcd2..ab7964ed1644f2105e848949424a5ccb5d9729ff 100644 --- a/core/telemetry/src/lib.rs +++ b/core/telemetry/src/lib.rs @@ -14,14 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Telemetry utils. //! //! `telemetry` macro may be used anywhere in the Substrate codebase //! in order to send real-time logging information to the telemetry //! server (if there is one). We use the async drain adapter of `slog` //! so that the logging thread doesn't get held up at all. -// end::description[] extern crate parking_lot; extern crate ws; @@ -29,7 +27,7 @@ extern crate slog_async; extern crate slog_json; #[macro_use] extern crate log; -#[macro_use(o, kv)] +#[macro_use(o)] extern crate slog; extern crate slog_scope; @@ -68,7 +66,7 @@ pub fn init_telemetry(config: TelemetryConfig) -> slog_scope::GlobalLoggerGuard thread::spawn(move || { loop { - trace!(target: "telemetry", "Connecting to Telemetry..."); + trace!(target: "telemetry", "Connecting to Telemetry... {:?}", config.url); let _ = ws::connect(config.url.as_str(), |out| Connection::new(out, &*out_sync, &config)); thread::sleep(time::Duration::from_millis(5000)); diff --git a/core/test-client/Cargo.toml b/core/test-client/Cargo.toml index aa48f95211131f293a350624736eed429344e7d3..b5eb8a66f58e5a2884e62d4e44b1e26bdcdca5b2 100644 --- a/core/test-client/Cargo.toml +++ b/core/test-client/Cargo.toml @@ -5,11 +5,11 @@ authors = ["Parity Technologies "] [dependencies] substrate-client = { path = "../client" } -parity-codec = "2.1" +parity-codec = "2.2" substrate-executor = { path = "../executor" } substrate-consensus-common = { path = "../consensus/common" } substrate-keyring = { path = "../../core/keyring" } substrate-primitives = { path = "../primitives" } +substrate-state-machine = { path = "../state-machine" } substrate-test-runtime = { path = "../test-runtime" } sr-primitives = { path = "../sr-primitives" } - diff --git a/core/test-client/README.adoc b/core/test-client/README.adoc deleted file mode 100644 index e56c4c7f66e7ca2f0fcba9969e6b4911ff11ac1a..0000000000000000000000000000000000000000 --- a/core/test-client/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Test client - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/test-client/src/block_builder_ext.rs b/core/test-client/src/block_builder_ext.rs index 11dd859c07d3e27835caf29c6ede6aa8f224e62d..5803c5303d4e5af4b9ec2a04916289d0845d7fda 100644 --- a/core/test-client/src/block_builder_ext.rs +++ b/core/test-client/src/block_builder_ext.rs @@ -20,8 +20,8 @@ use codec; use client; use keyring; use runtime; - -use primitives::{Blake2Hasher}; +use runtime_primitives::traits::ProvideRuntimeApi; +use client::block_builder::api::BlockBuilder; /// Extension trait for test block builder. pub trait BlockBuilderExt { @@ -29,10 +29,9 @@ pub trait BlockBuilderExt { fn push_transfer(&mut self, transfer: runtime::Transfer) -> Result<(), client::error::Error>; } -impl<'a, B, E> BlockBuilderExt for client::block_builder::BlockBuilder<'a, B, E, runtime::Block, Blake2Hasher> - where - B: client::backend::Backend, - E: client::CallExecutor + Clone, +impl<'a, A> BlockBuilderExt for client::block_builder::BlockBuilder<'a, runtime::Block, (), A> where + A: ProvideRuntimeApi + client::blockchain::HeaderBackend + 'a, + A::Api: BlockBuilder { fn push_transfer(&mut self, transfer: runtime::Transfer) -> Result<(), client::error::Error> { self.push(sign_tx(transfer)) @@ -41,5 +40,5 @@ impl<'a, B, E> BlockBuilderExt for client::block_builder::BlockBuilder<'a, B, E, fn sign_tx(transfer: runtime::Transfer) -> runtime::Extrinsic { let signature = keyring::Keyring::from_raw_public(transfer.from.to_fixed_bytes()).unwrap().sign(&codec::Encode::encode(&transfer)).into(); - runtime::Extrinsic { transfer, signature } + runtime::Extrinsic::Transfer(transfer, signature) } diff --git a/core/test-client/src/client_ext.rs b/core/test-client/src/client_ext.rs index 61133c4d9da811328ffa011537aefc82c1421cdf..f766f427cd724494f7c34484977ce56af7bc4ddc 100644 --- a/core/test-client/src/client_ext.rs +++ b/core/test-client/src/client_ext.rs @@ -17,48 +17,71 @@ //! Client extension for tests. use client::{self, Client}; -use consensus::{ImportBlock, BlockImport, BlockOrigin}; +use consensus::{ImportBlock, BlockImport, BlockOrigin, Error as ConsensusError, ForkChoiceStrategy}; +use runtime_primitives::Justification; use runtime_primitives::generic::BlockId; use primitives::Blake2Hasher; use runtime; /// Extension trait for a test client. pub trait TestClient: Sized { - /// Justify and import block to the chain. No finality. - fn justify_and_import(&self, origin: BlockOrigin, block: runtime::Block) - -> client::error::Result<()>; + /// Import block to the chain. No finality. + fn import(&self, origin: BlockOrigin, block: runtime::Block) + -> Result<(), ConsensusError>; + + /// Import block with justification, finalizes block. + fn import_justified(&self, origin: BlockOrigin, block: runtime::Block, justification: Justification) + -> Result<(), ConsensusError>; /// Finalize a block. - fn finalize_block(&self, id: BlockId) -> client::error::Result<()>; + fn finalize_block(&self, id: BlockId, justification: Option) -> client::error::Result<()>; /// Returns hash of the genesis block. fn genesis_hash(&self) -> runtime::Hash; } -impl TestClient for Client +impl TestClient for Client where B: client::backend::Backend, E: client::CallExecutor, - Self: BlockImport + Self: BlockImport, { - fn justify_and_import(&self, origin: BlockOrigin, block: runtime::Block) - -> client::error::Result<()> + fn import(&self, origin: BlockOrigin, block: runtime::Block) + -> Result<(), ConsensusError> { let import = ImportBlock { origin, header: block.header, - external_justification: vec![], - post_runtime_digests: vec![], + justification: None, + post_digests: vec![], body: Some(block.extrinsics), finalized: false, auxiliary: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, + }; + + self.import_block(import, None).map(|_| ()) + } + + fn import_justified(&self, origin: BlockOrigin, block: runtime::Block, justification: Justification) + -> Result<(), ConsensusError> + { + let import = ImportBlock { + origin, + header: block.header, + justification: Some(justification), + post_digests: vec![], + body: Some(block.extrinsics), + finalized: true, + auxiliary: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, }; self.import_block(import, None).map(|_| ()) } - fn finalize_block(&self, id: BlockId) -> client::error::Result<()> { - self.finalize_block(id, true) + fn finalize_block(&self, id: BlockId, justification: Option) -> client::error::Result<()> { + self.finalize_block(id, justification, true) } fn genesis_hash(&self) -> runtime::Hash { diff --git a/core/test-client/src/lib.rs b/core/test-client/src/lib.rs index 98887c2b6e35c0c1955cf293daa92e4eed4f1fc2..c2cd79f3a1a82dedbd1b3c776b1553bf69cf94b5 100644 --- a/core/test-client/src/lib.rs +++ b/core/test-client/src/lib.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Client testing utilities. -// end::description[] #![warn(missing_docs)] @@ -29,6 +27,7 @@ pub extern crate substrate_client as client; pub extern crate substrate_keyring as keyring; pub extern crate substrate_test_runtime as runtime; pub extern crate substrate_consensus_common as consensus; +extern crate substrate_state_machine as state_machine; pub mod client_ext; pub mod trait_tests; @@ -51,7 +50,12 @@ mod local_executor { #![allow(missing_docs)] use super::runtime; // TODO: change the macro and pass in the `BlakeHasher` that dispatch needs from here instead - native_executor_instance!(pub LocalExecutor, runtime::api::dispatch, runtime::native_version, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm")); + native_executor_instance!( + pub LocalExecutor, + runtime::api::dispatch, + runtime::native_version, + include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm") + ); } /// Native executor used for tests. @@ -67,12 +71,14 @@ pub type Executor = client::LocalCallExecutor< >; /// Creates new client instance used for tests. -pub fn new() -> client::Client { +pub fn new() -> client::Client { new_with_backend(Arc::new(Backend::new()), false) } /// Creates new test client instance that suports changes trie creation. -pub fn new_with_changes_trie() -> client::Client { +pub fn new_with_changes_trie() + -> client::Client +{ new_with_backend(Arc::new(Backend::new()), true) } @@ -81,9 +87,12 @@ pub fn new_with_changes_trie() -> client::Client( backend: Arc, support_changes_trie: bool -) -> client::Client>, runtime::Block> - where - B: backend::LocalBackend, +) -> client::Client< + B, + client::LocalCallExecutor>, + runtime::Block, + runtime::RuntimeApi +> where B: backend::LocalBackend { let executor = NativeExecutor::new(); client::new_with_backend(backend, executor, genesis_storage(support_changes_trie)).unwrap() diff --git a/core/test-client/src/trait_tests.rs b/core/test-client/src/trait_tests.rs index 3a05b78600003c324949c8f4e5528db1de57a415..aef6c7565474679f69fdc4321c70e51b460e822d 100644 --- a/core/test-client/src/trait_tests.rs +++ b/core/test-client/src/trait_tests.rs @@ -32,7 +32,7 @@ use runtime::{self, Transfer}; use runtime_primitives::generic::BlockId; /// helper to test the `leaves` implementation for various backends -pub fn test_leaves_for_backend(backend: Arc) where +pub fn test_leaves_for_backend(backend: Arc) where B: backend::LocalBackend, { // block tree: @@ -51,35 +51,35 @@ pub fn test_leaves_for_backend(backend: Arc) where // G -> A1 let a1 = client.new_block().unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a1.clone()).unwrap(); + client.import(BlockOrigin::Own, a1.clone()).unwrap(); assert_eq!( backend.blockchain().leaves().unwrap(), vec![a1.hash()]); // A1 -> A2 let a2 = client.new_block_at(&BlockId::Hash(a1.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a2.clone()).unwrap(); + client.import(BlockOrigin::Own, a2.clone()).unwrap(); assert_eq!( client.backend().blockchain().leaves().unwrap(), vec![a2.hash()]); // A2 -> A3 let a3 = client.new_block_at(&BlockId::Hash(a2.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a3.clone()).unwrap(); + client.import(BlockOrigin::Own, a3.clone()).unwrap(); assert_eq!( backend.blockchain().leaves().unwrap(), vec![a3.hash()]); // A3 -> A4 let a4 = client.new_block_at(&BlockId::Hash(a3.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a4.clone()).unwrap(); + client.import(BlockOrigin::Own, a4.clone()).unwrap(); assert_eq!( backend.blockchain().leaves().unwrap(), vec![a4.hash()]); // A4 -> A5 let a5 = client.new_block_at(&BlockId::Hash(a4.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a5.clone()).unwrap(); + client.import(BlockOrigin::Own, a5.clone()).unwrap(); assert_eq!( backend.blockchain().leaves().unwrap(), vec![a5.hash()]); @@ -94,21 +94,21 @@ pub fn test_leaves_for_backend(backend: Arc) where nonce: 0, }).unwrap(); let b2 = builder.bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, b2.clone()).unwrap(); + client.import(BlockOrigin::Own, b2.clone()).unwrap(); assert_eq!( backend.blockchain().leaves().unwrap(), vec![a5.hash(), b2.hash()]); // B2 -> B3 let b3 = client.new_block_at(&BlockId::Hash(b2.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, b3.clone()).unwrap(); + client.import(BlockOrigin::Own, b3.clone()).unwrap(); assert_eq!( backend.blockchain().leaves().unwrap(), vec![a5.hash(), b3.hash()]); // B3 -> B4 let b4 = client.new_block_at(&BlockId::Hash(b3.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, b4.clone()).unwrap(); + client.import(BlockOrigin::Own, b4.clone()).unwrap(); assert_eq!( backend.blockchain().leaves().unwrap(), vec![a5.hash(), b4.hash()]); @@ -123,7 +123,7 @@ pub fn test_leaves_for_backend(backend: Arc) where nonce: 1, }).unwrap(); let c3 = builder.bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, c3.clone()).unwrap(); + client.import(BlockOrigin::Own, c3.clone()).unwrap(); assert_eq!( backend.blockchain().leaves().unwrap(), vec![a5.hash(), b4.hash(), c3.hash()]); @@ -138,14 +138,14 @@ pub fn test_leaves_for_backend(backend: Arc) where nonce: 0, }).unwrap(); let d2 = builder.bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, d2.clone()).unwrap(); + client.import(BlockOrigin::Own, d2.clone()).unwrap(); assert_eq!( backend.blockchain().leaves().unwrap(), vec![a5.hash(), b4.hash(), c3.hash(), d2.hash()]); } -pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc) where +pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc) where B: backend::LocalBackend, { // block tree: @@ -157,23 +157,23 @@ pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc) where // G -> A1 let a1 = client.new_block().unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a1.clone()).unwrap(); + client.import(BlockOrigin::Own, a1.clone()).unwrap(); // A1 -> A2 let a2 = client.new_block_at(&BlockId::Hash(a1.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a2.clone()).unwrap(); + client.import(BlockOrigin::Own, a2.clone()).unwrap(); // A2 -> A3 let a3 = client.new_block_at(&BlockId::Hash(a2.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a3.clone()).unwrap(); + client.import(BlockOrigin::Own, a3.clone()).unwrap(); // A3 -> A4 let a4 = client.new_block_at(&BlockId::Hash(a3.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a4.clone()).unwrap(); + client.import(BlockOrigin::Own, a4.clone()).unwrap(); // A4 -> A5 let a5 = client.new_block_at(&BlockId::Hash(a4.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, a5.clone()).unwrap(); + client.import(BlockOrigin::Own, a5.clone()).unwrap(); // A1 -> B2 let mut builder = client.new_block_at(&BlockId::Hash(a1.hash())).unwrap(); @@ -185,15 +185,15 @@ pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc) where nonce: 0, }).unwrap(); let b2 = builder.bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, b2.clone()).unwrap(); + client.import(BlockOrigin::Own, b2.clone()).unwrap(); // B2 -> B3 let b3 = client.new_block_at(&BlockId::Hash(b2.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, b3.clone()).unwrap(); + client.import(BlockOrigin::Own, b3.clone()).unwrap(); // B3 -> B4 let b4 = client.new_block_at(&BlockId::Hash(b3.hash())).unwrap().bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, b4.clone()).unwrap(); + client.import(BlockOrigin::Own, b4.clone()).unwrap(); // // B2 -> C3 let mut builder = client.new_block_at(&BlockId::Hash(b2.hash())).unwrap(); @@ -205,7 +205,7 @@ pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc) where nonce: 1, }).unwrap(); let c3 = builder.bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, c3.clone()).unwrap(); + client.import(BlockOrigin::Own, c3.clone()).unwrap(); // A1 -> D2 let mut builder = client.new_block_at(&BlockId::Hash(a1.hash())).unwrap(); @@ -217,7 +217,7 @@ pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc) where nonce: 0, }).unwrap(); let d2 = builder.bake().unwrap(); - client.justify_and_import(BlockOrigin::Own, d2.clone()).unwrap(); + client.import(BlockOrigin::Own, d2.clone()).unwrap(); let genesis_hash = client.info().unwrap().chain.genesis_hash; diff --git a/core/test-runtime/Cargo.toml b/core/test-runtime/Cargo.toml index 6687c019f6886c465f2d2625e8e70e2a80b4d7f2..f7838450cc10f16798247368ee67e9d905bff59a 100644 --- a/core/test-runtime/Cargo.toml +++ b/core/test-runtime/Cargo.toml @@ -8,17 +8,21 @@ log = { version = "0.4", optional = true } hex-literal = { version = "0.1.0", optional = true } serde = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-keyring = { path = "../keyring", optional = true } +substrate-client = { path = "../client", default-features = false } substrate-primitives = { path = "../primitives", default-features = false } -sr-api = { path = "../sr-api", default-features = false } +substrate-consensus-aura-primitives = { path = "../consensus/aura/primitives", default-features = false } sr-std = { path = "../sr-std", default-features = false } sr-io = { path = "../sr-io", default-features = false } sr-primitives = { path = "../sr-primitives", default-features = false } sr-version = { path = "../sr-version", default-features = false } srml-support = { path = "../../srml/support", default-features = false } +[dev-dependencies] +substrate-executor = { path = "../executor" } + [features] default = ["std"] std = [ @@ -26,13 +30,14 @@ std = [ "hex-literal", "serde", "serde_derive", + "substrate-client/std", "substrate-keyring", "parity-codec/std", - "sr-api/std", "sr-std/std", "sr-io/std", "srml-support/std", "substrate-primitives/std", "sr-primitives/std", "sr-version/std", + "substrate-consensus-aura-primitives/std", ] diff --git a/core/test-runtime/README.adoc b/core/test-runtime/README.adoc deleted file mode 100644 index 15b3c4c4ac32769a9a8e134fb4be02694b56b396..0000000000000000000000000000000000000000 --- a/core/test-runtime/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Test runtime - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/test-runtime/src/genesismap.rs b/core/test-runtime/src/genesismap.rs index 5e6adec86aff563dc7599ce335306db4918983ce..82e9423f05f018d4936cf2d30b823bcf86d75e7c 100644 --- a/core/test-runtime/src/genesismap.rs +++ b/core/test-runtime/src/genesismap.rs @@ -19,23 +19,23 @@ use std::collections::HashMap; use runtime_io::twox_128; use codec::{Encode, KeyedVec, Joiner}; -use primitives::{AuthorityId, ChangesTrieConfiguration}; +use primitives::{Ed25519AuthorityId, ChangesTrieConfiguration}; use primitives::storage::well_known_keys; use runtime_primitives::traits::Block; /// Configuration of a general Substrate test genesis block. pub struct GenesisConfig { pub changes_trie_config: Option, - pub authorities: Vec, - pub balances: Vec<(AuthorityId, u64)>, + pub authorities: Vec, + pub balances: Vec<(Ed25519AuthorityId, u64)>, } impl GenesisConfig { - pub fn new_simple(authorities: Vec, balance: u64) -> Self { + pub fn new_simple(authorities: Vec, balance: u64) -> Self { Self::new(false, authorities, balance) } - pub fn new(support_changes_trie: bool, authorities: Vec, balance: u64) -> Self { + pub fn new(support_changes_trie: bool, authorities: Vec, balance: u64) -> Self { GenesisConfig { changes_trie_config: match support_changes_trie { true => Some(super::changes_trie_config()), diff --git a/core/test-runtime/src/lib.rs b/core/test-runtime/src/lib.rs index de678e7205748e6693a6f9c777083b90f0fdbccd..fd87782e38a4d5dcd2e965b9687c34da159dd859 100644 --- a/core/test-runtime/src/lib.rs +++ b/core/test-runtime/src/lib.rs @@ -14,31 +14,29 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! The Substrate runtime. This can be compiled with #[no_std], ready for Wasm. -// end::description[] #![cfg_attr(not(feature = "std"), no_std)] +#[cfg(feature = "std")] +extern crate serde; + extern crate sr_std as rstd; extern crate parity_codec as codec; extern crate sr_primitives as runtime_primitives; +extern crate substrate_consensus_aura_primitives as consensus_aura; -#[cfg(feature = "std")] #[macro_use] -extern crate serde_derive; +extern crate substrate_client as client; #[macro_use] extern crate srml_support as runtime_support; #[macro_use] extern crate parity_codec_derive; -#[macro_use] -extern crate sr_api as runtime_api; extern crate sr_io as runtime_io; #[macro_use] extern crate sr_version as runtime_version; - #[cfg(test)] #[macro_use] extern crate hex_literal; @@ -47,29 +45,37 @@ extern crate substrate_keyring as keyring; #[cfg_attr(any(feature = "std", test), macro_use)] extern crate substrate_primitives as primitives; +#[cfg(test)] extern crate substrate_executor; + #[cfg(feature = "std")] pub mod genesismap; pub mod system; use rstd::prelude::*; use codec::{Encode, Decode}; -use runtime_api::runtime::*; -use runtime_primitives::traits::{BlindCheckable, BlakeTwo256, Block as BlockT, Extrinsic as ExtrinsicT}; -use runtime_primitives::{ApplyResult, Ed25519Signature, transaction_validity::TransactionValidity}; +use client::{runtime_api as client_api, block_builder::api as block_builder_api}; +use runtime_primitives::{ + ApplyResult, Ed25519Signature, transaction_validity::TransactionValidity, + traits::{ + BlindCheckable, BlakeTwo256, Block as BlockT, Extrinsic as ExtrinsicT, + GetNodeBlockType, GetRuntimeBlockType + }, CheckInherentError +}; use runtime_version::RuntimeVersion; pub use primitives::hash::H256; -use primitives::AuthorityId; +use primitives::{Ed25519AuthorityId, OpaqueMetadata}; #[cfg(any(feature = "std", test))] use runtime_version::NativeVersion; +use consensus_aura::api as aura_api; /// Test runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: ver_str!("test"), - impl_name: ver_str!("parity-test"), + spec_name: create_runtime_str!("test"), + impl_name: create_runtime_str!("parity-test"), authoring_version: 1, spec_version: 1, impl_version: 1, - apis: apis_vec!([]), + apis: RUNTIME_API_VERSIONS, }; fn version() -> RuntimeVersion { @@ -87,7 +93,7 @@ pub fn native_version() -> NativeVersion { /// Calls in transactions. #[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[cfg_attr(feature = "std", derive(Debug))] pub struct Transfer { pub from: AccountId, pub to: AccountId, @@ -97,20 +103,33 @@ pub struct Transfer { /// Extrinsic for test-runtime. #[derive(Clone, PartialEq, Eq, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] -pub struct Extrinsic { - pub transfer: Transfer, - pub signature: Ed25519Signature, +#[cfg_attr(feature = "std", derive(Debug))] +pub enum Extrinsic { + AuthoritiesChange(Vec), + Transfer(Transfer, Ed25519Signature), +} + +#[cfg(feature = "std")] +impl serde::Serialize for Extrinsic +{ + fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { + self.using_encoded(|bytes| seq.serialize_bytes(bytes)) + } } impl BlindCheckable for Extrinsic { type Checked = Self; fn check(self) -> Result { - if ::runtime_primitives::verify_encoded_lazy(&self.signature, &self.transfer, &self.transfer.from) { - Ok(self) - } else { - Err("bad signature") + match self { + Extrinsic::AuthoritiesChange(new_auth) => Ok(Extrinsic::AuthoritiesChange(new_auth)), + Extrinsic::Transfer(transfer, signature) => { + if ::runtime_primitives::verify_encoded_lazy(&signature, &transfer, &transfer.from) { + Ok(Extrinsic::Transfer(transfer, signature)) + } else { + Err("bad signature") + } + }, } } } @@ -121,6 +140,15 @@ impl ExtrinsicT for Extrinsic { } } +impl Extrinsic { + pub fn transfer(&self) -> &Transfer { + match self { + Extrinsic::Transfer(ref transfer, _) => transfer, + _ => panic!("cannot convert to transfer ref"), + } + } +} + /// An identifier for an account on this system. pub type AccountId = H256; /// A simple hash type for all our hashing. @@ -130,7 +158,7 @@ pub type BlockNumber = u64; /// Index of a transaction. pub type Index = u64; /// The item of a block digest. -pub type DigestItem = runtime_primitives::generic::DigestItem; +pub type DigestItem = runtime_primitives::generic::DigestItem; /// The digest of a block. pub type Digest = runtime_primitives::generic::Digest; /// A test block. @@ -158,44 +186,59 @@ pub fn changes_trie_config() -> primitives::ChangesTrieConfiguration { } } -mod test_api { - decl_apis! { - pub trait TestAPI { - fn balance_of(id: AccountId) -> u64; - } +decl_runtime_apis! { + pub trait TestAPI { + fn balance_of(id: AccountId) -> u64; + /// A benchmkark function that adds one to the given value and returns the result. + fn benchmark_add_one(val: &u64) -> u64; + /// A benchmark function that adds one to each value in the given vector and returns the + /// result. + fn benchmark_vector_add_one(vec: &Vec) -> Vec; } } -use test_api::runtime::TestAPI; +pub struct Runtime; + +impl GetNodeBlockType for Runtime { + type NodeBlock = Block; +} -struct Runtime; +impl GetRuntimeBlockType for Runtime { + type RuntimeBlock = Block; +} -impl_apis! { - impl Core for Runtime { +impl_runtime_apis! { + impl client_api::Core for Runtime { fn version() -> RuntimeVersion { version() } - fn authorities() -> Vec { + fn authorities() -> Vec { system::authorities() } fn execute_block(block: Block) { system::execute_block(block) } + + fn initialise_block(header: &::Header) { + system::initialise_block(header) + } } - impl TaggedTransactionQueue for Runtime { - fn validate_transaction(utx: ::Extrinsic) -> TransactionValidity { - system::validate_transaction(utx) + impl client_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + unimplemented!() } } - impl BlockBuilder for Runtime { - fn initialise_block(header: ::Header) { - system::initialise_block(header) + impl client_api::TaggedTransactionQueue for Runtime { + fn validate_transaction(utx: ::Extrinsic) -> TransactionValidity { + system::validate_transaction(utx) } + } + impl block_builder_api::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyResult { system::execute_transaction(extrinsic) } @@ -204,12 +247,12 @@ impl_apis! { system::finalise_block() } - fn inherent_extrinsics(_data: u32) -> Vec { + fn inherent_extrinsics(_data: ()) -> Vec<::Extrinsic> { unimplemented!() } - fn check_inherents(_block: Block, _data: u32) -> Result<(), u32> { - unimplemented!() + fn check_inherents(_block: Block, _data: ()) -> Result<(), CheckInherentError> { + Ok(()) } fn random_seed() -> ::Hash { @@ -217,9 +260,23 @@ impl_apis! { } } - impl TestAPI for Runtime { + impl self::TestAPI for Runtime { fn balance_of(id: AccountId) -> u64 { system::balance_of(id) } + + fn benchmark_add_one(val: &u64) -> u64 { + val + 1 + } + + fn benchmark_vector_add_one(vec: &Vec) -> Vec { + let mut vec = vec.clone(); + vec.iter_mut().for_each(|v| *v += 1); + vec + } + } + + impl aura_api::AuraApi for Runtime { + fn slot_duration() -> u64 { 1 } } } diff --git a/core/test-runtime/src/system.rs b/core/test-runtime/src/system.rs index a3041647d43f2fc18e774333e360fd75b50ba04c..5b01ecb5008d75b0248683b7713666306b07d055 100644 --- a/core/test-runtime/src/system.rs +++ b/core/test-runtime/src/system.rs @@ -24,8 +24,8 @@ use runtime_primitives::traits::{Hash as HashT, BlakeTwo256, Digest as DigestT}; use runtime_primitives::generic; use runtime_primitives::{ApplyError, ApplyOutcome, ApplyResult, transaction_validity::TransactionValidity}; use codec::{KeyedVec, Encode}; -use super::{AccountId, BlockNumber, Extrinsic, H256 as Hash, Block, Header, Digest}; -use primitives::{Blake2Hasher}; +use super::{AccountId, BlockNumber, Extrinsic, Transfer, H256 as Hash, Block, Header, Digest}; +use primitives::{Ed25519AuthorityId, Blake2Hasher}; use primitives::storage::well_known_keys; const NONCE_OF: &[u8] = b"nonce:"; @@ -36,6 +36,7 @@ storage_items! { // The current block number being processed. Set by `execute_block`. Number: b"sys:num" => required BlockNumber; ParentHash: b"sys:pha" => required Hash; + NewAuthorities: b"sys:new_auth" => Vec; } pub fn balance_of_key(who: AccountId) -> Vec { @@ -51,7 +52,7 @@ pub fn nonce_of(who: AccountId) -> u64 { } /// Get authorities ar given block. -pub fn authorities() -> Vec<::primitives::AuthorityId> { +pub fn authorities() -> Vec { let len: u32 = storage::unhashed::get(well_known_keys::AUTHORITY_COUNT) .expect("There are always authorities in test-runtime"); (0..len) @@ -61,7 +62,7 @@ pub fn authorities() -> Vec<::primitives::AuthorityId> { .collect() } -pub fn initialise_block(header: Header) { +pub fn initialise_block(header: &Header) { // populate environment. ::put(&header.number); ::put(&header.parent_hash); @@ -93,8 +94,11 @@ pub fn execute_block(block: Block) { // check digest let mut digest = Digest::default(); - if let Some(storage_changes_root) = storage_changes_root(header.number) { - digest.push(generic::DigestItem::ChangesTrieRoot::(storage_changes_root.into())); + if let Some(storage_changes_root) = storage_changes_root(header.parent_hash.into(), header.number - 1) { + digest.push(generic::DigestItem::ChangesTrieRoot(storage_changes_root.into())); + } + if let Some(new_authorities) = ::take() { + digest.push(generic::DigestItem::AuthoritiesChange(new_authorities)); } assert!(digest == header.digest, "Header digest items must match that calculated."); } @@ -102,11 +106,11 @@ pub fn execute_block(block: Block) { /// Execute a transaction outside of the block execution function. /// This doesn't attempt to validate anything regarding the block. pub fn validate_transaction(utx: Extrinsic) -> TransactionValidity { - let tx = match check_signature(&utx) { - Ok(tx) => tx, - Err(_) => return TransactionValidity::Invalid, - }; + if check_signature(&utx).is_err() { + return TransactionValidity::Invalid; + } + let tx = utx.transfer(); let nonce_key = tx.from.to_keyed_vec(NONCE_OF); let expected_nonce: u64 = storage::get_or(&nonce_key, 0); if tx.nonce < expected_nonce { @@ -160,11 +164,14 @@ pub fn finalise_block() -> Header { let number = ::take(); let parent_hash = ::take(); let storage_root = BlakeTwo256::storage_root(); - let storage_changes_root = BlakeTwo256::storage_changes_root(number); + let storage_changes_root = BlakeTwo256::storage_changes_root(parent_hash, number - 1); let mut digest = Digest::default(); if let Some(storage_changes_root) = storage_changes_root { - digest.push(generic::DigestItem::ChangesTrieRoot::(storage_changes_root)); + digest.push(generic::DigestItem::ChangesTrieRoot(storage_changes_root)); + } + if let Some(new_authorities) = ::take() { + digest.push(generic::DigestItem::AuthoritiesChange(new_authorities)); } Header { @@ -177,21 +184,21 @@ pub fn finalise_block() -> Header { } #[inline(always)] -fn check_signature(utx: &Extrinsic) -> Result<::Transfer, ApplyError> { +fn check_signature(utx: &Extrinsic) -> Result<(), ApplyError> { use runtime_primitives::traits::BlindCheckable; - - let utx = match utx.clone().check() { - Ok(tx) => tx, - Err(_) => return Err(ApplyError::BadSignature), - }; - - Ok(utx.transfer) + utx.clone().check().map_err(|_| ApplyError::BadSignature)?; + Ok(()) } fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult { - // check signature - let tx = check_signature(utx)?; + check_signature(utx)?; + match utx { + Extrinsic::Transfer(ref transfer, _) => execute_transfer_backend(transfer), + Extrinsic::AuthoritiesChange(ref new_auth) => execute_new_authorities_backend(new_auth), + } +} +fn execute_transfer_backend(tx: &Transfer) -> ApplyResult { // check nonce let nonce_key = tx.from.to_keyed_vec(NONCE_OF); let expected_nonce: u64 = storage::get_or(&nonce_key, 0); @@ -217,6 +224,12 @@ fn execute_transaction_backend(utx: &Extrinsic) -> ApplyResult { Ok(ApplyOutcome::Success) } +fn execute_new_authorities_backend(new_authorities: &[Ed25519AuthorityId]) -> ApplyResult { + let new_authorities: Vec = new_authorities.iter().cloned().collect(); + ::put(new_authorities); + Ok(ApplyOutcome::Success) +} + #[cfg(feature = "std")] fn info_expect_equal_hash(given: &Hash, expected: &Hash) { use primitives::hexdisplay::HexDisplay; @@ -248,6 +261,10 @@ mod tests { use ::{Header, Digest, Extrinsic, Transfer}; use primitives::{Blake2Hasher}; use primitives::storage::well_known_keys; + use substrate_executor::WasmExecutor; + + const WASM_CODE: &'static [u8] = + include_bytes!("../wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"); fn new_test_ext() -> TestExternalities { TestExternalities::new(map![ @@ -262,11 +279,10 @@ mod tests { fn construct_signed_tx(tx: Transfer) -> Extrinsic { let signature = Keyring::from_raw_public(tx.from.to_fixed_bytes()).unwrap().sign(&tx.encode()).into(); - Extrinsic { transfer: tx, signature } + Extrinsic::Transfer(tx, signature) } - #[test] - fn block_import_works() { + fn block_import_works(block_executor: F) where F: Fn(Block, &mut TestExternalities) { let mut t = new_test_ext(); let h = Header { @@ -282,13 +298,27 @@ mod tests { extrinsics: vec![], }; - with_externalities(&mut t, || { - execute_block(b); + block_executor(b, &mut t); + + } + + #[test] + fn block_import_works_native() { + block_import_works(|b, ext| { + with_externalities(ext, || { + execute_block(b); + }); }); } #[test] - fn block_import_with_transaction_works() { + fn block_import_works_wasm() { + block_import_works(|b, ext| { + WasmExecutor::new().call(ext, 8, &WASM_CODE, "Core_execute_block", &b.encode()).unwrap(); + }) + } + + fn block_import_with_transaction_works(block_executor: F) where F: Fn(Block, &mut TestExternalities) { let mut t = new_test_ext(); with_externalities(&mut t, || { @@ -301,7 +331,7 @@ mod tests { parent_hash: [69u8; 32].into(), number: 1, state_root: hex!("c3d2cc317b5897af4c7f65d76b028971ce9fad745678732ff6d42301b4245a9c").into(), - extrinsics_root: hex!("4e689a607609f69df099af82577ae6c5969c44f1afe33a43cd7af926eba42272").into(), + extrinsics_root: hex!("198205cb7729fec8ccdc2e58571a4858586a4f305898078e0e8bee1dddea7e4b").into(), digest: Digest { logs: vec![], }, }, extrinsics: vec![ @@ -326,7 +356,7 @@ mod tests { parent_hash: b.header.hash(), number: 2, state_root: hex!("2c822d948bb68d7f7a1976d4f827a276a95a3ba1c4c15dbfab3bafbeb85f2b4d").into(), - extrinsics_root: hex!("009268a854b21f339c53d3c7a6619a27f564703311d91f11f61573a7fed5ca1c").into(), + extrinsics_root: hex!("041fa8971dda28745967179a9f39e3ca1a595c510682105df1cff74ae6f05e0d").into(), digest: Digest { logs: vec![], }, }, extrinsics: vec![ @@ -345,12 +375,29 @@ mod tests { ], }; + block_executor(b, &mut t); + with_externalities(&mut t, || { - execute_block(b); assert_eq!(balance_of(Keyring::Alice.to_raw_public().into()), 0); assert_eq!(balance_of(Keyring::Bob.to_raw_public().into()), 42); assert_eq!(balance_of(Keyring::Charlie.to_raw_public().into()), 69); }); } + + #[test] + fn block_import_with_transaction_works_native() { + block_import_with_transaction_works(|b, ext| { + with_externalities(ext, || { + execute_block(b); + }); + }); + } + + #[test] + fn block_import_with_transaction_works_wasm() { + block_import_with_transaction_works(|b, ext| { + WasmExecutor::new().call(ext, 8, &WASM_CODE, "Core_execute_block", &b.encode()).unwrap(); + }) + } } diff --git a/core/test-runtime/wasm/Cargo.lock b/core/test-runtime/wasm/Cargo.lock index 70007a0d7cc4ec05ed3eada028377511a3fbd529..127b3d0a02edd5e16019837b17bbeebde2c67a55 100644 --- a/core/test-runtime/wasm/Cargo.lock +++ b/core/test-runtime/wasm/Cargo.lock @@ -1,9 +1,30 @@ [[package]] name = "arrayvec" -version = "0.4.7" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -21,20 +42,44 @@ name = "blake2-rfc" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "byteorder" -version = "1.2.6" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bytes" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cc" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "chrono" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cloudabi" version = "0.0.3" @@ -48,35 +93,39 @@ name = "constant_time_eq" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "crossbeam" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "crossbeam-deque" -version = "0.2.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-epoch" -version = "0.3.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-utils" -version = "0.2.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -102,19 +151,45 @@ name = "environmental" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "error-chain" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fixed-hash" -version = "0.3.0-beta.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fnv" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -130,19 +205,19 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "gcc" -version = "0.3.54" +name = "futures" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hash-db" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" [[package]] name = "hash256-std-hasher" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -172,11 +247,75 @@ dependencies = [ "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "httparse" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "idna" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "impl-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "impl-serde" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "integer-sqrt" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "iovec" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "itoa" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kvdb" +version = "0.1.0" +source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" +dependencies = [ + "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", +] + [[package]] name = "lazy_static" version = "0.2.11" @@ -184,51 +323,67 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "1.1.0" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazycell" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "libc" -version = "0.2.43" +version = "0.2.44" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lock_api" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "mashup" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "mashup-impl 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mashup-impl 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "mashup-impl" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "matches" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "memoffset" version = "0.2.1" @@ -237,7 +392,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memory-db" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" dependencies = [ "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -249,15 +404,78 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "nan-preserving-float" -version = "0.1.0" +name = "mio" +version = "0.6.16" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-extras" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-uds" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "net2" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "nodrop" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "num-integer" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-traits" version = "0.2.6" @@ -268,24 +486,58 @@ name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "once_cell" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "openssl" +version = "0.10.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "openssl-sys" +version = "0.9.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "owning_ref" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parity-bytes" +version = "0.1.0" +source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" + [[package]] name = "parity-codec" -version = "2.1.5" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -293,8 +545,8 @@ name = "parity-codec-derive" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -303,29 +555,73 @@ name = "parity-wasm" version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parking_lot" -version = "0.4.8" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parking_lot_core" -version = "0.2.14" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "percent-encoding" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pkg-config" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "primitive-types" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro-hack" version = "0.4.1" @@ -341,7 +637,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "proc-macro2" -version = "0.4.19" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -349,10 +645,10 @@ dependencies = [ [[package]] name = "quote" -version = "0.6.8" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -361,7 +657,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -372,47 +668,105 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_chacha" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_core" -version = "0.2.1" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "rayon" -version = "0.8.2" +name = "rand_hc" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rayon-core" -version = "1.4.1" +name = "rand_isaac" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_pcg" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "redox_syscall" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ring" -version = "0.12.1" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustc-demangle" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc-hex" version = "2.0.1" @@ -426,6 +780,11 @@ dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ryu" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "scopeguard" version = "0.3.3" @@ -446,35 +805,91 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.79" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slab" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slog" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slog-async" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "slog-json" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "slog-scope" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "smallvec" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "sr-api" +name = "sr-api-macros" version = "0.1.0" dependencies = [ - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 0.1.0", - "sr-std 0.1.0", - "sr-version 0.1.0", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -483,7 +898,7 @@ version = "0.1.0" dependencies = [ "environmental 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 0.1.0", "substrate-primitives 0.1.0", @@ -496,12 +911,12 @@ name = "sr-primitives" version = "0.1.0" dependencies = [ "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-std 0.1.0", "substrate-primitives 0.1.0", @@ -518,27 +933,72 @@ dependencies = [ name = "sr-version" version = "0.1.0" dependencies = [ - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 0.1.0", "sr-std 0.1.0", ] +[[package]] +name = "srml-metadata" +version = "0.1.0" +dependencies = [ + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 0.1.0", + "substrate-primitives 0.1.0", +] + [[package]] name = "srml-support" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mashup 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", - "substrate-metadata 0.1.0", + "srml-metadata 0.1.0", + "srml-support-procedural 0.1.0", +] + +[[package]] +name = "srml-support-procedural" +version = "0.1.0" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-api-macros 0.1.0", + "srml-support-procedural-tools 0.1.0", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "srml-support-procedural-tools" +version = "0.1.0" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "srml-support-procedural-tools-derive 0.1.0", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "srml-support-procedural-tools-derive" +version = "0.1.0" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -552,13 +1012,91 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "substrate-metadata" +name = "substrate-client" version = "0.1.0" dependencies = [ - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-api-macros 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "sr-version 0.1.0", + "substrate-consensus-common 0.1.0", + "substrate-executor 0.1.0", + "substrate-keyring 0.1.0", + "substrate-primitives 0.1.0", + "substrate-state-machine 0.1.0", + "substrate-telemetry 0.3.0", + "substrate-trie 0.4.0", +] + +[[package]] +name = "substrate-consensus-aura-primitives" +version = "0.1.0" +dependencies = [ + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-version 0.1.0", + "srml-support 0.1.0", + "substrate-client 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "substrate-consensus-common" +version = "0.1.0" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "sr-version 0.1.0", + "substrate-primitives 0.1.0", + "tokio 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-executor" +version = "0.1.0" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-version 0.1.0", + "substrate-primitives 0.1.0", + "substrate-serializer 0.1.0", + "substrate-state-machine 0.1.0", + "substrate-trie 0.4.0", + "wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-keyring" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-primitives 0.1.0", ] [[package]] @@ -567,23 +1105,30 @@ version = "0.1.0" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fixed-hash 0.3.0-beta.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", "hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)", "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 0.1.0", - "twox-hash 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.5.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "twox-hash 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-serializer" +version = "0.1.0" +dependencies = [ + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -593,39 +1138,64 @@ dependencies = [ "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 0.1.0", "substrate-trie 0.4.0", "trie-db 0.9.0 (git+https://github.com/paritytech/trie)", "trie-root 0.9.0 (git+https://github.com/paritytech/trie)", ] +[[package]] +name = "substrate-telemetry" +version = "0.3.0" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-scope 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "substrate-test-runtime" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 0.1.0", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", "sr-version 0.1.0", "srml-support 0.1.0", + "substrate-client 0.1.0", + "substrate-consensus-aura-primitives 0.1.0", + "substrate-keyring 0.1.0", "substrate-primitives 0.1.0", ] +[[package]] +name = "substrate-test-runtime-wasm" +version = "0.1.0" +dependencies = [ + "substrate-test-runtime 0.1.0", +] + [[package]] name = "substrate-trie" version = "0.4.0" dependencies = [ "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", "memory-db 0.9.0 (git+https://github.com/paritytech/trie)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.9.0 (git+https://github.com/paritytech/trie)", "trie-root 0.9.0 (git+https://github.com/paritytech/trie)", ] @@ -635,25 +1205,203 @@ name = "syn" version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "0.15.6" +version = "0.15.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "time" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-fs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-current-thread" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-executor" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-fs" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-io" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-reactor" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-tcp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-timer" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-udp" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-uds" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "trie-db" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", @@ -664,29 +1412,43 @@ dependencies = [ [[package]] name = "trie-root" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" dependencies = [ "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", ] [[package]] name = "twox-hash" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uint" -version = "0.5.0-beta.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.1.0" @@ -702,12 +1464,22 @@ dependencies = [ [[package]] name = "untrusted" -version = "0.5.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "version_check" -version = "0.1.5" +name = "url" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "vcpkg" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -717,15 +1489,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasmi" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" version = "0.3.6" @@ -735,6 +1511,11 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -745,84 +1526,183 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ws" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [metadata] -"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" +"checksum arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f405cc4c21cd8b784f6c8fc2adf9bc00f59558f0049b5ec21517f875963040cc" +"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" +"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" -"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" +"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" +"checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" +"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" +"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" +"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" -"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" -"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" +"checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" +"checksum crossbeam-deque 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe1b6f945f824c7a25afe44f62e25d714c0cc523f8e99d8db5cd1026e1269d3" +"checksum crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2449aaa4ec7ef96e5fb24db16024b935df718e9ae1cec0a1e68feeca2efca7b8" +"checksum crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e07fc155212827475223f0bcfae57e945e694fc90950ddf3f6695bbfd5555c72" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2" "checksum elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88d4851b005ef16de812ea9acdb7bece2f0a40dd86c07b85631d7dafa54537bb" "checksum environmental 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db746025e3ea695bfa0ae744dbacd5fcfc8db51b9760cf8bd0ab69708bb93c49" -"checksum fixed-hash 0.3.0-beta.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e71c99c903a9fe54baed1bc701b43daba8c6dc6d4aec89a32f667ab6b3094c4" +"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" +"checksum fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a557e80084b05c32b455963ff565a9de6f2866da023d6671705c6aff6f65e01c" +"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" +"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" "checksum hash-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" "checksum hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4da5f0e01bd8a71a224a4eedecaacfcabda388dbb7a80faf04d3514287572d95" "checksum hex-literal-impl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d340b6514f232f6db1bd16db65302a5278a04fef9ce867cb932e7e5fa21130a" +"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" +"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum impl-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c88568d828291c50eed30cd7fb9f8e688ad0013620186fa3e777b9f206c79f2" +"checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" +"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" +"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" +"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" +"checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311" +"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" -"checksum mashup 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d886e371548f5c66258a99df9ec03366bff02cc96ea3d3f8f346b5d2d6836de7" -"checksum mashup-impl 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8d426741e35fab52542d84dfee615f442c2b37247bee8b1ed5c25ca723487580" +"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f2d82b34c7fb11bb41719465c060589e291d505ca4735ea30016a91f6fc79c3b" +"checksum mashup-impl 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "aa607bfb674b4efb310512527d64266b065de3f894fc52f84efcbf7eaa5965fb" +"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum memory-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" -"checksum nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d4f00fcc2f4c9efa8cc971db0da9e28290e28e97af47585e48691ef10ff31f" -"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" +"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" +"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" +"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" +"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" -"checksum parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dca389ea5e1632c89b2ce54f7e2b4a8a8c9d278042222a91e0bf95451218cb4c" +"checksum once_cell 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d7ce3535d54560c937c1652ba4a0da66bfc63e0f8e07bed127483afb6e5ee925" +"checksum openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ec7bd7ca4cce6dbdc77e7c1230682740d307d1218a87fb0349a571272be749f9" +"checksum openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)" = "1bb974e77de925ef426b6bc82fce15fd45bdcbeb5728bffcfc7cdeeb7ce1c2d6" +"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" +"checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" +"checksum parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7b6a1290fe78aa6bbb5f3338ecede3062687a98b9e40cd1dbcaa47261d44097" "checksum parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa42c2cb493b60b12c75b26e8c94cb734af4df4d7f2cc229dc04c1953dac189" "checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" -"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" -"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" +"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" +"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" +"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" +"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" +"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" +"checksum primitive-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f47c18b4601125931d69fcf7b000c2c16a304e4f84d58218d6470b4502e00b58" "checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8" "checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a" -"checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901" -"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" +"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" +"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" -"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" -"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" -"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" -"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" +"checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a" +"checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a" +"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" +"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" +"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" +"checksum rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3" +"checksum redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "679da7508e9a6390aeaf7fbd02a800fdc64b73fe2204dd2c8ae66d22d9d5ad5d" +"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" +"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9" -"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe" -"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" +"checksum serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)" = "c91eb5b0190ae87b4e2e39cbba6e3bed3ac6186935fe265f0426156c4c49961b" +"checksum serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)" = "477b13b646f5b5b56fc95bedfc3b550d12141ce84f466f6c44b9a17589923885" +"checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811" +"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" +"checksum slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1a2eec401952cd7b12a84ea120e2d57281329940c3f93c2bf04f462539508e" +"checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f" +"checksum slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a" +"checksum slog-scope 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "053344c94c0e2b22da6305efddb698d7c485809427cf40555dc936085f67a9df" +"checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum syn 0.15.6 (registry+https://github.com/rust-lang/crates.io-index)" = "854b08a640fc8f54728fb95321e3ec485b365a97fe47609797c671addd1dde69" +"checksum syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)" = "ae8b29eb5210bc5cf63ed6149cbf9adfc82ac0be023d8735c176ee74a2db4da7" +"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" +"checksum tokio 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "a7817d4c98cc5be21360b3b37d6036fe9b7aefa5b7a201b7b16ff33423822f7d" +"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" +"checksum tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "331c8acc267855ec06eb0c94618dcbbfea45bed2d20b77252940095273fb58f6" +"checksum tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c117b6cf86bb730aab4834f10df96e4dd586eff2c3c27d3781348da49e255bde" +"checksum tokio-fs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "60ae25f6b17d25116d2cba342083abe5255d3c2c79cb21ea11aa049c53bf7c75" +"checksum tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7392fe0a70d5ce0c882c4778116c519bd5dbaa8a7c3ae3d04578b3afafdcda21" +"checksum tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "502b625acb4ee13cbb3b90b8ca80e0addd263ddacf6931666ef751e610b07fb5" +"checksum tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ad235e9dadd126b2d47f6736f65aa1fdcd6420e66ca63f44177bc78df89f912" +"checksum tokio-threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "56c5556262383032878afad66943926a1d1f0967f17e94bd7764ceceb3b70e7f" +"checksum tokio-timer 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4f37f0111d76cc5da132fe9bc0590b9b9cfd079bc7e75ac3846278430a299ff8" +"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" +"checksum tokio-uds 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "99ce87382f6c1a24b513a72c048b2c8efe66cb5161c9061d00bee510f08dc168" "checksum trie-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum trie-root 0.9.0 (git+https://github.com/paritytech/trie)" = "" -"checksum twox-hash 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f85be565a110ed72ed7048cf56570db04ce0a592c98aa59b7dacde3e5718750" -"checksum uint 0.5.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4630460173a57c0af94b8306091e018025d988473f641a4af754b6cde980e1e3" +"checksum twox-hash 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "555cd4909480122bbbf21e34faac4cb08a171f324775670447ed116726c474af" +"checksum uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "082df6964410f6aa929a61ddfafc997e4f32c62c22490e439ac351cec827f436" +"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" +"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" +"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum wasmi 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d184c4b7081f30316f74f8d73c197314dcb56ea7af9323522b42a2fa9cb19453" +"checksum wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21ef487a11df1ed468cf613c78798c26282da5c30e9d49f824872d4c77b47d1d" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "329d3e6dd450a9c5c73024e1047f0be7e24121a68484eb0b5368977bee3cf8c3" +"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/core/test-runtime/wasm/Cargo.toml b/core/test-runtime/wasm/Cargo.toml index f606a6b300a502931d37733ca9d2d3e79a35b2a2..5efaa01cf8777c773f4da99cddfbe85acadf1ef1 100644 --- a/core/test-runtime/wasm/Cargo.toml +++ b/core/test-runtime/wasm/Cargo.toml @@ -1,39 +1,21 @@ [package] -name = "substrate-test-runtime" +name = "substrate-test-runtime-wasm" version = "0.1.0" authors = ["Parity Technologies "] +[lib] +name = "substrate_test_runtime" +crate-type = ["cdylib"] + [dependencies] -log = { version = "0.4", optional = true } -hex-literal = { version = "0.1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } -parity-codec-derive = { version = "2.1", default-features = false } -substrate-primitives = { path = "../../primitives", default-features = false } -sr-api = { path = "../../sr-api", default-features = false } -sr-std = { path = "../../sr-std", default-features = false } -sr-io = { path = "../../sr-io", default-features = false } -sr-version = { path = "../../sr-version", default-features = false } -sr-primitives = { path = "../../sr-primitives", default-features = false } -srml-support = { path = "../../../srml/support", default-features = false } +substrate-test-runtime = { path = "..", default-features = false } [features] default = [] std = [ - "log", - "hex-literal", - "parity-codec/std", - "sr-api/std", - "sr-std/std", - "sr-io/std", - "srml-support/std", - "sr-version/std", - "substrate-primitives/std", - "sr-primitives/std" + "substrate-test-runtime/std", ] -[lib] -crate-type = ["cdylib"] - [profile.release] panic = "abort" lto = true diff --git a/core/test-runtime/wasm/src b/core/test-runtime/wasm/src deleted file mode 120000 index 5cd551cf2693e4b4f65d7954ec621454c2b20326..0000000000000000000000000000000000000000 --- a/core/test-runtime/wasm/src +++ /dev/null @@ -1 +0,0 @@ -../src \ No newline at end of file diff --git a/core/test-runtime/wasm/src/lib.rs b/core/test-runtime/wasm/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..3238cca84f6e2c21f2373eb1be59e9c3e96e8e56 --- /dev/null +++ b/core/test-runtime/wasm/src/lib.rs @@ -0,0 +1,22 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 Substrate test runtime reexported for WebAssembly compile. + +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate substrate_test_runtime; +pub use substrate_test_runtime::*; diff --git a/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm b/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm index 72683d7e19b2af43325f7f1ec1357721881a4c0d..4cc222f4566adf48ae5a9cd51af7b58597718d05 100644 Binary files a/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm and b/core/test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm differ diff --git a/core/transaction-pool/Cargo.toml b/core/transaction-pool/Cargo.toml index 93768f16d2264126cc8d605ca598ddf87842d53a..59e16e42e8b2bddd518132165e0dccc53f1f11fe 100644 --- a/core/transaction-pool/Cargo.toml +++ b/core/transaction-pool/Cargo.toml @@ -7,8 +7,8 @@ authors = ["Parity Technologies "] error-chain = "0.12" futures = "0.1" log = "0.4" -parity-codec = "2.1" -parking_lot = "0.4" +parity-codec = "2.2" +parking_lot = "0.7.1" sr-primitives = { path = "../sr-primitives" } substrate-client = { path = "../client" } substrate-primitives = { path = "../primitives" } diff --git a/core/transaction-pool/README.adoc b/core/transaction-pool/README.adoc deleted file mode 100644 index 336a67a8418fd0a3384a0b3f50a4655264fe1e3d..0000000000000000000000000000000000000000 --- a/core/transaction-pool/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Transaction Pool - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/transaction-pool/graph/Cargo.toml b/core/transaction-pool/graph/Cargo.toml index 9c154d4b3a4053ff6c413cdb5ce500f3a54d7d88..7910e10d9fd75b2fe4fb1f86c38a458ae9149155 100644 --- a/core/transaction-pool/graph/Cargo.toml +++ b/core/transaction-pool/graph/Cargo.toml @@ -7,7 +7,7 @@ authors = ["Parity Technologies "] error-chain = "0.12" futures = "0.1" log = "0.4" -parking_lot = "0.4" +parking_lot = "0.7.1" serde = "1.0" serde_derive = "1.0" sr-primitives = { path = "../../sr-primitives" } diff --git a/core/transaction-pool/graph/README.adoc b/core/transaction-pool/graph/README.adoc deleted file mode 100644 index 6746537217111dc35a55337614ea951f9fc8702f..0000000000000000000000000000000000000000 --- a/core/transaction-pool/graph/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= transaction-graph - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/transaction-pool/graph/src/base_pool.rs b/core/transaction-pool/graph/src/base_pool.rs index 21a52a9750297aee9dc89b93a8b1e97e44b7b3a9..2e96cc75c251fabd0d92f9508a141fcdcb1e6146 100644 --- a/core/transaction-pool/graph/src/base_pool.rs +++ b/core/transaction-pool/graph/src/base_pool.rs @@ -23,6 +23,7 @@ use std::{ sync::Arc, }; +use serde::Serialize; use sr_primitives::traits::Member; use sr_primitives::transaction_validity::{ TransactionTag as Tag, @@ -79,7 +80,7 @@ pub struct PruneStatus { /// Immutable transaction #[cfg_attr(test, derive(Clone))] -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq)] pub struct Transaction { /// Raw extrinsic representing that transaction. pub data: Extrinsic, @@ -120,7 +121,7 @@ impl Default for BasePool { } } -impl BasePool { +impl BasePool { /// Imports transaction to the pool. /// /// The pool consists of two parts: Future and Ready. @@ -293,6 +294,13 @@ pub struct Status { pub future: usize, } +impl Status { + /// Returns true if the are no transactions in the pool. + pub fn is_empty(&self) -> bool { + self.ready == 0 && self.future == 0 + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/core/transaction-pool/graph/src/lib.rs b/core/transaction-pool/graph/src/lib.rs index e41284efe309e8373df8396d698c1327dd1a6a9c..a4879f3cb0e78d37e489fe69b9775b9557f583f8 100644 --- a/core/transaction-pool/graph/src/lib.rs +++ b/core/transaction-pool/graph/src/lib.rs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Generic Transaction Pool //! //! The pool is based on dependency graph between transactions @@ -24,7 +23,6 @@ //! //! TODO [ToDr] //! - [ ] Multi-threading (getting ready transactions should not block the pool) -// end::description[] #![warn(missing_docs)] #![warn(unused_extern_crates)] @@ -33,6 +31,7 @@ extern crate futures; extern crate parking_lot; extern crate sr_primitives; +extern crate serde; #[macro_use] extern crate error_chain; #[macro_use] extern crate log; #[macro_use] extern crate serde_derive; diff --git a/core/transaction-pool/graph/src/listener.rs b/core/transaction-pool/graph/src/listener.rs index 1947bfb93b03e69361a74dc9f42b87b31c610631..d4645eb2c55dc8fc4a058ab1aeb7f141e45409f7 100644 --- a/core/transaction-pool/graph/src/listener.rs +++ b/core/transaction-pool/graph/src/listener.rs @@ -19,6 +19,7 @@ use std::{ collections::HashMap, hash, }; +use serde::Serialize; use watcher; use sr_primitives::traits; @@ -35,7 +36,7 @@ impl Default for Listener { } } -impl Listener { +impl Listener { 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); diff --git a/core/transaction-pool/graph/src/pool.rs b/core/transaction-pool/graph/src/pool.rs index fe1f2d2aee20a874355ab8b29ead71f0d6b5f509..923a4f22950dd5b48c3ea7791d99fdce14449047 100644 --- a/core/transaction-pool/graph/src/pool.rs +++ b/core/transaction-pool/graph/src/pool.rs @@ -26,6 +26,7 @@ use error; use listener::Listener; use rotator::PoolRotator; use watcher::Watcher; +use serde::Serialize; use futures::sync::mpsc; use parking_lot::{Mutex, RwLock}; @@ -53,13 +54,13 @@ pub type TransactionFor = Arc, ExtrinsicFor>>; pub trait ChainApi: Send + Sync { /// Block type. type Block: traits::Block; - /// Hash type - type Hash: hash::Hash + Eq + traits::Member; + /// Transaction Hash type + type Hash: hash::Hash + Eq + traits::Member + Serialize; /// Error type. type Error: From + error::IntoPoolError; /// Verify extrinsic at given block. - fn validate_transaction(&self, at: &BlockId, uxt: &ExtrinsicFor) -> Result; + fn validate_transaction(&self, at: &BlockId, uxt: ExtrinsicFor) -> Result; /// Returns a block number given the block id. fn block_id_to_number(&self, at: &BlockId) -> Result>, Self::Error>; @@ -104,10 +105,10 @@ impl Pool { bail!(error::Error::from(error::ErrorKind::TemporarilyBanned)) } - match self.api.validate_transaction(at, &xt)? { + match self.api.validate_transaction(at, xt.clone())? { TransactionValidity::Valid { priority, requires, provides, longevity } => { Ok(base::Transaction { - data: xt, + data: xt, hash, priority, requires, @@ -287,7 +288,7 @@ fn fire_events( listener: &mut Listener, imported: &base::Imported, ) where - H: hash::Hash + Eq + traits::Member, + H: hash::Hash + Eq + traits::Member + Serialize, H2: Clone, { match *imported { @@ -324,9 +325,9 @@ mod tests { type Error = error::Error; /// Verify extrinsic at given block. - fn validate_transaction(&self, at: &BlockId, uxt: &ExtrinsicFor) -> Result { + fn validate_transaction(&self, at: &BlockId, uxt: ExtrinsicFor) -> Result { let block_number = self.block_id_to_number(at)?.unwrap(); - let nonce = uxt.transfer.nonce; + let nonce = uxt.transfer().nonce; if nonce < block_number { Ok(TransactionValidity::Invalid) @@ -358,15 +359,12 @@ mod tests { /// Hash the extrinsic. fn hash(&self, uxt: &ExtrinsicFor) -> Self::Hash { - (uxt.transfer.from.to_low_u64_be() << 5) + uxt.transfer.nonce + (uxt.transfer().from.to_low_u64_be() << 5) + uxt.transfer().nonce } } fn uxt(transfer: Transfer) -> Extrinsic { - Extrinsic { - transfer, - signature: Default::default(), - } + Extrinsic::Transfer(transfer, Default::default()) } fn pool() -> Pool { diff --git a/core/transaction-pool/graph/src/ready.rs b/core/transaction-pool/graph/src/ready.rs index 47ab34c7fb44c0b5a71659145f94919544a0ebc9..1a531b3f4902fc72ecc06f357722b198adbb5508 100644 --- a/core/transaction-pool/graph/src/ready.rs +++ b/core/transaction-pool/graph/src/ready.rs @@ -21,6 +21,7 @@ use std::{ sync::Arc, }; +use serde::Serialize; use parking_lot::RwLock; use sr_primitives::traits::Member; use sr_primitives::transaction_validity::{ @@ -120,7 +121,7 @@ impl Default for ReadyTransactions { } } -impl ReadyTransactions { +impl ReadyTransactions { /// Borrows a map of tags that are provided by transactions in this queue. pub fn provided_tags(&self) -> &HashMap { &self.provided_tags diff --git a/core/transaction-pool/src/api.rs b/core/transaction-pool/src/api.rs index a8cb3ada50b504bd0d66fbf7ea6b651aefc50af1..382f4f6ed8b6079e05c4dec59a3eda23adfeea73 100644 --- a/core/transaction-pool/src/api.rs +++ b/core/transaction-pool/src/api.rs @@ -18,8 +18,9 @@ use std::{ sync::Arc, + marker::PhantomData, }; -use client::{self, runtime_api::TaggedTransactionQueue}; +use client::{runtime_api::TaggedTransactionQueue, blockchain::HeaderBackend}; use parity_codec::Encode; use txpool; use substrate_primitives::{ @@ -36,30 +37,34 @@ use sr_primitives::{ use error; /// The transaction pool logic -pub struct ChainApi { - client: Arc>, +pub struct ChainApi { + client: Arc, + _marker: PhantomData, } -impl ChainApi { +impl ChainApi where + Block: traits::Block, + T: traits::ProvideRuntimeApi + HeaderBackend { /// Create new transaction pool logic. - pub fn new(client: Arc>) -> Self { + pub fn new(client: Arc) -> Self { ChainApi { client, + _marker: Default::default() } } } -impl txpool::ChainApi for ChainApi where +impl txpool::ChainApi for ChainApi where Block: traits::Block, - B: client::backend::Backend + Send + Sync + 'static, - E: client::CallExecutor + Send + Sync + Clone + 'static, + T: traits::ProvideRuntimeApi + HeaderBackend, + T::Api: TaggedTransactionQueue { type Block = Block; type Hash = H256; type Error = error::Error; - fn validate_transaction(&self, at: &BlockId, uxt: &txpool::ExtrinsicFor) -> error::Result { - Ok(self.client.validate_transaction(at, uxt)?) + fn validate_transaction(&self, at: &BlockId, uxt: txpool::ExtrinsicFor) -> error::Result { + Ok(self.client.runtime_api().validate_transaction(at, uxt)?) } // TODO [toDr] Use proper lbock number type diff --git a/core/transaction-pool/src/lib.rs b/core/transaction-pool/src/lib.rs index 5d31ac8fb7a84f80b993ae8091b9757bfc9bfc06..44f63ed37d299a593b486beda9855325d96dd1df 100644 --- a/core/transaction-pool/src/lib.rs +++ b/core/transaction-pool/src/lib.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Substrate transaction pool. -// end::description[] #![warn(missing_docs)] #![warn(unused_extern_crates)] diff --git a/core/transaction-pool/src/tests.rs b/core/transaction-pool/src/tests.rs index e02bf054014b427ee7008b19c88f07d34e2fb7b3..5e00b63ad0dd94b1181d95c0aaeda210492817f7 100644 --- a/core/transaction-pool/src/tests.rs +++ b/core/transaction-pool/src/tests.rs @@ -40,14 +40,14 @@ impl txpool::ChainApi for TestApi { type Hash = Hash; type Error = error::Error; - fn validate_transaction(&self, at: &BlockId, uxt: &txpool::ExtrinsicFor) -> error::Result { + fn validate_transaction(&self, at: &BlockId, uxt: txpool::ExtrinsicFor) -> error::Result { let expected = index(at); - let requires = if expected == uxt.transfer.nonce { + let requires = if expected == uxt.transfer().nonce { vec![] } else { - vec![vec![uxt.transfer.nonce as u8 - 1]] + vec![vec![uxt.transfer().nonce as u8 - 1]] }; - let provides = vec![vec![uxt.transfer.nonce as u8]]; + let provides = vec![vec![uxt.transfer().nonce as u8]]; Ok(TransactionValidity::Valid { priority: 1, @@ -93,10 +93,7 @@ fn uxt(who: Keyring, nonce: Index) -> Extrinsic { amount: 1, }; let signature = transfer.using_encoded(|e| who.sign(e)); - Extrinsic { - transfer, - signature: signature.into(), - } + Extrinsic::Transfer(transfer, signature.into()) } fn pool() -> Pool { @@ -109,7 +106,7 @@ fn submission_should_work() { assert_eq!(209, index(&BlockId::number(0))); pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer.nonce).collect(); + let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209]); } @@ -119,7 +116,7 @@ fn multiple_submission_should_work() { pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer.nonce).collect(); + let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); } @@ -128,7 +125,7 @@ fn early_nonce_should_be_culled() { let pool = pool(); pool.submit_one(&BlockId::number(0), uxt(Alice, 208)).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer.nonce).collect(); + let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); } @@ -137,11 +134,11 @@ fn late_nonce_should_be_queued() { let pool = pool(); pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer.nonce).collect(); + let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer.nonce).collect(); + let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); } @@ -151,12 +148,12 @@ fn prune_tags_should_work() { pool.submit_one(&BlockId::number(0), uxt(Alice, 209)).unwrap(); pool.submit_one(&BlockId::number(0), uxt(Alice, 210)).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer.nonce).collect(); + let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); pool.prune_tags(&BlockId::number(1), vec![vec![209]]).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer.nonce).collect(); + let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![210]); } @@ -169,7 +166,7 @@ fn should_ban_invalid_transactions() { pool.submit_one(&BlockId::number(0), uxt.clone()).unwrap_err(); // when - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer.nonce).collect(); + let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); // then diff --git a/core/trie/Cargo.toml b/core/trie/Cargo.toml index 955c6b95cd4e232f420dd501ec89affad07abbf8..6a27af336b510d218aab327ef70be6570ba6d563 100644 --- a/core/trie/Cargo.toml +++ b/core/trie/Cargo.toml @@ -11,17 +11,17 @@ name = "bench" harness = false [dependencies] -parity-codec = { version = "2.1" } -hash-db = { git = "https://github.com/paritytech/trie", default-features = false } -trie-db = { git = "https://github.com/paritytech/trie", optional = true } -trie-root = { git = "https://github.com/paritytech/trie", default-features = false } -memory-db = { git = "https://github.com/paritytech/trie", optional = true } +parity-codec = { version = "2.2" } +hash-db = { version = "0.9", default-features = false } +trie-db = { version = "0.9", optional = true } +trie-root = { version = "0.9", default-features = false } +memory-db = { version = "0.9", optional = true } [dev-dependencies] substrate-primitives = { path = "../primitives" } -trie-bench = { git = "https://github.com/paritytech/trie" } -trie-standardmap = { git = "https://github.com/paritytech/trie" } -keccak-hasher = { git = "https://github.com/paritytech/trie" } +trie-bench = { version = "0.9" } +trie-standardmap = { version = "0.9" } +keccak-hasher = { version = "0.2" } criterion = "0.1.2" hex-literal = "0.1.0" diff --git a/core/trie/README.adoc b/core/trie/README.adoc deleted file mode 100644 index 953724ca12061e90ec22189ef9518c8e5674f5f8..0000000000000000000000000000000000000000 --- a/core/trie/README.adoc +++ /dev/null @@ -1,12 +0,0 @@ -= Substrate Trie - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/core/trie/src/lib.rs b/core/trie/src/lib.rs index 8232b6889f15d480d34323497a19ee24c0c635fc..abfd72b960df0c0a18ff9b5c8ef7af5b5e71af46 100644 --- a/core/trie/src/lib.rs +++ b/core/trie/src/lib.rs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -// tag::description[] //! Utility functions to interact with Substrate's Base-16 Modified Merkle Patricia tree ("trie"). -// end::description[] // TODO: no_std @@ -134,10 +132,11 @@ pub fn unhashed_trie(input: I) -> Vec where /// compact-encoded index (using `parity-codec` crate). pub fn ordered_trie_root(input: I) -> H::Out where - I: IntoIterator + Iterator, + I: IntoIterator, A: AsRef<[u8]>, { trie_root::(input + .into_iter() .enumerate() .map(|(i, v)| (codec::Encode::encode(&codec::Compact(i as u32)), v)) ) diff --git a/doc/packages/misc.adoc b/doc/packages/misc.adoc deleted file mode 100644 index 2081d34efc471bf1c6aed9dbb9f8c5eb3b478f19..0000000000000000000000000000000000000000 --- a/doc/packages/misc.adoc +++ /dev/null @@ -1,8 +0,0 @@ - -=== Misc packages - -:leveloffset: +3 - -include::../../subkey/README.adoc[] - -:leveloffset: -3 diff --git a/doc/packages/packages.adoc b/doc/packages/packages.adoc deleted file mode 100644 index aa95bb1f934a89889e927fcb2bf8558430c57515..0000000000000000000000000000000000000000 --- a/doc/packages/packages.adoc +++ /dev/null @@ -1,4 +0,0 @@ - -include::substrate.adoc[] - -include::misc.adoc[] diff --git a/doc/packages/substrate.adoc b/doc/packages/substrate.adoc deleted file mode 100644 index 3df3366def95c98bbe831f1835224fa390d1e539..0000000000000000000000000000000000000000 --- a/doc/packages/substrate.adoc +++ /dev/null @@ -1,66 +0,0 @@ - -== Substrate Packages - -=== Substrate Core - -:leveloffset: +3 - -include::../../core/client/README.adoc[] - -include::../../core/test-client/README.adoc[] - -include::../../core/client/db/README.adoc[] - -include::../../core/state-db/README.adoc[] - -include::../../core/consensus/common/README.adoc[] - -include::../../core/consensus/rhd/README.adoc[] - -include::../../core/executor/README.adoc[] - -include::../../core/finality-grandpa/README.adoc[] - -include::../../core/transaction-pool/README.adoc[] - -include::../../core/keyring/README.adoc[] - -include::../../core/network/README.adoc[] - -include::../../core/network-libp2p/README.adoc[] - -include::../../core/rpc/README.adoc[] - -include::../../core/rpc-servers/README.adoc[] - -include::../../srml/README.adoc[] - -include::../../core/sr-api/README.adoc[] - -include::../../core/sr-io/README.adoc[] - -include::../../core/sr-primitives/README.adoc[] - -include::../../core/sr-sandbox/README.adoc[] - -include::../../core/sr-std/README.adoc[] - -include::../../core/state-machine/README.adoc[] - -include::../../core/test-runtime/README.adoc[] - -include::../../core/telemetry/README.adoc[] - -include::../../core/cli/README.adoc[] - -include::../../core/service/README.adoc[] - -include::../../core/trie/README.adoc[] - -include::../../core/keystore/README.adoc[] - -include::../../core/primitives/README.adoc[] - -include::../../core/serializer/README.adoc[] - -:leveloffset: -3 diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 6f1f92cc82e4e31c39b6e84fbe283193105afc3a..f0d570a8d268fa12279e0ddb52fd681eebd7d57c 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -3,14 +3,15 @@ name = "node-cli" version = "0.1.0" authors = ["Parity Technologies "] description = "Substrate node implementation in Rust." +build = "build.rs" [dependencies] log = "0.4" tokio = "0.1.7" +futures = "0.1" exit-future = "0.1" substrate-cli = { path = "../../core/cli" } -parity-codec = { version = "2.1" } -parking_lot = "0.4" +parity-codec = { version = "2.2" } slog = "^2" sr-io = { path = "../../core/sr-io" } substrate-client = { path = "../../core/client" } @@ -18,12 +19,21 @@ substrate-primitives = { path = "../../core/primitives" } node-runtime = { path = "../runtime" } node-primitives = { path = "../primitives" } hex-literal = "0.1" +substrate-basic-authorship = { path = "../../core/basic-authorship" } substrate-service = { path = "../../core/service" } substrate-transaction-pool = { path = "../../core/transaction-pool" } substrate-network = { path = "../../core/network" } substrate-consensus-aura = { path = "../../core/consensus/aura" } +substrate-finality-grandpa = { path = "../../core/finality-grandpa" } sr-primitives = { path = "../../core/sr-primitives" } node-executor = { path = "../executor" } +structopt = "0.2.13" +substrate-keystore = { path = "../../core/keystore" } [dev-dependencies] substrate-service-test = { path = "../../core/service/test" } + +[build-dependencies] +substrate-cli = { path = "../../core/cli" } +structopt = "0.2.13" +clap = "~2.32" diff --git a/core/cli/build.rs b/node/cli/build.rs similarity index 91% rename from core/cli/build.rs rename to node/cli/build.rs index 61929bee63f23cf78226348a51e64c7414b9cfbe..74472bff06c1e40ae0570dcff492679fa182c2e4 100644 --- a/core/cli/build.rs +++ b/node/cli/build.rs @@ -14,14 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -#[macro_use] extern crate clap; +extern crate substrate_cli as cli; +extern crate structopt; use std::fs; use std::env; use clap::Shell; use std::path::Path; +include!("src/params.rs"); + fn main() { build_shell_completion(); } @@ -37,7 +40,6 @@ fn build_shell_completion() { /// Build the shell auto-completion for a given Shell fn build_completion(shell: &Shell) { - let yml = load_yaml!("src/cli.yml"); let outdir = match env::var_os("OUT_DIR") { None => return, @@ -51,9 +53,9 @@ fn build_completion(shell: &Shell) { fs::create_dir(&path).ok(); - let mut app = clap::App::from_yaml(&yml); + let mut app = Params::clap(); app.gen_completions( - "polkadot", + "substrate-node", *shell, &path); } diff --git a/core/cli/doc/shell-completion.adoc b/node/cli/doc/shell-completion.adoc similarity index 100% rename from core/cli/doc/shell-completion.adoc rename to node/cli/doc/shell-completion.adoc diff --git a/node/cli/res/bbq-birch.json b/node/cli/res/bbq-birch.json deleted file mode 100644 index 7504b7e8ca32a85ada9000bb74e774ac5a345cf1..0000000000000000000000000000000000000000 --- a/node/cli/res/bbq-birch.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "name": "BBQ Birch", - "id": "bbq-birch", - "telemetryUrl": "wss://telemetry.polkadot.io/submit/", - "protocolId": null, - "bootNodes": [ - "/ip4/104.211.54.233/tcp/30333/p2p/QmV6ttrdRBjuY6EV4Zh5saz8MaqY6anjXo4SrCWt5caANX", - "/ip4/104.211.48.51/tcp/30333/p2p/QmNWVCgizRFj96AkPv2Zi2MHUnSDBTF3y9eMsa3cJgAJV7", - "/ip4/104.211.48.247/tcp/30333/p2p/QmfPmL2L1cmupSgJSJgVg4KW8frGLq9AEH2iwHE3rCsfvg", - "/ip4/40.114.120.164/tcp/30333/p2p/QmYV2Dv6ZfHkxHtQgYMGPTkNbtaSHUb4r8CsP4Pp2PDTNs" - ], - "genesis": { - "raw": { - "0x3a617574683a00000000": "0x82c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf5", - "0x7935e46f94f24b82716c0142e2271de9": "0x0087000000000000", - "0x27b3872d47181b4a2dc15f0da43e7026": "0xe803000000000000", - "0x5278a9149ec1adfa8090a8ad336c881e": "0x0500000000000000", - "0x329586a7b97f2ac15f6c26a02c3c5621": "0x1082c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf54de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7063d7787ebca768b7445dfebe7d62cbb1625ff4dba288ea34488da266dd6dca58101764f45778d4980dadaceee6e8af2517d3ab91ac9bec9cd1714fa5994081c", - "0xb9b861cab4bbce870c811515bd5f33d7": "0x00", - "0xd437fe93b0bd0a5d67d30d85d010edc2": "0x40420f00", - "0x3a617574683a03000000": "0x8101764f45778d4980dadaceee6e8af2517d3ab91ac9bec9cd1714fa5994081c", - "0x472b8f236d06a2ff7f1e9b2e848ef1d5": "0x0080e03779c311000000000000000000", - "0x3a636f6465": "0x0061736d0100000001f3012260017f0060037f7f7f017f60027f7f017f60057f7f7f7f7f0060047f7f7f7f0060037f7f7f0060017f017f60057f7f7f7f7f017f60027f7f0060017e0060047f7f7f7f017f60067f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60027e7f017f60000060017f017e60067f7f7f7f7f7f00600a7f7f7f7f7e7e7f7f7f7f00600a7f7f7f7e7e7f7f7f7f7f0060047f7e7f7f006000017e60047f7f7f7f017e60027f7e0060037e7e7f0060027e7f0060037f7e7e017f60027f7f017e60037f7e7e0060087f7f7f7f7f7e7e7f0060037f7f7e0060047f7f7e7e0060057f7e7e7e7e0060067f7e7e7e7e7f0060047f7e7e7f0002cc041703656e760a6578745f6d616c6c6f63000603656e76086578745f66726565000003656e760c6578745f74776f785f313238000503656e760f6578745f7365745f73746f72616765000403656e76146578745f6765745f73746f726167655f696e746f000703656e76236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74000403656e760e6578745f7072696e745f75746638000803656e760d6578745f7072696e745f6e756d000903656e76166578745f73616e64626f785f6d656d6f72795f676574000a03656e76166578745f73616e64626f785f6d656d6f72795f736574000a03656e76116578745f636c6561725f73746f72616765000803656e76126578745f656432353531395f766572696679000a03656e76166578745f73616e64626f785f6d656d6f72795f6e6577000203656e761b6578745f73616e64626f785f6d656d6f72795f74656172646f776e000003656e76176578745f73616e64626f785f696e7374616e7469617465000b03656e76126578745f73616e64626f785f696e766f6b65000c03656e761d6578745f73616e64626f785f696e7374616e63655f74656172646f776e000003656e760e6578745f626c616b65325f323536000503656e760d6578745f7072696e745f686578000803656e76106578745f73746f726167655f726f6f74000003656e76126578745f6578697374735f73746f72616765000203656e76106578745f636c6561725f707265666978000803656e76186578745f73746f726167655f6368616e6765735f726f6f74000d03c602c402080e0808080808080805080808080808080505080000080e00000008080808080808080808080808050805080805050805050505020800080808080805020005020608080b0208000500010e020208020201020808050402020202020602020100000f0404041004100405050808080805050508040405080002040e04030411041204040404040813080000080808080808000005140000000808080808080808050500080000050200000000000000050500000005000808080c04080005080815080005050816081718080505050803050808081908000508080200050805020e08050000021a1a1a1a051a051a0e09001a1a1a1a1a1a1a0f1a1a0218081b000400080802060000000508021c0000060800060505051d061e1f1e001b1b1e091b000000050800080000000800000000000000000000010101011f201f1f1f212121210405017001484805030100110619037f01418080c0000b7f0041eedfc2000b7f0041eedfc2000b07c00213066d656d6f72790200195f5f696e6469726563745f66756e6374696f6e5f7461626c6501000b5f5f686561705f6261736503010a5f5f646174615f656e6403020776657273696f6e00fe01086d6574616461746100ff010b617574686f72697469657300800210696e697469616c6973655f626c6f636b0081020f6170706c795f65787472696e7369630083020d657865637574655f626c6f636b0085020e66696e616c6973655f626c6f636b00890213696e686572656e745f65787472696e73696373008a020f76616c696461746f725f636f756e74008b020a76616c696461746f7273008c020974696d657374616d70008d020b72616e646f6d5f73656564008e020d6163636f756e745f6e6f6e6365008f020e6c6f6f6b75705f616464726573730091021476616c69646174655f7472616e73616374696f6e009202098201010041010b47644b546974636e6f705c728b018c0193019501970199019a019b019c019d01d80171fd017868666779e701ef01e501e901a6029401fa01f601f9015ec702c501a002af01bb02cd02c601ca02ae01c102c002c602c502c402c202fc01fb01c201c1019f029e02ad01aa01ba02b902cc02cb02c401c301c902c802a9010adeb821c4029e0203097f017e017f024002400240024002400240200041046a2802002202200041086a28020022036b2001410c6a2802002204200141086a28020022056b220641d0006d22074f0d00200320076a22082003490d0420024101742209200820082009491b220aad42d0007e220b422088a70d04200ba722094100480d042002450d012000280200210c200910002208450d052008200c2009200241d0006c2202200220094b1b10ce021a200c10010c020b200028020021080c020b200910002208450d030b20002008360200200041046a200a3602000b2008200341d0006c6a2005200610ce021a200141086a2004360200200041086a200320076a36020002402001280204450d00200128020010010b0f0b1018000b200941081019000b0a0041c083c000104d000b0d0041eda0c1004122100600000bafa601030a7f027e017f230041206b2202240020024100360218200242013703102000280200210302400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002802082200413f4b0d00410110002204450d6b200220043602102002428180808010370214200420004102743a000020000d010c020b02402000418080014f0d00410210002204450d6a200220043602102002428280808020370214200420004102744101723b00000c010b024020004180808080044f0d00410410002204450d692002200436021020024284808080c000370214200420004102744102723600000c010b410110002204450d67200220043602102002428180808010370214200441033a0000024002400240024020022802142205200241186a28020022046b41044f0d00200441046a22062004490d0620054101742207200620062007491b22084100480d062005450d0120022802102109200810002207450d6a2007200920082005200520084b1b10ce021a200910010c020b200441046a2106200228021021070c020b200810002207450d680b20022008360214200220073602100b200241186a2006360200200720046a20003600000b2003200041f8006c6a210a200241106a41086a210003400240024002400240024002400240024002400240024002400240024002400240024020032802704101470d00200228021420002802002204470d01200441016a22062004490d1320044101742207200620062007491b22054100480d132004450d0320022802102108200510002207450d0a2007200820052004200420054b1b10ce021a200810010c040b200228021420002802002204470d01200441016a22062004490d1220044101742207200620062007491b22054100480d122004450d0520022802102108200510002207450d0a2007200820052004200420054b1b10ce021a200810010c060b200441016a2106200228021021070c030b200441016a2106200228021021070c050b200510002207450d060b20022005360214200220073602100b20002006360200200720046a41013a000020032d0000417f6a220441084b0d030c0a0b200510002207450d040b20022005360214200220073602100b20002006360200200720046a41003a0000200341f4006a2802002109024002400240024020022802142205200028020022046b41044f0d00200441046a22062004490d0e20054101742207200620062007491b22084100480d0e2005450d012002280210210b200810002207450d072007200b20082005200520084b1b10ce021a200b10010c020b200441046a2106200228021021070c020b200810002207450d050b20022008360214200220073602100b20002006360200200720046a200936000020032d0000417f6a220441084d0d070b0240024002400240200228021420002802002204470d00200441016a22062004490d0d20044101742207200620062007491b22054100480d0d2004450d0120022802102108200510002207450d072007200820052004200420054b1b10ce021a200810010c020b200441016a2106200228021021070c020b200510002207450d050b20022005360214200220073602100b20002006360200200720046a41003a00002000280200210420022802142106024002400240024002400240024002400240200341016a2d00004101470d0020062004470d01200441016a22062004490d1220044101742207200620062007491b22054100480d122004450d0320022802102108200510002207450d0d2007200820052004200420054b1b10ce021a200810010c040b20062004470d01200441016a22062004490d1120044101742207200620062007491b22054100480d112004450d0520022802102108200510002207450d0d2007200820052004200420054b1b10ce021a200810010c060b200441016a2106200228021021070c030b200441016a2106200228021021070c050b200510002207450d090b20022005360214200220073602100b20002006360200200720046a41013a0000200341f8006a2203200a470d0a0c0b0b200510002207450d070b20022005360214200220073602100b20002006360200200720046a41003a0000200341f8006a2203200a470d070c080b200541011019000b200541011019000b200841011019000b200541011019000b200541011019000b200541011019000b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020040e09000502030106070408000b200228021420002802002204470d0c200441016a22062004490dc00220044101742207200620062007491b22054100480dc0022004450d1d20022802102108200510002207450dc9022007200820052004200420054b1b10ce021a200810010c1e0b200228021420002802002204470d07200441016a22062004490dbf0220044101742207200620062007491b22054100480dbf022004450d1020022802102108200510002207450dc4022007200820052004200420054b1b10ce021a200810010c110b200228021420002802002204470d07200441016a22062004490dbe0220044101742207200620062007491b22054100480dbe022004450d1220022802102108200510002207450dc4022007200820052004200420054b1b10ce021a200810010c130b200228021420002802002204470d07200441016a22062004490dbd0220044101742207200620062007491b22054100480dbd022004450d1420022802102108200510002207450dc4022007200820052004200420054b1b10ce021a200810010c150b200228021420002802002204470d07200441016a22062004490dbd0220044101742207200620062007491b22054100480dbd022004450d1620022802102108200510002207450dc4022007200820052004200420054b1b10ce021a200810010c170b200228021420002802002204470d08200441016a22062004490dbb0220044101742207200620062007491b22054100480dbb022004450d1b20022802102108200510002207450dc5022007200820052004200420054b1b10ce021a200810010c1c0b200228021420002802002204470d08200441016a22062004490dba0220044101742207200620062007491b22054100480dba022004450d1d20022802102108200510002207450dc5022007200820052004200420054b1b10ce021a200810010c1e0b200228021420002802002204470d08200441016a22062004490dba0220044101742207200620062007491b22054100480dba022004450d2220022802102108200510002207450dc6022007200820052004200420054b1b10ce021a200810010c230b200228021420002802002204470d08200441016a22062004490db90220044101742207200620062007491b22054100480db9022004450d2420022802102108200510002207450dc6022007200820052004200420054b1b10ce021a200810010c250b200441016a2106200228021021070c0a0b200441016a2106200228021021070c0c0b200441016a2106200228021021070c0e0b200441016a2106200228021021070c100b200441016a2106200228021021070c120b200441016a2106200228021021070c140b200441016a2106200228021021070c160b200441016a2106200228021021070c1b0b200441016a2106200228021021070c1d0b200510002207450db3020b20022005360214200220073602100b20002006360200200720046a41053a000002400240200341046a2d000022044103714101460d00024020044102460d0020044103470d02200228021420002802002204470d31200441016a22062004490daf0220044101742207200620062007491b22054100480daf022004450d880120022802102108200510002207450dd7022007200820052004200420054b1b10ce021a200810010c89010b200228021420002802002204470d2e200441016a22062004490dae0220044101742207200620062007491b22054100480dae022004450d810120022802102108200510002207450dd4022007200820052004200420054b1b10ce021a200810010c82010b200228021420002802002204470d2e200441016a22062004490dad0220044101742207200620062007491b22054100480dad022004450d830120022802102108200510002207450dd4022007200820052004200420054b1b10ce021a200810010c84010b200228021420002802002204470d2f200441016a22062004490dac0220044101742207200620062007491b22054100480dac022004450d880120022802102108200510002207450dd5022007200820052004200420054b1b10ce021a200810010c89010b200510002207450db1020b20022005360214200220073602100b20002006360200200720046a41033a000002400240200341086a22042d000022064103714101460d0020064102470d01200228021420002802002206470d23200641016a22072006490dab0220064101742205200720072005491b22084100480dab022006450d5a20022802102109200810002205450dc6022005200920082006200620084b1b10ce021a200910010c5b0b200228021420002802002206470d20200641016a22072006490daa0220064101742205200720072005491b22084100480daa022006450d5620022802102109200810002205450dc4022005200920082006200620084b1b10ce021a200910010c570b200228021420002802002204470d22200441016a22062004490da90220044101742207200620062007491b22054100480da9022004450d5b20022802102108200510002207450dc5022007200820052004200420054b1b10ce021a200810010c5c0b200510002207450daf020b20022005360214200220073602100b20002006360200200720046a41043a0000200341086a2d0000417f6a220441044b0d25024020040e0500231e221c000b200228021420002802002204470d4f200441016a22062004490da60220044101742207200620062007491b22054100480da6022004450dd20120022802102108200510002207450deb022007200820052004200420054b1b10ce021a200810010cd3010b200510002207450dad020b20022005360214200220073602100b20002006360200200720046a41083a00000240024002400240200341086a22062d0000417f6a220441034b0d00024020040e0400040203000b200228021420002802002204470d2f200441016a22062004490da80220044101742207200620062007491b22054100480da8022004450d980120022802102108200510002207450dd7022007200820052004200420054b1b10ce021a200810010c99010b200228021420002802002204470d2a200441016a22072004490da70220044101742205200720072005491b22084100480da7022004450d880120022802102109200810002205450dd1022005200920082004200420084b1b10ce021a200910010c89010b200228021420002802002204470d2a200441016a22062004490da60220044101742207200620062007491b22054100480da6022004450d8a0120022802102108200510002207450dd1022007200820052004200420054b1b10ce021a200810010c8b010b200228021420002802002204470d2b200441016a22062004490da50220044101742207200620062007491b22054100480da5022004450d920120022802102108200510002207450dd3022007200820052004200420054b1b10ce021a200810010c93010b200228021420002802002204470d2c200441016a22072004490da40220044101742205200720072005491b22084100480da4022004450d970120022802102109200810002205450dd4022005200920082004200420084b1b10ce021a200910010c98010b200510002207450dab020b20022005360214200220073602100b20002006360200200720046a41013a000002400240200341086a22042d000022064103714101460d0020064102470d01200228021420002802002206470d1f200641016a22072006490da20220064101742205200720072005491b22084100480da2022006450d5d20022802102109200810002205450dc1022005200920082006200620084b1b10ce021a200910010c5e0b200228021420002802002206470d1b200641016a22072006490da10220064101742205200720072005491b22084100480da1022006450d5620022802102109200810002205450dbe022005200920082006200620084b1b10ce021a200910010c570b200228021420002802002206470d1e200641016a22072006490da00220064101742205200720072005491b22084100480da0022006450d5e20022802102109200810002205450dc0022005200920082006200620084b1b10ce021a200910010c5f0b200510002207450da9020b20022005360214200220073602100b20002006360200200720046a41023a00000240200228021420002802002204470d00200441016a22062004490d9e0220044101742207200620062007491b22054100480d9e022004450d0420022802102108200510002207450daa022007200820052004200420054b1b10ce021a200810010c050b200441016a2106200228021021070c050b200510002207450da7020b20022005360214200220073602100b20002006360200200720046a41063a0000200341056a21062000280200210420022802142107024002400240200341046a2d00004101470d0020072004470d01200441016a22072004490d9e0220044101742205200720072005491b22084100480d9e022004450d2b20022802102109200810002205450daf022005200920082004200420084b1b10ce021a200910010c2c0b20072004470d01200441016a22072004490d9c0220044101742205200720072005491b22084100480d9c022004450d2d20022802102109200810002205450daf022005200920082004200420084b1b10ce021a200910010c2e0b200441016a2107200228021021050c2b0b200441016a2107200228021021050c2d0b200510002207450da5020b20022005360214200220073602100b20002006360200200720046a41003a0000200341086a290300210c024020022802142205200028020022046b41084f0d00200441086a22062004490d980220054101742207200620062007491b22084100480d98022005450d0720022802102109200810002207450da7022007200920082005200520084b1b10ce021a200910010c080b200441086a2106200228021021070c080b200510002207450da3020b20022005360214200220073602100b20002006360200200720046a41073a00000240024002400240200341046a2d0000417f6a220441034b0d00024020040e0400040203000b200228021420002802002204470d24200441016a22062004490d990220044101742207200620062007491b22054100480d99022004450da40120022802102108200510002207450dd1022007200820052004200420054b1b10ce021a200810010ca5010b200228021420002802002204470d1d200441016a22062004490d980220044101742207200620062007491b22054100480d98022004450d820120022802102108200510002207450dc5022007200820052004200420054b1b10ce021a200810010c83010b200228021420002802002204470d20200441016a22062004490d970220044101742207200620062007491b22054100480d97022004450d900120022802102108200510002207450dc9022007200820052004200420054b1b10ce021a200810010c91010b200228021420002802002204470d20200441016a22062004490d960220044101742207200620062007491b22054100480d96022004450d980120022802102108200510002207450dcb022007200820052004200420054b1b10ce021a200810010c99010b200228021420002802002204470d21200441016a22062004490d950220044101742207200620062007491b22054100480d95022004450da30120022802102108200510002207450dce022007200820052004200420054b1b10ce021a200810010ca4010b200510002207450da1020b20022005360214200220073602100b20002006360200200720046a41093a00000240200228021420002802002204470d00200441016a22062004490d930220044101742207200620062007491b22054100480d93022004450d0420022802102108200510002207450da2022007200820052004200420054b1b10ce021a200810010c050b200441016a2106200228021021070c050b200810002207450d9f020b20022008360214200220073602100b20002006360200200720046a200c370000200341f8006a2203200a470d8c020c8d020b200510002207450d9d020b20022005360214200220073602100b20002006360200200720046a41003a0000200341186a200241106a101b200341386a200241106a101b200341106a290300210c200341086a290300210d024002400240024020022802142205200028020022046b41104f0d00200441106a22062004490d900220054101742207200620062007491b22084100480d90022005450d0120022802102109200810002207450da0022007200920082005200520084b1b10ce021a200910010c020b200441106a2106200228021021070c020b200810002207450d9e020b20022008360214200220073602100b200720046a2204200c3700082004200d37000020002006360200200341f8006a2203200a470d89020c8a020b200228021420002802002204470d30200441016a22062004490d8a0220044101742207200620062007491b22054100480d8a022004450daa0120022802102108200510002207450dcb022007200820052004200420054b1b10ce021a200810010cab010b200641016a2107200228021021050c370b200228021420002802002204470d2f200441016a22062004490d880220044101742207200620062007491b22054100480d88022004450dab0120022802102108200510002207450dca022007200820052004200420054b1b10ce021a200810010cac010b200641016a2107200228021021050c380b200441016a2106200228021021070c3a0b200641016a2107200228021021050c3c0b200228021420002802002204470d2c200441016a22062004490d840220044101742207200620062007491b22054100480d84022004450dad0120022802102108200510002207450dc8022007200820052004200420054b1b10ce021a200810010cae010b200228021420002802002204470d2d200441016a22062004490d830220044101742207200620062007491b22054100480d83022004450db20120022802102108200510002207450dc9022007200820052004200420054b1b10ce021a200810010cb3010b200641016a2107200228021021050c3f0b200641016a2107200228021021050c410b200228021420002802002204470d2b200441016a22062004490d800220044101742207200620062007491b22054100480d80022004450dbb0120022802102108200510002207450dca022007200820052004200420054b1b10ce021a200810010cbc010b200441016a2106200228021021070c540b200441016a2106200228021021070c560b200441016a2106200228021021070c580b200441016a2106200228021021070c5a0b200441016a2107200228021021050c5f0b200441016a2106200228021021070c610b200441016a2106200228021021070c660b200441016a2106200228021021070c680b200441016a2106200228021021070c6a0b200441016a2107200228021021050c6c0b200441016a2106200228021021070c710b200441016a2106200228021021070c790b200441016a2106200228021021070c81010b200441016a2106200228021021070c83010b200810002205450d83020b20022008360214200220053602100b20002007360200200520046a41013a00002006200241106a101b200341286a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490df10120054101742207200620062007491b22084100480df1012005450d042002280210210b200810002207450d84022007200b20082005200520084b1b10ce021a200b10010c050b200441046a2106200228021021070c050b200810002205450d81020b20022008360214200220053602100b20002007360200200520046a41003a00002006200241106a101b200341286a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490ded0120054101742207200620062007491b22084100480ded012005450d042002280210210b200810002207450d82022007200b20082005200520084b1b10ce021a200b10010c050b200441046a2106200228021021070c050b200810002207450dff010b20022008360214200220073602100b20002006360200200720046a20093600002003412c6a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490deb0120054101742207200620062007491b22084100480deb012005450d042002280210210b200810002207450d80022007200b20082005200520084b1b10ce021a200b10010c050b200441046a2106200228021021070c050b200810002207450dfd010b20022008360214200220073602100b20002006360200200720046a20093600002003412c6a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490de70120054101742207200620062007491b22084100480de7012005450d042002280210210b200810002207450dfe012007200b20082005200520084b1b10ce021a200b10010c050b200441046a2106200228021021070c050b200810002207450dfb010b20022008360214200220073602100b20002006360200200720046a2009360000200341306a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490de50120054101742207200620062007491b22084100480de5012005450d042002280210210b200810002207450dfc012007200b20082005200520084b1b10ce021a200b10010c050b200441046a2106200228021021070c050b200810002207450df9010b20022008360214200220073602100b20002006360200200720046a2009360000200341306a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490de20120054101742207200620062007491b22084100480de2012005450d042002280210210b200810002207450dfa012007200b20082005200520084b1b10ce021a200b10010c050b200441046a2106200228021021070c050b200810002207450df7010b20022008360214200220073602100b20002006360200200720046a2009360000200341f8006a2203200a470ddb010cdc010b200810002207450df5010b20022008360214200220073602100b20002006360200200720046a2009360000200341f8006a2203200a470dd8010cd9010b200441016a2106200228021021070c7b0b200441016a2106200228021021070c7d0b200441016a2106200228021021070c82010b200441016a2106200228021021070c84010b200441016a2106200228021021070c86010b200441016a2106200228021021070c91010b200810002205450ded010b20022008360214200220053602100b20002007360200200520066a41013a0000200441016a200241106a101b200441246a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490dd20120054101742207200620062007491b22084100480dd2012005450d0a2002280210210b200810002207450df0012007200b20082005200520084b1b10ce021a200b10010c0b0b200441046a2106200228021021070c0b0b200810002205450deb010b20022008360214200220053602100b20002007360200200520066a41023a0000200441016a200241106a101b200341386a290300210c200341306a290300210d024020022802142205200028020022046b41104f0d00200441106a22062004490dcf0120054101742207200620062007491b22084100480dcf012005450d1020022802102109200810002207450df0012007200920082005200520084b1b10ce021a200910010c110b200441106a2106200228021021070c110b200510002207450de9010b20022005360214200220073602100b20002006360200200720046a41003a0000200341186a290300210c200341106a290300210d024020022802142205200028020022046b41104f0d00200441106a22062004490dcc0120054101742207200620062007491b22084100480dcc012005450d1020022802102109200810002207450dee012007200920082005200520084b1b10ce021a200910010c110b200441106a2106200228021021070c110b200810002205450de7010b20022008360214200220053602100b20002007360200200520066a41013a0000200441016a200241106a101b200341f8006a2203200a470dc6010cc7010b200810002207450de5010b20022008360214200220073602100b20002006360200200720046a2009360000200341f8006a2203200a470dc3010cc4010b200810002205450de3010b20022008360214200220053602100b20002007360200200520066a41023a0000200441016a200241106a101b200441216a200241106a101b200341d8006a290300210c200341d0006a290300210d024020022802142208200028020022056b41104f0d00200541106a22042005490dc30120084101742206200420042006491b22064100480dc3012008450d0a20022802102109200610002207450de6012007200920062008200820064b1b10ce021a200910010c0b0b200541106a210420022802102107200821060c0b0b200810002205450de1010b20022008360214200220053602100b20002007360200200520066a41003a0000200441016a200241106a101b200441246a280200210b024020022802142208200028020022066b41044f0d00200641046a22072006490dc00120084101742205200720072005491b22094100480dc0012008450d0a2002280210210e200910002205450de4012005200e20092008200820094b1b10ce021a200e10010c0b0b200641046a2107200228021021050c0b0b200810002207450ddf010b20022008360214200220073602100b200720046a2204200c3700082004200d37000020002006360200200341f8006a2203200a470dba010cbb010b200810002207450ddd010b20022008360214200220073602100b200720046a2204200c3700082004200d37000020002006360200200341f8006a2203200a470db7010cb8010b200610002207450ddb010b20022006360214200220073602100b200720056a2205200c3700082005200d37000020002004360200200341e8006a290300210c200341e0006a290300210d0240200620046b41104f0d00200441106a22082004490db70120064101742205200820082005491b22094100480db7012009100021052006450d042005450ddc012005200720092006200620094b1b10ce021a200710010c050b200441106a2108200721050c050b200910002205450dd9010b20022009360214200220053602100b20002007360200200520066a200b36000002400240200441216a2d000022044103714101460d0020044102470d01200228021420002802002204470d06200441016a22062004490db50120044101742207200620062007491b22054100480db5012004450d850120022802102108200510002207450d86022007200820052004200420054b1b10ce021a200810010c86010b200228021420002802002204470d04200441016a22062004490db40120044101742207200620062007491b22054100480db4012004450d810120022802102108200510002207450d84022007200820052004200420054b1b10ce021a200810010c82010b200228021420002802002204470d05200441016a22062004490db30120044101742207200620062007491b22054100480db3012004450d860120022802102108200510002207450d85022007200820052004200420054b1b10ce021a200810010c87010b2005450dd7010b20022009360214200220053602100b200520046a2204200c3700082004200d37000020002008360200200341f8006a2203200a470dae010caf010b200441016a2106200228021021070c7e0b200441016a2106200228021021070c80010b200441016a2106200228021021070c82010b200510002207450dd2010b20022005360214200220073602100b20002006360200200720046a41023a0000200341086a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490dab0120054101742207200620062007491b22084100480dab012005450d0a2002280210210b200810002207450dd5012007200b20082005200520084b1b10ce021a200b10010c0b0b200441046a2106200228021021070c0b0b200510002207450dd0010b20022005360214200220073602100b20002006360200200720046a41013a0000200341056a200241106a101b200341f8006a2203200a470da5010ca6010b200510002207450dce010b20022005360214200220073602100b20002006360200200720046a41033a0000200341086a280200210402400240024020032802102206413f4b0d00200228021420002802002207470d01200741016a22052007490da70120074101742208200520052008491b22094100480da7012007450d712002280210210b200910002208450df6012008200b20092007200720094b1b10ce021a200b10010c720b2006418080014f0d0120022802142209200028020022076b41024f0d44200741026a22052007490da60120094101742208200520052008491b220b4100480da6012009450d83012002280210210e200b10002208450dfa012008200e200b20092009200b4b1b10ce021a200e10010c84010b200741016a2105200228021021080c710b20064180808080044f0d4320022802142209200028020022076b41044f0d7c200741046a22052007490da40120094101742208200520052008491b220b4100480da4012009450d92012002280210210e200b10002208450dfd012008200e200b20092009200b4b1b10ce021a200e10010c93010b200510002207450dcc010b20022005360214200220073602100b20002006360200200720046a41003a0000200341056a200241106a101b200341256a200241106a101b200341f8006a2203200a470d9f010ca0010b200810002207450dca010b20022008360214200220073602100b20002006360200200720046a2009360000200341f8006a2203200a470d9c010c9d010b200810002205450dc8010b20022008360214200220053602100b20002007360200200520046a41003a0000200641046a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490d9d0120054101742207200620062007491b22084100480d9d012005450d042002280210210b200810002207450dc9012007200b20082005200520084b1b10ce021a200b10010c050b200441046a2106200228021021070c050b200510002207450dc6010b20022005360214200220073602100b20002006360200200720046a41033a0000200341186a290300210c200341106a290300210d024020022802142205200028020022046b41104f0d00200441106a22062004490d9a0120054101742207200620062007491b22084100480d9a012005450d1020022802102109200810002207450dcb012007200920082005200520084b1b10ce021a200910010c110b200441106a2106200228021021070c110b200810002207450dc4010b20022008360214200220073602100b20002006360200200720046a2009360000200341f8006a2203200a470d93010c94010b200510002207450dc2010b20022005360214200220073602100b20002006360200200720046a41003a0000200341056a200241106a101b200341c8006a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490d940120054101742207200620062007491b22084100480d94012005450d102002280210210b200810002207450dc7012007200b20082005200520084b1b10ce021a200b10010c110b200441046a2106200228021021070c110b200510002207450dc0010b20022005360214200220073602100b20002006360200200720046a41043a0000200341186a290300210c200341106a290300210d024020022802142205200028020022046b41104f0d00200441106a22062004490d910120054101742207200620062007491b22084100480d91012005450d1020022802102109200810002207450dc5012007200920082005200520084b1b10ce021a200910010c110b200441106a2106200228021021070c110b200510002207450dbe010b20022005360214200220073602100b20002006360200200720046a41013a0000200341186a290300210c200341106a290300210d024020022802142205200028020022046b41104f0d00200441106a22062004490d8e0120054101742207200620062007491b22084100480d8e012005450d1320022802102109200810002207450dc4012007200920082005200520084b1b10ce021a200910010c140b200441106a2106200228021021070c140b200810002205450dbc010b20022008360214200220053602100b20002007360200200520046a41023a0000200641246a280200210b024020022802142208200028020022046b41044f0d00200441046a22072004490d8b0120084101742205200720072005491b22094100480d8b012008450d132002280210210e200910002205450dc2012005200e20092008200820094b1b10ce021a200e10010c140b200441046a2107200228021021050c140b200810002207450dba010b20022008360214200220073602100b200720046a2204200c3700082004200d37000020002006360200200341f8006a2203200a470d84010c85010b200510002207450db8010b20022005360214200220073602100b20002006360200200720046a41033a0000200341056a200241106a101b200341f8006a2203200a470d81010c82010b200810002207450db6010b20022008360214200220073602100b20002006360200200720046a2009360000200341256a200241106a101b200341cc006a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490d820120054101742207200620062007491b22084100480d82012005450d132002280210210b200810002207450dbc012007200b20082005200520084b1b10ce021a200b10010c140b200441046a2106200228021021070c140b200810002207450db4010b20022008360214200220073602100b200720046a2204200c3700082004200d37000020002006360200200341f8006a2203200a470d7b0c7c0b200510002207450db2010b20022005360214200220073602100b20002006360200200720046a41043a0000200341056a200241106a101b0240200228021420002802002204470d00200441016a22062004490d7c20044101742207200620062007491b22054100480d7c2004450d1020022802102108200510002207450db7012007200820052004200420054b1b10ce021a200810010c110b200441016a2106200228021021070c110b200810002207450db0010b20022008360214200220073602100b200720046a2204200c3700082004200d37000020002006360200200341f8006a2203200a470d750c760b200910002205450dae010b20022009360214200220053602100b20002007360200200520046a200b360000200341386a290300210c200341306a290300210d024020022802142208200028020022046b41104f0d00200441106a22072004490d7620084101742205200720072005491b22094100480d762008450d0d2002280210210b200910002205450db2012005200b20092008200820094b1b10ce021a200b10010c0e0b200441106a2107200228021021050c0e0b200510002207450dac010b20022005360214200220073602100b20002006360200200720046a41013a0000200341056a200241106a101b200341256a200241106a101b0240200228021420002802002204470d00200441016a22062004490d7320044101742207200620062007491b22054100480d732004450d0d20022802102108200510002207450db0012007200820052004200420054b1b10ce021a200810010c0e0b200441016a2106200228021021070c0e0b200510002207450daa010b20022005360214200220073602100b20002006360200200720046a41023a0000200341056a200241106a101b200341f8006a2203200a470d6c0c6d0b200810002207450da8010b20022008360214200220073602100b20002006360200200720046a2009360000200341f8006a2203200a470d690c6a0b200510002207450da6010b20022005360214200220073602100b20002006360200200720046a200341256a2d00003a0000200341f8006a2203200a470d660c670b200910002205450da4010b20022009360214200220053602100b200520046a2204200c3700082004200d37000020002007360200200641016a200241106a101b200341f8006a2203200a470d630c640b200510002207450da2010b20022005360214200220073602100b20002006360200200720046a200341c5006a2d00003a0000200341c8006a2802002109024002400240024020022802142205200028020022046b41044f0d00200441046a22062004490d6720054101742207200620062007491b22084100480d672005450d012002280210210b200810002207450da5012007200b20082005200520084b1b10ce021a200b10010c020b200441046a2106200228021021070c020b200810002207450da3010b20022008360214200220073602100b20002006360200200720046a2009360000200341cc006a2802002109024002400240024020022802142205200028020022046b41044f0d00200441046a22062004490d6720054101742207200620062007491b22084100480d672005450d012002280210210b200810002207450da6012007200b20082005200520084b1b10ce021a200b10010c020b200441046a2106200228021021070c020b200810002207450da4010b20022008360214200220073602100b20002006360200200720046a2009360000200341f8006a2203200a470d600c610b200741026a2105200228021021080c400b200228021420002802002207470d39200741016a22052007490d6020074101742208200520052008491b22094100480d602007450d512002280210210b200910002208450dba012008200b20092007200720094b1b10ce021a200b10010c520b200510002207450da0010b20022005360214200220073602100b20002006360200200720046a41053a00002003410c6a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490d5e20054101742207200620062007491b22084100480d5e2005450d042002280210210b200810002207450da1012007200b20082005200520084b1b10ce021a200b10010c050b200441046a2106200228021021070c050b200510002207450d9e010b20022005360214200220073602100b20002006360200200720046a41033a00002003410c6a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490d5b20054101742207200620062007491b22084100480d5b2005450d0d2002280210210b200810002207450da2012007200b20082005200520084b1b10ce021a200b10010c0e0b200441046a2106200228021021070c0e0b200810002207450d9c010b20022008360214200220073602100b20002006360200200720046a20093600000240200228021420002802002204470d00200441016a22062004490d5820044101742207200620062007491b22054100480d582004450d0d20022802102108200510002207450da0012007200820052004200420054b1b10ce021a200810010c0e0b200441016a2106200228021021070c0e0b200510002207450d9a010b20022005360214200220073602100b20002006360200200720046a41043a00002003410c6a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490d5520054101742207200620062007491b22084100480d552005450d0d2002280210210b200810002207450d9e012007200b20082005200520084b1b10ce021a200b10010c0e0b200441046a2106200228021021070c0e0b200510002207450d98010b20022005360214200220073602100b20002006360200200720046a41013a00002003410c6a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490d5220054101742207200620062007491b22084100480d522005450d102002280210210b200810002207450d9d012007200b20082005200520084b1b10ce021a200b10010c110b200441046a2106200228021021070c110b200510002207450d96010b20022005360214200220073602100b20002006360200200720046a41023a00002003410c6a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490d4f20054101742207200620062007491b22084100480d4f2005450d102002280210210b200810002207450d9b012007200b20082005200520084b1b10ce021a200b10010c110b200441046a2106200228021021070c110b200810002207450d94010b20022008360214200220073602100b20002006360200200720046a2009360000200341f8006a2203200a470d490c4a0b200510002207450d92010b20022005360214200220073602100b20002006360200200720046a200341096a2d00003a0000200341f8006a2203200a470d460c470b200810002207450d90010b20022008360214200220073602100b20002006360200200720046a2009360000200341f8006a2203200a470d430c440b200510002207450d8e010b20022005360214200220073602100b20002006360200200720046a41003a00002003410c6a2802002109024020022802142205200028020022046b41044f0d00200441046a22062004490d4320054101742207200620062007491b22084100480d432005450d072002280210210b200810002207450d90012007200b20082005200520084b1b10ce021a200b10010c080b200441046a2106200228021021070c080b200810002207450d8c010b20022008360214200220073602100b20002006360200200720046a200936000002400240200341096a2d000022044103714101460d0020044102470d01200228021420002802002204470d09200441016a22062004490d4120044101742207200620062007491b22054100480d412004450d2420022802102108200510002207450d97012007200820052004200420054b1b10ce021a200810010c250b200228021420002802002204470d07200441016a22062004490d4020044101742207200620062007491b22054100480d402004450d2020022802102108200510002207450d95012007200820052004200420054b1b10ce021a200810010c210b200228021420002802002204470d08200441016a22062004490d3f20044101742207200620062007491b22054100480d3f2004450d2520022802102108200510002207450d96012007200820052004200420054b1b10ce021a200810010c260b200810002207450d8a010b20022008360214200220073602100b20002006360200200720046a2009360000200341f8006a2203200a470d3a0c3b0b200810002207450d88010b20022008360214200220073602100b20002006360200200720046a2009360000200341286a290300210c200341206a290300210d024002400240024020022802142205200028020022046b41104f0d00200441106a22072004490d3d20054101742206200720072006491b22064100480d3d2005450d0120022802102109200610002208450d8b012008200920062005200520064b1b10ce021a200910010c020b200441106a210720022802102108200521060c020b200610002208450d89010b20022006360214200220083602100b200820046a2204200c3700082004200d37000020002007360200200341106a280200210402400240024020032802182205413f4b0d0020062007470d01200641016a220b2006490d3c20064101742209200b200b2009491b220e4100480d3c200e100021092006450d162009450d8f0120092008200e20062006200e4b1b10ce021a200810010c170b2005418080014f0d01200620076b41024f0d11200741026a220b2007490d3b20064101742209200b200b2009491b220e4100480d3b200e100021092006450d262009450d930120092008200e20062006200e4b1b10ce021a200810010c270b200741016a210b200821090c160b20054180808080044f0d10200620076b41044f0d22200741046a220b2007490d3920064101742209200b200b2009491b220e4100480d39200e100021092006450d2f2009450d9a0120092008200e20062006200e4b1b10ce021a200810010c300b200441016a2106200228021021070c1a0b200441016a2106200228021021070c1c0b200441016a2106200228021021070c1e0b200910002208450d84010b20022009360214200220083602100b20002005360200200820076a20064102743a000020060d270c280b200510002207450d82010b20022005360214200220073602100b20002006360200200720046a41013a0000200341f8006a2203200a470d2e0c2f0b200510002207450d80010b20022005360214200220073602100b20002006360200200720046a41023a0000200341f8006a2203200a470d2b0c2c0b200510002207450d7e0b20022005360214200220073602100b20002006360200200720046a41003a0000200341f8006a2203200a470d280c290b200741026a210b200821090c160b20062007470d12200641016a220b2006490d2820064101742209200b200b2009491b220e4100480d28200e100021092006450d212009450d8a0120092008200e20062006200e4b1b10ce021a200810010c220b200741046a2105200228021021080c170b200741016a2105200228021021080c190b2009450d780b2002200e360214200220093602100b2000200b360200200920076a20054102743a000020050d1f0c200b200b10002208450d760b2002200b360214200220083602100b20002005360200200820076a20064102744101723b00000c140b200510002207450d740b20022005360214200220073602100b20002006360200200720046a41013a0000200341f8006a2203200a470d1b0c1c0b200510002207450d720b20022005360214200220073602100b20002006360200200720046a41023a0000200341f8006a2203200a470d180c190b200510002207450d700b20022005360214200220073602100b20002006360200200720046a41003a0000200341f8006a2203200a470d150c160b200741046a210b200821090c0e0b200741016a210b200821090c100b2009450d6c0b2002200e360214200220093602100b2000200b360200200920076a20054102744101723b00000c0e0b200b10002208450d6a0b2002200b360214200220083602100b20002005360200200820076a20064102744102723600000c030b200910002208450d680b20022009360214200220083602100b20002005360200200820076a41033a0000024002400240024020022802142209200028020022076b41044f0d00200741046a22052007490d1020094101742208200520052008491b220b4100480d102009450d012002280210210e200b10002208450d6b2008200e200b20092009200b4b1b10ce021a200e10010c020b200741046a2105200228021021080c020b200b10002208450d690b2002200b360214200220083602100b20002005360200200820076a20063600000b2006410574210b200028020021062002280214210503400240024002400240200520066b41204f0d00200641206a22072006490d1020054101742208200720072008491b22094100480d102005450d012002280210210e200910002208450d122008200e20092005200520094b1b10ce021a200e10010c020b200641206a2107200228021021080c020b200910002208450d100b2002200936021420022008360210200921050b20002007360200200820066a220641086a200441086a290000370000200641106a200441106a290000370000200641186a200441186a2900003700002006200429000037000020072106200441206a2104200b41606a220b0d000b0b200341146a2802002104024002400240024002400240024002400240024002400240024002400240024002400240024002402003411c6a2802002206413f4b0d00200228021420002802002207470d01200741016a22052007490d1e20074101742208200520052008491b22094100480d1e2007450d052002280210210b200910002208450d7a2008200b20092007200720094b1b10ce021a200b10010c060b2006418080014f0d0120022802142209200028020022076b41024f0d02200741026a22052007490d1d20094101742208200520052008491b220b4100480d1d2009450d092002280210210e200b10002208450d7a2008200e200b20092009200b4b1b10ce021a200e10010c0a0b200741016a2105200228021021080c050b20064180808080044f0d0120022802142209200028020022076b41044f0d05200741046a22052007490d1b20094101742208200520052008491b220b4100480d1b2009450d0a2002280210210e200b10002208450d792008200e200b20092009200b4b1b10ce021a200e10010c0b0b200741026a2105200228021021080c080b200228021420002802002207470d04200741016a22052007490d1920074101742208200520052008491b22094100480d192007450d0b2002280210210b200910002208450d782008200b20092007200720094b1b10ce021a200b10010c0c0b200910002208450d740b20022009360214200220083602100b20002005360200200820076a20064102743a000020060d0b0c130b200741046a2105200228021021080c060b200741016a2105200228021021080c080b200b10002208450d700b2002200b360214200220083602100b20002005360200200820076a20064102744101723b00000c060b200b10002208450d6e0b2002200b360214200220083602100b20002005360200200820076a20064102744102723600000c030b200910002208450d6c0b20022009360214200220083602100b20002005360200200820076a41033a0000024002400240024020022802142209200028020022076b41044f0d00200741046a22052007490d0f20094101742208200520052008491b220b4100480d0f2009450d012002280210210e200b10002208450d6f2008200e200b20092009200b4b1b10ce021a200e10010c020b200741046a2105200228021021080c020b200b10002208450d6d0b2002200b360214200220083602100b20002005360200200820076a20063600000b2006410574210b200028020021062002280214210503400240024002400240200520066b41204f0d00200641206a22072006490d0f20054101742208200720072008491b22094100480d0f2005450d012002280210210e200910002208450d122008200e20092005200520094b1b10ce021a200e10010c020b200641206a2107200228021021080c020b200910002208450d100b2002200936021420022008360210200921050b20002007360200200820066a220641086a200441086a290000370000200641106a200441106a290000370000200641186a200441186a2900003700002006200429000037000020072106200441206a2104200b41606a220b0d000c080b0b2009450d6a0b2002200e360214200220093602100b2000200b360200200920076a20054102744102723600000c030b2009450d680b2002200e360214200220093602100b2000200b360200200920076a41033a0000024002400240024020022802142209200028020022066b41044f0d00200641046a22072006490d0820094101742208200720072008491b220b4100480d082009450d012002280210210e200b10002208450d6b2008200e200b20092009200b4b1b10ce021a200e10010c020b200641046a2107200228021021080c020b200b10002208450d690b2002200b360214200220083602100b20002007360200200820066a20053600000b2005410574210b200028020021062002280214210503400240024002400240200520066b41204f0d00200641206a22072006490d0820054101742208200720072008491b22094100480d082005450d012002280210210e200910002208450d0c2008200e20092005200520094b1b10ce021a200e10010c020b200641206a2107200228021021080c020b200910002208450d0a0b2002200936021420022008360210200921050b20002007360200200820066a220641086a200441086a290000370000200641106a200441106a290000370000200641186a200441186a2900003700002006200429000037000020072106200441206a2104200b41606a220b0d000b0b200341f8006a2203200a470d000b0b200241106a41086a2200280200210420022802142106200228021021032001280204210720012802002105200042003703002002420037031020052007200241106a1002200241086a2000290300370300200220022903103703002002411020032004100302402006450d00200310010b200241206a24000f0b1018000b1018000b200941011019000b200941011019000b200941011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200841011019000b200541011019000b200841011019000b200841011019000b200841011019000b200841011019000b200841011019000b200841011019000b200841011019000b200841011019000b200841011019000b200841011019000b200841011019000b200541011019000b200841011019000b200841011019000b200841011019000b200841011019000b200841011019000b200841011019000b200641011019000b200941011019000b200941011019000b200541011019000b200541011019000b200541011019000b200541011019000b200841011019000b200841011019000b200541011019000b200841011019000b200541011019000b200541011019000b200541011019000b200841011019000b200841011019000b200541011019000b200841011019000b200841011019000b200541011019000b200841011019000b200941011019000b200541011019000b200541011019000b200841011019000b200541011019000b200941011019000b200541011019000b200841011019000b200841011019000b200541011019000b200541011019000b200841011019000b200541011019000b200541011019000b200541011019000b200841011019000b200541011019000b200841011019000b200541011019000b200841011019000b200841011019000b200841011019000b200641011019000b200941011019000b200541011019000b200541011019000b200541011019000b200e41011019000b200b41011019000b200541011019000b200541011019000b200541011019000b200e41011019000b200b41011019000b200941011019000b200b41011019000b200941011019000b200b41011019000b200b41011019000b200941011019000b200b41011019000b200e41011019000b200e41011019000b200b41011019000b200841011019000b410141011019000b410441011019000b410241011019000b410141011019000bfd0101067f024002400240024002400240200141046a2802002202200141086a28020022036b41204f0d00200341206a22042003490d0420024101742205200420042005491b22064100480d042002450d0120012802002107200610002205450d052005200720062002200220064b1b10ce021a200710010c020b200341206a2104200128020021050c020b200610002205450d030b20012005360200200141046a20063602000b200141086a2004360200200520036a220141186a200041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200120002900003700000f0b1018000b200641011019000bae0d01097f230041206b220224002000280200210302400240024002400240024002400240024002400240410410002204450d002004200336000020002802042105410810002203450d01200320042800003600002004100120032005360004200041086a2802002106024002400240024002400240200041106a280200220441c0004f0d00411010002205450d082005200329000037000020031001200520044102743a00084109210720040d01411021030c020b02402004418080014f0d00411010002205450d092005200329000037000020031001200520044102744101723b0008410a21070c010b411010002105024020044180808080044f0d002005450d0b200520032900003700002003100120052004410274410272360008410c21070c010b2005450d0b200520032900003700002003100120052004360009200541033a0008410d21070b200441057421084110210303402006210402400240024002402003200722096b41204f0d00200941206a22072009490d0620034101742206200720072006491b22064100480d062003450d0120061000220a450d07200a200520062003200320064b1b10ce02210320051001200321050c020b200941206a21070c020b200610002205450d050b200621030b200441206a2106200520096a22092004290000370000200941186a200441186a290000370000200941106a200441106a290000370000200941086a200441086a290000370000200841606a22080d000b0b200041146a28020021080240024002400240024002400240024002400240024002400240024002400240024002400240024002402000411c6a2802002204413f4b0d0020032007470d01200341016a22062003490d1520034101742209200620062009491b22094100480d152003450d0520091000220a450d1c200a200520092003200320094b1b10ce02210320051001200321050c060b2004418080014f0d01200320076b41024f0d02200741026a22062007490d1420034101742209200620062009491b22094100480d142003450d0920091000220a450d1e200a200520092003200320094b1b10ce02210320051001200321050c0a0b200741016a21060c050b20044180808080044f0d01200320076b41044f0d05200741046a22062007490d1220034101742209200620062009491b22094100480d122003450d0a20091000220a450d1d200a200520092003200320094b1b10ce02210320051001200321050c0b0b200741026a21060c080b20032007470d04200341016a22092003490d1020034101742206200920092006491b22064100480d102003450d0b20061000220a450d1c200a200520062003200320064b1b10ce02210320051001200321050c0c0b200910002205450d160b200921030b200520076a20044102743a000020040d0b0c0c0b200741046a21060c060b200741016a21090c080b200910002205450d140b200921030b200520076a20044102744101723b00000c060b200910002205450d120b200921030b200520076a20044102744102723600000c030b200610002205450d100b200621030b200520076a41033a00000240024002400240200320096b41044f0d00200941046a22062009490d0620034101742207200620062007491b22074100480d062003450d0120071000220a450d13200a200520072003200320074b1b10ce02210320051001200321050c020b200941046a21060c020b200710002205450d110b200721030b200520096a20043600000b2004410574210a03402008210402400240024002402003200622096b41204f0d00200941206a22062009490d0620034101742207200620062007491b22074100480d062003450d01200710002208450d082008200520072003200320074b1b10ce02210320051001200321050c020b200941206a21060c020b200710002205450d060b200721030b200441206a2108200520096a22092004290000370000200941186a200441186a290000370000200941106a200441106a290000370000200941086a200441086a290000370000200a41606a220a0d000b0b2001280204210420012802002109200241106a41086a220742003703002002420037031020092004200241106a1002200241086a2007290300370300200220022903103703002002411020052006100302402003450d00200510010b200241206a24000f0b1018000b200641011019000b200741011019000b410441011019000b410841011019000b411041011019000b411041011019000b200941011019000b411041011019000b411041011019000b200941011019000b200941011019000b200641011019000b200741011019000bc00201067f024002400240024002400240200041046a2802002202200041086a28020022036b41c0004f0d00200341c0006a22042003490d0420024101742205200420042005491b22064100480d042002450d0120002802002107200610002205450d052005200720062002200220064b1b10ce021a200710010c020b200341c0006a2104200028020021050c020b200610002205450d030b20002005360200200041046a20063602000b200041086a2004360200200520036a220041386a200141386a290000370000200041306a200141306a290000370000200041286a200141286a290000370000200041206a200141206a290000370000200041186a200141186a290000370000200041106a200141106a290000370000200041086a200141086a290000370000200020012900003700000f0b1018000b200641011019000bff0101027f230041206b220224000240200128020022034102470d0020004100101f200241206a24000f0b20004101101f024020034101470d00200141086a2802002001410c6a280200200010202000200141106a1021200241206a24000f0b200220012802041100002002280204200241086a2802002000102020002002410c6a10210240200228020c450d00200241106a28020021030240200241186a2802002201450d002001413c6c2100200341306a210103400240200141786a280200450d002001280200450d002001417c6a28020010010b2001413c6a2101200041446a22000d000b0b200241146a280200450d00200310010b200241206a24000bc30101057f024002400240024002400240200041046a280200200041086a2802002202470d00200241016a22032002490d0420024101742204200320032004491b22054100480d042002450d0120002802002106200510002204450d052004200620052002200220054b1b10ce021a200610010c020b200241016a2103200028020021040c020b200510002204450d030b20002004360200200041046a20053602000b200041086a2003360200200420026a20013a00000f0b1018000b200541011019000bde0601087f02400240024002400240024002402001413f4b0d0020022001410274101f200241046a2103200241086a21040c010b024002400240024002400240024002400240024002400240024002402001418080014f0d00200241046a22032802002205200241086a220428020022066b41024f0d01200641026a22072006490d0f20054101742208200720072008491b22094100480d0f2005450d052002280200210a200910002208450d112008200a20092005200520094b1b10ce021a200a10010c060b20014180808080044f0d01200241046a22032802002205200241086a220428020022066b41044f0d02200641046a22072006490d0e20054101742208200720072008491b22094100480d0e2005450d072002280200210a200910002208450d112008200a20092005200520094b1b10ce021a200a10010c080b200641026a2107200228020021080c050b20024103101f200241046a22032802002205200241086a220428020022066b41044f0d01200641046a22072006490d0c20054101742208200720072008491b22094100480d0c2005450d082002280200210a200910002208450d102008200a20092005200520094b1b10ce021a200a10010c090b200641046a2107200228020021080c060b200641046a2107200228020021080c080b200910002208450d0b0b20022008360200200241046a20093602000b20042007360200200820066a20014102744101723b00000c060b200910002208450d090b20022008360200200241046a20093602000b20042007360200200820066a20014102744102723600000c030b200910002208450d070b20022008360200200241046a20093602000b20042007360200200820066a20013600000b02400240024020032802002206200428020022036b20014f0d00200320016a22082003490d0320064101742207200820082007491b22074100480d032006450d0120022802002109200710002205450d042005200920072006200620074b1b10ce021a200910010c020b200228020021022004200320016a360200200220036a2000200110ce021a0f0b200710002205450d020b20022005360200200241046a200736020020042008360200200520036a2000200110ce021a0f0b1018000b200741011019000b200941011019000b200941011019000b200941011019000b880f01077f200128020421020240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802004101470d002001410c6a280200220141c0004f0d0120002001410274101f20010d1c0c270b200141086a280200220141c0004f0d0120002001410274101f20010d250c260b2001418080014f0d01200041046a2802002203200041086a28020022046b41024f0d03200441026a22052004490d2020034101742206200520052006491b22074100480d202003450d0b20002802002108200710002206450d1f2006200820072003200320074b1b10ce021a200810010c0c0b2001418080014f0d01200041046a2802002203200041086a28020022046b41024f0d03200441026a22052004490d1f20034101742206200520052006491b22074100480d1f2003450d0d20002802002108200710002206450d1d2006200820072003200320074b1b10ce021a200810010c0e0b20014180808080044f0d03200041046a2802002203200041086a28020022046b41044f0d05200441046a22052004490d1e20034101742206200520052006491b22074100480d1e2003450d0f20002802002108200710002206450d1b2006200820072003200320074b1b10ce021a200810010c100b20014180808080044f0d03200041046a2802002203200041086a28020022046b41044f0d05200441046a22052004490d1d20034101742206200520052006491b22074100480d1d2003450d1120002802002108200710002206450d192006200820072003200320074b1b10ce021a200810010c120b200441026a2105200028020021060c090b200441026a2105200028020021060c0b0b20004103101f200041046a2802002203200041086a28020022046b41044f0d03200441046a22052004490d1a20034101742206200520052006491b22074100480d1a2003450d1120002802002108200710002206450d152006200820072003200320074b1b10ce021a200810010c120b20004103101f200041046a2802002203200041086a28020022046b41044f0d03200441046a22052004490d1920034101742206200520052006491b22074100480d192003450d1a20002802002108200710002206450d1f2006200820072003200320074b1b10ce021a200810010c1b0b200441046a2105200028020021060c0b0b200441046a2105200028020021060c0d0b200441046a2105200028020021060c0f0b200441046a2105200028020021060c180b200710002206450d130b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744101723b00000c0c0b200710002206450d0f0b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744101723b00000c130b200710002206450d0b0b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744102723600000c060b200710002206450d070b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744102723600000c0d0b200710002206450d030b20002006360200200041046a20073602000b200041086a2005360200200620046a20013600000b2001413c6c2106410021040340200220046a220141046a280200200141086a2802002000102002400240024002400240200141386a2d000022054103714101460d0020054102470d0120004102101f2001410c6a2802004101460d030c020b20004101101f2001410c6a2802004101470d010c020b20004100101f2001410c6a2802004101460d010b20004100101f200141146a280200200141186a280200200010200c010b20004101101f200141146a280200200141186a28020020001020200141206a280200200141246a280200200010200b2001412c6a28020021050240200141286a2802004101470d002005200141346a2802002000102820062004413c6a2204470d010c0c0b2005200141306a2802002000102820062004413c6a2204470d000c0b0b0b200741011019000b200741011019000b200741011019000b200741011019000b200741011019000b1018000b200710002206450d040b20002006360200200041046a20073602000b200041086a2005360200200620046a20013600000b2001413c6c2106410021040340200220046a220141046a280200200141086a2802002000102002400240024002400240200141386a2d000022054103714101460d0020054102470d0120004102101f2001410c6a2802004101460d030c020b20004101101f2001410c6a2802004101470d010c020b20004100101f2001410c6a2802004101460d010b20004100101f200141146a280200200141186a280200200010200c010b20004101101f200141146a280200200141186a28020020001020200141206a280200200141246a280200200010200b2001412c6a28020021050240200141286a2802004101470d002005200141346a2802002000102820062004413c6a2204470d010c020b2005200141306a2802002000102820062004413c6a2204470d000b0b0f0b200741011019000b8f0201037f230041306b22022400024020012802004101470d00200141086a2802002001410c6a280200200010202000200141106a1023200241306a24000f0b200241086a2001280204110000200228020c200241106a280200200010202000200241146a10230240200241206a280200450d00200241086a411c6a28020021030240200241086a41246a2802002201450d00200141306c21044100210003400240200320006a2201410c6a280200450d00200141146a280200450d00200141106a28020010010b02402001411c6a280200450d00200141246a280200450d00200141206a28020010010b2004200041306a2200470d000b0b200241286a280200450d00200310010b200241306a24000be80c01077f2001280204200141086a28020020001020200141106a280200210202400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200128020c4101470d00200141186a280200220141c0004f0d0120002001410274101f20010d1c0c210b200141146a280200220141c0004f0d0120002001410274101f20010d1f0c200b2001418080014f0d01200041046a2802002203200041086a28020022046b41024f0d03200441026a22052004490d2020034101742206200520052006491b22074100480d202003450d0b20002802002108200710002206450d212006200820072003200320074b1b10ce021a200810010c0c0b2001418080014f0d01200041046a2802002203200041086a28020022046b41024f0d03200441026a22052004490d1f20034101742206200520052006491b22074100480d1f2003450d0d20002802002108200710002206450d212006200820072003200320074b1b10ce021a200810010c0e0b20014180808080044f0d03200041046a2802002203200041086a28020022046b41044f0d05200441046a22052004490d1e20034101742206200520052006491b22074100480d1e2003450d0f20002802002108200710002206450d212006200820072003200320074b1b10ce021a200810010c100b20014180808080044f0d03200041046a2802002203200041086a28020022046b41044f0d05200441046a22052004490d1d20034101742206200520052006491b22074100480d1d2003450d1120002802002108200710002206450d212006200820072003200320074b1b10ce021a200810010c120b200441026a2105200028020021060c090b200441026a2105200028020021060c0b0b20004103101f200041046a2802002203200041086a28020022046b41044f0d03200441046a22052004490d1a20034101742206200520052006491b22074100480d1a2003450d1120002802002108200710002206450d1f2006200820072003200320074b1b10ce021a200810010c120b20004103101f200041046a2802002203200041086a28020022046b41044f0d03200441046a22052004490d1920034101742206200520052006491b22074100480d192003450d1420002802002108200710002206450d1f2006200820072003200320074b1b10ce021a200810010c150b200441046a2105200028020021060c0b0b200441046a2105200028020021060c0d0b200441046a2105200028020021060c0f0b200441046a2105200028020021060c120b200710002206450d150b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744101723b00000c0c0b200710002206450d130b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744101723b00000c0d0b200710002206450d110b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744102723600000c060b200710002206450d0f0b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744102723600000c070b200710002206450d0d0b20002006360200200041046a20073602000b200041086a2005360200200620046a20013600000b200141306c21064100210403402000200220046a2201412c6a2f01001026200141046a280200200141086a2802002000102020002001410c6a1027200141206a280200210502402001411c6a2802004101470d002005200141286a280200200010282006200441306a2204470d010c060b2005200141246a280200200010282006200441306a2204470d000c050b0b200710002206450d0a0b20002006360200200041046a20073602000b200041086a2005360200200620046a20013600000b200141306c21064100210403402000200220046a2201412c6a2f01001026200141046a280200200141086a2802002000102020002001410c6a1027200141206a280200210502402001411c6a2802004101470d002005200141286a280200200010282006200441306a2204470d010c020b2005200141246a280200200010282006200441306a2204470d000b0b0f0b1018000b200741011019000b200741011019000b200741011019000b200741011019000b200741011019000b200741011019000b8112010e7f230041106b220224002001280200210302400240024002400240024002400240024002400240024002400240024002402001280208220141c0004f0d0020002001410274101f20010d010c020b024002400240024002400240024002400240024002400240024002402001418080014f0d00200041046a2802002204200041086a28020022056b41024f0d01200541026a22062005490d1020044101742207200620062007491b22084100480d102004450d0520002802002109200810002207450d1a2007200920082004200420084b1b10ce021a200910010c060b20014180808080044f0d01200041046a2802002204200041086a28020022056b41044f0d02200541046a22062005490d0f20044101742207200620062007491b22084100480d0f2004450d0720002802002109200810002207450d1a2007200920082004200420084b1b10ce021a200910010c080b200541026a2106200028020021070c050b20004103101f200041046a2802002204200041086a28020022056b41044f0d01200541046a22062005490d0d20044101742207200620062007491b22084100480d0d2004450d0820002802002109200810002207450d192007200920082004200420084b1b10ce021a200910010c090b200541046a2106200028020021070c060b200541046a2106200028020021070c080b200810002207450d140b20002007360200200041046a20083602000b200041086a2006360200200720056a20014102744101723b00000c060b200810002207450d120b20002007360200200041046a20083602000b200041086a2006360200200720056a20014102744102723600000c030b200810002207450d100b20002007360200200041046a20083602000b200041086a2006360200200720056a20013600000b2003200141246c6a210a200241086a210b0340024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020032d00004101470d00200328020c210520032802042101200b410036020020024201370300410110002206450d1a200220063602002002428180808010370204200641013a00002005413f4b0d012002280204200b2802002206470d02200641016a22072006490d1820064101742204200720072004491b22084100480d182006450d0620022802002109200810002204450d1d2004200920082006200620084b1b10ce021a200910010c070b200b410036020020024201370300410110002201450d1a200220013602002002428180808010370204200141023a0000200341016a2002101b0c140b2005418080014f0d0120022802042208200b28020022066b41024f0d02200641026a22072006490d1620084101742204200720072004491b22094100480d162008450d092002280200210c200910002204450d1c2004200c20092008200820094b1b10ce021a200c10010c0a0b200641016a2107200228020021040c050b20054180808080044f0d0120022802042208200b28020022066b41044f0d05200641046a22072006490d1420084101742204200720072004491b22094100480d142008450d0a2002280200210c200910002204450d1b2004200c20092008200820094b1b10ce021a200c10010c0b0b200641026a2107200228020021040c080b2002280204200b2802002206470d04200641016a22072006490d1220064101742204200720072004491b22084100480d122006450d0b20022802002109200810002204450d1a2004200920082006200620084b1b10ce021a200910010c0c0b200810002204450d160b20022008360204200220043602000b200b2007360200200420066a20054102743a000020050d0b0c0c0b200641046a2107200228020021040c060b200641016a2107200228020021040c080b200910002204450d120b20022009360204200220043602000b200b2007360200200420066a20054102744101723b00000c060b200910002204450d100b20022009360204200220043602000b200b2007360200200420066a20054102744102723600000c030b200810002204450d0e0b20022008360204200220043602000b200b2007360200200420066a41033a0000024002400240024020022802042208200b28020022066b41044f0d00200641046a22072006490d0820084101742204200720072004491b22094100480d082008450d012002280200210c200910002204450d112004200c20092008200820094b1b10ce021a200c10010c020b200641046a2107200228020021040c020b200910002204450d0f0b20022009360204200220043602000b200b2007360200200420066a20053600000b20054105742109200b28020021052002280204210703400240024002400240200720056b41204f0d00200541206a22062005490d0820074101742204200620062004491b22084100480d082007450d012002280200210c200810002204450d092004200c20082007200720084b1b10ce021a200c10010c020b200541206a2106200228020021040c020b200810002204450d070b2002200836020420022004360200200821070b200b2006360200200420056a220541086a200141086a290000370000200541106a200141106a290000370000200541186a200141186a2900003700002005200129000037000020062105200141206a2101200941606a22090d000b0b2002280204210c200228020021040240024002400240200041046a220d2802002208200041086a220e28020022016b200b28020022054f0d00200120056a22062001490d0620084101742207200620062007491b22094100480d062008450d012000280200210f200910002207450d0a2007200f20092008200820094b1b10ce021a200f10010c020b200120056a2106200028020021070c020b200910002207450d080b20002007360200200d20093602000b200341246a2103200e2006360200200720016a2004200510ce021a0240200c450d00200410010b2003200a470d000b0b200241106a24000f0b1018000b200841011019000b410141011019000b410141011019000b200941011019000b200841011019000b200941011019000b200941011019000b200841011019000b200941011019000b200841011019000b200841011019000b200841011019000bc80501077f2001280200210202400240024002400240024002402001280208220141c0004f0d0020002001410274101f20010d010c020b024002400240024002400240024002400240024002400240024002402001418080014f0d00200041046a2802002203200041086a28020022046b41024f0d01200441026a22052004490d1020034101742206200520052006491b22074100480d102003450d0520002802002108200710002206450d112006200820072003200320074b1b10ce021a200810010c060b20014180808080044f0d01200041046a2802002203200041086a28020022046b41044f0d02200441046a22052004490d0f20034101742206200520052006491b22074100480d0f2003450d0720002802002108200710002206450d112006200820072003200320074b1b10ce021a200810010c080b200441026a2105200028020021060c050b20004103101f200041046a2802002203200041086a28020022046b41044f0d01200441046a22052004490d0d20034101742206200520052006491b22074100480d0d2003450d0820002802002108200710002206450d102006200820072003200320074b1b10ce021a200810010c090b200441046a2105200028020021060c060b200441046a2105200028020021060c080b200710002206450d0b0b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744101723b00000c060b200710002206450d090b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744102723600000c030b200710002206450d070b20002006360200200041046a20073602000b200041086a2005360200200620046a20013600000b20022001410c6c6a210103402002280200200241086a280200200010202002410c6a22022001470d000b0b0f0b1018000b200741011019000b200741011019000b200741011019000bc80101067f024002400240024002400240200041046a2802002202200041086a28020022036b41024f0d00200341026a22042003490d0420024101742205200420042005491b22064100480d042002450d0120002802002107200610002205450d052005200720062002200220064b1b10ce021a200710010c020b200341026a2104200028020021050c020b200610002205450d030b20002005360200200041046a20063602000b200041086a2004360200200520036a20013b00000f0b1018000b200641011019000bc80b01077f200128020421020240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802004101470d002001410c6a280200220141c0004f0d0120002001410274101f20010d1c0c210b200141086a280200220141c0004f0d0120002001410274101f20010d1f0c200b2001418080014f0d01200041046a2802002203200041086a28020022046b41024f0d03200441026a22052004490d2020034101742206200520052006491b22074100480d202003450d0b20002802002108200710002206450d212006200820072003200320074b1b10ce021a200810010c0c0b2001418080014f0d01200041046a2802002203200041086a28020022046b41024f0d03200441026a22052004490d1f20034101742206200520052006491b22074100480d1f2003450d0d20002802002108200710002206450d212006200820072003200320074b1b10ce021a200810010c0e0b20014180808080044f0d03200041046a2802002203200041086a28020022046b41044f0d05200441046a22052004490d1e20034101742206200520052006491b22074100480d1e2003450d0f20002802002108200710002206450d212006200820072003200320074b1b10ce021a200810010c100b20014180808080044f0d03200041046a2802002203200041086a28020022046b41044f0d05200441046a22052004490d1d20034101742206200520052006491b22074100480d1d2003450d1120002802002108200710002206450d212006200820072003200320074b1b10ce021a200810010c120b200441026a2105200028020021060c090b200441026a2105200028020021060c0b0b20004103101f200041046a2802002203200041086a28020022046b41044f0d03200441046a22052004490d1a20034101742206200520052006491b22074100480d1a2003450d1120002802002108200710002206450d1f2006200820072003200320074b1b10ce021a200810010c120b20004103101f200041046a2802002203200041086a28020022046b41044f0d03200441046a22052004490d1920034101742206200520052006491b22074100480d192003450d1420002802002108200710002206450d1f2006200820072003200320074b1b10ce021a200810010c150b200441046a2105200028020021060c0b0b200441046a2105200028020021060c0d0b200441046a2105200028020021060c0f0b200441046a2105200028020021060c120b200710002206450d150b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744101723b00000c0c0b200710002206450d130b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744101723b00000c0d0b200710002206450d110b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744102723600000c060b200710002206450d0f0b20002006360200200041046a20073602000b200041086a2005360200200620046a20014102744102723600000c070b200710002206450d0d0b20002006360200200041046a20073602000b200041086a2005360200200620046a20013600000b200141186c2104200241146a21010340200141706a280200200141746a280200200010202001417c6a280200200128020020001020200141186a2101200441686a22040d000c050b0b200710002206450d0a0b20002006360200200041046a20073602000b200041086a2005360200200620046a20013600000b200141186c2104200241146a21010340200141706a280200200141746a280200200010202001417c6a280200200128020020001020200141186a2101200441686a22040d000b0b0f0b1018000b200741011019000b200741011019000b200741011019000b200741011019000b200741011019000b200741011019000bd90501067f02400240024002400240024002402001413f4b0d0020022001410274101f200141037422010d010c020b024002400240024002400240024002400240024002400240024002402001418080014f0d00200241046a2802002203200241086a28020022046b41024f0d01200441026a22052004490d1020034101742206200520052006491b22074100480d102003450d0520022802002108200710002206450d112006200820072003200320074b1b10ce021a200810010c060b20014180808080044f0d01200241046a2802002203200241086a28020022046b41044f0d02200441046a22052004490d0f20034101742206200520052006491b22074100480d0f2003450d0720022802002108200710002206450d112006200820072003200320074b1b10ce021a200810010c080b200441026a2105200228020021060c050b20024103101f200241046a2802002203200241086a28020022046b41044f0d01200441046a22052004490d0d20034101742206200520052006491b22074100480d0d2003450d0820022802002108200710002206450d102006200820072003200320074b1b10ce021a200810010c090b200441046a2105200228020021060c060b200441046a2105200228020021060c080b200710002206450d0b0b20022006360200200241046a20073602000b200241086a2005360200200620046a20014102744101723b0000200141037422010d060c070b200710002206450d090b20022006360200200241046a20073602000b200241086a2005360200200620046a2001410274410272360000200141037422010d030c040b200710002206450d070b20022006360200200241046a20073602000b200241086a2005360200200620046a200136000020014103742201450d010b200020016a210103402000280200200041046a28020020021020200041086a22002001470d000b0b0f0b1018000b200741011019000b200741011019000b200741011019000bcb0101067f024002400240024002400240200041046a2802002203200041086a28020022046b20024f0d00200420026a22052004490d0420034101742206200520052006491b22074100480d042003450d0120002802002108200710002206450d052006200820072003200320074b1b10ce021a200810010c020b200420026a2105200028020021060c020b200710002206450d030b20002006360200200041046a20073602000b200041086a2005360200200620046a2001200210ce021a0f0b1018000b200741011019000bee0201067f02400240024002400240024002400240024002400240200041086a280200220220014f0d00200041046a280200220320026b200120026b22044f0d01200220046a22012002490d0620034101742205200120012005491b22014100480d062003450d0320002802002106200110002205450d072005200620012003200320014b1b10ce021a200610010c040b200220014d0d012002210303402003417f6a2103200141016a22012002490d000c0a0b0b200028020020026a21054102210620044102490d030c060b200041086a20023602000f0b200110002205450d030b20002005360200200041046a2001360200200520026a210541022106200441024f0d030b200221032004450d040c030b1018000b200141011019000b410021010340200520016a41003a0000200120066a2103200141016a2207210120032004490d000b200220076a2102200520076a21050b200541003a0000200241016a21030b200041086a20033602000bfc0d01067f0240024002400240024002400240024002400240024002400240024020002d00002201410f71410d4b0d00024020010e0e0002030405060708090e0a0b0c0d000b200041086a280200450d0d200041046a28020010010f0b0240200041086a280200450d00200041046a28020010010b0240200041146a2802002201450d00200041186a280200450d00200110010b200041246a280200450d0c200041206a28020010010f0b0240200041086a280200450d00200041046a28020010010b200041146a280200450d0b200041106a28020010010f0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d00200128020010010b200141106a2101200241706a22020d000b0b200041086a280200450d0a200041046a28020010010f0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101200241586a22020d000b0b200041086a280200450d09200041046a28020010010f0b200041086a280200450d08200041046a28020010010f0b200041086a280200450d07200041046a28020010010f0b200041086a280200450d06200041046a28020010010f0b02402000410c6a2802002201450d00200041046a280200220320014104746a21040340024020032802082202450d0020032802002101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200241706a22020d000b0b200341106a21010240200341046a280200450d00200328020010010b2001210320012004470d000b0b200041086a280200450d05200041046a28020010010f0b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d00200128020010010b200141146a21012002416c6a22020d000b0b200041086a280200450d04200041046a28020010010f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200241706a22020d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b2001210320012004470d000b0b200041086a280200450d03200041046a28020010010f0b02402000410c6a2802002201450d00200041046a2802002203200141186c6a210403400240200341046a280200450d00200328020010010b0240200341146a2802002202450d00200328020c2101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200241706a22020d000b0b200341186a21010240200341106a280200450d002003410c6a28020010010b2001210320012004470d000b0b200041086a280200450d02200041046a28020010010f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200241706a22020d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b2001210320012004470d000b0b200041086a280200450d01200041046a28020010010f0b024002400240200041046a2d000022014103714102460d0020014101460d0120010d022000410c6a280200450d03200041086a28020010010f0b0240200041146a2802002201450d002000410c6a280200220520014104746a210603402005220441106a2105024020042802042201450d0002402004410c6a2802002202450d002002410c6c21020340024020012802002203450d00200141046a280200450d00200310010b2001410c6a2101200241746a22020d000b0b200441086a280200450d00200441046a28020010010b20052006470d000b0b200041106a280200450d022000410c6a28020010010c020b0240200041146a2802002202450d002000410c6a28020021012002410c6c21020340024020012802002203450d00200141046a280200450d00200310010b2001410c6a2101200241746a22020d000b0b200041106a280200450d012000410c6a28020010010f0b2000410c6a280200450d00200041086a28020010010f0b0b9c0401027f0240024002400240024002400240024002400240024002402000280200220141094b0d0020010e0a010b0b0b0b020304050b010b200041086a2d00002201411e74411e75417f4a0d0a20014102470d06200041306a280200450d0a2000412c6a28020010010f0b200041086a280200220141054b0d06024020010e060a0a0a0008090a0b200041106a280200450d092000410c6a28020010010f0b200041086a2d000022014107714105460d0320014102470d082000410c6a2200280200102c200028020010010f0b200041086a2802004102470d07200041106a280200450d072000410c6a28020010010f0b200041086a2d00004102470d062000410c6a2200280200102c200028020010010f0b20002d00044102470d052000410c6a2200280200102c200028020010010f0b2000410c6a2200280200102c200028020010010f0b0240200041106a280200450d002000410c6a28020010010b2000411c6a280200450d03200041186a28020010010f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141186a2101200241686a22020d000b0b200041106a280200450d022000410c6a28020010010f0b200041106a280200450d012000410c6a28020010010f0b200041106a280200450d002000410c6a28020010010f0b0b5c01027f024020012802082202417f4c0d0020012802002101024002402002450d002002100022030d01200241011019000b410121030b20032001200210ce0221012000200236020420002001360200200020023602080f0b102e000b05001018000bdb0101087f024020002802082201200028020c2202460d000340200041086a2001411c6a220336020020012802042204450d01200141146a2802002105200141086a28020021062001280210210702402001410c6a2802002201450d0020014104742108200421010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200841706a22080d000b0b02402006450d00200410010b02402005450d00200710010b2003210120032002470d000b0b02402000280204450d00200028020010010b0bda0101087f024020002802082201200028020c2202460d00200041086a210303402003200141186a220436020020012802002205450d01200141146a2802002106200141106a2802002107200128020c210802402001280204450d00200510010b02402006450d0020064104742106200821010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200641706a22060d000b0b02402007450d00200810010b2004210120042002470d000b0b02402000280204450d00200028020010010b0bc60101077f024020002802082201200028020c2202460d00200041086a210303402003200141106a22043602002001410d6a2d00004102460d012001280204210520012802002106024020012802082201450d0020014104742107200621010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200741706a22070d000b0b02402005450d00200610010b2004210120042002470d000b0b02402000280204450d00200028020010010b0bd20303027f017e0a7f230041106b2202240020022001103302400240024002400240024002400240024002402002280200450d0020022802042203ad2204421e88a70d032004420286a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241106a24000f0b4104210620030d030b4100210a4100210b0c030b102e000b200541041019000b200128020021072001280204210541002108410021094100210a2003210b03402002410036020c2002410c6a2007200541042005410449220c1b220d10ce021a200141046a2005200d6b220536020020012007200d6a2207360200200c0d02200228020c210d0240200a200b470d002009200a41016a220c200c2009491b220bad4202862204422088a70d042004a7220c4100480d040240200a450d00200c1000220e450d06200e2006200c20082008200c4b1b10ce02210c20061001200c21060c010b200c10002206450d050b200620086a200d360200200841046a2108200941026a2109200a41016a220a2003490d000b0b2000200b36020420002006360200200041086a200a360200200241106a24000f0b200041003602000240200b450d00200610010b200241106a24000f0b1018000b200c41041019000ba60301077f230041106b2202240041002103200241003a0003200241036a2001280200220420012802042205410047220610ce021a2001200520066b22073602042001200420066a2206360200024002402005450d0002400240024020022d000322044103712205450d0020054101460d0120054102470d0241002103200241003a000e200241003b010c2002410c6a200620074103200741034922081b220510ce021a200141046a200720056b3602002001200620056a36020020080d0420022f010c20022d000e411074724108742004724102762105410121030c040b20044102762105410121030c030b41002103200241003a000b2002410b6a20062007410047220510ce021a200141046a200720056b3602002001200620056a3602002007450d0120022d000b4108742004724102762105410121030c020b200441044f0d014100210320024100360204200241046a200620074104200741044922041b220510ce021a200141046a200720056b3602002001200620056a36020020040d0020022802042105410121030c010b0b2000200536020420002003360200200241106a24000bbc1007027f017e147f017e027f017e017f230041d0016b22022400200241106a20011035024002400240024002400240024002400240024002402002280210450d0020022802142203ad42247e2204422088a70d0a2004a72205417f4c0d0a2005450d01200510002206450d032003450d020c040b20004100360200200241d0016a24000f0b4104210620030d020b41002110410021110c020b200541041019000b200241186a41116a210720024197016a210820024188016a41106a210520024188016a4101722109200241c0006a410172210a200141046a210b200141086a210c20024188016a41186a210d4100210e4100210f41002110200321110340200241003a008801200c200c280200221220012802002213200b280200221420024188016a41012012100441016a221241014b6a221536020002400240024002400240024002400240024020124102490d004103211620022d0088012212450d0220124101460d0120124102470d08200d42003703002005420037030020024188016a41086a221742003703002002420037038801200c41002013201420024188016a41202015100422122012417f461b2212412020124120491b20156a3602002012411f4d0d03200241c8016a41026a20022d008a013a0000200241b0016a41086a200841086a290000370300200241b0016a41106a200841106a2d00003a0000200220022f0188013b01c801200220082900003703b001200228008b012118200229008f012119410121120c040b410321160c070b20024188016a200110362002280288012212450d06200229028c01210420024184016a41026a200241b0016a41026a2d00003a0000200241186a41086a20024188016a41086a290200370300200241186a41106a2005280200360200200220022f00b0013b0184012002200229028801370318410021162012211b0c060b200241086a200110352002280208450d05200228020c2212417f4c0d0c2012450d02201210002215450d0420154100201210d0021a0c030b410021120b200241cc016a41026a2215200241c8016a41026a2d00003a00002017200241b0016a41086a2903003703002005200241b0016a41106a2d00003a0000200220022f01c8013b01cc01200220022903b001370388012012450d0320024184016a41026a20152d00003a0000200241186a41086a2017290300370300200241186a41106a20052d00003a0000200220022f01cc013b0184012002200229038801370318200741026a20024188016a41026a2d00003a0000200720022f0088013b000041012116201921042018211b0c030b410121150b200c200c2802002213201241002001280200200b280200201520122013100422132013417f461b2213201320124b1b6a3602000240201220134d0d00201510010c020b2015450d012012ad220442208620048421044102211620024184016a41026a200241b0016a41026a2d00003a0000200241186a41086a20024188016a41086a290200370300200241186a41106a2005280200360200200220022f00b0013b01840120022002290288013703182015211b0c010b201241011019000b200241b0016a41026a221420024184016a41026a2d00003a000020024188016a41086a2212200241186a41086a22152903003703002005200241186a41106a2213280200360200200220022f0184013b01b001200220022903183703880120164103460d0220024180016a41026a221720142d00003a0000200241e8006a41086a22142012290300370300200241e8006a41106a221a2005280200360200200220022f01b0013b018001200220022903880137036820122004370300200920022f0180013b0000200941026a20172d00003a000020052002290368370000200541086a2014290300370000200541106a201a280200360000200220163a0088012002201b36028c01200241c0006a20024188016a103720022d0040211620024188016a41226a2214200a41226a2d00003a000020024188016a41206a2217200a41206a2f00003b0100200d200a41186a2900003703002005200a41106a2900003703002012200a41086a2900003703002002200a2900003703880120164102460d03200241186a41226a221a20142d00003a0000200241186a41206a221420172f01003b0100200241186a41186a2217200d29030037030020132005290300370300201520122903003703002002200229038801370318024020102011470d00200e201041016a22122012200e491b2211ad42247e221c422088a70d05201ca722124100480d0502402010450d0020121000221d450d07201d20062012200f200f20124b1b10ce02211220061001201221060c010b201210002206450d060b2006200f6a221220163a0000201241236a201a2d00003a0000201241216a20142f01003b0000201241196a2017290300370000201241116a2013290300370000201241096a2015290300370000201241016a2002290318370000200e41026a210e200f41246a210f201041016a22102003490d000b0b2000201136020420002006360200200041086a2010360200200241d0016a24000f0b200241023a004020024188016a41226a200a41226a2d00003a000020024188016a41206a200a41206a2f00003b010020024188016a41186a200a41186a29000037030020024188016a41106a200a41106a29000037030020024188016a41086a200a41086a2900003703002002200a290000370388010b2000410036020002402010450d00200621050340024020052d0000450d00200541086a280200450d00200541046a28020010010b200541246a2105200f415c6a220f0d000b0b02402011450d00200610010b200241d0016a24000f0b1018000b201241041019000b102e000b990301077f230041106b2202240041002103200241003a000f20012001280208220420012802002205200128020422062002410f6a41012004100441016a220441014b6a220736020802400240024020044102490d0002400240024020022d000f22084103712204450d0020044101460d0120044102470d0220024100360208200220083a000841012103200141086a410020052006200241086a41017241032007100422012001417f461b22014103200141034922011b20076a36020020010d04200228020841027621040c050b20084102762104410121030c040b41002103200241003b0106200220083a0006200141086a200720052006200241066a41017241012007100441016a220141014b6a36020020014102490d0120022f01064102762104410121030c030b200841044f0d024100210320024100360200200141086a410020052006200241042007100422012001417f461b22014104200141044922011b20076a36020020010d0020022802002104410121030c020b0c010b410021030b2000200436020420002003360200200241106a24000bbc0705027f017e0e7f027e037f230041f0006b22022400200241086a2001103502400240024002400240024002400240024002402002280208450d00200228020c2203ad2204421b88a70d032004420586a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241f0006a24000f0b4101210620030d030b410021054100210e0c030b102e000b200541011019000b200128020821072001280204210820012802002109200241d0006a41186a210a200241d0006a41106a210b4100210c4100210d410021052003210e0340200a4200370300200b4200370300200241d0006a41086a220f420037030020024200370350200141086a410020092008200241d0006a41202007100422102010417f461b2210412020104120491b20076a22073602002010411f4d0d02200241306a41186a2210200a290300370300200241306a41106a2211200b290300370300200241306a41086a2212200f29030037030020022002290350370330200a20102903002204370300200b20112903002213370300200f20122903002214370300200241106a41086a22152014370300200241106a41106a22162013370300200241106a41186a2217200437030020022002290330220437031020022004370350200a20172903002204370300200b20162903002213370300200f201529030022143703002012201437030020112013370300201020043703002002200229031022043703302002200437035002402005200e470d00200d200541016a220f200f200d491b220ead4205862204422088a70d042004a7220f4100480d0402402005450d00200f10002215450d0620152006200f200c200c200f4b1b10ce02210f20061001200f21060c010b200f10002206450d050b2006200c6a220f2002290330370000200f41186a2010290300370000200f41106a2011290300370000200f41086a2012290300370000200c41206a210c200d41026a210d200541016a22052003490d000b0b2000200e36020420002006360200200041086a2005360200200241f0006a24000f0b200241d0006a41186a2205200241306a41186a290000370300200241d0006a41106a220a200241306a41106a290000370300200241d0006a41086a220b200241306a41086a290000370300200220022900303703502005200241106a41186a290000370300200a200241106a41106a290000370300200b200241106a41086a29000037030020022002290010370350200041003602000240200e450d00200610010b200241f0006a24000f0b1018000b200f41011019000bac0b03057f017e017f23004180016b22022400024002400240024002400240024002400240024002400240024020012d00002203410371450d0020034101470d02200041003a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a29000037000020030d014101450d0c0c0b0b200241eb006a2001410c6a280000360000200041013a00002002200141046a29000037006320002002290060370001200041086a200241e7006a2900003700002003450d020b200341037122004101460d0a20000d07200141086a280200450d0a200141046a280200100120024180016a24000f0b20034102470d07200141046a28020021042001410c6a2802002103200241003a0060200241e0006a20042003410047220510ce021a2002200320056b22063602242002200420056a22043602202003450d07024020022d00602203450d0020034101470d08200241003a0060200241e0006a20042006410047220310ce021a2002200620036b3602242002200420036a3602202006450d0820022d00600d08200241e0006a200241206a103b20022802602203450d08200229026421072002411c6a41026a200241c0006a41026a2d00003a0000200241086a41086a200241e0006a41086a290200370300200241086a41106a200241e0006a41106a280200360200200220022f00403b011c20022002290260370308410121060c060b41002105200241003a0060200241e0006a20042006410047220310ce021a2002200620036b22083602242002200420036a22033602202006450d0320022d00600d0341002104200241e0006a2008412020084120491b22066a41004100412020066b2006411f4b1b10d0021a200241e0006a2003200610ce021a2002200820066b3602242002200320066a3602202008411f4d0d01200241d8006a41026a200241e0006a41026a2d00003a0000200241c8006a200241f7006a290000370300200241d0006a200241e0006a411f6a2d00003a0000200220022f00603b01582002200229006f3703402002280063210320022900672107410121040c020b41000d070c080b0b200241dc006a41026a2206200241d8006a41026a2d00003a0000200241e0006a41086a2205200241c0006a41086a290300370300200241e0006a41106a2208200241c0006a41106a2d00003a0000200220022f01583b015c2002200229034037036002402004450d002002413c6a41026a20062d00003a0000200241286a41086a2005290300370300200241286a41106a20082d00003a0000200220022f015c3b013c20022002290360370328410121050c020b410021050b0b200241c0006a41026a22062002413c6a41026a2d00003a0000200241e0006a41086a2204200241286a41086a290300370300200241e0006a41106a2208200241286a41106a2d00003a0000200220022f013c3b0140200220022903283703602005450d022002411c6a41026a20062d00003a0000200241086a41086a2004290300370300200241086a41106a20082d00003a0000200220022f01403b011c200220022903603703082002411b6a200241e0006a41026a2d00003a0000200220022f00603b0019410021060b200241c0006a41026a22042002411c6a41026a2d00003a0000200241e0006a41086a2205200241086a41086a290300370300200241e0006a41106a2208200241086a41106a280200360200200220022f011c3b014020022002290308370360200020063a0000200041046a2003360000200041086a2007370000200020022f01403b0001200041036a20042d00003a0000200041106a2002290360370000200041186a2005290300370000200041206a20082802003600000b200141086a280200450d02200141046a28020010010c020b41b28dc200411e1040000b200141086a280200450d00200141046a280200100120024180016a24000f0b20024180016a24000bdb0303027f017e0b7f230041106b2202240020022001103502400240024002400240024002400240024002402002280200450d0020022802042203ad2204421e88a70d032004420286a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241106a24000f0b4104210620030d030b410021014100210c0c030b102e000b200541041019000b200128020821072001280204210820012802002109200141086a210a410021054100210b410021012003210c03402002410036020c200a4100200920082002410c6a410420071004220d200d417f461b220d4104200d410449220d1b20076a2207360200200d0d02200228020c210d02402001200c470d00200b200141016a220c200c200b491b220cad4202862204422088a70d042004a7220e4100480d0402402001450d00200e1000220f450d06200f2006200e20052005200e4b1b10ce02210e20061001200e21060c010b200e10002206450d050b200620056a200d360200200541046a2105200b41026a210b200141016a22012003490d000b0b2000200c36020420002006360200200041086a2001360200200241106a24000f0b200041003602000240200c450d00200610010b200241106a24000f0b1018000b200e41041019000bb00605027f017e0e7f027e017f230041f0006b22022400200241086a2001103502400240024002400240024002400240024002402002280208450d00200228020c2203ad2204421b88a70d032004420586a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241f0006a24000f0b4101210620030d030b410021054100210e0c030b102e000b200541011019000b200128020821072001280204210820012802002109200241d0006a41186a210a200241d0006a41106a210b4100210c4100210d410021052003210e0340200a4200370300200b4200370300200241d0006a41086a220f420037030020024200370350200141086a410020092008200241d0006a41202007100422102010417f461b2210412020104120491b20076a22073602002010411f4d0d02200241306a41186a2210200a290300370300200241306a41106a2211200b290300370300200241306a41086a2212200f29030037030020022002290350370330200a20102903002204370300200b20112903002213370300200f20122903002214370300200241106a41086a220f2014370300200241106a41106a22112013370300200241106a41186a221220043703002002200229033022043703102002200437035002402005200e470d00200d200541016a22102010200d491b220ead4205862204422088a70d042004a722104100480d0402402005450d00201010002215450d06201520062010200c200c20104b1b10ce02211020061001201021060c010b201010002206450d050b2006200c6a22102002290310370000201041186a2012290300370000201041106a2011290300370000201041086a200f290300370000200c41206a210c200d41026a210d200541016a22052003490d000b0b2000200e36020420002006360200200041086a2005360200200241f0006a24000f0b200241d0006a41186a200241306a41186a290000370300200241d0006a41106a200241306a41106a290000370300200241d0006a41086a200241306a41086a29000037030020022002290030370350200041003602000240200e450d00200610010b200241f0006a24000f0b1018000b201041011019000b9203010b7f230041106b22022400200220011035024002400240024002400240024002402002280200450d0020022802042203417f4c0d062003450d01200310002204450d07200128020821052001280204210620012802002107200141086a210841002109410021012003210a034020012101200241003a000f20082005200720062002410f6a41012005100441016a220b41014b6a2205360200200b4102490d0420022d000f210b02402001200a470d002009200141016a220a200a2009491b220a4100480d0602402001450d00200a1000220c450d08200c2004200a20012001200a4b1b10ce02210c20041001200c21040c010b200a10002204450d070b200420016a200b3a0000200941026a2109200141016a22012003490d000c030b0b20004100360200200241106a24000f0b41012104410021014100210a0b2000200a36020420002004360200200041086a2001360200200241106a24000f0b200041003602000240200a450d00200410010b200241106a24000f0b1018000b200a41011019000b102e000b200341011019000bb90705027f017e0e7f027e037f230041f0006b22022400200241086a2001103302400240024002400240024002400240024002402002280208450d00200228020c2203ad2204421b88a70d032004420586a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241f0006a24000f0b4101210620030d030b4100210c4100210d0c030b102e000b200541011019000b2001280200210720012802042108200141046a21094100210a4100210b4100210c2003210d0340200241d0006a2008220e4120200e4120491b22056a41004100412020056b2005411f4b1b10d0021a200241d0006a2007200510ce021a2009200e20056b22083602002001200720056a2207360200200e411f4d0d02200241306a41186a2205200241d0006a41186a220f290000370300200241306a41106a220e200241d0006a41106a2210290000370300200241306a41086a2211200241d0006a41086a221229000037030020022002290050370330200f200529030022043703002010200e2903002213370300201220112903002214370300200241106a41086a22152014370300200241106a41106a22162013370300200241106a41186a2217200437030020022002290330220437031020022004370350200f2017290300220437030020102016290300221337030020122015290300221437030020112014370300200e201337030020052004370300200220022903102204370330200220043703500240200c200d470d00200b200c41016a220f200f200b491b220dad4205862204422088a70d042004a7220f4100480d040240200c450d00200f10002210450d0620102006200f200a200a200f4b1b10ce02210f20061001200f21060c010b200f10002206450d050b2006200a6a220f2002290330370000200f41186a2005290300370000200f41106a200e290300370000200f41086a2011290300370000200a41206a210a200b41026a210b200c41016a220c2003490d000b0b2000200d36020420002006360200200041086a200c360200200241f0006a24000f0b200241d0006a41186a2205200241306a41186a290000370300200241d0006a41106a220c200241306a41106a290000370300200241d0006a41086a220e200241306a41086a290000370300200220022900303703502005200241106a41186a290000370300200c200241106a41106a290000370300200e200241106a41086a29000037030020022002290010370350200041003602000240200d450d00200610010b200241f0006a24000f0b1018000b200f41011019000b880606027f017e0b7f017e037f017e230041d0006b22022400200241086a200110350240024002400240024002400240024002402002280208450d00200228020c2203ad42307e2204422088a70d032004a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241d0006a24000f0b4108210620030d030b4100210e4100210f0c030b102e000b200541081019000b200128020821072001280204210820012802002109200141086a210a200241306a41186a210b4100210c4100210d4100210e2003210f024003402002420037033820024200370330200a410020092008200241306a41102007100422012001417f461b2201411020014110491b20076a22073602002001410f4d0d01200241306a41086a2205290300210420022903302110200b4200370300200241306a41106a221142003703002005420037030020024200370330200a410020092008200241306a41202007100422012001417f461b2201412020014120491b20076a22073602002001411f4d0d01200241106a41186a2201200b290300370300200241106a41106a22122011290300370300200241106a41086a2213200529030037030020022002290330370310200b20012903003703002011201229030037030020052013290300370300200220022903103703300240200e200f470d00200c200e41016a22012001200c491b220fad42307e2214422088a70d042014a722014100480d040240200e450d00200110002212450d06201220062001200d200d20014b1b10ce02210120061001200121060c010b200110002206450d050b2006200d6a2201200437030820012010370300200141286a200b290300370300200141206a2011290300370300200141186a2005290300370300200141106a2002290330370300200c41026a210c200d41306a210d200e41016a220e2003490d000c020b0b200041003602000240200f450d00200610010b200241d0006a24000f0b2000200f36020420002006360200200041086a200e360200200241d0006a24000f0b1018000b200141081019000bbd0201057f0240024002400240024002400240200041046a2802002202200028020822036b20012802042204200128020022056b22064f0d00200320066a22052003490d0420024101742206200520052006491b22054100480d042002450d0120002802002104200510002206450d052006200420052002200220054b1b10ce021a200410010c020b2000280200210620052004470d020c050b200510002206450d030b20002006360200200041046a200536020020012802002205200141046a280200460d030b2001200541016a36020020052d00002105200141046a210202400340200620036a20053a0000200128020022052002280200460d01200341016a21032001200541016a36020020052d000021050c000b0b200041086a200341016a3602000f0b1018000b200541011019000b200041086a20033602000bed0104017e047f017e027f20012902002102410021030240024002400240024002400240200128020c2204200128020822016b2205450d0020054102752206ad4202862207422088a70d022007a722084100480d02200810002209450d0320012004470d010c040b410421094100210620012004460d030b2005417c6a410276210520092103034020032001280200360200200341046a21032004200141046a2201470d000b200541016a210320024280808080105a0d030c040b1018000b200841041019000b2002428080808010540d010b2002a710010b2000200636020420002009360200200020033602080b970704037f017e0c7f027e230041a0016b220324000240024002400240024002400240024020022001200220014b22041b20016b2205450d002005ad4205862206422088a70d022006a722074100480d02200710002208450d032004450d010c040b410121084100210520040d030b4100210b0c030b1018000b200741011019000b200341186a2109200341106a210a200821044100210b034020032001200b6a360240410610002207450d032003200736028001200342063702840120034180016a41d1aac20041061029200341e0006a41086a220d20034180016a41086a22072802003602002003200329038001370360200341e0006a200341c0006a410410292003280264210c0240024002402003280260220e200d280200220f41b8d6c200410041001004417f470d0020094200370300200a4200370300200341086a420037030020034200370300200c0d010c020b20034180016a41186a2210420037030020034180016a41106a22114200370300200742003703002003420037038001200e200f20034180016a412041001004220f417f460d04200f411f4d0d04200341e0006a41186a220f2010290300370300200341e0006a41106a22122011290300370300200d200729030037030020032003290380013703602010200f29030022063703002011201229030022133703002007200d2903002214370300200341c0006a41086a220d2014370300200341c0006a41106a220f2013370300200341c0006a41186a221220063703002003200329036022063703402003200637038001201020122903003703002011200f2903003703002007200d2903003703002003200329034037038001201220102903002206370300200f20112903002213370300200d20072903002214370300200341086a2014370300200a2013370300200920063703002003200329038001220637034020032006370300200c450d010b200e10010b20042003290300370000200441186a2009290300370000200441106a200a290300370000200441086a200341086a290300370000200441206a21042001200b41016a220b6a2002490d000b0b20002005360204200020083602002000200b360208200341a0016a24000f0b20034180016a41186a200341e0006a41186a29000037030020034180016a41106a200341e0006a41106a29000037030020034180016a41086a200341e0006a41086a290000370300200320032900603703800141b2eac10041331040000b410641011019000b7201017f230041306b220224002002200136020c200220003602082002411c6a4101360200200241246a41013602002002410136022c200241e892c00036021020024101360214200241c0c5c2003602182002200241086a3602282002200241286a360220200241106a41f092c0001065000bb20101057f200220016b2203410c6e21044104210541002106410021070240024002402003410c490d00200441037422034100480d01200310002205450d02200421070b024020012002460d004100210620052103034020012802002104200341046a200141086a28020036020020032004360200200341086a2103200641016a21062001410c6a22012002470d000b0b2000200736020420002005360200200020063602080f0b1018000b200341041019000b890a03027f047e027f230041d0006b2102024002400240024002400240024002400240024020012d002022034103714101460d0020034102470d0120012802142203200141186a280200460d02200141146a200341206a360200200241286a41186a200341186a2900002204370300200241286a41106a200341106a2900002205370300200241286a41086a200341086a2900002206370300200020032900002207370308200041106a2006370300200041186a2005370300200041206a2004370300200041286a2001411c6a28020029030037030020022007370328200042013703000f0b20012802102208450d02200141106a4100360200024020012802082203200128020c2209460d002008417f7321080340200241286a41206a200341206a290300370300200241286a41186a200341186a290300370300200241286a41106a200341106a290300370300200241286a41086a200341086a29030037030020022003290300370328200841016a2208450d072009200341286a2203470d000b200141086a20093602000b200042003703000f0b20012802102208450d02200141106a410036020020012802082203200128020c2209460d032008417f7321080340200241286a41206a200341206a290300370300200241286a41186a200341186a290300370300200241286a41106a200341106a290300370300200241286a41086a200341086a29030037030020022003290300370328200841016a2208450d062009200341286a2203470d000b200141086a20093602000c030b200042003703000f0b20012802082202200128020c460d05200141086a200241286a360200200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a29030037030020002002290300370308200042013703000f0b20012802082203200128020c460d00200141086a200341286a360200200241206a200341206a290300370300200241186a200341186a290300370300200241106a200341106a290300370300200241086a200341086a290300370300200220032903003703000c030b200141206a41023a0000024020012802142203200141186a280200460d00200141146a200341206a360200200241286a41186a200341186a2900002204370300200241286a41106a200341106a2900002205370300200241286a41086a200341086a2900002206370300200020032900002207370308200041106a2006370300200041186a2005370300200041206a2004370300200041286a2001411c6a28020029030037030020022007370328200042013703000f0b200042003703000f0b2000200229032837030820004201370300200141086a200341286a360200200041106a200241286a41086a290300370300200041186a200241286a41106a290300370300200041206a200241286a41186a290300370300200041286a200241286a41206a2903003703000f0b200141086a200341286a360200200241086a200241286a41086a290300370300200241106a200241286a41106a290300370300200241186a200241286a41186a290300370300200241206a200241286a41206a290300370300200220022903283703000b2000200229030037030820004201370300200041106a200241086a290300370300200041186a200241106a290300370300200041206a200241186a290300370300200041286a200241206a2903003703000f0b200042003703000beb04020b7f017e230041e0046b22022400024020012d000c450d002000410b360208200241e0046a24000f0b024002400240024020012802002203200128020422044f0d002001200341016a2205360200200241106a41086a21060240411a10002207450d000340200220073602102002421a370214200241106a4188c9c100411a102920022802102107024002400240024020022802142208200628020022096b41044f0d00200941046a220a2009490d082008410174220b200a200a200b491b220b4100480d082008450d01200b1000220c450d09200c2007200b20082008200b4b1b10ce02210820071001200821070c020b200941046a210a0c020b200b10002207450d070b200b21080b200720096a2003360000200241b0026a2007200a104402402008450d00200710010b200241b0026a41086a2802002207410b470d03200520044f0d022001200541016a22073602002005210320072105411a100022070d000b0b411a41011019000b2000410b360208200241e0046a24000f0b200241d8046a2d0000210820022903b002210d200241106a200241b0026a410c6a2205419c0210ce021a2002410c6a41026a2209200241ad026a41026a2d00003a0000200220022f00ad023b010c200220073602b8022002200d3703b0022005200241106a419c0210ce021a200241df046a20092d00003a0000200220083a00dc04200220033602d804200220022f010c3b00dd040240200d2001280208290300520d002000200241b0026a41b00210ce021a200241e0046a24000f0b2000410b3602082001410c6a41013a0000200241b8026a102c200241e0046a24000f0b1018000b200b41011019000b8c0403027f017e017f23004180076b22032400200341e0046a41086a22044200370300200342003703e00420012002200341e0046a1002200341086a2004290300370300200320032903e0043703000240024002402003411041b8d6c200410041001004417f460d002003200336021020034110360214200342003703e0042003410020034110200341e0046a41084100100422012001417f461b2201410820014108491b360218200141074d0d0220032903e0042105200341e0046a200341106a10bb0120032802e004410b460d02200341c0026a200341e0046a41a00210ce021a200341003a0024200341186a22012001280200220120032802102003280214200341246a41012001100441016a220141014b6a36020020014102490d0120032d0024220241034f0d0120032802c0022101200341246a200341c0026a410472419c0210ce021a2003411c6a41066a2204200341c0026a41066a2d00003a00002003411c6a41046a2206200341c0026a41046a2f00003b0100200320032800c00236021c2001410b460d0220002001360208200020053703002000410c6a200341246a419c0210ce021a200041a8026a20023a00002000200328021c3600a902200041ad026a20062f01003b0000200041af026a20042d00003a000020034180076a24000f0b2000410b36020820034180076a24000f0b200341c0026a10bc010b41b2eac10041331040000bdda501040a7f017e417f037e23002203210420034180096b41607122032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240411010002205450d00200541063a00000240412010002206450d00200620032f00c0053b00012006412d3a000020064100360204200641063a0010200641036a200341c2056a2d00003a0000024020052d00004109470d00200528020841ffffffff0371450d00200528020410010b20051001200141086a2107200141106a280200412c6c2105200128020841586a210802400240024002400240024002400240024003402005450d01200541546a2105200841286a21092008412c6a220a210820092d00004107470d000b200320032f01a0033b01c005200a41086a22082802002205200a41046a280200470d03200541016a22092005490d1c2005410174220b20092009200b491b220cad420486220d422088a70d1c200da722094100480d1c2005450d01200a280200210e20091000220b450d05200b200e200920054104742205200520094b1b10ce021a200e10010c020b411010002208450d0620082006360200200842828080802037020420084180023b010c200820032f01a0033b010e0240200141106a28020022052001410c6a280200470d00200541016a22092005490d1c2005410174220a20092009200a491b2206ad422c7e220d422088a70d1c200da722094100480d1c024002402005450d002007280200210b20091000220a450d08200a200b20092005412c6c220c200c20094b1b10ce021a200b10010c010b20091000220a450d070b2001410c6a2006360200200141086a200a3602000b200141086a280200220c2005412c6c6a220541073a0000200520032f00b0043b0001200520083600042005428180808010370008200520032902c005370210200141106a2208200828020041016a220e360200200541036a200341b2046a2d00003a0000200541186a200341c0056a41086a290200370200200541206a200341c0056a41106a290200370200200541286a200341c0056a41186a2802003602004100210f0c030b20091000220b450d030b200a200b360200200a41046a200c360200200a41086a28020021050b200a28020020054104746a22052006360200200542828080802037020420054180023b010c200520032f01c0053b010e2008200828020041016a360200200341106a200a10462003280214417f6a210f200141086a280200210c200141106a280200210e0b200e412c6c2105200c41586a210802400340410021092005450d01200541546a2105200841286a210a2008412c6a22062108200a2d00004103470d000b200641086a2802002205450d00200541286c2108200628020041186a2105410021090340200920052d0000456a2109200541286a2105200841586a22080d000b0b200e412c6c2105200c41586a2108024003404100210a2005450d01200541546a2105200841286a21062008412c6a220b210820062d00004103470d000b200b41086a2802002205450d00200541286c2108200b28020041186a21054100210a0340200a20052d0000456a210a200541286a2105200841586a22080d000b0b200e412c6c2105200c41606a21080240024003402005450d01200541546a2105200841206a21062008412c6a220b210820062d00004104470d000b200b28020021050c010b410021050b2005200a6a2210ad220d421e88a70d16200d420286a72205417f4c0d16024002400240024002402005450d00200510002211450d0820114100200510d0021a20100d010c020b410421112010450d010b201120104102746a211241002113200141106a2114200141086a21152011211603400240201320094f0d00201341016a2113201641046a22162012470d010c020b20142802002217412c6c220c21052015280200221841586a220e2108024003404100210a2005450d01200541546a2105200841286a21062008412c6a220b210820062d00004103470d000b200b41086a2802002205450d00200541286c2108200b28020041186a21054100210a0340200a20052d0000456a210a200541286a2105200841586a22080d000b0b2013200a6b221920134b0d0f200c2105200e210803402005450d14200541546a2105200841286a210a2008412c6a22062108200a2d0000410b470d000b200641086a28020020194d0d0e2006280200201941186c221a6a280208211b200c2105200e210803402005450d13200541546a2105200841286a210a2008412c6a22062108200a2d00004104470d000b200c2105200e210803402005450d12200541546a2105200841286a210a2008412c6a220b2108200a2d0000410b470d000b0340200c450d11200c41546a210c200e41286a2105200e412c6a2208210e20052d00004102470d000b200341086a20061046200328020c20194d0d0d200328020820194102746a2205450d0d200841086a280200200528020022054d0d0c200b41086a28020020194d0d0b2008280200210a200b280200210b200341b0046a41086a221c420037030020034280808080c0003703b004200a20054104746a2d000d210a200341c0056a41026a220c200341a0036a41026a2d00003a0000200320032f00a0033b01c005411010002205450d0a201c4101360200200341b0046a410c6a22192802002106200320053602b404200520064104746a2205200a410447221d3602044100210620054100360208200541003a000c2005201d360200200520032f01c0053b000d2005410f6a200c2d00003a00002019201928020041016a3602000240200b201a6a2205280214220b450d002005410c6a211a200541146a211e410021064100210a0340024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020032802b004220520064d0d002019280200220c417f6a220e200c4b0d01200c200e4d0d0d2006200520032802b404200e4104746a2d000c1b21060b200a200b4f0d0d02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240201a280200220c200a4104746a2d0000220b41ab014b0d000240200b0eac011ea401151515a4011f20212a2b222324251c2627282906060606060606060606060606060a0a0a0a0a0a0a0a0a1d2c121212121800000000000000000000180000000000000000000000000000000000000000000004040401010101010101010101010101010104040401010101010101010101010101010104040404040404010101010101010404040404040401010101010101020202020202020202020202020202020202020202020202021e0b200341bc046a280200220b417f6a220c200b4d0d04200341c0056a41cd9ac1004116104720032902c405210d20032802c00522050d81010c9f010b2019280200220b417f6a220c200b4d0d01200341c0056a41cd9ac1004116104720032902c405210d20032802c00522050d80010c9a010b200341bc046a280200220b417f6a220c200b4d0d04200341c0056a41cd9ac1004116104720032902c405210d20032802c00522050d7f0c95010b200b200c4d0d5e200520032802b404200c4104746a220b280208470d04200b2d000c0d9901200341c0056a41cb9cc1004125104720032902c405210d20032802c0052205450d98010c7e0b200341bc046a280200220b417f6a220c200b4d0d04200341c0056a41cd9ac1004116104720032902c405210d20032802c00522050d7d0c8f010b200b200c4d0d5d200520032802b404200c4104746a220b280208470d05200b2d000c0d9b01200341c0056a41cb9cc1004125104720032902c405210d20032802c0052205450d9a010c7c0b200341bc046a280200220b417f6a220c200b4d0d05200341c0056a41cd9ac1004116104720032902c405210d20032802c00522050d7b0c89010b200b200c4d0d5c200520032802b404200c4104746a220b280208470d05200b2d000c0d9101200341c0056a41cb9cc1004125104720032902c405210d20032802c0052205450d90010c7a0b2005417e6a220b20054d0d05200341c0056a41f09cc100410f104720032902c405210d20032802c0052205450d93010c790b200b200c4d0d5b200520032802b404200c4104746a220b280208470d05200b2d000c0d8b01200341c0056a41cb9cc1004125104720032902c405210d20032802c0052205450d8a010c780b200341bc046a280200220b417f6a220c200b4d0d05200341c0056a41cd9ac1004116104720032802c0052205450d99010c9e010b2005417e6a220b20054d0d05200341c0056a41f09cc100410f104720032902c405210d20032802c0052205450d94010c760b200b200c4d0d59200520032802b404200c4104746a220b280208470d06200b2d000c0d8401200341c0056a41cb9cc1004125104720032902c405210d20032802c0052205450d83010c750b2005417f6a220b20054d0d06200341c0056a41f09cc100410f104720032902c405210d20032802c0052205450d8a010c740b2003200b3602b004200b220541016a220b2005490d8f010c90010b2005417f6a220b20054d0d06200341c0056a41f09cc100410f104720032902c405210d20032802c0052205450d84010c720b200b200c4d0d56200520032802b404200c4104746a220b280208470d06200b2d000c0d9301200341c0056a41cb9cc1004125104720032802c0052205450d93010c98010b2003200b3602b004200b220541016a220b2005490d90010c91010b200541016a220b20054f0d06200341c0056a41fa9ac100410e104720032802c0052205450d91010c96010b2005417f6a220b20054d0d06200341c0056a41f09cc100410f104720032902c405210d20032802c0052205450d7c0c6e0b2003200b3602b004200b220541016a220b2005490d85010c86010b200c200a4104746a2d0001211f200341c0056a41026a2220200341a0036a41026a2d00003a0000200320032f00a0033b01c005200341bc046a220e280200220c200341b8046a280200470d1a200c41016a2221200c490dac01200c4101742222202120212022491b2223ad420486220d422088a70dac01200da722214100480dac01200c450d1820032802b4042124202110002222450d57202220242021200c410474220c200c20214b1b10ce021a202410010c190b2003200b3602b004200b220541016a220b2005490d7f0c80010b2005417e6a220b20054d0d03200341c0056a41f09cc100410f104720032802c0052205450d8c010c91010b200341bc046a280200220b417f6a220c200b4d0d14200341c0056a41cd9ac1004116104720032902c405210d20032802c00522050d690c730b2003200b3602b004200a41016a220a201e280200220b490d8b010c8c010b2003200b3602b004200b220541016a220b2005490d770c780b2003200b3602b004200a41016a220a201e280200220b490d89010c8a010b200541016a220b20054f0d14200341c0056a41fa9ac100410e104720032802c0052205450d87010c8c010b200541016a220b20054f0d14200341c0056a41fa9ac100410e104720032802c0052205450d86010c8b010b200341bc046a2802002205450d1f20032802b40420054104746a417c6a41013a0000200a41016a220a201e280200220b490d86010c87010b0240200341bc046a2205280200220b450d002005200b417f6a220b360200200341c0056a41086a220c20032802b404200b4104746a220541086a280200360200200320052902003703c00520052d000c4102470d230b200341306a41e39ac100411710474101210c0c230b200341bc046a2802002205417f6a220b20054b0d36200b200c200a4104746a41046a2802006b220c200b4b0d3c2005200c4d0d47200341c0056a200341b0046a20032802b404200c4104746a280204104820032802c00522050d8801200341bc046a2802002205450d1f20032802b40420054104746a417c6a41013a0000200a41016a220a201e280200220b490d84010c85010b200341bc046a2802002205417f6a220b20054b0d36200b200c200a4104746a41046a2802006b220c200b4b0d3c2005200c4d0d47200341c0056a200341b0046a20032802b404200c4104746a280204220b104820032802c00522050d8701200341bc046a2802002205417f6a220c20054d0d1b200341c0056a41cd9ac1004116104720032902c405210d20032802c00522050d600c660b200341c0056a200c200a4104746a41046a2802002001104920032802c0054101460d38200341c0056a200341b0046a20032802c405220b280208104820032802c00522050d860120032802b0042205200b2d000d4104476a220b20054f0d18200341c0056a41fa9ac100410e104720032802c0052205450d81010c86010b200841086a280200200c200a4104746a41046a280200220b4d0d36200341c0056a200341b0046a2008280200220c200b4104746a280208104820032802c00522050d850120032802b0042205200c200b4104746a2d000d4104476a220b20054f0d18200341c0056a41fa9ac100410e104720032802c0052205450d80010c85010b200341bc046a280200220b417f6a220c200b4d0d0e200341c0056a41cd9ac1004116104720032802c0052205450d7f0c84010b200341bc046a280200220b417f6a220c200b4b220e450d0e200341c0056a41cd9ac1004116104720032902c405210d20032802c00522050d5c0c580b200341bc046a280200220b417f6a220c200b4d0d0e200341c0056a41cd9ac1004116104720032802c0052205450d7d0c82010b200341bc046a280200220b417f6a220c200b4d0d0e200341c0056a41cd9ac1004116104720032902c405210d20032802c00522050d5a0c520b200541016a220b20054f0d0e200341c0056a41fa9ac100410e104720032802c0052205450d7b0c80010b200341bc046a280200220b417f6a220c200b4d0d0e200341c0056a41cd9ac1004116104720032802c0052205450d7a0c7f0b200341b0046a410c6a280200221f417f6a220e201f4b0d2e200e200c200a4104746a410c6a2802006b220b200e4b0d34201f200b4d0d3f200c200a4104746a220c41086a280200410274210520032802b4042221200b4104746a2802042120200c41046a280200210b03402005450d17200e200b2802006b220c200e4b0d2b201f200c4d0d412005417c6a2105200b41046a210b2021200c4104746a2802042020460d000c2c0b0b200341c0056a200341b0046a201d104820032802c00522050d7d200341bc046a2802002205450d1320032802b40420054104746a417c6a41013a0000200a41016a220a201e280200220b490d790c7a0b200341bc046a280200220b417f6a220c200b4d0d0c200341c0056a41cd9ac1004116104720032902c405210d20032802c00522050d550c490b200b200c4d0d3e200520032802b404200c4104746a220b280208470d0c200b2d000c0d5f200341c0056a41cb9cc1004125104720032902c405210d20032802c0052205450d5e0c540b202110002222450d3e0b200341b8046a2023360200200320223602b404200341bc046a280200210c0b20032802b404200c4104746a220c200b410347201f410447220b71360204200c200b360200200c2005360208200c41003a000c200c20032f01c0053b000d200c410f6a20202d00003a0000200e200e28020041016a360200200a41016a220a201e280200220b490d740c750b2003200b3602b004200a41016a220a201e280200220b490d730c740b2003200b3602b004200a41016a220a201e280200220b490d720c730b200b200c4d0d3a200520032802b404200c4104746a220b280208470d10200b2d000c0d70200341c0056a41cb9cc1004125104720032802c0052205450d700c750b200b200c4d0d3a200520032802b404200c4104746a221f280208470d10201f2d000c0d4a200341c0056a41cb9cc1004125104720032902c405210d20032802c0052205450d490c4d0b200b200c4d0d3a200520032802b404200c4104746a220b280208470d10200b2d000c0d6e200341c0056a41cb9cc1004125104720032802c0052205450d6e0c730b200b200c4d0d3a200520032802b404200c4104746a220b280208470d10200b2d000c0d44200341c0056a41cb9cc1004125104720032902c405210d20032802c0052205450d430c4b0b2003200b3602b004200a41016a220a201e280200220b490d6d0c6e0b200b200c4d0d39200520032802b404200c4104746a220b280208470d0f200b2d000c0d6b200341c0056a41cb9cc1004125104720032802c0052205450d6b0c700b200b200c4d0d39200520032802b404200c4104746a220b280208470d0f200b2d000c0d3d200341c0056a41cb9cc1004125104720032902c405210d20032802c0052205450d3c0c480b2005417f6a220b20054d0d0f200341c0056a41f09cc100410f104720032902c405210d20032802c0052205450d510c470b2003200b3602b004200a41016a220a201e280200220b490d690c6a0b2003200b3602b004200a41016a220a201e280200220b490d680c690b2005200c4d0d3620032802b004220520032802b404200c4104746a220c280208470d0d200c2d000c0d4b200341c0056a41cb9cc1004125104720032902c405210d20032802c0052205450d4a0c440b200341c0056a41e39ac1004117104720032802c0052205450d650c6a0b200341c0056a41e39ac1004117104720032802c0052205450d640c690b200341c0056a41e39ac1004117104720032802c0052205450d630c680b200341c0056a200341b0046a2020104820032802c00522050d67200341bc046a2802002205450d1020032802b40420054104746a417c6a41013a0000200a41016a220a201e280200220b490d630c640b200341306a41086a200c280200360200200320032903c0053703304100210c0b200341386a280200210b20032802302105200c0d182003200b3602b0040240200b20056a2205200b4f0d00200341c0056a41fa9ac100410e104720032802c0052205450d610c660b200320053602b004200a41016a220a201e280200220b490d610c620b2005417f6a220b20054d0d07200341c0056a41f09cc100410f104720032802c0052205450d5f0c640b2005417e6a221f20054d0d07200341c0056a41f09cc100410f104720032902c405210d20032802c0052205450d380c3c0b2005417f6a220b20054d0d07200341c0056a41f09cc100410f104720032802c0052205450d5d0c620b2005417f6a220b20054d0d07200341c0056a41f09cc100410f104720032902c405210d20032802c0052205450d320c3a0b2005417f6a220b20054d0d07200341c0056a41f09cc100410f104720032802c0052205450d5b0c600b2005417f6a220b20054d0d07200341c0056a41f09cc100410f104720032902c405210d20032802c0052205450d2c0c380b2003200b3602b004200b220541016a220b2005490d430c440b2005417f6a220c20054d0d07200341c0056a41f09cc100410f104720032902c405210d20032802c0052205450d3c0c360b2003200b3602b004200a41016a220a201e280200220b490d580c590b2003201f3602b004200e4101710d320c330b2003200b3602b004200a41016a220a201e280200220b490d560c570b2003200b3602b004200b220541016a220b2005490d2c0c2d0b2003200b3602b004200a41016a220a201e280200220b490d540c550b2003200b3602b004200b220541016a220b2005490d260c270b200341c0056a41e39ac1004117104720032802c0052205450d510c560b2003200c3602b004200c2205200b6a220b2005490d360c370b200341c0056a41cd9ac100411610470c200b200341c0056a41889bc100411b10470c1f0b200341c0056a41a39bc100412710470c1e0b200341c0056a41cd9ac100411610470c1d0b200341c0056a41cd9ac100411610470c1c0b200341c0056a41cd9ac100411610470c1b0b200341c0056a41ca9bc100410e10470c1a0b200341c8056a290300210d20032802c4052105200341b8046a2802000d4e0c600b200bad422086200335023484210d200341b8046a2802000d4d0c5f0b200341c0056a41889bc100411b10470c170b200341c0056a41889bc100411b10470c160b200341c0056a41889bc100411b10470c150b41f081c000200e200c104a000b418082c000200a200b104a000b41f081c000200c200b104a000b41f081c000200c200b104a000b41f081c000200c200b104a000b41f081c000200c200b104a000b41f081c000200c200b104a000b41f081c000200c200b104a000b41f081c000200c2005104a000b41f081c000200c2005104a000b41f081c000200b201f104a000b41f081c000200c201f104a000b41f081c000200c200b104a000b202141041019000b41f081c000200c200b104a000b41f081c000200c200b104a000b41f081c000200c200b104a000b41f081c000200c200b104a000b41f081c000200c200b104a000b41f081c000200c200b104a000b41f081c000200c2005104a000b20032902c405210d20032802c00521050c0c0b20032802b00421050b200541016a220b20054f0d010b200341c0056a41fa9ac100410e104720032802c0052205450d2b0c300b2003200b3602b004200a41016a220a201e280200220b490d2b0c2c0b20032802b00421050b200541016a220b20054f0d010b200341c0056a41fa9ac100410e104720032802c0052205450d270c2c0b2003200b3602b004200a41016a220a201e280200220b490d270c280b200341bc046a280200220b417f6a220c200b4b210e0b200e410171450d010b200341c0056a41cd9ac1004116104720032902c405210d20032802c00522050d010c030b200b200c4d0d01024020032802b004220520032802b404200c4104746a220b280208470d00200b2d000c0d04200341c0056a41cb9cc1004125104720032902c405210d20032802c0052205450d030c010b02402005417f6a220b20054d0d00200341c0056a41f09cc100410f104720032902c405210d20032802c0052205450d030c010b2003200b3602b004200b220541016a220b2005490d040c050b200341b8046a280200450d390c270b41f081c000200c200b104a000b20032802b00421050b200541016a220b20054f0d010b200341c0056a41fa9ac100410e104720032802c0052205450d1d0c220b2003200b3602b004200a41016a220a201e280200220b490d1d0c1e0b20032802b00421050b2005200b6a220b20054f0d010b200341c0056a41fa9ac100410e104720032802c0052205450d190c1e0b2003200b3602b0040c180b20032802b00421050b200541016a220b20054f0d010b200341c0056a41fa9ac100410e104720032802c0052205450d150c1a0b2003200b3602b004200a41016a220a201e280200220b490d150c160b20032802b00421050b200541016a220b20054f0d010b200341c0056a41fa9ac100410e104720032802c0052205450d110c160b2003200b3602b004200a41016a220a201e280200220b490d110c120b20032802b00421050b200541016a220b20054f0d010b200341c0056a41fa9ac100410e104720032802c0052205450d0d0c120b2003200b3602b004200a41016a220a201e280200220b490d0d0c0e0b20032802b00421050b200541016a220b20054f0d010b200341c0056a41fa9ac100410e104720032802c0052205450d090c0e0b2003200b3602b004200a41016a220a201e280200220b490d090c0a0b20032802b00421050b200541016a220b20054f0d010b200341c0056a41fa9ac100410e104720032802c0052205450d050c0a0b2003200b3602b004200a41016a220a201e280200220b490d050c060b20032802b00421050b200541016a220b20054f0d010b200341c0056a41fa9ac100410e104720032802c0052205450d010c060b2003200b3602b004200a41016a220a201e280200220b490d010c020b200a41016a220a201e280200220b490d000b0b0240201c280200450d0020032802b40410010b20162006201b6a360200201341016a2113201641046a22162012470d000b0b200141086a2802002118412c2125200141106a28020022170d160c170b20032902c405210d200341b8046a280200450d120b20032802b40410012011100120050d120c130b200941041019000b200941041019000b411041041019000b200541041019000b412041081019000b411041081019000b411041041019000b200341c0056a41a69ac100412710470c080b200341c0056a41819ac100412510470c070b200341c0056a41819ac100412510470c060b200341c0056a418495c100411e10470c050b200341c0056a41ac94c100412c10470c040b200341c0056a41f299c100410f10470c030b200341c0056a41e399c100410f10470c020b200341c0056a41d099c100411310470c010b200341c0056a41d894c100412c10470b20032902c405210d20032802c00521050b201110012005450d010b2000200536020420004101360200200041086a200d3702000c050b41002111412c21252017450d010b2018201720256c6a2126200341b0046a41146a2113200341b0076a2127200341c0056a410172211a200341c0056a41106a2115200341c0056a41206a211b200341f0056a211e200341f4056a212820034180066a211c20034184066a212920034190066a211d20034194066a212a200341a0066a211f200341b0066a2120200341c0066a2121200341e0066a2122200341d0066a2123200341e4066a212b200341f0066a2124200341f4066a212c20034180076a212d20034184076a212e20034190076a212f200341a0076a2130200341a4076a2131200341b0046a41086a210c200341e8056a2132200341e4056a2133200341f8056a213420034188066a213520034198066a2136200341a8066a2137200341a4066a2138200341b8066a2139200341b4066a213a200341c8066a213b200341c4066a213c200341d8066a213d200341d4066a213e200341e8066a213f200341f8066a214020034188076a214120034198076a214220034194076a2143200341a8076a21440340024020182d0000410b470d00201828020c2205450d0020182802042245200541186c6a214603400240204541146a220a2802002205450d002045410c6a211641002106034002400240024002400240024002400240024002400240024002400240200620054f0d0002400240024002402016280200200641047422196a22052d0000410b470d002003200541046a2205360290022011450d052010200528020022054d0d03201120054102746a2802002208450d002015412d3a0000200341c0056a41146a22472008360200201b41d6003a0000201e41133a00002028200f360200201c41123a00002029200f360200201d412d3a0000202a2002360200201f41373a000020204184083b0100202141003a0000201a20032f00b0043b0000201a41026a200341b0046a41026a2d00003a0000200341123a00c0052003200f3602c4052022410b3a0000202341063a0000202b2005360200202441123a0000202c200f360200202d412d3a0000202e2008360200202f41d7003a0000203041133a00002031200f360200200a2802002208200641016a2217490d06200a200636020020162802002105200341b0046a41106a22142016360200200341b0046a41186a22482027360200200320173602b004200341b0046a410c6a2249200520174104746a220b360200200c200520196a220e41106a22053602002013200341c0056a3602002003200820176b22123602b4040240200e2d0000220941ac01460d00410021050340200e20056a21080240200941ff01714109470d00200841086a28020041ffffffff0371450d00200841046a28020010010b2005450d03200c200841206a360200200541106a2105200841106a2d0000220941ac01470d000b200e20056a41106a21050b2005200b460d020c070b410121050c100b200841106a2205200b470d050b20120d050c060b200341c0056a41086a41c0c5c200360200200341c0056a410c6a4101360200200341c0056a41146a4101360200200341023602a4032003418081c0003602c005200341013602c4052015200341a0036a360200200320034190026a3602a003200341b0046a200341c0056a104c20032802b0042205450d0f20032902b404210d2000200536020420004101360200200041086a200d3702002011450d162010450d16201110010c160b41f080c00020062005104a000b41e093c10041cc001040000b41c081c000104d000b024003400240024020052d000022084109460d00200841ac01470d010c030b200541086a28020041ffffffff0371450d00200541046a28020010010b200541106a2205200b470d000b200c200b36020020120d010c020b200c200541106a3602002012450d010b02400240024002400240201720452802142205470d002027200341c0056a6b41047622050d010c020b201941106a200541047422056b2108201628020020056a21050340200341a0036a2013104e20032d00a00341ac01460d0a200520032903a003370300200541086a200341a0036a41086a290300370300200a200a28020041016a360200200541106a2105200841706a22080d000b204828020020132802006b4104762205450d010b02400240024002402014280200220b41046a2212280200220e20032802b404221720032802b00422096a22086b20054f0d00200820056a22192008490d17200e4101742208201920192008491b2248ad420486220d422088a70d17200da722194100480d17200e450d01200b280200214a201910002208450d052008204a2019200e410474220e200e20194b1b10ce021a204a10010c020b200b28020021080c020b201910002208450d030b200b2008360200201220483602000b2008200920056a2205410474220e6a200820094104746a201741047410cf021a200320053602b0042005200b2802082208460d00200e200841047422056b2108200b28020020056a21050340200341a0036a2013104e20032d00a00341ac01460d09200520032903a003370300200541086a200341a0036a41086a290300370300200b41086a2209200928020041016a360200200541106a2105200841706a22080d000b0b200341a0036a41086a22054100360200200342083703a003200341a0036a2013104f20032802a003224820052802002208410474220e6a210b20032802a403214b2048210502402008450d0002400240024002402014280200221241046a224c280200221720032802b404221920032802b00422086a22056b200e41047522094f0d00200520096a224a2005490d1720174101742205204a204a2005491b224dad420486220d422088a70d17200da7224a4100480d172017450d012012280200214e204a10002205450d062005204e204a201741047422172017204a4b1b10ce021a204e10010c020b201228020021050c020b204a10002205450d040b20122005360200204c204d3602000b2005200820096a220941047422176a200520084104746a201941047410cf021a200320093602b00420482105200920122802082208460d002012280200220520176a214a200520084104746a2109204821080340200e450d06200341a0036a41026a2205200841036a2d00003a0000200320082f00013b01a00320082d0000221741ac01460d052008410c6a2802002119200841046a290200210d200920173a0000200941046a200d3702002009410c6a201936020020032f01a0032117200941036a20052d00003a0000200941016a20173b0000201241086a2205200528020041016a360200200e41706a210e200841106a22052108200941106a2209204a470d000b0b2005200b460d060c050b201941081019000b204a41081019000b20162013104f200c280200220520492802002209470d050c060b200841106a2205200b470d010c020b200b2205200b460d010b03400240024020052d000022084109460d00200841ac01470d010c030b200541086a28020041ffffffff0371450d00200541046a28020010010b200541106a2205200b470d000b0b204b450d00204810010b200c280200220520492802002209460d010b0240024003400240024020052d000022084109460d00200841ac01470d010c030b200541086a28020041ffffffff0371450d00200541046a28020010010b200541106a22052009470d000c020b0b200541106a21090b200c20093602000b024020032802b4042205450d00024020032802b004220b2014280200220e41086a22092802002208460d00200e280200220e20084104746a200e200b4104746a200541047410cf021a0b2009200820056a3602000b024020032d00c0054109470d00200341c0056a41086a28020041ffffffff0371450d0020032802c40510010b024020152d00004109470d00200341c0056a41186a28020041ffffffff0371450d00204728020010010b0240201b2d00004109470d00203228020041ffffffff0371450d00203328020010010b0240201e2d00004109470d00203428020041ffffffff0371450d00202828020010010b0240201c2d00004109470d00203528020041ffffffff0371450d00202928020010010b0240201d2d00004109470d00203628020041ffffffff0371450d00202a28020010010b0240201f2d00004109470d00203728020041ffffffff0371450d00203828020010010b024020202d00004109470d00203928020041ffffffff0371450d00203a28020010010b024020212d00004109470d00203b28020041ffffffff0371450d00203c28020010010b024020232d00004109470d00203d28020041ffffffff0371450d00203e28020010010b024020222d00004109470d00203f28020041ffffffff0371450d00202b28020010010b024020242d00004109470d00204028020041ffffffff0371450d00202c28020010010b0240202d2d00004109470d00204128020041ffffffff0371450d00202e28020010010b0240202f2d00004109470d00204228020041ffffffff0371450d00204328020010010b024020302d00004109470d00204428020041ffffffff0371450d00203128020010010b410f21050b200520066a2206200a2802002205490d000b0b204541186a22452046470d000b0b201820256a22182026470d000b0b200341186a41106a2205200141106a280200360200200341186a41086a2248200141086a290200370300200320012902003703182005280200222420256c21052048280200222341586a21080240024003402005450d01200541546a2105200841286a2109200820256a220a210820092d00004108470d000b2003200a104620032802002105200328020421080c010b410021050b2008410020051b210b2024412c6c2108202341586a2109200541b8d6c20020051b21050240024003402008450d01200841546a2108200941286a210a2009412c6a22062109200a2d0000410a470d000b200641086a2802002109200628020021080c010b410021080b200341a0a1c10036025020034200370254200841b8d6c20020081b220e2009410020081b411c6c6a212f2005200b41146c6a2109200341c0056a410472211e200341d0006a41086a214541042115410421494104213e410421164100214b410021144100211a4100211c410021120340024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240201241037122084101460d0020084102470d01201b2108201a4101470d022008201c460d020c040b034020092005460d062005410c6a2108200541146a220a210520082802000d000b41012112200a21052003200a417c6a280200220836025c20110d040c0c0b02400240024020052009460d0003402005410c6a280200450d022009200541146a2205470d000b0b201a4101470d01201b2208201c460d010c030b200541106a2108200541146a21054100211220032008280200220836025c20110d040c0c0b0340200e202f460d05200e41186a210a200e2802102105200e411c6a210e200522082005200a2802004102746a221c470d020c000b0b0340200e202f460d04200e41186a210a200e2802102108200e411c6a210e20082008200a2802004102746a221c470d020c000b0b2008450d02200841046a211b410221124101211a2009210520032008280200220836025c20110d010c090b2008450d01200841046a211b410221124101211a20032008280200220836025c2011450d080b201020084d0d10201120084102746a280200220a450d1502400240024002402014204b470d00204b41016a2206204b490d1b204b410174220b20062006200b491b2220ad420286220d422088a70d1b200da722064100480d1b204b450d01200610002215450d05201520492006204b410274220b200b20064b1b10ce021a204910010c020b204b21202014214b0c020b200610002215450d030b201521492015213e201521160b2016204b4102746a2008360200200341c0056a200328025c220c200341186a1049200341c0056a410c6a2122200341c0056a41086a2230280200212d20032802c405211720032802c00522214101460d0f20172802082208417f4c0d162017280200210620172d000c210b024002402008450d002008100022130d010c080b410121130b20132006200810ce0221062003200836028401200320063602800120032008360288012017410d6a2d000021082003200b3a008c01200320083a008d0120034100360290012003200328025c360298012003200a36029c01024002402003280250220841a0a1c100460d00200328025421190c010b41940310002208450d0641002119200841003b010620084100360200200841086a200341c0056a418c0310ce021a20034100360254200320083602500b201441016a2114024002400340200841086a210b200841066a211f20082f0106221d4102742106417f210a02400240024003402006450d01200a41016a210a4100417f4101200b2802002213200c4b1b2013200c461b2213450d052006417c6a2106200b41046a210b20134101460d000b20190d010c020b201d210a2019450d010b2019417f6a21192008200a4102746a4194036a28020021080c010b0b2045204528020041016a36020020034100360230200341306a41086a200341d0006a36020020032008360234200329039801210d200329039001214f20032903880121502003290380012151200841066a22062f0100220b410b4f0d01200841086a2213200a41016a22194102746a2013200a4102746a2213200b200a6b41027410cf021a2013200c360200200841346a220820194105746a2008200a4105746a220820062f0100200a6b41057410cf021a200841186a200d3702002008204f3702102008205037020820082051370200200620062f010041016a3b01002003410236027041024102470d150c160b200341306a41086a2206200a360200200320083602302003200341d0006a360234201e41086a2006280200360200201e2003290330370200200341c0056a41106a204536020020032802c40520222802004105746a220841cc006a220a290000214f200a200329039801370000200841c4006a220a290000210d200a2003290390013700002008413c6a220a2900002150200a200329038801370000200841346a220829000021512008200329038001370000200320193602c0052003204f3703782003200d3703702003205037036820032051370360200da74102460d150c140b41940310002227450d04202741003b010620274100360200202741086a200341c0056a418c0310ce022113200341c0056a41186a221d2008418c026a290200370300200341c0056a41106a222220084184026a2902003703002030200841fc016a2902003703002003200841f4016a2902003703c005200841206a280200212c2013200841246a20062f010041796a220b41027410ce022113202741346a20084194026a200b41057410ce022119200641063b01002027200b3b0106200341b0046a41186a222e201d290300370300200341b0046a41106a22312022290300370300200341b0046a41086a22472030290300370300200320032903c0053703b00402400240200a41064b0d00200841086a220b200a41016a22134102746a200b200a4102746a220b20062f0100200a6b41027410cf021a200b200c360200200841346a220b20134105746a200b200a4105746a220b20062f0100200a6b41057410cf021a200b41186a200d370200200b204f370210200b2050370208200b20513702000c010b2013200a417a6a221f4102746a2013200a41796a22064102746a220a200b41ffff037120066b41027410cf021a200a200c3602002019201f4105746a201920064105746a220a202741066a221f2f010020066b41057410cf021a200a41186a200d370200200a204f370210200a2050370208200a20513702000b201f201f2f010041016a3b0100200341a0036a41186a2229202e290300370300200341a0036a41106a222a2031290300370300200341a0036a41086a222b2047290300370300200320032903b0043703a00320034190026a41186a224b202929030037030020034190026a41106a2232202a29030037030020034190026a41086a2234202b290300370300200320032903a003370390020240024020082802002213450d0020082f0104211f03402029204b290300370300202a2032290300370300202b203429030037030020032003290390023703a003201f41ffff0371210c20132f01062208410a4d0d0241c4031000220b450d06200b41003b0106200b4100360200200b41086a200341c0056a41bc0310ce02210a201341206a2802002135201d2013418c026a290200370300202220134184026a2902003703002030201341fc016a2902003703002003201341f4016a2902003703c005200a201341246a201341066a224a2f0100220641796a220841027410ce022136200b41346a20134194026a200841057410ce022137200b4194036a201341b0036a2006417a6a221941027410ce022128204a41063b0100200b20083b010602402019450d00410021082028210a0340200a280200220620083b01042006200b360200200a41046a210a2019200841016a2208470d000b0b202e201d2903003703002031202229030037030020472030290300370300200320032903c0053703b004201d202e2903003703002022203129030037030020302047290300370300200320032903b0043703c00502400240201f41ffff0371220a41064b0d00201341086a2208200c41016a221941027422066a2008200c410274221f6a2208204a2f01002228200c6b223641027410cf021a2008202c360200201341346a220820194105746a2008200c4105746a2208203641057410cf021a200841186a2029290300370200200841106a202a290300370200200841086a202b290300370200200820032903a003370200204a202841016a22083b010020134194036a224a201f6a41086a204a20066a224a200841ffff0371220620196b41027410cf021a204a2027360200200a20064f0d012013201f6a4198036a210803402008280200220a200c41016a220c3b0104200a2013360200200841046a21082006200c470d000c020b0b2036200c417a6a2206410274221f6a2036200c41796a22084102746a220a200b41066a22192f010020086b41027410cf021a200a202c360200203720064105746a203720084105746a220a20192f010020086b41057410cf021a200a41186a2029290300370200200a41106a202a290300370200200a41086a202b290300370200200a20032903a003370200201920192f010041016a220a3b01002028200c410274224a6a416c6a2028201f6a2219200a41ffff0371220c20066b41027410cf021a201920273602002006200c4b0d00200b204a6a41fc026a210a0340200a2802002206200841016a22083b01042006200b360200200a41046a210a200c2008470d000b0b0240204b201d2903003703002032202229030037030020342030290300370300200320032903c0053703900220132802002208450d0020132f0104211f200821132035212c200b21270c010b0b200b21272035212c0b41c40310002208450d03200841003b010620084100360200200841086a200341c0056a41bc0310ce02210b20082003280250220a360294032003200328025441016a360254200a41003b010420032008360250200a2008360200200820082f010622064105746a220a413c6a2034290300370200200a41346a200329039002370200200a41cc006a204b290300370200200a41c4006a2032290300370200200b20064102746a202c36020020084194036a200641016a220a4102746a20273602002008200a3b01062027200a3b0104202720083602000c130b201341086a220a200c41016a2206410274220b6a200a200c41027422196a220a2008200c6b221d41027410cf021a200a202c360200201341346a220a20064105746a200a200c4105746a220a201d41057410cf021a200a41186a2029290300370200200a41106a202a290300370200200a41086a202b290300370200200a20032903a003370200201341066a200841016a22083b010020134194036a220a20196a41086a200a200b6a220a200841ffff0371220b20066b41027410cf021a200a2027360200200c200b4f0d1220132006417f6a22084102746a4198036a210a0340200a2802002206200841016a22083b010420062013360200200a41046a210a200b2008470d000c130b0b200341c0006a41086a200341d0006a41086a280200360200200320032903503703402024412c6c2105202341586a210802400340410021092005450d01200541546a2105200841286a210a2008412c6a22062108200a2d00004103470d000b200641086a2802002205450d00200541286c2108200628020041186a2105410021090340200920052d0000456a2109200541286a2105200841586a22080d000b0b2024412c6c2105202341606a21080240024003402005450d01200541546a2105200841206a210a2008412c6a22062108200a2d00004104470d000b200628020021050c010b410021050b200341c0056a41106a2212200341186a41106a280200360200200341c0056a41086a2232200341186a41086a290300370300200320032903183703c00520034180016a200341c0056a105002402014450d00201620144102746a2128200520096a2117200341b0076a2129200341c0056a41146a212d200341c0056a41206a2114200341f0056a211520034180066a211a200341c0056a41c4006a212f20034194066a2130200341a0066a211b200341b0066a211e200341c0066a211c200341d0066a211d200341e0066a211f200341e4066a2149200341f4066a2145200341f0066a212020034180076a212120034184076a214820034190076a2122200341a0076a2123200341a4076a214a200341b7046a212a200341ac036a212b200341bc036a212c200341a0036a41246a212e200341a0036a41286a2131200341cc036a2147200341d8056a2134200341f8056a213520034198066a2136200341a8066a2137200341a4066a214c200341b8066a2139200341b4066a2133200341c8066a213b200341c4066a2138200341d8066a213d200341d4066a213a200341e8066a213f200341f8066a214020034188076a214120034198076a214220034194076a213c200341a8076a214403402016220541046a21162005280200210a200341c0006a21052003280244210c024002400240024002400240024003402005280200220641086a210920062f0106220e4102742108417f210502400240024003402008450d01200541016a21054100417f41012009280200220b200a4b1b200b200a461b220b450d032008417c6a2108200941046a2109200b4101460d000b200c0d010c040b200e2105200c450d030b200c417f6a210c200620054102746a4194036a21050c010b0b200620054105746a221341cc006a2802002108201341d0006a28020021052012412d3a0000202d2005360200201441d6003a0000201541133a0000200341c0056a41346a2227200f360200201a41123a0000202f200f360200200341c0056a41d0006a2224412d3a000020302002360200201b41373a0000201e4184083b0100201c41003a0000201d41063a0000201f410b3a0000204920083602002003200f3602c405200341123a00c0052045200f360200202041123a00002021412d3a000020482005360200202241d7003a0000202341133a0000204a200f3602002013413c6a2219280200220b41106a2208ad220d421c88a70d1e200d420486a72205417f4c0d1e024002402005450d00200510002206450d032019280200220b450d010c040b41082106200b0d030b41002109200841006b410f490d030c040b41a29dc1004180011040000b200541081019000b4100210a410021050340024020052008470d00200841016a22092008490d1e2008410174220c20092009200c491b220cad420486220d422088a70d1e200da722094100480d1e024002402008450d0020091000220e450d17200e2006200920084104742208200820094b1b10ce02210820061001200821060c010b200910002206450d160b200c21080b2006200a6a2209410f3a0000200941046a2005360200200941036a200341a0036a41026a2d00003a0000200941016a20032f01a0033b0000200a41106a210a200541016a22092105200b2009470d000b200820096b410f4f0d010b2009410f6a22052009490d1b2008410174220a20052005200a491b220aad420486220d422088a70d1b200da722054100480d1b2008450d0120051000220b450d0d200b2006200520084104742208200820054b1b10ce02210520061001200521060c020b2008210a0c010b200510002206450d0b0b20032029360294022003200341c0056a36029002200341b0046a20034190026a104e024020032d00b00441ac01460d00200620094104746a21050340200341a0036a41086a2208200341b0046a41086a290300370300200320032903b0043703a003200541086a2008290300370300200520032903a003370300200941016a2109200541106a2105200341b0046a20034190026a104e20032d00b00441ac01470d000b0b0240024002402009200a470d00200a41016a2205200a490d1b200a4101742208200520052008491b220ead420486220d422088a70d1b200da722054100480d1b200a450d0120051000220b450d0c200b20062005200a4104742208200820054b1b10ce021a200610010c020b2006210b200a210e2009210a0c010b20051000220b450d0a0b200b200a4104746a220541063a0000200541086a202a290000370000200520032900b004370001200341b0046a20034180016a418c0110ce021a411010002208450d0e200841063a0000200341a0036a200341b0046a418c0110ce021a20192802002205417f4c0d17201341346a220c28020021194101210a4101210602402005450d00200510002206450d0d0b20062019200510ce02210602400240024020050d004100211941012006200510ce021a20050d010c020b20051000220a450d0d20052119200a2006200510ce021a2005450d010b200610010b200341b0046a200341a0036a418c0110ce021a200c31000d210d200341a0036a200341b0046a418c0110ce021a200341b0046a200341a0036a418c0110ce021a20034190026a200341b0046a418c0110ce021a411010002206450d0d200941016a2109204f428080808080804083224f2005ad84200d422886844280808080800c84210d200641063a000020061001200341a0036a20034190026a418c0110ce021a200341b0046a200341a0036a418c0110ce021a024020082d00004109470d00200828020841ffffffff0371450d00200828020410010b2008100120034190026a200341b0046a418c0110ce021a200341b0046a20034190026a418c0110ce021a200341a0036a41086a2019360200202b200d370200200341a0036a41146a4204370200202c4100360200200341a0036a41206a200b360200202e200e36020020312009360200204741003602002003200a3602a403200341013602a003200341b0046a200341a0036a105120034180016a200341b0046a418c0110ce021a201341c4006a4101360200201341c8006a2017360200024020032d00c0054109470d00203228020041ffffffff0371450d0020032802c40510010b024020122d00004109470d00203428020041ffffffff0371450d00202d28020010010b024020142d00004109470d00200341c0056a41286a28020041ffffffff0371450d00200341c0056a41246a28020010010b024020152d00004109470d00203528020041ffffffff0371450d00202728020010010b0240201a2d00004109470d00200341c0056a41c8006a28020041ffffffff0371450d00202f28020010010b024020242d00004109470d00203628020041ffffffff0371450d00203028020010010b0240201b2d00004109470d00203728020041ffffffff0371450d00204c28020010010b0240201e2d00004109470d00203928020041ffffffff0371450d00203328020010010b0240201c2d00004109470d00203b28020041ffffffff0371450d00203828020010010b0240201d2d00004109470d00203d28020041ffffffff0371450d00203a28020010010b0240201f2d00004109470d00203f28020041ffffffff0371450d00204928020010010b024020202d00004109470d00204028020041ffffffff0371450d00204528020010010b024020212d00004109470d00204128020041ffffffff0371450d00204828020010010b024020222d00004109470d00204228020041ffffffff0371450d00203c28020010010b024020232d00004109470d00204428020041ffffffff0371450d00204a28020010010b204f4280808080808c0184214f201741016a211720162028470d000b0b0240204b450d00203e10010b200341c0056a20034180016a418c0110ce021a200341b0046a200341c0056a105202400240200341b0046a41106a2802002205450d0020032802b80422122005412c6c6a211403400240024020122d00002205410f71410a460d0020054108470d01201228020c2208450d0120122802042205200841146c6a211303400240200528020c0d0020052802102106200341c0006a21082003280244210e03402008280200220b41086a210a200b2f010622164102742109417f210802400240024003402009450d01200841016a21084100417f4101200a280200220c20064b1b200c2006461b220c450d032009417c6a2109200a41046a210a200c4101460d000b200e0d010c040b20162108200e450d030b200e417f6a210e200b20084102746a4194036a21080c010b0b0240200b20084105746a220841c4006a280200450d00200541106a200841c8006a280200360200200541146a22052013470d020c040b41a29ec10041351040000b200541146a22052013470d000c020b0b201228020c2205450d00201228020422172005411c6c6a21190340024020172802182205450d002017280210220e20054102746a210f0340200e221341046a210e2013280200210a200341c0006a21052003280244210c024003402005280200220641086a210920062f010622164102742108417f210502400240024003402008450d01200541016a21054100417f41012009280200220b200a4b1b200b200a461b220b450d052008417c6a2108200941046a2109200b4101460d000b200c0d010c020b20162105200c450d010b200c417f6a210c200620054102746a4194036a21050c010b0b200e200f470d010c020b200620054105746a220541c4006a280200450d062013200541c8006a280200360200200e200f470d000b0b2017411c6a22172019470d000b0b2012412c6a22122014470d000b0b200341bc046a290200210d20032802b004210520032902b404214f2003280240200328024420032802481053200041086a204f37020020002005360204200041106a200d370200200041003602002011450d192010450d1920111001200424000f0b41a29ec10041351040000b200641041019000b41c40341041019000b41c40341041019000b41940341041019000b41940341041019000b200841011019000b41e093c10041cc001040000b200541081019000b200541081019000b200541011019000b200541011019000b411041081019000b411041081019000b200941081019000b202228020021052020214b0c010b200341c8056a41c0c5c200360200200341cc056a4101360200200341d4056a4101360200200341033602a4032003419082c0003602c005200341023602c405200341d0056a200341a0036a3602002003200341dc006a3602a003200341b0046a200341c0056a104c20032902b404220d422088a7210520032802b0042117200da7212d0b20032802502003280254200341d8006a28020010530240204b450d00201510010b204810550240200341246a280200450d00202310010b2000201736020420004101360200200041086a2005ad422086202dad843702002011450d072010450d0720111001200424000f0b2003410236027041024102460d010b2003280264450d00200328026010010b02402021450d00202d450d00201710010b2020214b0c000b0b102e000b1018000b200710552001410c6a280200450d00200728020010010b200424000b160020002001280208360204200020012802003602000b5001017f02402002417f4c0d00024002402002450d002002100022030d01200241011019000b410121030b20032001200210ce0221012000200236020420002001360200200020023602080f0b102e000bb30201037f230041106b22032400024002402002450d002001410c6a2802002204417f6a220520044d0d01200341cd9ac10041161047200328020021012000200329020437020420002001360200200341106a24000f0b20004100360200200341106a24000f0b0240200420054d0d000240024020012802002204200141046a28020020054104746a2205280208470d0020052d000c450d0120004100360200200341106a24000f0b0240200420026b220220044d0d00200341f09cc100410f1047200328020021012000200329020437020420002001360200200341106a24000f0b2000410036020020012002360200200341106a24000f0b200341cb9cc10041251047200041086a200341086a28020036020020002003290300370200200341106a24000f0b41f081c00020052004104a000be907020b7f017e230041d0006b22032400200320013602102002280208220441586a2105200241106a2802002206412c6c21020240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004102470d000b200841086a2802002102200828020021070c010b410021070b2002410020071b21092006412c6c2102200441586a2105200741b8d6c20020071b210a0240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004104470d000b200341086a200810462003280208210b200328020c210c0c010b4100210b0b2006412c6c2102200441586a2105200b41b8d6c200200b1b210d02400240024002400240024002400240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b200841086a2802002202450d00200241286c2107200828020041186a2102410021050340200520022d0000456a2105200241286a2102200741586a22070d000b200520014d0d012006412c6c2102200441586a210503402002450d06200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b2003200810462003280204220b41286c210520032802002204210703402005450d05200541586a2105200741186a2108200741286a2202210720082d00000d000b2001450d022004200b41286c6a210803402001417f6a2101034020082002460d06200241186a2105200241286a2207210220052d00000d000b2007210220010d000b200741586a21020c030b410021050b0240200c4100200b1b200120056b22024d0d00200d20024102746a2202450d00200320022802002202360214200920024d0d060c050b200341346a41013602002003413c6a41013602002003410336021c2003418881c0003602282003410236022c200341c0c5c2003602302003200341106a3602182003200341186a360238200341c0006a200341286a104c2003290244210e200328024021020c060b200241586a21020b20032002411c6a2802002202360214200920024b0d020c030b41f696c10041dd001040000b41b496c10041c2001040000b200a20024104746a2202450d002000410036020020002002360204200341d0006a24000f0b200341c0006a410c6a4103360200200341286a410c6a41023602002003413c6a4102360200200341033602442003419881c0003602282003410336022c200341a0d2c2003602302003200341146a3602402003200341106a3602482003200341c0006a360238200341186a200341286a104c200329021c210e200328021821020b2000200236020420004101360200200041086a200e370200200341d0006a24000b860101017f230041306b220324002003200236020420032001360200200341206a410c6a4104360200200341086a410c6a41023602002003411c6a410236020020034104360224200341c892c0003602082003410236020c200341a0d2c2003602102003200341046a360220200320033602282003200341206a360218200341086a20001065000bd80201067f230041306b2202240041272103024002400240024002400240200028020028020022004190ce00490d00412721030340200241096a20036a2204417c6a200020004190ce006e220541f0b17f6c6a220641e4006e22074101744182a2c1006a2f00003b00002004417e6a20062007419c7f6c6a4101744182a2c1006a2f00003b00002003417c6a2103200041ffc1d72f4b21042005210020040d000b41e4002104200541e400480d010c020b41e40021042000220541e4004e0d010b2005220041094a0d010c020b200241096a2003417e6a22036a2005200520046e2200419c7f6c6a4101744182a2c1006a2f00003b0000200041094c0d010b200241096a2003417e6a22036a220520004101744182a2c1006a2f00003b00000c010b200241096a2003417f6a22036a2205200041306a3a00000b2001410141b8d6c20041002005412720036b105b2100200241306a240020000bfd0201067f230041306b22022400200128020021030240024002400240024002400240200128020422044103742205450d00200341046a2106410021070340200628020020076a2107200641086a2106200541786a22050d000b200141146a280200450d010c020b41002107200141146a2802000d010b200721060c010b2004450d020240024020032802040d0020074110490d010b200720076a220620074f0d010b4101210541002106200241086a21070c010b2006417f4c0d02200241086a210702402006450d002006100022050d01200641011019000b41012105410021060b2002200636020c20022005360208200241003602102002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a290200370300200220012902003703180240200241146a41a883c000200241186a10610d0020002007290200370200200041086a200741086a280200360200200241306a24000f0b1062000b41d883c00041004100104a000b102e000b6802017f037e230041306b22012400200029021021022000290208210320002902002104200141146a41003602002001200437031820014201370204200141b8d6c2003602102001200141186a36020020012003370320200120023703282001200141206a1065000ba80a02047f017e024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200128020022022001280204460d002001200241106a36020020022d00002203417e6a2204412e4b0d01024020040e2f001f233030152019301e0b30300e0d1d271a0c161c242212112829061b0a091025172605140721080403182b2a130f000b20022d00012105410221030c2f0b200041ac013a00000f0b0c2b0b20022d00012105412b21030c2c0b200241086a3502002106200241046a2802002101412a21030c2a0b200241086a3502002106200241046a2802002101412521030c290b200241086a3502002106200241046a2802002101411d21030c280b200241086a3502002106200241046a2802002101412721030c270b200241086a3502002106200241046a2802002101412921030c260b200241086a3502002106200241046a2802002101412021030c250b200241086a3502002106200241046a2802002101411f21030c240b200241046a280200210120022d00012105410c21030c240b200241086a3502002106200241046a2802002101411421030c220b200241046a2802002101411021030c210b200241046a2802002101410f21030c200b200241086a2903002106413021030c1e0b200241086a3502002106200241046a2802002101412121030c1e0b200241086a3502002106200241046a2802002101411a21030c1d0b200241086a3502002106200241046a2802002101411921030c1c0b200241046a2802002101412f21030c1b0b200241086a3502002106200241046a2802002101412621030c1a0b200241046a2802002101410721030c190b200241086a3502002106200241046a2802002101411521030c180b200241086a3502002106200241046a2802002101412321030c170b20022d00012105412c21030c170b200241086a2802002205ad2206421e88a70d122006420286a72203417f4c0d124104210102402003450d00200310002201450d140b02402005450d00200241046a28020021032005410274210420012105034020052003280200360200200541046a2105200341046a21032004417c6a22040d000b0b2002410c6a3502004220862006842106410921030c150b200241046a2802002101411321030c140b200241086a3502002106200241046a2802002101411e21030c130b200241086a3502002106200241046a2802002101411621030c120b200241046a2802002101411121030c110b200241046a2802002101410b21030c100b20022d00012105410321030c100b200241046a2802002101410821030c0e0b200241086a3502002106200241046a2802002101412821030c0d0b200241086a3502002106200241046a2802002101411821030c0c0b20022d00012105410421030c0c0b200241086a3502002106200241046a2802002101411721030c0a0b200241086a3502002106200241046a2802002101412221030c090b200241086a3502002106200241046a2802002101412421030c080b200241046a2802002101411221030c070b200241086a3502002106200241046a2802002101411b21030c060b200241086a3502002106200241046a2802002101411c21030c050b200241086a2903002106412e21030c030b200241046a2802002101412d21030c030b102e000b200341041019000b0b0b200020053a0001200020033a0000200041046a2001360200200041086a20063703000be80203067f017e017f230041206b22022400024002400240024002400240200041046a2802002203200028020822046b200128020420012802006b41047622054f0d00200420056a22052004490d0420034101742206200520052006491b2207ad4204862208422088a70d042008a722064100480d042003450d0120002802002109200610002205450d0520052009200620034104742203200320064b1b10ce021a200910010c020b200028020021050c020b200610002205450d030b20002005360200200041046a20073602000b200241106a2001104e024020022d001041ac01460d00200520044104746a21030340200241086a2205200241106a41086a29030037030020022002290310370300200341086a200529030037030020032002290300370300200241106a2001104e200441016a2104200341106a210320022d001041ac01470d000b0b200041086a2004360200200241206a24000f0b1018000b200641081019000bf92801367f23004190016b22022400200241106a4200370300200241206a4280808080c000370300200241286a4200370300200241386a4280808080c000370300200241c0006a4200370300200241d0006a4200370300200241e4006a4280808080c000370200200241ec006a4200370200200241fc006a4280808080c0003702004100210320024184016a41003602002002420437030020024280808080c0003703082002420437031820024204370330200242043703482002420437025c2002420437027420024188016a41003602002001410c6a280200210420012802082105024002400240200141106a2802002206450d004100210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f410021104100211102400240034020132112201121030240024002400240024020052006417f6a2206412c6c6a22012d00002214410f460d002001280024211520012800202116200128001821172001280014211820012800102119200128000c211a2001280008211b2001280004211c41012111024002400240024002400240024002402014410f71221d417e6a2201410a4b0d00201c211302400240024002400240024020010e0b00010203080904120c050d000b02402010450d000240201e450d00201e41047421142010210103400240200141046a280200450d00200128020010010b200141106a2101201441706a22140d000b0b201f450d00201010010b4101212041002121201a211e201b211f201c21100c060b0240200f450d0002402022450d00202241286c2114200f210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101201441586a22140d000b0b2023450d00200f10010b4100212041012121201a2122201b2123201c210f0c050b02402024450d00200e450d00200e10010b2003211120122113201c210e201b2124201a212520060d100c110b02402026450d00200d450d00200d10010b2003211120122113201c210d201b2126201a212720060d0f0c100b0240200a450d0002402028450d00202841146c2114200a210103400240200141046a280200450d00200128020010010b200141146a21012014416c6a22140d000b0b2029450d00200a10010b4100212a41012121201a2128201b2129201c210a410121204101212b0c060b02402008450d000240202c450d002008202c41186c6a21112008212d03400240202d41046a280200450d00202d28020010010b0240202d41146a2802002214450d00202d28020c2101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b202d41186a21010240202d41106a280200450d00202d410c6a28020010010b2001212d20012011470d000b0b202e450d00200810010b4100210141012121201a212c201b212e201c2108410121204101212b4101212a410121144101212d201d410d4d0d0a0c090b41012121410121200b4101212b0c020b0240202f450d00200c450d00200c10010b2003211120122113201c210c201b212f201a213020060d0a0c0b0b0240200b450d0002402031450d00200b20314104746a2111200b212d03400240202d2802082214450d00202d2802002101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b202d41106a21010240202d41046a280200450d00202d28020010010b2001212d20012011470d000b0b2032450d00200b10010b4100212b41012121201a2131201b2132201c210b410121200b4101212a0b41012114410121014101212d201d410d4b0d030c040b02402009450d0002402033450d0020092033411c6c6a21112009212d03400240202d410c6a2802002214450d00202d2802042101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b0240202d41086a280200450d00202d41046a28020010010b202d411c6a21010240202d41146a280200450d00202d28021010010b2001212d20012011470d000b0b2034450d00200910010b4100211441012121201a2133201b2134201c2109410121204101212b4101212a410121014101212d201d410d4d0d030c020b02402007450d0002402035450d0020072035411c6c6a21112007212d03400240202d410c6a2802002214450d00202d2802042101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b0240202d41086a280200450d00202d41046a28020010010b202d411c6a21010240202d41146a280200450d00202d28021010010b2001212d20012011470d000b0b2036450d00200710010b4100212d41012121201a2135201b2136201c2107410121204101212b4101212a4101211441012101201d410d4d0d020c010b20122113200321110c060b0240201b450d00201c10010b02402018450d002017450d00201810010b2015450d01201610010c010b20032111201221130240024002400240024002400240024002400240201d0e0e0900010209090903040b05060708090b0240201b450d00201c10010b2018450d09201910010c090b2021450d08201a450d07201a4104742114201c210103400240200141046a280200450d00200128020010010b200141106a2101201441706a22140d000c080b0b2020450d07201a450d06201a41286c2114201c210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101201441586a22140d000c070b0b202b450d06201a450d05201c201a4104746a2111201c212d03400240202d2802082214450d00202d2802002101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b202d41106a21010240202d41046a280200450d00202d28020010010b2001212d20012011470d000c060b0b202a450d05201a450d04201a41146c2114201c210103400240200141046a280200450d00200128020010010b200141146a21012014416c6a22140d000c050b0b2014450d04201a450d03201c201a411c6c6a2111201c212d03400240202d410c6a2802002214450d00202d2802042101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b0240202d41086a280200450d00202d41046a28020010010b202d411c6a21010240202d41146a280200450d00202d28021010010b2001212d20012011470d000c040b0b2001450d03201a450d02201c201a41186c6a2111201c212d03400240202d41046a280200450d00202d28020010010b0240202d41146a2802002214450d00202d28020c2101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b202d41186a21010240202d41106a280200450d00202d410c6a28020010010b2001212d20012011470d000c030b0b202d450d02201a450d01201c201a411c6c6a2111201c212d03400240202d410c6a2802002214450d00202d2802042101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b0240202d41086a280200450d00202d41046a28020010010b202d411c6a21010240202d41146a280200450d00202d28021010010b2001212d20012011470d000c020b0b024002400240201c41037122014102460d0020014101460d01201a450d04201b10010c040b2018450d01201a20184104746a211c201a211303402013221141106a2113024020112802042201450d0002402011410c6a2802002214450d002014410c6c2114034002402001280200222d450d00200141046a280200450d00202d10010b2001410c6a2101201441746a22140d000b0b201141086a280200450d00201141046a28020010010b2013201c470d000c020b0b2018450d002018410c6c2114201a2101034002402001280200222d450d00200141046a280200450d00202d10010b2001410c6a2101201441746a22140d000b0b2019450d01201a10010c010b201b450d00201c10010b20032111201221130b20060d000b0b410021060b202c410020081b2103202e410020081b211b2033410020091b21372034410020091b213420284100200a1b211a20294100200a1b211820314100200b1b212e20324100200b1b213120304100200c1b2115202f4100200c1b211720274100200d1b213320264100200d1b212620254100200e1b212a20244100200e1b212020224100200f1b212220234100200f1b2128201e410020101b212b201f410020101b212c2008410420081b211d2009410420091b211e200a4104200a1b2119200b4104200b1b210a200c4104200c1b2116200d4104200d1b210b200e4104200e1b2121200f4104200f1b21092010410420101b210820070d020c010b4104211d4100211b4100211a41002118410421194100211541002117410421164100212a41002120410421214100212b4100212c4104210841002106410021114104210941002128410021224104210b41002126410021334104210a410021314100212e4104211e41002134410021370b4104210741002136410021350b2002280200212d0240200241086a2802002201450d0020014104742114202d210103400240200141046a280200450d00200128020010010b200141106a2101201441706a22140d000b0b02402002280204450d00202d10010b2002410c6a280200212d0240200241146a2802002201450d00200141286c2114202d210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101201441586a22140d000b0b0240200241106a280200450d00202d10010b02402002411c6a280200450d00200241186a28020010010b0240200241286a280200450d00200241246a28020010010b0240200241346a280200450d00200241306a28020010010b2002413c6a28020021120240200241c4006a2802002201450d00201220014104746a211c2012212d03400240202d2802082214450d00202d2802002101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b202d41106a21010240202d41046a280200450d00202d28020010010b2001212d2001201c470d000b0b0240200241c0006a280200450d00201210010b200241c8006a280200212d0240200241d0006a2802002201450d00200141146c2114202d210103400240200141046a280200450d00200128020010010b200141146a21012014416c6a22140d000b0b0240200241cc006a280200450d00202d10010b200241dc006a28020021120240200241e4006a2802002201450d0020122001411c6c6a211c2012212d03400240202d410c6a2802002214450d00202d2802042101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b0240202d41086a280200450d00202d41046a28020010010b202d411c6a21010240202d41146a280200450d00202d28021010010b2001212d2001201c470d000b0b0240200241e0006a280200450d00201210010b200241e8006a28020021120240200241f0006a2802002201450d002012200141186c6a211c2012212d03400240202d41046a280200450d00202d28020010010b0240202d41146a2802002214450d00202d28020c2101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b202d41186a21010240202d41106a280200450d00202d410c6a28020010010b2001212d2001201c470d000b0b0240200241ec006a280200450d00201210010b200241f4006a28020021120240200241fc006a2802002201450d0020122001411c6c6a211c2012212d03400240202d410c6a2802002214450d00202d2802042101201441047421140340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201441706a22140d000b0b0240202d41086a280200450d00202d41046a28020010010b202d411c6a21010240202d41146a280200450d00202d28021010010b2001212d2001201c470d000b0b20024180016a21010240200241f8006a280200450d00201210010b20011055024020024184016a2201280200450d0020024180016a28020010010b200241086a202b3602002002410c6a2009360200200241106a2028360200200241146a2022360200200241186a20213602002002411c6a2020360200200241206a202a360200200241246a200b360200200241286a20263602002002412c6a2033360200200241306a2016360200200241346a2017360200200241386a20153602002002413c6a200a360200200241c0006a2031360200200241c4006a202e360200200241c8006a20193602002002202c36020420022008360200200241d0006a201a360200200241cc006a2018360200200241d4006a2011360200200241d8006a2013360200200241dc006a201e360200200241e0006a2034360200200241e4006a2037360200200241e8006a201d360200200241ec006a201b360200200241f0006a2003360200200241f4006a2007360200200241f8006a2036360200200241fc006a203536020020024180016a20053602002001200436020020024188016a200636020020002002418c0110ce021a20024190016a24000b9005030b7f017e027f230041306b22022400200241106a2203200141246a290200370300200241086a22042001411c6a29020037030020022001290214370300200241186a41106a2205200141106a280200360200200241186a41086a2206200141086a290200370300200220012902003703182000200241186a105721070240024002400240200041206a220828020022092000411c6a280200470d00200941016a220a2009490d012009410174220b200a200a200b491b220cad420286220d422088a70d01200da7220a4100480d01024002402009450d00200041186a280200210e200a1000220b450d04200b200e200a2009410274220f200f200a4b1b10ce021a200e10010c010b200a1000220b450d030b2000411c6a200c360200200041186a200b3602000b2008200941016a360200200041186a28020020094102746a20073602002005200329030037030020062004290300370300200220022903003703180240200041f0006a22032802002209200041ec006a280200470d00200941016a22042009490d0120094101742205200420042005491b2206ad42187e220d422088a70d01200da722044100480d01024002402009450d00200041e8006a2802002107200410002205450d05200520072004200941186c2208200820044b1b10ce021a200710010c010b200410002205450d040b200041ec006a2006360200200041e8006a20053602000b2003200941016a360200200041e8006a280200200941186c6a22032002290318370200200341086a200241186a41086a290300370200200341106a200241186a41106a290300370200024020012d002c450d0020004101360254200041d8006a20093602000b200241306a24000f0b1018000b200a41041019000b200441041019000bfc24032e7f017e017f230041306b2202240020012802042103200128020021044101210502400240024002400240024002400240024002400240024002400240024002400240024020012802082206450d00412c10002207450d0220072004360004200741023a0000200720033600082007200636000c41002108410121090c010b4104210741002109410121080b200141106a280200210a200128020c210b0240024002400240200141146a280200220c450d002009410174220d200941016a220e200e200d491b220e412c6c210f2009450d01200f1000220d450d05200d2007200f2009412c6c22102010200f4b1b10ce021a200710010c020b2009210e2007210d0c020b200f1000220d450d030b200d2009412c6c6a220720022f002d3b0001200741033a00002007200b3600042007200a3600082007200c36000c20072002290208370210200741036a2002412f6a2d00003a0000200741186a200241106a290200370200200741206a200241186a290200370200200741286a200241086a41186a280200360200200941016a210941002105200d21070b2001411c6a28020021112001280218211241002113024002400240024002400240200141206a2802002210450d002009200e470d0141000d1041000d10200e4101742207200e41016a220f200f2007491b220fad422c7ea722074100480d10200e450d02200710002214450d082014200d2007200e412c6c220e200e20074b1b10ce021a200d10010c030b200e210f200d2114410021150c040b200e210f200d21140c020b200710002214450d050b201421070b20072009412c6c6a220d41043a0000200d2012360004200d2011360008200d201036000c200d41036a2002412f6a2d00003a0000200d20022f002d3b0001200d41286a200241086a41186a280200360200200d41206a200241186a290200370200200d41186a200241106a290200370200200d200229020837021041012115200941016a21090b200141286a2802002116200128022421170240024002400240024002402001412c6a2802002218450d002009200f470d0141000d1041000d10200f4101742207200f41016a220d200d2007491b2210ad422c7ea722074100480d10200f450d0220071000220e450d09200e20142007200f412c6c220d200d20074b1b10ce021a201410010c030b200f21102014210e0c040b200f21102014210e0c020b20071000220e450d060b200e21070b20072009412c6c6a220d41053a0000200d2017360004200d2016360008200d201836000c200d41036a2002412f6a2d00003a0000200d20022f002d3b0001200d41286a200241086a41186a280200360200200d41206a200241186a290200370200200d41186a200241106a290200370200200d200229020837021041012113200941016a21090b200141346a280200211420012802302119024002400240024002400240200141386a2802002218450d0020092010470d0141000d1041000d1020104101742207201041016a220d200d2007491b220fad422c7ea722074100480d102010450d0220071000220d450d0a200d200e20072010412c6c2210201020074b1b10ce022107200e10012007210e0c030b4100211a2010210f0c040b2010210f0c020b20071000220e450d070b200e21070b20072009412c6c6a220d41063a0000200d2019360004200d2014360008200d201836000c200d41036a2002412f6a2d00003a0000200d20022f002d3b0001200d41286a200241086a41186a280200360200200d41206a200241186a290200370200200d41186a200241106a290200370200200d20022902083702104101211a200941016a21090b200141c0006a280200211b200128023c211c41012118024002400240024002400240200141c4006a280200221d450d002009200f470d0141000d1041000d10200f4101742207200f41016a220d200d2007491b2210ad422c7ea722074100480d10200f450d0220071000221e450d0b201e200e2007200f412c6c220d200d20074b1b10ce021a200e10010c030b200f2110200e211e4101211f0c040b200f2110200e211e0c020b20071000221e450d080b201e21070b20072009412c6c6a220d41073a0000200d201c360004200d201b360008200d201d36000c200d41036a2002412f6a2d00003a0000200d20022f002d3b0001200d41286a200241086a41186a280200360200200d41206a200241186a290200370200200d41186a200241106a290200370200200d2002290208370210200941016a21094100211f0b200141cc006a280200212020012802482121024002400240024002400240200141d0006a2802002222450d0020092010470d0141000d1041000d1020104101742207201041016a220d200d2007491b220fad422c7ea722074100480d102010450d02200710002223450d0c2023201e20072010412c6c220d200d20074b1b10ce021a201e10010c030b2010210f201e21234101211e20012802544101460d040c0d0b2010210f201e21230c020b200710002223450d090b202321070b20072009412c6c6a220d41083a0000200d2021360004200d2020360008200d202236000c200d41036a2002412f6a2d00003a0000200d20022f002d3b0001200d41286a200241086a41186a280200360200200d41206a200241186a290200370200200d41186a200241086a41086a290200370200200d2002290208370210200941016a2109410021184101211e20012802544101470d090b200141d8006a280200212402400240024002402009200f470d0041000d0e41000d0e200f4101742207200f41016a220d200d2007491b220ead422c7ea722074100480d0e200f450d01200710002210450d0b201020232007200f412c6c220d200d20074b1b10ce021a202310010c020b200f210e202321100c020b200710002210450d090b201021070b20072009412c6c6a220d41093a0000200d2024360204200d41036a2002412f6a2d00003a0000200d20022f002d3b0001200d2002290208370208200d41106a200241106a290200370200200d41186a200241086a41106a290200370200200d41206a200241086a41186a290200370200200d41286a200241086a41206a280200360200200941016a21090c090b412c41041019000b200f41041019000b200741041019000b200741041019000b200741041019000b200741041019000b200741041019000b200741041019000b200f210e202321100b200141e0006a2802002125200128025c2126024002400240024002400240200141e4006a2802002227450d002009200e470d0141000d0641000d06200e4101742207200e41016a220d200d2007491b220fad422c7ea722074100480d06200e450d02200710002224450d09202420102007200e412c6c220d200d20074b1b10ce021a201010010c030b200e210f201021240c040b200e210f201021240c020b200710002224450d060b202421070b20072009412c6c6a220d410a3a0000200d2026360004200d2025360008200d202736000c200d41036a2002412f6a2d00003a0000200d20022f002d3b0001200d41286a200241086a41186a280200360200200d41206a200241186a290200370200200d41186a200241106a290200370200200d2002290208370210200941016a21094100211e0b200141ec006a28020021282001280268212941012123024002400240024002400240200141f0006a280200222a450d002009200f470d0141000d0641000d06200f4101742207200f41016a220d200d2007491b2210ad422c7ea722074100480d06200f450d0220071000222b450d0a202b20242007200f412c6c220d200d20074b1b10ce021a202410010c030b200f21102024212b4101212c0c040b200f21102024212b0c020b20071000222b450d070b202b21070b20072009412c6c6a220d410b3a0000200d2029360004200d2028360008200d202a36000c200d41036a2002412f6a2d00003a0000200d20022f002d3b0001200d41286a200241086a41186a280200360200200d41206a200241186a290200370200200d41186a200241106a290200370200200d2002290208370210200941016a21094100212c0b200141f8006a280200212d2001280274210f024002400240024002400240200141fc006a2802002224450d0020092010470d0141000d0641000d0620104101742207201041016a220d200d2007491b220ead422c7ea722074100480d062010450d0220071000222e450d0b202e202b20072010412c6c220d200d20074b1b10ce021a202b10010c030b2010210e202b212e0c040b2010210e202b212e0c020b20071000222e450d080b202e21070b20072009412c6c6a220d410c3a0000200d200f360004200d202d360008200d202436000c200d41036a2002412f6a2d00003a0000200d20022f002d3b0001200d41286a200241086a41186a280200360200200d41206a200241186a290200370200200d41186a200241106a290200370200200d2002290208370210200941016a2109410021230b20014184016a280200212b200128028001210d0240024002400240200e20096b20014188016a280200412c6c2201412c6d22104f0d00200920106a22072009490d04200e410174222f20072007202f491b222fad422c7e2230422088a70d042030a722314100480d04200e450d01203110002207450d062007202e2031200e412c6c220e200e20314b1b10ce02210e202e1001200e2009412c6c6a200d200110ce021a202b0d020c030b200e212f20072009412c6c6a200d200110ce021a202b0d010c020b203110002207450d0420072009412c6c6a200d200110ce021a202b450d010b200d10010b41c00510002201450d0120004280c2cdeb1637020020002007360208200241086a410c6a42103702002000410c6a202f360200200041106a200920106a36020020024280c2cdeb1637030820022001360210200241106a10552001100102402023450d0002402024450d00200f2024411c6c6a210d200f2107034002402007410c6a2802002209450d0020072802042101200941047421090340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200941706a22090d000b0b0240200741086a280200450d00200741046a28020010010b2007411c6a21010240200741146a280200450d00200728021010010b200121072001200d470d000b0b202d450d00200f10010b0240202c450d000240202a450d002029202a41186c6a210d2029210703400240200741046a280200450d00200728020010010b0240200741146a2802002209450d00200728020c2101200941047421090340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200941706a22090d000b0b200741186a21010240200741106a280200450d002007410c6a28020010010b200121072001200d470d000b0b2028450d00202910010b0240201e450d0002402027450d0020262027411c6c6a210d20262107034002402007410c6a2802002209450d0020072802042101200941047421090340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200941706a22090d000b0b0240200741086a280200450d00200741046a28020010010b2007411c6a21010240200741146a280200450d00200728021010010b200121072001200d470d000b0b2025450d00202610010b02402018450d0002402022450d00202241146c21092021210103400240200141046a280200450d00200128020010010b200141146a21012009416c6a22090d000b0b2020450d00202110010b0240201f450d000240201d450d00201c201d4104746a210d201c21070340024020072802082209450d0020072802002101200941047421090340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200941706a22090d000b0b200741106a21010240200741046a280200450d00200728020010010b200121072001200d470d000b0b201b450d00201c10010b02402014410047201a41017371450d00201910010b02402016410047201341017371450d00201710010b02402011410047201541017371450d00201210010b02402005450d000240200c450d00200c41286c2109200b210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101200941586a22090d000b0b200a450d00200b10010b02402008450d0002402006450d00200641047421092004210103400240200141046a280200450d00200128020010010b200141106a2101200941706a22090d000b0b2003450d00200410010b200241306a24000f0b1018000b41c00541041019000b203141041019000b200741041019000b200741041019000b200741041019000bb60504057f017e017f017e230041106b2203240002402001450d0020012104034020002802940321002004417f6a22040d000b2001450d0003402001417f6a22010d000b0b4100210502402002450d0041002104034002400240200420002f01064f0d00200020044105746a220641386a2802002101200641346a2802002107200441016a2104200641c4006a2802004102460d030c010b0240024020002802002201450d0020003301044220862005ad84210841012106200121040c010b2005ad210841002106410021040b200010012008a72105024002402008422088a7220720012f01064f0d00200421010c010b03400240024020042802002200450d00200641016a210620043301044220862005ad842108200021010c010b2005ad2108410021010b200410012008a72105200121042008422088a7220720002f01064f0d000b0b200120074102746a4198036a2802002100200120074105746a220441c4006a2802002109200441386a2802002101200441346a2802002107024020064101460d00410120066b210403402000280294032100200441016a22040d000b0b4100210420094102460d020b2002417f6a210202402001450d00200710010b20020d000b0b02400240200041a0a1c100460d000240024020002802002204450d00200033010421082003200436020420034101360200200320084220862005ad84220837030841022101200010012004450d020c010b2005ad21084100210441012101200010014100450d010b024020042802002200450d002004330104210a20032000360204200320013602002003200a422086200842ffffffff0f8384370308200410012000450d010c020b410021002004100141000d010b200341106a24000f0b024020002802002204450d000340200010012004210020042802002201210420010d000b0b20001001200341106a24000bd50201067f230041306b2202240041272103024002400240024002400240200028020022004190ce00490d00412721030340200241096a20036a2204417c6a200020004190ce006e220541f0b17f6c6a220641e4006e22074101744182a2c1006a2f00003b00002004417e6a20062007419c7f6c6a4101744182a2c1006a2f00003b00002003417c6a2103200041ffc1d72f4b21042005210020040d000b41e4002104200541e400480d010c020b41e40021042000220541e4004e0d010b2005220041094a0d010c020b200241096a2003417e6a22036a2005200520046e2200419c7f6c6a4101744182a2c1006a2f00003b0000200041094c0d010b200241096a2003417e6a22036a220520004101744182a2c1006a2f00003b00000c010b200241096a2003417f6a22036a2205200041306a3a00000b2001410141b8d6c20041002005412720036b105b2100200241306a240020000bb20f01097f024020002802082201450d00200028020022022001412c6c6a2103034020022204412c6a21020240024002400240024002400240024002400240024002400240024020042d00002200410f71410d4b0d00024020000e0e0002030405060708090e0a0b0c0d000b200441086a280200450d0d200441046a280200100120022003470d0e0c0f0b0240200441086a280200450d00200441046a28020010010b0240200441146a2802002200450d00200441186a280200450d00200010010b200441246a280200450d0c200441206a280200100120022003470d0d0c0e0b0240200441086a280200450d00200441046a28020010010b200441146a280200450d0b200441106a280200100120022003470d0c0c0d0b200441046a210502402004410c6a2802002201450d00200528020021002001410474210103400240200041046a280200450d00200028020010010b200041106a2100200141706a22010d000b0b200441086a280200450d0a2005280200100120022003470d0b0c0c0b200441046a210502402004410c6a2802002201450d0020052802002100200141286c210103400240200041046a280200450d00200028020010010b0240200041106a280200450d002000410c6a28020010010b200041286a2100200141586a22010d000b0b200441086a280200450d092005280200100120022003470d0a0c0b0b200441086a280200450d08200441046a280200100120022003470d090c0a0b200441086a280200450d07200441046a280200100120022003470d080c090b200441086a280200450d06200441046a280200100120022003470d070c080b200441046a210602402004410c6a2802002200450d002006280200220520004104746a21070340024020052802082201450d0020052802002100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010010b200041106a2100200141706a22010d000b0b200541106a21000240200541046a280200450d00200528020010010b2000210520002007470d000b0b200441086a280200450d052006280200100120022003470d060c070b200441046a210502402004410c6a2802002201450d0020052802002100200141146c210103400240200041046a280200450d00200028020010010b200041146a21002001416c6a22010d000b0b200441086a280200450d042005280200100120022003470d050c060b200441046a210602402004410c6a2802002200450d00200628020022052000411c6c6a2107034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010010b200041106a2100200141706a22010d000b0b0240200541086a280200450d00200541046a28020010010b2005411c6a21000240200541146a280200450d00200528021010010b2000210520002007470d000b0b200441086a280200450d032006280200100120022003470d040c050b200441046a210602402004410c6a2802002200450d0020062802002205200041186c6a210703400240200541046a280200450d00200528020010010b0240200541146a2802002201450d00200528020c2100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010010b200041106a2100200141706a22010d000b0b200541186a21000240200541106a280200450d002005410c6a28020010010b2000210520002007470d000b0b200441086a280200450d022006280200100120022003470d030c040b200441046a210602402004410c6a2802002200450d00200628020022052000411c6c6a2107034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010010b200041106a2100200141706a22010d000b0b0240200541086a280200450d00200541046a28020010010b2005411c6a21000240200541146a280200450d00200528021010010b2000210520002007470d000b0b200441086a280200450d012006280200100120022003470d020c030b024002400240200441046a2d000022004103714102460d0020004101460d0120000d022004410c6a280200450d03200441086a280200100120022003470d040c050b2004410c6a21080240200441146a2802002200450d002008280200220620004104746a210903402006220741106a2106024020072802042200450d0002402007410c6a2802002201450d002001410c6c21010340024020002802002205450d00200041046a280200450d00200510010b2000410c6a2100200141746a22010d000b0b200741086a280200450d00200741046a28020010010b20062009470d000b0b200441106a280200450d022008280200100120022003470d030c040b2004410c6a21070240200441146a2802002201450d00200728020021002001410c6c21010340024020002802002205450d00200041046a280200450d00200510010b2000410c6a2100200141746a22010d000b0b200441106a280200450d012007280200100120022003470d020c030b2004410c6a280200450d00200441086a28020010010b20022003470d000b0b0bc727030d7f017e147f23004180046b22032400200341f0026a41106a2204200141106a280200360200200341f0026a41086a2205200141086a290200370300200320012902003703f0022003200341f0026a1050024002400240024002400240410110002201450d00200141003a0000200320032f01f0023b01c0012005428180808010370300200441e0083b0100200320013602f402200341013602f002200320032f01c0013b0182032003200341f0026a10572105200341f0026a41eae9c1004103104720032802f802210620032802f402210720032802f0022108200341f0026a41e8c2c1004103104720032802f802210920032802f402210a20032802f002210b200341c0016a41026a2201200341f0026a41026a22042d00003a0000200320032f00f0023b01c001200420012d00003a0000200320032f01c0013b01f0020240024002400240024002400240024002400240024002400240200341146a220c2802002201200341106a280200470d00200141016a220d2001490d012001410174220e200d200d200e491b220fad42287e2210422088a70d012010a7220d4100480d01024002402001450d002003410c6a2802002111200d1000220e450d10200e2011200d200141286c22122012200d4b1b10ce021a201110010c010b200d1000220e450d0f0b200341106a200f3602002003410c6a200e3602000b200c200141016a3602002003410c6a280200200141286c6a2201200836020020012007360204200120063602082001200b36020c200141003a0018200141106a200a360200200141146a2009360200200141196a20032f01f0023b00002001411b6a20042d00003a00002001411c6a2005360200200341f0026a2003418c0110ce021a20034190016a200341f0026a105220034190016a41106a2802002209412c6c2101200328029801221341586a210402400340410021052001450d01200141546a2101200441286a21062004412c6a2207210420062d00004103470d000b200741086a2802002201450d00200141286c2104200728020041186a2101410021050340200520012d0000456a2105200141286a2101200441586a22040d000b0b2009412c6c2101201341586a21042005417f6a210602400340410021052001450d01200141546a2101200441286a21072004412c6a2208210420072d00004103470d000b200841086a2802002201450d00200141286c2104200828020041186a2101410021050340200520012d0000456a2105200141286a2101200441586a22040d000b0b2009412c6c2101201341606a210402400240024003402001450d01200141546a2101200441206a21072004412c6a2208210420072d00004104470d000b2008280200210120090d010c020b410021012009450d010b200120056a211420132009412c6c6a2115200241046a2116200341f0026a41026a211141002117410021090240034002400240024020132d00002201410f71410b460d0002402001410a460d0020014108470d02201328020c2201450d02200141146c2104201328020441106a2101034002402001417c6a2802000d00200128020022052006490d002001200541016a3602000b200141146a21012004416c6a22040d000c030b0b201328020c2201450d01201328020422072001411c6c6a2108034020072201411c6a2107024020012802182204450d00200128021021012004410274210403400240200128020022052006490d002001200541016a3602000b200141046a21012004417c6a22040d000b0b20072008470d000c020b0b201328020c2201450d0020132802042207200141186c6a211803402009211902402007220b41146a220f2802004104742204450d00200b28020c21010340024020012d0000410b470d00200141046a220528020022072006490d002005200741016a3602000b200141106a2101200441706a22040d000b0b41081000221a450d10201a42808080801037020041041000221b450d11201b4100360200024002400240200f280200221c450d004100210141012104201a211d41012107201b211e41012105410121094100201c22084f0d0e02400340200141016a210a024002400240024002400240024002400240024002400240024002400240200b410c6a28020020014104746a2d00002201417e6a41034f0d00200110582121200241086a28020021222016210103402001280200220c41086a2112200c2f01062108410021010240034020082001460d014100417f4101201220016a2d0000220d202141ff0171220e4b1b200d200e461b220d450d04200141016a2101200d4101460d000b2001417f6a21080b02402022450d002022417f6a2122200c20084102746a41ec006a21010c010b0b2002210120090d060c160b20014105460d0120014106470d022009450d152009417f6a21090c030b200c20014103746a41146a220c28020022084101460d142002210120084102460d0320090d040c140b2009450d1320072004470d04200441016a22012004490d1720044101742208200120012008491b221fad4203862210422088a70d172010a722014100480d172004450d0820011000221a450d1f201a201d200120044103742208200820014b1b10ce021a201d10010c090b200110582121200241086a2802002122201621010240024003402001280200220c41086a2112200c2f01062108410021010240034020082001460d014100417f4101201220016a2d0000220d202141ff0171220e4b1b200d200e461b220d450d03200141016a2101200d4101460d000b2001417f6a21080b02402022450d002022417f6a2122200c20084102746a41ec006a21010c010b0b2002210120090d010c140b200c20014103746a41146a220c28020022084101460d1320022101024020084102470d00200c41046a21010b2009450d130b2007201e20094102746a417c6a28020022084d0d12201d20084103746a220c280204220820012802006a22012008490d12200c41046a20013602000b2004211f2007210120052120200a201c490d090c0b0b200c41046a21012009450d100b2007201e20094102746a417c6a28020022084d0d0f201d20084103746a220c280204220820012802006a22012008490d0f200c41046a2001360200024020072004470d00200441016a22012004490d1420044101742208200120012008491b221fad4203862210422088a70d142010a722014100480d142004450d0220011000221d450d1a201d201a200120044103742208200820014b1b10ce021a201a10010c030b2004211f200721040c030b2004211f200721040c050b20011000221d450d170b201d211a0b201d20044103746a220141013602042001200a360200024002400240024020092005470d00200541016a22012005490d1320054101742204200120012004491b2220ad4202862210422088a70d132010a722014100480d132005450d0120011000221e450d1a201e201b200120054102742204200420014b1b10ce021a201b10010c020b20052120200921050c020b20011000221e450d180b201e211b0b200741016a2101201e20054102746a2007360200200941016a2109200a201c490d030c050b20011000221a450d160b201a211d0b201d20044103746a220141013602042001200a36020002400240024002402009417f6a22012005470d00200541016a22012005490d1020054101742204200120012004491b2220ad4202862210422088a70d102010a722014100480d102005450d0120011000221b450d19201b201e200120054102742204200420014b1b10ce021a201e10010c020b20052120200121050c020b20011000221b450d170b201b211e0b200741016a2101201e20054102746a2007360200200a201c4f0d020b201f21042001210720202105200a2201200f28020022084f0d100c000b0b2001450d02201d20014103746a2122201d211a0c010b201a41086a2122410121204101211f0b200f280200221d417f73211c201d410174210a410021054100201d6b2123201d410474210d201a21080340201d20056a2201200520082802006a2209490d09200841046a280200210702402001200b41106a220c280200470d00200141016a22042001490d09200a20042004200a491b2212ad4204862210422088a70d092010a722044100480d090240024020232005470d0020041000220e0d010c0e0b200b410c6a280200212120041000220e450d0d200e20212004200d200d20044b1b10ce021a202110010b200c2012360200200b410c6a200e3602000b200b410c6a220e28020020094104746a220441106a2004200120096b41047410cf021a2004412d3a0000200441046a2007360200200441036a20112d00003a0000200420032f00f0023b0001200f200141016a22073602002007200941016a2209490d0a02402007200c280200470d00200741016a22042007490d09200a41026a2212200420042012491b2221ad4204862210422088a70d092010a722044100480d0902400240201c2005470d002004100022120d010c0f0b200e280200211e200410002212450d0e2012201e2004200d41106a2224202420044b1b10ce021a201e10010b200c2021360200200e20123602000b200e28020020094104746a220441106a2004200720096b41047410cf021a2004410b3a0000200441046a2006360200200441036a20112d00003a0000200420032f00f0023b0001200f200141026a360200200a41046a210a200d41206a210d200541026a2105200841086a22082022470d000b201a211d0b0240201f450d00201d10010b02402020450d00201b10010b200b41186a21070240200241106a280200450d00200f2802002204450d00200b410c6a280200210120044104742104410021050340024020012d0000412c470d002001410b3a0000200141046a2014360200200541016a21050b200141106a2101200441706a22040d000b410121092005450d0020072018470d010c020b2019210920072018470d000b0b2013412c6a22132015470d010c020b02402004450d00201a10010b4101211702402005450d00201b10010b201921092013412c6a22132015470d000b0b02402017410171450d00200020032903900137020420004101360200200041146a200341a0016a2802003602002000410c6a20034198016a29030037020020034180046a24000f0b2009410171450d00200341f0026a41106a20034190016a41106a280200360200200341f0026a41086a220120034190016a41086a29030037030020032003290390013703f002200341c0016a200341f0026a1050411010002204450d0f200441063a0000200341a8016a41086a2001280200360200200320032902f0023703a801200341ec026a41026a2205200341f0026a41026a2d00003a0000200320032f00f0023b01ec02200320032f01d8023b01ea02410110002201450d10200141003a0000200341d8026a41086a2207200341a8016a41086a280200360200200341d4026a41026a220820052d00003a0000200320032903a8013703d802200320032f01ec023b01d402200320032f01ea023b01d2022003418c036a410036020020034190036a2205200436020020034194036a2209428180808010370200200341a8036a22044100360200200341ac036a41e0083b0100200341f0026a41086a220d20032903d802370300200341f0026a41106a20072802003602002003419f036a20082d00003a0000200342003703f0022003420437028403200341003a009c03200342013703a003200320032f01d4023b009d03200341ae036a20032f01d2023b0100200320013602a801200320013602b001200341013602ac012003200141016a3602b401200341a0036a200341a8016a105920042903002110200341a4036a280200210820034198036a2802002104200928020021092005280200210720034188036a280200210a20032802a003210b200328029c03210c200328028403210e024020032802f002450d00200d280200450d0020032802f40210010b411010002201450d11200141063a000041f00010002205450d122005410f3a0000200541003602042005410f3a0010200541003602142005412d3a0020200541d8003a00302005410b3a0040200520063602442005412c3b0150200541063a00602005200241106a280200360224024020012d00004109470d00200128020841ffffffff0371450d00200128020410010b200110010240200a450d00200e10010b02402004450d0020044104742104200721010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200441706a22040d000b0b201042ffffffffff9f4083211002402009450d00200710010b200341f0026a41086a2008360200200341f0026a410c6a20103702002003418c036a410036020020034190036a200536020020034194036a4287808080f0003702002003200b3602f402200341013602f00220034204370284032003200c36029c03200341c0016a200341f0026a1051200341f0026a200341c0016a418c0110ce021a200341a8016a200341f0026a105220004100360200200041146a200341b8016a2802003602002000410c6a200341a8016a41086a290300370200200020032903a80137020420034180046a24000f0b200020032903900137020420004100360200200041146a200341a0016a2802003602002000410c6a20034198016a29030037020020034180046a24000f0b1018000b41d881c000104d000b41d881c000104d000b200441081019000b200441081019000b41b081c00020012008104a000b200141041019000b200141041019000b200141041019000b200141041019000b410841041019000b410441041019000b410141011019000b200d41041019000b411041081019000b410141011019000b411041081019000b41f00041081019000b9d0a02107f017e0240024002400240024002400240024002400240024020012802004101470d0020002802002202200028020822034104746a2104200141106a2d000021052001410c6a2802002106200141086a280200210720012f0112210820012d00112109200128020421014100210a2002210b024020034104490d004100210a200541ff0171210c2002210b03400240200b2d000c200c470d00200b2802082006470d00200b280200210d4100210e02400340200e20064f0d012001200e6a210f200d200e6a2110200e41016a210e20102d0000200f2d0000460d000c020b0b200941ff0171220e410447200b410d6a2d0000220f410447730d00200f200e460d06200e4104460d06200f4104460d060b0240200b411c6a2d0000200c470d00200b41186a2802002006470d00200b41106a280200210d4100210e02400340200e20064f0d012001200e6a210f200d200e6a2110200e41016a210e20102d0000200f2d0000460d000c020b0b200941ff0171220e410447200b411d6a2d0000220f410447730d00200f200e460d07200e4104460d07200f4104460d070b0240200b412c6a2d0000200c470d00200b41286a2802002006470d00200b41206a280200210d4100210e02400340200e20064f0d012001200e6a210f200d200e6a2110200e41016a210e20102d0000200f2d0000460d000c020b0b200941ff0171220e410447200b412d6a2d0000220f410447730d00200f200e460d08200e4104460d08200f4104460d080b0240200b413c6a2d0000200c470d00200b41386a2802002006470d00200b41306a280200210d4100210e02400340200e20064f0d012001200e6a210f200d200e6a2110200e41016a210e20102d0000200f2d0000460d000c020b0b200941ff0171220e410447200b413d6a2d0000220f410447730d00200f200e460d09200e4104460d09200f4104460d090b200a41046a210a2004200b41c0006a220b6b413f4b0d000b0b200b2004460d02200941ff017122114104470d01200541ff0171210c03400240200b2d000c200c470d00200b2802082006470d00200b280200210d4100210e02400340200e20064f0d012001200e6a210f200d200e6a2110200e41016a210e20102d0000200f2d0000460d000c020b0b200b410d6a2d00004104460d050b200a41016a210a200b41106a220b2004470d000c030b0b200128020421060c090b200541ff0171210c03400240200b2d000c200c470d00200b2802082006470d00200b280200210d4100210e02400340200e20064f0d012001200e6a210f200d200e6a2110200e41016a210e20102d0000200f2d0000460d000c020b0b200b410d6a2d0000220e4104460d00200e2011460d030b200a41016a210a200b41106a220b2004470d000b0b02400240024002402003200041046a280200470d00200341016a220e2003490d082003410174220b200e200e200b491b220fad4204862212422088a70d082012a7220b4100480d082003450d01200b1000220e450d09200e2002200b200341047422102010200b4b1b10ce021a200210010c020b2002210e0c020b200b1000220e450d070b2000200e360200200041046a200f3602000b200041086a200341016a360200200e20034104746a220e2007360204200e2001360200200e2006360208200e20053a000c200e20093a000d200e20083b010e20030f0b200a21062007450d060c050b200a410172210620070d040c050b200a410272210620070d030c040b200a410372210620070d020c030b1018000b200b41041019000b2001100120060f0b20060bb505000240024002400240024002400240024002400240200041ff0171417f6a220041aa014b0d00024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000eab014a00000000000000000000000000010101010103030404050506060707080809094b0a0a0b0b0c0c0d0d4c4d0e0e0f0f10101111121213131414151516161717181819191a1a1b1b1c1c1d1d1e1e1f1f20204e212122224f2323242450252526262727282829292a2a512b2b2c2c2d2d2e2e2f2f30303131323233333434353536363737383839393a3a3b3b3c3c3d3d3e3e523f3f404041414242434344444545464647474848020202024a0b410a0f0b41080f0b41100f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41050f0b41050f0b41050f0b41050f0b41060f0b41070f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b41000f0b41010f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b41000f0b41010f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410f0f0b410f0f0b410e0f0b410f0f0b410f0f0b410f0f0b410f0f0b410f0f0b410f0f0b410f0f0b41110f0b41120f0b41050f0b41130f0b41140f0b41000f0b41020f0b41000f0b41020f0b410e0bae0201087f024002400240024002400240200041046a2802002202200041086a28020022036b2001410c6a2802002204200141086a28020022056b22064f0d00200320066a22072003490d0420024101742208200720072008491b22084100480d042002450d0120002802002109200810002207450d052007200920082002200220084b1b10ce021a200910010c020b200028020021070c020b200810002207450d030b20002007360200200041046a20083602000b200720036a2005200610ce021a200141086a22072004360200200041086a200320066a36020041002100024003402000450d012007200441016a22033602002000417f6a210020042d000021062003210420064104470d000b0b02402001280204450d00200128020010010b0f0b1018000b200841011019000bcd0f01127f230041b0016b2202240002400240024002400240024002402000280200220341a0a1c100460d00200028020421040c010b41ec0010002203450d0141002104200341003b010620034100360200200341086a200241186a41e40010ce021a20004100360204200020033602000b200141ff01712105024002400340200341066a210720032f01062106410021080240034020062008460d014100417f4101200320086a41086a2d0000220920054b1b20092005461b2209450d03200841016a210820094101460d000b2008417f6a21060b02402004450d002004417f6a2104200320064102746a41ec006a28020021030c010b0b2000200028020841016a3602082002410036020820022000360210200220063602142002200336020c200341066a22082f01002205410b4f0d01200341086a2209200641016a22006a200920066a2209200520066b10cf021a200920013a0000200341146a220320004103746a200320064103746a220320082f010020066b41037410cf021a20034101360200200820082f010041016a3b0100200241b0016a24000f0b20022004360218200220003602202002200041086a360228200220083602242002200336021c200320084103746a41146a42013702000c050b41ec0010002205450d02200541003b010620054100360200200541086a200241186a41e40010ce022104200341c8006a280200210a200341c4006a280200210b2003410e6a2d0000210c20042003410f6a200341066a22092f010041796a220810ce022104200541146a200341cc006a200841037410ce02210d200941063b0100200520083b010602400240200641064b0d00200341086a2208200641016a22046a200820066a220820092f010020066b10cf021a200820013a0000200341146a220820044103746a200820064103746a220820092f010020066b41037410cf021a200841013602000c010b20042006417a6a22096a2004200641796a22066a2204200841ffff037120066b10cf021a200420013a0000200d20094103746a200d20064103746a2208200541066a22072f010020066b41037410cf021a200841013602000b200720072f010041016a3b01000240024020032802002208450d0003402005210e200a210f200b2110200c211120032f01042109200822072f01062208410a4d0d02419c0110002205450d04200541003b010620054100360200200541086a200241186a41940110ce022103200741c8006a280200210a200741c4006a280200210b2007410e6a2d0000210c20032007410f6a200741066a22012f0100220641796a220810ce022112200541146a200741cc006a200841037410ce022113200541ec006a20074188016a2006417a6a220441027410ce02210d200141063b0100200520083b010602402004450d0041002108200d210303402003280200220620083b010420062005360200200341046a21032004200841016a2208470d000b0b02400240200941064b0d00200741086a2203200941016a22086a200320096a220320012f0100220620096b220410cf021a200320113a0000200741146a220320084103746a200320094103746a2203200441037410cf021a200320103602002003200f3602042001200641016a22033b0100200741ec006a2206200941027422016a41086a200620084102746a2204200341ffff0371220620086b41027410cf021a2004200e360200200920064f0d01200720016a41f0006a2108034020082802002203200941016a22093b010420032007360200200841046a210820062009470d000c020b0b20122009417a6a22036a2012200941796a22086a2204200541066a22062f010020086b10cf021a200420113a0000201320034103746a201320084103746a220420062f010020086b41037410cf021a200420103602002004200f360204200620062f010041016a22043b0100200d200941027422016a416c6a200d20034102746a2206200441ffff0371220920036b41027410cf021a2006200e360200200320094b0d00200520016a41d4006a2103034020032802002206200841016a22083b010420062005360200200341046a210320092008470d000b0b20072103200728020022080d000b0b419c0110002208450d04200841003b010620084100360200200841086a200241186a41940110ce02210620082000280200220336026c200020083602002000200028020441016a360204200341003b010420032008360200200820082f010622034103746a220941146a200b360200200941186a200a360200200620036a200c3a0000200841ec006a200341016a22034102746a2005360200200820033b0106200520033b010420052008360200200241b0016a24000f0b200741086a2206200941016a22036a200620096a2206200820096b220510cf021a200620113a0000200741146a220620034103746a200620094103746a2206200541037410cf021a200620103602002006200f360204200741066a200841016a22083b0100200741ec006a220620094102746a41086a200620034102746a2206200841ffff0371220520036b41027410cf021a2006200e360200200920054f0d0420072003417f6a22084102746a41f0006a2103034020032802002206200841016a22083b010420062007360200200341046a210320052008470d000c050b0b41ec0041041019000b419c0141041019000b41ec0041041019000b419c0141041019000b200241b0016a24000bbd0701057f230041206b2206240020062003360204200620023602002006418080c4003602080240024002402001450d00200028020022074101710d01200521080c020b2006412d360208200541016a2108200028020021070c010b2006412b360208200541016a21080b41002101200641003a000f02402007410471450d00200641013a000f02402003450d0041002101200321090340200120022d000041c00171418001466a2101200241016a21022009417f6a22090d000b0b200820036a20016b21080b2000280208210220062006410f6a3602142006200641086a360210200620063602180240024002400240024002400240024002400240024020024101470d002000410c6a280200220220084d0d0120074108710d02200220086b2102410120002d0030220120014103461b41037122014102460d03410021072001450d04200221030c050b200641106a200010750d082000280218200420052000411c6a28020028020c1101002102200641206a240020020f0b200641106a200010750d072000280218200420052000411c6a28020028020c1101002102200641206a240020020f0b200041013a003020004130360204200641106a200010750d062006413036021c200220086b210120002802182109417f21022000411c6a2802002203410c6a21000340200241016a220220014f0d0420092006411c6a41012000280200110100450d000c070b0b20024101762103200241016a41017621070c010b41002103200221070b2006410036021c02402000280204220241ff004b0d00200620023a001c410121090c030b200241ff0f4b0d0120062002413f71418001723a001d20062002410676411f7141c001723a001c410221090c020b2009200420052003410c6a2802001101002102200641206a240020020f0b0240200241ffff034b0d0020062002413f71418001723a001e20062002410676413f71418001723a001d20062002410c76410f7141e001723a001c410321090c010b2006200241127641f001723a001c20062002413f71418001723a001f20062002410c76413f71418001723a001d20062002410676413f71418001723a001e410421090b20002802182101417f21022000411c6a280200220a410c6a210802400340200241016a220220034f0d0120012006411c6a20092008280200110100450d000c020b0b200641106a200010750d00200120042005200a410c6a28020022001101000d00417f21020340200241016a220220074f0d0220012006411c6a20092000110100450d000b0b200641206a240041010f0b200641206a240041000b6e000240024020002d000022004103714101460d0020004102470d012001280218418e9fc100410b2001411c6a28020028020c1101000f0b200128021841819fc100410d2001411c6a28020028020c1101000f0b200128021841f59ec100410c2001411c6a28020028020c1101000b2701017f230041106b22022400200241086a2001104620002002290308370200200241106a24000b130020004102360204200041a882c0003602000bd20403027f017e0a7f230041c0006b2203240041002104024002400240024002402002450d002002ad4202862205422088a70d022005a722064100480d02200610002207450d04200221080c010b41042107410021080b02400240200120024103746a22092001460d002002410374210a200941786a210b410021022007210603402006200120026a41046a280200360200200641046a2106200a200241086a2202470d000b200b20016b41037641016a21044101210c410021064100210a03402001280200210d0240024002402006200a22026b200141046a280200220b4f0d002002200b6a220a2002490d062006410174220e200a200a200e491b220e4100480d062006450d01200e1000220f450d07200f200c200e20062006200e4b1b10ce02210f200c1001200e2106200f210c0c020b2002200b6a210a0c010b200e1000220c450d05200e21060b200c20026a200d200b10ce021a200141086a22012009470d000c020b0b4101210c410021060b200341206a41186a22014200370300200341206a41106a22024200370300200341206a41086a220a420037030020034200370320200c20072004200341206a1005200341186a2001290300370300200341106a2002290300370300200341086a200a2903003703002003200329032037030002402006450d00200c10010b02402008450d00200710010b20002003290300370000200041186a200341186a290300370000200041106a200341106a290300370000200041086a200341086a290300370000200341c0006a24000f0b1018000b200e41011019000b200641041019000b2700200028020c200041106a2802001006200041146a3502001007200041186a350200100700000b9a0801107f230041c0006b22032400200341246a22042001360200200341346a2205200241146a2802002206360200200341033a0038200341086a41246a220720022802102201200641037422066a36020020034280808080800437030820034100360210200341003602182003200036022020032001360228200320013602302002280204220841037421092002280200210a024002400240024020022802082200450d00200041146a210120002002410c6a28020041246c6a210b200341206a210c200341386a210d200341306a210e200341186a210f200341286a211020092108200a2102024003402000200b460d032008450d05200c2802002002280200200241046a280200200428020028020c1101000d04200d20002d00203a00002003200028020836020c2003200028020c3602084100210602400240024002400240200028021822114101460d00024020114102460d0020114103460d05200141086a28020021120c020b201028020022112007280200460d022010201141086a36020020112802044105470d04201128020028020021120c010b200141086a2802002211200528020022124f0d02200e28020020114103746a22112802044105470d03201128020028020021120b410121060c020b0c010b419886c00020112012104a000b200341086a410c6a2012360200200341086a41086a20063602004100210602400240024002400240200028021022114101460d00024020114102460d0020114103460d05200128020021120c020b201028020022112007280200460d022010201141086a36020020112802044105470d04201128020028020021120c010b20012802002211200528020022124f0d02200e28020020114103746a22112802044105470d03201128020028020021120b410121060c020b0c010b419886c00020112012104a000b0240200341086a41146a2012360200200f20063602000240024020002802004101470d00200141706a2802002206200528020022124f0d02200e28020020064103746a21060c010b201028020022062007280200460d032010200641086a3602000b200041246a2100200241086a2102200141246a2101200841786a21082006280200200341086a200641046a280200110200450d010c050b0b41c086c00020062012104a000b41a886c000104d000b20084103742100200341206a2111200a210203402006450d012000450d0320112802002002280200200241046a280200200428020028020c1101000d02200641786a2106200041786a2100200241086a21022001280200210820012802042112200141086a21012008200341086a2012110200450d000c020b0b2002200a20096a460d01200341206a28020020022802002002280204200341246a28020028020c110100450d010b200341c0006a240041010f0b200341c0006a240041000b900101017f230041c0006b220024002000413336020c200041a8a1c100360208200041286a410c6a4106360200200041106a410c6a4102360200200041246a41023602002000410136022c2000419888c10036021020004102360214200041a0d2c2003602182000200041086a3602282000200041386a3602302000200041286a360220200041106a41a888c1001065000b1c002001280218418db5c10041052001411c6a28020028020c1101000b100020012000280200200028020410760b4a02017f017e230041206b2202240020012902002103200241146a2001290208370200200241d892c000360204200241b8d6c200360200200220003602082002200337020c20021060000be90401057f230041106b22022400200028020021000240024002400240024002400240024002400240024020014180014f0d00200028020822032000280204470d03200341016a22042003490d0820034101742205200420042005491b22044100480d082003450d0120002802002106200410002205450d092005200620042003200320044b1b10ce021a200610010c020b2002410036020c0240024020014180104f0d0020022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b0240200141ffff034b0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c010b2002200141127641f001723a000c20022001413f71418001723a000f20022001410c76413f71418001723a000d20022001410676413f71418001723a000e410421010b024020002802042205200028020822036b20014f0d00200320016a22042003490d0820054101742203200420042003491b22034100480d082005450d0420002802002106200310002204450d0a2004200620032005200520034b1b10ce021a200610010c050b200028020021040c050b200410002205450d070b20002005360200200041046a2004360200200041086a28020021030b200028020020036a20013a0000200041086a2200200028020041016a3602000c030b200310002204450d050b20002004360200200041046a2003360200200041086a28020021030b200041086a200320016a360200200420036a2002410c6a200110ce021a0b200241106a240041000f0b1018000b200441011019000b200341011019000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41a883c000200241086a10612101200241206a240020010bd20101047f024002400240024002400240200028020022002802042203200028020822046b20024f0d00200420026a22052004490d0420034101742204200520052004491b22044100480d042003450d0120002802002106200410002205450d052005200620042003200320044b1b10ce021a200610010c020b200028020021050c020b200410002205450d030b20002005360200200041046a2004360200200041086a28020021040b200041086a200420026a360200200520046a2001200210ce021a41000f0b1018000b200441011019000bd50201067f230041306b2202240041272103024002400240024002400240200028020022004190ce00490d00412721030340200241096a20036a2204417c6a200020004190ce006e220541f0b17f6c6a220641e4006e22074101744182a2c1006a2f00003b00002004417e6a20062007419c7f6c6a4101744182a2c1006a2f00003b00002003417c6a2103200041ffc1d72f4b21042005210020040d000b41e4002104200541e400480d010c020b41e40021042000220541e4004e0d010b2005220041094a0d010c020b200241096a2003417e6a22036a2005200520046e2200419c7f6c6a4101744182a2c1006a2f00003b0000200041094c0d010b200241096a2003417e6a22036a220520004101744182a2c1006a2f00003b00000c010b200241096a2003417f6a22036a2205200041306a3a00000b2001410141b8d6c20041002005412720036b105b2100200241306a240020000b890101017f230041306b220224002002200136020420022000360200200241206a410c6a4104360200200241086a410c6a41023602002002411c6a410236020020024104360224200241e883c0003602082002410236020c200241a0d2c200360210200220023602202002200241046a3602282002200241206a360218200241086a41f883c0001065000b890101017f230041306b220224002002200136020420022000360200200241206a410c6a4104360200200241086a410c6a41023602002002411c6a4102360200200241043602242002418884c0003602082002410236020c200241a0d2c200360210200220023602202002200241046a3602282002200241206a360218200241086a419884c0001065000baa0603057f027e017f02400240024002400240024002402002450d00200241796a4100200241074b1b210341002104034002400240024002400240200120046a22052d0000220641187441187522074100480d002005410371450d01200441016a22042002490d050c060b4280808080102108200641adaec1006a2d000022054104460d0120054103460d0220054102470d06200441016a220520024f0d084280808080802021094280808080102108200120056a2d000041c00171418001460d030c0b0b0240200420034f0d000340200120046a220541046a280200200528020072418081828478710d01200441086a22042003490d000b0b0240200420024f0d000340200120046a2c00004100480d01200441016a22042002490d000b0b20042002490d030c040b42002109200441016a220520024f0d07200120056a2d000021050240024020074170470d00200541f0006a41ff0171412f4d0d010b0240200541ff0171220641bf014b0d002007410f6a41ff017141024b0d0020054118744118754100480d010b2006418f014b0d0520074174470d05200541187441187541004e0d050b200441026a220520024f0d07200120056a2d000041c00171418001470d0542002108200441036a220520024f0d09200120056a2d000041c00171418001460d010c080b42002109200441016a220520024f0d06200120056a2d000021050240024020074160470d00200541607141ff017141a001460d010b0240200541ff0171220641bf014b220a0d002007411f6a41ff0171410b4b0d0020054118744118754100480d010b02402006419f014b0d002007416d470d0020054118744118754100480d010b200a0d04200741fe017141ee01470d04200541187441187541004e0d040b42002108200441026a220520024f0d08200120056a2d000041c00171418001470d040b200541016a22042002490d000b0b20002001360204200041086a2002360200200041003602000f0b4280808080802021090c040b428080808080c000210942808080801021080c030b420021090b420021080c010b428080808080e000210942808080801021080b200020092008842004ad84370204200041013602000bc50901067f230041f0006b220424002004200336020c20042002360208410121052001210602402001418102490d00410020016b21074180022108024003400240200820014f0d00200020086a2c000041bf7f4a0d020b2008417f6a21064100210520084101460d02200720086a21092006210820094101470d000c020b0b41002105200821060b200420063602142004200036021020044100410520051b36021c200441b8d6c20041adb0c10020051b360218024002400240024002400240024002400240200220014b22080d00200320014b0d00200220034b0d02024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200420023602202002450d0120022001460d01200141016a2109024003400240200220014f0d00200020026a22062c000041bf7f4a0d020b02402002417f6a210820024101460d0020092002462106200821022006450d010b0b200020086a2206200020016a2202470d040c050b200221082006200020016a2202460d040c030b20042002200320081b360228200441c8006a410c6a4101360200200441c8006a41146a4101360200200441306a410c6a4103360200200441306a41146a41033602002004410436024c200441a884c00036023020044103360234200441dcedc1003602382004200441286a3602482004200441106a3602502004200441186a3602582004200441c8006a360240200441306a41c084c0001065000b2000200222086a2206200020016a2202470d010c020b200441c8006a410c6a4104360200200441c8006a41146a4101360200200441e4006a4101360200200441306a410c6a4104360200200441306a41146a41043602002004410436024c200441d084c00036023020044104360234200441b4b0c1003602382004200441086a36024820042004410c6a3602502004200441106a3602582004200441186a3602602004200441c8006a360240200441306a41f084c0001065000b4101210141002109024020062c000022064100480d002004200641ff01713602240c050b200221010240200020086a220041016a2002460d00200041026a2101200041016a2d0000413f7121090b2006411f712100200641ff017141e001490d014100210520022107024020012002460d00200141016a210720012d0000413f7121050b20052009410674722101200641ff017141f001490d0241002106024020072002460d0020072d0000413f7121060b20014106742000411274418080f00071722006722202418080c400470d030b41a886c000104d000b200920004106747221020c010b20012000410c747221020b20042002360224410121012002418001490d00410221012002418010490d0041034104200241808004491b21010b200420083602282004200120086a36022c200441c8006a410c6a4107360200200441c8006a41146a4108360200200441e4006a4101360200200441ec006a4101360200200441306a410c6a4105360200200441306a41146a41053602002004410436024c2004418085c00036023020044105360234200441c4b1c1003602382004200441206a3602482004200441246a3602502004200441286a3602582004200441106a3602602004200441186a3602682004200441c8006a360240200441306a41a885c0001065000ba90b03037f017e057f4101210202402001280218220341272001411c6a28020028021022041102000d0041022102024002400240024002400240024002400240024002400240024002402000280200220041776a2201411e4b0d00024020010e1f000402020302020202020202020202020202020202020202020e020202020e000b41f40021000c0c0b200041dc00460d0b0b20001073450d02200041017267410276410773ad4280808080d0008421050c030b41f20021000c090b41ee0021000c080b0240024002400240200041ffff034b0d0020004180fe0371410876210641caa3c100210241002107200041ff0171210802400340200241026a2109200720022d000122016a210a0240024020022d000022022006470d00200a2007490d09200a41b0024f0d0a2007419aa4c1006a210203402001450d022001417f6a210120022d00002107200241016a210220072008470d000c080b0b200220064b0d02200a2107200921022009419aa4c100470d010c020b200a2107200921022009419aa4c100470d000b0b200041ffff0371210841c9a6c100210141caa6c10021024101210703400240024020012d0000220a4118744118752209417f4c0d00200221012008200a6b220841004e0d010c040b20024185a9c100460d0b200241016a21012008200941ff007141087420022d0000726b22084100480d030b200141016a21022007410173210720014185a9c100470d000c020b0b200041ffff074b0d0120004180fe037141087621064185a9c100210241002107200041ff0171210802400340200241026a2109200720022d000122016a210a0240024020022d000022022006470d00200a2007490d0a200a419f014f0d0b200741c7a9c1006a210203402001450d022001417f6a210120022d00002107200241016a210220072008470d000c070b0b200220064b0d02200a210720092102200941c7a9c100470d010c020b200a210720092102200941c7a9c100470d000b0b200041ffff0371210841e5aac100210141e6aac10021024101210703400240024020012d0000220a4118744118752209417f4c0d00200221012008200a6b220841004e0d010c030b200241e2adc100460d0b200241016a21012008200941ff007141087420022d0000726b22084100480d020b200141016a210220074101732107200141e2adc100470d000b0b410121022007410171450d010c090b20004190fc476a4190fc0b490d00200041e28b746a41e28d2c490d002000419fa8746a419f18490d00200041dee2746a410e490d00200041feffff0071419ef00a460d00200041a9b2756a4129490d00200041cb91756a410a4d0d00410121020c080b200041017267410276410773ad4280808080d0008421050b410321020c070b2007200a106b000b200a41af02106a000b2007200a106b000b200a419e01106a000b41a886c000104d000b41a886c000104d000b0b0240024003400240200241037122014103460d00024020014102460d0020014101470d0441002102200320002004110200450d020c030b41012102200341dc002004110200450d010c020b2005422088a7410771417f6a220141044b0d020240024002400240024020010e050004020301000b200542ffffffff8f60832105200341fd002004110200450d040c050b200542ffffffff8f60834280808080c000842105200341dc002004110200450d030c040b200542ffffffff8f6083428080808020842105200341fb002004110200450d020c030b200542ffffffff8f6083428080808030842105200341f5002004110200450d010c020b20002005a72207410274411c7176410f712201413072200141d7006a2001410a491b210102402007450d002005427f7c42ffffffff0f83200542808080807083842105200320012004110200450d010c020b200542ffffffff8f6083428080808010842105200320012004110200450d000b0b41010f0b20034127200411020021020b20020b950101017f230041306b22022400200241086a410c6a41093602002002410936020c200220003602082002200041046a3602102001411c6a280200210020012802182101200241186a410c6a41023602002002412c6a41023602002002410236021c2002418886c000360218200241a0d2c2003602202002200241086a36022820012000200241186a10612101200241306a240020010be00401067f23004180016b220224000240024002400240024002400240024002400240200128020022034110710d002000280200210020034120710d014127210320004190ce00490d02412721030340200220036a2204417c6a200020004190ce006e220541f0b17f6c6a220641e4006e22074101744182a2c1006a2f00003b00002004417e6a20062007419c7f6c6a4101744182a2c1006a2f00003b00002003417c6a2103200041ffc1d72f4b21042005210020040d000b41e4002104200541e400480d030c060b20002802002103410021000340200220006a41ff006a2003410f712205413072200541d7006a2005410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d03200141014180a2c1004102200220006a4180016a410020006b105b210020024180016a240020000f0b410021030340200220036a41ff006a2000410f712205413072200541376a2005410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d03200141014180a2c1004102200220036a4180016a410020036b105b210020024180016a240020000f0b41e40021042000220541e4004e0d030b2005220041094a0d030c040b2003418001106b000b2000418001106b000b20022003417e6a22036a2005200520046e2200419c7f6c6a4101744182a2c1006a2f00003b0000200041094c0d010b20022003417e6a22036a220520004101744182a2c1006a2f00003b00000c010b20022003417f6a22036a2205200041306a3a00000b2001410141b8d6c20041002005412720036b105b210020024180016a240020000b1c00200128021841aeb4c100410b2001411c6a28020028020c1101000b1c00200128021841b9b4c100410e2001411c6a28020028020c1101000b960201017f024002400240024002400240024020004180104f0d00200041037641f8ffffff017141d086c0006a21010c010b02402000418080044f0d00200041067641606a220141e0074f0d02200141e888c0006a2d0000220141c9004b0d0320014103744198b5c1006a21010c010b2000410c7641706a22014180024f0d03200141c890c0006a2d00004106742000410676413f7172220141ff034b0d04200141e8b9c1006a2d0000220141364b0d05200141037441e8bdc1006a21010b200129030042012000413f71ad86834200520f0b41b885c000200141e007104a000b41c885c000200141ca00104a000b41d885c0002001418002104a000b41e885c0002001418004104a000b41f885c00020014137104a000bd50201067f230041306b2202240041272103024002400240024002400240200028020022004190ce00490d00412721030340200241096a20036a2204417c6a200020004190ce006e220541f0b17f6c6a220641e4006e22074101744182a2c1006a2f00003b00002004417e6a20062007419c7f6c6a4101744182a2c1006a2f00003b00002003417c6a2103200041ffc1d72f4b21042005210020040d000b41e4002104200541e400480d010c020b41e40021042000220541e4004e0d010b2005220041094a0d010c020b200241096a2003417e6a22036a2005200520046e2200419c7f6c6a4101744182a2c1006a2f00003b0000200041094c0d010b200241096a2003417e6a22036a220520004101744182a2c1006a2f00003b00000c010b200241096a2003417f6a22036a2205200041306a3a00000b2001410141b8d6c20041002005412720036b105b2100200241306a240020000be80201057f230041106b2202240002400240024020002802002802002203418080c400460d002001411c6a2802002104200128021821052002410036020c02400240200341ff004b0d00200220033a000c410121060c010b0240200341ff0f4b0d0020022003413f71418001723a000d20022003410676411f7141c001723a000c410221060c010b0240200341ffff034b0d0020022003413f71418001723a000e20022003410676413f71418001723a000d20022003410c76410f7141e001723a000c410321060c010b2002200341127641f001723a000c20022003413f71418001723a000f20022003410c76413f71418001723a000d20022003410676413f71418001723a000e410421060b4101210320052002410c6a2006200428020c1101000d010b20002802042d0000450d0120012802182000280208220028020020002802042001411c6a28020028020c11010021030b200241106a240020030f0b200241106a240041000be40a010c7f230041106b220324002000280210210402400240024002400240024002400240024002400240024002400240200028020822054101470d0020040d010c080b2004450d010b2002450d01200120026a2106200041146a2802002107200141016a21044100210820012c0000220941004e0d042006210a024020024101460d00200141016a2d0000413f712108200141026a2204210a0b200941ff017141e001490d04200a2006460d02200a2d0000413f71210b200a41016a2204210a0c030b2000280218200120022000411c6a28020028020c1101002104200341106a240020040f0b4100210220050d040c050b4100210b2006210a0b200941ff017141f001490d002009411f71210c200b200841067472210802400240200a2006460d00200a41016a2104200a2d0000413f7121090c010b410021090b2008410674200c411274418080f0007172200972418080c400460d010b02400240024002402007450d00200420016b2109034020092108200620042209460d05200941016a2104024020092c0000220a41004e0d000240024020042006460d0020042d0000413f71210d200941026a220b2104200a41ff0171220c41e001490d020c010b4100210d2006210b200a41ff0171220c41e001490d010b02400240200b2006460d00200b2d0000413f71210e200b41016a2204210b200c41f0014f0d010c020b4100210e2006210b200c41f001490d010b200a411f71210a200e200d41067472210c02400240200b2006460d00200b41016a2104200b2d0000413f71210b0c010b4100210b0b200c410674200a411274418080f0007172200b72418080c400460d060b200820096b20046a21092007417f6a22070d000b2008450d020c010b410021084100450d010b20082002460d0041002104200820024f0d01200120086a2c00004140480d010b200121040b2008200220041b21022004200120041b21010b2005450d010b4100210902402002450d0020022108200121040340200920042d000041c00171418001466a2109200441016a21042008417f6a22080d000b0b200220096b2000410c6a28020022074f0d01410021064100210902402002450d004100210920022108200121040340200920042d000041c00171418001466a2109200441016a21042008417f6a22080d000b0b200920026b20076a2104410020002d0030220920094103461b41037122094102460d022009450d03200421070c040b2000280218200120022000411c6a28020028020c1101002104200341106a240020040f0b2000280218200120022000411c6a28020028020c1101002104200341106a240020040f0b20044101762107200441016a41017621060c010b41002107200421060b2003410036020c024002402000280204220441ff004b0d00200320043a000c410121080c010b0240200441ff0f4b0d0020032004413f71418001723a000d20032004410676411f7141c001723a000c410221080c010b0240200441ffff034b0d0020032004413f71418001723a000e20032004410676413f71418001723a000d20032004410c76410f7141e001723a000c410321080c010b2003200441127641f001723a000c20032004413f71418001723a000f20032004410c76413f71418001723a000d20032004410676413f71418001723a000e410421080b20002802182109417f21042000411c6a280200220a410c6a21000240024002400340200441016a220420074f0d0120092003410c6a20082000280200110100450d000c020b0b200920012002200a410c6a2802002200110100450d010b200341106a240041010f0b417f210402400340200441016a220420064f0d0120092003410c6a20082000110100450d000b200341106a240041010f0b200341106a240041000b2601017f20002802002201280200200128020420002802042802002000280208280200106d000b02000b0c004291ea88ff9bc4a9875d0bf90c01107f230041f0076b220424000240200128020422052f01062206410a4b0d002005200128020c22074105746a220541286a200541086a2208200620076b41057410cf021a200541206a200241186a290000370000200541186a200241106a290000370000200541106a200241086a29000037000020082002290000370000200141046a22022802002206200128020c220741306c6a22054198036a200541e8026a220820062f010620076b41306c10cf021a20054190036a200341286a29030037030020054188036a200341206a29030037030020054180036a200341186a290300370300200541f8026a200341106a290300370300200541f0026a200341086a290300370300200820032903003703002002280200220520052f010641016a3b0106200128020c21032004418b016a200141086a280000360000200041003a0000200041106a200336000020002005200341306c6a41e8026a36026820042001290000370083012000200429008001370001200041086a20044187016a290000370000200441f0076a24000f0b200128020821092001280200210a024041f80610002206450d00200641003b010620064100360200200641086a20044180016a41f00610ce02210b200441e0006a41186a220c200541e0016a290200370300200441e0006a41106a220d200541d8016a290200370300200441e0006a41086a220e200541d0016a29020037030020044180016a41086a220f20054190056a29030037030020044180016a41106a221020054198056a29030037030020044180016a41186a2211200541a0056a29030037030020044180016a41206a2212200541a8056a29030037030020044180016a41286a2213200541b0056a2903003703002004200541c8016a290200370360200420054188056a29030037038001200b200541e8016a200541066a22072f010041796a220841057410ce02210b200641e8026a200541b8056a200841306c10ce021a200741063b0100200620083b0106200441086a41186a200c290300370300200441086a41106a200d290300370300200441086a41086a200e29030037030020042004290360370308200441286a41286a2013290300370300200441286a41206a2012290300370300200441286a41186a2011290300370300200441286a41106a2010290300370300200441286a41086a200f29030037030020042004290380013703282004410036025c2004200636025802400240200128020c220141064b0d00200520014105746a220641286a200641086a220820072f010020016b41057410cf021a200641206a200241186a290000370000200641186a200241106a290000370000200641106a200241086a290000370000200820022900003700002005200141306c6a22024198036a200241e8026a220620072f010020016b41306c10cf021a20024190036a200341286a29030037030020024188036a200341206a29030037030020024180036a200341186a290300370300200241f8026a200341106a290300370300200241f0026a200341086a29030037030020062003290300370300200720072f010041016a3b01000c010b200b20014105746a41c07e6a200b200141796a220c4105746a2207200641066a22082f0100200c6b41057410cf021a200741186a200241186a290000370000200741106a200241106a290000370000200741086a200241086a290000370000200720022900003700002006200141306c6a220141c8006a200141186a220620082f0100200c6b41306c10cf021a200141c0006a200341286a290300370300200141386a200341206a290300370300200141306a200341186a290300370300200141286a200341106a290300370300200141206a200341086a29030037030020062003290300370300200820082f010041016a3b01000b200041013a000020002004290308370001200041246a200a360000200041286a20053600002000412c6a2009360000200041306a2004290358370300200041386a2004290328370300200041096a200441086a41086a290300370000200041116a200441086a41106a290300370000200041196a200441086a41186a290300370000200041d8006a200441c8006a290300370300200041d0006a200441286a41186a290300370300200041c8006a200441286a41106a290300370300200041c0006a200441286a41086a290300370300200041e0006a200441286a41286a29030037030020002006360268200441f0076a24000f0b41f80641081019000bc607010c7f230041c0026b220424000240200128020422052f01062206410a4b0d002005200128020c2207410c6c6a220541146a200541086a2208200620076b410c6c10cf021a200541106a200241086a28020036020020082002290200370200200141046a22062802002202200128020c2207410c6c6a22054198016a2005418c016a220820022f010620076b410c6c10cf021a20054194016a200341086a2802003602002008200329020037020020004100360200200020012902003702042000410c6a200141086a280200360200200041106a200128020c22053602002006280200220120012f010641016a3b0106200020012005410c6c6a418c016a360230200441c0026a24000f0b200128020821092001280200210a024041900210002206450d00200641003b010620064100360200200641086a200441386a41880210ce022108200441386a41086a220b200541d8006a280200360200200441286a41086a220c200541dc016a2802003602002004200541d0006a2902003703382004200541d4016a2902003703282008200541dc006a200541066a22072f010041796a220d410c6c220e10ce02210f2006418c016a200541e0016a200e10ce02210e200741063b01002006200d3b0106200441086a200b28020036020020042004290338370300200441106a41086a200c28020036020020042004290328370310200441003602242004200636022002400240200128020c220841064b0d00200541086a22062008410c6c2201410c6a220b6a200620016a220620072f010020086b410c6c10cf021a200641086a200241086a280200360200200620022902003702002005418c016a2206200b6a200620016a220120072f010020086b410c6c10cf021a200141086a200341086a28020036020020012003290200370200200720072f010041016a3b01000c010b200f2008410c6c220141b87f6a22076a200f200141ac7f6a220b6a2201200641066a22062f0100200841796a22086b410c6c10cf021a200141086a200241086a28020036020020012002290200370200200e20076a200e200b6a220120062f010020086b410c6c10cf021a200141086a200341086a28020036020020012003290200370200200620062f010041016a3b01000b200041013602002000200a36020420002001360230200041086a20053602002000410c6a2009360200200041106a20042903003702002000411c6a2004290310370200200041286a2004290320370200200041186a200441086a280200360200200041246a200441106a41086a280200360200200441c0026a24000f0b41900241041019000bc30201057f200041046a22042802002205200028020c2206410c6c6a220741146a200741086a220820052f010620066b410c6c10cf021a200741106a200141086a280200360200200820012902003702002005200641146c6a220141a0016a2001418c016a220720052f010620066b41146c10cf021a2001419c016a200241106a28020036020020014194016a200241086a29020037020020072002290200370200200520052f010641016a3b01062004280200220241e8026a2206200028020c220541027422016a41086a2006200541016a22054102746a220020022f010620056b41027410cf021a200020033602000240200520022f010622074b0d00200141ec026a21020340200541016a22002005490d012004280200220620026a280200220120053b010420012006360200200241046a210220002105200020074d0d000b0b0bbe07010b7f23004190036b220624000240200128020422072f0106410a4b0d0020064180036a41086a200241086a2802003602002006200229020037038003200641c8006a41086a200341086a28020036020020062003290200370348200120064180036a200641c8006a2004107e20004100360200200020012902003702042000410c6a200141086a29020037020020064190036a24000f0b2001280208210820012802002109024041c0021000220a450d004100210b200a41003b0106200a4100360200200a41086a200641c8006a41b80210ce02210c20064180036a41086a200741d8006a2802003602002006200741d0006a29020037038003200641c8006a41086a200741dc016a2802003602002006200741d4016a290200370348200c200741dc006a200741066a220d2f0100220e41796a220f410c6c221010ce021a200a418c016a200741e0016a201010ce021a419002210c200a4190026a200741ac026a200e417a6a220e41027410ce021a200d41063b0100200a200f3b0106200620093602142006200a36021002400240200e450d0003402006280210220a200c6a280200220d200b3b0104200d200a360200200c41046a210c200b41016a220b200e490d000b2006280214210c2006280210210a0c010b2009210c0b200641386a41086a220b20064180036a41086a220d280200360200200641286a41086a220e200641c8006a41086a280200360200200620062903800337033820062006290348370328200641086a200b28020036020020062006290338370300200641106a41086a200e280200360200200620062903283703102006200c3602242006200a36022002400240200128020c220e41064b0d002006200736024c20062009360248200620083602502006200e360254200b200241086a28020036020020062002290200370338200d200341086a2802003602002006200329020037038003200641c8006a200641386a20064180036a2004107e0c010b2006200a36024c2006200c3602482006200e41796a3602542006200641206a360250200b200241086a28020036020020062002290200370338200d200341086a2802003602002006200329020037038003200641c8006a200641386a20064180036a2004107e0b2000200936020420004101360200200041086a20073602002000410c6a2008360200200041106a20062903003702002000411c6a2006290310370200200041286a2006290320370200200041186a200641086a280200360200200041246a200641106a41086a28020036020020064190036a24000f0b41c00241041019000bb40201067f200041046a2204280200220541086a2206200028020c2207410c6c2208410c6a22096a200620086a220620052f010620076b410c6c10cf021a200641086a200141086a280200360200200620012902003702002005418c016a220120096a200120086a220120052f010620076b410c6c10cf021a200141086a200241086a28020036020020012002290200370200200520052f010641016a3b0106200428020022024190026a2201200028020c220541027422076a41086a2001200541016a22054102746a220020022f010620056b41027410cf021a200020033602000240200520022f010622084b0d0020074194026a21000340200541016a22022005490d012004280200220120006a280200220720053b010420072001360200200041046a210020022105200220084d0d000b0b0bce0d02167f017e230041d0086b220624000240200128020422072f0106410a4b0d0020064180016a41186a200241186a29000037030020064180016a41106a200241106a29000037030020064180016a41086a200241086a2900003703002006200229000037038001200641b0016a41286a200341286a290300370300200641b0016a41206a200341206a290300370300200641b0016a41186a200341186a290300370300200641b0016a41106a200341106a290300370300200641b0016a41086a200341086a290300370300200620032903003703b001200120064180016a200641b0016a2004108001200041003a0000200041046a20012902003702002000410c6a200141086a290200370200200641d0086a24000f0b2001280208210820012802002109024041a8071000220a450d004100210b200a41003b0106200a4100360200200a41086a200641b0016a41a00710ce02210c200641286a41186a200741e0016a290000370300200641286a41106a200741d8016a290000370300200641286a41086a200741d0016a2900003703002006200741c8016a290000370328200641d8016a200741b0056a290300370300200641d0016a200741a8056a290300370300200641b0016a41186a200741a0056a290300370300200641b0016a41106a20074198056a290300370300200641b0016a41086a20074190056a290300370300200620074188056a2903003703b001200c200741e8016a200741066a220d2f0100220e41796a220f41057410ce021a200a41e8026a200741b8056a200f41306c10ce021a41f806210c200a41f8066a20074194076a200e417a6a220e41027410ce021a200d41063b0100200a200f3b01062006200936020c2006200a36020802400240200e450d0003402006280208220a200c6a280200220f200b3b0104200f200a360200200c41046a210c200b41016a220b200e490d000b200628020c210e2006280208210a0c010b2009210e0b20064180016a41286a220d200641b0016a41286a221029030037030020064180016a41206a2211200641b0016a41206a221229030037030020064180016a41186a220b200641b0016a41186a221329030037030020064180016a41106a220c200641b0016a41106a221429030037030020064180016a41086a220f200641b0016a41086a2215290300370300200641e0006a41086a2216200641286a41086a2217290300370300200641e0006a41106a2218200641286a41106a2219290300370300200641e0006a41186a221a200641286a41186a221b290300370300200620062903b0013703800120062006290328370360200641086a41186a201a290300370300200641086a41106a2018290300370300200641086a41086a201629030037030020062006290360370308200641286a41286a200d290300370300200641286a41206a2011290300370300201b200b2903003703002019200c2903003703002017200f29030037030020062006290380013703282006200e36025c2006200a36025802400240200128020c220141064b0d002006200736026420062009360260200620083602682006200136026c200b200241186a290000370300200c200241106a290000370300200f200241086a29000037030020062002290000370380012010200341286a2903003703002012200341206a2903003703002013200341186a2903003703002014200341106a2903003703002015200341086a290300370300200620032903003703b001200641e0006a20064180016a200641b0016a20041080010c010b2006200a3602642006200e3602602006200141796a36026c2006200641d8006a360268200b200241186a290000370300200c200241106a290000370300200f200241086a29000037030020062002290000370380012010200341286a2903003703002012200341206a2903003703002013200341186a2903003703002014200341106a2903003703002015200341086a290300370300200620032903003703b001200641e0006a20064180016a200641b0016a20041080010b20002006290308370001200041246a2009360200200041286a20073602002000412c6a2008360200200041386a2006290328370300200041096a200641086a41086a290300370000200041116a200641086a41106a290300370000200041196a200641086a41186a290300370000200041c0006a200641286a41086a290300370300200041c8006a200641286a41106a290300370300200041d0006a200641286a41186a290300370300200041d8006a200641c8006a290300370300200041e0006a200641286a41286a2903003703002006290358211c200041013a0000200041306a201c370200200641d0086a24000f0b41a80741081019000b960301057f200041046a22042802002205200028020c22064105746a220741286a200741086a220820052f010620066b41057410cf021a200741206a200141186a290000370000200741186a200141106a290000370000200741106a200141086a290000370000200820012900003700002005200641306c6a22014198036a200141e8026a220720052f010620066b41306c10cf021a20014190036a200241286a29030037030020014188036a200241206a29030037030020014180036a200241186a290300370300200141f8026a200241106a290300370300200141f0026a200241086a29030037030020072002290300370300200520052f010641016a3b01062004280200220141f8066a2205200028020c220241027422076a41086a2005200241016a22024102746a220520012f010620026b41027410cf021a200520033602000240200220012f010622064b0d00200741fc066a21010340200241016a22052002490d012004280200220720016a280200220020023b010420002007360200200141046a210120052102200520064d0d000b0b0bc504020d7f017e230041c0006b22032400200128020022042001280208220541047422066a2107200128020421080240024002400240024002402005450d00200341306a41017221094100210a200341306a41026a210b200341206a410172220c41076a210d0340200b2004200a6a220141036a2d00003a00002003200141016a2f00003b013020012d0000220e41ac01460d022003410c6a41026a220f200b2d00003a0000200320032f01303b010c200141046a2902002110200341306a410c6a2001410c6a280200360200200920032f010c3b0000200941026a200f2d00003a00002003200e3a003020032010370234200341206a200341306a20021082012003200c2900003703102003200d29000037001720032d0020220e411a470d052006200a41106a220a470d000c040b0b200422012007470d010c020b200141106a22012007460d010b03400240024020012d0000220a4109460d00200a41ac01470d010c030b200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a22012007470d000b0b02402008450d00200410010b2000411a3a00000c010b200020032903103700012000200e3a0000200041086a20032900173700000240200541047441706a200a460d00200141186a2101034002400240200141786a220a2d0000220b4109460d00200b41ac01470d010c030b200128020041ffffffff0371450d002001417c6a28020010010b200141106a2101200a41106a2007470d000b0b2008450d0020041001200341c0006a24000f0b200341c0006a24000bdc4903057f017e027f230041106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220441aa014b0d00024020040eab0100020304057576777806070879090a0b7a0c0d0e0f1011127b7c13147d7e7f15161780011881018201191a1b1c83011d1e1f840120212223850186012487018801252689018a012728292a2b2c8b018c012d8d018e018f012e90012f910130313233920193013494019501960135363738393a97013b3c3d980199019a013e3f409b0141424344454647489c01499d014a9e019f014ba001a1014c4d4e4fa201505152a3015354a401a50155565758595a5b5ca601a7015da8015e5fa901aa016061ab0162636465666768696a6b6c6d6e6f7071727374000b200341013a0008200241046a200341086a410110290cab010b200341003a0008200241046a200341086a410110290caa010b20012d00012104200341023a0008200241046a2202200341086a41011029200342fffdf7e78f182004410374ad42f8018388a72204413f7141c00072200420044118744118754100481b3a00082002200341086a410110290ca9010b20012d00012104200341033a0008200241046a2202200341086a41011029200342fffdf7e78f182004410374ad42f8018388a72204413f7141c00072200420044118744118754100481b3a00082002200341086a410110290ca8010b20012d00012104200341043a0008200241046a2202200341086a41011029200342fffdf7e78f182004410374ad42f8018388a72204413f7141c00072200420044118744118754100481b3a00082002200341086a410110290ca7010b200341053a0008200241046a200341086a410110290ca6010b2003410f3a0008200241046a200341086a410110290ca5010b200141046a2802002104200341103a0008200241046a2205200341086a41011029200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110292002210420020d000ca5010b0b200141046a280200210420012d00012106200341113a0008200241046a2205200341086a41011029200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110292002210420020d000b200320063a00082005200341086a410110290ca3010b2003411b3a0008200241046a200341086a410110290ca2010b200141046a2802002104200341203a0008200241046a2205200341086a41011029200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110292002210420020d000ca2010b0b200141046a2802002104200341213a0008200241046a2205200341086a41011029200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110292002210420020d000ca1010b0b200141046a2802002104200341233a0008200241046a2205200341086a41011029200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110292002210420020d000ca0010b0b200141046a2802002104200341243a0008200241046a2205200341086a41011029200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110292002210420020d000c9f010b0b200141086a2802002104200141046a2802002105200341283a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c9e010b0b200141086a2802002104200141046a2802002105200341293a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c9d010b0b200141086a2802002104200141046a28020021052003412a3a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c9c010b0b200141086a2802002104200141046a28020021052003412b3a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c9b010b0b200141086a2802002104200141046a28020021052003412c3a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c9a010b0b200141086a2802002104200141046a28020021052003412f3a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c99010b0b200141086a2802002104200141046a2802002105200341303a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c98010b0b200141086a2802002104200141046a2802002105200341343a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c97010b0b200141086a2802002104200141046a2802002105200341353a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c96010b0b200141086a2802002104200141046a2802002105200341363a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c95010b0b200141086a2802002104200141046a2802002105200341383a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c94010b0b200141086a2802002104200141046a28020021052003413b3a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c93010b0b200141086a2802002104200141046a28020021052003413c3a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c92010b0b200141086a2802002104200141046a28020021052003413d3a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c91010b0b200141086a2802002104200141046a28020021052003413e3a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c90010b0b20012d00012104200341c0003a0008200241046a2202200341086a41011029200320043a00082002200341086a410110290c8e010b200141046a2802002106200341c1003a0008200241046a2207200341086a410110292003200641ff00713a0008024020064107752204200641c00071220272452004417f4720024572734101470d00034020032006418001723a00082007200341086a410110292003200441ff00713a0008200441c000712102200421062004410775220521042005200272452005417f4720024572470d000b0b2007200341086a410110290c8d010b200141086a2903002108200341c2003a0008200241046a2205200341086a4101102920032008a7220441ff00713a000802402008420787220850200441c00071452202712008427f52200272734101470d00034020032004418001723a00082005200341086a4101102920032008a7220441ff00713a00082008420787220850200441c00071452202712008427f52200272470d000b0b2005200341086a410110290c8c010b200141086a2903002108200341c4003a0008200241046a2204200341086a41011029200320083703082004200341086a410810290c8b010b200341c5003a0008200241046a200341086a410110290c8a010b200341c6003a0008200241046a200341086a410110290c89010b200341c7003a0008200241046a200341086a410110290c88010b200341ca003a0008200241046a200341086a410110290c87010b200341cd003a0008200241046a200341086a410110290c86010b200341ce003a0008200241046a200341086a410110290c85010b200341d1003a0008200241046a200341086a410110290c84010b200341d2003a0008200241046a200341086a410110290c83010b200341d3003a0008200241046a200341086a410110290c82010b200341d4003a0008200241046a200341086a410110290c81010b200341d5003a0008200241046a200341086a410110290c80010b200341d6003a0008200241046a200341086a410110290c7f0b200341d9003a0008200241046a200341086a410110290c7e0b200341dd003a0008200241046a200341086a410110290c7d0b200341df003a0008200241046a200341086a410110290c7c0b200341e1003a0008200241046a200341086a410110290c7b0b200341e2003a0008200241046a200341086a410110290c7a0b200341e3003a0008200241046a200341086a410110290c790b200341e4003a0008200241046a200341086a410110290c780b200341e7003a0008200241046a200341086a410110290c770b200341eb003a0008200241046a200341086a410110290c760b200341ec003a0008200241046a200341086a410110290c750b200341ed003a0008200241046a200341086a410110290c740b200341ee003a0008200241046a200341086a410110290c730b200341ef003a0008200241046a200341086a410110290c720b200341f0003a0008200241046a200341086a410110290c710b200341f2003a0008200241046a200341086a410110290c700b200341f3003a0008200241046a200341086a410110290c6f0b200341f4003a0008200241046a200341086a410110290c6e0b200341f8003a0008200241046a200341086a410110290c6d0b200341f9003a0008200241046a200341086a410110290c6c0b200341fa003a0008200241046a200341086a410110290c6b0b200341fc003a0008200241046a200341086a410110290c6a0b200341fd003a0008200241046a200341086a410110290c690b200341fe003a0008200241046a200341086a410110290c680b200341ff003a0008200241046a200341086a410110290c670b20034180013a0008200241046a200341086a410110290c660b20034181013a0008200241046a200341086a410110290c650b20034182013a0008200241046a200341086a410110290c640b20034183013a0008200241046a200341086a410110290c630b20034185013a0008200241046a200341086a410110290c620b20034187013a0008200241046a200341086a410110290c610b2003418a013a0008200241046a200341086a410110290c600b2003418d013a0008200241046a200341086a410110290c5f0b2003418e013a0008200241046a200341086a410110290c5e0b2003418f013a0008200241046a200341086a410110290c5d0b20034190013a0008200241046a200341086a410110290c5c0b20034192013a0008200241046a200341086a410110290c5b0b20034193013a0008200241046a200341086a410110290c5a0b20034194013a0008200241046a200341086a410110290c590b20034196013a0008200241046a200341086a410110290c580b20034197013a0008200241046a200341086a410110290c570b2003419a013a0008200241046a200341086a410110290c560b2003419b013a0008200241046a200341086a410110290c550b2003419c013a0008200241046a200341086a410110290c540b2003419d013a0008200241046a200341086a410110290c530b2003419e013a0008200241046a200341086a410110290c520b2003419f013a0008200241046a200341086a410110290c510b200341a0013a0008200241046a200341086a410110290c500b200341a1013a0008200241046a200341086a410110290c4f0b200341a4013a0008200241046a200341086a410110290c4e0b200341a6013a0008200241046a200341086a410110290c4d0b200341a7013a0008200241046a200341086a410110290c4c0b200341aa013a0008200241046a200341086a410110290c4b0b200341ab013a0008200241046a200341086a410110290c4a0b200341ad013a0008200241046a200341086a410110290c490b200341ae013a0008200241046a200341086a410110290c480b200341af013a0008200241046a200341086a410110290c470b200341b0013a0008200241046a200341086a410110290c460b200341b1013a0008200241046a200341086a410110290c450b200341b2013a0008200241046a200341086a410110290c440b200341b3013a0008200241046a200341086a410110290c430b200341b4013a0008200241046a200341086a410110290c420b200341b5013a0008200241046a200341086a410110290c410b200341b6013a0008200241046a200341086a410110290c400b200341b7013a0008200241046a200341086a410110290c3f0b200341b8013a0008200241046a200341086a410110290c3e0b200341b9013a0008200241046a200341086a410110290c3d0b200341ba013a0008200241046a200341086a410110290c3c0b200341bb013a0008200241046a200341086a410110290c3b0b200341bc013a0008200241046a200341086a410110290c3a0b200341bd013a0008200241046a200341086a410110290c390b200341be013a0008200241046a200341086a410110290c380b200341bf013a0008200241046a200341086a410110290c370b2003410b3a0008200241046a200341086a410110290c360b200141046a28020021042003410c3a0008200241046a2205200341086a41011029200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110292002210420020d000c360b0b200141046a28020021042003410d3a0008200241046a2205200341086a41011029200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110292002210420020d000c350b0b2001410c6a2802002105200141086a2802002109200141046a280200210a2003410e3a0008200241046a2202200341086a41011029200341003a00082009210103402003200141800172200141ff0071200141077622041b3a00082002200341086a410110292004210120040d000b02402009450d00200a20094102746a2107200a2106034020062802002101200341003a000803402003200141800172200141ff0071200141077622041b3a00082002200341086a410110292004210120040d000b200641046a22062007470d000b0b200341003a000803402003200541800172200541ff0071200541077622011b3a00082002200341086a410110292001210520010d000b0240200941ffffffff0371450d00200a10010b2000411a3a0000200341106a24000f0b2003411a3a0008200241046a200341086a410110290c320b200141046a2802002104200341223a0008200241046a2205200341086a41011029200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110292002210420020d000c320b0b200141086a2802002104200141046a28020021052003412d3a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c310b0b200141086a2802002104200141046a28020021052003412e3a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c300b0b200141086a2802002104200141046a2802002105200341313a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c2f0b0b200141086a2802002104200141046a2802002105200341323a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c2e0b0b200141086a2802002104200141046a2802002105200341333a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c2d0b0b200141086a2802002104200141046a2802002105200341373a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c2c0b0b200141086a2802002104200141046a2802002105200341393a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c2b0b0b200141086a2802002104200141046a28020021052003413a3a0008200241046a2206200341086a41011029200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110292002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110292002210420020d000c2a0b0b20012d000121042003413f3a0008200241046a2202200341086a41011029200320043a00082002200341086a410110290c280b200141046a2802002104200341c3003a0008200241046a2202200341086a41011029200320043602082002200341086a410410290c270b200341c8003a0008200241046a200341086a410110290c260b200341c9003a0008200241046a200341086a410110290c250b200341cb003a0008200241046a200341086a410110290c240b200341cc003a0008200241046a200341086a410110290c230b200341cf003a0008200241046a200341086a410110290c220b200341d0003a0008200241046a200341086a410110290c210b200341d7003a0008200241046a200341086a410110290c200b200341d8003a0008200241046a200341086a410110290c1f0b200341da003a0008200241046a200341086a410110290c1e0b200341db003a0008200241046a200341086a410110290c1d0b200341dc003a0008200241046a200341086a410110290c1c0b200341de003a0008200241046a200341086a410110290c1b0b200341e0003a0008200241046a200341086a410110290c1a0b200341e5003a0008200241046a200341086a410110290c190b200341e6003a0008200241046a200341086a410110290c180b200341e8003a0008200241046a200341086a410110290c170b200341e9003a0008200241046a200341086a410110290c160b200341ea003a0008200241046a200341086a410110290c150b200341f1003a0008200241046a200341086a410110290c140b200341f5003a0008200241046a200341086a410110290c130b200341f6003a0008200241046a200341086a410110290c120b200341f7003a0008200241046a200341086a410110290c110b200341fb003a0008200241046a200341086a410110290c100b20034184013a0008200241046a200341086a410110290c0f0b20034186013a0008200241046a200341086a410110290c0e0b20034188013a0008200241046a200341086a410110290c0d0b20034189013a0008200241046a200341086a410110290c0c0b2003418b013a0008200241046a200341086a410110290c0b0b2003418c013a0008200241046a200341086a410110290c0a0b20034191013a0008200241046a200341086a410110290c090b20034195013a0008200241046a200341086a410110290c080b20034198013a0008200241046a200341086a410110290c070b20034199013a0008200241046a200341086a410110290c060b200341a2013a0008200241046a200341086a410110290c050b200341a3013a0008200241046a200341086a410110290c040b200341a5013a0008200241046a200341086a410110290c030b200341a8013a0008200241046a200341086a410110290c020b200341a9013a0008200241046a200341086a410110290c010b200341ac013a0008200241046a200341086a410110290b2000411a3a0000024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200341106a24000bef03030a7f017e017f230041306b22022400200241216a220341076a210441002105410021064100210741002108410821090240024002400340200241186a200110840120022802184101460d01200220032900003703082002200429000037000f200241186a41086a2d0000210a2002200229000f37001f20022002290308370318024020072008470d00200741016a220b2007490d032005200b200b2005491b2208ad420486220c422088a70d03200ca7220b4100480d0302402007450d00200b1000220d450d05200d2009200b20062006200b4b1b10ce02210b20091001200b21090c010b200b10002209450d040b200920066a220b200a3a0000200b41086a200229001f370000200b41016a2002290318370000200541026a2105200641106a2106200741016a2107200a41ff01714106470d000b2000200936020420004100360200200041086a20083602002000410c6a2007360200200241306a24000f0b2000200229021c370204200041013602002000410c6a200241186a410c6a29020037020002402007450d00200921070340024020072d00004109470d00200741086a28020041ffffffff0371450d00200741046a28020010010b200741106a2107200641706a22060d000b0b02402008450d00200910010b200241306a24000f0b1018000b200b41081019000bdd5103067f017e037f230041e0006b22022400024020012802082203200128020c2204470d00200241013a0058200241c0006a410c6a4101360200200241d4006a41013602002002410a360234200241a082c00036024020024101360244200241c0c5c2003602482002200241d8006a3602302002200241306a360250200241086a200241c0006a104c200241cb006a200241106a280200360000200220022903083700432002200241c7006a29000037001f20022002290040370318200041053a000420004101360200200020022903183700052000410c6a200229001f370000200241e0006a24000f0b200441016a2105024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402004417f460d0020032005490d012001280200220620046a2d000021072001410c6a20053602000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200741bf014b0d000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020070ec001ac02ac0200840124ac02aa01aa01aa01aa01aa01a801a501a701a101200b11aa01aa01aa01aa01aa01aa01aa01aa01a60103aa01aa01aa01aa0112189801511aaa01aa01aa0121520533069f0186016f238f019e01a40132080d8801379b01a20104013841714970548b010209441476783f8101752226778701070c252c1016920194011f96019a01a3015ba0011599015e1b5a0f9c019d011d900174720a0e42452813950119602f91018e01890129173497013a27644b5565624a7c407b2e8a0185012b8c0193011c463e2d8d016e3b1e7d5f487982012a3130363d6d5c6c80017f3583014e4f7e7366617a695d39533c674c436a4d6b5768634756505859ac020b20032005470dc301200241013a002f200241cc006a4101360200200241d4006a41013602002002410a36025c200241a082c00036024020024101360244200241c0c5c20036024820022002412f6a3602582002200241d8006a360250200241306a200241c0006a104c200241ca006a200241386a280200360100200220022903303701422002200241c6006a29010037011e20022002290140370318410521010cf2010b200241186a200110850120022802184101470da9012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200320056b41084f0da901200241013a0030200241cc006a4101360200200241d4006a41013602002002410a36020c200241a082c00036024020024101360244200241c0c5c2003602482002200241306a3602082002200241086a360250200241186a200241c0006a104c20022802202101200041086a2002290318370200200041106a200136020020004281808080d000370200200241e0006a24000f0b410e21070ca5010b200241186a200110850120022802184101470da8012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241186a200110850120022802184101470da8012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241186a200110850120022802184101470da8012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b413d21070ca1010b200241186a200110850120022802184101470da7012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b413121070c9f010b41d70021070c9e010b200241c0006a200110850120022802404101470da50120002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b413e21070c9c010b200241186a200110850120022802184101470da4012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41d80021070c9a010b41d00021070c99010b41c10021070c98010b200241c0006a200110850120022802404101470da10120002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200241c0006a200110850120022802404101470da10120002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b41dc0021070c95010b413321070c94010b41cb0021070c93010b41c20021070c92010b41e50021070c91010b200241c0006a200110850120022802404101470d9c0120002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b41de0021070c8f010b200241c0006a200110850120022802404101470d9b0120002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b41ce0021070c8d010b41f90021070c8c010b41d30021070c8b010b41800121070c8a010b41c50021070c89010b410a21070c88010b200241186a200110850120022802184101470d95012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b413921070c86010b200241186a200110850120022802184101470d94012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b20032005470d9401200241013a002f200241cc006a4101360200200241d4006a41013602002002410a36025c200241a082c00036024020024101360244200241c0c5c20036024820022002412f6a3602582002200241d8006a360250200241306a200241c0006a104c200241ca006a200241386a280200360100200220022903303701422002200241c6006a29010037011e20022002290140370318410521010cca010b413f21070c83010b413a21070c82010b41e90021070c81010b41db0021070c80010b41e40021070c7f0b41860121070c7e0b41f60021070c7d0b41c00021070c7c0b41fc0021070c7b0b41f30021070c7a0b41e00021070c790b41880121070c780b41870121070c770b200241186a200110850120022802184101470d87012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241186a200110850120022802184101470d87012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41e60021070c740b41900121070c730b41890121070c720b200241186a200110850120022802184101470d84012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241186a200110850120022802184101470d84012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b419b0121070c6f0b41e80021070c6e0b41ff0021070c6d0b419d0121070c6c0b418a0121070c6b0b41fb0021070c6a0b413621070c690b41f10021070c680b200241186a200110850120022802184101470d7c2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41d90021070c660b41a00121070c650b413221070c640b41da0021070c630b41fa0021070c620b41a70121070c610b41830121070c600b20032005470d75200241013a0058200241c0006a410c6a4101360200200241d4006a41013602002002410a360234200241a082c00036024020024101360244200241c0c5c2003602482002200241d8006a3602302002200241306a360250200241086a200241c0006a104c200241cb006a200241106a280200360000200220022903083700432002200241c7006a29000037001f20022002290040370318200041053a000420004101360200200020022903183700052000410c6a200229001f370000200241e0006a24000f0b41ef0021070c5e0b41eb0021070c5d0b419f0121070c5c0b41a20121070c5b0b41920121070c5a0b41930121070c590b41a90121070c580b200241c0006a200110850120022802404101470d6e20002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200241186a200110850120022802184101470d6e2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b419c0121070c550b42002108410021042001410c6a21090340410e210a2004413f4b0dac0120032005460d7f2005417f460dbc012003200541016a2201490dbd01200620056a2d0000210720092001360200200741ff0071220bad2004413f71ad862008842108200441076a21042001210520074118744118752201417f4c0d000b200141c0007121072004413f4b0da1012007450da1012008427f2004413f71ad86842108412e21070cd7010b41ec0021070c530b41a80121070c520b41a40121070c510b41aa0121070c500b41ab0121070c4f0b41cf0021070c4e0b41c90021070c4d0b418c0121070c4c0b419a0121070c4b0b41cd0021070c4a0b41820121070c490b41df0021070c480b41970121070c470b41ee0021070c460b41a60121070c450b41ea0021070c440b41ed0021070c430b41960121070c420b419e0121070c410b41a50121070c400b41990121070c3f0b41a10121070c3e0b41a30121070c3d0b418d0121070c3c0b418b0121070c3b0b41fe0021070c3a0b200241186a200110850120022802184101470d522000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b2001410c6a210b410021014100210a0340410d21092001411f4b0db90120032005460d642005417f460da2012003200541016a2204490da301200620056a2d00002107200b2004360200200741ff00712001411f7174200a72210a200141076a210120042105200741187441187522044100480d000b200441c0007121072001411f4b0d86012007450d8601200a417f2001411f717472210a412d21070cb9010b20032005470d51200241013a0058200241c0006a410c6a4101360200200241d4006a41013602002002410a360234200241a082c00036024020024101360244200241c0c5c2003602482002200241d8006a3602302002200241306a360250200241086a200241c0006a104c200241cb006a200241106a280200360000200220022903083700432002200241c7006a29000037001f20022002290040370318200041053a000420004101360200200020022903183700052000410c6a200229001f370000200241e0006a24000f0b41d60021070c360b41950121070c350b41d50021070c340b413821070c330b413421070c320b413b21070c310b413521070c300b41840121070c2f0b41980121070c2e0b41f20021070c2d0b41f00021070c2c0b41810121070c2b0b41940121070c2a0b418f0121070c290b418e0121070c280b413721070c270b41850121070c260b41910121070c250b20032005470d40200241013a002f200241cc006a4101360200200241d4006a41013602002002410a36025c200241a082c00036024020024101360244200241c0c5c20036024820022002412f6a3602582002200241d8006a360250200241306a200241c0006a104c200241ca006a200241386a280200360100200220022903303701422002200241c6006a29010037011e20022002290140370318410521010c700b41f50021070c230b200241186a200110850120022802184101470d3f2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b413c21070c210b200241186a200110850120022802184101470d3e2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41e30021070c1f0b41f40021070c1e0b200320056b41044f0d3c200241013a0030200241cc006a4101360200200241d4006a41013602002002410a36020c200241a082c00036024020024101360244200241c0c5c2003602482002200241306a3602082002200241086a360250200241186a200241c0006a104c20004281808080d000370200200041086a2002290218370200200041106a200241186a41086a280200360200200241e0006a24000f0b41f70021070c1c0b41fd0021070c1b0b41e20021070c1a0b200241186a200110850120022802184101470d392000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41d40021070c180b41e10021070c170b41c30021070c160b41f80021070c150b41c40021070c140b41dd0021070c130b41c60021070c120b41e70021070c110b200241c0006a200110850120022802404101470d3120002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b41cc0021070c0f0b41c70021070c0e0b200241186a200110850120022802184101470d2f2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41d10021070c0c0b41d20021070c0b0b200241186a200110850120022802184101470d2d2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241186a200110850120022802184101470d2d2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41ca0021070c080b200241c0006a200110860120022802404101470d2c200041013602002000200241c0006a41047222012902003702042000410c6a200141086a290200370200200241e0006a24000f0b200241186a200110850120022802184101470d2c2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41c80021070c050b200241186a200110850120022802184101470d2b2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241c0006a200110850120022802404101470d2b20002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b410d21070c020b200241c0006a200110850120022802404101470d2a20002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b410621070b0c80010b2000410b3a000420004101360200200041056a20073a0000200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d2920002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200441096a2104200541784f0d6720032004490d68200620056a29000021082001410c6a2004360200413021070c7f0b200228021c210a200241c0006a200110850120022802404101470d2820002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d2820002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d2820002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d2820002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b2002280244210a410b21070c780b200228021c210a200241c0006a200110850120022802404101470d2720002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200141086a28020022072001410c6a2802002204470d27200241013a0058200241c0006a410c6a4101360200200241d4006a41013602002002410a360234200241a082c00036024020024101360244200241c0c5c2003602482002200241d8006a3602302002200241306a360250200241086a200241c0006a104c200241cb006a200241086a41086a280200360000200220022903083700432002200241c7006a29000037001f20022002290040370318200041053a000420004101360200200020022903183700052000410c6a200229001f370000200241e0006a24000f0b2002280244210a410f21070c750b2002280244210a411021070c740b2002280244210a411321070c730b200228021c210a200241c0006a200110850120022802404101470d2420002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d2420002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200441026a21072005417f460d5c20032007490d5d200620056a2c000021042001410c6a20073602004100210920044100480d34200441017441807f71200472220441ff0171220741847e6a220141034b0d3e024020010e04004e4c4d000b41032109410421070c710b200228021c210a200241c0006a200110850120022802404101470d2320002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d2320002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d2320002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d2320002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d2320002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200441026a21042005417f460d5820032004490d59200620056a2d000021072001410c6a20043602002007450d30200041153a000420004101360200200041056a20073a0000200241e0006a24000f0b2002280244210a411221070c690b200228021c210a200241c0006a200110850120022802404101470d2120002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d2120002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200441026a21042005417f460d5620032004490d57200620056a2d000021072001410c6a20043602002007450d2d200041153a000420004101360200200041056a20073a0000200241e0006a24000f0b200441026a21072005417f460d5720032007490d58200620056a2c000021042001410c6a20073602004100210920044100480d2d200441017441807f71200472220441ff0171220741847e6a220141034b0d34024020010e0400464445000b41032109410221070c660b200441026a21072005417f460d5820032007490d59200620056a2c000021042001410c6a20073602004100210920044100480d2e200441017441807f71200472220441ff0171220741847e6a220141034b0d34024020010e0400484647000b41032109410321070c650b200228021c210a200241c0006a200110850120022802404101470d1e20002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d1e20002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200441056a21042005417c4f0d5720032004490d58200620056a280000210a2001410c6a2004360200412f21070c610b200228021c210a200241c0006a200110850120022802404101470d1d20002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b2002280244210a411121070c5f0b200228021c210a200241c0006a200110850120022802404101470d1c20002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d1c20002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d1c20002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200241cc006a2802002107200228024421042002200241c8006a28020036021c20022004360218200220043602202002200420074102746a360224200241086a200241186a103e20022802082105200228020c220720022802102204470d1c2005210a200721040c2f0b200228021c210a200241c0006a200110850120022802404101470d1c20002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c0006a200110850120022802404101470d1c20002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200241e0006a24000f0b2002280244210a410721070c580b2002280244210a410821070c570b200241013a0058200241cc006a4101360200200241d4006a41013602002002410a36020c200241a082c00036024020024101360244200241c0c5c2003602482002200241d8006a3602082002200241086a360250200241186a200241c0006a104c20022802202101200229031821084105210a0c2d0b200241013a0030200241cc006a4101360200200241d4006a41013602002002410a36020c200241a082c00036024020024101360244200241c0c5c2003602482002200241306a3602082002200241086a360250200241186a200241c0006a104c410521090c540b20023502442108412821070c560b20023502442108412721070c550b20023502442108411621070c540b20023502442108411821070c530b20023502442108412121070c520b20023502442108412221070c510b200441016a21052004417f460d4620072005490d472002280244210a200128020020046a2d00002104410c21072001410c6a20053602002004450d1f200041163a000420004101360200200041056a20043a0000200241e0006a24000f0b20023502442108411421070c4f0b20023502442108411c21070c4e0b20023502442108412021070c4d0b20023502442108411721070c4c0b20023502442108412421070c4b0b20023502442108412921070c4a0b20023502442108412a21070c490b20023502442108411521070c480b20023502442108411b21070c470b20023502442108411a21070c460b20023502442108412321070c450b20023502442108411d21070c440b20023502442108412521070c430b20023502442108411e21070c420b20023502442108411921070c410b20072004490d382004450d10200441027422031000220a450d39200a2005200320074102742207200720034b1b10ce021a0c110b20023502442108412621070c3f0b20023502442108411f21070c3e0b411821010b2002200229011e37010e200220022903183703080c380b412c2107410021090c3a0b412b2107410021090c390b411821010b2002200229011e37010e200220022903183703080c330b411821010b2002200229011e37010e200220022903183703080c300b200441c000490d082007450d08200b41ff00470d090c0b0b20014120490d0b2007450d0b2004417f7341ff00716741686a41ff01714105490d310c0c0b41062101200741c001470d2f41042109410421070c320b41062101200741c001470d2d41042109410221070c310b41062101200741c001470d2b41042109410321070c300b410021090c2f0b410021044104210a2007450d010b200510010b200241c0006a2001108501024020022802404101470d0020002002290244370204200041013602002000410c6a200241c0006a410c6a290200370200200441ffffffff0371450d2f200a1001200241e0006a24000f0b20023502444220862004ad842108410921070c2d0b200441c000490d022001450d020b0b200020022f00303b00052000200a3a000420004101360200200041086a2008370200200041106a2001360200200041076a200241326a2d00003a0000200241e0006a24000f0b412e21070c290b200441ff01716741686a41ff017141044b0d0020014120490d002007450d250b412d21070c250b410121090b410421070c240b41022109410421070c230b410121090b410221070c210b41022109410221070c200b410121090b410321070c1e0b41022109410321070c1d0b417f2005106b000b20052003106a000b417f200541016a106b000b200541016a2003106a000b417f200541016a106b000b200541016a2003106a000b20052004106b000b20042003106a000b417f2007106b000b20072003106a000b417f2004106b000b20042003106a000b417f2004106b000b20042003106a000b417f2007106b000b20072003106a000b417f2007106b000b20072003106a000b20052004106b000b20042003106a000b417f2005106b000b20052007106a000b418093c000104d000b200341041019000b200020043a0005200020013a000420002002290308370106200041013602002000410c6a200229010e370100200241e0006a24000f0b200020043a0005200020013a000420002002290308370106200041013602002000410c6a200229010e370100200241e0006a24000f0b200020043a0005200020013a000420002002290308370106200041013602002000410c6a200229010e370100200241e0006a24000f0b2000200936020420004101360200200041086a2002290218370200200041106a200241186a41086a280200360200200241e0006a24000f0b0b0b20004100360200200041096a20093a0000200041086a20073a00002000410c6a200a360200200041106a20083703000b200241e0006a24000ba80301077f230041c0006b220224002001280208210320012802002104410021052001410c6a210641002107024002400240024002400340200541204f0d01200320062802002201460d02200141016a21082001417f460d0420032008490d0520062008360200200420016a2d0000220141ff00712005411f71742007722107200541076a21052001418001710d000b20054120490d0220016741686a41ff017141044f0d02200041013602002000410d3a0004200241c0006a24000f0b200041013602002000410f3a0004200241c0006a24000f0b200241013a000f200241206a410c6a4101360200200241346a41013602002002410a36023c200241a082c00036022020024101360224200241c0c5c20036022820022002410f6a3602382002200241386a360230200241106a200241206a104c2002412b6a200241186a28020036000020022002290310370023200041053a000420004101360200200020022900203700052000410c6a200241276a290000370000200241c0006a24000f0b2000410036020020002007360204200241c0006a24000f0b417f2008106b000b20082003106a000ba808030c7f017e017f230041c0006b220224002001280208210320012802002104410021052001410c6a21064100210702400240024002400240024002400240024002400240024002400240024003402005411f4b0d01200320062802002208460d02200841016a21092008417f460d0820032009490d0920062009360200200420086a2d0000220841ff00712005411f71742007722107200541076a21052008418001710d000b200241086a200241186a41086a280200360200200220022902183703004104210a4100210b410d200741ff01712005411f4b20086741686a41ff01714104497122051b4100200741807e7120051b72210c20050d034100210d0240200c450d002001410c6a21064100210b4100210d4104210a0340200b220141016a210b410021054100210703402005411f4b0d07200320062802002208460d08200841016a21092008417f460d0c20032009490d0d20062009360200200420086a2d0000220841ff00712005411f71742007722107200541076a21052008418001710d000b024020054120490d0020086741686a41ff01714104490d090b02402001200d470d0020014101742205200141016a220820082005491b220dad420286220e422088a70d0e200ea722054100480d0e02402001450d00200510002208450d102008200a200520014102742209200920054b1b10ce022105200a10012005210a0c010b20051000220a450d0f0b200a20014102746a2007410876220f410874200741ff017172360200200b200c490d000b0b2000200a36020420004100360200200041086a200d3602002000410c6a200b360200200241c0006a24000f0b410f210c0c010b200241013a000f200241346a41013602002002413c6a41013602002002410a360214200241a082c0003602282002410136022c200241c0c5c20036023020022002410f6a3602102002200241106a360238200241186a200241286a104c4105210c0b200241086a200241186a41086a280200360200200220022902183703000b2000200c36020420004101360200200041086a2002290300370200200041106a200241086a2802003602000c0a0b410f21050c080b200241013a0000200241286a41086a41c0c5c200360200200241346a41013602002002413c6a41013602002002410a360214200241a082c0003602282002410136022c200241386a200241106a36020020022002360210200241186a200241286a104c200241186a41086a2802002103200228021c2109200228021821084100210f410521050c070b410d21050c060b417f2009106b000b20092003106a000b417f2009106b000b20092003106a000b1018000b200541041019000b20004101360200200041086a20083602002000410c6a2009360200200041106a20033602002000200f410874200572360204200d450d00200a1001200241c0006a24000f0b200241c0006a24000bc504020d7f017e230041c0006b22032400200128020022042001280208220541047422066a2107200128020421080240024002400240024002402005450d00200341306a41017221094100210a200341306a41026a210b200341206a410172220c41076a210d0340200b2004200a6a220141036a2d00003a00002003200141016a2f00003b013020012d0000220e41ac01460d022003410c6a41026a220f200b2d00003a0000200320032f01303b010c200141046a2902002110200341306a410c6a2001410c6a280200360200200920032f010c3b0000200941026a200f2d00003a00002003200e3a003020032010370234200341206a200341306a20021082012003200c2900003703102003200d29000037001720032d0020220e411a470d052006200a41106a220a470d000c040b0b200422012007470d010c020b200141106a22012007460d010b03400240024020012d0000220a4109460d00200a41ac01470d010c030b200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a22012007470d000b0b02402008450d00200410010b2000411a3a00000c010b200020032903103700012000200e3a0000200041086a20032900173700000240200541047441706a200a460d00200141186a2101034002400240200141786a220a2d0000220b4109460d00200b41ac01470d010c030b200128020041ffffffff0371450d002001417c6a28020010010b200141106a2101200a41106a2007470d000b0b2008450d0020041001200341c0006a24000f0b200341c0006a24000b860101047f230041106b22032400200141086a2802002104200341003a000f200241046a21052004210203402003200241800172200241ff0071200241077622061b3a000f20052003410f6a410110292006210220060d000b200128020421022005200128020022062004102902402002450d00200610010b2000411a3a0000200341106a24000bbd03010a7f200241046a22032802002104200241086a22052802002106200141086a280200220721080240024002400340024002400240024020042006470d00200441016a22092004490d052004410174220a20092009200a491b220a4100480d052004450d012002280200210b200a1000220c450d06200c200b200a20042004200a4b1b10ce021a200b10010c020b200641016a21092002280200210c0c020b200a1000220c450d040b2002200c3602002003200a360200200a21040b20052009360200200c20066a200841807f72200841ff00712008410776220a1b3a000020092106200a2108200a0d000b2001280204210b2001280200210a0240024002400240200420096b20074f0d00200920076a22062009490d0420044101742208200620062008491b22054100480d042005100021082004450d012008450d062008200c20052004200420054b1b10ce021a200c10010c020b200920076a2106200c21080c020b2008450d040b20022008360200200241046a20053602000b200241086a2006360200200820096a200a200710ce021a0240200b450d00200a10010b2000411a3a00000f0b1018000b200a41011019000b200541011019000be00501087f230041e0086b22022400200241286a2001108501024020022802284101470d002000200229022c370204200041013602002000410c6a200241286a410c6a290200370200200241e0086a24000f0b024002400240024002400240200228022c2203450d00410021042002410036022020024201370318200241286a410041800810d0021a200128020c210520012802082106200128020021072001410c6a21080340200620056b200320046b22014180082001418008491b2201490d02200520016a22092005490d0520062009490d06200241286a200720056a200110ce021a20082009360200200241186a200241286a20011029200921052003200120046a22044b0d000b200228021c2109200241286a20022802182201200241206a2802002204106c4101210520022802284101470d02200241106a200229022c37030020022001360204200241047221010c030b2000428080808010370200200041086a4200370200200241e0086a24000f0b200241013a00af08200241c0086a410c6a4101360200200241d4086a41013602002002410a3602dc08200241a082c0003602c008200241013602c408200241c0c5c2003602c8082002200241af086a3602d8082002200241d8086a3602d008200241b0086a200241c0086a104c200241cb086a200241b8086a280200360000200220022903b0083700c308200041053a000420004101360200200020022900c0083700052000410c6a200241c7086a2900003700000240200228021c450d00200228021810010b200241e0086a24000f0b2002200136020420024104722101410021050b2002410c6a2004360200200241086a220420093602002002200536020002402005450d0002402004280200450d00200128020010010b200041083a000420004101360200200241e0086a24000f0b200020012902003702042000410c6a200141086a28020036020020004100360200200241e0086a24000f0b20052009106b000b20092006106a000b5d01027e02402003450d0020022802000d002001280224220342002003290308220420023502047d220520052004562005507222021b37030802402002450d00200041053602000f0b200041043602000f0b41e1c3c10041f4031040000bbf0702057f017e230041d0016b22042400024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320022802042103200241146a2802002105200241246a2802002106200241346a2802002107200441186a4200370300200441106a4200370300200441086a42003703002004420037030002402001280220220820032004412010082202417e460d0020020d050240024002402005450d002004410036023820044201370330200441306a2007102a2008200620042802302203200428023810082202417e460d0220020d09200429023421090c010b410021030b20012802002802002102412010002201450d082004200136023020044220370234200441306a200441201029200441206a41086a20042802383602002004200429033037032020022802000d092002417f36020020044180016a2201200241c0006a290000370300200441e8006a41106a2205200241386a290000370300200441e8006a41086a200241306a29000037030020042002290028370368200441306a200241046a200441e8006a108d010240024020042802304101470d00200441386a2802002101200441306a41106a2802002105200441a0a1c1003602a001200442003702a4012001200541306c6a41e8026a2101200441e8006a200441a0016a108e01200441e8006a108f010c010b200441e8006a41306a200441e4006a280200360200200441e8006a41286a200441dc006a29020037030020044188016a200441d4006a2902003703002001200441cc006a2902003703002005200441c4006a290200370300200441f0006a2004413c6a29020037030020042004290234370368200441a0016a41286a4200370300200441003602b801200442003703a001200441a0a1c1003602c401200441e8006a200441a0016a10900121010b200441a0016a41086a200441206a41086a280200360200200420042903203703a0012004200937026c20042003360268200441306a200141246a200441a0016a200441e8006a10910102402004280230450d0020042802342203450d00200441386a280200450d00200310010b2002200228020041016a36020020004104360200200441d0016a24000f0b2004280234450d00200310010b20004105360200200441d0016a24000f0b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41c080c000104d000b41c080c000104d000b412041011019000b109201000b9f0301087f230041f0066b220324000240024002402001280200220441a0a1c100460d00200128020421050c010b41f80610002204450d0141002105200441003b010620044100360200200441086a200341f00610ce021a20014100360204200120043602000b024002400340200441086a210720042f010622084105742109417f210602400240024003402009450d01200641016a2106417f410120022007412010d102220a4100481b4100200a1b220a450d05200941606a2109200741206a2107200a4101460d000b20050d010c020b200821062005450d010b2005417f6a2105200420064102746a41f8066a28020021040c010b0b41012109410021050c010b410021090b20002005360204200041086a20043602002000410c6a2001360200200041106a2006360200200041146a200141086a3602004101210402402009450d00200041186a2002290000370000200041306a200241186a290000370000200041286a200241106a290000370000200041206a200241086a290000370000410021040b20002004360200200341f0066a24000f0b41f80641081019000bb00301097f23002102200141046a280200210320012802082104200241306b220241186a2205200128020022063602002002411c6a2207410036020020022003360214200220034100472208360210024002402003450d002003417f6a2101200241106a41047221092006210a03402005200a28029002220a3602002007410036020020022001360214200220014100473602102001417f6a2201417f470d000c020b0b200241106a41047221090b200241086a200941086a28020036020020022009290200370300200241106a41086a220a20063602002002411c6a22054100360200200220033602142002200836021002402003450d002003417f6a21010340200a200620062f01064102746a4190026a28020022063602002005410036020020022001360214200220014100473602102001417f6a2201417f470d000b0b200241106a41086a28020022012f010621062002411c6a280200210a200228021421052000410036020c20002005360210200041146a2001360200200041186a200a3602002000411c6a200636020020002004360220200041086a200241086a280200360200200020022903003702000bf20202067f027e230041206b22012400200141086a200010ed01024020012802082202450d00200141186a2103200141146a2104034020032802002105200428020021060240200128020c450d00200210010b02402006450d002005450d00200610010b200141086a200010ed01200128020822020d000b0b024002402000280204220641a0a1c100460d0020002802082103200028020021020240024020062802002205450d00200633010421072001200536020c2001200241016a2202360208200120074220862003ad842207370310200610012005450d020c010b2003ad210741002105200610014100450d010b0240024020052802002206450d00200533010421082001200636020c2001200241016a36020820012008422086200742ffffffff0f8384370310200510012006450d020c010b41002106200510014100450d010b034020062802002205450d02200610012005210620050d000b0b200141206a24000f0b20061001200141206a24000be80d01117f230041d0086b2202240020002802102203200328020041016a360200200241e0006a41086a200041086a29020037030020022000290200370360200241206a41186a22032000412c6a290000370300200241206a41106a2204200041246a290000370300200241206a41086a22052000411c6a2900003703002002200029001437032020024180016a41286a200141286a29030037030020024180016a41206a200141206a29030037030020024180016a41186a200141186a29030037030020024180016a41106a200141106a29030037030020024180016a41086a200141086a2903003703002002200129030037038001200241b0016a200241e0006a200241206a20024180016a107a024002400240024002400240024020022d00b0014101470d00200241086a200241b9016a290000370300200241106a200241c1016a290000370300200241186a200241c9016a2900003703002005200241f0016a2903003703002004200241f8016a290300370300200320024180026a290300370300200241206a41206a20024188026a290300370300200241206a41286a20024190026a290300370300200220022900b1013703002002200241e8016a290300370320200241e4016a2802002106200241e0016a28020021042002280298022107200241b0016a412c6a2802002103200241b0016a41246a2802002100200241b0016a41286a28020022012802002205450d0120012f0104210820022005360284012002200041016a22093602800120022003360288012002200836028c014100450d020c030b200241b0016a41106a2802002100200241b0016a41086a2802002101200241d0086a24002001200041306c6a41e8026a0f0b2002200136028401200220003602800120022003360288012003210941010d010b200241e8016a2100200241b0016a4101722101200241dc006a210a200241e4016a210b200241e0016a210c200241dc016a210d200241d4016a210e0340200241d0006a41086a2003360200200a20083602002002200536025420022009360250200241e0006a41186a200241186a2203290300370300200241e0006a41106a200241106a2205290300370300200241e0006a41086a200241086a22082903003703002002200229030037036020024180016a41286a200241206a41286a220929030037030020024180016a41206a200241206a41206a220f29030037030020024180016a41186a200241206a41186a221029030037030020024180016a41106a200241206a41106a221129030037030020024180016a41086a200241206a41086a22122903003703002002200229032037038001200241b0016a200241d0006a200241e0006a20024180016a20042006107f20022d00b0014101470d0302402008200141086a2900003703002005200141106a2900003703002003200141186a2900003703002012200041086a2903003703002011200041106a2903003703002010200041186a290300370300200f200041206a2903003703002009200041286a2903003703002002200129000037030020022000290300370320200c2802002104200d2802002103200241b0016a41286a28020022082802002205450d00200b2802002106200e28020041016a210920082f010421080c010b0b41a807210141a80710002200450d030c010b2009210341a807210141a80710002200450d020b200041003b010620004100360200200041086a200241b0016a41a00710ce022101200020032802003602f806200320003602002003200328020441016a36020420002802f806220341003b01042003200036020020024180016a41186a2205200241186a29030037030020024180016a41106a2208200241106a29030037030020024180016a41086a2209200241086a2903003703002002200229030037038001200241b0016a41286a2206200241206a41286a290300370300200241b0016a41206a220f200241206a41206a290300370300200241b0016a41186a2210200241206a41186a290300370300200241b0016a41106a2211200241206a41106a290300370300200241b0016a41086a2212200241206a41086a290300370300200120002f010622034105746a2201200229038001370000200141086a2009290300370000200141106a2008290300370000200141186a2005290300370000200220022903203703b0012000200341306c6a22014190036a200629030037030020014188036a200f29030037030020014180036a2010290300370300200141f8026a2011290300370300200141f0026a2012290300370300200141e8026a20022903b001370300200041f8066a200341016a22014102746a2004360200200020002f010641016a3b0106200420013b0104200420003602000b200241d0086a240020070f0b200141081019000be80c03097f017e027f230041b0036b2204240020022802082105200228020421062002280200210702400240024002402001280200220841a0a1c100460d00200128020421090c010b41900210002208450d0141002109200841003b010620084100360200200841086a200441f8006a41880210ce021a20014100360204200120083602000b0240024002400240024002400340200841086a210220082f0106220b410c6c210c428080808070210d417f210a0240024002400340200c450d0102400240200720022802002002280208220e20052005200e4b1b10d102220f450d00200d4280808080107c210d417f4101200f4100481b220e0d010c070b200d4280808080107c210d4100417f41012005200e491b2005200e461b220e450d060b2002410c6a2102200c41746a210c200a41016a210a200e4101460d000b20090d010c020b200b210a2009450d010b2009417f6a21092008200a4102746a4190026a28020021080c010b0b200441086a41106a20083602002001200128020841016a3602082004411c6a200aad4220862001ad84220d3702002004200636020c2004200736020820042005ad3703102004200836026c200441003602682004200d3703702004200636024c2004200736024820042005360250200441d8006a41086a200341086a28020036020020042003290200370358200441f8006a200441e8006a200441c8006a200441d8006a107b20042802784101470d05200441286a41086a20044190016a280200360200200441386a41086a2004419c016a2802003602002004200441f8006a41106a290300370328200420044194016a29020037033820044184016a2802002102200441a4016a280200210a200441a0016a2802002108200428027c210e200441f8006a41086a280200220c2802002205450d01200c2f0104210c2004200536026c2004200e41016a220e360268200420023602702004200c36027441000d020c030b200141086a2102200d2001ad84210d02402006450d00200710010b2004200936027820042002360288012004200836027c2004200d37038001200441e8006a41086a2202200341086a28020036020020042003290200370368200441086a41086a22052008200d422088a7410c6c6a22084194016a220c28020036020020042008418c016a2208290200370308200c20022802003602002008200429036837020020022005280200360200200420042903083703682005200228020036020020042004290368370308200041013602002000410c6a200528020036020020002004290308370204200441b0036a24000f0b2004200c36026c2004200e360268200420023602702002210e4101450d010b200e210241c002210c41c002100022050d010c040b20044194016a210120044188016a2109200441e8006a410c6a210f200441a4016a2103200441a0016a21070340200441e8006a41086a2002360200200f200c3602002004200536026c2004200e360268200441c8006a41086a200441286a41086a220228020036020020042004290328370348200441d8006a41086a200441386a41086a220528020036020020042004290338370358200441f8006a200441e8006a200441c8006a200441d8006a2008200a107d20042802784101470d0202402002200941086a2802003602002005200141086a2802003602002004200929020037032820042001290200370338200441f8006a410c6a280200210220072802002108200441f8006a41086a280200220c2802002205450d002003280200210a200428027c41016a210e200c2f0104210c0c010b0b41c002210c41c00210002205450d030b200541003b010620054100360200200541086a200441f8006a41b80210ce02210c2005200228020036029002200220053602002002200228020441016a360204200528029002220241003b010420022005360200200441e8006a41086a2202200441286a41086a28020036020020042004290328370368200c20052f0106220e410c6c220a6a220c20042903683702002005200a6a220a4194016a200441386a41086a2802002201360200200a418c016a2004290338220d370200200c41086a200228020036020020054190026a200e41016a22024102746a2008360200200441f8006a41086a2001360200200520052f010641016a3b01062004200d37037820082005360200200820023b01040b20004100360200200441b0036a24000f0b41900241041019000b200c41041019000b900101017f230041c0006b220024002000411036020c200041fdeac100360208200041286a410c6a410b360200200041106a410c6a4102360200200041246a41023602002000410136022c2000419888c10036021020004102360214200041a0d2c2003602182000200041086a3602282000200041386a3602302000200041286a360220200041106a41a888c1001065000ba50301037f230041d0006b220424000240024002402003450d0020022802000d0020022802042102200441186a4200370300200441106a4200370300200441086a42003703002004420037030002400240200128022020022004412010082202417e460d0020020d03200441206a20012802002802002202200241286a2004412010940120042802202205450d01200441306a41086a200441206a41086a220228020036020020042004290320370330200441c0006a41086a2203200228020036020020042004290320370340200141106a21020240200141146a280200450d00200228020010010b20022004290340370200200241086a2003280200360200410021020c040b20004105360200200441d0006a24000f0b0240200141186a22022802002206450d00410021032006210203402002417f6a2102200341016a22032006490d000b200141186a20023602004101210241000d032005450d032004280224450d03200510010c030b20024100360200410121020c020b41e1c3c10041f4031040000b41c080c000104d000b2000410036020020002002360204200441d0006a24000bae0301097f230041206b220524000240200128020022064100480d00200641ffffffff07460d002001200641016a36020002400240200141046a200210f7012207450d00200741246a21062007280228210803402006280200220941086a210620092f0106220a410c6c210b417f210702400340024002400240200b450d000240200320062802002006280208220c2004200c2004491b10d102220d450d00200741016a2107417f4101200d4100481b220c450d020c030b200741016a21074100417f4101200c20044b1b200c2004461b220c0d020c010b200a21070c030b0240024020092007410c6c6a418c016a2206280200450d00200541106a2006102d0c010b200541003602100b200541086a2206200541106a41086a28020036020020052005290310370300200041086a2006280200360200200020052903003702000c050b2006410c6a2106200b41746a210b200c4101460d000b0b2008450d012008417f6a2108200920074102746a4190026a21060c000b0b20002001280210200220032004200141146a28020028020c1103000b20012001280200417f6a360200200541206a24000f0b10f801000bb30904027f017e057f037e230041c0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042103200241146a2802002105200241286a2903002106200241346a2802002107200241c4006a2802002108200241d4006a2802002109200241e4006a280200210a2004410036021820044201370310200441106a2005102a02400240024020012802202003200428021022022004280218220510082203417e460d0020030d0a200441a0016a200541202005412049220b1b22036a41004100412020036b2003411f4b1b10d0021a200441a0016a2002200310ce021a200b0d00200441206a41186a200441a0016a41186a290000370300200441206a41106a200441a0016a41106a290000370300200441206a41086a200441a0016a41086a290000370300200420042900a0013703202004410036024820044201370340200441c0006a2008102a0240200141206a2802002007200428024022082004280248220310082205417e460d0020050d0c200442003703a801200442003703a001200441a0016a20082003411020034110491b10ce021a2003410f4d0d00200441a8016a290300210c20042903a001210d2004410036025820044201370350200441d0006a200a102a0240200141206a2802002009200428025022072004280258220a10082203417e460d0020030d0e200141186a22092802002205450d03410021030340200341016a22032005490d000b200520036b21030c040b2004280254450d00200710010b2004280244450d00200810010b02402004280214450d00200210010b20004105360200200441c0016a24000f0b410021030b2009200336020041012103024020012802242205290308220e200e20062006501b2206540d00200441e0006a41186a200541186a29030037030020042006370360200420063703682004200529031037037020044180016a41186a2001280200280200220341c0006a29000037030020044180016a41106a200341386a29000037030020044180016a41086a200341306a2900003703002004200329002837038001200441a0016a41186a200441206a41186a290300370300200441a0016a41106a200441206a41106a290300370300200441a0016a41086a200441206a41086a290300370300200420042903203703a001200441086a200320044180016a200441a0016a200d200c200441e0006a2007200a200141106a10960120042802082103200541086a2004290368200e20067d7c370300200341004721030b02402004280254450d00200710010b02402004280244450d00200810010b02402004280214450d00200210010b2000410036020020002003360204200441c0016a24000f0b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41c080c000104d000b41c080c000104d000b41c080c000104d000bf90802037f027e230041b0016b220a24002001280218210b200a41206a41086a220c4200370300200a420037032041a5d4c1004111200a41206a1002200a4188016a41086a200c290300370300200a200a2903203703880102400240200a4188016a411041b8d6c200410041001004417f460d00200a410036022002400240200a4188016a4110200a41206a41044100100441016a41044d0d0002400240200b200a280220470d0041d788c2002103412921010c010b200a41206a41086a220c4200370300200a420037032041c0cbc1004114200a41206a1002200a4188016a41086a200c290300370300200a200a29032037038801200a4188016a411041b8d6c200410041001004417f460d04200a4200370320200a4188016a4110200a41206a41084100100441016a41084d0d02200642002006290308220d200a2903207d220e200e200d56200e5072220c1b3703080240200c450d00418089c2002103412321010c010b200a41106a200310b601200a41206a41086a4200370300200a41346a4198cbc000360200200a41c4006a4100360200200a41e0006a200341186a290000370300200a41d8006a200341106a290000370300200a41d0006a200341086a290000370300200a4100360220200a41a0a1c100360224200a2001360230200a200b41016a360238200a420837023c200a2003290000370348024002402004200584500d00200a41086a20064100200141286a200320042005200a41206a10a402200a2802082203450d00200a28020c21010c010b02400240200a2802182203450d00200a280210210b200a4194016a200241086a290000370200200a419c016a200241106a290000370200200a41a4016a200241186a290000370200200a200229000037028c01200a200a41206a36028801200a4201370370200a4201370368200a4201370378200a4280808480800237038001200b2003200720082009200a4188016a200a41e8006a200610d10141ff01714108470d010b200a4188016a41086a2206200a41206a41086a220b290300370300200a41e8006a41086a220c200a4194016a280200360200200a200a29032037038801200a200a29028c01370368200a41c4006a2802002102200a41206a411c6a2802002103200a41c0006a28020021072006200c280200360200200a200a29036837038801200b2006280200360200200a200a290388013703202001200a41206a10f901200a2007360224200a2003360220200a2003360228200a2003200241d0006c6a36022c2001411c6a200a41206a10170240200a280214450d00200a28021010010b410021030c020b41a389c2002103412421010b200a41e8006a41086a200a41206a410472220641086a280200360200200a2006290200370368200a4188016a200a41e8006a10ea01200a4188016a10ee010240200a41c0006a280200450d00200a413c6a28020010010b200a280214450d00200a28021010010b2000200136020420002003360200200a41b0016a24000f0b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b41c3d7c10041221040000b930907037f017e037f027e017f017e027f230041a0016b220424000240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042105200241146a2802002106200241286a2903002107200241346a2802002108200241c4006a2802002103200241d4006a2802002109200241e4006a280200210a2004410036021020044201370308200441086a2003102a02400240024020012802202008200428020822032004280210220210082208417e460d0020080d0a2004420037036020044200370358200441d8006a200320024110200241104922081b10ce021a20080d00200441e0006a290300210b2004290358210c2004410036022020044201370318200441186a2006102a0240200141206a2802002005200428021822062004280220220d10082202417e460d0020020d0c2004410036023020044201370328200441286a200a102a0240200141206a2802002009200428022822052004280230220a10082202417e460d0020020d0e200141186a22092802002208450d03410021020340200241016a22022008490d000b200820026b21020c040b200428022c450d00200510010b200428021c450d00200610010b0240200428020c450d00200310010b20004105360200200441a0016a24000f0b410021020b200920023602000240024020012802242202290308220e200e20072007501b2207540d00200441386a41186a200241186a29030037030020042007370338200420073703402004200229031037034820044180016a41186a22092001280200280200220841c0006a29000037030020044190016a220f200841386a29000037030020044180016a41086a2210200841306a2900003703002004200829002837038001200441d8006a200820044180016a200c200b200441386a2006200d2005200a109801200e20077d210741012108024020042d00584101460d002009200441f1006a290000370300200f200441e9006a2900003703002010200441e1006a2900003703002004200429005937038001410021080b200241086a200441386a41086a29030020077c3703002008450d010b41012102200428022c450d0c0c0b0b200441d8006a41186a20044180016a41186a290300370300200441d8006a41106a20044180016a41106a290300370300200441d8006a41086a20044180016a41086a2903003703002004200429038001370358200441d8006a200141106a101b41002102200428022c0d0a0c0b0b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41c080c000104d000b41c080c000104d000b41c080c000104d000b200510010b0240200428021c450d00200610010b0240200428020c450d00200310010b2000410036020020002002360204200441a0016a24000bd41403037f027e077f230041b0026b220a24002001280218210b200a41286a41086a220c4200370300200a420037032841a5d4c1004111200a41286a1002200a4190016a41086a200c290300370300200a200a290328370390010240024002400240200a4190016a411041b8d6c200410041001004417f460d00200a410036022802400240200a4190016a4110200a41286a41044100100441016a41044d0d000240200b200a280228470d00200041013a0000200041086a4124360200200041046a41e989c200360200200a41b0026a24000f0b200a41286a41086a220b4200370300200a420037032841eacbc1004116200a41286a1002200a4190016a41086a200b290300370300200a200a29032837039001200a4190016a411041b8d6c200410041001004417f460d03200a4200370328200a4190016a4110200a41286a41084100100441016a41084d0d01200542002005290308220d200a2903287d220e200e200d56200e5072220b1b3703080240200b450d00200041013a0000200041086a4125360200200041046a418d8ac200360200200a41b0026a24000f0b200a41286a41186a220b4200370300200a41286a41106a220c4200370300200a41286a41086a220f4200370300200a420037032820062007200a41286a1011200a4190016a41186a2210200b290300370300200a4190016a41106a2211200c290300370300200a4190016a41086a2212200f290300370300200a200a29032837039001200a4180026a41186a2010290300370300200a4180026a41106a2011290300370300200a4180026a41086a2012290300370300200a200a2903900137038002200b4200370300200c4200370300200f4200370300200a420037032820082009200a41286a10112010200b2903003703002011200c2903003703002012200f290300370300200a200a29032837039001200a41c8016a41186a2010290300370300200a41c8016a41106a2011290300370300200a41c8016a41086a2012290300370300200a200a290390013703c801200a410036028801200a420137038001200a4180016a200a4180026a41201029200a4180016a200a41c8016a41201029200a4180016a200141286a221341201029200a280288012114200a280280012115200b4200370300200c4200370300200f4200370300200a420037032820152014200a41286a10112010200b2903003703002011200c2903003703002012200f290300370300200a200a29032837039001200a41086a41186a2010290300370300200a41086a41106a2011290300370300200a41086a41086a2012290300370300200a200a290390013703080240200a28028401450d00201510010b410f1000220b450d04200a200b360228200a420f37022c200a41286a41d5c7c100410f1029200a4190016a41086a220b200a280230360200200a200a29032837039001200a41086a200a4190016a101b200b280200210f200a280294012110200a28029001210c200a41286a41086a22114200370300200a4200370328200c200f200a41286a1002200b2011290300370300200a200a29032837039001200a4190016a41101014210b02402010450d00200c10010b0240200b450d00200041013a0000200041086a4117360200200041046a41b28ac200360200200a41b0026a24000f0b200a41286a41086a4200370300200a41286a41146a4198cbc000360200200a41cc006a4100360200200a41d8006a200a41086a41086a290300370300200a41e0006a200a41086a41106a290300370300200a41e8006a200a41086a41186a290300370300200a4100360228200a41a0a1c10036022c200a4208370244200a200a290308370350200a2001360238200a200141186a28020041016a360240024002400240024002402003200484500d00200a200541012013200a41086a20032004200a41286a10a402200a280200220b450d00200a2802042101200041013a0000200041086a2001360200200041046a200b3602000c010b200a4100360278200a4201370370200a419c016a200241086a290000370200200a4190016a41146a200241106a290000370200200a41ac016a200241186a290000370200200a200229000037029401200a200a41286a36029001200a42013703d001200a42013703c801200a42013703d801200a428080848080023703e00102402006200720082009200a41f0006a200a4190016a200a41c8016a200510d10141ff01714108470d00200a4180016a41086a200a41f0006a41086a280200360200200a200a29037037038001200a2802280d0a200a417f360228200a41c8016a41186a2205200a41086a41186a290300370300200a41c8016a41106a220b200a41086a41106a290300370300200a41c8016a41086a200a41086a41086a290300370300200a200a2903083703c801200a4190016a200a41286a410472200a41c8016a108d01200a280290014101470d02200a4198016a2802002105200a4190016a41106a280200210b200a41a0a1c10036028002200a420037028402200a41c8016a200a4180026a108e01200a41c8016a108f014118210c2005200b41306c6a41e8026a220b41186a2105200b280218220f0d030c040b200041013a0000200041086a4126360200200041046a41c98ac200360200200a280274450d00200a28027010010b200a41c8016a41086a200a41286a410472220041086a280200360200200a20002902003703c801200a4190016a200a41c8016a10ea01200a4190016a10ee010240200a41c8006a280200450d00200a41c4006a28020010010b200a41b0026a24000f0b200a41f8016a200a41c4016a280200360200200a41c8016a41286a200a41bc016a290200370300200a41e8016a200a41b4016a2902003703002005200a41ac016a290200370300200b200a41a4016a290200370300200a41d0016a200a419c016a290200370300200a200a290294013703c801200a4180026a41286a4200370300200a410036029802200a420037038002200a41a0a1c1003602a4024118210c200a41c8016a200a4180026a109001220b41186a2105200b280218220f450d010b200b411c6a280200450d00200f10010b2005200a29038001370200200541086a200a4180016a41086a280200360200200a200a28022841016a360228200a4190016a41086a220b200a41286a41086a220f290300370300200a41c8016a41086a2210200a419c016a280200360200200a200a29032837039001200a200a290294013703c801200a41cc006a2802002111200a41286a411c6a2802002105200a41c8006a2802002112200b2010280200360200200a200a2903c80137039001200f200b280200360200200a200a290390013703282001200a41286a10f901200a201236022c200a2005360228200a2005360230200a2005201141d0006c6a3602342001411c6a200a41286a1017200041003a0000200041196a200a41086a200c6a290300370000200041116a200a41186a290300370000200041096a200a41086a41086a2903003700002000200a290308370001200a41b0026a24000f0b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b41c3d7c10041221040000b410f41011019000b109201000bea0102027f027e230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d01200228020421032004200128021c2903104200200241146a2802002202ad420010d502024020042903084200520d002001280224220542002005290308220620042903007d220720072006562007507222051b37030820050d00200128020c22052002102a200128022020032005280200200528020810082202417e460d0020020d03200141013a00280b20004105360200200441106a24000f0b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41c080c000104d000b1600200041003602002000200141086a2802003602040bbe0101017f02400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d020240200141086a2802002204200241146a2802002203490d00200420036b200241246a2802002204470d0020012802202002280204200128020420036a200410092202417e460d0020020d04200041043602000f0b200041053602000f0b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41d880c000104d000b1600200041003602002000200141186a2802003602040bbe0101017f02400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d020240200141186a2802002204200241146a2802002203490d00200420036b200241246a2802002204470d0020012802202002280204200128021020036a200410092202417e460d0020020d04200041043602000f0b200041053602000f0b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41e1c3c10041f4031040000b41d880c000104d000bc70402077f027e230041c0006b2202240020012802042802a002210302400240024002400240411310002201450d002002200136023020024213370234200241306a41a0c8c100411310292002280230210102400240024020022802342204200228023822056b41044f0d00200541046a22062005490d0420044101742207200620062007491b22074100480d042004450d01200710002208450d052008200120072004200420074b1b10ce0221082001100120072104200821010c020b200541046a21060c010b200710002201450d03200721040b200120056a2003360000200241306a41086a220542003703002002420037033020012006200241306a1002200241106a41086a2005290300370300200220022903303703104100210502400240200241106a411041b8d6c200410041001004417f460d002002200241106a36022020024110360224200242003703382002420037033020024100200241106a4110200241306a41104100100422052005417f461b2205411020054110491b3602282005410f4d0d01200241386a220629030021092002290330210a200241306a200241206a103920022802302205450d0120062802002106200228023421072004450d060c050b20040d040c050b41b2eac10041331040000b411341011019000b1018000b200741011019000b200110010b024002402005450d002002200a20092006ad420010d502200241086a29030021092002290300210a2007450d01200510010c010b4200210a420021090b2000200a37030020002009370308200241c0006a24000b840d03087f017e027f230041f0046b22042400200441086a220542003703002004420037030041dcc8c100411920041002200441e0046a41086a2005290300370300200420042903003703e004024002400240024002400240024002400240200441e0046a411041b8d6c200410041001004417f460d00200441003602b00202400240200441e0046a4110200441b0026a41044100100441016a41044d0d00024020042802b0022205450d00411a10002206450d06200420063602b0022004421a3702b402200441b0026a4188c9c100411a102920042802b002210602400240024020042802b402220720042802b80222086b41044f0d00200841046a22092008490d052007410174220a20092009200a491b220a4100480d052007450d01200a1000220b450d0b200b2006200a20072007200a4b1b10ce02210b20061001200a2107200b21060c020b200841046a21090c010b200a10002206450d09200a21070b200620086a2005417f6a360000200420062009104402402007450d00200610010b2004280208410b460d00200441b0026a200441b00210ce021a20042903b002210c200441b0026a41086a102c200c2001580d00200041b2c9c10036020420004101360200200041086a41c7003602002002102c200441f0046a24000f0b2004200541016a3602b002200441086a220642003703002004420037030041dcc8c100411920041002200441e0046a41086a2006290300370300200420042903003703e004200441e0046a4110200441b0026a41041003200420013703b002200441b0026a41086a200241a00210ce022109200420033a00d804411a10002206450d03200420063602002004421a37020420044188c9c100411a10292004280200210602400240024020042802042208200428020822076b41044f0d00200741046a220a2007490d0420084101742202200a200a2002491b22024100480d042008450d0120021000220b450d09200b200620022008200820024b1b10ce02210820061001200821060c020b200741046a210a200821020c010b200210002206450d070b200620076a2005360000200441003602082004420137030020042903b0022101410810002207450d0420042007360200200442888080808001370204200720013700002009200410a001024002400240024002400240024002400240024002400240024002400240200441d8046a2d000022074103714101460d0020074102470d012004280204200441086a2802002207470d03200741016a22082007490d102007410174220b20082008200b491b220d4100480d102007450d082004280200210e200d1000220b450d18200b200e200d20072007200d4b1b10ce021a200e10010c090b2004280204200441086a2802002207470d01200741016a22082007490d0f2007410174220b20082008200b491b220d4100480d0f2007450d042004280200210e200d1000220b450d16200b200e200d20072007200d4b1b10ce021a200e10010c050b2004280204200441086a2802002207470d02200741016a22082007490d0e2007410174220b20082008200b491b220d4100480d0e2007450d092004280200210e200d1000220b450d17200b200e200d20072007200d4b1b10ce021a200e10010c0a0b200741016a21082004280200210b0c040b200741016a21082004280200210b0c060b200741016a21082004280200210b0c080b200d1000220b450d110b2004200d3602042004200b3602000b200441086a2008360200200b20076a41013a00000c060b200d1000220b450d0f0b2004200d3602042004200b3602000b200441086a2008360200200b20076a41023a00000c030b200d1000220b450d0d0b2004200d3602042004200b3602000b200441086a2008360200200b20076a41003a00000b200441086a2207280200210b2004280204210d2004280200210820074200370300200442003703002006200a20041002200441e0046a41086a2007290300370300200420042903003703e004200441e0046a41102008200b10030240200d450d00200810010b02402002450d00200610010b2009102c200441b8026a41013a0000200441b9026a20033a0000200441bc026a2005360200200441043a00b002200441b0026a10a1012000410036020020002005360204200441f0046a24000f0b41b2eac10041331040000b1018000b41c3d7c10041221040000b411a41011019000b410841011019000b411a41011019000b200241011019000b200a41011019000b200d41011019000b200d41011019000b200d41011019000bee2f02097f017e02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002802002202450d004101210320024101470d010c0a0b20014100101f0240200041086a28020022024102470d0020014100101f200041e0016a2001101b200041106a290300200110e1010240024002400240200141046a2802002206200141086a28020022026b41204f0d00200241206a22032002490d3e20064101742204200320032004491b22054100480d3e2006450d0120012802002107200510002204450d082004200720052006200620054b1b10ce021a200710010c020b200241206a2103200128020021040c020b200510002204450d060b20012004360200200141046a20053602000b200141086a22062003360200200420026a220241186a20004180026a220341186a290000370000200241106a200341106a290000370000200241086a200341086a2900003700002002200329000037000020004199016a2103200041f9006a2104200041396a2105200041196a2107200141046a2802002108200628020021020240024002400240024002400240024002400240200041186a2d00004101470d0020082002470d01200241016a22062002490d4420024101742208200620062008491b22094100480d442002450d032001280200210a200910002208450d0f2008200a20092002200220094b1b10ce021a200a10010c040b20082002470d01200241016a22062002490d4320024101742208200620062008491b22094100480d432002450d052001280200210a200910002208450d0f2008200a20092002200220094b1b10ce021a200a10010c060b200241016a2106200128020021080c030b200241016a2106200128020021080c050b200910002208450d0b0b20012008360200200141046a20093602000b200141086a2006360200200820026a41123a0000200041dc016a280200200110df010c030b200910002208450d090b20012008360200200141046a20093602000b200141086a2006360200200820026a41113a0000200041dc016a280200200110df010b20072001101b20012005101d20042001101b20012003101d200041086a28020021020b024002402002417d6a220341034b0d0002400240024002400240024020030e0400030102000b20014101101f2000410c6a280200200041146a280200200110e30141012103200028020022024101470d070c100b20014103101f2000410c6a280200200041146a2802002001102041012103200028020022024101470d060c0f0b20014104101f2000410c6a2802002102200041146a280200220341c0004f0d0120012003410274101f20030d020c040b20014102101f2000410c6a280200200041146a2802002001102041012103200028020022024101470d040c0d0b024002400240024002400240024002400240024002400240024002402003418080014f0d00200141046a2802002207200141086a28020022046b41024f0d01200441026a22062004490d4a20074101742205200620062005491b22084100480d4a2007450d0520012802002109200810002205450d172005200920082007200720084b1b10ce021a200910010c060b20034180808080044f0d01200141046a2802002207200141086a28020022046b41044f0d02200441046a22062004490d4920074101742205200620062005491b22084100480d492007450d0720012802002109200810002205450d172005200920082007200720084b1b10ce021a200910010c080b200441026a2106200128020021050c050b20014103101f200141046a2802002207200141086a28020022046b41044f0d01200441046a22062004490d4720074101742205200620062005491b22084100480d472007450d0820012802002109200810002205450d162005200920082007200720084b1b10ce021a200910010c090b200441046a2106200128020021050c060b200441046a2106200128020021050c080b200810002205450d110b20012005360200200141046a20083602000b200141086a2006360200200520046a20034102744101723b00000c060b200810002205450d0f0b20012005360200200141046a20083602000b200141086a2006360200200520046a20034102744102723600000c030b200810002205450d0d0b20012005360200200141046a20083602000b200141086a2006360200200520046a20033600000b2002200341186c6a210303402002280200200241086a280200200110202002410c6a280200200241146a28020020011020200241186a22022003470d000b200041086a28020021020b20024101460d022002450d030b41012103200028020022024101460d090b4102210320024102470d090c0b0b41c4fbc000104d000b41c4fbc000104d000b200541011019000b200941011019000b200941011019000b200841011019000b200841011019000b200841011019000b20012003101f0240024002400240200041086a220428020022024102470d0020014100101f2000410c6a200110d001200041306a290300200041386a290300200110e00141032103200428020022024103460d010c020b4103210320024103470d010b20014101101f2000410c6a200110d001200041306a290300200041386a290300200110e001200041c0006a290300200041c8006a290300200110e001200041086a28020020037122024101470d010c030b200220037122024101460d020b2002450d0441022103200028020022024102460d020b4103210320024103470d020c060b41acfbc000104d000b20012003101f0240200041086a2202290300220b4202520d0020014100101f200041106a290300200110e1012002290300210b0b200ba722024101460d022002450d0341032103200028020022024103460d040b4104210320024104470d040c050b41acfbc000104d000b41c0b5c000104d000b41c0b5c000104d000b20012003101f0240200041086a22032d000022024102470d0020014100101f0240024002400240200141046a2802002205200141086a28020022026b41204f0d00200241206a22042002490d2c20054101742206200420042006491b22074100480d2c2005450d0120012802002108200710002206450d0c2006200820072005200520074b1b10ce021a200810010c020b200241206a2104200128020021060c020b200710002206450d0a0b20012006360200200141046a20073602000b200141086a2004360200200620026a220241186a200341196a290000370000200241106a200341116a290000370000200241086a200341096a2900003700002002200329000137000020032d000021020b0240200241ff01714103470d0020014101101f200041106a290300200110e101200041086a2d000021020b0240200241ff01714104470d0020014102101f0240024002400240200141046a280200200141086a2802002202470d00200241016a22042002490d2c20024101742206200420042006491b22054100480d2c2002450d0120012802002107200510002206450d0d2006200720052002200220054b1b10ce021a200710010c020b200241016a2104200128020021060c020b200510002206450d0b0b20012006360200200141046a20053602000b200141086a2004360200200620026a200341016a2d00003a000020032d000021020b200241ff017122024101460d032002450d0441042103200028020022024104460d010b4105210320024105470d010c090b20012003101f02400240200041086a22032d00002202410f714103460d0020024102470d0120014100101f0c010b20014101101f2000410c6a280200200110df0120032d000021020b0240200241ff01714104470d0020014102101f2000410c6a200110d001200041086a2d000021020b0240200241ff01714105470d0020014103101f2000410c6a280200200110df01200041086a2d000021020b0240200241ff01714106470d0020014104101f2000410c6a280200200110df01200041206a280200200110df01200041106a290300200041186a290300200110e001200041086a2d000021020b0240200241ff01714107470d0020014105101f200041106a290300200110e101200041086a2d000021020b0240200241ff01714108470d0020014106101f200041106a290300200110e101200041086a2d000021020b0240200241ff01714109470d0020014107101f2000410c6a280200200110df01200041086a2d000021020b0240200241ff0171410a470d0020014108101f0240024002400240200141046a280200200141086a2802002202470d00200241016a22032002490d2a20024101742204200320032004491b22064100480d2a2002450d0120012802002105200610002204450d0c2004200520062002200220064b1b10ce021a200510010c020b200241016a2103200128020021040c020b200610002204450d0a0b20012004360200200141046a20063602000b200141086a2003360200200420026a200041096a2d00003a0000200041086a2d000021020b0240200241ff0171410b470d0020014109101f2000410c6a280200200110df01200041086a2d000021020b2002410f7122024101460d032002450d0441052103200028020022024105460d080b4106210320024106470d080c090b41f0aec000104d000b41f0aec000104d000b41e8cac000104d000b41e8cac000104d000b200741011019000b200541011019000b200641011019000b20012003101f0240200041086a22032d000022024102470d0020014100101f2000410c6a280200200110a001200041106a290300200041186a290300200110e00120032d000021020b0240200241ff01714103470d0020014101101f2000410c6a280200200110df01200041086a2d000021020b0240200241ff01714104470d0020014102101f2000410c6a280200200110df010240024002400240200141046a280200200141086a2802002202470d00200241016a22032002490d2120024101742204200320032004491b22064100480d212002450d0120012802002105200610002204450d092004200520062002200220064b1b10ce021a200510010c020b200241016a2103200128020021040c020b200610002204450d070b20012004360200200141046a20063602000b200141086a2003360200200420026a200041096a2d00003a0000200041086a2d000021020b0240200241ff01714105470d0020014103101f2000410c6a280200200110a001024002400240200041096a2d000022024103714101460d0020024102470d0120014102101f0c020b20014101101f0c010b20014100101f0b200041086a2d000021020b0240200241ff01714106470d0020014104101f2000410c6a280200200110df01200041086a2d000021020b200241ff017122024101460d022002450d0341062103200028020022024106460d010b4107210320024107470d140c170b20012003101f02400240200041086a220328020022024102470d0020014100101f2000410c6a280200200041146a280200200110e401200041186a280200200110df01200328020022024103460d010c050b20024103470d040b20014101101f2000410c6a280200200110df01200041106a200110d001200041346a280200200110df01200041386a280200200110df01200041086a28020022024104460d040c050b41b0a3c000104d000b41b0a3c000104d000b200641011019000b20024104470d010b20014102101f2000410c6a280200200110df01200041086a28020022024105460d010c020b20024105470d010b20014103101f2000410c6a280200200110df01200041086a28020022024106460d010c020b20024106470d010b20014104101f2000410c6a200110d001200041386a290300200041c0006a290300200110e001200041306a280200200110df01200041086a28020022024107460d010c020b20024107470d010b20014105101f2000410c6a280200200110df0141082103200041086a28020022024108460d010c020b4108210320024108470d010b20014106101f2000410c6a200110d001200020036a28020022024109460d010c020b20024109470d010b20014107101f200041106a290300200110e101200041086a2802002202410a460d010c020b2002410a470d010b20014108101f200041106a290300200110e101200041086a28020022024101470d010c040b20024101460d030b2002450d0141072103200028020022024107460d030b4108210320024108470d030c040b41fce8c000104d000b41fce8c000104d000b20012003101f0240200041086a22032d000022024102470d0020014100101f2000410c6a280200200110a00120032d000021020b0240200241ff01714103470d0020014101101f200341016a2001101b0240024002400240200141046a280200200141086a2802002202470d00200241016a22042002490d0820024101742206200420042006491b22054100480d082002450d0120012802002107200510002206450d0d2006200720052002200220054b1b10ce021a200710010c020b200241016a2104200128020021060c020b200510002206450d0b0b20012006360200200141046a20053602000b200141086a2004360200200620026a200341216a2d00003a000020032d000021020b0240200241ff01714104470d0020014102101f200341016a2001101b20032d000021020b0240200241ff01714105470d0020014103101f200041106a290300200110e101200041086a2d000021020b0240200241ff01714106470d0020014104101f200041106a290300200110e101200041086a2d000021020b200241ff017122024101460d042002450d0541082103200028020022024108460d010b4109210320024109470d010c090b20012003101f024020002d000422024102470d0020014100101f200041086a280200200110df012000410c6a280200200110a00120002d000421020b0240200241ff01714103470d0020014101101f200041046a220341016a2001101b200041286a280200200110df010240024002400240200141046a280200200141086a2802002202470d00200241016a22042002490d0620024101742206200420042006491b22054100480d062002450d0120012802002107200510002206450d0c2006200720052002200220054b1b10ce021a200710010c020b200241016a2104200128020021060c020b200510002206450d0a0b20012006360200200141046a20053602000b200141086a2004360200200620026a200341216a2d00003a000020032d000021020b200241037122024101460d042002450d0541092103200028020022024109460d080b410a21032002410a470d090c080b1018000b41b093c100104d000b41b093c100104d000b41f4b1c000104d000b41f4b1c000104d000b200541011019000b200541011019000b20012003101f0240200041086a22032d000022024102470d0020014100101f200041306a290300200041386a290300200110e001200341016a2001101b20032d000021020b0240200241ff01714103470d0020014101101f200041106a290300200041186a290300200110e001200041086a2d000021020b0240200241ff01714104470d0020014102101f2000410c6a280200200110df01200041186a290300200041206a290300200110e001200041286a290300200110e101200041106a280200200110df01200041086a2d000021020b0240200241ff01714105470d0020014103101f2000410c6a280200200110df01200041086a2d000021020b0240200241ff01714106470d0020014104101f2000410c6a280200200110df01200041086a2d000021020b200241ff017122024101460d022002450d03410a21032000280200410a470d010b20012003101f0240200041086a22032d000022024102470d0020014100101f200341016a2001101b200041386a290300200041c0006a290300200110e001200041c8006a290300200110e1012000412c6a280200200041346a2802002001102020032d000021020b0240200241ff01714103470d0020014101101f200041286a290300200041306a290300200110e001200041386a290300200110e1012000410c6a280200200041146a28020020011020200041186a280200200041206a28020020011020200041086a2d000021020b200241037122014101460d032001450d040b0f0b41e48ac100104d000b41e48ac100104d000b4198a3c000104d000b4198a3c000104d000bd60903077f017e077f23004190036b22012400200141106a10f301200128021421022001280210210341082104200141a8016a41086a22054200370300200142003703a801418dacc200410d200141a8016a1002200141186a41086a2005290300370300200120012903a8013703184100210602400240024002400240024002400240024002400240024002400240200141186a411041b8d6c200410041001004417f460d002001421037022c2001200141186a360228200141086a200141286a10352001280208450d08200128020c2207ad42f8007e2208422088a70d032008a72205417f4c0d032005450d01200510002204450d042007450d020c050b4100210a0c050b4108210420070d030b410021064100210a2004450d050c030b102e000b200541081019000b200141a8016a41f4006a2109410021052007210a410021060340200141a8016a200141286a10bd02200141a0026a200141a8016a41f00010ce021a200141a8016a41f0006a280200220b4102460d022009280200210c200141386a200141a0026a41f00010ce021a02402006200a470d00200a41016a220d200a490d07200a410174220e200d200d200e491b220ead42f8007e2208422088a70d072008a7220d4100480d0702400240200a450d00200d1000220f450d0a200f2004200d200a41f8006c220a200a200d4b1b10ce02210a20041001200a21040c010b200d10002204450d090b200e210a0b200420056a200141386a41f00010ce02220d41f4006a200c360200200d41f0006a200b360200200541f8006a2105200641016a22062007490d000b0b200141a8016a200041f00010ce021a2006200a470d03200641016a22052006490d042006410174220a20052005200a491b220aad42f8007e2208422088a70d042008a722054100480d042006450d0220051000220b450d06200b20042005200641f8006c220c200c20054b1b10ce02210520041001200521040c030b02402006450d00200441186a2101034002400240200141686a2d00002206410f714105460d0020064104470d01200141706a2d00000d012001417c6a280200450d01200141786a2802001001200141f8006a2101200541887f6a22050d020c030b2001416c6a2d00004103470d000240200141746a280200450d00200141706a28020010010b2001280200450d002001417c6a28020010010b200141f8006a2101200541887f6a22050d000b0b200a450d00200410010b41b2eac10041331040000b200510002204450d030b2004200641f8006c220b6a200141a8016a41f00010ce02220541f4006a200236020020052003453602702001200a3602ac01200120043602a8012001200641016a22053602b0012001410d3602a4022001418dacc2003602a002200141a8016a200141a0026a101a02402005450d00200b41f8006a210c41002105034002400240200420056a22062d0000220b410f714105460d00200b4104470d01200641086a2d00000d01200641146a280200450d01200641106a2802001001200c200541f8006a2205470d020c030b200641046a2d00004103470d0002402006410c6a280200450d00200641086a28020010010b200641186a280200450d00200641146a28020010010b200c200541f8006a2205470d000b0b0240200a450d00200410010b20014190036a24000f0b1018000b200d41081019000b200541081019000ba00a010b7f230041d0006b22012400024002400240024002400240024002400240411a10002202450d00200120023602082001421a37020c200141086a4188c9c100411a1029200128020821020240024002400240200128020c2203200128021022046b41044f0d00200441046a22052004490d0320034101742206200520052006491b22064100480d032003450d01200610002207450d082007200220062003200320064b1b10ce0221072002100120062103200721020c020b200441046a21050c010b200610002202450d06200621030b200220046a2000360000200141c0006a41086a220442003703002001420037034020022005200141c0006a1002200141306a41086a200429030037030020012001290340370330200141306a4110100a02402003450d00200210010b411310002202450d02200120023602082001421337020c200141086a41f5c8c10041131029200128020821020240024002400240200128020c2203200128021022046b41044f0d00200441046a22052004490d0420034101742206200520052006491b22064100480d042003450d01200610002207450d0a2007200220062003200320064b1b10ce02210320021001200321020c020b200441046a21050c020b200610002202450d080b200621030b200220046a2000360000200141c0006a41086a220442003703002001420037034020022005200141c0006a1002200141306a41086a200429030037030020012001290340370330200141306a4110100a02402003450d00200210010b411310002202450d03200120023602082001421337020c200141086a41f5c8c10041131029200128020821020240024002400240200128020c2203200128021022046b41044f0d00200441046a22052004490d0420034101742206200520052006491b22064100480d042003450d01200610002207450d0b2007200220062003200320064b1b10ce02210320021001200321020c020b200441046a21050c020b200610002202450d090b200621030b200220046a2000360000200141c0006a41086a220442003703002001420037034020022005200141c0006a1002200141306a41086a200429030037030020012001290340370330410021040240200141306a411041b8d6c200410041001004417f460d00200142103702442001200141306a360240200141086a200141c0006a103920012802082208450d05200141106a2802002104200128020c21092003450d0a0c090b410121084100210920030d080c090b1018000b411a41011019000b411341011019000b411341011019000b41b2eac10041331040000b200641011019000b200641011019000b200641011019000b200210010b024002402004450d0020044105742107200141086a410472210320082102034020032002290000370000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a29000037000020012000360208411010002204450d022001200436024020014210370244200141c0006a41a2c9c10041101029200141306a41086a2204200141c0006a41086a220528020036020020012001290340370330200141086a200141306a10a3012004280200210a2001280234210b2001280230210620054200370300200142003703402006200a200141c0006a10022004200529030037030020012001290340370330200141306a4110100a0240200b450d00200610010b200241206a2102200741606a22070d000b0b02402009450d00200810010b200141d0006a24000f0b411041011019000b870201067f2000280200200110df01024002400240024002400240200141046a2802002202200141086a28020022036b41204f0d00200341206a22042003490d0420024101742205200420042005491b22064100480d042002450d0120012802002107200610002205450d052005200720062002200220064b1b10ce021a200710010c020b200341206a2104200128020021050c020b200610002205450d030b20012005360200200141046a20063602000b200141086a2004360200200520036a220141186a2000411c6a290000370000200141106a200041146a290000370000200141086a2000410c6a290000370000200120002900043700000f0b1018000b200641011019000b851404027f017e107f067e23004190096b22022400200241086a2001103302400240024002400240024002402002280208450d000240200228020c2203450d002003ad2104410021054100210603402005417f460d04200442ffffffff0f832004422088a741016a2205ad422086842104200641016a22062003490d000b0b200241003a00c003200241c0036a2001280200220320012802042205410047220610ce021a2001200520066b3602042001200320066a3602002005450d0420022d00c003220541ff00714101470d042005411874411875417f4c0d01420221040c060b2000420337037020024190096a24000f0b200241a8086a200110a50102400240024020022d00a8084102460d0020024180086a41206a200241a8086a41206a28020036020020024180086a41186a200241a8086a41186a29030037030020024180086a41106a200241a8086a41106a29030037030020024180086a41086a200241a8086a41086a290300370300200220022903a8083703800820012802002103200241c0036a200141046a2207280200220641c000200641c000491b22056a4100410041c00020056b2005413f4b1b10d0021a200241c0036a2003200510ce021a2007200620056b22083602002001200320056a220536020002402006413f4d0d00200241e0056a41386a2206200241c0036a41386a2203290000370300200241e0056a41306a2209200241c0036a41306a220a290000370300200241e0056a41286a220b200241c0036a41286a220c290000370300200241e0056a41206a220d200241c0036a41206a220e290000370300200241e0056a41186a220f200241c0036a41186a2210290000370300200241e0056a41106a2211200241c0036a41106a2212290000370300200241e0056a41086a2213200241c0036a41086a2214290000370300200220022900c0033703e005200320062903002204370300200a20092903002215370300200c200b2903002216370300200e200d29030022173703002010200f290300221837030020122011290300221937030020142013290300221a370300200241d0086a41086a201a370300200241d0086a41106a2019370300200241d0086a41186a2018370300200241d0086a41206a2017370300200241d0086a41286a2016370300200241d0086a41306a2015370300200241d0086a41386a2004370300200220022903e00522043703d008200220043703c003200242003703c003200241c0036a20052008410820084108491b220610ce021a2007200820066b22033602002001200520066a2205360200200841074d0d0120022903c0032115200241003a00c003200241c0036a20052003410047220610ce021a200141046a200320066b22083602002001200520066a22053602002003450d0120023100c0032217500d02200241003a00c003200241c0036a20052008410047220610ce021a200141046a200820066b3602002001200520066a3602002008450d0142022017420f838622164204540d014201210420023100c0034208862017844204882016420c882217420120174201561b7e22172016540d030c010b200241c0036a41386a200241e0056a41386a290000370300200241c0036a41306a200241e0056a41306a290000370300200241c0036a41286a200241e0056a41286a290000370300200241c0036a41206a200241e0056a41206a290000370300200241c0036a41186a200241e0056a41186a290000370300200241c0036a41106a200241e0056a41106a290000370300200241c0036a41086a200241e0056a41086a290000370300200220022900e0053703c0030b420221040c030b420021040b200241f8006a41206a20024180086a41206a280200360200200241f8006a41186a20024180086a41186a290300370300200241f8006a41106a20024180086a41106a290300370300200241f8006a41086a20024180086a41086a290300370300200241a0016a41086a200241d0086a41086a290300370300200241a0016a41106a200241d0086a41106a290300370300200241a0016a41186a200241d0086a41186a290300370300200241a0016a41206a200241d0086a41206a290300370300200241a0016a41286a200241d0086a41286a290300370300200241a0016a41306a200241d0086a41306a290300370300200241a0016a41386a200241d0086a41386a2903003703002002200229038008370378200220022903d0083703a0010c010b1018000b200241e0056a41206a2205200241f8006a41206a280200360200200241e0056a41186a2206200241f8006a41186a290300370300200241e0056a41106a2203200241f8006a41106a290300370300200241e0056a41086a2208200241f8006a41086a290300370300200241c0036a41086a2207200241a0016a41086a290300370300200241c0036a41106a2209200241a0016a41106a290300370300200241c0036a41186a220a200241a0016a41186a290300370300200241c0036a41206a220b200241a0016a41206a290300370300200241c0036a41286a220c200241a0016a41286a290300370300200241c0036a41306a220d200241a0016a41306a290300370300200241c0036a41386a220e200241a0016a41386a290300370300200220022903783703e005200220022903a0013703c00320044202520d010b2000420337037020024190096a24000f0b200241d0006a41206a2005280200360200200241d0006a41186a2006290300370300200241d0006a41106a2003290300370300200241d0006a41086a2008290300370300200241106a41086a2007290300370300200241106a41106a2009290300370300200241106a41186a200a290300370300200241106a41206a200b290300370300200241106a41286a200c290300370300200241106a41306a200d290300370300200241106a41386a200e290300370300200220022903e005370350200220022903c0033703100b200241c0036a200110a60120022802c0032105200241e0056a200241c0036a410472419c0210ce021a02402005410b470d002000420337037020024190096a24000f0b200241a0016a200241e0056a419c0210ce021a2000201537030020002002290350370308200041106a200241d0006a41086a290300370300200041186a200241d0006a41106a290300370300200041206a200241d0006a41186a290300370300200041286a200241d0006a41206a2802003602002000200229031037022c200041346a200241106a41086a2903003702002000413c6a200241106a41106a290300370200200041c4006a200241106a41186a290300370200200041cc006a200241106a41206a290300370200200041d4006a200241106a41286a290300370200200041dc006a200241c0006a290300370200200041e4006a200241c8006a290300370200200020163703782000200437037020004180016a201737030020004188016a20053602002000418c016a200241a0016a419c0210ce021a20024190096a24000bfb0701067f230041f0006b22022400200241003a0050200241d0006a2001280200220320012802042204410047220510ce021a2001200420056b22063602042001200320056a22053602000240024002402004450d0020022d0050220441f0014f0d01410121010c020b200041023a0000200241f0006a24000f0b024002400240024002400240200441847e6a220441034b0d0002400240024020040e0400040102000b200241003b0150200241d0006a20052006410220064102491b220410ce021a200141046a200620046b3602002001200520046a36020041012101200641014d0d0641ef01210420022f015041ef014b0d08200041023a0000200241f0006a24000f0b200041023a0000200141046a20062006410420064104491b22006b3602002001200520006a360200200241f0006a24000f0b41002103200241d0006a2006412020064120491b22046a41004100412020046b2004411f4b1b10d0021a200241d0006a2005200410ce021a200141046a200620046b3602002001200520046a3602002006411f4d0d022002412c6a41026a200241d0006a41026a2d00003a0000200241186a200241df006a290000370300200241206a200241e7006a290000370300200241286a200241d0006a411f6a2d00003a0000200220022f00503b012c2002200229005737031020022800532104410121030c030b200041023a0000200241f0006a24000f0b20024100360250200241d0006a20052006410420064104491b220410ce021a200141046a200620046b3602002001200520046a360200200641034d0d0341ffff03210441012101200228025041ffff034b0d04200041023a0000200241f0006a24000f0b0b200241cc006a41026a22012002412c6a41026a2d00003a0000200241306a41086a2205200241106a41086a290300370300200241306a41106a2206200241106a41106a290300370300200241306a41186a2207200241106a41186a2d00003a0000200220022f012c3b014c2002200229031037033002402003450d002002410c6a41026a20012d00003a0000200241d0006a41086a2005290300370300200241d0006a41106a2006290300370300200241d0006a41186a20072d00003a0000200220022f014c3b010c20022002290330370350410021010c030b200041023a0000200241f0006a24000f0b200041023a0000200241f0006a24000f0b200041023a0000200241f0006a24000f0b200020022f010c3b0001200020013a0000200041046a2004360200200041086a2002290350370200200041036a2002410e6a2d00003a0000200041106a200241d0006a41086a290300370200200041186a200241d0006a41106a290300370200200041206a200241d0006a41186a280200360200200241f0006a24000bfda0010d097f027e057f017e017f027e087f027e127f077e047f027e057f230041b00e6b22022400200241003a00f009200241f0096a2001280200220320012802042204410047220510ce021a2001200420056b22063602042001200320056a220536020002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402004450d0020022d00f0092204410a4b0d0b024020040e0b00070405020809060b030a000b200241003a00f009200241f0096a20052006410047220410ce021a200141046a200620046b22033602002001200520046a22053602002006450d0e4107210420022d00f009220641044b0d9f01024020060e05002d21261c000b200241c0066a20034120200341204922071b22066a41004100412020066b2006411f4b1b10d0021a200241c0066a2005200610ce021a200141046a2208200320066b22033602002001200520066a220536020020070d52200220022f00c1063b01f00920022d00c006210920022800c306210a20022900c706210b20022900cf06210c20022800d706210d20022d00db06210e20022d00dc06210f20022f00dd06211020022d00df062111200220022f01f00922063b01900c200220063b01a805200242003703f009200241f0096a20052003410820034108491b220610ce021a2008200320066b22073602002001200520066a2206360200200341074d0d6520022903f0092112200241c0066a2007412020074120491b22056a41004100412020056b2005411f4b1b10d0021a200241c0066a2006200510ce021a200141046a2213200720056b22033602002001200620056a22053602002007411f4d0d64200241f0096a41186a2206200241c0066a41186a290000370300200241f0096a41106a2207200241c0066a41106a290000370300200241f0096a41086a2208200241c0066a41086a290000370300200220022900c0063703f009200241900c6a41086a2008290300370300200241900c6a41106a2007290300370300200241900c6a41186a2006290300370300200220022903f0093703900c200220022f00910c3b01880720022d00900c210720022800930c210820022900970c2114200229009f0c211520022800a70c211620022d00ab0c211720022d00ac0c211820022f00ad0c211920022d00af0c211a200220022f0188073b01d007200220022f01d00722063b01900c200220063b01aa05200241003a00f009200241f0096a20052003410047220610ce021a2013200320066b221b3602002001200520066a22053602002003450d840141014102410320022d00f00922064112461b20064111461b22064103460d840120064101470d76200241003602f009200241f0096a2005201b4104201b4104491b220610ce021a200141046a221c201b20066b22133602002001200520066a2206360200201b41034d0d840120022802f0092103200241c0066a201341202013412049221b1b22056a41004100412020056b2005411f4b1b10d0021a200241c0066a2006200510ce021a201c201320056b22133602002001200620056a2206360200201b0d7c200220022f00c1063b01f00920022d00c006211c20022800c306211d20022900c706211e20022900cf06211f20022800d706212020022d00db06212120022d00dc06212220022f00dd06212320022d00df062124200220022f01f00922053b01900c200220053b01ce07200241f0096a201341c000201341c000491b22056a4100410041c00020056b2005413f4b1b10d0021a200241f0096a2006200510ce021a200141046a2225201320056b221b3602002001200620056a22063602002013413f4d0d7e200241900c6a41386a2205200241f0096a41386a2213290000370300200241900c6a41306a2226200241f0096a41306a2227290000370300200241900c6a41286a2228200241f0096a41286a2229290000370300200241900c6a41206a222a200241f0096a41206a222b290000370300200241900c6a41186a222c200241f0096a41186a222d290000370300200241900c6a41106a222e200241f0096a41106a222f290000370300200241900c6a41086a2230200241f0096a41086a2231290000370300200220022900f0093703900c201320052903002232370300202720262903002233370300202920282903002234370300202b202a2903002235370300202d202c2903002236370300202f202e290300223737030020312030290300223837030020024188076a41086a203837030020024188076a41106a203737030020024188076a41186a203637030020024188076a41206a203537030020024188076a41286a203437030020024188076a41306a203337030020024188076a41386a2032370300200220022903900c223237038807200220323703f009200220022f01ce073b01cc07200241c0066a201b4120201b4120491b22056a41004100412020056b2005411f4b1b10d0021a200241c0066a2006200510ce021a2025201b20056b22133602002001200620056a2225360200201b411f4d0d8001200220022f00c1063b01f00920022d00c006211b20022800c306212620022900c706213220022900cf06213320022800d706212720022d00db06212820022d00dc06212920022f00dd06212a20022d00df06212b200220022f01f00922053b01900c200220053b01ce0741002105200241f0096a201341c000201341c000491b22066a4100410041c00020066b2006413f4b1b10d0021a200241f0096a2025200610ce021a200141046a201320066b3602002001202520066a3602002013413f4d0d8201200241900c6a41386a222f200241f0096a41386a2201290000370300200241900c6a41306a2230200241f0096a41306a2206290000370300200241900c6a41286a2231200241f0096a41286a2213290000370300200241900c6a41206a2239200241f0096a41206a2225290000370300200241900c6a41186a223a200241f0096a41186a222c290000370300200241900c6a41106a223b200241f0096a41106a222d290000370300200241900c6a41086a223c200241f0096a41086a222e290000370300200220022900f0093703900c2001202f2903002234370300200620302903002235370300201320312903002236370300202520392903002237370300202c203a2903002238370300202d203b290300223d370300202e203c290300223e370300200241c0066a41086a203e370300200241c0066a41106a203d370300200241c0066a41186a2038370300200241c0066a41206a2037370300200241c0066a41286a2036370300200241c0066a41306a2035370300200241c0066a41386a2034370300200220022903900c22343703c006200220343703f009200220022f01ce073b018607202e20024188076a41086a290300370300202d20024188076a41106a290300370300202c20024188076a41186a290300370300202520024188076a41206a290300370300201320024188076a41286a290300370300200620024188076a41306a290300370300200120024188076a41386a290300370300200220022f01cc073b01ce0720022002290388073703f0090c770b2000410b360200200241b00e6a24000f0b200241003a00f009200241f0096a20052006410047220410ce021a200141046a200620046b22033602002001200520046a22043602002006450d4c20022d00f009220541094b0d4c41022107024020050e0a4c004345414849464b424c0b200241003602f009200241f0096a200420034104200341044922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d4c20022802f0092206410876210d410321070c460b200241003a00f009200241f0096a20052006410047220410ce021a200141046a200620046b22033602002001200520046a22053602002006450d0a4107210420022d00f009220641044b0d9e01024020060e05001b171a16000b200242003703f809200242003703f009200241f0096a200520034110200341104922071b220610ce021a200141046a2208200320066b22033602002001200520066a220636020020070d9e01200241f0096a41086a290300211220022903f0092114200241900c6a2003412020034120491b22056a41004100412020056b2005411f4b1b10d0021a200241900c6a2006200510ce021a2008200320056b3602002001200620056a3602002003411f4d0d52200220022f00910c3b01f00920022d00af0c210120022900a70c2115200229009f0c210b20022900970c210c20022800930c2105200220022d00900c3a00c006200220053600c3062002200c3700c7062002200b3700cf06200220153700d706200220013a00df06200220022f01f00922043b018807200220043b00c1064102210420024198026a41026a200241c0066a41026a2d00003a0000200241d0076a41086a20022900cf06370300200241e0076a20022900d706370300200220022f00c0063b019802200220022900c7063703d0072001ad42ff018321150c9f010b200241003a00f009200241f0096a20052006410047220410ce021a200141046a200620046b22033602002001200520046a22043602002006450d0820022d00f0090d08200242003703f009200241f0096a20042003410820034108491b220510ce021a200141046a200320056b3602002001200420056a360200200341074d0d0820022903f0092112200041086a420237030020004102360200200041106a2012370300200241b00e6a24000f0b200241003a00f009200241f0096a20052006410047220410ce021a200141046a200620046b22033602002001200520046a22043602002006450d2f20022d00f0092205450d1120054101460d1020054102470d2f200241003a00f009200241f0096a20042003410047220510ce021a41042108200141046a200320056b3602002001200420056a3602002003450d2f20022d00f00941017121170c120b200241003a00f009200241f0096a20052006410047220410ce021a200141046a200620046b22033602002001200520046a22043602002006450d1e20022d00f009220541044b0d1e024020050e050021191c15000b200110aa022204450d1e410221050c1d0b200241003a00f009200241f0096a20052006410047220410ce021a200141046a200620046b3602002001200520046a3602002006450d0a20022d00f0092204450d0820044101470d0a200241f0096a200110a501200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922044102460d0a2002418c0a6a2802002105200241900a6a28020021082002418a0a6a2f01002116200241890a6a2d00002117200241880a6a2d00002118200241840a6a28020021192002419b0c6a290000210b20022900930c211220022f01900c210a20022d00920c210d200242003703f809200242003703f009200241f0096a20012802002209200141046a221a2802002206411020064110491b220310ce021a201a200620036b22073602002001200920036a22033602002006410f4d0d0a200241f8096a220e290300211420022903f0092115200242003703f809200242003703f009200241f0096a20032007411020074110491b220610ce021a201a200720066b3602002001200320066a3602002007410f4d0d0a2005411076210620054108762103200a200d411074722101200b422088a72109200ba7210a200e290300210b20022903f009210c410321070c090b200241003a00f009200241f0096a20052006410047220410ce021a200141046a200620046b22033602002001200520046a22043602002006450d2e20022d00f009220541044b0d2e024020050e050028242718000b200110aa022204450d2e200242003703f809200242003703f009200241f0096a20012802002203200141046a22072802002205411020054110491b220610ce021a2007200520066b3602002001200320066a3602002005410f4d0d2d200241f8096a290300211220022903f0092114410221050c290b200241003a00f009200241f0096a20052006410047220410ce021a200141046a200620046b22033602002001200520046a22043602002006450d8c0120022d00f009220541084b0d8c01024020050e09003330312f34363237000b200241286a200110332002280228450d8c01200228022c2217417f4c0d7d2017450d57201710002205450d8601200141046a22182802002104200128020021062017ad2112410021070340200241003a00f009200241f0096a20062004410047220310ce021a2018200420036b22083602002001200620036a22063602002004450d5f20022d00f009211602402012422088a72012a72204470d00200441016a22032004490d800120044101742219200320032019491b22034100480d8001024002402004450d00200310002219450d8301201920052003200420032004491b10ce02210420051001200421050c010b200310002205450d82010b2012428080808070832003ad8421120b20052012422088a76a20164101713a000020124280808080107c211220082104200741016a22072017490d000c590b0b200241003a00f009200241f0096a20052006410047220410ce021a200141046a200620046b22033602002001200520046a22043602002006450d910120022d00f0092205450d0820054101470d9101200242003703f809200242003703f009200241f0096a200420034110200341104922071b220510ce021a200141046a2208200320056b22063602002001200420056a220436020020070d9101200241f0096a41086a290300211220022903f0092114200242003703f009200241f0096a20042006410820064108491b220510ce021a2008200620056b3602002001200420056a360200200641074d0d910120022903f0092115200241c0006a200110332002280240450d910120022802442204417f4c0d7c2004450d5f200410002205450d860120054100200410d0021a0c600b200241003a00f009200241f0096a20052006410047220410ce021a200141046a200620046b22033602002001200520046a22043602002006450d0920022d00f0092205450d0820054101470d09200241900c6a20034120200341204922071b22056a41004100412020056b2005411f4b1b10d0021a200241900c6a2004200510ce021a41042106200141046a200320056b22033602002001200420056a221936020020070d1c200220022f00910c3b01f00920022d00af0c210520022f00ad0c210720022d00ac0c210820022d00ab0c211620022800a70c2117200229009f0c211220022900970c211420022800930c2104200220022d00900c22183a00c006200220043600c306200220143700c706200220123700cf06200220173600d706200220163a00db06200220083a00dc06200220073b00dd06200220053a00df06200220022f01f00922063b018807200220063b00c106200241003602f00941042106200241f0096a20192003410420034104491b221a10ce021a200141046a2003201a6b220936020020012019201a6a2219360200200341034d0d1d20022802f0092103200241003a00f009200241f0096a20192009410047221a10ce021a41042106200141046a2009201a6b36020020012019201a6a3602002009450d1d2014422088a721192014a7210120022d00f00921062002200241c0066a41016a2f00003b01d0072006410171211a410321060c1e0b2000410b360200200241b00e6a24000f0b2000410b360200200241b00e6a24000f0b410721040c93010b410721040c90010b200241f0096a200110a501200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922044102460d012002418c0a6a2802002105200241900a6a28020021082002418a0a6a2f01002116200241890a6a2d00002117200241880a6a2d00002118200241840a6a2802002119200228009f0c2109200228009b0c210a20022900930c211220022f01900c210d20022d00920c210e200242003703f809200242003703f009200241f0096a20012802002207200141046a221a2802002206411020064110491b220310ce021a201a200620036b3602002001200720036a3602002006410f4d0d012005411076210620054108762103200d200e411074722101200241f8096a290300211420022903f0092115410221070b200020013b000d20004101360200200020173a0025200020033a0029200020063b002a2000410f6a20014110763a0000200041386a2014370200200041306a2015370200200041c8006a200b370200200041c0006a200c370200200041086a20073602002000410c6a20043a0000200041106a2012370000200041186a200a3600002000411c6a2009360000200041206a2019360000200041246a20183a0000200041266a20163b0000200041286a20053a00002000412c6a2008360000200241b00e6a24000f0b2000410b360200200241b00e6a24000f0b200241900c6a20034120200341204922071b22056a41004100412020056b2005411f4b1b10d0021a200241900c6a2004200510ce021a200141046a2208200320056b22063602002001200420056a220436020020070d1a200220022f00910c3b01f00920022d00af0c210520022900a70c2112200229009f0c211420022900970c211520022800930c2103200220022d00900c3a00c006200220033600c306200220153700c706200220143700cf06200220123700d706200220053a00df06200220022f01f00922053b018807200220053b00c106200242003703f809200242003703f009200241f0096a20042006411020064110491b220510ce021a2008200620056b22033602002001200420056a22053602002006410f4d0d40200241f0096a41086a290300210b20022903f0092115200242003703f009200241f0096a20052003410820034108491b220610ce021a41042104200141046a200320066b3602002001200520066a360200200341074d0d850120022903f009210c200241306a200110332002280230450d850120022802342205417f4c0d732005450d5b200510002207450d7e20074100200510d0021a0c5c0b200241003602f009200241f0096a200420034104200341044922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d0020022802f0092104200110aa022201450d00200220022f01d0073b01f009410221060c160b200220022f01d0073b01f0090c89010b200242003703f009200241f0096a200420034108200341084922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d1e20022903f0092212422088a721182012a72119410321080c010b200241900c6a20034120200341204922061b22056a41004100412020056b2005411f4b1b10d0021a200241900c6a2004200510ce021a200141046a200320056b3602002001200420056a36020020060d1c200220022f00910c3b01f00920022d00af0c210620022f00ad0c210520022d00ac0c210420022d00ab0c210120022800a70c2103200229009f0c211220022900970c211420022800930c2107200220022d00900c22173a00c006200220073600c306200220143700c706200220123700cf06200220033600d706200220013a00db06200220043a00dc06200220053b00dd06200220063a00df06200220022f01f00922083b018807200220083b00c106200220022f00c10622083b01ce07200220083b01d0072014422088a721182014a72119410221080b200220022f01d00722163b01f009200220163b01e003200041086a20083a000020004103360200200020173a00092000410c6a2007360200200041106a2019360200200041146a2018360200200041186a2012370200200041206a2003360200200041246a20013a0000200020043a0025200041266a20053b0100200041286a20063a0000200020022f01e0033b000a200241b00e6a24000f0b200241003602f009200241f0096a200520034104200341044922071b220610ce021a200141046a200320066b3602002001200520066a36020020070d880120022802f0092105410621040c89010b200241003602f009200241f0096a20052003410420034104491b220610ce021a200141046a2208200320066b22073602002001200520066a2206360200200341034d0d870120022802f0092105200242003703f809200242003703f009200241f0096a200620074110200741104922161b220310ce021a2008200720036b22073602002001200620036a220636020020160d8701200241f0096a41086a290300211220022903f0092114200242003703f009200241f0096a20062007410820074108491b220410ce021a200141046a2208200720046b22033602002001200620046a220636020041072104200741074d0d870120022903f0092115200241003602f009200241f0096a20062003410420034104491b220710ce021a2008200320076b3602002001200620076a360200200341034d0d870120022802f0092101200241e0076a2012370300200220143703d807200220013602d007410421040c88010b200242003703f009200241f0096a200420034108200341084922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d0920022903f0092212422088a721012012a72117410621050c070b200241206a200110332002280220450d3820022802242219ad221242187e2214422088a70d6a2014a72205417f4c0d6a2005450d3a2005100022130d3b200541041019000b200241003602f009200241f0096a200520034104200341044922071b220610ce021a200141046a200320066b3602002001200520066a36020020070d840120022802f0092105410521040c85010b200242003703f809200242003703f009200241f0096a200520034110200341104922071b220610ce021a200141046a200320066b3602002001200520066a36020020070d830120022903f00921122002200241f8096a2903003703d807200220123703d007410321040c83010b200241900c6a20034120200341204922071b22066a41004100412020066b2006411f4b1b10d0021a200241900c6a2004200610ce021a41042105200141046a200320066b3602002001200420066a36020020070d30200220022f00910c3b01f00920022d00af0c210620022f00ad0c210320022d00ac0c210720022d00ab0c210820022800a70c2116200229009f0c211220022900970c211420022800930c2104200220022d00900c22183a00c006200220043600c306200220143700c706200220123700cf06200220163600d706200220083a00db06200220073a00dc06200220033b00dd06200220063a00df06200220022f01f00922013b018807200220013b00c106200220022f00c1063b01d0072014422088a721012014a721170c3e0b200241003602f009200241f0096a200420034104200341044922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d1620022802f0092104410621050c100b200220011033410021062002280200450d5320022802042205417f4c0d652005450d37200510002208450d6c20084100200510d0021a0c380b200242003703f009200241f0096a200420034108200341084922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d0220022903f0092212422088a721012012a72117410521050b0b200220022f01d0073b01f0090c3b0b200220022f01d0073b01f0090c780b200241086a20011033410021062002280208450d4e200228020c2205417f4c0d602005450d34200510002208450d6820084100200510d0021a0c350b200241900c6a20034120200341204922061b22056a41004100412020056b2005411f4b1b10d0021a200241900c6a2004200510ce021a200141046a2219200320056b22173602002001200420056a220536020020060d29200220022f00910c3b01f00920022d00900c211820022800930c210420022900970c2114200229009f0c211220022800a70c211620022d00ab0c210820022d00ac0c210720022f00ad0c210320022d00af0c2106200220022f01f009221a3b0188072002201a3b01ce07200241003a00f009200241f0096a20052017410047221a10ce021a20192017201a6b36020020012005201a6a3602002017450d3520022d00f0092101200220022f01ce073b01d007200141017121192014422088a721012014a72117410321050c370b200220022f01f0093b0188070b0b200220022f01d0073b01f00920064104460d740b200220022f01f0093b01e003200020063a000420004108360200200020183a0005200041086a20043602002000410c6a2001360200200041106a2019360200200041146a20123702002000411c6a2017360200200041206a20163a0000200020083a0021200041226a20073b0100200041246a20053a00002000201a3a0025200041286a2003360200200020022f01e0033b0006200241b00e6a24000f0b200241003602f009200241f0096a200420034104200341044922071b220510ce021a200141046a2208200320056b22063602002001200420056a220536020020070d0a20022802f0092104200241003a00f009200241f0096a20052006410047220310ce021a2008200620036b3602002001200520036a3602002006450d0a20022d00f0094101712101410421050c060b200241f0096a2001103220022802f0092206450d7220022902f4092112410321040c480b200220022f01f0093b0188070c6d0b200241f0096a200110a60120022802f0092105200241900c6a200241f0096a410472419c0210ce021a2005410b460d07200241d0076a200241900c6a419c0210ce021a41a00210002204450d5d20042005360200200441046a200241d0076a419c0210ce021a200141046a22032802002105200241003a00f009200241f0096a200128020022072005410047220610ce021a2003200520066b3602002001200720066a3602002005450d0620022d00f009220141034f0d06410521050c030b200241003602f009200241f0096a200420034104200341044922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d0620022802f0092104410321050b0b0b200220022f01e00322063b01f009200220063b019802200041186a2012370200200041106a2014370200200041086a20053a000020004105360200200020013a00092000410c6a2004360200200020022f0198023b000a200241b00e6a24000f0b200220022f01f0093b0188070b200220022f01d0073b01f0092000410b360200200241b00e6a24000f0b2004102c200410010b200220022f01e0033b01f0092000410b360200200241b00e6a24000f0b200241f0096a200110a501200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922054102460d5d2002418c0a6a2802002104200241900a6a28020021072002418a0a6a2f01002119200241890a6a2d0000211a200241880a6a2d00002103200241840a6a2802002108200228009f0c2116200228009b0c211720022900930c210b20022f01900c210e20022d00920c210f200242003703f809200242003703f009200241f0096a2001280200220d200141046a220a2802002206411020064110491b221810ce021a200a200620186b22093602002001200d20186a22183602002006410f4d0d5d200241f8096a290300211220022903f0092114200241003602f009200241f0096a20182009410420094104491b220610ce021a200a200920066b3602002001201820066a360200200941034d0d5d200441107621092004410876210a200e200f411074722101200b420888211520022802f009210d200ba72118410621060c2b0b200241003602f00941042106200241f0096a200420034104200341044922071b220510ce021a200141046a200320056b3602002001200420056a36020020070d5c20022802f009220541087621010c040b200241003602f009200241f0096a200420034104200341044922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d5b20022802f00922054108762101410521060c030b200242003703f009200241f0096a200420034108200341084922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d5a20022903f009221242088821152012a72118410921060c050b200241003602f009200241f0096a200420034104200341044922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d5920022802f0092105200241f0096a200110a501200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922184102460d59200241900a6a280200210d2002418c0a6a28020021072002418a0a6a2f01002109200241890a6a2d0000210a200241880a6a2d00002104200241840a6a2802002103200228009f0c2108200228009b0c211620022800970c211720023502900c211220023301940c211420023100960c2115200241003602f009200241f0096a2001280200220e200141046a220f2802002206410420064104491b221910ce021a200f200620196b221a3602002001200e20196a2219360200200641034d0d5920022802f009210e200241003602f009200241f0096a2019201a4104201a4104491b220610ce021a200f201a20066b3602002001201920066a360200201a41034d0d59200341107621192003410876211a201220142015421086844220868421152005410876210120023502f009211442002112410321060c270b200241003602f009200241f0096a200420034104200341044922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d5820022802f00922054108762101410721060b0c030b200241f0096a200110a50141082106200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922054102460d5620022900930c221242088821152002418c0a6a2802002204410876210a2004411076210920022f01900c20022d00920c4110747221012002419b0c6a2900002214422088a72116200241840a6a2802002108200241880a6a2d00002103200241890a6a2d0000211a2002418a0a6a2f01002119200241900a6a28020021072012a721182014a721170c230b200242003703f009200241f0096a200420034108200341084922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d5520022903f009221242088821152012a72118410a21060b0b0c210b200241003602f009200241f0096a200420034104200341044922061b220510ce021a200141046a2207200320056b22033602002001200420056a220436020020060d0b20022802f0092106200241003602f009200241f0096a200420034104200341044922081b220510ce021a2007200320056b22033602002001200420056a220436020020080d0b20022802f0092116200242003703f809200242003703f009200241f0096a20042003411020034110491b220510ce021a200141046a200320056b3602002001200420056a3602002003410f4d0d0b2006410876210d200241f0096a41086a290300211220022903f0092214a7210f410621070c020b200241003602f009200241f0096a200420034104200341044922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d0a20022802f0092206410876210d410b21070c040b200241f0096a200110a501200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922064102460d092002418c0a6a2802002208410876210a2008411076211a20022f01900c20022d00920c41107472210d2002419b0c6a2900002112200241840a6a2802002116200241880a6a2d00002117200241890a6a2d000021182002418a0a6a2f01002119200241900a6a280200210920022900930c2214a7210f410421070b2014422088a7210e0c070b200241003602f009200241f0096a200420034104200341044922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d0720022802f0092206410876210d410521070c010b200241003602f009200241f0096a200420034104200341044922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d0620022802f0092206410876210d410921070b0c040b200242003703f009200241f0096a200420034108200341084922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d0420022903f0092212422088a7210e2012a7210f410721070c010b200242003703f00941082107200241f0096a200420034108200341084922061b220510ce021a200141046a200320056b3602002001200420056a36020020060d0320022903f0092212422088a7210e2012a7210f0b0c010b200241003a00f009200241f0096a20042003410047220510ce021a200141046a200320056b3602002001200420056a3602002003450d0120022d00f0094101712110410a21070b200220022f01d00722013b01f009200220013b01e003200041086a20073a000020004104360200200020103a00092000410c6a200d410874200641ff017172360200200041106a200f360200200041146a200e360200200041186a2012370200200041206a2016360200200041246a20173a0000200020183a0025200041266a20193b0100200041286a20083a00002000200a3a00292000201a3b012a2000412c6a2009360200200020022f01e0033b000a200241b00e6a24000f0b200220022f01d0073b01f0092000410b360200200241b00e6a24000f0b200220022f01f0093b0188070c010b200220022f01f0093b0188070b410721050c0c0b200220022f01f0093b01900c410221050c130b410421040c440b410021060c1f0b200220022f01f0093b0188070c4b0b410421130b02402019450d00200141046a2106410021170340200241186a200110332002280218450d1d200228021c2205417f4c0d30024002402005450d00200510002208450d3520084100200510d0021a0c010b410121080b20082001280200221620062802002203200520032005491b220710ce0221082006200320076b3602002001201620076a36020020032005490d1c2008450d1d2005ad22144220862014842114200241106a200110332002280210450d1b20022802142205417f4c0d30024002402005450d00200510002216450d3620164100200510d0021a0c010b410121160b20162001280200221820062802002203200520032005491b220710ce0221162006200320076b3602002001201820076a36020020032005490d1a2016450d1b02402012422088a722032012a7470d00200341016a22072003490d3220034101742218200720072018491bad221542187e220b422088a70d32200ba722074100480d32024002402003450d00200710002218450d38201820132007200341186c2203200320074b1b10ce02210320131001200321130c010b200710002213450d370b20124280808080708320158421120b20132012422088a741186c6a22032014370204200320083602002003201636020c200341106a2005ad221442208620148437020020124280808080107c2112201741016a22172019490d000b0b2013450d1441062104201321060c480b410121080b200820012802002216200141046a22172802002203200520032005491b220710ce0221132017200320076b3602002001201620076a3602002005ad221242208620128421120240200320054f0d00201310010c1c0b2013450d0e20132106410421040c460b410121080b200820012802002216200141046a22172802002203200520032005491b220710ce0221132017200320076b3602002001201620076a3602002005ad221242208620128421120240200320054f0d00201310010c1a0b2013450d0f41052104201321060c440b410721050b0b200220022f01d0073b01f00920054107460d3e0b200220022f01f0093b01e003200041086a20053a000020004107360200200020183a00092000410c6a2004360200200041106a2017360200200041146a2001360200200041186a2012370200200041206a2016360200200041246a20083a0000200020073a0025200041266a20033b0100200041286a20063a0000200020193a0029200020022f01e0033b000a200241b00e6a24000f0b42002112410121050b2005450d33200241003602f009200241f0096a20012802002203200141046a22072802002204410420044104491b220610ce021a2007200420066b3602002001200320066a360200200441034d0d0b201242088821152005410876210120022802f00921172012a72118410221060b0b200041063602002000201a3a00252000200a3a0029200020093b012a200041c0006a2012370200200041386a2014370200200041086a2006360200200041186a20173602002000411c6a2016360200200041206a2008360200200041246a20033a0000200041266a20193b0100200041286a20043a00002000412c6a2007360200200041306a200d360200200041346a200e3602002000410c6a2001410874200541ff017172360200200041106a20154208862018ad42ff018384370200200241b00e6a24000f0b200241900c6a41186a200241f0096a41186a290000370300200241900c6a41106a200241f0096a41106a290000370300200241900c6a41086a200241f0096a41086a290000370300200220022900f0093703900c200220022f01d0073b01900c0b410221050b0c2f0b2012a7450d2d0c2c0b201321060c0c0b410121050b200520012802002208200141046a22162802002206200420062004491b220310ce0221072016200620036b3602002001200820036a36020020062004490d102007450d30200241386a200110332004ad220b422086200b84220ba721062002280238450d0f200228023c2204417f4c0d1b2004450d0d200410002203450d2720034100200410d0021a0c0e0b201321060c090b201321060c080b2012a70d260c270b410121070b41042104200720012802002208200141046a22162802002206200520062005491b220310ce0221072016200620036b3602002001200820036a3602000240200620054f0d00200710010c290b2007450d2841022104200241d0076a41026a200241c0066a41026a2d00003a0000200220022f00c0063b01d0072005ad2212422086201284221242088842088620124238862007ad4218868422144238888421122014420886200241df066a310000842114200241db066a2800002108200241cf066a2800002103200241c7066a2800002106200241c3066a280000210520022900d306211e20022800cb0621070c290b201610010b2014a7450d010b200810010b02402012422088a72201450d00200141186c21052013210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141186a2101200541686a22050d000b0b410021062012a7450d00201310010b0b0c2a0b200241003602f009200241f0096a2005201b4104201b4104491b220610ce021a200141046a221c201b20066b22133602002001200520066a2206360200201b41034d0d0d20022802f0092103200241c0066a201341202013412049221b1b22056a41004100412020056b2005411f4b1b10d0021a200241c0066a2006200510ce021a201c201320056b22133602002001200620056a2206360200201b0d06200220022f00c1063b01f00920022d00c006211c20022800c306211d20022900c706211e20022900cf06211f20022800d706212020022d00db06212120022d00dc06212220022f00dd06212320022d00df062124200220022f01f00922053b01900c200220053b01ce07200241f0096a201341c000201341c000491b22056a4100410041c00020056b2005413f4b1b10d0021a200241f0096a2006200510ce021a200141046a2225201320056b221b3602002001200620056a22063602002013413f4d0d08200241900c6a41386a2205200241f0096a41386a2213290000370300200241900c6a41306a2226200241f0096a41306a2227290000370300200241900c6a41286a2228200241f0096a41286a2229290000370300200241900c6a41206a222a200241f0096a41206a222b290000370300200241900c6a41186a222c200241f0096a41186a222d290000370300200241900c6a41106a222e200241f0096a41106a222f290000370300200241900c6a41086a2230200241f0096a41086a2231290000370300200220022900f0093703900c201320052903002232370300202720262903002233370300202920282903002234370300202b202a2903002235370300202d202c2903002236370300202f202e290300223737030020312030290300223837030020024188076a41086a203837030020024188076a41106a203737030020024188076a41186a203637030020024188076a41206a203537030020024188076a41286a203437030020024188076a41306a203337030020024188076a41386a2032370300200220022903900c223237038807200220323703f009200220022f01ce073b01cc07200241c0066a201b4120201b4120491b22056a41004100412020056b2005411f4b1b10d0021a200241c0066a2006200510ce021a2025201b20056b22133602002001200620056a2206360200201b411f4d0d0a200220022f00c1063b01f00920022d00c006211b20022800c306212620022900c706213220022900cf06213320022800d706212720022d00db06212820022d00dc06212920022f00dd06212a20022d00df06212b200220022f01f00922053b01900c200220053b01ce07200241f0096a201341c000201341c000491b22056a4100410041c00020056b2005413f4b1b10d0021a200241f0096a2006200510ce021a200141046a201320056b3602002001200620056a3602002013413f4d0d0c200241900c6a41386a222e200241f0096a41386a2201290000370300200241900c6a41306a222f200241f0096a41306a2205290000370300200241900c6a41286a2230200241f0096a41286a2206290000370300200241900c6a41206a2231200241f0096a41206a2213290000370300200241900c6a41186a2239200241f0096a41186a2225290000370300200241900c6a41106a223a200241f0096a41106a222c290000370300200241900c6a41086a223b200241f0096a41086a222d290000370300200220022900f0093703900c2001202e29030022343703002005202f2903002235370300200620302903002236370300201320312903002237370300202520392903002238370300202c203a290300223d370300202d203b290300223e370300200241c0066a41086a203e370300200241c0066a41106a203d370300200241c0066a41186a2038370300200241c0066a41206a2037370300200241c0066a41286a2036370300200241c0066a41306a2035370300200241c0066a41386a2034370300200220022903900c22343703c006200220343703f009200220022f01ce073b018607202d20024188076a41086a290300370300202c20024188076a41106a290300370300202520024188076a41186a290300370300201320024188076a41206a290300370300200620024188076a41286a290300370300200520024188076a41306a290300370300200120024188076a41386a290300370300200220022f01cc073b01ce0720022002290388073703f009410121050b200241f8056a41086a2201200241f0096a41086a223f290300370300200241f8056a41106a2206200241f0096a41106a2240290300370300200241f8056a41186a2213200241f0096a41186a2241290300370300200241f8056a41206a2225200241f0096a41206a2242290300370300200241f8056a41286a222c200241f0096a41286a290300370300200241f8056a41306a222d200241f0096a41306a290300370300200241f8056a41386a222e200241f0096a41386a290300370300200220022f01ce073b01be06200220022903f0093703f805200241b0056a41086a222f200241c0066a41086a290300370300200241b0056a41106a2230200241c0066a41106a290300370300200241b0056a41186a2231200241c0066a41186a290300370300200241b0056a41206a2239200241c0066a41206a290300370300200241b0056a41286a223a200241c0066a41286a290300370300200241b0056a41306a223b200241c0066a41306a290300370300200241b0056a41386a223c200241c0066a41386a290300370300200220022f0186073b01f605200220022903c0063703b005200241ac056a41026a2243200241900c6a41026a2d00003a0000200220022f00900c3b01ac05200241900c6a41286a2001290300370000200241900c6a41306a2006290300370000200241900c6a41386a2013290300370000200241d00c6a2025290300370000200241d80c6a202c290300370000200241e00c6a202d290300370000200241e80c6a202e2903003700002002201c3a00900c2002201d3600930c2002201e3700970c2002201f37009f0c200220203600a70c200220213a00ab0c200220223a00ac0c200220233b00ad0c200220243a00af0c200220022f01be063b00910c200220022903f8053700b00c200241980d6a202f290300370000200241a00d6a2030290300370000200241a80d6a2031290300370000200241b00d6a2039290300370000200241b80d6a203a290300370000200241c00d6a203b290300370000200241c80d6a203c2903003700002002201b3a00f00c200220263600f30c200220323700f70c200220333700ff0c200220273600870d200220283a008b0d200220293a008c0d2002202a3b008d0d2002202b3a008f0d200220022f01f6053b00f10c200220022903b0053700900d200241d20d6a20432d00003a0000200220022f01ac053b00d00d203f201e3703002040201f370300204120203602002002418c0a6a20213a00002002418d0a6a20223a00002002418e0a6a20233b0100204220243a0000200241910a6a20022903f805370000200241990a6a2001290300370000200241a10a6a2006290300370000200241a90a6a2013290300370000200241b10a6a2025290300370000200241b90a6a202c290300370000200241c10a6a202d290300370000200241c90a6a202e2903003700002002201c3a00f109200220053a00f0092002201d3602f409200220022f01be063b01f209200241d10a6a201b3a0000200241d40a6a2026360200200241d80a6a2032370300200241e00a6a2033370300200241e80a6a2027360200200241ec0a6a20283a0000200241ed0a6a20293a0000200241ee0a6a202a3b0100200241f00a6a202b3a0000200241d20a6a20022f01f6053b0100200241f10a6a20022903b005370000200241f90a6a202f290300370000200241810b6a2030290300370000200241890b6a2031290300370000200241910b6a2039290300370000200241990b6a203a290300370000200241a10b6a203b290300370000200241a90b6a203c290300370000200241b40b6a2003360200200241f0096a41c3016a20432d00003a0000200241b10b6a20022f01ac053b0000200241d0076a200241900c6a41c30110ce021a20054102460d0d0c1b0b410121030b200320012802002217200141046a22182802002208200420082004491b221610ce0221192018200820166b3602002001201720166a3602000240200820044f0d00201910010c010b2019450d00200b422088a721072004ad220b422086200b84211e200241f0096a41026a200241d0076a41026a2d00003a0000200220022f00d0073b01f00941032104200241f0096a21010c200b2006450d200b200710010c1f0b200220022f01f0093b01900c0c070b200220022f01f0093b01900c0c060b200241f0096a41386a200241900c6a41386a290000370300200241f0096a41306a200241900c6a41306a290000370300200241f0096a41286a200241900c6a41286a290000370300200241f0096a41206a200241900c6a41206a290000370300200241f0096a41186a200241900c6a41186a290000370300200241f0096a41106a200241900c6a41106a290000370300200241f0096a41086a200241900c6a41086a290000370300200220022900900c3703f0090c050b200241f0096a41386a200241900c6a41386a290000370300200241f0096a41306a200241900c6a41306a290000370300200241f0096a41286a200241900c6a41286a290000370300200241f0096a41206a200241900c6a41206a290000370300200241f0096a41186a200241900c6a41186a290000370300200241f0096a41106a200241900c6a41106a290000370300200241f0096a41086a200241900c6a41086a290000370300200220022900900c3703f0090c040b200220022f01f0093b01900c0c030b200220022f01f0093b01900c0c020b200241f0096a41386a200241900c6a41386a290000370300200241f0096a41306a200241900c6a41306a290000370300200241f0096a41286a200241900c6a41286a290000370300200241f0096a41206a200241900c6a41206a290000370300200241f0096a41186a200241900c6a41186a290000370300200241f0096a41106a200241900c6a41106a290000370300200241f0096a41086a200241900c6a41086a290000370300200220022900900c3703f0090c010b200241f0096a41386a200241900c6a41386a290000370300200241f0096a41306a200241900c6a41306a290000370300200241f0096a41286a200241900c6a41286a290000370300200241f0096a41206a200241900c6a41206a290000370300200241f0096a41186a200241900c6a41186a290000370300200241f0096a41106a200241900c6a41106a290000370300200241f0096a41086a200241900c6a41086a290000370300200220022900900c3703f0090b200241900c6a41286a200241f8056a41086a290000370000200241900c6a41306a200241f8056a41106a290000370000200241900c6a41386a200241f8056a41186a290000370000200241d00c6a200241f8056a41206a290000370000200241d80c6a200241f8056a41286a290000370000200241e00c6a200241f8056a41306a290000370000200241e80c6a200241f8056a41386a290000370000200220022f01be063b00910c200220022900f8053700b00c200241980d6a200241b0056a41086a290000370000200241a00d6a200241b0056a41106a290000370000200241a80d6a200241b0056a41186a290000370000200241b00d6a200241b0056a41206a290000370000200241b80d6a200241b0056a41286a290000370000200241c00d6a200241b0056a41306a290000370000200241c80d6a200241b0056a41386a290000370000200220022f01f6053b00f10c200220022900b0053700900d41022105200241d20d6a200241ac056a41026a2d00003a0000200220022f00ac053b00d00d41024102470d0e0b410221050c100b102e000b1018000b200341011019000b200541011019000b200541011019000b200741041019000b41a00241081019000b200541011019000b200541011019000b201741011019000b200441011019000b200541011019000b200441011019000b200220022f01a8053b01de03200220022f01aa053b01dc03200241e0036a200241d0076a41c30110ce021a0c030b200510010b2000410b360200200241b00e6a24000f0b0b200241f0096a200241e0036a41c30110ce021a200220022f01de033b01900c200220022f01dc033b01d007024020054102470d000c090b20024198026a200241f0096a41c30110ce021a200220022f01900c3b019602200220022f01d0073b019402410221040c080b0b200241f0096a41026a200241d0076a41026a2d00003a0000200220022f01d0073b01f009200241f0096a210120044104460d020b200241e0036a41026a2216200141026a2d00003a0000200220012f00003b01e003200041306a2012370000200041286a2014370000200041c0006a200b370000200041386a2015370000200041086a20043a00002000410a3602002000410c6a2005360000200041106a2006360000200041146a2007360000200041186a20033600002000411c6a201e370000200041246a2008360000200041c8006a200c370000200020022f01e0033b00092000410b6a20162d00003a0000200241b00e6a24000f0b200241f0096a41026a200241d0076a41026a2d00003a0000200220022f01d0073b01f0090b2000410b360200200241b00e6a24000f0b2000410b360200200241b00e6a24000f0b2000410b360200200241b00e6a24000f0b0b200241f0096a20024198026a41c30110ce021a200220022f0196023b01900c200220022f0194023b01d007024020044107470d002000410b360200200241b00e6a24000f0b200241d0006a200241f0096a41c30110ce021a200220022f01900c3b014e200220022f01d0073b014c200041086a2004360200200041003602002000410c6a2006360200200041106a2012370200200041186a20053a0000200041196a200241d0006a41c30110ce021a200041e0016a20093a0000200041dc016a2003360000200041e3016a200a360000200041e7016a200b370000200041ef016a200c370000200041f7016a200d3600002000200e3a00fb01200041fc016a200f3a0000200041fd016a20103b0000200020113a00ff0120004180026a20073a000020004183026a200836000020004187026a20143700002000418f026a201537000020004197026a2016360000200020022f014e3b00e101200020022f014c3b0081022000419c026a20183a0000200020173a009b022000419d026a20193b00002000201a3a009f02200241b00e6a24000f0b0b200241900c6a41026a220120024198026a41026a2d00003a0000200241f0096a41086a2206200241d0076a41086a290300370300200241f0096a41106a2203200241d0076a41106a290300370300200220022f0198023b01900c200220022903d0073703f009024020044107470d002000410b360200200241b00e6a24000f0b200241d0006a41026a220720012d00003a0000200241e0036a41086a22012006290300370300200241e0036a41106a22062003290300370300200220022f01900c3b0150200220022903f0093703e003200041386a2012370000200041306a2014370000200041086a20043a0000200041093602002000410c6a2005360000200041286a2015370000200020022f01503b00092000410b6a20072d00003a0000200041106a20022903e003370000200041186a2001290300370000200041206a2006290300370000200241b00e6a24000bb41705017f027e017f037e067f230041c0076b2202240002400240200129037022034202520d00200220014188016a41a00210ce021a420021030c010b200241a0026a41206a200141286a280200360200200241a0026a41186a200141206a290200370300200241a0026a41106a200141186a290200370300200241a0026a41086a200141106a290200370300200220012902083703a00220024180036a200141e4006a290000370300200241f8026a200141dc006a290000370300200241c8026a41286a200141d4006a290000370300200241c8026a41206a200141cc006a290000370300200241c8026a41186a200141c4006a290000370300200241c8026a41106a2001413c6a290000370300200241c8026a41086a200141346a2900003703002002200129002c3703c8022001290300210420024188036a41106a200141f0006a220541106a29030037030020024188036a41086a200541086a290300370300200220052903003703880320014180016a290300210620012903782107200241c0036a41086a22054200370300200242003703c00341dcacc200410d200241c0036a1002200241a0066a41086a2005290300370300200220022903c0033703a006024002400240024002400240024002400240200241a0066a411041b8d6c200410041001004417f460d00200242003703c003024002400240200241a0066a4110200241c0036a41084100100441016a41084d0d0042002108024020034201520d002007500d0720022903c0032203200620062003541b2203200320067d2007827d21080b411010002205450d04200220053602c003200242103702c403200241c0036a41c7acc2004110102920022802c0032105024002400240024020022802c403220920022802c803220a6b41084f0d00200a41086a220b200a490d062009410174220c200b200b200c491b220c4100480d062009450d01200c1000220d450d0b200d2005200c20092009200c4b1b10ce02210920051001200921050c020b200a41086a210b0c020b200c10002205450d090b200c21090b2005200a6a2008370000200241c0036a41086a220a4200370300200242003703c0032005200b200241c0036a1002200241a0066a41086a200a290300370300200220022903c0033703a006200241a0066a411041b8d6c200410041001004417f460d0520024198076a420037030020024180076a41106a420037030020024180076a41086a42003703002002420037038007200241a0066a411020024180076a412041001004220a417f460d01200a411f4d0d01200241e0066a41026a220a20022d0082073a0000200241086a220b20024193076a2900003703002002410d6a220c20024198076a290000370000200220022f0180073b01e0062002200229008b07370300200228008307210d200228008707210e02402009450d00200510010b200241bc036a41026a2209200a2d00003a0000200241c0036a41086a2205200b290300370300200241c0036a410d6a220a200c290000370000200220022f01e0063b01bc03200220022903003703c003200241a0036a410d6a220b200a290000370000200241a0036a41086a220c2005290300370300200220022903c0033703a003200220043703c003200520014188016a41a00210ce02210a20024183066a200d36000020024187066a200e360000200241f8056a20024198036a290300370300200241f0056a20024188036a41086a29030037030020024182066a20092d00003a00002002418b066a20022903a00337000020024193066a200c29030037000020024198066a200b29000037000020022002290388033703e805200220022f01bc033b018006200241a0026a41086a280200210520022802a402210120022d00a002210b200241bc076a41026a20022d00a3023a0000200241a0076a41086a200241b4026a290200370300200241a0076a410d6a200241b9026a290000370000200220022f00a1023b01bc072002200241ac026a2902003703a00741012109024002400240200b4101470d002002200110a80120022d00004101470d01200241fe066a20022d00033a000020024198076a200241196a290000220337030020024190076a200241116a29000037030020024180076a41086a200241096a290000370300200241e0066a41086a200241146a290200370300200241ed066a20033700002002200229000137038007200220022f00013b01fc0620022002410c6a2902003703e006200241086a280200210541002109200228020421010c020b200241026a200241bc076a41026a2d000022093a0000200241136a200241a0076a41086a2903002203370000200241186a200241a0076a410d6a2900002206370000200241fc066a41026a20093a0000200241e0066a41086a2003370300200241e0066a410d6a20063700002002200136000320022005360007200220022f01bc0722093b0100200220022903a007220337000b200220093b01fc06200220033703e006410021090c010b4180c9c2002101411521050b200241dc066a41026a220b200241fc066a41026a2d00003a0000200241c0066a41086a220c200241e0066a41086a290300370300200241c0066a41106a200241e0066a41106a290300370300200220022f01fc063b01dc06200220022903e0063703c0060240024002402009450d002000200136020420004101360200200041086a20053602000c010b200241b3066a200c290300370000200241b8066a200241cd066a290000370000200220022f01dc063b01a006200220013600a306200220053600a706200220022903c0063700ab062002200b2d00003a00a2062002410036020820024201370300410810002201450d0a2002200136020020024288808080800137020420012004370000200a200210a00102400240024002400240024002400240024020022903e8054201520d00200241f0056a2903002203420c882206420120064201561b22064200510d14200241f8056a29030020068021062002280204220b200241086a28020022016b41024f0d01200141026a22052001490d0d200b4101742209200520052009491b220c4100480d0d200b450d052002280200210d200c10002209450d162009200d200c200b200b200c4b1b10ce021a200d10010c060b02402002280204200241086a2802002201470d00200141016a22052001490d0d20014101742209200520052009491b220b4100480d0d2001450d022002280200210c200b10002209450d152009200c200b20012001200b4b1b10ce021a200c10010c030b200141016a2105200228020021090c030b200141026a2105200228020021090c050b200b10002209450d120b2002200b360204200220093602000b200241086a2005360200200920016a41003a00000c030b200c10002209450d100b2002200c360204200220093602000b200241086a2005360200200920016a2006a741047420037aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b20024180066a2002101b2002280204210120022802002209200241086a280200200241c8026a200241a0066a100b210502402001450d00200910010b2005450d0120004192cbc10036020420004101360200200041086a411a3602000b200a102c200241c0076a24000f0b20024180076a41186a200241a0066a41186a29030037030020024180076a41106a200241a0066a41106a29030037030020024180076a41086a200241a0066a41086a290300370300200220022903a006370380072002200a41a00210ce021a420121030c0c0b41b2eac10041331040000b41b2eac10041331040000b1018000b41c3d7c10041221040000b411041011019000b41c3d7c10041221040000b419083c000104d000b200c41011019000b410841011019000b41e4b2c000104d000b200b41011019000b200c41011019000b200041086a2003370300200041306a2004370300200041106a200229038007370300200041186a20024180076a41086a290300370300200041206a20024180076a41106a290300370300200041286a20024180076a41186a290300370300200041386a200241a00210ce021a20004100360200200241c0076a24000b8a0401077f230041306b22022400024002400240024002400240411010002203450d002002200336022020024210370224200241206a419db0c2004110102920022802202103024002400240024020022802242204200228022822056b41044f0d00200541046a22062005490d0520044101742207200620062007491b22074100480d052004450d01200710002208450d072008200320072004200420074b1b10ce02210420031001200421030c020b200541046a21060c020b200710002203450d050b200721040b200320056a2001410676360000200241206a41086a220542003703002002420037032020032006200241206a1002200241086a2005290300370300200220022903203703004100210502402002411041b8d6c200410041001004417f460d002002421037021420022002360210200241206a200241106a103920022802202206450d03200241286a2802002105200228022421072004450d060c050b410121064100210720040d040c050b411041011019000b1018000b41b2eac10041331040000b200741011019000b200310010b41002103024020052001413f7122044d0d002000200620044105746a2203290000370001200041196a200341186a290000370000200041116a200341106a290000370000200041096a200341086a290000370000410121030b200020033a000002402007450d00200610010b200241306a24000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a41d893c000360200200041206a41023602000b3400200041b3ccc10036020420004100360200200041086a4209370200200041106a41a896c000360200200041146a410b3602000bc60103017f017e017f230041b0026b2203240010ac012104200341086a220542003703002003420037030041b3c8c100411620031002200341a0026a41086a2005290300370300200320032903003703a0020240200341a0026a411041b8d6c200410041001004417f460d00200342003703000240200341a0026a4110200341084100100441016a41084d0d002000200329030020047c2003200141a00210ce0222032002109f01200341b0026a24000f0b41b2eac10041331040000b41c3d7c10041221040000ba70102027f017e230041206b22002400200041106a41086a220142003703002000420037031041dcacc200410d200041106a1002200041086a20012903003703002000200029031037030002402000411041b8d6c200410041001004417f460d0020004200370310024020004110200041106a41084100100441016a41084d0d0020002903102102200041206a240020020f0b41b2eac10041331040000b41c3d7c10041221040000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a418c9cc000360200200041206a41053602000b13002000410136020420004184a0c0003602000b130020004106360204200041d0a0c0003602000b9e0201017f02400240024020012d0000417e6a220241044b0d000240024002400240024020020e050004020301000b41a00210002202450d052002200141046a28020010b101200041046a2002360200200041106a200141106a290300370300200041086a200141086a290300370300200041023a00000f0b200041046a200141046a280200360200200041063a00000f0b200041046a200141046a280200360200200020012d00014100473a0001200041043a00000f0b41a00210002202450d032002200141046a28020010b101200041046a2002360200200020012d00013a0001200041053a00000f0b200041046a200141046a280200360200200041033a00000f0b41b0a3c000104d000b41a00241081019000b41a00241081019000be31a05047f057e047f017e017f230041c0026b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0002400240024002400240024002400240024020030e0a00060304010708050a02000b200141086a28020022034102460d0e20034103470d29410121042001410c6a2d00004101470d12200141106a28020021050c130b200241086a200141086a10b00120004105360200200041186a200241086a41106a290300370300200041106a200241086a41086a290300370300200041086a2002290308370300200241c0026a24000f0b41022104200141086a22032d000022054103714102460d0820054103470d28200141306a2903002106200141286a2903002107200141386a2903002108200241a0026a2001410c6a102d200241b0026a200141186a102d200241136a200241a0026a41086a2802003600002002411f6a200241b0026a41086a280200360000200220022903a00237000b200220022903b00237001742002109410321044200210a0c090b41022103200141086a22042d000022054107714102460d0d4103210320054103460d0c4104210320054104470d2820042d000141004721010c0e0b200141086a2d0000417e6a220b41094b0d28410221034100210c0240200b0e0a30001d1e1b21221f231c300b2001410c6a280200220c4108762104410321030c1f0b20012d000422034103714102460d0720034103470d2841032104200241b2026a200141046a220341036a2d00003a0000200241086a41086a200141186a290000370300200241156a2001411d6a290000370000200220032f00013b01b0022002200141106a290000370308200141256a2d00004100472105200141286a280200210d2001410c6a2800002103200141086a280000210e0c080b200141086a2903004202520d2820004102360200200041086a4202370300200041106a200141106a290300370300200241c0026a24000f0b200241086a200141086a10b20120004106360200200041c0006a200241086a41386a290300370300200041386a200241086a41306a290300370300200041306a200241086a41286a290300370300200041286a200241086a41206a290300370300200041206a200241086a41186a290300370300200041186a200241086a41106a290300370300200041106a200241086a41086a290300370300200041086a2002290308370300200241c0026a24000f0b200241086a200141086a10b30120004107360200200041286a200241086a41206a290300370300200041206a200241086a41186a290300370300200041186a200241086a41106a290300370300200041106a200241086a41086a290300370300200041086a2002290308370300200241c0026a24000f0b200241086a200141086a10b401200041086a200241086a41980210ce021a20004100360200200241c0026a24000f0b200141086a22042d0000417e6a220341044b0d25024020030e0500130f100e000b41022103200241b0026a41026a200441036a2d00003a0000200241106a200141186a290000370300200241086a41106a200141206a290000370300200220042f00013b01b0022002200141106a290000370308200141386a2903002106200141306a2903002107200141286a31000021082001410c6a28000021010c130b2002411f6a200341186a290000370000200241186a200341116a290000370300200241086a41086a200341096a29000037030020022003290001370308200141c0006a290300210a200141386a2903002108200141c8006a290300210f200141286a3100002107200241b0026a2001412c6a102d200241b0026a41086a35020042208620022903b002220942208884210620072009422086842107420021090b200020022903083700092000410a360200200041306a2006370300200041286a2007370300200041c0006a200a370300200041386a2009200884370300200041086a20043a0000200041c8006a200f370300200041116a200241086a41086a290300370000200041196a200241186a290300370000200041206a2002411f6a290000370000200241c0026a24000f0b200141086a280200210e41a00210002203450d2320032001410c6a28020010b501410221040b200020022f01b0023b0005200020043a0004200020053a0025200020022f01a0023b012620004108360200200041086a200e3602002000410c6a2003360200200041106a2002290308370200200041286a200d360200200041076a200241b2026a2d00003a0000200041186a200241086a41086a2903003702002000411d6a200241156a290000370000200241c0026a24000f0b410121042001410c6a2d00004101470d05200141106a28020021050c060b200141106a29030021060c010b200241b4026a200441066a2f00003b0100200241086a41086a200141206a290000370300200241086a41106a200141286a2d00003a00002002200441026a2800003602b0022002200141186a290000370308200141106a2900002106200141096a2d000021010b200020013a0009200020022802b00236010a20004103360200200041086a20033a0000200041106a2006370300200041186a20022903083703002000410e6a200241b4026a2f01003b0100200041206a200241086a41086a290300370300200041286a200241086a41106a290300370300200241c0026a24000f0b200241106a2001412c6a2d00003a00002002200141246a2900003703082001410d6a2f00002001410f6a2d0000411074722103200141206a280000210d200141186a2900002106200141146a280000210e200141106a2800002105410021040b200241b0026a41086a200241086a41086a280200360200200220022903083703b002200141c8006a2903002107200141c0006a2903002108200141386a2903002109200141306a290300210a410321010c020b200241106a2001412c6a2d00003a00002002200141246a2900003703082001410d6a2f00002001410f6a2d0000411074722103200141206a280000210d200141186a2900002106200141146a280000210e200141106a2800002105410021040b200241b0026a41086a200241086a41086a280200360200200220022903083703b002200141386a2903002109200141306a290300210a410221010b200020033b000d200041013602002000410f6a20034110763a0000200041386a2009370300200041306a200a370300200041c8006a2007370300200041c0006a20083703002000410c6a20043a0000200041086a2001360200200041106a2005360200200041146a200e360200200041186a2006370200200041206a200d360200200041246a20022903b0023702002000412c6a200241b0026a41086a280200360200200241c0026a24000f0b2001410c6a2802002101410621030c020b200241086a41106a200141206a2903003703002002200141186a2903003703102002200141106a280200360208200141286a29030021082001410c6a2802002101410421030c020b2001410c6a2802002101410521030b0b0c010b2002200141186a2903003703102002200141106a290300370308410321030b200020022f01b0023b000920004109360200200041386a2006370300200041306a2007370300200041086a20033a00002000410c6a2001360200200041106a2002290308370300200041286a20083703002000410b6a200241b2026a2d00003a0000200041186a200241086a41086a290300370300200041206a200241086a41106a290300370300200241c0026a24000f0b2001410c6a280200220c4108762104200141186a2903002106200141206a2802002110200141106a2903002207a7210d2007422088a72105410621030c130b2001410c6a280200220c4108762104410b21030c030b4101210c2001410c6a2d00004101470d06200141106a280200210d0c070b2001410c6a280200220c4108762104410521030c010b2001410c6a280200220c4108762104410921030b0c0d0b200141106a2903002206a7210d2006422088a72105410721030c0c0b200141106a2903002206a7210d2006422088a72105410821030c0b0b4100210c200141096a2d0000410047210e410a21030c0c0b200241106a2001412c6a2d00003a00002002200141246a2900003703082001410d6a2f00002001410f6a2d0000411074722104200141206a2800002110200141186a2900002106200141146a2800002105200141106a280000210d4100210c0b200241b0026a41086a200241086a41086a280200360200200220022903083703b002410421030c090b41acfbc000104d000b4198a3c000104d000b41f0aec000104d000b41e8cac000104d000b41f4b1c000104d000b41c0b5c000104d000b41e48ac100104d000b41a00241081019000b0b0b2000200e3a0009200020022f01083b010a20004104360200200041186a2006370300200041086a20033a0000200041206a2010360200200041246a20022903b0023702002000410c6a2004410874200c41ff0171723602002000412c6a200241b0026a41086a280200360200200041106a2005ad422086200dad84370300200241c0026a24000bac0901047f230041206b22022400024002402001280200417e6a220341084b0d000240024002400240024002400240024002400240024002400240024002400240024020030e09000502030106070408000b2001410c6a2802002203417f4c0d11200128020421042003450d0e2003100022050d0f200341011019000b4101210320012d00044101470d07200141086a28020021040c080b2000410436020020002001280204360204200241206a24000f0b2000410536020020002001280204360204200241206a24000f0b20004109360200200041086a200141086a290300370300200241206a24000f0b2001280204210441012103200141086a22052d00004101470d052001410c6a28020021050c060b2000410736020020002001280204360204200241206a24000f0b4101210320012d00044101470d05200141086a28020021010c060b2000410a360200200041086a200141086a290300370300200241206a24000f0b2002411e6a200141046a220341036a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290000370300200141086a2800002104410021030b200020033a0004200020022f011c3b0005200041086a20043602002000410c6a2002290300370200200041386a200141386a290300370300200041306a200141306a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a280200360200200141286a280200210120004106360200200041286a2001360200200241206a24000f0b2002411e6a200541036a2d00003a0000200241086a200141186a290000370300200241106a200141206a290000370300200241186a200141286a2d00003a0000200220052f00013b011c2002200141106a2900003703002001410c6a2800002105410021030b20002004360204200020022f011c3b0009200041086a20033a00002000410c6a2005360200200041106a20022903003702002000410b6a2002411e6a2d00003a0000200041186a200241086a290300370200200041206a200241106a290300370200200041286a200241186a280200360200200041033602002000412c6a2001412c6a290200370200200241206a24000f0b2002411e6a200141046a220341036a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290000370300200141086a2800002101410021030b200020022f011c3b0005200020033a000420004108360200200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a280200360200200241206a24000f0b410121050b200020052004200310ce02360204200041086a20033602002000410c6a200336020020004102360200200041106a200141106a280200360200200241206a24000f0b41fce8c000104d000b102e000beb1b05057f057e047f017e017f230041c0026b220224000240024002400240024002400240024002400240024002400240024020012d0000417e6a220341044b0d00024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e050004020301000b41a00210002203450d2e200141046a2802002201280200417f6a220441094b0d0c024020040e0a000a0708050b0c090e06000b200141086a28020022044102460d1220044103470d2f410121052001410c6a2d00004101470d16200141106a28020021060c170b200041063a0000200041086a200141086a290300370300200241c0026a24000f0b200041043a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200241c0026a24000f0b200041053a0000200041086a200141086a290300370300200241c0026a24000f0b200041033a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00004100473a0000200241c0026a24000f0b200241086a200141086a10b00120034105360200200341186a200241086a41106a290300370300200341106a200241086a41086a290300370300200320022903083703080c350b41022105200141086a22042d000022064103714102460d0820064103470d2a200141306a2903002107200141286a2903002108200141386a2903002109200241a0026a2001410c6a102d200241b0026a200141186a102d200241136a200241a0026a41086a2802003600002002411f6a200241b0026a41086a280200360000200220022903a00237000b200220022903b0023700174200210a410321054200210b0c090b41022104200141086a22052d000022064107714102460d0d4103210420064103460d0c4104210420064104470d2a20052d000141004721010c0e0b200141086a2d0000417e6a220c41094b0d2a410221044100210d0240200c0e0a32001d1e1b21221f231c320b2001410c6a280200220d4108762105410321040c1f0b20012d000422044103714102460d0720044103470d2a41032105200241b2026a200141046a220441036a2d00003a0000200241086a41086a200141186a290000370300200241156a2001411d6a290000370000200220042f00013b01b0022002200141106a290000370308200141256a2d00004100472106200141286a280200210e2001410c6a2800002104200141086a280000210f0c080b200141086a2903004202520d2a20034202370308200341023602002003200141106a2903003703100c300b200241086a200141086a10b20120034106360200200341c0006a200241086a41386a290300370300200341386a200241086a41306a290300370300200341306a200241086a41286a290300370300200341286a200241086a41206a290300370300200341206a200241086a41186a290300370300200341186a200241086a41106a290300370300200341106a200241086a41086a290300370300200320022903083703080c2f0b200241086a200141086a10b30120034107360200200341286a200241086a41206a290300370300200341206a200241086a41186a290300370300200341186a200241086a41106a290300370300200341106a200241086a41086a290300370300200320022903083703080c2e0b200241086a200141086a10b401200341086a200241086a41980210ce021a200341003602000c2d0b200141086a22052d0000417e6a220441044b0d27024020040e0500130f100e000b41022104200241b0026a41026a200541036a2d00003a0000200241106a200141186a290000370300200241086a41106a200141206a290000370300200220052f00013b01b0022002200141106a290000370308200141386a2903002108200141306a2903002109200141286a31000021072001410c6a28000021010c130b2002411f6a200441186a290000370000200241186a200441116a290000370300200241086a41086a200441096a29000037030020022004290001370308200141c0006a290300210b200141386a2903002109200141c8006a2903002110200141286a3100002108200241b0026a2001412c6a102d200241b0026a41086a35020042208620022903b002220a4220888421072008200a4220868421084200210a0b2003200837032820032002290308370009200320053a0008200320103703482003410a360200200341306a2007370300200341c0006a200b3703002003200a200984370338200341116a200241106a290300370000200341196a200241186a290300370000200341206a2002411f6a2900003700000c2a0b200141086a280200210f41a00210002204450d2520042001410c6a28020010b501410221050b200320022f01b0023b0005200320053a00042003200f3602082003200436020c20032002290308370210200320063a0025200320022f01a0023b01262003200e36022820034108360200200341076a200241b2026a2d00003a0000200341186a200241086a41086a2903003702002003411d6a200241156a2900003700000c280b410121052001410c6a2d00004101470d05200141106a28020021060c060b200141106a29030021070c010b200241b4026a200541066a2f00003b0100200241086a41086a200141206a290000370300200241086a41106a200141286a2d00003a00002002200541026a2800003602b0022002200141186a290000370308200141106a2900002107200141096a2d000021010b200320013a0009200320043a0008200320022802b00236010a2003200737031020032002290308370318200341033602002003410e6a200241b4026a2f01003b0100200341206a200241106a290300370300200341286a200241186a2903003703000c240b200241106a2001412c6a2d00003a00002002200141246a2900003703082001410d6a2f00002001410f6a2d0000411074722104200141206a280000210e200141186a2900002107200141146a280000210f200141106a2800002106410021050b200241b0026a41086a200241086a41086a280200360200200220022903083703b002200141c8006a2903002108200141c0006a2903002109200141386a290300210a200141306a290300210b410321010c020b200241106a2001412c6a2d00003a00002002200141246a2900003703082001410d6a2f00002001410f6a2d0000411074722104200141206a280000210e200141186a2900002107200141146a280000210f200141106a2800002106410021050b200241b0026a41086a200241086a41086a280200360200200220022903083703b002200141386a290300210a200141306a290300210b410221010b200320043b000d2003200b37033020032009370340200320053a000c20032001360208200320063602102003200f360214200320073702182003200e360220200320022903b002370224200341013602002003410f6a20044110763a0000200341386a200a370300200341c8006a20083703002003412c6a200241b8026a2802003602000c1f0b2001410c6a2802002101410621040c020b200241086a41106a200141206a2903003703002002200141186a2903003703102002200141106a280200360208200141286a29030021072001410c6a2802002101410421040c020b2001410c6a2802002101410521040b0b0c010b2002200141186a2903003703102002200141106a290300370308410321040b20032009370330200320022f01b0023b0009200320043a00082003200136020c200320022903083703102003200737032820034109360200200341386a20083703002003410b6a200241b2026a2d00003a0000200341186a200241106a290300370300200341206a200241186a2903003703000c180b2001410c6a280200220d4108762105200141186a2903002107200141206a280200210f200141106a2903002208a7210e2008422088a72106410621040c150b2001410c6a280200220d4108762105410b21040c030b4101210d2001410c6a2d00004101470d06200141106a280200210e0c070b2001410c6a280200220d4108762105410521040c010b2001410c6a280200220d4108762105410921040b0c0f0b200141106a2903002207a7210e2007422088a72106410721040c0e0b200141106a2903002207a7210e2007422088a72106410821040c0d0b4100210d200141096a2d00004100472111410a21040c0e0b200241106a2001412c6a2d00003a00002002200141246a2900003703082001410d6a2f00002001410f6a2d0000411074722105200141206a280000210f200141186a2900002107200141146a2800002106200141106a280000210e4100210d0b200241b0026a41086a200241086a41086a280200360200200220022903083703b002410421040c0b0b41b093c100104d000b41a00241081019000b41acfbc000104d000b4198a3c000104d000b41f0aec000104d000b41e8cac000104d000b41f4b1c000104d000b41c0b5c000104d000b41e48ac100104d000b41a00241081019000b0b0b200320113a0009200320043a0008200320022f01083b010a2003200f360220200320022903b00237022420034104360200200341186a200737030020032005410874200d41ff01717236020c2003412c6a200241b0026a41086a28020036020020032006ad422086200ead843703100b200041023a0000200041046a2003360200200241c0026a24000b870803037f017e0a7f230041d0006b220224000240024002402001280200417e6a220341044b0d00024002400240024002400240024002400240024020030e050004020301000b200041086a200141086a290300370300200041106a200141106a2d00003a0000200141d4016a2802002103200041116a200141116a41e00010ce021a200041f1006a200141f1006a41e00010ce021a200041d4016a200336020020004102360200200041d8016a200141d8016a290000370000200041e0016a200141e0016a290000370000200041e8016a200141e8016a290000370000200041f0016a200141f0016a290000370000200041f8016a200141f8016a29000037000020004180026a20014180026a29000037000020004188026a20014188026a29000037000020004190026a20014190026a290000370000200241d0006a24000f0b2001410c6a2802002204ad42187e2205422088a70d092005a72203417f4c0d09200128020421012003450d03200310002206450d0a4118210341002107200441186c0d040c050b200241386a200141046a102d200041043602002000410c6a200241c0006a28020036020020002002290338370204200241d0006a24000f0b200241386a200141046a102d200041053602002000410c6a200241c0006a28020036020020002002290338370204200241d0006a24000f0b2001410c6a2802002203ad2205421e88a70d062005420286a72208417f4c0d06200128020421012008450d032008100022090d04200841041019000b410421064118210341002107200441186c450d010b200241386a2001102d200241386a410c6a220a2001410c6a102d200241206a41086a220b2002290244370300200241206a41106a220c200241386a41146a2802003602002002200229023c3703202002280238220d450d00200120036a2103200441186c41686a2108200241386a41047221094101210e200621010340200e2107200241086a41106a220e200c280200360200200241086a41086a220f200b290300370300200220022903203703082001200d360200200141146a200e2802003602002001410c6a200f290300370200200141046a20022903083702002008450d01200241386a2003102d200a2003410c6a102d200b200941086a290200370300200c200941106a28020036020020022009290200370320200141186a2101200741016a210e200841686a2108200341186a21032002280238220d0d000b0b200041086a2004360200200020063602042000410c6a200736020020004106360200200241d0006a24000f0b410421090b20092001200341027410ce022101200041086a2003360200200020013602042000410c6a200336020020004103360200200241d0006a24000f0b41c4fbc000104d000b102e000b200341041019000bd81a05047f057e047f017e017f230041c0026b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0002400240024002400240024002400240024020030e0a00060304010708050a02000b200141086a28020022034102460d0e20034103470d29410121042001410c6a2d00004101470d12200141106a28020021050c130b200241086a200141086a10b00120004105360200200041186a200241086a41106a290300370300200041106a200241086a41086a290300370300200041086a2002290308370300200241c0026a24000f0b41022104200141086a22032d000022054103714102460d0820054103470d28200141306a2903002106200141286a2903002107200141386a2903002108200241a0026a2001410c6a102d200241b0026a200141186a102d200241136a200241a0026a41086a2802003600002002411f6a200241b0026a41086a280200360000200220022903a00237000b200220022903b00237001742002109410321044200210a0c090b41022103200141086a22042d000022054107714102460d0d4103210320054103460d0c4104210320054104470d2820042d000141004721010c0e0b200141086a2d0000417e6a220b41094b0d28410221034100210c0240200b0e0a30001d1e1b21221f231c300b2001410c6a280200220c4108762104410321030c1f0b20012d000422034103714102460d0720034103470d2841032104200241b2026a200141046a220341036a2d00003a0000200241086a41086a200141186a290000370300200241156a2001411d6a290000370000200220032f00013b01b0022002200141106a290000370308200141256a2d00004100472105200141286a280200210d2001410c6a2800002103200141086a280000210e0c080b200141086a2903004202520d2820004102360200200041086a4202370300200041106a200141106a290300370300200241c0026a24000f0b200241086a200141086a10b20120004106360200200041c0006a200241086a41386a290300370300200041386a200241086a41306a290300370300200041306a200241086a41286a290300370300200041286a200241086a41206a290300370300200041206a200241086a41186a290300370300200041186a200241086a41106a290300370300200041106a200241086a41086a290300370300200041086a2002290308370300200241c0026a24000f0b200241086a200141086a10b30120004107360200200041286a200241086a41206a290300370300200041206a200241086a41186a290300370300200041186a200241086a41106a290300370300200041106a200241086a41086a290300370300200041086a2002290308370300200241c0026a24000f0b200241086a200141086a10b401200041086a200241086a41980210ce021a20004100360200200241c0026a24000f0b200141086a22042d0000417e6a220341044b0d25024020030e0500130f100e000b41022103200241b0026a41026a200441036a2d00003a0000200241106a200141186a290000370300200241086a41106a200141206a290000370300200220042f00013b01b0022002200141106a290000370308200141386a2903002106200141306a2903002107200141286a31000021082001410c6a28000021010c130b2002411f6a200341186a290000370000200241186a200341116a290000370300200241086a41086a200341096a29000037030020022003290001370308200141c0006a290300210a200141386a2903002108200141c8006a290300210f200141286a3100002107200241b0026a2001412c6a102d200241b0026a41086a35020042208620022903b002220942208884210620072009422086842107420021090b200020022903083700092000410a360200200041306a2006370300200041286a2007370300200041c0006a200a370300200041386a2009200884370300200041086a20043a0000200041c8006a200f370300200041116a200241086a41086a290300370000200041196a200241186a290300370000200041206a2002411f6a290000370000200241c0026a24000f0b200141086a280200210e41a00210002203450d2320032001410c6a28020010b501410221040b200020022f01b0023b0005200020043a0004200020053a002520004108360200200041086a200e3602002000410c6a2003360200200041106a2002290308370200200041286a200d360200200041076a200241b2026a2d00003a0000200041186a200241086a41086a2903003702002000411d6a200241156a290000370000200241c0026a24000f0b410121042001410c6a2d00004101470d05200141106a28020021050c060b200141106a29030021060c010b200241b4026a200441066a2f00003b0100200241086a41086a200141206a290000370300200241086a41106a200141286a2d00003a00002002200441026a2800003602b0022002200141186a290000370308200141106a2900002106200141096a2d000021010b200020013a0009200020022802b00236010a20004103360200200041086a20033a0000200041106a2006370300200041186a20022903083703002000410e6a200241b4026a2f01003b0100200041206a200241086a41086a290300370300200041286a200241086a41106a290300370300200241c0026a24000f0b200241106a2001412c6a2d00003a00002002200141246a2900003703082001410d6a2f00002001410f6a2d0000411074722103200141206a280000210d200141186a2900002106200141146a280000210e200141106a2800002105410021040b200241b0026a41086a200241086a41086a280200360200200220022903083703b002200141c8006a2903002107200141c0006a2903002108200141386a2903002109200141306a290300210a410321010c020b200241106a2001412c6a2d00003a00002002200141246a2900003703082001410d6a2f00002001410f6a2d0000411074722103200141206a280000210d200141186a2900002106200141146a280000210e200141106a2800002105410021040b200241b0026a41086a200241086a41086a280200360200200220022903083703b002200141386a2903002109200141306a290300210a410221010b200020033b000d200041013602002000410f6a20034110763a0000200041386a2009370300200041306a200a370300200041c8006a2007370300200041c0006a20083703002000410c6a20043a0000200041086a2001360200200041106a2005360200200041146a200e360200200041186a2006370200200041206a200d360200200041246a20022903b0023702002000412c6a200241b0026a41086a280200360200200241c0026a24000f0b2001410c6a2802002101410621030c020b200241086a41106a200141206a2903003703002002200141186a2903003703102002200141106a280200360208200141286a29030021082001410c6a2802002101410421030c020b2001410c6a2802002101410521030b0b0c010b2002200141186a2903003703102002200141106a290300370308410321030b200020022f01b0023b000920004109360200200041386a2006370300200041306a2007370300200041086a20033a00002000410c6a2001360200200041106a2002290308370300200041286a20083703002000410b6a200241b2026a2d00003a0000200041186a200241086a41086a290300370300200041206a200241086a41106a290300370300200241c0026a24000f0b2001410c6a280200220c4108762104200141186a2903002106200141206a2802002110200141106a2903002207a7210d2007422088a72105410621030c130b2001410c6a280200220c4108762104410b21030c030b4101210c2001410c6a2d00004101470d06200141106a280200210d0c070b2001410c6a280200220c4108762104410521030c010b2001410c6a280200220c4108762104410921030b0c0d0b200141106a2903002206a7210d2006422088a72105410721030c0c0b200141106a2903002206a7210d2006422088a72105410821030c0b0b4100210c200141096a2d0000410047210e410a21030c0c0b200241106a2001412c6a2d00003a00002002200141246a2900003703082001410d6a2f00002001410f6a2d0000411074722104200141206a2800002110200141186a2900002106200141146a2800002105200141106a280000210d4100210c0b200241b0026a41086a200241086a41086a280200360200200220022903083703b002410421030c090b41acfbc000104d000b4198a3c000104d000b41f0aec000104d000b41e8cac000104d000b41f4b1c000104d000b41c0b5c000104d000b41e48ac100104d000b41a00241081019000b0b0b2000200e3a0009200020022f01083b010a20004104360200200041186a2006370300200041086a20033a0000200041206a2010360200200041246a20022903b0023702002000410c6a2004410874200c41ff0171723602002000412c6a200241b0026a41086a280200360200200041106a2005ad422086200dad84370300200241c0026a24000bc60302057f017e230041306b2202240002400240024002400240410f10002203450d00200220033602202002420f370224200241206a41d5c7c100410f1029200241106a41086a22032002280228360200200220022903203703102001200241106a101b200328020021012002280214210420022802102105200241206a41086a220642003703002002420037032020052001200241206a1002200320062903003703002002200229032037031002400240024002400240200241106a411041b8d6c200410041001004417f460d00200242103702242002200241106a360220200241086a200241206a10352002280208450d08200228020c2203417f4c0d062003450d01200310002201450d0920014100200310d0021a0c020b200041003602082000420137020020040d020c030b410121010b200241286a2206200628020022062003410020022802202002280224200120032006100422062006417f461b2206200620034b1b6a360200200320064b0d042001450d0520002003ad2207422086200784370204200020013602002004450d010b200510010b200241306a24000f0b410f41011019000b102e000b200110010b41b2eac10041331040000b200341011019000bc10703077f027e047f230041206b220224000240024002400240024002400240411310002203450d002002200336021020024213370214200241106a41a0c8c10041131029200228021021040240024002400240024020022802142205200228021822036b41044f0d00200341046a22062003490d0320054101742207200620062007491b22084100480d032005450d01200810002207450d072007200420082005200520084b1b10ce02210520041001200521040c020b200341046a2106200521080c010b200810002204450d050b200420036a2000360000200141086a29030021092001290300210a411010002203450d032003200a37000020032009370008200141106a280200210b024002400240200141186a2802002205413f4b0d004120210041201000220c450d08200c2003290000370000200c41086a200341086a29000037000020031001200c20054102743a00104111210720050d010c020b02402005418080014f0d0041201000220c450d09200c2003290000370000200c41086a200341086a29000037000020031001200c20054102744101723b0010411221070c010b41201000210c024020054180808080044f0d00200c450d0a200c2003290000370000200c41086a200341086a29000037000020031001200c2005410274410272360010411421070c010b200c450d0a200c2003290000370000200c41086a200341086a29000037000020031001200c2005360011200c41033a0010411521070b2005410574210d412021000340200b210302400240024002402000200722056b41204f0d00200541206a22072005490d062000410174220b20072007200b491b220b4100480d062000450d01200b1000220e450d07200e200c200b20002000200b4b1b10ce022100200c10012000210c0c020b200541206a21070c020b200b1000220c450d050b200b21000b200341206a210b200c20056a22052003290000370000200541186a200341186a290000370000200541106a200341106a290000370000200541086a200341086a290000370000200d41606a220d0d000b0b200241106a41086a220342003703002002420037031020042006200241106a1002200241086a20032903003703002002200229031037030020024110200c2007100302402000450d00200c10010b02402008450d00200410010b0240200141146a280200450d00200141106a28020010010b200241206a24000f0b1018000b200b41011019000b411341011019000b411041011019000b200841011019000b412041011019000b412041011019000b412041011019000b412041011019000bc80201027f230041c0006b22032400200341106a41086a220442003703002003420037031020012002200341106a1002200341086a20042903003703002003200329031037030002402003411041b8d6c200410041001004417f460d00200341386a4200370300200341206a41106a4200370300200341206a41086a420037030020034200370320024020034110200341206a4120410010042204417f460d002004411f4d0d0020002003290320370000200041186a200341206a41186a290300370000200041106a200341206a41106a290300370000200041086a200341206a41086a2200290300370000200341106a41086a220442003703002003420037031020012002200341106a10022000200429030037030020032003290310370320200341206a4110100a200341c0006a24000f0b41b2eac10041331040000b41c3d7c10041221040000bfe0104017f017e017f017e230041206b2203240042002104200341106a41086a220542003703002003420037031020012002200341106a1002200341086a2005290300370300200320032903103703000240024002402003411041b8d6c200410041001004417f460d002003410036021020034110200341106a41044100100441016a4105490d0220032802102101200342003703182003420037031020034110200341106a4110410410042202417f460d022002410f4d0d02200341186a2903002106200329031021040c010b41032101420021060b200020043703002000200136021020002006370308200341206a24000f0b41b2eac10041331040000b930a04037f027e107f017e230041f0076b22012400200141b0056a41086a22024200370300200142003703b005418bc8c1004115200141b0056a1002200141106a41086a2002290300370300200120012903b005370310024002400240024002400240024002400240024002400240200141106a411041b8d6c200410041001004417f460d00200142103702242001200141106a360220200141086a200141206a10352001280208450d07200128020c2203ad220442c8027e2205422088a70d092005a72202417f4c0d092002450d01200210002206450d0b20030d020c030b2000410036020820004208370200200141f0076a24000f0b410821062003450d010b20014190036a4104722107200141206a41086a220828020021092001280224210a2001280220210b200141d0076a41186a210c200141d0076a41106a210d4100210e0340200141003602b00520084100200b200a200141b0056a41042009100422022002417f461b2202410420024104491b20096a360200200241034d0d0320012802b005210f200141b0056a200141206a10bb0120012802b005410b460d0320014190036a200141b0056a41a00210ce021a200c4200370300200d4200370300200141d0076a41086a22024200370300200142003703d00720082008280200220941002001280220220b2001280224220a200141d0076a41202009100422092009417f461b2210412020104120491b6a22093602002010411f4d0d02200141d0006a41186a2211200c290300370300200141d0006a41106a2212200d290300370300200141d0006a41086a22132002290300370300200120012903d0073703502001280290032110200141f4006a2007419c0210ce021a200141b0056a200141f4006a419c0210ce021a200c2011290300370300200d201229030037030020022013290300370300200120012903503703d0072010410b460d0420014190036a200141b0056a419c0210ce021a200141306a41186a2211200c290300370300200141306a41106a2212200d290300370300200141306a41086a22132002290300370300200120012903d00737033002402004422088a722022004a7470d00200241016a22142002490d0720024101742215201420142015491bad220542c8027e2216422088a70d072016a722144100480d07024002402002450d00201410002215450d0b201520062014200241c8026c2202200220144b1b10ce02210220061001200221060c010b201410002206450d0a0b20044280808080708320058421040b20062004422088a741c8026c6a22022010360200200241046a20014190036a419c0210ce021a200241a0026a200f360200200241bc026a2011290300370200200241b4026a2012290300370200200241ac026a2013290300370200200241a4026a200129033037020020044280808080107c2104200e41016a220e2003490d000b0b2006450d032000200437020420002006360200200141f0076a24000f0b20014190036a10bc010b200141b0056a200141f4006a419c0210ce021a200141d0076a41186a200141d0006a41186a290300370300200141d0076a41106a200141d0006a41106a290300370300200141d0076a41086a200141d0006a41086a290300370300200120012903503703d0070b02402004422088a72201450d00200141c8026c21022006210103402001102c200141c8026a2101200241b87d6a22020d000b0b2004a7450d00200610010b41b2eac10041331040000b1018000b102e000b201441081019000b200241081019000bcaa4010d087f027e057f017e037f027e057f027e147f077e047f027e057f230041b00e6b22022400200241003a00f00920012001280208220320012802002001280204200241f0096a41012003100441016a220341014b6a22043602080240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020034102490d0020022d00f0092203410a4b0d0b024020030e0b00070405020809060b030a000b200241003a00f009200141086a20042001280200200141046a280200200241f0096a41012004100441016a220341014b6a220436020020034102490d0e4107210320022d00f009220541044b0d9901024020050e05002e21261c000b200241d8066a4200370300200241d0066a4200370300200241c0066a41086a4200370300200242003703c006200141086a220641002001280200200141046a2207280200200241c0066a41202004100422052005417f461b22054120200541204922051b20046a220436020020050d55200220022f00c1063b01f00920022d00c006210820022800c306210920022900c706210a20022900cf06210b20022800d706210c20022d00db06210d20022d00dc06210e20022f00dd06210f20022d00df062110200220022f01f00922053b01900c200220053b01a805200242003703f0092006410020012802002007280200200241f0096a41082004100422052005417f461b2205410820054108491b20046a2204360200200541074d0d6520022903f0092111200241c0066a41186a22064200370300200241c0066a41106a22074200370300200241c0066a41086a22124200370300200242003703c006200141086a221341002001280200200141046a2214280200200241c0066a41202004100422052005417f461b2205412020054120491b20046a22043602002005411f4d0d64200241f0096a41186a22052006290300370300200241f0096a41106a22062007290300370300200241f0096a41086a22072012290300370300200220022903c0063703f009200241900c6a41086a2007290300370300200241900c6a41106a2006290300370300200241900c6a41186a2005290300370300200220022903f0093703900c200220022f00910c3b01880720022d00900c210720022800930c211220022900970c2115200229009f0c211620022800a70c211720022d00ab0c211820022d00ac0c211920022f00ad0c211a20022d00af0c211b200220022f0188073b01d007200220022f01d00722053b01900c200220053b01aa05200241003a00f0092013200420012802002014280200200241f0096a41012004100441016a41014b22056a22043602002005450d800141014102410320022d00f00922054112461b20054111461b22054103460d800120054101470d76200141046a22132802002105200241003602f009200141086a2214410020012802002005200241f0096a41042004100422052005417f461b2205410420054104491b20046a2204360200200541034d0d800120022802f0092106200241c0066a41186a4200370300200241c0066a41106a4200370300200241c0066a41086a4200370300200242003703c0062014410020012802002013280200200241c0066a41202004100422052005417f461b22054120200541204922051b20046a220436020020050d78200220022f00c1063b01f00920022d00c006211320022800c306211420022900c706211c20022900cf06211d20022800d706211e20022d00db06211f20022d00dc06212020022f00dd06212120022d00df062122200220022f01f00922053b01900c200220053b01ce07200241f0096a41386a22234200370300200241f0096a41306a22244200370300200241f0096a41286a22254200370300200241f0096a41206a4200370300200241f0096a41186a4200370300200241f0096a41106a4200370300200241f0096a41086a22264200370300200242003703f009200141086a222741002001280200200141046a2228280200200241f0096a41c0002004100422052005417f461b220541c000200541c000491b20046a22043602002005413f4d0d7a200241900c6a41386a22052023290300370300200241900c6a41306a22292024290300370300200241900c6a41286a222a2025290300370300200241900c6a41206a222b200241f0096a41206a222c290300370300200241900c6a41186a222d200241f0096a41186a222e290300370300200241900c6a41106a222f200241f0096a41106a2230290300370300200241900c6a41086a22312026290300370300200220022903f0093703900c2023200529030022323703002024202929030022333703002025202a2903002234370300202c202b2903002235370300202e202d29030022363703002030202f290300223737030020262031290300223837030020024188076a41086a203837030020024188076a41106a203737030020024188076a41186a203637030020024188076a41206a203537030020024188076a41286a203437030020024188076a41306a203337030020024188076a41386a2032370300200220022903900c223237038807200220323703f009200220022f01ce073b01cc07200241c0066a41186a4200370300200241c0066a41106a4200370300200241c0066a41086a4200370300200242003703c0062027410020012802002028280200200241c0066a41202004100422052005417f461b2205412020054120491b20046a22233602002005411f4d0d7c200220022f00c1063b01f00920022d00c006210520022800c306212420022900c706213220022900cf06213320022800d706212520022d00db06212620022d00dc06212720022f00dd06212820022d00df062129200220022f01f00922043b01900c200220043b01ce07200241f0096a41386a222a4200370300200241f0096a41306a222b4200370300200241f0096a41286a222d4200370300202c4200370300202e420037030020304200370300200241f0096a41086a222c4200370300200242003703f00941002104200141086a41002001280200200141046a280200200241f0096a41c0002023100422012001417f461b220141c000200141c000491b20236a3602002001413f4d0d7e200241900c6a41386a2230202a290300370300200241900c6a41306a222f202b290300370300200241900c6a41286a2231202d290300370300200241900c6a41206a2239200241f0096a41206a2201290300370300200241900c6a41186a223a200241f0096a41186a2223290300370300200241900c6a41106a223b200241f0096a41106a222e290300370300200241900c6a41086a223c202c290300370300200220022903f0093703900c202a20302903002234370300202b202f2903002235370300202d203129030022363703002001203929030022373703002023203a2903002238370300202e203b290300223d370300202c203c290300223e370300200241c0066a41086a203e370300200241c0066a41106a203d370300200241c0066a41186a2038370300200241c0066a41206a2037370300200241c0066a41286a2036370300200241c0066a41306a2035370300200241c0066a41386a2034370300200220022903900c22343703c006200220343703f009200220022f01ce073b018607202c20024188076a41086a290300370300202e20024188076a41106a290300370300202320024188076a41186a290300370300200120024188076a41206a290300370300202d20024188076a41286a290300370300202b20024188076a41306a290300370300202a20024188076a41386a290300370300200220022f01cc073b01ce0720022002290388073703f0090c770b2000410b360200200241b00e6a24000f0b200241003a00f009200141086a20042001280200200141046a280200200241f0096a41012004100441016a220341014b6a22043602004102210520034102490d4f20022d00f009220341094b0d4f024020030e0a4f004648444b4c494e454f0b200141046a2802002103200241003602f009200141086a410020012802002003200241f0096a41042004100422012001417f461b22014104200141044922011b20046a36020020010d4f20022802f0092206410876210d410321050c490b200241003a00f009200141086a20042001280200200141046a280200200241f0096a41012004100441016a220341014b6a220436020020034102490d0a4107210320022d00f009220541044b0d9901024020050e05001b171a16000b200242003703f809200242003703f009200141086a220641002001280200200141046a2207280200200241f0096a41102004100422052005417f461b22054110200541104922051b20046a220436020020050d9901200241f0096a41086a290300211120022903f0092115200241a80c6a4200370300200241900c6a41106a4200370300200241900c6a41086a4200370300200242003703900c2006410020012802002007280200200241900c6a41202004100422012001417f461b2201412020014120491b20046a3602002001411f4d0d54200220022f00910c3b01f00920022d00af0c210120022900a70c2116200229009f0c210a20022900970c210b20022800930c2104200220022d00900c3a00c006200220043600c3062002200b3700c7062002200a3700cf06200220163700d706200220013a00df06200220022f01f00922033b018807200220033b00c1064102210320024198026a41026a200241c0066a41026a2d00003a0000200241d8076a20022900cf06370300200241e0076a20022900d706370300200220022f00c0063b019802200220022900c7063703d0072001ad42ff018321160c9a010b200241003a00f009200141086a200420012802002205200141046a2802002206200241f0096a41012004100441016a220341014b6a220436020020034102490d0820022d00f0090d08200242003703f009200141086a410020052006200241f0096a41082004100422012001417f461b2201410820014108491b20046a360200200141074d0d0820022903f0092111200041086a420237030020004102360200200041106a2011370300200241b00e6a24000f0b200241003a00f009200141086a200420012802002205200141046a2802002206200241f0096a41012004100441016a220341014b6a220436020020034102490d3020022d00f0092203450d1120034101460d1020034102470d30200241003a00f009200141086a200420052006200241f0096a41012004100441016a220141014b6a36020020014102490d3020022d00f0092112410421170c120b200241003a00f009200141086a200420012802002205200141046a2802002206200241f0096a41012004100441016a220341014b6a220436020020034102490d1e20022d00f009220341044b0d1e024020030e050022191c15000b200110a7022203450d1e410221010c1d0b200241003a00f009200141086a20042001280200200141046a280200200241f0096a41012004100441016a220341014b6a36020020034102490d0a20022d00f0092203450d0820034101470d0a200241f0096a200110a802200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922034102460d0a2002418c0a6a2802002104200241900a6a28020021062002418a0a6a2f01002107200241890a6a2d00002112200241880a6a2d00002117200241840a6a28020021182002419b0c6a290000210a20022900930c211120022f01900c210820022d00920c210c200242003703f809200242003703f009200141086a22052005280200220541002001280200221a200141046a280200221b200241f0096a41102005100422052005417f461b2205411020054110491b6a22193602002005410f4d0d0a200241f0096a41086a220d290300211520022903f0092116200242003703f809200242003703f009200141086a4100201a201b200241f0096a41102019100422012001417f461b2201411020014110491b20196a3602002001410f4d0d0a2004411076211a200441087621092008200c411074722101200a422088a72105200aa72119200d290300210a20022903f009210b4103211b0c090b200241003a00f009200141086a20042001280200200141046a280200200241f0096a41012004100441016a220341014b6a220436020020034102490d2f20022d00f009220341044b0d2f024020030e050029252818000b200110a7022203450d2f200242003703f809200242003703f009200141086a22042004280200220441002001280200200141046a280200200241f0096a41102004100422012001417f461b2201411020014110491b6a3602002001410f4d0d2e200241f0096a41086a290300211120022903f0092115410221040c2a0b200241003a00f009200141086a20042001280200200141046a280200200241f0096a41012004100441016a220341014b6a220436020020034102490d5a20022d00f009220341084b0d5a024020030e09003431323035373339000b200241f0096a2001103a20022802f0092203450d5a20022902f4092111200141046a2802002105200141086a22062802002104200241003602f00920062004410020012802002005200241f0096a41042004100422012001417f461b2201410420014104491b6a360200200141034d0d59201142088821162003410876210120022802f00921072011a72119410221050c370b200241003a00f009200141086a20042001280200200141046a280200200241f0096a41012004100441016a220341014b6a220436020020034102490d890120022d00f0092203450d0820034101470d8901200242003703f809200242003703f009200141086a220541002001280200200141046a2206280200200241f0096a41102004100422032003417f461b22034110200341104922031b20046a220436020020030d8901200241f0096a41086a290300211120022903f0092115200242003703f0092005410020012802002006280200200241f0096a41082004100422032003417f461b2203410820034108491b20046a360200200341074d0d890120022903f0092116200241c0006a200110352002280240450d890120022802442203417f4c0d782003450d5e200310002204450d800120044100200310d0021a0c5f0b200241003a00f009200141086a200420012802002205200141046a2802002206200241f0096a41012004100441016a220341014b6a220436020020034102490d0920022d00f0092203450d0820034101470d09200241a80c6a4200370300200241a00c6a4200370300200241900c6a41086a4200370300200242003703900c200141086a2207410020052006200241900c6a41202004100422032003417f461b22034120200341204922031b20046a220436020020030d1d200220022f00910c3b01f00920022d00af0c210320022900a70c2111200229009f0c211520022900970c211620022800930c2112200220022d00900c3a00c006200220123600c306200220163700c706200220153700cf06200220113700d706200220033a00df06200220022f01f00922033b018807200220033b00c106200241003602f009410421032007410020052006200241f0096a41042004100422122012417f461b2212410420124104491b20046a2204360200201241034d0d1e20022802f0092107200241003a00f009200141086a200420052006200241f0096a41012004100441016a41014b22016a3602002001450d1e20022d00f00921052002200241c0066a41016a2f00003b01d007200241df066a2d00002106200241dd066a2f00002112200241dc066a2d00002117200241db066a2d00002118200241d7066a2800002119200241cf066a2900002111200241c7066a280000210141032103200241c0066a41036a280000210420022800cb06211a20022d00c006211b0c1f0b2000410b360200200241b00e6a24000f0b2000410b360200200241b00e6a24000f0b410721030c8e010b410721030c8a010b200241f0096a200110a802200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922034102460d012002418c0a6a2802002104200241900a6a28020021062002418a0a6a2f01002107200241890a6a2d00002112200241880a6a2d00002117200241840a6a2802002118200228009f0c2105200228009b0c211920022900930c211120022f01900c211b20022d00920c2108200242003703f809200242003703f009200141086a221a201a280200221a41002001280200200141046a280200200241f0096a4110201a100422012001417f461b2201411020014110491b6a3602002001410f4d0d012004411076211a20044108762109201b2008411074722101200241f8096a290300211520022903f00921164102211b0b200020013b000d20004101360200200020123a0025200020093a00292000201a3b002a2000410f6a20014110763a0000200041386a2015370200200041306a2016370200200041c8006a200a370200200041c0006a200b370200200041086a201b3602002000410c6a20033a0000200041106a2011370000200041186a20193600002000411c6a2005360000200041206a2018360000200041246a20173a0000200041266a20073b0000200041286a20043a00002000412c6a2006360000200241b00e6a24000f0b2000410b360200200241b00e6a24000f0b200241a80c6a4200370300200241900c6a41106a4200370300200241900c6a41086a4200370300200242003703900c200141086a220541002001280200200141046a2206280200200241900c6a41202004100422032003417f461b22034120200341204922031b20046a220436020020030d1b200220022f00910c3b01f00920022d00af0c210320022900a70c2111200229009f0c211520022900970c211620022800930c2107200220022d00900c3a00c006200220073600c306200220163700c706200220153700cf06200220113700d706200220033a00df06200220022f01f00922033b018807200220033b00c106200242003703f809200242003703f0092005410020012802002006280200200241f0096a41102004100422032003417f461b2203411020034110491b20046a22043602002003410f4d0d43200241f0096a41086a290300210a20022903f0092116200242003703f00941042103200141086a41002001280200200141046a280200200241f0096a41082004100422052005417f461b2205410820054108491b20046a360200200541074d0d7d20022903f009210b200241306a200110352002280230450d7d20022802342204417f4c0d6f2004450d59200410002205450d7820054100200410d0021a0c5a0b200241003602f009200141086a410020052006200241f0096a41042004100422032003417f461b22034104200341044922031b20046a36020020030d0020022802f0092104200110a7022201450d00200220022f01d0073b01f009410221030c170b200220022f01d0073b01f0090c83010b200242003703f009200141086a410020052006200241f0096a41082004100422012001417f461b22014108200141084922011b20046a36020020010d1f20022903f0092211422088a721182011a72119410321170c010b200241a80c6a4200370300200241a00c6a4200370300200241900c6a41086a4200370300200242003703900c200141086a410020052006200241900c6a41202004100422012001417f461b22014120200141204922011b20046a36020020010d1d200220022f00910c3b01f00920022d00af0c210520022f00ad0c210420022d00ac0c210320022d00ab0c210120022800a70c2106200229009f0c211120022900970c211520022800930c2107200220022d00900c22123a00c006200220073600c306200220153700c706200220113700cf06200220063600d706200220013a00db06200220033a00dc06200220043b00dd06200220053a00df06200220022f01f00922173b018807200220173b00c106200220022f00c10622173b01ce07200220173b01d0072015422088a721182015a72119410221170b200220022f01d007221a3b01f0092002201a3b01e003200041086a20173a000020004103360200200020123a00092000410c6a2007360200200041106a2019360200200041146a2018360200200041186a2011370200200041206a2006360200200041246a20013a0000200020033a0025200041266a20043b0100200041286a20053a0000200020022f01e0033b000a200241b00e6a24000f0b200141046a2802002105200241003602f009200141086a410020012802002005200241f0096a41042004100422012001417f461b22014104200141044922011b20046a36020020010d830120022802f0092104410621030c84010b200141046a22072802002105200241003602f009200141086a2212410020012802002005200241f0096a41042004100422052005417f461b2205410420054104491b20046a2206360200200541034d0d820120022802f0092104200242003703f809200242003703f0092012410020012802002007280200200241f0096a41102006100422052005417f461b22054110200541104922051b20066a220636020020050d8201200241f0096a41086a290300211120022903f0092115200242003703f009200141086a220741002001280200200141046a2212280200200241f0096a41082006100422032003417f461b2205410820054108491b20066a220636020041072103200541074d0d820120022903f009211620122802002105200241003602f0092007410020012802002005200241f0096a41042006100422012001417f461b2201410420014104491b20066a360200200141034d0d820120022802f0092101200241e0076a2011370300200220153703d807200220013602d007410421030c83010b200242003703f009200141086a410020052006200241f0096a41082004100422012001417f461b22014108200141084922011b20046a36020020010d0920022903f0092211422088a721052011a72106410621010c070b200241286a200110352002280228450d0a200228022c2219ad221142187e2215422088a70d662015a72204417f4c0d662004450d402004100022130d41200441041019000b200141046a2802002105200241003602f009200141086a410020012802002005200241f0096a41042004100422012001417f461b22014104200141044922011b20046a36020020010d7f20022802f0092104410521030c80010b200242003703f809200242003703f009200141086a41002001280200200141046a280200200241f0096a41102004100422012001417f461b22014110200141104922011b20046a36020020010d7e20022903f00921112002200241f0096a41086a2903003703d807200220113703d007410321030c7e0b200241a80c6a4200370300200241a00c6a4200370300200241900c6a41086a4200370300200242003703900c200141086a410020052006200241900c6a41202004100422012001417f461b22014120200141204922011b20046a36020020010d33200220022f00910c3b01f00920022d00af0c210420022f00ad0c210720022d00ac0c211220022d00ab0c211720022800a70c2118200229009f0c211120022900970c211520022800930c2103200220022d00900c221a3a00c006200220033600c306200220153700c706200220113700cf06200220183600d706200220173a00db06200220123a00dc06200220073b00dd06200220043a00df06200220022f01f00922013b018807200220013b00c106200220022f00c1063b01d0072015422088a721052015a72106410421010c3a0b200141046a2802002103200241003602f009200141086a410020012802002003200241f0096a41042004100422012001417f461b22014104200141044922011b20046a36020020010d1720022802f0092103410621040c110b200241086a200110352002280208450d05200228020c2204417f4c0d612004450d3d200410002213450d6720134100200410d0021a0c3e0b200242003703f009200141086a410020052006200241f0096a41082004100422012001417f461b22014108200141084922011b20046a36020020010d0220022903f0092211422088a721052011a72106410521010b0b200220022f01d0073b01f0090c370b200220022f01d0073b01f0090c720b200241106a200110352002280210450d0020022802142204417f4c0d5c2004450d3a200410002213450d6320134100200410d0021a0c3b0b410021050c6e0b200241a80c6a4200370300200241a00c6a4200370300200241900c6a41086a4200370300200242003703900c200141086a221b410020052006200241900c6a41202004100422012001417f461b22014120200141204922011b20046a221936020020010d2b200220022f00910c3b01f00920022d00900c211a20022800930c210320022900970c2115200229009f0c211120022800a70c211820022d00ab0c211720022d00ac0c211220022f00ad0c210720022d00af0c2104200220022f01f00922013b018807200220013b01ce07200241003a00f009201b201920052006200241f0096a41012019100441016a41014b22016a3602002001450d3020022d00f0092119200220022f01ce073b01d0072015422088a721052015a72106410321010c320b200220022f01f0093b018807410421030b0b200220022f01d0073b01f00920034104460d6d0b200220022f01f0093b01e003200020033a0004200041083602002000201b3a0005200041086a20043602002000410c6a2001360200200041106a201a360200200041146a20113702002000411c6a2019360200200041206a20183a0000200020173a0021200041226a20123b0100200041246a20063a0000200020053a0025200041286a2007360200200020022f01e0033b0006200241b00e6a24000f0b200141046a22052802002103200241003602f009200141086a2206410020012802002003200241f0096a41042004100422032003417f461b22034104200341044922031b20046a220436020020030d0a20022802f0092103200241003a00f0092006200420012802002005280200200241f0096a41012004100441016a41014b22016a3602002001450d0a20022d00f0092101410421040c060b200241f0096a2001103820022802f0092205450d6b20022902f4092111410321030c680b200220022f01f0093b0188070c640b200241f0096a200110bb0120022802f0092104200241900c6a200241f0096a410472419c0210ce021a2004410b460d07200241d0076a200241900c6a419c0210ce021a41a00210002203450d5720032004360200200341046a200241d0076a419c0210ce021a200241003a00f009200141086a2204200428020022042001280200200141046a280200200241f0096a41012004100441016a41014b22016a3602002001450d0620022d00f009220141034f0d06410521040c030b200141046a2802002103200241003602f009200141086a410020012802002003200241f0096a41042004100422012001417f461b22014104200141044922011b20046a36020020010d0620022802f0092103410321040b0b0b200220022f01e00322053b01f009200220053b019802200041186a2011370200200041106a2015370200200041086a20043a000020004105360200200020013a00092000410c6a2003360200200020022f0198023b000a200241b00e6a24000f0b200220022f01f0093b0188070b200220022f01d0073b01f0092000410b360200200241b00e6a24000f0b2003102c200310010b200220022f01e0033b01f0092000410b360200200241b00e6a24000f0b200241f0096a200110a802200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922034102460d2a2002418c0a6a2802002104200241900a6a28020021122002418a0a6a2f0100211a200241890a6a2d0000211b200241880a6a2d00002106200241840a6a2802002117200228009f0c2118200228009b0c210720022900930c210a20022f01900c210c20022d00920c210d200242003703f809200242003703f009200141086a22052005280200220541002001280200200141046a2208280200200241f0096a41102005100422052005417f461b2205411020054110491b6a22193602002005410f4d0d2a200241f0096a41086a290300211120022903f009211520082802002105200241003602f009200141086a410020012802002005200241f0096a41042019100422012001417f461b2201410420014104491b20196a360200200141034d0d2a2004411076210820044108762109200c200d411074722101200a420888211620022802f009210c200aa72119410621050c0b0b41042105200141046a2802002103200241003602f009200141086a410020012802002003200241f0096a41042004100422012001417f461b22014104200141044922011b20046a36020020010d2920022802f009220341087621010c040b200141046a2802002103200241003602f009200141086a410020012802002003200241f0096a41042004100422012001417f461b22014104200141044922011b20046a36020020010d2820022802f00922034108762101410521050c030b200242003703f009200141086a41002001280200200141046a280200200241f0096a41082004100422012001417f461b22014108200141084922011b20046a36020020010d2720022903f009221142088821162011a72119410921050c060b200141046a2802002103200241003602f009200141086a410020012802002003200241f0096a41042004100422032003417f461b22034104200341044922031b20046a36020020030d2620022802f0092103200241f0096a200110a802200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922194102460d26200241900a6a280200210c2002418c0a6a28020021122002418a0a6a2f01002108200241890a6a2d00002109200241880a6a2d00002104200241840a6a2802002106200228009f0c2117200228009b0c211820022800970c210720023502900c211120023301940c211520023100960c2116200141046a220e280200211a200141086a221b2802002105200241003602f009201b200541002001280200201a200241f0096a410420051004221a201a417f461b221a4104201a4104491b6a2205360200201a41034d0d2620022802f009210d200e280200211a200241003602f009201b41002001280200201a200241f0096a41042005100422012001417f461b2201410420014104491b20056a360200200141034d0d262006411076211a2006410876211b201120152016421086844220868421162003410876210120023502f009211542002111410321050c070b200141046a2802002103200241003602f009200141086a410020012802002003200241f0096a41042004100422012001417f461b22014104200141044922011b20046a36020020010d2520022802f00922034108762101410721050b0c040b200241f0096a200110a80241082105200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922034102460d2320022900930c221142088821162002418c0a6a280200220441087621092004411076210820022f01900c20022d00920c4110747221012002419b0c6a2900002215422088a72118200241840a6a2802002117200241880a6a2d00002106200241890a6a2d0000211b2002418a0a6a2f0100211a200241900a6a28020021122011a721192015a721070b0c030b200242003703f009200141086a41002001280200200141046a280200200241f0096a41082004100422012001417f461b22014108200141084922011b20046a36020020010d2120022903f009221142088821162011a72119410a21050b0b0b200041063602002000201b3a0025200020093a0029200020083b012a200041c0006a2011370200200041386a2015370200200041086a2005360200200041186a20073602002000411c6a2018360200200041206a2017360200200041246a20063a0000200041266a201a3b0100200041286a20043a00002000412c6a2012360200200041306a200c360200200041346a200d3602002000410c6a2001410874200341ff017172360200200041106a20164208862019ad42ff018384370200200241b00e6a24000f0b200141046a22052802002103200241003602f009200141086a2207410020012802002003200241f0096a41042004100422032003417f461b22034104200341044922031b20046a220436020020030d0b20022802f009210620052802002103200241003602f0092007410020012802002003200241f0096a41042004100422032003417f461b22034104200341044922031b20046a220436020020030d0b20022802f0092112200242003703f809200242003703f009200141086a41002001280200200141046a280200200241f0096a41102004100422012001417f461b2201411020014110491b20046a3602002001410f4d0d0b2006410876210d200241f0096a41086a290300211120022903f0092215a7210e410621050c020b200141046a2802002103200241003602f009200141086a410020012802002003200241f0096a41042004100422012001417f461b22014104200141044922011b20046a36020020010d0a20022802f0092206410876210d410b21050c040b200241f0096a200110a802200241900c6a41086a200241f9096a290000370300200241900c6a41106a200241810a6a2f00003b0100200241a20c6a200241830a6a2d00003a0000200220022900f1093703900c20022d00f00922064102460d092002418c0a6a280200220741087621082007411076211a20022f01900c20022d00920c41107472210d2002419b0c6a2900002111200241840a6a2802002112200241880a6a2d00002117200241890a6a2d000021182002418a0a6a2f01002119200241900a6a280200211b20022900930c2215a7210e410421050b2015422088a721090c070b200141046a2802002103200241003602f009200141086a410020012802002003200241f0096a41042004100422012001417f461b22014104200141044922011b20046a36020020010d0720022802f0092206410876210d410521050c010b200141046a2802002103200241003602f009200141086a410020012802002003200241f0096a41042004100422012001417f461b22014104200141044922011b20046a36020020010d0620022802f0092206410876210d410921050b0c040b200242003703f009200141086a41002001280200200141046a280200200241f0096a41082004100422012001417f461b22014108200141084922011b20046a36020020010d0420022903f0092211422088a721092011a7210e410721050c010b200242003703f00941082105200141086a41002001280200200141046a280200200241f0096a41082004100422012001417f461b22014108200141084922011b20046a36020020010d0320022903f0092211422088a721092011a7210e0b0c010b200241003a00f009200141086a20042001280200200141046a280200200241f0096a41012004100441016a220141014b6a36020020014102490d0120022d00f009210c410a21050b200220022f01d00722013b01f009200220013b01e003200041086a20053a0000200041043602002000200c3a00092000410c6a200d410874200641ff017172360200200041106a200e360200200041146a2009360200200041186a2011370200200041206a2012360200200041246a20173a0000200020183a0025200041266a20193b0100200041286a20073a0000200020083a00292000201a3b012a2000412c6a201b360200200020022f01e0033b000a200241b00e6a24000f0b200220022f01d0073b01f0092000410b360200200241b00e6a24000f0b200220022f01f0093b0188070c010b200220022f01f0093b0188070b410721010c050b200220022f01f0093b01900c410221040c100b410421030c390b200220022f01f0093b0188070c440b410721010b0b200220022f01d0073b01f00920014107460d3c0b200220022f01f0093b01e003200041086a20013a0000200041073602002000201a3a00092000410c6a2003360200200041106a2006360200200041146a2005360200200041186a2011370200200041206a2018360200200041246a20173a0000200020123a0025200041266a20073b0100200041286a20043a0000200020193a0029200020022f01e0033b000a200241b00e6a24000f0b410421130b02402019450d00200141086a2107200141046a2117410021180340200241206a200110352002280220450d1520022802242204417f4c0d26024002402004450d00200410002205450d2a20054100200410d0021a0c010b410121050b2007200728020022062004410020012802002017280200200520042006100422062006417f461b2206200620044b1b6a360200200420064b0d142005450d152004ad22154220862015842115200241186a200110352002280218450d13200228021c2204417f4c0d26024002402004450d00200410002206450d2b20064100200410d0021a0c010b410121060b2007200728020022122004410020012802002017280200200620042012100422122012417f461b2212201220044b1b6a360200200420124b0d122006450d1302402011422088a722122011a7470d00201241016a221a2012490d282012410174221b201a201a201b491bad221642187e220a422088a70d28200aa7221a4100480d28024002402012450d00201a1000221b450d2d201b2013201a201241186c22122012201a4b1b10ce02211220131001201221130c010b201a10002213450d2c0b20114280808080708320168421110b20132011422088a741186c6a22122015370204201220053602002012200636020c201241106a2004ad221542208620158437020020114280808080107c2111201841016a22182019490d000b0b2013450d0d41062103201321050c3d0b410121130b41002105200141086a220620062802002206200441002001280200200141046a280200201320042006100422012001417f461b2201200120044b1b6a3602002004ad221142208620118421110240200420014d0d00201310010c370b2013450d0720132105410421030c3b0b410121130b41002105200141086a220620062802002206200441002001280200200141046a280200201320042006100422012001417f461b2201200120044b1b6a3602002004ad221142208620118421110240200420014d0d00201310010c350b2013450d0841052103201321050c390b2011a7450d00200310010b2000410b360200200241b00e6a24000f0b200241900c6a41186a200241f0096a41186a290000370300200241900c6a41106a200241f0096a41106a290000370300200241900c6a41086a200241f0096a41086a290000370300200220022900f0093703900c200220022f01d0073b01900c0b410221040b0c270b201321050c2e0b410121040b200141086a220520052802002205200341002001280200200141046a280200200420032005100422052005417f461b2205200520034b1b6a360200200320054b0d0b2004450d29200241386a200110352003ad220a422086200a84220aa721062002280238450d0a200228023c2203417f4c0d182003450d08200310002205450d2220054100200310d0021a0c090b201321050c2b0b201321050c2a0b410121050b41042103200141086a220620062802002206200441002001280200200141046a280200200520042006100422012001417f461b2201200120044b1b6a3602000240200420014d0d00200510010c230b2005450d2241022103200241d0076a41026a200241c0066a41026a2d00003a0000200220022f00c0063b01d0072004ad2211422086201184221142088842088620114238862005ad4218868422154238888421112015420886200241df066a310000842115200241db066a2800002112200241cf066a2800002105200241c7066a2800002106200241c3066a280000210420022900d306211c20022800cb0621070c230b200610010b2015a7450d010b200510010b02402011422088a72201450d00200141186c21042013210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141186a2101200441686a22040d000b0b410021052011a7450d23201310010c230b410121050b200141086a220720072802002207200341002001280200200141046a280200200520032007100422012001417f461b2201200120034b1b6a3602000240200320014d0d00200510010c010b2005450d00200a422088a721072003ad220a422086200a84211c200241f0096a41026a200241d0076a41026a2d00003a0000200220022f00d0073b01f00941032103200241f0096a21010c1e0b2006450d1e0b200410010c1d0b200141046a22132802002105200241003602f009200141086a2214410020012802002005200241f0096a41042004100422052005417f461b2205410420054104491b20046a2204360200200541034d0d0920022802f0092106200241c0066a41186a4200370300200241c0066a41106a4200370300200241c0066a41086a4200370300200242003703c0062014410020012802002013280200200241c0066a41202004100422052005417f461b22054120200541204922051b20046a220436020020050d02200220022f00c1063b01f00920022d00c006211320022800c306211420022900c706211c20022900cf06211d20022800d706211e20022d00db06211f20022d00dc06212020022f00dd06212120022d00df062122200220022f01f00922053b01900c200220053b01ce07200241f0096a41386a22234200370300200241f0096a41306a22244200370300200241f0096a41286a22254200370300200241f0096a41206a4200370300200241f0096a41186a4200370300200241f0096a41106a4200370300200241f0096a41086a22264200370300200242003703f009200141086a222741002001280200200141046a2228280200200241f0096a41c0002004100422052005417f461b220541c000200541c000491b20046a22043602002005413f4d0d04200241900c6a41386a22052023290300370300200241900c6a41306a22292024290300370300200241900c6a41286a222a2025290300370300200241900c6a41206a222b200241f0096a41206a222c290300370300200241900c6a41186a222d200241f0096a41186a222e290300370300200241900c6a41106a222f200241f0096a41106a2230290300370300200241900c6a41086a22312026290300370300200220022903f0093703900c2023200529030022323703002024202929030022333703002025202a2903002234370300202c202b2903002235370300202e202d29030022363703002030202f290300223737030020262031290300223837030020024188076a41086a203837030020024188076a41106a203737030020024188076a41186a203637030020024188076a41206a203537030020024188076a41286a203437030020024188076a41306a203337030020024188076a41386a2032370300200220022903900c223237038807200220323703f009200220022f01ce073b01cc07200241c0066a41186a4200370300200241c0066a41106a4200370300200241c0066a41086a4200370300200242003703c0062027410020012802002028280200200241c0066a41202004100422052005417f461b2205412020054120491b20046a22043602002005411f4d0d06200220022f00c1063b01f00920022d00c006210520022800c306212420022900c706213220022900cf06213320022800d706212520022d00db06212620022d00dc06212720022f00dd06212820022d00df062129200220022f01f00922233b01900c200220233b01ce07200241f0096a41386a22234200370300200241f0096a41306a222a4200370300200241f0096a41286a222b4200370300202c4200370300202e420037030020304200370300200241f0096a41086a222c4200370300200242003703f009200141086a41002001280200200141046a280200200241f0096a41c0002004100422012001417f461b220141c000200141c000491b20046a3602002001413f4d0d08200241900c6a41386a22302023290300370300200241900c6a41306a222d202a290300370300200241900c6a41286a222f202b290300370300200241900c6a41206a2231200241f0096a41206a2201290300370300200241900c6a41186a2239200241f0096a41186a2204290300370300200241900c6a41106a223a200241f0096a41106a222e290300370300200241900c6a41086a223b202c290300370300200220022903f0093703900c202320302903002234370300202a202d2903002235370300202b202f2903002236370300200120312903002237370300200420392903002238370300202e203a290300223d370300202c203b290300223e370300200241c0066a41086a203e370300200241c0066a41106a203d370300200241c0066a41186a2038370300200241c0066a41206a2037370300200241c0066a41286a2036370300200241c0066a41306a2035370300200241c0066a41386a2034370300200220022903900c22343703c006200220343703f009200220022f01ce073b018607202c20024188076a41086a290300370300202e20024188076a41106a290300370300200420024188076a41186a290300370300200120024188076a41206a290300370300202b20024188076a41286a290300370300202a20024188076a41306a290300370300202320024188076a41386a290300370300200220022f01cc073b01ce0720022002290388073703f009410121040b200241f8056a41086a2201200241f0096a41086a223f290300370300200241f8056a41106a2223200241f0096a41106a2240290300370300200241f8056a41186a222c200241f0096a41186a2241290300370300200241f8056a41206a222e200241f0096a41206a2242290300370300200241f8056a41286a2230200241f0096a41286a290300370300200241f8056a41306a222a200241f0096a41306a290300370300200241f8056a41386a222b200241f0096a41386a290300370300200220022f01ce073b01be06200220022903f0093703f805200241b0056a41086a222d200241c0066a41086a290300370300200241b0056a41106a222f200241c0066a41106a290300370300200241b0056a41186a2231200241c0066a41186a290300370300200241b0056a41206a2239200241c0066a41206a290300370300200241b0056a41286a223a200241c0066a41286a290300370300200241b0056a41306a223b200241c0066a41306a290300370300200241b0056a41386a223c200241c0066a41386a290300370300200220022f0186073b01f605200220022903c0063703b005200241ac056a41026a2243200241900c6a41026a2d00003a0000200220022f00900c3b01ac05200241900c6a41286a2001290300370000200241900c6a41306a2023290300370000200241900c6a41386a202c290300370000200241d00c6a202e290300370000200241d80c6a2030290300370000200241e00c6a202a290300370000200241e80c6a202b290300370000200220133a00900c200220143600930c2002201c3700970c2002201d37009f0c2002201e3600a70c2002201f3a00ab0c200220203a00ac0c200220213b00ad0c200220223a00af0c200220022f01be063b00910c200220022903f8053700b00c200241980d6a202d290300370000200241a00d6a202f290300370000200241a80d6a2031290300370000200241b00d6a2039290300370000200241b80d6a203a290300370000200241c00d6a203b290300370000200241c80d6a203c290300370000200220053a00f00c200220243600f30c200220323700f70c200220333700ff0c200220253600870d200220263a008b0d200220273a008c0d200220283b008d0d200220293a008f0d200220022f01f6053b00f10c200220022903b0053700900d200241d20d6a20432d00003a0000200220022f01ac053b00d00d203f201c3703002040201d3703002041201e3602002002418c0a6a201f3a00002002418d0a6a20203a00002002418e0a6a20213b0100204220223a0000200241910a6a20022903f805370000200241990a6a2001290300370000200241a10a6a2023290300370000200241a90a6a202c290300370000200241b10a6a202e290300370000200241b90a6a2030290300370000200241c10a6a202a290300370000200241c90a6a202b290300370000200220133a00f109200220043a00f009200220143602f409200220022f01be063b01f209200241d10a6a20053a0000200241d40a6a2024360200200241d80a6a2032370300200241e00a6a2033370300200241e80a6a2025360200200241ec0a6a20263a0000200241ed0a6a20273a0000200241ee0a6a20283b0100200241f00a6a20293a0000200241d20a6a20022f01f6053b0100200241f10a6a20022903b005370000200241f90a6a202d290300370000200241810b6a202f290300370000200241890b6a2031290300370000200241910b6a2039290300370000200241990b6a203a290300370000200241a10b6a203b290300370000200241a90b6a203c290300370000200241b40b6a2006360200200241f0096a41c3016a20432d00003a0000200241b10b6a20022f01ac053b0000200241d0076a200241900c6a41c30110ce021a20044102460d090c150b200220022f01f0093b01900c0c070b200220022f01f0093b01900c0c060b2023200241900c6a41386a2900003703002024200241900c6a41306a2900003703002025200241900c6a41286a290000370300200241f0096a41206a200241900c6a41206a290000370300200241f0096a41186a200241900c6a41186a290000370300200241f0096a41106a200241900c6a41106a2900003703002026200241900c6a41086a290000370300200220022900900c3703f0090c050b2023200241900c6a41386a2900003703002024200241900c6a41306a2900003703002025200241900c6a41286a290000370300200241f0096a41206a200241900c6a41206a290000370300200241f0096a41186a200241900c6a41186a290000370300200241f0096a41106a200241900c6a41106a2900003703002026200241900c6a41086a290000370300200220022900900c3703f0090c040b200220022f01f0093b01900c0c030b200220022f01f0093b01900c0c020b202a200241900c6a41386a290000370300202b200241900c6a41306a290000370300202d200241900c6a41286a290000370300200241f0096a41206a200241900c6a41206a290000370300200241f0096a41186a200241900c6a41186a290000370300200241f0096a41106a200241900c6a41106a290000370300202c200241900c6a41086a290000370300200220022900900c3703f0090c010b2023200241900c6a41386a290000370300202a200241900c6a41306a290000370300202b200241900c6a41286a290000370300200241f0096a41206a200241900c6a41206a290000370300200241f0096a41186a200241900c6a41186a290000370300200241f0096a41106a200241900c6a41106a290000370300202c200241900c6a41086a290000370300200220022900900c3703f0090b200241900c6a41286a200241f8056a41086a290000370000200241900c6a41306a200241f8056a41106a290000370000200241900c6a41386a200241f8056a41186a290000370000200241d00c6a200241f8056a41206a290000370000200241d80c6a200241f8056a41286a290000370000200241e00c6a200241f8056a41306a290000370000200241e80c6a200241f8056a41386a290000370000200220022f01be063b00910c200220022900f8053700b00c200241980d6a200241b0056a41086a290000370000200241a00d6a200241b0056a41106a290000370000200241a80d6a200241b0056a41186a290000370000200241b00d6a200241b0056a41206a290000370000200241b80d6a200241b0056a41286a290000370000200241c00d6a200241b0056a41306a290000370000200241c80d6a200241b0056a41386a290000370000200220022f01f6053b00f10c200220022900b0053700900d41022104200241d20d6a200241ac056a41026a2d00003a0000200220022f00ac053b00d00d41024102470d0c0b410221040c0c0b102e000b1018000b200441011019000b200441011019000b201a41041019000b41a00241081019000b200441011019000b200441011019000b200341011019000b200441011019000b200341011019000b200220022f01a8053b01de03200220022f01aa053b01dc03200241e0036a200241d0076a41c30110ce021a0c010b0b200241f0096a200241e0036a41c30110ce021a200220022f01de033b01900c200220022f01dc033b01d00720044102460d0a20024198026a200241f0096a41c30110ce021a200220022f01900c3b019602200220022f01d0073b019402410221030c0b0b0b200241f0096a41026a200241d0076a41026a2d00003a0000200220022f01d0073b01f009200241f0096a210120034104460d020b200241e0036a41026a2217200141026a2d00003a0000200220012f00003b01e003200041306a2011370000200041286a2015370000200041c0006a200a370000200041386a2016370000200041086a20033a00002000410a3602002000410c6a2004360000200041106a2006360000200041146a2007360000200041186a20053600002000411c6a201c370000200041246a2012360000200041c8006a200b370000200020022f01e0033b00092000410b6a20172d00003a0000200241b00e6a24000f0b200241f0096a41026a200241d0076a41026a2d00003a0000200220022f01d0073b01f0090b2000410b360200200241b00e6a24000f0b0b0c040b2000410b360200200241b00e6a24000f0b2000410b360200200241b00e6a24000f0b0b0b200241f0096a20024198026a41c30110ce021a200220022f0196023b01900c200220022f0194023b01d007024020034107470d002000410b360200200241b00e6a24000f0b200241d0006a200241f0096a41c30110ce021a200220022f01900c3b014e200220022f01d0073b014c200041086a2003360200200041003602002000410c6a2005360200200041106a2011370200200041186a20043a0000200041196a200241d0006a41c30110ce021a200041e0016a20083a0000200041dc016a2006360000200041e3016a2009360000200041e7016a200a370000200041ef016a200b370000200041f7016a200c3600002000200d3a00fb01200041fc016a200e3a0000200041fd016a200f3b0000200020103a00ff0120004180026a20073a000020004183026a201236000020004187026a20153700002000418f026a201637000020004197026a2017360000200020022f014e3b00e101200020022f014c3b0081022000419c026a20193a0000200020183a009b022000419d026a201a3b00002000201b3a009f02200241b00e6a24000f0b0b200241900c6a41026a220120024198026a41026a2d00003a0000200241f0096a41086a2205200241d0076a41086a290300370300200241f0096a41106a2206200241d0076a41106a290300370300200220022f0198023b01900c200220022903d0073703f009024020034107470d002000410b360200200241b00e6a24000f0b200241d0006a41026a220720012d00003a0000200241e0036a41086a22012005290300370300200241e0036a41106a22052006290300370300200220022f01900c3b0150200220022903f0093703e003200041386a2011370000200041306a2015370000200041086a20033a0000200041093602002000410c6a2004360000200041286a2016370000200020022f01503b00092000410b6a20072d00003a0000200041106a20022903e003370000200041186a2001290300370000200041206a2005290300370000200241b00e6a24000bca0201017f0240024002400240024002400240024002402000280200220141094b0d0020010e0a01080808080203040508010b200041086a2d00002201411e74411e75417f4a0d0720014102470d06200041306a280200450d072000412c6a28020010010f0b200041086a10a9020f0b200041086a2d000022014107714105460d0320014102470d052000410c6a220028020010bc01200028020010010f0b200041086a2802004102470d04200041106a280200450d042000410c6a28020010010f0b200041086a2d00004102470d032000410c6a220028020010bc01200028020010010f0b20002d00044102470d022000410c6a220028020010bc01200028020010010f0b2000410c6a220028020010bc01200028020010010f0b0240200041106a280200450d002000410c6a28020010010b2000411c6a280200450d00200041186a28020010010f0b0bbf0704037f027e0c7f037e23004190016b22012400200141f0006a41086a220242003703002001420037037041f88dc2004115200141f0006a1002200141106a41086a2002290300370300200120012903703703100240024002400240024002400240024002400240200141106a411041b8d6c200410041001004417f460d00200142103702242001200141106a360220200141086a200141206a10352001280208450d05200128020c2203ad220442287e2205422088a70d082005a72202417f4c0d082002450d01200210002206450d0920030d020c030b200041003602082000420837020020014190016a24000f0b410821062003450d010b200141206a41086a22072802002108200128022421092001280220210a200141f0006a41186a210b200141f0006a41106a210c4100210d0340200b4200370300200c4200370300200141f0006a41086a220e42003703002001420037037020074100200a2009200141f0006a41202008100422022002417f461b2202412020024120491b20086a22083602002002411f4d0d02200141d0006a41186a220f200b290300370300200141d0006a41106a2210200c290300370300200141d0006a41086a2211200e290300370300200120012903703703502001420037037020074100200a2009200141f0006a41082008100422022002417f461b2202410820024108491b20086a2208360200200241074d0d0220012903702105200141306a41186a2202200f290300370300200141306a41106a220f2010290300370300200141306a41086a2210201129030037030020012001290350370330200b2002290300370300200c200f290300370300200e20102903003703002001200129033037037002402004422088a72004a72202470d00200241016a220f2002490d0520024101742210200f200f2010491bad221242287e2213422088a70d052013a7220f4100480d05024002402002450d00200f10002210450d0820102006200f200241286c22022002200f4b1b10ce02210220061001200221060c010b200f10002206450d070b20044280808080708320128421040b20062004422088a741286c6a22022001290370370300200e2903002112200c2903002113200b290300211420022005370320200241186a2014370300200241106a2013370300200241086a201237030020044280808080107c2104200d41016a220d2003490d000b0b2006450d01200020043702042000200636020020014190016a24000f0b2004a7450d00200610010b41b2eac10041331040000b1018000b200f41081019000b102e000b200241081019000b8e0203027f017e017f230041306b22032400200341106a41086a220442003703002003420037031020012002200341106a1002200341206a41086a20042903003703002003200329031037032002400240200341206a411041b8d6c200410041001004417f460d00200342103702042003200341206a360200200341106a2003103920032802102204450d0120032902142105200341106a41086a220642003703002003420037031020012002200341106a1002200341206a41086a200629030037030020032003290310370320200341206a4110100a2000200537020420002004360200200341306a24000f0b2000410036020820004201370200200341306a24000f0b41b2eac10041331040000ba20101027f230041206b22022400200241106a41086a220342003703002002420037031020002001200241106a1002200241086a20032903003703002002200229031037030002402002411041b8d6c200410041001004417f460d0020024100360210024020024110200241106a41044100100441016a41044d0d0020022802102100200241206a240020000f0b41b2eac10041331040000b41c3d7c10041221040000be30604037f027e0b7f027e230041f0006b22012400200141d0006a41086a220242003703002001420037035041b8d6c2004117200141d0006a1002200141106a41086a20022903003703002001200129035037031002400240200141106a411041b8d6c200410041001004417f460d00200142103702242001200141106a360220200141086a200141206a103502400240024002402001280208450d00200128020c2203ad220442287e2205422088a70d032005a72202417f4c0d0302400240024002402002450d00200210002206450d0920030d010c020b410821062003450d010b200141206a41086a22072802002108200128022421092001280220210a200141d0006a41186a210b200141d0006a41106a210c4100210d03402001420037035020074100200a2009200141d0006a41082008100422022002417f461b2202410820024108491b20086a2208360200200241074d0d0220012903502105200b4200370300200c4200370300200141d0006a41086a220e42003703002001420037035020074100200a2009200141d0006a41202008100422022002417f461b2202412020024120491b20086a22083602002002411f4d0d02200141306a41186a2202200b290300370300200141306a41106a220f200c290300370300200141306a41086a2210200e29030037030020012001290350370330200b2002290300370300200c200f290300370300200e20102903003703002001200129033037035002402004422088a72004a72202470d00200241016a220f2002490d0520024101742210200f200f2010491bad221142287e2212422088a70d052012a7220f4100480d05024002402002450d00200f10002210450d0820102006200f200241286c22022002200f4b1b10ce02210220061001200221060c010b200f10002206450d070b20044280808080708320118421040b20062004422088a741286c6a22022005370300200241206a200b290300370300200241186a200c290300370300200241106a200e2903003703002002200129035037030820044280808080107c2104200d41016a220d2003490d000b0b2006450d012000200437020420002006360200200141f0006a24000f0b2004a7450d00200610010b41b2eac10041331040000b1018000b200f41081019000b102e000b41c3d7c10041221040000b200241081019000b3400200041f2d9c10036020420004100360200200041086a4207370200200041106a41aca4c000360200200041146a41083602000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a41d4a8c000360200200041206a41033602000b3400200041c5dec10036020420004100360200200041086a420e370200200041106a4194aac000360200200041146a41043602000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a41a4acc000360200200041206a41023602000b130020004101360204200041acaec0003602000b13002000410536020420004188afc0003602000bd70101027f230041206b22032400200341106a41086a220442003703002003420037031020012002200341106a1002200341086a20042903003703002003200329031037030041002101024002402003411041b8d6c200410041001004417f460d002003410036021020034110200341106a41044100100441016a41044d0d01200328021021012003410036021020034110200341106a41044104100441016a41044d0d01200041086a200328021036020020002001360204410121010b20002001360200200341206a24000f0b41b2eac10041331040000b980202027f017e230041c0006b22032400200341306a41086a220442003703002003420037033020012002200341306a1002200341086a200429030037030020032003290330370300024002402003411041b8d6c200410041001004417f460d002003200336021020034110360214200342003703302003410020034110200341306a41084100100422012001417f461b2201410820014108491b360218200141074d0d0120032903302105200341306a200341106a103920032802302201450d012003200329023437032020002001360208200020053703002000200329032037020c200041146a200341286a280200360200200341c0006a24000f0b20004100360208200341c0006a24000f0b41b2eac10041331040000bec0503067f027e027f230041206b22012400200028020021020240024002400240024002400240024002400240024020002802082203413f4b0d0041012100410110002204450d06200420034102743a00004101210520030d010c020b02402003418080014f0d0041022100410210002204450d07200420034102744101723b00000c010b024020034180808080044f0d0041042100410410002204450d08200420034102744102723600000c010b410110002205450d08200541033a000041052100410510002204450d09200420052d00003a000020051001200420033600010b2002200341306c6a2106200021050340200241086a2903002107200229030021080240024002400240200020056b41104f0d00200541106a22032005490d0620004101742209200320032009491b22094100480d062000450d0120091000220a450d07200a200420092000200020094b1b10ce02210020041001200021040c020b200541106a21030c020b200910002204450d050b200921000b200420056a22052007370008200520083700000240024002400240200020036b41204f0d00200341206a22052003490d0620004101742209200520052009491b22094100480d062000450d0120091000220a450d08200a200420092000200020094b1b10ce02210020041001200021040c020b200341206a21050c020b200910002204450d060b200921000b200420036a220341186a200241286a290000370000200341106a200241206a290000370000200341086a200241186a2900003700002003200241106a290000370000200241306a22022006470d000b0b200141106a41086a220242003703002001420037031041898fc2004113200141106a1002200141086a2002290300370300200120012903103703002001411020042005100302402000450d00200410010b200141206a24000f0b1018000b200941011019000b200941011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000bd90503067f017e027f230041206b22012400200028020021020240024002400240024002400240024002400240024020002802082203413f4b0d0041012100410110002204450d06200420034102743a00004101210520030d010c020b02402003418080014f0d0041022100410210002204450d07200420034102744101723b00000c010b024020034180808080044f0d0041042100410410002204450d08200420034102744102723600000c010b410110002205450d08200541033a000041052100410510002204450d09200420052d00003a000020051001200420033600010b2002200341286c6a2106200021050340200229030021070240024002400240200020056b41084f0d00200541086a22032005490d0620004101742208200320032008491b22084100480d062000450d01200810002209450d072009200420082000200020084b1b10ce02210020041001200021040c020b200541086a21030c020b200810002204450d050b200821000b200420056a20073700000240024002400240200020036b41204f0d00200341206a22052003490d0620004101742208200520052008491b22084100480d062000450d01200810002209450d082009200420082000200020084b1b10ce02210020041001200021040c020b200341206a21050c020b200810002204450d060b200821000b200420036a220341186a200241206a290000370000200341106a200241186a290000370000200341086a200241106a2900003700002003200241086a290000370000200241286a22022006470d000b0b200141106a41086a220242003703002001420037031041b8d6c2004117200141106a1002200141086a2002290300370300200120012903103703002001411020042005100302402000450d00200410010b200141206a24000f0b1018000b200841011019000b200841011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000bbd06010a7f230041206b22012400200141003602182001420137031020002802002102024002400240024002400240024002400240024020002802082200413f4b0d00410110002203450d05200120033602102001428180808010370214200320004102743a000020000d010c020b02402000418080014f0d00410210002203450d06200120033602102001428280808020370214200320004102744101723b00000c010b024020004180808080044f0d00410410002203450d072001200336021020014284808080c000370214200320004102744102723600000c010b410110002203450d07200120033602102001428180808010370214200341033a0000024002400240024020012802142204200141186a28020022036b41044f0d00200341046a22052003490d0620044101742206200520052006491b22074100480d062004450d0120012802102108200710002206450d0c2006200820072004200420074b1b10ce021a200810010c020b200341046a2105200128021021060c020b200710002206450d0a0b20012007360214200120063602100b200141186a2005360200200620036a20003600000b200041c8026c2107200141186a21080340200241a0026a2802002109024002400240024020012802142206200828020022006b41044f0d00200041046a22032000490d0620064101742205200320032005491b22044100480d062006450d012001280210210a200410002205450d072005200a20042006200620044b1b10ce021a200a10010c020b200041046a2103200128021021050c020b200410002205450d050b20012004360214200120053602100b20082003360200200520006a20093600002002200141106a10a001200241a4026a200141106a101b200241c8026a2102200741b87d6a22070d000b0b200141106a41086a2202280200210320012802142105200128021021002002420037030020014200370310418bc8c1004115200141106a1002200141086a2002290300370300200120012903103703002001411020002003100302402005450d00200010010b200141206a24000f0b1018000b200441011019000b410141011019000b410241011019000b410441011019000b410141011019000b200741011019000b7501027f230041206b220324000240410410002204450d0020042002360000200341106a41086a220242003703002003420037031020002001200341106a1002200341086a2002290300370300200320032903103703002003411020044104100320041001200341206a24000f0b410441011019000bd70502087f017e230041206b22012400200028020021020240024002400240024002400240024002400240024020002802082203413f4b0d0041012100410110002204450d06200420034102743a00004101210520030d010c020b02402003418080014f0d0041022100410210002204450d07200420034102744101723b00000c010b024020034180808080044f0d0041042100410410002204450d08200420034102744102723600000c010b410110002205450d08200541033a000041052100410510002204450d09200420052d00003a000020051001200420033600010b2002200341286c6a21062000210503400240024002400240200020056b41204f0d00200541206a22032005490d0620004101742207200320032007491b22074100480d062000450d01200710002208450d072008200420072000200020074b1b10ce02210020041001200021040c020b200541206a21030c020b200710002204450d050b200721000b200420056a22052002290000370000200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a290000370000200241206a29030021090240024002400240200020036b41084f0d00200341086a22052003490d0620004101742207200520052007491b22074100480d062000450d01200710002208450d082008200420072000200020074b1b10ce02210020041001200021040c020b200341086a21050c020b200710002204450d060b200721000b200420036a20093700002006200241286a2202470d000b0b200141106a41086a220242003703002001420037031041f88dc2004115200141106a1002200141086a2002290300370300200120012903103703002001411020042005100302402000450d00200410010b200141206a24000f0b1018000b200741011019000b200741011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000ba40401057f230041c0006b2202240002400240024002400240024020012802082203200128020c2204470d00200241013a000f2002412c6a4101360200200241346a41013602002002410a36023c200241a082c00036022020024101360224200241c0c5c20036022820022002410f6a3602382002200241386a360230200241106a200241206a104c2002412a6a200241186a280200360100200220022903103701222002200241266a29010037010620022002290120370300410521030c010b200441016a21052004417f460d0320032005490d0420012802002106410c21032001410c6a2005360200200620046a2d00002204450d014101210520044101460d020b200020043a0005200020033a000420002002290300370106200041013602002000410c6a2002290106370100200241c0006a24000f0b410021050b200241206a2001108501024020022802204101470d0020002002290224370204200041013602002000410c6a200241206a410c6a290200370200200241c0006a24000f0b200228022421040240024002402005450d00200241206a20011085014101210120022802204101470d0120002002290224370204200041013602002000410c6a200241206a410c6a290200370200200241c0006a24000f0b410021010c010b200228022421030b2000200436020420004100360200200041086a20013602002000410c6a2003360200200241c0006a24000f0b417f2005106b000b20052003106a000ba41405067f017e017f017e037f230041c0006b22022400024002400240024002400240024002400240024002400240024002400240024041aa0310002203450d0020022003360200200242aa0337020420024102102a02400240024002400240024002400240200128020022012903704202520d00200241086a220428020022032002280204470d03200341016a22052003490d1520034101742206200520052006491b22054100480d152003450d0120022802002107200510002206450d0a2006200720052003200320054b1b10ce021a200710010c020b200241086a220428020022032002280204470d05200341016a22052003490d1420034101742206200520052006491b22054100480d142003450d0320022802002107200510002206450d0a2006200720052003200320054b1b10ce021a200710010c040b200510002206450d080b2002200536020420022006360200200241086a28020021030b200228020020036a41013a00002004200428020041016a3602000c030b200510002206450d060b2002200536020420022006360200200241086a28020021030b200228020020036a4181013a00002004200428020041016a360200200141086a200210d00120022001412c6a101d20012903002108024002400240024020022802042206200428020022036b41084f0d00200341086a22042003490d1220064101742205200420042005491b22074100480d122006450d0120022802002109200710002205450d092005200920072006200620074b1b10ce021a200910010c020b200341086a2104200228020021050c020b200710002205450d070b20022007360204200220053602000b200241086a22062004360200200520036a200837000002400240024002400240024002400240200141f0006a2903004201520d00200141f8006a2903002208420c88220a4201200a4201561b220a4200510d0e20014180016a290300200a80210a20022802042206200241086a28020022036b41024f0d01200341026a22042003490d1620064101742205200420042005491b22074100480d162006450d0520022802002109200710002205450d102005200920072006200620074b1b10ce021a200910010c060b0240200228020420062802002203470d00200341016a22042003490d1620034101742205200420042005491b22064100480d162003450d0220022802002107200610002205450d0f2005200720062003200320064b1b10ce021a200710010c030b200341016a2104200228020021050c030b200341026a2104200228020021050c050b200610002205450d0c0b20022006360204200220053602000b200241086a2004360200200520036a41003a00000c030b200710002205450d0a0b20022007360204200220053602000b200241086a2004360200200520036a200aa741047420087aa7417f6a22034101200341014b1b2203410f2003410f491b723b00000b20014188016a200210a0010240024002400240200241086a28020022034102460d004101210120034103460d012003417e6a21034101210103402001220441016a22012003490d000b200441016a2201413f4d0d012001418080014f0d0241022103410210002209450d0c200920014102744101723b00002002280208220441014b0d100c030b410021010b41012103410110002209450d03200920014102743a00002002280208220441014d0d010c0e0b024020014180808080044f0d0041042103410410002209450d0b200920014102744102723600002002280208220441014b0d0e0c010b410110002204450d0b200441033a000041052103410510002209450d0c200920042d00003a000020041001200920013600012002280208220441014b0d0d0b41c081c000104d000b41aa0341011019000b410141011019000b200541011019000b200541011019000b200741011019000b41e4b2c000104d000b200641011019000b200741011019000b410241011019000b410441011019000b410141011019000b410541011019000b41002101200241086a22054100360200200241286a2207200920036a220b360200200241023602102002411c6a2002280200220641026a22033602002002200936022420022004417e6a220c3602142002200336021820022002360220200241246a21040240024002400240024002400240200c450d0020092203200b460d06024003402004200341016a360200200620016a20032d00003a00002005200528020041016a36020020014101460d01200141016a2101200428020022032007280200460d080c000b0b200241286a280200220b200241246a280200220d6b2201450d05200241206a280200220641046a28020022072002280214220c200228021022036a22056b20014f0d01200520016a22032005490d0720074101742205200320032005491b22034100480d072007450d022006280200210c200310002205450d082005200c20032007200720034b1b10ce021a200c10010c030b20022004103d0c050b200628020021050c020b200310002205450d050b20062005360200200641046a20033602002002280214210c200228021021030b2005200320016a22016a200520036a200c10cf021a200220013602102001200241206a28020022072802082205460d002003200b6a200d20056a6b2106200728020020056a2101200241286a210c200241246a2105200741086a2107034020052802002203200c280200460d022005200341016a360200200120032d00003a00002007200728020041016a360200200141016a21012006417f6a22060d000b0b2002410036023820024201370330200241306a2004103d200228023421072002280230210c024020022802382201450d000240024002400240200241206a280200220541046a28020022062002280214220b200228021022036a22046b20014f0d00200420016a22032004490d0620064101742204200320032004491b22034100480d062006450d012005280200210b200310002204450d082004200b20032006200620034b1b10ce021a200b10010c020b200528020021040c020b200310002204450d060b20052004360200200541046a20033602002002280214210b200228021021030b2004200320016a22056a200420036a200b10cf021a200220053602102005200241206a2802002204280208220b460d00200b20036b21062004280200200b6a2103200441086a2105200c210403402001450d01200320042d00003a00002005200528020041016a360200200441016a2104200341016a210320062001417f6a2201470d000b0b2007450d00200c10010b0240200241186a22012802002002411c6a2802002203460d00200120033602000b024020022802142201450d00024020022802102205200241206a280200220641086a22042802002203460d002006280200220620036a200620056a200110cf021a200228021421010b2004200120036a3602000b20091001200041086a200241086a28020036020020002002290300370200200241c0006a24000f0b1018000b200341011019000b200341011019000b900101017f230041106b220224000240024020002d00004101470d002002200041046a280200220036020c200041ffff034d0d01200141fd01101f2000200110df01200241106a24000f0b200141ff01101f200041016a2001101b200241106a24000f0b0240200041ef014b0d0020012000101f200241106a24000f0b200141fc01101f200120001026200241106a24000b8e5604097f017e167f017e23004190036b22082400200841a0a1c1003602382008420037023c200841c8026a41e8c2c1004103104702400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410110002209450d00200941003a0000200841a0026a428180808010370300200841a8026a41e0083b0100200841aa026a20082f01f8023b01002008410c360298022008200936029c02200841c8006a200841386a200841c8026a20084198026a10d201024020082d00594105460d002008280250450d00200828024c10010b200841c8026a41ebc2c100410f10470240410410002209450d0020094100360000200841a0026a4284808080c000370300200841a8026a41e0083b0100200841aa026a20082f01f8023b01002008410d360298022008200936029c02200841e0006a200841386a200841c8026a20084198026a10d201024020082d00714105460d002008280268450d00200828026410010b200841c8026a41fac2c100410f10470240410110002209450d00200941003a000020084198026a41086a428180808010370300200841a8026a41e0003b0100200841aa026a20082f01f8023b01002008410e360298022008200936029c02200841f8006a200841386a200841c8026a20084198026a10d201024020082d0089014105460d00200828028001450d00200828027c10010b200841c8026a4189c3c100410810470240410710002209450d00200941013a0002200941003b000020094100360003200841a0026a4287808080f000370300200841a8026a41e0003b0100200841aa026a20082f01f8023b01002008410f360298022008200936029c0220084190016a200841386a200841c8026a20084198026a10d201024020082d00a1014105460d00200828029801450d0020082802940110010b200841c8026a4191c3c100410a10470240410710002209450d00200941013a0002200941003b000020094100360003200841a0026a4287808080f000370300200841a8026a41e0003b0100200841aa026a20082f01f8023b010020084110360298022008200936029c02200841a8016a200841386a200841c8026a20084198026a10d201024020082d00b9014105460d0020082802b001450d0020082802ac0110010b200841c8026a419bc3c100410a10470240410210002209450d00200941003b0000200841a0026a428280808020370300200841a8026a220a41e0083b0100200841aa026a20082f01f8023b010020084111360298022008200936029c02200841c0016a200841386a200841c8026a20084198026a10d201024020082d00d1014105460d0020082802c801450d0020082802c40110010b200841c8026a41a5c3c100410e1047200841a4026a4100360200200a41e0003b010020084112360298022008420137029c02200841d8016a200841386a200841c8026a20084198026a10d201024020082d00e9014105460d0020082802e001450d0020082802dc0110010b200841c8026a41b3c3c100410e10470240410310002209450d00200941003a0002200941003b0000200841a0026a42838080803037030020084198026a41106a220a41e0083b0100200841aa026a20082f01f8023b010020084113360298022008200936029c02200841f0016a200841386a200841c8026a20084198026a10d201024020082d0081024105460d0020082802f801450d0020082802f40110010b200841c8026a41c1c3c10041101047200841a4026a4100360200200a41e0003b010020084114360298022008420137029c02200841f8026a200841386a200841c8026a20084198026a10d201024020082d0089034105460d00200828028003450d0020082802fc0210010b20084188026a41d1c3c100411010470240410310002209450d00200941003a0002200941003b000020084198026a41086a42838080803037030020084198026a41106a41e0083b0100200841aa026a20082f01c8023b010020084115360298022008200936029c02200841c8026a200841386a20084188026a20084198026a10d201024020082d00d9024105460d0020082802d002450d0020082802cc0210010b200841286a41086a200841386a41086a28020036020020082008290338370328200820003602f8022008410036028003200820013602fc020240200141044f0d00200841013a00d801200841a4026a4101360200200841ac026a41013602002008410a3602f401200841a082c000360298022008410136029c02200841c0c5c2003602a0022008200841d8016a3602f0012008200841f0016a3602a802200841c8026a20084198026a104c0c1d0b20084180036a41043602000240024020002800004180c2cdeb06470d002001417c714104470d01200841013a00d801200841a4026a4101360200200841ac026a41013602002008410a3602f401200841a082c000360298022008410136029c02200841c0c5c2003602a0022008200841d8016a3602f0012008200841f0016a3602a802200841c8026a20084198026a104c0c1e0b410121010c1b0b0240200141074d0d00200841f8026a41086a41083602000240024002400240024002402000280004220c4101470d0020084198026a200841f8026a10d301200828029802220e4101470d014100210a4104210f4100211020082d009c020d020c0f0b410221010c210b20084198026a410572210c4104210f20084198026a412c6a2112200841bc026a2113200841b8026a2114200841b4026a2115200841b0026a2116200841ac026a2117200841a8026a2118200841a4026a2119200841a0026a211a4128210d4100210a41002110410021000340200841f0016a41026a2209200c41026a2d00003a00002008200c2f00003b01f0012012280200211b200841c0026a280200211c2013280200211d2014280200211e2015280200211f20162802002120201728020021212018280200212220192802002123201a2802002124024020082d009c02220b410e6a410f71410b4f0d00024002400240024002400240024002400240024002400240024002400240200b410f71417e6a2225410a4b22260d00024020250e0b00070405020809060b030a000b200041ff0171222741014d0d0c0c0b0b200041ff0171222741004b0d0a0c0b0b200041ff0171222741054d0d0a0c090b200041ff01712227410a4d0d090c080b200041ff0171222741034d0d080c070b200041ff0171222741044d0d070c060b200041ff0171222741084d0d060c050b200041ff0171222741024d0d050c040b200041ff0171222741064d0d040c030b200041ff0171222741074d0d030c020b200041ff01712227410b4d0d020c010b200041ff0171222741094d0d010b411321010c010b02400240024002400240024002400240024002400240024020260d00024020250e0b00070405020809060b030a000b20274101470d0d0c0b0b20274100460d0a0c0c0b20274105470d0b0c090b2027410a470d0a0c080b20274103470d090c070b20274104470d080c060b20274108470d070c050b20274102470d060c040b20274106470d050c030b20274107470d040c020b2027410b470d030c010b20274109470d020b411421010b024002400240024002400240200b410f712209410d4b0d0002400240024002400240024002400240024020090e0e0d0405010d0d0d08030e070002060d0b2022450d0c2024202241186c6a21222024210c03400240200c41046a280200450d00200c28020010010b0240200c41146a280200220d450d00200c28020c2109200d410474210d0340024020092d00004109470d00200941086a28020041ffffffff0371450d00200941046a28020010010b200941106a2109200d41706a220d0d000b0b200c41186a21090240200c41106a280200450d00200c410c6a28020010010b2009210c20092022470d000c0d0b0b2022450d0b202241286c210d2024210903400240200941046a280200450d00200928020010010b0240200941106a280200450d002009410c6a28020010010b200941286a2109200d41586a220d0d000c0c0b0b2022450d0a20242022411c6c6a21222024210c03400240200c410c6a280200220d450d00200c2802042109200d410474210d0340024020092d00004109470d00200941086a28020041ffffffff0371450d00200941046a28020010010b200941106a2109200d41706a220d0d000b0b0240200c41086a280200450d00200c41046a28020010010b200c411c6a21090240200c41146a280200450d00200c28021010010b2009210c20092022470d000c0b0b0b2022450d09202241146c210d2024210903400240200941046a280200450d00200928020010010b200941146a2109200d416c6a220d0d000c0a0b0b02402023450d00202410010b2020450d09202110010c090b2022450d072022410474210d2024210903400240200941046a280200450d00200928020010010b200941106a2109200d41706a220d0d000c080b0b202441037122094102460d0420094101460d032022450d07202310010c070b2022450d0520242022411c6c6a21222024210c03400240200c410c6a280200220d450d00200c2802042109200d410474210d0340024020092d00004109470d00200941086a28020041ffffffff0371450d00200941046a28020010010b200941106a2109200d41706a220d0d000b0b0240200c41086a280200450d00200c41046a28020010010b200c411c6a21090240200c41146a280200450d00200c28021010010b2009210c20092022470d000c060b0b2022450d04202420224104746a21222024210c03400240200c280208220d450d00200c2802002109200d410474210d0340024020092d00004109470d00200941086a28020041ffffffff0371450d00200941046a28020010010b200941106a2109200d41706a220d0d000b0b200c41106a21090240200c41046a280200450d00200c28020010010b2009210c20092022470d000c050b0b02402023450d00202410010b02402020450d00201f450d00202010010b201c450d04201d10010c040b2020450d012020410c6c210d20222109034002402009280200220c450d00200941046a280200450d00200c10010b2009410c6a2109200d41746a220d0d000c020b0b2020450d00202220204104746a211f2022211c0340201c222041106a211c024020202802042209450d0002402020410c6a280200220d450d00200d410c6c210d034002402009280200220c450d00200941046a280200450d00200c10010b2009410c6a2109200d41746a220d0d000b0b202041086a280200450d00202041046a28020010010b201c201f470d000b0b2021450d01202210010c010b2023450d00202410010b0240200b41ff01714105470d00200e450d002023450d00202410010b200f21092010450d050c040b0240024002400240024002400240024002400240024020260d00024020250e0b00070405020809060b030a000b410121000c0b0b410021000c0a0b410521000c090b410a21000c080b410321000c070b410421000c060b410821000c050b410221000c040b410621000c030b410721000c020b410b21000c010b410921000b200841c8026a41026a222520092d00003a0000200820082f01f0013b01c80202402010200a470d00200a41016a2209200a490d10200a4101742226200920092026491b2226ad422c7e2211422088a70d102011a722094100480d1002400240200a450d0020091000220e450d07200e200f2009200a412c6c220a200a20094b1b10ce022109200f10012009210f0c010b20091000220f450d060b2026210a0b200f200d6a220941586a200b3a00002009201b3602002009415c6a2024360200200941606a2023360200200941646a2022360200200941686a20213602002009416c6a2020360200200941706a201f360200200941746a201e360200200941786a201d3602002009417c6a201c3602002009415b6a20252d00003a0000200941596a20082f01c8023b0000200d412c6a210d201041016a211020084198026a200841f8026a10d301200828029802220e4101470d000b20082d009c02450d0d0b200829029c022211422088a7210c2011421088a7210d2011420888a72100200841a4026a280200210b2011a72101200f21092010450d010b2010412c6c211003402009102b2009412c6a2109201041546a22100d000b0b200a450d1f200f10010c1f0b200941041019000b41082001106a000b410341011019000b410341011019000b410241011019000b410741011019000b410741011019000b410141011019000b410441011019000b410141011019000b2010412c6c2109200f41606a21002010ad422086200aad8421110240024003402009450d01200941546a2109200041206a210d2000412c6a220b2100200d2d0000410b470d000b200b280200210c0c010b4100210c0b2010412c6c2109200f41586a21000240024003402009450d01200941546a2109200041286a210d2000412c6a220b2100200d2d00004104470d000b200841206a200b1046200c2008280224460d010c120b200c4100470d110b024002400240024002400240024002400240024020084180036a2802002001470d00200f450d022011a72110200f2011422088a7220d412c6c6a2100200f2109034020002009460d0220092d000021012009412c6a220a210920014106470d000b200841186a200a41586a105d200828021c450d01410221090c180b200841003a00d801200841a4026a4101360200200841ac026a41013602002008410a3602f401200841a082c000360298022008410136029c02200841c0c5c2003602a0022008200841d8016a3602f0012008200841f0016a3602a802200841c8026a20084198026a104c20082802cc02210b20082802c802210c02402011422088a72209450d002009412c6c2101200f210903402009102b2009412c6a2109200141546a22010d000b0b410521012011a7450d1e200f10010c1e0b20084198026a41086a22014200370300200841a0a1c10036029c02200820062903083e029802200820062903003e02a80220084198026a4104722209410d105a2009410c105a20094107105a2009410f105a20084188036a20082802a802360200200841f8026a41086a200129030037030020082008290398023703f802200f450d01200841c8026a410c6a20113702002008200f3602d00220084280c2cdeb163703c80220084198026a200841c8026a200841f8026a105602402008280298024101470d00200841a8026a280200210a200841a4026a28020021000240200841ac026a2802002209450d002009412c6c21012000210903402009102b2009412c6a2109200141546a22010d000b0b0240200a450d00200010010b200841f8026a41047210d401410321090c1f0b200841a8026a290300211120084198026a410c6a2802002109200829029c022128200841f8026a41047210d4012009450d02200841c8026a410c6a2011370200200820093602d002200820283703c80220084198026a200841c8026a2006280218104502402008280298024101470d000240200841a0026a280200450d00200828029c0210010b410421090c1f0b200841a4026a280200220f450d03200829029c022128200841a8026a2903002211a72110200f2011422088a7220d412c6c6a2100200f210902400240034020002009460d0120092d000021012009412c6a220a210920014102470d000b200a41586a2802002109200a41606a28020021010c010b410021090b2001410020091b211c200941b8d6c20020091b211f200f200d412c6c6a2100200f210902400240034020002009460d0120092d000021012009412c6a220a210920014103470d000b200841106a200a41586a104620082802102109200828021421010c010b410021090b200941b8d6c20020091b22202001410020091b41286c6a210a2008280228211d200828022c211b4100210c024003402020200a460d0120202101034041062109200141086a2802004103470d1902402001280200220041eae9c100460d00200041eae9c100410310d1020d1a0b024002400240200141186a2d000022004103714102460d0020000d010c020b2001411c6a210c0b200141286a2201200a470d010c030b0b201f2001411c6a28020022004104746a4100201c20004b1b220e450d18200e200b200e1b211e200141286a2120200141146a280200210b2001410c6a2802002126201b2125201d21240340202441086a210120242f01062212410c6c2123417f210002400240024003402023450d01024002402026200128020020012802082222200b2022200b491b10d1022221450d00200041016a2100417f410120214100481b22220d010c050b200041016a21004100417f41012022200b4b1b2022200b461b2222450d040b2001410c6a2101202341746a212320224101460d000b20250d010c1c0b201221002025450d1b0b2025417f6a2125202420004102746a41e8026a28020021240c010b0b2024200041146c6a2201419c016a2d0000201e2d000c470d1820014198016a2802002223201e280208470d182001418c016a212120014190016a2802002124201e28020021224100210102400340200120234f0d01202220016a2100202420016a210b200141016a2101200b2d000020002d0000460d000c1a0b0b202141116a2d00002201410447201e410d6a2d00002200410447730d18200e210b20012000460d00200e210b20014104460d00200e210b20004104460d000c180b0b02400240200c450d0041072109200c2802042200450d18200c280200220a200c28020822014b0d182001200628021c4b0d18200a2001417f20001b100c221e417f470d010c170b41004100100c221e417f460d160b200f450d04200841003602f801200842013703f001410410002209450d05200820093602f00120084284808080c0003702f401200920283e0000024002400240024020082802f401220a200841f8016a28020022096b41044f0d00200941046a22012009490d0c200a4101742200200120012000491b220d4100480d0c200a450d0120082802f0012110200d10002200450d0a20002010200d200a200a200d4b1b10ce021a201010010c020b200941046a210120082802f00121000c020b200d10002200450d080b2008200d3602f401200820003602f0010b200841f0016a41086a2001360200200020096a2028422088a7360000200f2011422088a72209412c6c22016a210a2011a72125024002400240024002402009450d00200141546a212220084198026a410172210120084198026a412a6a210d20084198026a41286a211020084198026a41206a210b20084198026a41186a210c20084198026a41106a212320084198026a41086a2124200f2109034020092d00002100200d2009412b6a2d00003a00002010200941296a2f00003b0100200b200941216a290000370300200c200941196a2900003703002023200941116a2900003703002024200941096a2900003703002008200941016a290000370398022000410f460d02200841c8026a412a6a2220200d2d00003a0000200841c8026a41286a222120102f01003b0100200841c8026a41206a221c200b290300370300200841c8026a41186a221f200c290300370300200841c8026a41106a221d2023290300370300200841c8026a41086a221b202429030037030020082008290398023703c802200120082903c802370000200141086a201b290300370000200141106a201d290300370000200141186a201f290300370000200141206a201c290300370000200141286a20212f01003b00002001412a6a20202d00003a0000200820003a009802200841f8026a20084198026a200841f0016a10d50120082d00f8022200411a470d05202241546a21222009412c6a2209200a470d000b200a2209200a470d020c030b200f2209200a470d010c020b2009412c6a2209200a460d010b20084198026a410172210120084198026a412a6a210d20084198026a41286a211020084198026a41206a210b20084198026a41186a210c20084198026a41106a212320084198026a41086a2124034020092d00002100200d2009412b6a2d00003a00002010200941296a2f00003b0100200b200941216a290000370300200c200941196a2900003703002023200941116a2900003703002024200941096a2900003703002008200941016a290000370398022000410f460d01200841c8026a412a6a2222200d2d00003a0000200841c8026a41286a222020102f01003b0100200841c8026a41206a2221200b290300370300200841c8026a41186a221c200c290300370300200841c8026a41106a221f2023290300370300200841c8026a41086a221d202429030037030020082008290398023703c802200120082903c802370000200141086a201d290300370000200141106a201f290300370000200141186a201c290300370000200141206a2021290300370000200141286a20202f01003b00002001412a6a20222d00003a0000200820003a00980220084198026a102b2009412c6a2209200a470d000b0b2025450d08200f10010c080b20082d00fb02212620082f00f902210e200841f8026a41086a280200211220082802fc02211302402022450d002009412c6a210920084198026a410172210120084198026a412a6a211020084198026a41286a210b20084198026a41206a210c20084198026a41186a212320084198026a41106a212420084198026a41086a2122034020092d0000210d20102009412b6a2d00003a0000200b200941296a2f00003b0100200c200941216a2900003703002023200941196a2900003703002024200941116a2900003703002022200941096a2900003703002008200941016a29000037039802200d410f460d01200841c8026a412a6a222020102d00003a0000200841c8026a41286a2221200b2f01003b0100200841c8026a41206a221c200c290300370300200841c8026a41186a221f2023290300370300200841c8026a41106a221d2024290300370300200841c8026a41086a221b202229030037030020082008290398023703c802200120082903c802370000200141086a201b290300370000200141106a201d290300370000200141186a201f290300370000200141206a201c290300370000200141286a20212f01003b00002001412a6a20202d00003a00002008200d3a00980220084198026a102b2009412c6a2209200a470d000b0b02402025450d00200f10010b2000411a460d07200e2026411074724108742000722109024020082802f401450d0020082802f00110010b0240200941ff01714105470d002012450d00201310010b201e100d410021090c1e0b4180e9c10041341040000b41b4e9c10041361040000b41b4e9c10041361040000b41b4e9c10041361040000b41b4e9c10041361040000b410441011019000b200d41011019000b200841f0016a41086a280200211f20082802f401211d20082802f001211c200842043703d801200841003602e001200828022c211020084198026a41086a220a200828022822013602002008201036029c02200841a4026a220d200841286a36020020082010410047220c36029802024002402010450d002010417f6a210920084198026a410472210b200121000340200a20002802e8022200360200200d200841286a3602002008200936029c0220082009410047360298022009417f6a2209417f470d000c020b0b20084198026a410472210b0b200841f8026a41086a200b41086a2802003602002008200b2902003703f80220084198026a41086a220020013602002008201036029c02200841a4026a220a200841286a3602002008200c3602980202402010450d002010417f6a210903402000200120012f01064102746a41e8026a2802002201360200200a200841286a3602002008200936029c0220082009410047360298022009417f6a2209417f470d000b0b20084198026a41086a222128020022092f0106210120084198026a410c6a2802002100200828029c022110200841f0016a41086a220a200841f8026a41086a2223280200360200200820082903f8023703f0012008280230210b20084198026a41146a2009360200200841b0026a2000360200411c210d20084198026a411c6a20013602002021200a2802003602004100210a200841003602a402200820103602a8022008200b3602b802200820082903f00137039802200841086a20084198026a10d6010240024020082802082209450d00200828020c2110200841f8026a410c6a2124200841f8026a41146a2122410021004100210a0340201028020021102009280200210120092802082109200841f8026a41eae9c100410310472009417f4c0d04024002402009450d0020091000220b0d010c070b4101210b0b200b2001200910ce022101200841f8026a41106a220b20093602002024200136020020222009360200200841c8026a41106a220c200b290300370300200841c8026a41086a220b2023290300370300200820082903f8023703c8020240200a2000470d00200041016a22092000490d0420004101742201200920092001491b2201ad4205862211422088a70d042011a722094100480d04024002402000450d0020082802d801212020091000220f450d09200f2020200920004105742200200020094b1b10ce021a202010010c010b20091000220f450d080b200820013602dc012008200f3602d801200121000b20082802d8012201200d6a22092010360200200841d8016a41086a200a41016a220a360200200941646a20082903c8023702002009416c6a200b290300370200200941746a200c2903003702002009417c6a4100360200200d41206a210d200820084198026a10d60120082802042110200828020022090d000c020b0b41042101410021000b200841c8026a41eae9c1004103104720084198026a41f2e8c10041061047200841c8026a41146a202128020036020020082008290398023702d40220084198026a41106a220d200841c8026a41106a2903003703002021200841c8026a41086a290300370300200820082903c802370398020240024002400240200a2000470d00200a41016a2209200a490d04200a4101742200200920092000491b2200ad4205862211422088a70d042011a722094100480d04200a450d01200910002210450d08201020012009200a410574220b200b20094b1b10ce021a200110010c020b200121100c020b200910002210450d060b200820003602dc01200820103602d801201021010b2001200a4105746a220920082903980237020020084198026a41086a220b2903002111200d290300212820094101360218200941106a2028370200200941086a20113702002009411c6a201e360200200841d8016a41086a200a41016a220c360200201e100d200b2003360200200841b0026a41003602002008200236029c022008200536029802200820043602a402200842013703a802200820063602b4022008201e3602b802200820073602bc02200841003a00c002200841c8026a200841d8016a10d701024002404116201c201f20082802c802220920082802d00220084198026a100e220d417f460d00200d417d470d01428004211120082802cc02450d0c0c0b0b4200211120082802cc020d0a0c0b0b024020082802cc02450d00200910010b2008200d3602f00141011000220b450d05200b41003a0000410a10002209450d0620094200370000200941086a41003b00004101210f02400240024002400240200d41f8e8c1004104200b41012009410a20084198026a100f2223417d460d0020230d0c200841093602fc022008200941016a3602f8020240024020092d0000220f4101460d00200f0d014100210f0c020b200841c8026a200841f8026a10d9014100210f20082802c8024101724105470d010b20091001200b1001200841b8026a280200210b200841ac026a2802002123200841a8026a2802002124200841c0026a2d00004521090c010b20091001200b1001200841b8026a280200210b200841ac026a2802002123200841a8026a2802002124200841c0026a2d00002122200f450d0120224521090b4105410820091b210920230d010c020b4108210920220d0a2023450d010b202410010b200b100d200d10104101210b4100210f200c450d0c0c0b0b1018000b102e000b200941011019000b200941041019000b200941041019000b410141011019000b410a41011019000b41b4cbc000104d000b419893c000104d000b200910010b0240201142800683428004520d00200841c0026a2d00002109200841b8026a280200210b0240200841ac026a280200450d00200841a8026a28020010010b4108410520091b2109200b100d4100210b4101210f200c0d010c020b0240200841ac026a280200450d00200841a8026a28020010010b20084198026a41206a280200100d0240200c450d00200a41057441206a210903400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141206a2101200941606a22090d000b0b02402000450d00201010010b0240201d450d00201c10010b200841286a10da0120084190036a240041060f0b200a41057441206a210a03400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141206a2101200a41606a220a0d000b0b02402000450d00201010010b0240201d450d00201c10010b200841286a10da01200b200f410047720d0a200d101020084190036a240020090f0b41072109200f0d010c080b200f450d070b0240200d450d00200d412c6c2100200f210103402001102b2001412c6a2101200041546a22000d000b0b2010450d06200f10010c060b02402010450d002010412c6c2101200f210903402009102b2009412c6a2109200141546a22010d000b0b41192101200a450d00200f10010b0b0c010b20082802cc02210b20082802c802210c41002100410521014100210d0b200d411074200041ff017141087472200141ff01717221010b41012109200141ff01714105470d00200b450d00200c10010b200841286a10da010b20084190036a240020090bc31805097f017e027f017e067f230041d0046b220424002002280208210520022802042106200228020021070240024002400240024002402001280200220841a0a1c100460d00200128020421090c010b41e80210002208450d0141002109200841003b010620084100360200200841086a200441f8006a41e00210ce021a20014100360204200120083602000b0240024002400340200841086a210220082f0106220b410c6c210c428080808070210d417f210a0240024002400340200c450d0102400240200720022802002002280208220e20052005200e4b1b10d102220f450d00200d4280808080107c210d417f4101200f4100481b220e0d010c070b200d4280808080107c210d4100417f41012005200e491b2005200e461b220e450d060b2002410c6a2102200c41746a210c200a41016a210a200e4101460d000b20090d010c020b200b210a2009450d010b2009417f6a21092008200a4102746a41e8026a28020021080c010b0b200441106a20083602002001200128020841016a360208200441146a200aad4220862001ad842210370200200420063602042004200736020020042005ad37030820044188046a41106a220a200341106a28020036020020044188046a41086a2201200341086a2902003703002004200329020037038804200841066a22022f01002209410b4f0d0120082010422088a7220c410c6c6a220e41146a200e41086a220f2009200c6b410c6c10cf021a200e410c6a2006360200200f2007360200200e41106a20053602002008200c41146c6a220841a0016a2008418c016a220520022f0100200c6b41146c10cf021a2008419c016a200a28020036020020084194016a20012903003702002005200429038804370200200220022f010041016a3b01000c020b200141086a2102200d2001ad84210d02402006450d00200710010b200420093602a804200420023602b804200420083602ac042004200d3703b004200441106a2202200341106a280200360200200441086a2205200341086a29020037030020042003290200370300200441f8006a41106a220c2008200d422088a741146c6a2208419c016a220e280200360200200441f8006a41086a220a20084194016a220129020037030020042008418c016a2208290200370378200e200228020036020020012005290300370200200820042903003702002002200c2802003602002005200a29030037030020042004290378370300200041106a2002280200360200200041086a200529030037020020002004290300370200200441d0046a24000f0b41e80210002202450d03200241003b010620024100360200200241086a200441f8006a41e00210ce02210a200441f8006a41106a220120084194026a280200360200200441f8006a41086a22092008418c026a290200370300200420084184026a290200370378200841d4006a290200210d200841d0006a280200210b200a200841dc006a200841066a220e2f010041796a220c410c6c10ce021a2002418c016a20084198026a200c41146c10ce021a200e41063b01002002200c3b0106200441a8046a41106a2001280200360200200441a8046a41086a2009290300370300200420042903783703a8042004410036023c20042002360238024002402010422088a7220c41064b0d002008200c410c6c6a220241146a200241086a220a200e2f0100200c6b410c6c10cf021a2002410c6a2006360200200a2007360200200241106a20053602002008200c41146c6a220241a0016a2002418c016a2205200e2f0100200c6b41146c10cf021a2002419c016a20044188046a41106a28020036020020024194016a20044188046a41086a2903003702002005200429038804370200200e200e2f010041016a3b01000c010b2002200c410c6c6a220e41406a200e41b47f6a2201200241066a220a2f0100200c41796a22096b410c6c10cf021a200e41b87f6a200636020020012007360200200e41bc7f6a20053602002002200c41146c6a220241146a2002200a2f010020096b41146c10cf021a200241106a20044188046a41106a280200360200200241086a20044188046a41086a2903003702002002200429038804370200200a200a2f010041016a3b01000b200441e0006a41086a2202200441a8046a41086a290300370300200441e0006a41106a2205200441a8046a41106a280200360200200420042903a80437036020042802382103200441206a41106a2005280200360200200441206a41086a2002290300370300200420042903603703202010a72111024002400240024002402008280200220a450d0020082f010421092004200a36027c41012101200441013602782004201136028001200420093602840141000d010c020b2004200836027c200441003602782004201136028001201121014101450d010b200441f8006a21084198032105419803100022020d010c070b200441d0006a410c6a21120340200441d0006a41086a201136020020122009360200200420013602502004200a360254200441e0006a41106a2206200441206a41106a2214280200360200200441e0006a41086a2215200441206a41086a221629030037030020042004290320370360200a2f0106410b490d0241980310002202450d05200241003b010620024100360200200241086a200441f8006a41900310ce022105200a2902542110200a2802502113200441f8006a41106a220f200a4194026a280200360200200441f8006a41086a2207200a418c026a2902003703002004200a290284023703782005200a41dc006a200a2f0106220c41796a2208410c6c10ce021a2002418c016a200a4198026a200841146c10ce021a200241e8026a200a4184036a200c417a6a220e41027410ce021a200a41063b0106200220083b01062004200136028c04200420023602880402400240200e450d004100210241e80221080340200428028804220520086a280200220c20023b0104200c2005360200200841046a2108200241016a2202200e490d000b200428028c04210520042802880421020c010b200121050b200441a8046a41106a220c200f280200360200200441a8046a41086a22082007290300370300200420042903783703a80420044188046a41106a220e200c28020036020020044188046a41086a220c2008290300370300200420042903a80437038804200420053602a404200420023602a00402400240200941064b0d0020082011360200200441a8046a410c6a20093602002004200a3602ac04200420013602a8042004200d3702c4042004200b3602c004200f20062802003602002007201529030037030020042004290360370378200441a8046a200441c0046a200441f8006a2003107c0c010b200441a8046a410c6a200941796a360200200420023602ac04200420053602a8042008200441a0046a3602002004200d3702c4042004200b3602c004200f20062802003602002007201529030037030020042004290360370378200441a8046a200441c0046a200441f8006a2003107c0b0240200441386a41086a2202200c290300370300200441386a41106a2208200e280200360200200420042903880437033820042802a0042103201420082802003602002016200229030037030020042004290338370320200a2802002202450d00200141016a2101200a2f010421092002210a2010210d2013210b0c010b0b200441f8006a21082010210d2013210b20112101419803210541980310002202450d060b200241003b010620024100360200200241086a200841900310ce022105200220012802003602e802200120023602002001200128020441016a36020420022802e802220841003b010420082002360200200520022f01062208410c6c6a220c200d3702042002200841146c6a2205419c016a200441206a41106a280200220e36020020054194016a200441206a41086a290300220d3702002005418c016a20042903202210370200200c200b360200200241e8026a200841016a22084102746a2003360200200441f8006a41086a200d370300200441f8006a41106a200e360200200220083b010620042010370378200320083b0104200320023602000c010b2004200d3702ac042004200b3602a804200441f8006a41106a200441e0006a41106a280200360200200441f8006a41086a200441e0006a41086a29030037030020042004290360370378200441d0006a200441a8046a200441f8006a2003107c0b200041053a0011200441d0046a24000f0b41e80241041019000b41980341041019000b41e80241041019000b200541041019000b8dc40108097f017e017f017e077f017e117f047e230041f080046b22022400024002402001280204220320012802082204470d00200241013a0020200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c2003602602002200241206a3602182002200241186a360268200241d880046a200241d8006a104c20022802dc8004210120022802d88004210520004101360200200041003a00042001450d01200510010c010b200441016a21050240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402004417f460d00024020032005490d0020012802002106200141086a2005360200024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200620046a2d00002204410b4b0d0002400240024002400240024002400240024002400240024020040e0c00070405020809060b030a01000b41002104200141086a21074100210803402004411f4b0d6320032005460d612005417f460d262003200541016a2209490d2520072009360200200620056a2d0000220a41ff00712004411f71742008722108200441076a210420092105200a418001710d000b20044120490d38200a6741686a41ff017141044f0d38410d21010c630b200241d8006a200110dd0120022802584101470d0b200228025c22064108762101200241e8006a2802002109200241d8006a41086a290300210b0c5e0b200241d8006a200110dd0120022802584101470d0b200228025c22014108762105200241e8006a2802002103200241d8006a41086a290300210b0c590b200241d8006a200110dd0120022802584101470d0b200228025c22094108762101200241e8006a2802002106200241d8006a41086a290300210b0c540b200241d8006a200110dd0120022802584101470d0b200228025c22034108762101200241e8006a2802002105200241d8006a41086a290300210b0c4f0b200241d8006a200110dd0120022802584101470d0b200228025c22014108762105200241e8006a2802002103200241d8006a41086a290300210b0c4b0b200241d8006a200110dd0120022802584101470d0b200228025c22054108762103200241e8006a2802002101200241d8006a41086a290300210b0c450b200241d8006a200110dd0120022802584101470d0b200228025c220c4108762105200241e8006a2802002101200241d8006a41086a290300210b0c400b200241d8006a200110dd0120022802584101470d61200228025c22054108762101200241e8006a2802002103200241d8006a41086a290300210b0c680b200241d8006a200110dd0120022802584101470d5e200228025c22014108762105200241e8006a2802002109200241d8006a41086a290300210b0c5f0b200241d8006a200110dd0120022802584101470d5b200228025c22034108762101200241e8006a2802002109200241d8006a41086a290300210b0c5c0b200241d8006a200110dd01200241d8006a410472210120022802584101470d5920004101360200200020012902003702042000410c6a200141086a290200370200200241f080046a24000f0b200041123a000420004101360200200041056a20043a0000200241f080046a24000f0b200241306a200241ec006a280200360200200241286a2208200241d8006a410c6a2902003703002002200229025c370320410021014100210303402001411f4b0d5020082802002209200241206a410c6a22062802002205460d36200541016a21042005417f460d1720092004490d16200228022020056a2d0000210520062004360200200541ff00712001411f71742003722103200141076a21012005418001710d000b41042104410d200341ff01712001411f4b20056741686a41ff01714104497122011b4100200341807e7120011b72210620010d502006450d204200210d41042104200241d8006a410c6a210e200241d8006a41086a210f410021100340200241d8006a200241206a108501200228025c211120022802584101460d1e200241d8006a200241206a108301200e280200210c200f2802002112200228025c211320022802584101460d1d200241d8006a200241206a108501200228025c210820022802584101460d1c41002105200241c8006a41086a2214410036020020024201370348200241d8006a41004180800410d0021a024002402008450d00410021030340200241206a41086a280200220a200241206a410c6a220728020022056b200820036b220141808004200141808004491b2201490d26200520016a22092005490d0c200a2009490d0b200241d8006a200228022020056a200110ce021a20072009360200200241c8006a200241d8006a200110292008200120036a22034b0d000b20142802002105200228024c2103200228024821090c010b41012109410021030b0240200d422088a72201200da7470d00200141016a22082001490d5f2001410174220a20082008200a491bad220b421c7e2215422088a70d5f2015a722084100480d5f024002402001450d0020081000220a450d0a200a200420082001411c6c2201200120084b1b10ce02210120041001200121040c010b200810002204450d090b200d42808080807083200b84210d0b2004200d422088a7411c6c6a2201201141087622083b0001200120113a00002001201336020420012009360210200141036a20084110763a0000200141086a20123602002001410c6a200c360200200141146a2003360200200141186a2005360200200d4280808080107c210d201041016a22102006490d000c220b0b200241e880046a200241ec006a280200360200200241e080046a2201200241e4006a2902003703002002200229025c3703d88004200128020021044100210520022802e48004210120022802d8800421084100210303402005411f4b0d4b20042001460d332001417f460d142004200141016a2209490d13200820016a2d0000220641ff00712005411f71742003722103200541076a2105200921012006418001710d000b200241e480046a200936020041042104410d200341ff01712005411f4b20066741686a41ff01714104497122051b4100200341807e7120051b7221012005450d294200210d0c4b0b200241e880046a200241ec006a280200360200200241e080046a2208200241d8006a410c6a2902003703002002200229025c3703d88004410021014100210303402001411f4b0d4620082802002209200241d880046a410c6a22062802002205460d30200541016a21042005417f460d1120092004490d1020022802d8800420056a2d0000210520062004360200200541ff00712001411f71742003722103200141076a21012005418001710d000b41042104410d200341ff01712001411f4b20056741686a41ff01714104497122011b4100200341807e7120011b7221102001450d27201021090c460b200241e880046a200241ec006a280200360200200241e080046a2208200241d8006a410c6a2902003703002002200229025c3703d88004410021014100210303402001411f4b0d4220082802002209200241d880046a410c6a22062802002205460d2e200541016a21042005417f460d0e20092004490d0d20022802d8800420056a2d0000210520062004360200200541ff00712001411f71742003722103200141076a21012005418001710d000b41042104410d20032001411f4b20056741686a41ff01714104497122011b41ff01714100200341807e7120011b7221032001450d252003410876210120022802dc80040d420c430b200241e880046a200241ec006a280200360200200241e080046a2201200241e4006a2902003703002002200229025c3703d88004200128020021044100210520022802e48004210120022802d8800421084100210303402005411f4b0d3c20042001460d2c2001417f460d0b2004200141016a2209490d0a200820016a2d0000220641ff00712005411f71742003722103200541076a2105200921012006418001710d000b200241e480046a200936020041042104410d200341ff01712005411f4b20066741686a41ff01714104497122051b4100200341807e7120051b7221012005450d234200210d0c3c0b200241e880046a200241ec006a280200360200200241e080046a2201200241e4006a2902003703002002200229025c3703d88004200128020021044100210520022802e48004210120022802d8800421084100210303402005411f4b0d3720042001460d292001417f460d082004200141016a2209490d07200820016a2d0000220641ff00712005411f71742003722103200541076a2105200921012006418001710d000b200241e480046a200936020041042104410d200341ff01712005411f4b20066741686a41ff01714104497122011b4100200341807e7120011b7221052001450d214200210d0c370b200241e880046a200241ec006a280200360200200241e080046a2208200241d8006a410c6a2902003703002002200229025c3703d88004410021014100210303402001411f4b0d3220082802002209200241d880046a410c6a22062802002205460d27200541016a21042005417f460d0520092004490d0420022802d8800420056a2d0000210520062004360200200541ff00712001411f71742003722103200141076a21012005418001710d000b41042104410d20032001411f4b20056741686a41ff01714104497122011b41ff01714100200341807e7120011b72210c20010d32200c450d184200210d200241d880046a410c6a2111200241d880046a41086a210e200241ec006a2114200241d8006a41106a210f2002412a6a2116200241296a2117200241ea006a2118200241e9006a211941042104410021100240034002400240200e280200220620112802002203470d0041012112200241013a0048200241d8006a41086a41c0c5c200360200200241d8006a410c6a4101360200201441013602002002410a360204200241a082c0003602582002410136025c200f20023602002002200241c8006a360200200241206a200241d8006a104c20162f0100210820172d00002106200241206a41086a2d000021012002280224210a20022802202103410521050c010b200341016a210102400240024002400240024002400240024002400240024002402003417f460d0020062001490d0120022802d88004221320036a2d000021092011200136020041012112411721050240024002400240024002400240200941e000470d00200341036a210a41002105410021070340200a21082005411f4b0d0220062001460d032001417f460d062006200141016a2209490d07201320016a2d0000210320112009360200200341ff00712005411f71742007722107200841016a210a200541076a2105200921012003418001710d000b410d20072005411f4b20036741686a41ff01714104497122011b41ff01714100200741807e7120011b7221072001450d04200721050c030b0c130b410f21050c010b200241013a0048200241d8006a41086a41c0c5c200360200200241d8006a410c6a4101360200201441013602002002410a360204200241a082c0003602582002410136025c200f20023602002002200241c8006a360200200241206a200241d8006a104c2002290320220b422088a7211a200241206a41086a280200211b200ba7211c410521050b201c2103201a210a201b21010c0f0b024002400240024002400240024002402007450d00200920066b211d201320096a211341002103410121054100210a0340201d200a22096a450d032008450d0d20062008490d0e201320096a2c000021012011200836020020014100480d04200141017441807f71200172220141ff017141847e6a220a41034b0d0541002101024002400240024002400240200a0e0400010203000b4103210120092003460d030c040b4102210120092003460d020c030b410121010b20092003470d010b200341016a220a2003490d732003410174221e200a200a201e491b220a4100480d73024002402003450d00200a1000221e450d12201e2005200a20032003200a4b1b10ce02210320051001200321050c010b200a10002205450d110b200a21030b200520096a20013a0000200841016a2108200941016a220a2007490d000c020b0b41012105410021034100210a0b200241d8006a200241d880046a108501024020022802584101470d0020182f0100210820192d00002106200f2d00002101200241d8006a410c6a280200210a200241d8006a41086a280200211d20022f015e210720022d005d210920022d005c2113410121122003450d140c130b41042113200228025c2201450d0320014101470d04200e280200220920112802002201470d05200241013a0000200241d8006a41086a41c0c5c200360200200241d8006a410c6a4101360200201441013602002002410a36024c200241a082c0003602582002410136025c200f200241c8006a36020020022002360248200241206a200241d8006a104c4105211320162f0100221f210820172d000022202106200241206a41086a2d00002221210120022802242222210a20022802202223211d4101211220030d120c130b200241013a0000200241d8006a41086a41c0c5c200360200200241d8006a410c6a4101360200201441013602002002410a36021c200241a082c0003602582002410136025c200f200241186a36020020022002360218200241206a200241d8006a104c200241206a41086a28020021242002280224212520022802202126410041ff017141087441057221092003450d100c0f0b200141ff0171410874411872210920030d0e0c0f0b200141ff0171410874410672210920030d0d0c0e0b410421060c0b0b419e8cc200211d4124210a4101211220030d0d0c0e0b200141016a21062001417f460d0720092006490d0820022802d8800420016a2c00002109201120063602000240024020094100480d0041062113200941017441807f71200972220941ff017141fc01490d012009417f7321060c0b0b411821130b201f210820202106202121012022210a2023211d4101211220030d0c0c0d0b417f200141016a106b000b200141016a2006106a000b417f2001106b000b20012006106a000b417f2008106b000b20082006106a000b200a41011019000b417f2006106b000b20062009106a000b20054110762107200541087621094100211241e00021010c050b200510010b202621032025210a20242101200921050c020b200510010b201d2103201321050c010b200141107621082001410876210620054110762107200541087621090b0240200641ff0171410874200141ff0171722008411074722101200941ff0171410874200541ff017172200741107472210920120d000240200d422088a72205200da7470d00200541016a22062005490d5b20054101742208200620062008491bad220b4204862215422088a70d5b2015a722064100480d5b024002402005450d00200610002208450d052008200420062005410474220520062005491b10ce02210520041001200521040c010b200610002204450d040b200d42808080807083200b84210d0b2004200d422088a74104746a22052003360204200520093602002005200a3602082005200136020c200d4280808080107c210d201041016a2210200c490d010c1c0b0b200aad422086210b2003ad21150240200d422088a72205450d00200541047421032004210503400240200541046a280200450d00200528020010010b200541106a2105200341706a22030d000b0b200b201584210b0240200da7450d00200410010b2009220c410876210520022802dc80040d340c350b200641041019000b200841041019000b2009200a106a000b20052009106b000b20042009106a000b417f2004106b000b200141016a2004106a000b417f200141016a106b000b200141016a2004106a000b417f200141016a106b000b20042009106a000b417f2004106b000b20042009106a000b417f2004106b000b200141016a2004106a000b417f200141016a106b000b20042009106a000b417f2004106b000b200541016a2003106a000b417f200541016a106b000b20052003106a000b417f2005106b000b2008410876210a200241e8006a2802002109200241e4006a2802002103200241d8006a41086a2802002106200c0d070c080b2013410876210a200241e8006a280200210920122106200c2103201321110c080b2011410876210a200241e8006a2802002109200241e4006a2802002103200241d8006a41086a28020021060c070b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410221010c450b20024103410220012005461b3a0000200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c200228022821012002290320210b0240200d422088a72205450d00200541047421032004210503400240200541046a280200450d00200528020010010b200541106a2105200341706a22030d000b0b4105210c41002105200da7450d1a200410010c1a0b4200210d0b2002412c6a28020021012002280230210502402002280224450d00200228022010010b024020012005470d00410c21010c430b20024103410220012005461b3a0000200241d8006a410c6a4101360200200241d8006a41146a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241d880046a200241d8006a104c20022802e08004210920022903d88004210b0240200d422088a72201450d0020042001411c6c6a210620042103034002402003410c6a2802002205450d0020032802042101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b2001210320012006470d000b0b4105210641002101200da7450d30200410010c300b200241013a0038200241d880046a41086a41c0c5c200360200200241e480046a4101360200200241ec80046a41013602002002410a36021c200241a082c0003602d88004200241013602dc8004200241e880046a200241186a3602002002200241386a3602182002200241d880046a104c200241086a280200210920022802042103200228020021060240200228024c450d00200228024810010b4100210a41052108200c450d010b200c4104742105201321010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b02402012450d0020131001200821110c010b200821110b201141ff01712108200a410874210a2003ad422086210b2006ad21150240200d422088a72201450d0020042001411c6c6a210620042103034002402003410c6a2802002205450d0020032802042101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b2001210320012006470d000b0b200a2008722106200b201584210b200da7450d10200410012006410876210120022802240d2b0c2c0b024002400240024002400240024002400240024002400240024002402005450d004200210d41042104200241d8006a410c6a210c200241d8006a41086a21134100210a0340200241d8006a200241d880046a108a01200c280200210920132802002106200228025c210820022802584101460d03200241d880046a41086a2802002207200241d880046a410c6a22112802002201460d04200141016a21032001417f460d0a20072003490d0b20022802d8800420016a2d0000210120112003360200200141034b0d050240024002400240024020010e0400030102000b200241d8006a200241d880046a108501200228025c210320022802584101460d0d410021070c030b200241d8006a200241d880046a108501200228025c210320022802584101460d0a410221070c020b200241d8006a200241d880046a108501200228025c210320022802584101460d08410321070c010b200241d8006a200241d880046a108501200228025c210320022802584101460d09410121070b0240200d422088a72201200da7470d00200141016a22112001490d4620014101742212201120112012491bad220b42147e2215422088a70d462015a722114100480d46024002402001450d00201110002212450d0f201220042011200141146c2201200120114b1b10ce02210120041001200121040c010b201110002204450d0e0b200d42808080807083200b84210d0b2004200d422088a741146c6a22012006360204200120083602002001200936020820012003ad4220862007ad84220b37020c200d4280808080107c210d200a41016a220a2005490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410821010c4a0b20024103410220012005461b3a0000200241e4006a4101360200200241d8006a41146a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c200228022821012002290320210b0240200d422088a72205450d00200541146c21032004210503400240200541046a280200450d00200528020010010b200541146a21052003416c6a22030d000b0b4105210541002103200da7450d23200410010c230b200b42808080807083200241e8006a350200842129200821052006210a0c0a0b200241013a0000200241e0006a41c0c5c200360200200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241e8006a200241186a36020020022002360218200241206a200241d8006a104c200229022421152002280220210a4105210341002105410021010c080b410a2103410021050c070b20034180807c71210520034108762101200241e4006a2902002115200241d8006a41086a280200210a0c060b20034180807c71210520034108762101200241e4006a2902002115200241d8006a41086a280200210a0c050b20034180807c71210520034108762101200241e4006a2902002115200241d8006a41086a280200210a0c040b20034180807c71210520034108762101200241e4006a2902002115200241d8006a41086a280200210a0c030b417f2003106b000b20032007106a000b201141041019000b200b428080808070832015422088842129200141ff0171410874200572200341ff01717221052015a721092006450d00200810010b2009ad422086210b200aad21150240200d422088a72201450d00200141146c21032004210103400240200141046a280200450d00200128020010010b200141146a21012003416c6a22030d000b0b200b201584210b2029a72101200da7450d07200410012005410876210320022802dc80040d160c170b02400240024002402001450d004200210d41042104410021030340200241d8006a200241d880046a108501200228025c210920022802584101460d030240200d422088a72205200da7470d00200541016a22062005490d3b20054101742208200620062008491bad220b4202862215422088a70d3b2015a722064100480d3b024002402005450d00200610002208450d072008200420062005410274220520062005491b10ce02210520041001200521040c010b200610002204450d060b200d42808080807083200b84210d0b2004200d422088a74102746a2009360200200d4280808080107c210d200341016a22032001490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410421010c3f0b20024103410220012005461b3a0000200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c200228022821032002290320210b4105210141002105200da7450d1d200410010c1d0b200241e8006a2802002103200241e0006a290300210b0240200da7450d00200410010b20092201410876210520022802dc80040d1b0c1c0b200641041019000b024002402003450d004200210d41042104200241d8006a410c6a2106200241d8006a41086a2109200241d8006a41146a211b200241d8006a41106a2117410021100240024002400340200241d8006a200241d880046a108a012006280200210a20092802002113200228025c21120240024002400240024002400240024002400240024002400240024020022802584101460d00200241d8006a200241d880046a108a012006280200210e20092802002107200228025c210c20022802584101460d010240200241d880046a41086a280200220f200241d880046a410c6a22142802002205470d0041012111200241013a0048200941c0c5c20036020020064101360200201b41013602002002410a360204200241a082c0003602582002410136025c201720023602002002200241c8006a360200200241206a200241d8006a104c2002290224210b20022802202108410521050c0c0b200541016a21082005417f460d02200f2008490d0320022802d88004221620056a2d000021012014200836020041012111024002400240024002400240024002400240024002400240024002400240200141034b0d00024002400240024020010e0400030102000b200241d8006a200241d880046a10850120022802584101470d062006290200210b2009280200210820022d005f211420022d005e210f20022d005d210120022d005c21050c1f0b200241d8006a200241d880046a10ce012009290300210b200228025c210820022802584101470d03200241206a41086a2017280200360200200841187621142008411076210f200841087621012002200b370320200ba72116200821052002290224210b201621080c1e0b200f2008470d0341012111200241013a0000200941c0c5c20036020020064101360200201b41013602002002410a36021c200241a082c0003602582002410136025c2017200241186a36020020022002360218200241206a200241d8006a104c4105210520022902242227210b2002280220221a21080c1c0b200f2008470d04200241013a0038200941c0c5c20036020020064101360200201b41013602002002410a36024c200241a082c0003602582002410136025c2017200241c8006a3602002002200241386a360248200241206a200241d8006a104c41052105200229032022152128200241206a41086a2802002208211e0c070b410921050c1b0b41002111410221050c180b200541026a211d2008417f460d10200f201d490d11201620086a2c000021012014201d36020020014100480d02200141017441807f71200172220141ff017141847e6a220841034b0d0b41002101024020080e040008090a000b41032101200f201d460d0a0c140b200228025c210841002105410021110c180b200541026a21052008417f460d10200f2005490d11201620086a2c000021012014200536020020014100480d0141072105200141017441807f71200172220141ff017141f001470d03200241d8006a200241d880046a10ce0120092903002115200228025c210520022802584101470d04201728020021080c140b411821052027210b201a21080c160b4118210520282115201e21080b200141ff01714108742005722105201521292008211c0c100b20292115201c21080c0f0b410021112015210b20052108410121050c120b41022101200f201d460d020c0c0b410121010b200f201d470d0a0b41012111200241013a0048200941c0c5c20036020020064101360200201b41013602002002410a360204200241a082c0003602582002410136025c201720023602002002200241c8006a360200200241206a200241d8006a104c410521052002290224222a210b2002280220222621080c0d0b410621052027210b201a2108410121110c0d0b200241e8006a28020021052012210c201321070c100b200241e8006a2802002105200e210a2013450d0f0c0e0b417f2008106b000b2008200f106a000b417f201d106b000b201d200f106a000b417f2005106b000b2005200f106a000b200541036a210802400240201d417f460d00200f2008490d012016201d6a2d00002116410c2105200241d880046a410c6a2008360200410021114100210f024002402016450d0020164101470d014101210f0b410321050c070b202a210b2026210820162101410121110c060b417f2008106b000b2008200f106a000b200141ff0171410874200541ff01717221050b200241086a2008360200200541187621142005411076210f20054108762101200220153703002002290204210b2015a721080c020b0b0b0240200141ff0171410874200541ff017172200f41ff017141107472201441187472210f200b422088a72105200ba7211420110d000240200d422088a72201200da7470d00200141016a22112001490d3c20014101742216201120112016491bad220b42287e2215422088a70d3c2015a722114100480d3c024002402001450d00201110002216450d05201620042011200141286c2201200120114b1b10ce02210120041001200121040c010b201110002204450d040b200d42808080807083200b84210d0b2004200d422088a741286c6a22012013360204200120123602002001200a3602082001200c36020c2001200f360218200141106a2007360200200141146a200e3602002001411c6a2008360200200141206a2014360200200141246a2005360200200d4280808080107c210d201041016a22102003490d010c060b0b02402007450d00200c10010b200f210c200821072014210a20130d010c020b201141041019000b201210010b200aad422086210b2007ad21150240200d422088a72201450d00200141286c21032004210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101200341586a22030d000b0b200b201584210b0240200da7450d00200410010b200c2203410876210120022802dc80040d1e0c1f0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410321010c3c0b20024103410220012005461b3a0000200241d8006a410c6a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c200228022821052002290320210b0240200d422088a72201450d00200141286c21032004210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101200341586a22030d000b0b4105210341002101200da7450d1d200410010c1d0b02400240024002400240024002402010450d004200210d41042104200241d8006a410c6a2106200241d8006a41086a2108410021070340200241d8006a200241d880046a108501200228025c210920022802584101460d03200241d8006a200241d880046a1083012006280200210520082802002103200228025c210a20022802584101460d04200241d8006a200241d880046a10860120022802584101460d05200828020021112006280200210c200241206a41086a200228025c2201360200200241206a410c6a2001200c4102746a36020020022011360224200220013602202002200241206a103e200241086a28020021112002280204210c200228020021130240200d422088a72201200da7470d00200141016a22122001490d3c2001410174220e20122012200e491bad220b421c7e2215422088a70d3c2015a722124100480d3c024002402001450d0020121000220e450d0a200e200420122001411c6c2201200120124b1b10ce02210120041001200121040c010b201210002204450d090b200d42808080807083200b84210d0b2004200d422088a7411c6c6a2201200941087622123b0001200120093a00002001200a36020420012013360210200141036a20124110763a0000200141086a20033602002001410c6a2005360200200141146a200c360200200141186a2011360200200d4280808080107c210d200741016a22072010490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410a21010c400b20024103410220012005461b3a0000200241d8006a410c6a4101360200200241d8006a41146a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c200228022821062002290320210b0240200d422088a72201450d0020042001411c6c6a210920042103034002402003410c6a2802002205450d0020032802042101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b2001210320012009470d000b0b4105210941002101200da7450d25200410010c250b200241e8006a2802002106200241e4006a2802002105200241e0006a28020021030c020b200241e8006a2802002106200a21090c010b200241d8006a41106a2802002106200241e4006a2802002108200241d8006a41086a2802002107200228025c210902402005450d0020054104742105200a21010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b02402003450d00200a10010b20072103200821050b2005ad422086210b2003ad21150240200d422088a72201450d0020042001411c6c6a210820042103034002402003410c6a2802002205450d0020032802042101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b2001210320012008470d000b0b200b201584210b200da7450d09200410012009410876210120022802dc80040d200c210b201241041019000b0240024002400240024002400240024002400240024002402001450d004200210d41042104200241d880046a410c6a2109200241d880046a41086a21134100210803402013280200220620092802002205460d03200541016a21032005417f460d0a20062003490d0b20022802d8800420056a2c000021052009200336020020054100480d04200541017441807f71200572220541ff017141f001470d05200241d8006a200241d880046a10ce0120022d005c210620022802584101460d0820022d005f210320022f005d210a200241d8006a410c6a2802002107200241d8006a41086a28020021110240200d422088a72205200da7470d00200541016a220c2005490d4020054101742212200c200c2012491bad220b420c7e2215422088a70d402015a7220c4100480d40024002402005450d00200c10002212450d0f20122004200c2005410c6c22052005200c4b1b10ce02210520041001200521040c010b200c10002204450d0e0b200d42808080807083200b84210d0b2004200d422088a7410c6c6a2205200a20034110747222033b0001200520063a00002005201136020420052007360208200541036a20034110763a0000200d4280808080107c210d200841016a22082001490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410521010c440b20024103410220012005461b3a0000200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c200228022821032002290320210b4105210141002105200da7450d2d200410010c2d0b200241013a0000200241d8006a41086a41c0c5c200360200200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241e8006a200241186a36020020022002360218200241206a200241d8006a104c200241206a41086a28020021032002280224210920022802202108410521060c030b411821060c010b410721060b0b200541ff017121010c010b20022f005d20022d005f411074722101200241d8006a41106a2802002103200241e4006a2802002109200241e0006a28020021080b2001410874200641ff01717221012009ad4220862008ad84210b200da7450d0c200410012001410876210520022802dc80040d250c260b417f2003106b000b20032006106a000b200c41041019000b410021042002410036020820024201370300200241d8006a41004180800110d0021a41002105410021074101210a02400240024002400240024002400240024002400240024002402008450d004100210a200141086a21070340200320096b2008200a6b220141808001200141808001491b2201490d02200920016a22052009490d0720032005490d08200241d8006a200620096a200110ce021a200720053602002002200241d8006a200110292005210920082001200a6a220a4b0d000b200241086a2802002105200228020421072002280200210a0b410021014100210303402001411f4b0d0220052004460d03200520044d0d08200a20046a2d0000220941ff00712001411f71742003722103200141076a2101200441016a220621042009418001710d000b20014120490d0420096741686a41ff017141044f0d04410d21010c030b200241013a0048200241e480046a4101360200200241ec80046a41013602002002410a36021c200241a082c0003602d88004200241013602dc8004200241c0c5c2003602e080042002200241c8006a3602182002200241186a3602e88004200241206a200241d880046a104c200228022821052002290320210d2002280204450d33200228020010010c330b410f21010c010b200241013a0020200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c2003602602002200241206a3602182002200241186a360268200241d880046a200241d8006a104c20022802e08004210520022903d88004210d410521010b200d42808080807083200d42ffffffff0f8384210d2007450d320c070b024002400240024002402003450d00410021042002410036025020024201370348200241d8006a410041800810d0021a0340200520066b200320046b22014180082001418008491b2201490d02200620016a22092006490d0920052009490d0a200241d8006a200a20066a200110ce021a200241c8006a200241d8006a20011029200921062003200120046a22044b0d000b200228024c2104200241d8006a20022802482203200241d0006a2802002206106c4101210120022802584101470d02200241306a200229025c37030020022003360224200241206a41047221030c030b41002104410121034200210d20052006490d030c090b200241013a0038200241e480046a4101360200200241ec80046a41013602002002410a36021c200241a082c0003602d88004200241013602dc8004200241c0c5c2003602e080042002200241386a3602182002200241186a3602e880042002200241d880046a104c2002290300210d200228020821050240200228024c450d00200228024810010b41052101200d42808080807083200d42ffffffff0f8384210d20070d090c340b20022003360224200241206a4104722103410021010b2002412c6a2006360200200241206a41086a220620043602002002200136022002402001450d0002402006280200450d00200328020010010b410821014200210d20070d080c330b2002280224220341087621042006290300210d2005200922064f0d060b20062005106b000b20092005106b000b20052003106a000b200441016a2005106a000b20062009106b000b20092005106a000b0240200520066b2201417f4c0d00024002402001450d002001100022050d01200141011019000b410121050b2002200136025c2002200536025820024100360260200241d8006a200a20066a20011029200229025c210b2002280258210502402007450d00200a10010b2004410874200341ff0171722104410121010c3a0b102e000b200a10010c2a0b200241013a0000200241e4006a4101360200200241ec006a41013602002002410a36024c200241a082c0003602582002410136025c200241c0c5c200360260200220023602482002200241c8006a360268200241206a200241d8006a104c4105210c200228022821012002290320210b4105410876210520022802dc8004450d0d0c0c0b200241d880046a410c6a2004360200200241013a0000200241d8006a410c6a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c20022802282101410521052002290320220d42808080807083200d42ffffffff0f8384210b0b2005410876210320022802dc8004450d0f0c0e0b200241d880046a410c6a2004360200200241013a0000200241d8006a410c6a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c2002290320220d42ffffffff0f83210b200d42808080807083210d20022802282103410521010c110b200241013a0000200241e4006a4101360200200241ec006a41013602002002410a36024c200241a082c0003602582002410136025c200241c0c5c200360260200220023602482002200241c8006a360268200241206a200241d8006a104c200228022821052002290320210b410521034105410876210120022802dc8004450d150c140b200241013a0000200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c20022802282106410521092002290320220d42808080807083200d42ffffffff0f8384210b0b2009410876210120022802dc8004450d170c160b200241d880046a410c6a2004360200200241013a0000200241d8006a410c6a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c20022802282103410521012002290320220d42808080807083200d42ffffffff0f8384210b0b2001410876210520022802dc8004450d190c180b200241013a0000200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241d880046a200241d8006a104c20022802e0800421094105210620022903d88004220d42808080807083200d42ffffffff0f8384210b0b200641087621012002280224450d1b0c1a0b410f210c0b200c410876210520022802dc8004450d010b20022802d8800410010b20004101360200200041086a200b370200200041106a200136020020002005410874200c41ff017172360204200241f080046a24000f0b200241e480046a20013602004200210d410f21050b200d420084210b2005410876210320022802dc8004450d010b20022802d8800410010b20004101360200200041086a200b370200200041106a200136020020002003410874200541ff017172360204200241f080046a24000f0b200241e480046a20013602004200210d410f21010b4200210b0b200d200b84210b2001410876210520022802dc8004450d010b20022802d8800410010b20004101360200200041086a200b370200200041106a200336020020002005410874200141ff017172360204200241f080046a24000f0b410f2103410f410876210120022802dc8004450d010b20022802d8800410010b20004101360200200041086a200b370200200041106a200536020020002001410874200341ff017172360204200241f080046a24000f0b410f21090b4200420084210b2009410876210120022802dc8004450d010b20022802d8800410010b20004101360200200041086a200b370200200041106a200636020020002001410874200941ff017172360204200241f080046a24000f0b200241e480046a20013602004200210d410f21010b200d420084210b2001410876210520022802dc8004450d010b20022802d8800410010b20004101360200200041086a200b370200200041106a200336020020002005410874200141ff017172360204200241f080046a24000f0b410f21060b4200420084210b200641087621012002280224450d010b200228022010010b20004101360200200041086a200b370200200041106a200936020020002001410874200641ff017172360204200241f080046a24000f0b200241013a0020200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c2003602602002200241206a3602182002200241186a360268200241d880046a200241d8006a104c20022802e08004210520022903d88004210d0b410521010c010b410f21010b2000200136020420004101360200200041086a200d370200200041106a2005360200200241f080046a24000f0b200241d880046a41106a200141106a280200360200200241d880046a41086a200141086a290200370300200220012902003703d88004200241d8006a200241d880046a108501024020022802584101470d002000200229025c370204200041013602002000410c6a200241d8006a410c6a29020037020020022802dc8004450d0e20022802d880041001200241f080046a24000f0b200228025c210420022802e4800420022802e88004462101024020022802dc8004450d0020022802d8800410010b02402001450d00410921010c0d0b20024103410220011b3a0000200241d8006a410c6a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c200241e3006a200241286a2802003600002002200229032037005b200041053a000420004101360200200020022900583700052000410c6a200241df006a290000370000200241f080046a24000f0b200241106a200241ec006a280200360200200241086a2201200241e4006a2902003703002002200229025c3703002001280200210441002105200228020c210120022802002108410021030240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024003402005411f4b0d0120042001460d032001417f460d152004200141016a2209490d16200820016a2d0000220641ff00712005411f71742003722103200541076a2105200921012006418001710d000b2002410c6a200936020041042104410d20032005411f4b20066741686a41ff01714104497122011b41ff01714100200341807e7120011b72210320010d012003450d03200241e1006a21134200210d200241386a41086a211d200241206a410c6a2111200241206a41106a2126200241d8006a41146a211c410421044100211a0340200241d8006a200210850120022802584101460d0b200228025c210a41002109201d410036020020024201370338200241d8006a41004180800110d0021a02400240200a450d002002410c6a220e2802002101200241086a2802002107410021062002280200210c0340200720016b200a20066b220541808001200541808001491b2205490d09200120056a22082001490d1a20072008490d1b200241d8006a200c20016a200510ce021a200241386a200241d8006a2005102920082101200a200520066a22064b0d000b200e2008360200201d2802002108200228023c2101200228023821070c010b4101210741002101410021080b201a41016a211a200241206a41086a220e200836020020114100360200202620083602002002200136022420022007360220410021014100210a03402001411f4b0d0920082009460d0a2009417f460d1a2008200941016a2206490d1b200720096a2d0000210520112006360200200541ff00712001411f7174200a72210a200141076a2101200621092005418001710d000b410d200a2001411f4b20056741686a41ff01714104497122011b41ff01714100200a41807e7120011b72210720010d1341002105024002402007450d004100210c410421064104211e410021170340200241d8006a200241206a108501200228025c210a20022802584101460d0f200e280200220820112802002201460d10200141016a21092001417f460d1f20082009490d20200228022020016a2c000021012011200936020020014100480d11200141017441807f71200172220141ff017141fb014d0d1202402017200c470d00200c41016a2209200c490d2f200c4101742208200920092008491b2208ad420386220b422088a70d2f200ba722094100480d2f02400240200c450d0020091000220f450d21200f201e2009200c410374220c200c20094b1b10ce022109201e10012009211e0c010b20091000221e450d200b2008210c0b201e20066a2209201b41807e712001417f7341ff017172221b3a00002009417c6a200a360200200641086a2106201741016a22172007490d000c020b0b4104211e4100210c410021170b410121094108210e41002106410021080340200241d8006a200241206a10840120022802584101460d0b200241d880046a41026a2201201341026a2d00003a0000200220132f00003b01d88004200241d8006a410c6a2802002114200241d8006a41106a280200210f201c280200211602400240200241d8006a41086a2d000022074106470d002009417f6a21090c010b2007417e6a41024b0d004104200941016a2225202520094922241b210a4115201020241b2110419ac2c100201220241b211220252009490d14200a21090b200241d8006a41026a220a20012d00003a0000200220022f01d880043b0158024020082006470d00200641016a22012006490d2d20064101742225200120012025491b2225ad420486220b422088a70d2d200ba722014100480d2d024002402006450d00200110002224450d222024200e200120064104742206200620014b1b10ce022101200e10012001210e0c010b20011000220e450d210b202521060b200e20056a220120073a0000200141046a2014360200200141086a200f3602002001410c6a2016360200200141036a200a2d00003a0000200141016a20022f01583b0000200541106a2105200841016a210820090d000b202628020021012011280200210502402002280224450d00200228022010010b20052001470d140240200d422088a72201200da7470d00200141016a22052001490d2c20014101742209200520052009491bad220b42187e2215422088a70d2c2015a722054100480d2c024002402001450d00200510002209450d22200920042005200141186c2201200120054b1b10ce02210120041001200121040c010b200510002204450d210b200d42808080807083200b84210d0b2004200d422088a741186c6a2201200c3602042001201e360200200120173602082001200e36020c200141106a2006360200200141146a2008360200200d4280808080107c210d201a2003490d000c050b0b2002410c6a2001360200410f21030b2003410876210120022802040d230c240b2002410c6a2004360200200241013a00d88004200241d8006a410c6a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c2003602602002200241d880046a3602182002200241186a360268200241206a200241d8006a104c41052103200228022821092002290320210b4105410876210120022802040d220c230b4200210d0b2002410c6a28020021012002280210210502402002280204450d00200228020010010b20012005470d01410b21010c2c0b2002410c6a2001360200200241013a0047200241d880046a41086a41c0c5c200360200200241d880046a410c6a4101360200200241ec80046a41013602002002410a36021c200241a082c0003602d88004200241013602dc8004200241e880046a200241186a3602002002200241c7006a360218200241c8006a200241d880046a104c200241c8006a41086a2802002109200228024c2110200228024821124105210a200228023c450d1e200228023810010c1e0b20024103410220012005461b3a0020200241d8006a410c6a4101360200200241d8006a41146a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c2003602602002200241206a3602182002200241186a360268200241d880046a200241d8006a104c20022802e08004210920022903d88004210b0240200d422088a72201450d002004200141186c6a21062004210303400240200341046a280200450d00200328020010010b0240200341146a2802002205450d00200328020c2101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b200341186a21010240200341106a280200450d002003410c6a28020010010b2001210320012006470d000b0b4105210341002101200da7450d1f200410010c1f0b410f210a20022802240d1b0c1c0b200241013a0048200241d8006a41086a41c0c5c200360200200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241e8006a200241186a3602002002200241c8006a360218200241d880046a200241d8006a104c20022903d88004220b422088a72110200241d880046a41086a2802002109200ba721124105210a20022802240d1a0c1b0b200241e8006a2802002109200241e4006a2802002110200241e0006a2802002112200228025c210a2008450d160c150b200241e8006a2802002109200241e4006a2802002110200241e0006a2802002112200228025c210a0c190b200241e8006a2802002109200241e4006a2802002110200241e0006a2802002112200c0d150c160b200241013a0048200241d8006a41086a41c0c5c200360200200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241e8006a200241186a3602002002200241c8006a360218200241d880046a200241d8006a104c200241e280046a2f01002105200241e180046a2d00002103200241d880046a41086a2d0000210920022802dc8004211020022802d880042112410521060c030b411821060c010b410621060b0b200341ff0171410874200941ff0171722005411074722109200141ff0171410874200672210a200c450d110c100b024020074109470d00200f41ffffffff0371450d00201410010b20080d0d0c0e0b2007210a20022802240d100c110b20024103410220052001461b3a0048200241d8006a41086a41c0c5c200360200200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241d8006a41106a200241186a3602002002200241c8006a360218200241d880046a200241d8006a104c200241d880046a41086a280200210920022802dc8004211020022802d88004211202402008450d0020084104742105200e21010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b02402006450d00200e10010b4105210a200c450d10201e10010c100b417f200141016a106b000b200141016a2004106a000b20012008106b000b20082007106a000b417f200941016a106b000b200941016a2008106a000b200941041019000b417f2009106b000b20092008106a000b200141081019000b200541041019000b200e21010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b02402006450d00200e10010b200c450d010b201e10010b2002280224450d010b200228022010010b2010ad422086210b2012ad21150240200d422088a72201450d002004200141186c6a21062004210303400240200341046a280200450d00200328020010010b0240200341146a2802002205450d00200328020c2101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b200341186a21010240200341106a280200450d002003410c6a28020010010b2001210320012006470d000b0b200b201584210b0240200da7450d00200410010b200a220341087621012002280204450d010b200228020010010b20004101360200200041086a200b370200200041106a200936020020002001410874200341ff017172360204200241f080046a24000f0b200241e880046a200241ec006a280200360200200241e080046a2208200241d8006a410c6a2902003703002002200229025c3703d88004410021014100210302400240024002400240024002400240024002400240024003402001411f4b0d0120082802002209200241d880046a410c6a22062802002205460d02200541016a21042005417f460d0520092004490d0620022802d8800420056a2d0000210520062004360200200541ff00712001411f71742003722103200141076a21012005418001710d000b41042104410d20032001411f4b20056741686a41ff01714104497122051b41ff01714100200341807e7120051b7221012005450d034200210d4200210b0c020b410f21014200210b4200210d0c010b200241013a0048200241e4006a4101360200200241ec006a41013602002002410a360204200241a082c0003602582002410136025c200241c0c5c2003602602002200241c8006a36020020022002360268200241206a200241d8006a104c2002290320220d42ffffffff0f83210b200d42808080807083210d20022802282109410521010b200d200b84210b2001410876210520022802dc8004450d090c080b0240024002400240024002400240024002400240024002402001450d004200210d200241d880046a410c6a2108200241d880046a41086a2112410421044100211303402012280200220620082802002209460d03200941016a21052009417f460d0f20062005490d1020022802d88004220720096a2c000021032008200536020020034100480d04200341017441807f71200372220341ff017141847e6a221141034b0d064100210a0240024002400240024020110e0400010203000b4103210a20062005470d030c0c0b4102210a20062005470d020c0b0b4101210a0b20062005460d090b200941026a21032005417f460d1120062003490d12200720056a2d00002105200820033602004100210302402005450d0020054101470d0a41800221030b200241d8006a200241d880046a108301200241d8006a410c6a2802002106200241d8006a41086a2802002107200228025c211120022802584101460d0b0240200d422088a72205200da7470d00200541016a22092005490d1820054101742210200920092010491bad220b4204862215422088a70d182015a722094100480d18024002402005450d00200910002210450d162010200420092005410474220520092005491b10ce02210520041001200521040c010b200910002204450d150b200d42808080807083200b84210d0b2004200d422088a74104746a2205200736020420052011360200200520063602082005200c4180807c71200a72200372220c36020c200d4280808080107c210d201341016a22132001490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410721010c1c0b20024103410220012005461b3a0000200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c200228022821092002290320210b0240200d422088a72201450d00200420014104746a2106200421030340024020032802082205450d0020032802002101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b200341106a21010240200341046a280200450d00200328020010010b2001210320012006470d000b0b4105210141002105200da7450d12200410010c120b200241013a0048200241d8006a41086a41c0c5c200360200200241e4006a4101360200200241ec006a41013602002002410a360204200241a082c0003602582002410136025c200241e8006a20023602002002200241c8006a360200200241206a200241d8006a104c200241206a41086a28020021092002280224210620022802202107410521010c010b411821010b200341ff017141087420017221010c010b410621010b200341ff0171410874200141ff01717221110c040b200241013a0000200241d8006a41086a41c0c5c200360200200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241e8006a200241186a36020020022002360218200241206a200241d8006a104c200241206a41086a2802002109200228022421062002280220210741002105410521010c010b410c21010b200541087420017221110c010b200241e8006a28020021090b2006ad422086210b2007ad21150240200d422088a72201450d00200420014104746a2106200421030340024020032802082205450d0020032802002101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b200341106a21010240200341046a280200450d00200328020010010b2001210320012006470d000b0b200b201584210b0240200da7450d00200410010b20112201410876210520022802dc80040d070c080b417f2004106b000b20042009106a000b417f2005106b000b20052006106a000b417f2003106b000b20032006106a000b200941041019000b20022802d8800410010b20004101360200200041086a200b370200200041106a200936020020002005410874200141ff017172360204200241f080046a24000f0b200241e880046a200241ec006a280200360200200241e080046a2201200241e4006a2902003703002002200229025c3703d88004200128020021044100210520022802e48004210120022802d88004210841002103024002400240024003402005411f4b0d0120042001460d032001417f460d062004200141016a2209490d07200820016a2d0000220641ff00712005411f71742003722103200541076a2105200921012006418001710d000b200241e480046a200936020041042104410d200341ff01712005411f4b20066741686a41ff01714104497122011b4100200341807e7120011b7221052001450d034200210d0c010b200241e480046a20013602004200210d410f21050b200d420084210b2005410876210120022802dc80040d070c080b200241d880046a410c6a2004360200200241013a0000200241d8006a410c6a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c20022802282103410521052002290320220d42808080807083200d42ffffffff0f8384210b0c050b0240024002402005450d004200210d41042104200241d8006a410c6a2111200241d8006a41086a210c4100210a0340200241d8006a200241d880046a10ce0120022f005d20022d005f41107472210320112802002109200c280200210620022d005c210820022802584101460d030240200d422088a72201200da7470d00200141016a22072001490d0520014101742213200720072013491bad220b420c7e2215422088a70d052015a722074100480d05024002402001450d00200710002213450d0a2013200420072001410c6c2201200120074b1b10ce02210120041001200121040c010b200710002204450d090b200d42808080807083200b84210d0b2004200d422088a7410c6c6a220120033b0001200120083a000020012006360204200141036a20034110763a0000200141086a2009360200200d4280808080107c210d200a41016a220a2005490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410621010c090b20024103410220012005461b3a0000200241e4006a4101360200200241ec006a41013602002002410a36021c200241a082c0003602582002410136025c200241c0c5c200360260200220023602182002200241186a360268200241206a200241d8006a104c200228022821032002290320210b4105210541002101200da7450d07200410010c070b200341087420087221052009ad4220862006ad84210b200241e8006a2802002103200da7450d04200410012005410876210120022802dc80040d050c060b1018000b417f200141016a106b000b200141016a2004106a000b200741041019000b2005410876210120022802dc8004450d010b20022802d8800410010b20004101360200200041086a200b370200200041106a200336020020002001410874200541ff017172360204200241f080046a24000f0b200020013a000420004100360200200041056a20022f00d880043b0000200041086a20043602002000410c6a200d370200200041146a2005360200200041186a200b370200200041206a2002290258370200200041076a200241da80046a2d00003a0000200041286a200241d8006a41086a290200370200200241f080046a24000f0b200241f080046a24000b830602077f027e230041206b220124002000280208210220002802042103200141186a2204200028020022053602002001411c6a22064100360200200120033602142001200341004736021002402003450d002003417f6a21002005210703402004200728026c22073602002006410036020020012000360214200120004100473602102000417f6a2200417f470d000b0b2001411c6a2802002106200141186a28020021072001280214210402402003450d000340200520052f01064102746a41ec006a28020021052003417f6a22030d000b0b02402002450d0041002100034002400240200020072f01064f0d0020004103742105200041016a2100200720056a41146a2802004103460d030c010b0240024020072802002200450d00200441016a210420073301044220862006ad8421080c010b2006ad2108410021000b20071001024002402008422088a7220320002f01064f0d00200021050c010b03400240024020002802002205450d002000330104422086200842ffffffff0f83842108200441016a21040c010b200842ffffffff0f832108410021050b20001001200521002008422088a7220320052f01064f0d000b0b200520034102746a41f0006a2802002107200520034103746a41146a28020021052008a72106024020044101460d00410120046b21000340200728026c2107200041016a22000d000b0b410021044100210020054103460d020b2002417f6a22020d000b0b02400240200741a0a1c100460d000240024020072802002205450d0020073301042108200120053602142001200441016a2204360210200120084220862006ad842208370318200710012005450d020c010b2006ad210841002105200710014100450d010b0240024020052802002200450d0020053301042109200120003602142001200441016a36021020012009422086200842ffffffff0f8384370318200510012000450d020c010b41002100200510014100450d010b034020002802002205450d02200010012005210020050d000b0b200141206a24000f0b20001001200141206a24000bdace01030f7f017e067f230041b0016b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2204410d4b0d00024020040e0e00090607030a0c080e050d02040b000b200141186a2802002105200141146a2802002106200141106a28020021072001410c6a2802002108200141086a2802002109200141046a280200210a4100210b200341003a006f200241046a280200200241086a2802002204470d16200441016a220c2004490db9012004410174220d200c200c200d491b220b4100480db9012004450d352002280200210e200b1000220d450da401200d200e200b20042004200b4b1b10ce021a200e10010c360b2001410c6a280200210b200141086a2802002104200141046a280200210c200320012d000122073a006f200241046a280200200241086a280200220d470d0d200d41016a2205200d490db801200d4101742206200520052006491b22074100480db801200d450d1c20022802002108200710002206450d9a01200620082007200d200d20074b1b10ce021a200810010c1d0b20034180016a41086a2001410c6a2802003602002003200141046a29020037038001410b210b2003410b3a006f200241046a280200200241086a2802002204470d0d200441016a220c2004490db7012004410174220d200c200c200d491b220b4100480db7012004450d1e20022802002105200b1000220d450d9b01200d2005200b20042004200b4b1b10ce021a200510010c1f0b2001410c6a280200210c200141086a280200210841042105200141046a2802002107200341043a006f200241046a280200200241086a2802002204470d0d200441016a220d2004490db6012004410174220b200d200d200b491b22054100480db6012004450d202002280200210620051000220b450d9b01200b200620052004200420054b1b10ce021a200610010c210b200341106a200141146a280200360200200341086a2001410c6a2902003703002003200141046a2902003703004100210b200341003a006f200241046a280200200241086a2802002204470d0d200441016a220c2004490db5012004410174220d200c200c200d491b220b4100480db5012004450d2220022802002105200b1000220d450d9b01200d2005200b20042004200b4b1b10ce021a200510010c230b2001410c6a280200210b200141086a2802002107200141046a280200210d41092106200341093a006f200241046a280200200241086a2802002204470d0d200441016a220c2004490db40120044101742205200c200c2005491b22064100480db4012004450d2420022802002108200610002205450d9b012005200820062004200420064b1b10ce021a200810010c250b2001410c6a280200210d200141086a280200210f200141046a280200211041022105200341023a006f200241046a280200200241086a2802002204470d0d200441016a220c2004490db3012004410174220b200c200c200b491b22054100480db3012004450d262002280200210620051000220b450d9b01200b200620052004200420054b1b10ce021a200610010c270b2001410c6a280200210d200141086a2802002107200141046a280200210541032106200341033a006f200241046a280200200241086a2802002204470d0d200441016a220c2004490db2012004410174220b200c200c200b491b22064100480db2012004450d282002280200210820061000220b450d9b01200b200820062004200420064b1b10ce021a200810010c290b2001410c6a280200210d200141086a2802002108200141046a280200210741072105200341073a006f200241046a280200200241086a2802002204470d0d200441016a220c2004490db1012004410174220b200c200c200b491b22054100480db1012004450d2a2002280200210620051000220b450d9b01200b200620052004200420054b1b10ce021a200610010c2b0b2001410c6a280200210d200141086a280200210a200141046a280200210941012105200341013a006f200241046a280200200241086a2802002204470d0e200441016a220c2004490db0012004410174220b200c200c200b491b22054100480db0012004450d2f2002280200210620051000220b450d9c01200b200620052004200420054b1b10ce021a200610010c300b2001410c6a2802002107200141086a2802002109200141046a28020021084105210b200341053a006f200241046a280200200241086a2802002204470d0e200441016a220c2004490daf012004410174220d200c200c200d491b220b4100480daf012004450d3120022802002105200b1000220d450d9c01200d2005200b20042004200b4b1b10ce021a200510010c320b200141286a2802002108200141246a280200210e200141206a28020021072001411c6a2802002111200141186a280200210a200141146a28020021092001410c6a2902002112200141086a2802002105200141046a28020021064100210b200341003a006f200241046a280200200241086a2802002204470d0e200441016a220c2004490dae012004410174220d200c200c200d491b220b4100480dae012004450d3320022802002113200b1000220d450d9c01200d2013200b20042004200b4b1b10ce021a201310010c340b2001410c6a280200210b200141086a2802002107200141046a280200210d41062106200341063a006f200241046a280200200241086a2802002204470d0e200441016a220c2004490dad0120044101742205200c200c2005491b22064100480dad012004450d3520022802002108200610002205450d9c012005200820062004200420064b1b10ce021a200810010c360b2001410c6a280200210b200141086a2802002107200141046a280200210d410a21062003410a3a006f200241046a280200200241086a2802002204470d0e200441016a220c2004490dac0120044101742205200c200c2005491b22064100480dac012004450d3720022802002108200610002205450d9c012005200820062004200420064b1b10ce021a200810010c380b200141046a2802002104200241046a280200210d41082105200341083a006f200d200241086a280200220c470d0e200c41016a220d200c490dab01200c410174220b200d200d200b491b22054100480dab01200c450d392002280200210620051000220b450d9c01200b20062005200c200c20054b1b10ce021a200610010c3a0b200d41016a2105200228020021060c100b200441016a210c2002280200210d0c120b200441016a210d2002280200210b0c140b200441016a210c2002280200210d0c160b200441016a210c200228020021050c180b200441016a210c2002280200210b0c1a0b200441016a210c2002280200210b0c1c0b200441016a210c2002280200210b0c1e0b200441016a210c2002280200210d0c200b200441016a210c2002280200210b0c220b200441016a210c2002280200210d0c240b200441016a210c2002280200210d0c260b200441016a210c200228020021050c280b200441016a210c200228020021050c2a0b200c41016a210d2002280200210b0c2c0b200710002206450d7d0b20022006360200200241046a200736020020032d006f21070b200241086a220820053602002006200d6a20073a00000240024002400240200241046a28020022072008280200220d6b200b4f0d00200d200b6a2205200d490d9d0120074101742206200520052006491b22084100480d9d012007450d0120022802002109200810002206450d80012006200920082007200720084b1b10ce021a200910010c020b200d200b6a2105200228020021060c020b200810002206450d7e0b20022006360200200241046a20083602000b200241086a20053602002006200d6a200c200b10ce021a4100210d41012108410121094101210a4101210e41012111410121134101210b4101211441012115410121054101210241012106410121074100450da2010ca3010b200b1000220d450d7c0b2002200d360200200241046a200b36020020032d006f210b0b200241086a200c360200200d20046a200b3a00002003280284012105200328028001210d200328028801210b200341ac016a4100360200200320023602a001200342013702a401200341003a006f200d200b411c6c6a2109200341a0016a410472210c200b210403402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b200320053602042003200d3602002003200d3602082003200936020c02400240200b450d00200341386a410172210a0340200341086a200d411c6a220b360200200d2802042207450d01200d41186a2802002105200d41146a2802002108200d41086a2902002112200d2802102106200d2802002104200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b2003201237021c20032007360218200341386a200341186a200341a0016a10810120032d00382204411a470d02200341003a006f2005210403402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b200c20062005102902402008450d00200610010b20032003290057370097012003200329035037039001200b210d200b2009470d000b0b2003102f200341ac016a2802002109200341a0016a41086a280200210e20032802a401210a20032802a001210b200341003a006f200b41046a21072009210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d9c012004410174220d200c200c200d491b22054100480d9c012004450d01200b280200210820051000220d450d75200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d730b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b20094f0d00200420096a22022004490d9801200d410174220c20022002200c491b22054100480d9801200d450d44200b280200210620051000220c450d8f01200c20062005200d200d20054b1b10ce021a200610010c450b200420096a2102200b280200210c0c450b2003200a2900003703502003200a41076a29000037005702402008450d00200610010b20032003290057370097012003200329035037039001200320032900970137007720032003290390013703702003102f20032003290077370067200320032903703703600240200341a0016a41086a280200450d0020032802a40110010b2003200329006737002f20032003290360370328200020043a000020002003290328370001200041086a200329002f3700004100210c41012107410121004101210d410121084101210b410121050c410b20051000220b450d7a0b2002200b360200200241046a200536020020032d006f21050b200241086a200d360200200b20046a20053a0000200341c4006a4100360200200320023602382003420137023c200341003a0000200341386a410472210d200c210403402003200441800172200441ff0071200441077622021b3a0000200d2003410110292002210420020d000b2007200c410c6c6a210602400240200c450d002007210403402004410c6a210b200428020422054102460d02200441086a280200210c20042802002104200341f0003a006f200d200341ef006a41011029200320054101463a006f200d200341ef006a41011029200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200d200341ef006a410110292002210420020d000b024020054101470d00200341003a006f03402003200c41800172200c41ff0071200c41077622041b3a006f200d200341ef006a410110292004210c20040d000b0b200b2104200b2006470d000b2006210b0c010b2007210b0b2006200b6b2104024003402004450d01200441746a2104200b2802042102200b410c6a210b20024102470d000b0b02402008450d00200710010b200341c4006a2802002109200341386a41086a280200210e200328023c210a2003280238210b200341003a006f200b41046a21072009210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d98012004410174220d200c200c200d491b22054100480d98012004450d01200b280200210820051000220d450d6c200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d6a0b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b20094f0d00200420096a22022004490d9401200d410174220c20022002200c491b22054100480d9401200d450d25200b280200210620051000220c450d8601200c20062005200d200d20054b1b10ce021a200610010c260b200420096a2102200b280200210c0c260b200b1000220d450d780b2002200d360200200241046a200b36020020032d006f210b0b200241086a200c360200200d20046a200b3a000020034190016a41fce8c10041041047200341106a28020021152003410c6a2802002114200341086a2802002111200328020421130240024020032d0000221041037122044101460d00024020044102460d0020044103470d0220032d0001210420032011360077200320133600732003201436007b200341f0006a41036a210c410021164101210f41012117410121180c92010b2003410036025820034201370350200341003a006f200341d8006a210941012108410021044100210d2013210c03402003200c41807f72200c41ff0071200c410776220b1b22063a006f02400240024002402004200d470d00200441016a220c2004490d970120044101742205200c200c2005491b22054100480d97012005100021072004450d012007450d772007200820052004200420054b1b10ce021a200810010c020b200d41016a210c0c020b2007450d750b200320053602542003200736025020032d006f210620072108200521040b2009200c3602002008200d6a20063a0000200c210d200b210c200b0d000b201120154104746a21092013450d5f410021162011210f201321180340200f2009460d6220162104200f210b02400340200b41046a280200220a0d01200441016a21042009200b41106a220b470d000c640b0b200b41086a2902002112200b2802002117200341003a006f200b41106a210f200441016a21162018417f6a2118200341d0006a41086a220e280200210d2003280254210c03402003200441807f72200441ff0071200441077622051b22083a006f0240024002400240200c200d470d00200c41016a2204200c490d9801200c4101742206200420042006491b22074100480d9801200c450d0120032802502108200710002206450d79200620082007200c200c20074b1b10ce021a200810010c020b200d41016a2104200328025021060c020b200710002206450d770b200320073602542003200636025020032d006f21082007210c0b200e20043602002006200d6a20083a00002004210d2005210420050d000b200341386a41086a20123703002003200a36023c20032017360238200341a0016a200341386a200341d0006a10db0120032d00a0012207411a470d6620180d000b200b41106a220b2009470d600c610b4100210f2003410036025820034201370350200341386a41086a2014360200200341386a410c6a20153602002003201136023c20032013360238200341a0016a200341386a200341d0006a10db0120032d00a0012204411a470d5b200341fb006a200341d8006a28020036000020032003290350370073200341f3006a210c410121174100211841002116410121040c90010b410021182003410036025820034201370350200320113602a401200320133602a001200320143602a801200341386a200341a0016a200341d0006a10890120032d00382204411a470d5b200341fb006a200341d0006a41086a28020036000020032003290350370073200341f3006a210c4101210f4101211741012116410021040c8f010b200610002205450d760b20022005360200200241046a200636020020032d006f21060b200241086a200c360200200520046a20063a0000200341ac016a4100360200200320023602a001200342013702a401200341003a006f200d200b411c6c6a2109200341a0016a410472210c200b210403402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b200320073602042003200d3602002003200d3602082003200936020c02400240200b450d00200341386a410172210a0340200341086a200d411c6a2205360200200d2802042207450d01200d41186a280200210b200d41146a2802002108200d41086a2902002112200d2802102106200d2802002104200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b2003201237021c20032007360218200341386a200341186a200341a0016a10810120032d00382204411a470d02200341003a006f200b210403402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b0240200b450d002006200b4102746a210b2006210d0340200d2802002104200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b200d41046a220d200b470d000b0b02402008450d00200610010b200320032900573700970120032003290350370390012005210d20052009470d000b0b2003102f200341ac016a2802002109200341a0016a41086a280200210e20032802a401210a20032802a001210b200341003a006f200b41046a21072009210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d93012004410174220d200c200c200d491b22054100480d93012004450d01200b280200210820051000220d450d6d200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d6b0b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b20094f0d00200420096a22022004490d8f01200d410174220c20022002200c491b22054100480d8f01200d450d3e200b280200210620051000220c450d8701200c20062005200d200d20054b1b10ce021a200610010c3f0b200420096a2102200b280200210c0c3f0b2003200a2900003703502003200a41076a29000037005702402008450d00200610010b20032003290057370097012003200329035037039001200320032900970137007720032003290390013703702003102f20032003290077370067200320032903703703600240200341a0016a41086a280200450d0020032802a40110010b2003200329006737002f20032003290360370328200020043a000020002003290328370001200041086a200329002f3700004100210b41012107410121004101210d410121080c360b20051000220b450d740b2002200b360200200241046a200536020020032d006f21050b200241086a200c360200200b20046a20053a00002003410c6a41003602002003200236020020034201370204200341003a006f2010200d41286c6a210520034104722102200d210403402003200441800172200441ff00712004410776220c1b3a006f2002200341ef006a41011029200c2104200c0d000b0240024002400240200d450d00200341386a410172221441076a21152010210b0340200341386a41086a2206200b220d41086a2802003602002003200d290200370338200d41286a210b200d2d001822094104460d02200d41246a280000210c200d41206a280000210e200d411c6a2800002104200d411a6a2d00002113200d41196a2c00002111200d41146a280200210a200d41106a2802002107200d28020c2108200341a0016a41086a220d2006280200360200200320032903383703a00120034180016a41086a2206200d280200360200200320032903a00137038001200d200628020036020020032003290380013703a001200341386a200341a0016a200310880120032d0038220d411a470d31200341f0006a41086a200a3602002003200736027420032008360270200341386a200341f0006a2003108801200320142900003703a001200320152900003700a70120032d0038220d411a470d330240024002402009410371220d4101460d000240200d4102460d00200d4103470d02200341033a006f2002200341ef006a4101102920032011417f732204413f7141c0007220042011417f4a1b3a006f2002200341ef006a410110292003201341ff01714100473a006f2002200341ef006a410110290c030b200341023a006f2002200341ef006a410110292003200e4101463a006f2002200341ef006a41011029200341003a006f03402003200441800172200441ff00712004410776220d1b3a006f2002200341ef006a41011029200d2104200d0d000b200e4101470d02200341003a006f03402003200c41800172200c41ff0071200c41077622041b3a006f2002200341ef006a410110292004210c20040d000c030b0b200341013a006f2002200341ef006a41011029200341f0003a006f2002200341ef006a410110292003200e4101463a006f2002200341ef006a41011029200341003a006f03402003200441800172200441ff00712004410776220d1b3a006f2002200341ef006a41011029200d2104200d0d000b200e4101470d01200341003a006f03402003200c41800172200c41ff0071200c41077622041b3a006f2002200341ef006a410110292004210c20040d000c020b0b200341003a006f2002200341ef006a41011029200341003a006f03402003200441800172200441ff00712004410776220c1b3a006f2002200341ef006a41011029200c2104200c0d000b0b20032003290057370097012003200329035037039001200b2005470d000b2005220b2005470d020c030b2010210b0b200b2005460d010b0340200b41186a2d00004104460d01200b41106a2802002104200b410c6a28020021020240200b41046a280200450d00200b28020010010b02402004450d00200210010b200b41286a220b2005470d000b0b0240200f450d00201010010b2003410c6a2802002109200341086a280200210e2003280204210a2003280200210b200341003a006f200b41046a21072009210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d8f012004410174220d200c200c200d491b22054100480d8f012004450d01200b280200210820051000220d450d6d200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d6b0b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b20094f0d00200420096a22022004490d8b01200d410174220c20022002200c491b22054100480d8b01200d450d47200b280200210620051000220c450d8701200c20062005200d200d20054b1b10ce021a200610010c480b200420096a2102200b280200210c0c480b20061000220b450d720b2002200b360200200241046a200636020020032d006f21060b200241086a200c360200200b20046a20063a0000200341c4006a4100360200200320023602382003420137023c200341003a006f200341386a410472210c200d210403402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b0240200d450d002005200d4102746a210b2005210d0340200d2802002104200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b200d41046a220d200b470d000b0b02402007450d00200510010b200341c4006a2802002109200341386a41086a280200210e200328023c210a2003280238210b200341003a006f200b41046a21072009210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d8c012004410174220d200c200c200d491b22054100480d8c012004450d01200b280200210820051000220d450d61200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d5f0b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b20094f0d00200420096a22022004490d8801200d410174220c20022002200c491b22054100480d8801200d450d1c200b280200210620051000220c450d7b200c20062005200d200d20054b1b10ce021a200610010c1d0b200420096a2102200b280200210c0c1d0b20051000220b450d700b2002200b360200200241046a200536020020032d006f21050b200241086a200c360200200b20046a20053a00002003410c6a41003602002003200236020020034201370204200341003a006f2007200d41146c6a210b2003410472210c200d210403402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b0240024002400240200d450d00200341386a4101722109200341306a2106200721020340200241146a210d200228020c22054104460d02200241106a2802002104200229020021122006200228020836020020032012370328200341386a200341286a200310880120032d00382202411a470d04200341828680082005410374411073763a006f200c200341ef006a41011029200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b200320032900a701370057200320032903a001370350200d2102200d200b470d000c030b0b2007210d0b200d200b460d000340200d410c6a2802004104460d010240200d41046a280200450d00200d28020010010b200d41146a220d200b470d000b0b02402008450d00200710010b2003410c6a2802002109200341086a280200210e2003280204210a2003280200210b200341003a006f200b41046a21072009210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d8a012004410174220d200c200c200d491b22054100480d8a012004450d01200b280200210820051000220d450d65200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d630b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b20094f0d00200420096a22022004490d8601200d410174220c20022002200c491b22054100480d8601200d450d38200b280200210620051000220c450d7f200c20062005200d200d20054b1b10ce021a200610010c390b200420096a2102200b280200210c0c390b200320092900003703a0012003200941076a2900003700a701200320032900a701370057200320032903a001370350200320032900573700970120032003290350370390010240200d200b460d000340200d410c6a2802004104460d010240200d41046a280200450d00200d28020010010b200d41146a220d200b470d000b0b02402008450d00200710010b200320032900970137007720032003290390013703700240200341086a280200450d00200328020410010b20032003290077370067200320032903703703602002411a460d3920002003290360370001200020023a0000200041086a20032900673700004100210841012107410121004101210d0c2c0b200b1000220d450d6e0b2002200d360200200241046a200b36020020032d006f210b0b200241086a200c360200200d20046a200b3a0000200341c8006a2006360200200341cc006a20053602002003200936023c2003200a36023820032008360240200320073602442003200341386a200210dc01200320032900013703a0012003200341086a2900003700a701024020032d00002204411a470d0041012109410021080c1c0b200020032903a001370001200020043a0000200041086a20032900a70137000041012100410021070c270b20051000220b450d6c0b2002200b360200200241046a200536020020032d006f21050b200241086a200c360200200b20046a20053a0000200341c4006a4100360200200320023602382003420137023c200341003a00002009200d4104746a2108200341386a410472210c200d210403402003200441800172200441ff0071200441077622021b3a0000200c2003410110292002210420020d000b024002400240200d450d00200921040340200441106a210520042d000d22064105460d022004280208210d20042902002112200320042d000c3a006f200c200341ef006a41011029200341003a006f2012a72107200d210403402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b0240200d450d0020072104034020042c000022024104460d01200441016a210420032002417f73220b413f7141c00072200b2002417f4a1b3a006f200c200341ef006a41011029200d417f6a220d0d000b0b02402012428080808010540d00200710010b024020064104470d00200341003a006f200c200341ef006a410110292005210420052008470d010c040b200341013a006f200c200341ef006a410110292003200641ff00733a006f200c200341ef006a410110292005210420052008470d000c030b0b200921050b20052008460d0003402005410d6a2d00004105460d010240200541046a280200450d00200528020010010b200541106a22052008470d000b0b0240200a450d00200910010b200341c4006a2802002109200341386a41086a280200210e200328023c210a2003280238210b200341003a006f200b41046a21072009210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d83012004410174220d200c200c200d491b22054100480d83012004450d01200b280200210820051000220d450d59200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d570b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b20094f0d00200420096a22022004490d7f200d410174220c20022002200c491b22054100480d7f200d450d16200b280200210620051000220c450d73200c20062005200d200d20054b1b10ce021a200610010c170b200420096a2102200b280200210c0c170b200b1000220d450d6a0b2002200d360200200241046a200b36020020032d006f210b0b200241086a200c360200200d20046a200b3a0000200341386a410c6a4100360200200320023602382003420137023c200341003a000020082007410c6c6a2106200341386a410472210d2007210403402003200441800172200441ff0071200441077622021b3a0000200d2003410110292002210420020d000b024002402007450d002008210403402004410c6a210b200428020422054102460d02200441086a280200210c20042802002104200320054101463a006f200d200341ef006a41011029200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200d200341ef006a410110292002210420020d000b024020054101470d00200341003a006f03402003200c41800172200c41ff0071200c41077622041b3a006f200d200341ef006a410110292004210c20040d000b0b200b2104200b2006470d000b2006210b0c010b2008210b0b20082007410c6c6a200b6b2104024003402004450d01200441746a2104200b2802042102200b410c6a210b20024102470d000b0b02402009450d00200810010b200341c4006a2802002109200341386a41086a280200210e200328023c210a2003280238210b200341003a006f200b41046a21072009210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d80012004410174220d200c200c200d491b22054100480d80012004450d01200b280200210820051000220d450d57200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d550b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b20094f0d00200420096a22022004490d7c200d410174220c20022002200c491b22054100480d7c200d450d17200b280200210620051000220c450d71200c20062005200d200d20054b1b10ce021a200610010c180b200420096a2102200b280200210c0c180b200b1000220d450d680b2002200d360200200241046a200b36020020032d006f210b0b200241086a200c360200200d20046a200b3a00004100210c2003410c6a4100360200200320023602002003420137020420032005360294012003200636029001200320123e029801200341386a20034190016a2003108801024020032d00382204411a470d002003410472210c200341003a006f2012422088a7210403402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b4101211302402009450d002003200a3602940120032009360290012003201136029801200341386a20034190016a200310880120032d00382204411a470d1d410021130b200341003a006f200720084104746a21062008210403402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b20062007460d412007210503402005220d41106a2105200d280200220b4108460d430240200d41086a2802002104200d280204210202400240024002400240200b410771417f6a220b41064b0d00200d410c6a280200210d0240024002400240200b0e0700050203010607000b200341013a006f200c200341ef006a41011029200341003a006f03402003200241800172200241ff00712002410776220d1b3a006f200c200341ef006a41011029200d2102200d0d000b200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000c080b0b200341053a006f200c200341ef006a41011029200341003a006f03402003200241800172200241ff00712002410776220b1b3a006f200c200341ef006a41011029200b2102200b0d000b200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b2003200d41ff00713a006f0240200d4107752204200d41c00071220272452004417f4720024572734101470d0003402003200d418001723a006f200c200341ef006a410110292003200441ff00713a006f200441c0007121022004210d2004410775220b2104200b20027245200b417f4720024572470d000b0b200c200341ef006a4101102920052006470d080c070b200341033a006f200c200341ef006a41011029200341003a006f03402003200241800172200241ff00712002410776220b1b3a006f200c200341ef006a41011029200b2102200b0d000b200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b2003200d41ff00713a006f0240200d4107752204200d41c00071220272452004417f4720024572734101470d0003402003200d418001723a006f200c200341ef006a410110292003200441ff00713a006f200441c0007121022004210d2004410775220b2104200b20027245200b417f4720024572470d000b0b200c200341ef006a4101102920052006470d070c060b200341043a006f200c200341ef006a41011029200341003a006f03402003200241800172200241ff00712002410776220b1b3a006f200c200341ef006a41011029200b2102200b0d000b200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b2003200d41ff00713a006f0240200d4107752204200d41c00071220272452004417f4720024572734101470d0003402003200d418001723a006f200c200341ef006a410110292003200441ff00713a006f200441c0007121022004210d2004410775220b2104200b20027245200b417f4720024572470d000b0b200c200341ef006a4101102920052006470d060c050b200341003a006f200c200341ef006a41011029200341003a006f03402003200241800172200241ff00712002410776220d1b3a006f200c200341ef006a41011029200d2102200d0d000b200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000c040b0b200341023a006f200c200341ef006a41011029200341003a006f03402003200241800172200241ff00712002410776220d1b3a006f200c200341ef006a41011029200d2102200d0d000b200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000c030b0b200341063a006f200c200341ef006a41011029200341003a006f03402003200241800172200241ff00712002410776220d1b3a006f200c200341ef006a41011029200d2102200d0d000b200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000c020b0b200341073a006f200c200341ef006a41011029200341003a006f03402003200241800172200241ff00712002410776220d1b3a006f200c200341ef006a41011029200d2102200d0d000b200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b0b20052006470d010b0b200621050c420b200320032900393703a0012003200341386a41086a2900003700a701200341086a280200450d84010c83010b200610002205450d660b20022005360200200241046a200636020020032d006f21060b200241086a200c360200200520046a20063a0000200341ac016a4100360200200320023602a001200342013702a401200341003a006f200d200b4104746a2105200341a0016a410472210c200b210403402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b200320073602042003200d3602002003200d3602082003200536020c02400240200b450d00200b4104742102200341086a2106200341386a410172220741076a210803402006200d41106a220b360200200d410d6a2d000022044102460d01200d2902002112200d41086a28020021052003200d410c6a2d000041ff00733a006f200c200341ef006a41011029200320043a006f200c200341ef006a41011029200341286a41086a2005360200200320123e0228200320124220883e022c200341386a200341286a200341a0016a108101200320072900003703502003200829000037005720032d00382204411a470d02200b210d200241706a22020d000b0b20031031200341ac016a2802002109200341a0016a41086a280200210e20032802a401210a20032802a001210b200341003a006f200b41046a21072009210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d7b2004410174220d200c200c200d491b22054100480d7b2004450d01200b280200210820051000220d450d57200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d550b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b20094f0d00200420096a22022004490d77200d410174220c20022002200c491b22054100480d77200d450d2d200b280200210620051000220c450d71200c20062005200d200d20054b1b10ce021a200610010c2e0b200420096a2102200b280200210c0c2e0b2003200329005737009701200320032903503703900120031031200320032900970137007720032003290390013703700240200341a0016a41086a280200450d0020032802a40110010b2003200329007737006720032003290370370360200020043a000020002003290360370001200041086a20032900673700004100210d41012107410121000c1c0b200610002205450d640b20022005360200200241046a200636020020032d006f21060b200241086a200c360200200520046a20063a0000200341dc006a41003602002003200236025020034201370254200341003a0000200d200b41186c6a2114200341d0006a410472210c200b210403402003200441800172200441ff0071200441077622021b3a0000200c2003410110292002210420020d000b200320073602a4012003200d3602a0012003200d3602a801200320143602ac0102400240200b450d00200341386a41017221102003410472210c200341a0016a41086a21152003410c6a210803402015200d41186a2207360200200d2802002206450d01200d41146a2802002109200d41106a280200210a200d2902042112200d28020c210e20084100360200200342013702042003200341d0006a360200200341003a006f20062012422088a7220441037422116a21052012a7211303402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b0240024020052006460d00200621040340200441086a210d200441046a2c0000220b4104460d0220042802002104200341003a006f03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b2003200b417f732204413f7141c000722004200b417f4a1b3a006f200c200341ef006a41011029200d2104200d2005470d000b2005210d0c010b2006210d0b20062011200d6b6a2104024003402004450d01200441786a2104200d41046a2102200d41086a210d20022d00004104470d000b0b02402013450d00200610010b20034180016a41086a20093602002003200a360284012003200e36028001200341386a20034180016a200310870120032d00382204411a470d022008280200210b200341086a28020021062003280204210520032802002104200341003a006f200441046a210d200b210403402003200441800172200441ff0071200441077622021b3a006f200d200341ef006a410110292002210420020d000b200d2005200b102902402006450d00200510010b200320032900970137007720032003290390013703702007210d20072014470d000b0b200341a0016a1030200341dc006a2802002109200341d0006a41086a280200210e2003280254210a2003280250210b200341003a006f200b41046a21072009210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d782004410174220d200c200c200d491b22054100480d782004450d01200b280200210820051000220d450d55200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d530b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b20094f0d00200420096a22022004490d74200d410174220c20022002200c491b22054100480d74200d450d2d200b280200210620051000220c450d6f200c20062005200d200d20054b1b10ce021a200610010c2e0b200420096a2102200b280200210c0c2e0b20032010290000370390012003201041076a290000370097010240200341086a280200450d00200328020410010b200320032900970137007720032003290390013703702003200329007737006720032003290370370360200341a0016a10302003200329006737002f200320032903603703280240200341d0006a41086a280200450d00200328025410010b2003200329002f37001f20032003290328370318200020043a000020002003290318370001200041086a200329001f3700004100210541012107410121004101210d410121084101210b0c1c0b20051000220b450d620b2002200b360200200241046a200536020020032d006f21050b200241086a200d360200200b200c6a20053a0000200341c4006a4100360200200320023602382003420137023c200341003a006f200341386a410472210c03402003200441800172200441ff0071200441077622021b3a006f200c200341ef006a410110292002210420020d000b200341c4006a2802002109200341386a41086a280200210e200328023c210a2003280238210b200341003a006f200b41046a21072009210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d742004410174220d200c200c200d491b22054100480d742004450d01200b280200210820051000220d450d4c200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d4a0b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b20094f0d00200420096a22022004490d70200d410174220c20022002200c491b22054100480d70200d450d0e200b280200210620051000220c450d66200c20062005200d200d20054b1b10ce021a200610010c0f0b200420096a2102200b280200210c0c0f0b20051000220c450d600b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a200a200910ce021a0240200e450d00200a10010b4100211141012108410121094101210a4101210e0c2e0b20051000220c450d5e0b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a200a200910ce021a0240200e450d00200a10010b4100210e41012108410121094101210a0c2a0b20051000220c450d5c0b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a200a200910ce021a0240200e450d00200a10010b41002109410121080b0c060b20051000220c450d590b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a200a200910ce021a0240200e450d00200a10010b4100211341012108410121094101210a4101210e410121110c250b20051000220c450d570b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a200a200910ce021a0240200e450d00200a10010b41012108410121090b4101210a0c1e0b200320142900003703502003201441076a2900003700572007450d02200810010c020b200320032900393703a0012003200341c0006a2900003700a7014101210c200341086a2802000d670c680b200320032900a701370057200320032903a0013703500b20032003290057370097012003200329035037039001200320032900970137006720032003290390013703600240200b2005460d000340200b41186a2d00004104460d01200b41106a2802002104200b410c6a28020021020240200b41046a280200450d00200b28020010010b02402004450d00200210010b200b41286a220b2005470d000b0b0240200f450d00201010010b2003200329006737002f200320032903603703280240200341086a280200450d00200328020410010b2003200329002f37001f20032003290328370318200d411a460d19200020032903183700012000200d3a0000200041086a200329001f37000041002100410121070b4101210d0b410121080b4101210b0b410121050b4101210c0b410121060c5c0b20051000220c450d4a0b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a200a200910ce021a0240200e450d00200a10010b2003200329006737002f200320032903603703284100210241012108410121094101210a4101210e41012111410121134101210b41012114410121154101210541012106410121074101210d4101450d5a0c5b0b20051000220c450d480b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a200a200910ce021a0240200e450d00200a10010b2003200329006737002f200320032903603703284100211541012108410121094101210a4101210e41012111410121134101210b410121140c140b20051000220c450d460b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a200a200910ce021a0240200e450d00200a10010b20032003290077370067200320032903703703600b4100211441012108410121094101210a4101210e41012111410121134101210b0c0f0b20051000220c450d430b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a200a200910ce021a0240200e450d00200a10010b20032003290077370067200320032903703703604100210b41012108410121094101210a4101210e41012111410121130c0b0b20051000220c450d410b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a200a200910ce021a0240200e450d00200a10010b2003200329002f37001f200320032903283703184100210541012108410121094101210a4101210e41012111410121134101210b41012114410121150c0b0b20051000220c450d3f0b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a200a200910ce021a0240200e450d00200a10010b2003200329002f37001f200320032903283703180b4100210a41012108410121090b4101210e0b410121110b410121130b4101210b0b410121140b410121150b410121050b4101210241012106410121074101210d41010d420c410b200721050b200720084104746a21020240034020022005460d0120052802002104200541106a210520044108470d000b0b0240200e450d00200710010b2003410c6a280200210e200341086a2802002114200328020421112003280200210b200341003a006f200b41046a2107200e210403402003200441807f72200441ff0071200441077622021b22053a006f02400240024002402007280200200b41086a22062802002204470d00200441016a220c2004490d3b2004410174220d200c200c200d491b22054100480d3b2004450d01200b280200210820051000220d450d1a200d200820052004200420054b1b10ce021a200810010c020b200441016a210c200b280200210d0c020b20051000220d450d180b200b200d3602002007200536020020032d006f21050b2006200c360200200d20046a20053a00002002210420020d000b0240200b41046a280200220d200b41086a28020022046b200e4f0d002004200e6a22022004490d37200d410174220c20022002200c491b22054100480d37200d450d07200b280200210620051000220c450d34200c20062005200d200d20054b1b10ce021a200610010c080b2004200e6a2102200b280200210c0c080b200341a0016a41086a290300211220032802a401210520032f00a10120032d00a3014110747241087420047221082003280254450d01200328025010010c010b200341386a41086a2903002112200328023c210520032f003920032d003b4110747241087420047221082003280254450d00200328025010010b410021040c390b2011220b2009460d010b0340200b220441106a210b024020042802042205450d002004280208210602402004410c6a2802002204450d002004410c6c210c20052104034002402004280200220d450d00200441046a280200450d00200d10010b2004410c6a2104200c41746a220c0d000b0b2006450d00200510010b200b2009470d000b0b2014450d2e201110010c2e0b20051000220c450d2c0b200b200c360200200b41046a20053602000b200b41086a2002360200200c20046a2011200e10ce021a02402014450d00201110010b02402013450d002009450d00200a450d00200910010b200320032900a701370057200320032903a0013703504100210741012108410121094101210a4101210e41012111410121134101210b41012114410121154101210541012102410121064101210d4101450d360c370b20032d00a301210a20032f00a101210e200341a0016a41086a290300211220032802a40121050240201120154104746a41706a200b460d00200b41106a210b0340200b220441106a210b024020042802042206450d002004280208210802402004410c6a2802002204450d002004410c6c210c20062104034002402004280200220d450d00200441046a280200450d00200d10010b2004410c6a2104200c41746a220c0d000b0b2008450d00200610010b200b2009470d000b0b02402014450d00201110010b2007411a460d2a200e200a41107472410874210402402003280254450d00200328025010010b2004200772210841012106024002402010410371220c450d00410021040240200c4101460d00200c4102460d02201310010c350b02402015450d002015410c6c210d2011210c03400240200c280200220b450d00200c41046a280200450d00200b10010b200c410c6a210c200d41746a220d0d000b0b410121062014450d0120111001410021090c350b4100210441000d002011450d0020131001410021090c340b410021090c330b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200741011019000b200741011019000b200841011019000b200b41011019000b200541011019000b200b41011019000b200641011019000b200541011019000b200641011019000b200541011019000b200b41011019000b200541011019000b200b41011019000b200b41011019000b200641011019000b200641011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200541011019000b200341fb006a200341d8006a28020036000020032003290350370073200341f3006a210c41022104410021174101210f41002118410021160b200c280000210a200328007b21082003280077210e200320043a006f410110002206450d02200620032d006f3a0000200341003a006f410121044101210d2008210c03402003200c41807f72200c41ff0071200c41077622051b220c3a006f02400240024002402004200d470d00200441016a220b2004490d052004410174220c200b200b200c491b22074100480d052004450d0120071000220c450d06200c200620072004200420074b1b10ce02210420061001200421060c020b200d41016a210b0c020b200710002206450d040b20032d006f210c200721040b2006200d6a200c3a0000200b210d2005210c20050d000b024002402004200b6b20084f0d00200b20086a2209200b490d022004410174220c20092009200c491b220c4100480d022004450d01200c1000220d450d05200d2006200c20042004200c4b1b10ce02210d20061001200c2104200d2206200b6a200a200810ce021a200e0d060c070b200b20086a21092006200b6a200a200810ce021a200e450d060c050b200c10002206450d03200c21042006200b6a200a200810ce021a200e0d040c050b1018000b200741011019000b410141011019000b200c41011019000b200a10010b02400240024002402010410371220c450d0002400240200c4101460d00200c4102470d03411a21082017450d052015450d01201120154104746a210a2011210703402007220541106a210702402005280204220c450d0002402005410c6a280200220d450d00200d410c6c210d03400240200c280200220b450d00200c41046a280200450d00200b10010b200c410c6a210c200d41746a220d0d000b0b200541086a280200450d00200541046a28020010010b2007200a470d000c020b0b411a2108200f450d042015450d002015410c6c210d2011210c03400240200c280200220b450d00200c41046a280200450d00200b10010b200c410c6a210c200d41746a220d0d000b0b2014450d03201110010c030b411a21082016201145720d020c010b411a21082018201145720d010b201310010b0c010b41012106410021090b024002400240200841ff0171411a470d00200341e0006a41086a220c20034190016a41086a2802003602002003200329039001370360200341c8006a2004360200200341cc006a2009360200200341386a41086a200c2802003602002003200636024420032003290360370338200341a0016a200341386a200210dc01200320032900a1013703502003200341a0016a41086a29000037005720032d00a0012204411a470d014100210641012108410121094101210a4101210e41012111410121134101210b41012114410121154101210541012102410121074101210d4101450d040c050b02402004450d00200610010b20002008360200200041046a2005360200200041086a2012370200200328029401450d0120032802900110010c010b20002003290350370001200020043a0000200041086a20032900573700000b4100210641012107410121004101210d410121084101210b410121054101210c0b410121020c040b2004450d00200c10010b2000411a3a0000024002400240024020012d00002204410f71410f460d000240024002400240024002400240024002400240024002400240024020040e0f0009080703050a0b0d0e0c02060401000b200d450d14200141086a280200450d14200141046a2802001001200341b0016a24000f0b2007450d130240200141086a280200450d00200141046a28020010010b0240200141146a2802002204450d00200141186a280200450d00200410010b200141246a280200450d13200141206a2802001001200341b0016a24000f0b2005450d1202402001410c6a2802002204450d00200141046a280200220c200441186c6a210d03400240200c41046a280200450d00200c28020010010b0240200c41146a2802002202450d00200c28020c2104200241047421020340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200241706a22020d000b0b200c41186a21040240200c41106a280200450d00200c410c6a28020010010b2004210c2004200d470d000b0b200141086a280200450d12200141046a2802001001200341b0016a24000f0b200e450d11200141086a280200450d11200141046a2802001001200341b0016a24000f0b2006450d10200141046a2d000022044103714102460d0b20044101460d0a20040d0c2001410c6a280200450d10200141086a2802001001200341b0016a24000f0b2011450d0f200141086a280200450d0f200141046a2802001001200341b0016a24000f0b2002450d0e02402001410c6a2802002204450d00200141046a280200220c2004411c6c6a210d03400240200c410c6a2802002202450d00200c2802042104200241047421020340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200241706a22020d000b0b0240200c41086a280200450d00200c41046a28020010010b200c411c6a21040240200c41146a280200450d00200c28021010010b2004210c2004200d470d000b0b200141086a280200450d0e200141046a2802001001200341b0016a24000f0b200a450d0d02402001410c6a2802002202450d00200141046a2802002104200241286c210203400240200441046a280200450d00200428020010010b0240200441106a280200450d002004410c6a28020010010b200441286a2104200241586a22020d000b0b200141086a280200450d0d200141046a2802001001200341b0016a24000f0b2009450d0c02402001410c6a2802002202450d00200141046a28020021042002410474210203400240200441046a280200450d00200428020010010b200441106a2104200241706a22020d000b0b200141086a280200450d0c200141046a2802001001200341b0016a24000f0b2008450d0b0240200141086a280200450d00200141046a28020010010b200141146a280200450d0b200141106a2802001001200341b0016a24000f0b2013450d0a200141086a280200450d0a200141046a2802001001200341b0016a24000f0b200b450d0902402001410c6a2802002204450d00200141046a280200220c20044104746a210d03400240200c2802082202450d00200c2802002104200241047421020340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200241706a22020d000b0b200c41106a21040240200c41046a280200450d00200c28020010010b2004210c2004200d470d000b0b200141086a280200450d09200141046a2802001001200341b0016a24000f0b2015450d0802402001410c6a2802002204450d00200141046a280200220c2004411c6c6a210d03400240200c410c6a2802002202450d00200c2802042104200241047421020340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200241706a22020d000b0b0240200c41086a280200450d00200c41046a28020010010b200c411c6a21040240200c41146a280200450d00200c28021010010b2004210c2004200d470d000b0b200141086a280200450d08200141046a2802001001200341b0016a24000f0b2014450d0702402001410c6a2802002202450d00200141046a2802002104200241146c210203400240200441046a280200450d00200428020010010b200441146a21042002416c6a22020d000b0b200141086a280200450d07200141046a2802001001200341b0016a24000f0b2001102b0c060b0240200141146a2802002202450d002001410c6a28020021042002410c6c2102034002402004280200220c450d00200441046a280200450d00200c10010b2004410c6a2104200241746a22020d000b0b200141106a280200450d052001410c6a2802001001200341b0016a24000f0b0240200141146a2802002204450d002001410c6a280200220b20044104746a21050340200b220d41106a210b0240200d2802042204450d000240200d410c6a2802002202450d002002410c6c2102034002402004280200220c450d00200441046a280200450d00200c10010b2004410c6a2104200241746a22020d000b0b200d41086a280200450d00200d41046a28020010010b200b2005470d000b0b200141106a280200450d042001410c6a2802001001200341b0016a24000f0b2001410c6a280200450d03200141086a2802001001200341b0016a24000f0b200328020410010b0240200945200c720d00200a450d00200910010b0240200e450d00200710010b200320032900a701370057200320032903a001370350200020043a000020002003290350370001200041086a20032900573700004100210241012107410121004101210d410121084101210b410121054101210c410121060b024002400240024020012d00002204410f71410f460d000240024002400240024002400240024002400240024002400240024020040e0f0009080703050a0b0d0e0c02060401000b200141086a280200450d11200141046a2802001001200341b0016a24000f0b2002450d100240200141086a280200450d00200141046a28020010010b0240200141146a2802002204450d00200141186a280200450d00200410010b200141246a280200450d10200141206a2802001001200341b0016a24000f0b2005450d0f02402001410c6a2802002204450d00200141046a280200220c200441186c6a210d03400240200c41046a280200450d00200c28020010010b0240200c41146a2802002202450d00200c28020c2104200241047421020340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200241706a22020d000b0b200c41186a21040240200c41106a280200450d00200c410c6a28020010010b2004210c2004200d470d000b0b200141086a280200450d0f200141046a2802001001200341b0016a24000f0b200141086a280200450d0e200141046a2802001001200341b0016a24000f0b2006450d0d200141046a2d000022044103714102460d0b20044101460d0a20040d0c2001410c6a280200450d0d200141086a2802001001200341b0016a24000f0b200141086a280200450d0c200141046a2802001001200341b0016a24000f0b200c450d0b02402001410c6a2802002204450d00200141046a280200220c2004411c6c6a210d03400240200c410c6a2802002202450d00200c2802042104200241047421020340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200241706a22020d000b0b0240200c41086a280200450d00200c41046a28020010010b200c411c6a21040240200c41146a280200450d00200c28021010010b2004210c2004200d470d000b0b200141086a280200450d0b200141046a2802001001200341b0016a24000f0b2000450d0a02402001410c6a2802002202450d00200141046a2802002104200241286c210203400240200441046a280200450d00200428020010010b0240200441106a280200450d002004410c6a28020010010b200441286a2104200241586a22020d000b0b200141086a280200450d0a200141046a2802001001200341b0016a24000f0b02402001410c6a2802002202450d00200141046a28020021042002410474210203400240200441046a280200450d00200428020010010b200441106a2104200241706a22020d000b0b200141086a280200450d09200141046a2802001001200341b0016a24000f0b2007450d080240200141086a280200450d00200141046a28020010010b200141146a280200450d08200141106a2802001001200341b0016a24000f0b200141086a280200450d07200141046a2802001001200341b0016a24000f0b200d450d0602402001410c6a2802002204450d00200141046a280200220c20044104746a210d03400240200c2802082202450d00200c2802002104200241047421020340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200241706a22020d000b0b200c41106a21040240200c41046a280200450d00200c28020010010b2004210c2004200d470d000b0b200141086a280200450d06200141046a2802001001200341b0016a24000f0b200b450d0502402001410c6a2802002204450d00200141046a280200220c2004411c6c6a210d03400240200c410c6a2802002202450d00200c2802042104200241047421020340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200241706a22020d000b0b0240200c41086a280200450d00200c41046a28020010010b200c411c6a21040240200c41146a280200450d00200c28021010010b2004210c2004200d470d000b0b200141086a280200450d05200141046a2802001001200341b0016a24000f0b2008450d0402402001410c6a2802002202450d00200141046a2802002104200241146c210203400240200441046a280200450d00200428020010010b200441146a21042002416c6a22020d000b0b200141086a280200450d04200141046a2802001001200341b0016a24000f0b2001102b200341b0016a24000f0b0240200141146a2802002202450d002001410c6a28020021042002410c6c2102034002402004280200220c450d00200441046a280200450d00200c10010b2004410c6a2104200241746a22020d000b0b200141106a280200450d022001410c6a2802001001200341b0016a24000f0b0240200141146a2802002204450d002001410c6a280200220b20044104746a21050340200b220d41106a210b0240200d2802042204450d000240200d410c6a2802002202450d002002410c6c2102034002402004280200220c450d00200441046a280200450d00200c10010b2004410c6a2104200241746a22020d000b0b200d41086a280200450d00200d41046a28020010010b200b2005470d000b0b200141106a280200450d012001410c6a2802001001200341b0016a24000f0b2001410c6a280200450d00200141086a2802001001200341b0016a24000f0b200341b0016a24000bfe0603047f017e077f230041d0006b21020240024020012802202203450d00200141206a2003417f6a360200200128020c2204200128020422032f01064f0d012001410c6a200441016a36020020002003200441146c6a418c016a360204200020032004410c6c6a41086a3602000f0b20004100360204200041003602000f0b0240024020032802002205450d00200128020041016a2104200333010442208620013502088421060c010b410021050b20052f01062103200241106a220720053602002002200436020c0240024002402006422088a7220820034f0d00200241186a2008360200200241146a20063e020020024100360208200241086a4104722109200241206a21030c010b200241146a220a200637020020024101360208200241086a41047221090240200528020022030d004103210b0c020b4100210b0c010b4105210b0b03400240024002400240024002400240024002400240024002400240024002400240200b0e0a01030002040508090607070b200a200637020020024101360208200322052802002203450d094100210b0c0f0b200642ffffffff0f832005330104422086842106200441016a21040c090b410021034101210b0c0d0b20032f01062105200720033602002002200436020c2006422088a7220820054f0d084104210b0c0c0b200241186a2008360200200241146a20063e020020024100360208200241206a21034105210b0c0b0b200341086a200941086a29020037020020032009290200370200200241086a41086a280200210a200241186a28020021092003280200210c20022802282105200241306a41086a22072002280224200228022c4102746a41ec026a2802002204360200200241306a410c6a220820053602002002200c417f6a220336023420022003410047360230200a200941146c6a210d200a2009410c6c6a21092003450d074108210b0c0a0b200c417e6a2103200241306a410472210a4109210b0c090b200720042802e80222043602002008200536020020022003360234200220034100473602302003417f6a2203417f470d060c070b200241306a410472210a4107210b0c070b2001200a2902003702002001410c6a4100360200200141086a200a41086a2802003602002000200d418c016a3602042000200941086a3602000f0b4103210b0c050b4101210b0c040b4102210b0c030b4106210b0c020b4109210b0c010b4107210b0c000b0b8009010a7f230041106b2202240020024100360208200242013703002001280200210302400240024002400240024002400240024002400240024002402001280208220141c0004f0d00410110002204450d08200220043602002002428180808010370204200420014102743a000020010d010c020b02402001418080014f0d00410210002204450d09200220043602002002428280808020370204200420014102744101723b00000c010b024020014180808080044f0d00410410002204450d0a2002200436020020024284808080c000370204200420014102744102723600000c010b410110002204450d0a200220043602002002428180808010370204200441033a0000410510002205450d0b200520042d00003a0000200410012002200536020020024285808080d000370204200520013600010b200320014105746a210603402003280200200341086a280200200210202003410c6a280200200341146a28020020021020200241086a2207280200210420022802042101024002400240024002400240024002400240024002400240024002400240200341186a2802004101470d0020012004470d01200441016a22052004490d1120044101742201200520052001491b22014100480d112004450d0320022802002108200110002209450d122009200820012004200420014b1b10ce021a200810010c040b20012004470d01200441016a22052004490d1020044101742201200520052001491b22014100480d102004450d0520022802002108200110002209450d122009200820012004200420014b1b10ce021a200810010c060b200441016a2105200228020021090c030b200441016a2105200228020021090c050b200110002209450d0e0b20022001360204200220093602000b20072005360200200920046a41023a00002003411c6a280200210a0240200120056b41044f0d00200541046a22082005490d0c20014101742204200820082004491b220b4100480d0c200b100021042001450d042004450d0f20042009200b20012001200b4b1b10ce021a200910010c050b200541046a2108200921040c050b200110002209450d0c0b20022001360204200220093602000b20072005360200200920046a41013a00002003411c6a280200210a0240200120056b41044f0d00200541046a22082005490d0920014101742204200820082004491b220b4100480d09200b100021042001450d042004450d0d20042009200b20012001200b4b1b10ce021a200910010c050b200541046a2108200921040c050b2004450d0a0b2002200b360204200220043602000b20072008360200200420056a200a360000200341206a22032006470d030c040b2004450d080b2002200b360204200220043602000b20072008360200200420056a200a360000200341206a22032006470d000b0b20002002290300370200200041086a200241086a280200360200200241106a24000f0b1018000b200141011019000b200141011019000b200b41011019000b200b41011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000bc20603027f017e087f230041c0006b220424002004200136020c2004200041b8d6c20020011b3602082004200441086a10330240024002400240024002402004280200450d0002400240024002400240024020042802042205ad2206421c88a70d002006420486a72201417f4c0d00024002402001450d00200110002207450d032005450d010c040b4108210720050d030b41002100410021012007450d060c030b102e000b200141081019000b200441206a41047221084104210920052101410021000340200441206a200441086a10d901200441306a41086a220a200841086a280200360200200420082902003703302004280220220b4104460d03200441106a41086a220c200a28020036020020042004290330370310024020002001470d00200141016a220a2001490d032001410174220d200a200a200d491b220dad4204862206422088a70d032006a7220a4100480d03024002402001450d00200a1000220e450d08200e2007200a200141047422012001200a4b1b10ce02210120071001200121070c010b200a10002207450d070b200d21010b200720096a220a417c6a200b360200200a41086a200c280200360200200a2004290310370200200941106a2109200041016a22002005490d000b0b200441206a200220072000200311040020044100360238200442013703302004280220210a41011000210002400240200a4105470d002000450d06200041013a000020042000360230200442818080801037023442012106200021090c010b2000450d06200041003a00002004200036023020044281808080103702344102100021090240200a4104470d002009450d08200920002d00003a000020001001200941003a0001200420093602302004428280808020370234420221060c010b2009450d08200920002d00003a000020001001200941013a0001200420093602302004428280808020370234200441206a200441306a10e201200441386a3502002106200428023021090b2009ad422086200684210602402001450d00200710010b200441c0006a240020060f0b1018000b2001450d00200710010b41ef8ac20041f0001040000b200a41081019000b410141011019000b410141011019000b410241011019000b410241011019000bb60401057f230041106b22022400200241003a0008200241086a2001280200220320012802042204410047220510ce021a2001200420056b22063602042001200320056a22053602000240024002400240024002400240024002402004450d0020022d0008417f6a220441034b0d04024020040e0400020304000b20024100360208200241086a20052006410420064104491b220410ce021a200141046a200620046b3602002001200520046a360200200641034d0d052000200228020836020420004100360200200241106a24000f0b20004104360200200241106a24000f0b20024200370308200241086a20052006410820064108491b220410ce021a200141046a200620046b3602002001200520046a360200200641074d0d04200041086a200229030837030020004101360200200241106a24000f0b20024100360208200241086a20052006410420064104491b220410ce021a200141046a200620046b3602002001200520046a360200200641034d0d042000200228020836020420004102360200200241106a24000f0b20024200370308200241086a20052006410820064108491b220410ce021a200141046a200620046b3602002001200520046a360200200641074d0d04200041086a200229030837030020004103360200200241106a24000f0b20004104360200200241106a24000f0b20004104360200200241106a24000f0b20004104360200200241106a24000f0b20004104360200200241106a24000f0b20004104360200200241106a24000b8d07020a7f027e230041206b220124002000280208210220002802042103200141186a2204200028020022053602002001411c6a22064100360200200120033602142001200341004736021002402003450d002003417f6a2100200521070340200420072802e80222073602002006410036020020012000360214200120004100473602102000417f6a2200417f470d000b0b2001411c6a2802002108200141186a28020021072001280214210402402003450d000340200520052f01064102746a41e8026a28020021052003417f6a22030d000b0b02402002450d0041002100034002400240200020072f01064f0d002007200041146c6a22094194016a280200210620094190016a280200210a20072000410c6c6a2203410c6a2802002105200341086a2802002103200041016a21002009419d016a2d000041ff01714105460d030c010b0240024020072802002200450d00200441016a210420073301044220862008ad84210b0c010b2008ad210b410021000b2007100102400240200b422088a7220320002f01064f0d00200021050c010b03400240024020002802002205450d002000330104422086200b42ffffffff0f8384210b200441016a21040c010b200b42ffffffff0f83210b410021050b2000100120052100200b422088a7220320052f01064f0d000b0b200520034102746a41ec026a28020021072005200341146c6a2200419d016a2d0000210920004194016a280200210620004190016a280200210a20052003410c6c6a2200410c6a2802002105200041086a2802002103200ba72108024020044101460d00410120046b2100034020072802e8022107200041016a22000d000b0b4100210441002100200941ff01714105460d020b02402005450d00200310010b2002417f6a210202402006450d00200a10010b20020d000b0b02400240200741a0a1c100460d000240024020072802002205450d002007330104210b200120053602142001200441016a22043602102001200b4220862008ad84220b370318200710012005450d020c010b2008ad210b41002105200710014100450d010b0240024020052802002200450d002005330104210c200120003602142001200441016a3602102001200c422086200b42ffffffff0f8384370318200510012000450d020c010b41002100200510014100450d010b034020002802002205450d02200010012005210020050d000b0b200141206a24000f0b20001001200141206a24000ba20703127f017e017f230041306b22032400200241046a22042802002105200241086a2206280200210720012802002208210902400240024002400340024002400240024020052007470d00200541016a220a2005490d052005410174220b200a200a200b491b220c4100480d052005450d012002280200210d200c1000220b450d06200b200d200c20052005200c4b1b10ce021a200d10010c020b200741016a210a2002280200210b0c020b200c1000220b450d040b2002200b3602002004200c360200200c21050b2006200a360200200b20076a200941807f72200941ff00712009410776220b1b3a0000200a2107200b2109200b0d000b2001280204220e2001410c6a280200220f410c6c6a210d200141086a2802002110200e21050240024002402008450d00200341106a4101722111200241086a2104200e21124100211303402012200d460d02201321052012210b02400340200b28020022010d01200541016a2105200d200b410c6a220b470d000c040b0b200b410c6a2112200541016a21132008417f6a2108200241046a2214280200210920042802002107200b41046a29020021150340024002400240024020092007470d00200941016a220a2009490d092009410174220c200a200a200c491b22064100480d092009450d012002280200211620061000220c450d0b200c201620062009200920064b1b10ce021a201610010c020b200741016a210a2002280200210c0c020b20061000220c450d090b2002200c36020020142006360200200621090b2004200a360200200c20076a200541807f72200541ff00712005410776220c1b3a0000200a2107200c2105200c0d000b2003201537022420032001360220200341106a200341206a2002108901200320112900003703002003201141076a29000037000720032d00102205411a470d0320080d000b200b410c6a21050b2005200d460d00200e200f410c6c6a2107034020052209410c6a210502402009280200220a450d00200941046a280200450d00200a10010b20072005470d000b0b02402010450d00200e10010b2000411a3a00000c040b20002003290300370001200020053a0000200041086a20032900073700000240200e200f410c6c6a220741746a200b460d00200b410c6a2105034020052209410c6a210502402009280200220a450d00200941046a280200450d00200a10010b20072005470d000b0b2010450d03200e1001200341306a24000f0b1018000b200c41011019000b200641011019000b200341306a24000bac05010d7f230041306b220324002003410c6a220441003602002003200236020020034201370204200341206a41086a200141086a28020036020020032001290200370320200341106a200341206a200310880102400240024002400240024002400240024020032d0010411a470d002003410472200128020c2205200141146a2802001029200341086a2802002106200328020421072003280200220841046a21092004280200220a2104034002400240024002402009280200200841086a220b2802002202470d00200241016a220c2002490d0b2002410174220d200c200c200d491b220e4100480d0b2002450d012008280200210f200e1000220d450d0c200d200f200e20022002200e4b1b10ce021a200f10010c020b200241016a210c2008280200210d0c020b200e1000220d450d0a0b2008200d3602002009200e3602000b200b200c360200200d20026a200441807f72200441ff0071200441077622021b3a00002002210420020d000b200841046a280200220d200841086a28020022026b200a4f0d012002200a6a22042002490d06200d410174220c20042004200c491b220e4100480d06200d450d022008280200210b200e1000220c450d08200c200b200e200d200d200e4b1b10ce021a200b10010c030b20002003290310370200200041086a200341106a41086a2903003702000240200341086a280200450d00200328020410010b200141106a280200450d042001410c6a2802001001200341306a24000f0b2002200a6a21042008280200210c0c020b200e1000220c450d050b2008200c360200200841046a200e3602000b200841086a2004360200200c20026a2007200a10ce021a02402006450d00200710010b2000411a3a0000200141106a280200450d00200510010b200341306a24000f0b1018000b200e41011019000b200e41011019000bd50602087f017e230041d080016b22022400200128020421032001280200210441002105200141086a21064100210702400240024002400240024002400240024003402005411f4b0d01200320062802002208460d02200841016a21092008417f460d0520032009490d0620062009360200200420086a2d0000220841ff00712005411f71742007722107200541076a21052008418001710d000b024020054120490d00410d210520086741686a41ff01714104490d030b2002410036021020024201370308200241186a41004180800110d0021a4100210502402007450d00200141086a22012802002105410021060340200320056b200720066b220841808001200841808001491b2208490d05200520086a22092005490d0820032009490d09200241186a200420056a200810ce021a20012009360200200241086a200241186a20081029200921052007200820066a22064b0d000b200241106a28020021050b2002290308210a2000410c6a20053602002000200a370204200041106a4100360200200041146a200536020020004100360200200241d080016a24000f0b410f21050c010b200241013a00a88001200241246a41013602002002412c6a41013602002002410a36029c8001200241a082c0003602182002410136021c200241c0c5c2003602202002200241a880016a360298800120022002419880016a360228200241b880016a200241186a104c410521050b2000200536020420004101360200200041086a20022902b88001370200200041106a200241b880016a41086a2802003602000c050b200241013a00a78001200241b880016a410c6a4101360200200241cc80016a41013602002002410a36029c8001200241a082c0003602b88001200241013602bc8001200241c0c5c2003602c080012002200241a780016a360298800120022002419880016a3602c88001200241a880016a200241b880016a104c200241c380016a200241b080016a280200360000200220022903a880013700bb8001200041053a000420004101360200200020022900b880013700052000410c6a200241bf80016a290000370000200228020c450d0420022802081001200241d080016a24000f0b417f2009106b000b20092003106a000b20052009106b000b20092003106a000b200241d080016a24000b3201017f0240410810002202450d0020002002360200200220013700002000428880808080013702040f0b410841011019000bc80101067f024002400240024002400240200141046a2802002202200141086a28020022036b41044f0d00200341046a22042003490d0420024101742205200420042005491b22064100480d042002450d0120012802002107200610002205450d052005200720062002200220064b1b10ce021a200710010c020b200341046a2104200128020021050c020b200610002205450d030b20012005360200200141046a20063602000b200141086a2004360200200520036a20003600000f0b1018000b200641011019000bd10101067f024002400240024002400240200241046a2802002203200241086a28020022046b41104f0d00200441106a22052004490d0420034101742206200520052006491b22074100480d042003450d0120022802002108200710002206450d052006200820072003200320074b1b10ce021a200810010c020b200441106a2105200228020021060c020b200710002206450d030b20022006360200200241046a20073602000b200620046a2204200137000820042000370000200241086a20053602000f0b1018000b200741011019000bc80101067f024002400240024002400240200141046a2802002202200141086a28020022036b41084f0d00200341086a22042003490d0420024101742205200420042005491b22064100480d042002450d0120012802002107200610002205450d052005200720062002200220064b1b10ce021a200710010c020b200341086a2104200128020021050c020b200610002205450d030b20012005360200200141046a20063602000b200141086a2004360200200520036a20003700000f0b1018000b200641011019000b7001017f024002400240200028020022024101460d0020024102460d0120024103470d0220014104101f200041086a290300200110e1010f0b20014102101f200041086a290300200110e1010f0b20014103101f2000280204200110df010f0b20014101101f2000280204200110df010bf80601097f02400240024002400240024002400240200141c0004f0d0020022001410274101f2001450d02200241086a220328020021040c010b024002400240024002400240024002400240024002400240024002402001418080014f0d00200241046a2802002205200241086a220328020022066b41024f0d01200641026a22042006490d1020054101742207200420042007491b22084100480d102005450d0520022802002109200810002207450d122007200920082005200520084b1b10ce021a200910010c060b20014180808080044f0d01200241046a2802002205200241086a220328020022066b41044f0d02200641046a22042006490d0f20054101742207200420042007491b22084100480d0f2005450d0720022802002109200810002207450d122007200920082005200520084b1b10ce021a200910010c080b200641026a2104200228020021070c050b20024103101f200241046a2802002205200241086a220328020022066b41044f0d01200641046a22042006490d0d20054101742207200420042007491b22084100480d0d2005450d0820022802002109200810002207450d112007200920082005200520084b1b10ce021a200910010c090b200641046a2104200228020021070c060b200641046a2104200228020021070c080b200810002207450d0c0b20022007360200200241046a20083602000b20032004360200200720066a20014102744101723b00000c060b200810002207450d0a0b20022007360200200241046a20083602000b20032004360200200720066a20014102744102723600000c030b200810002207450d080b20022007360200200241046a20083602000b20032004360200200720066a20013600000b20014102742108200241046a220a28020021060340200028020021090240024002400240200620046b41044f0d00200441046a22012004490d0620064101742207200120012007491b22054100480d062006450d012002280200210b200510002207450d072007200b20052006200620054b1b10ce021a200b10010c020b200441046a2101200228020021070c020b200510002207450d050b20022007360200200a2005360200200521060b200041046a210020032001360200200720046a2009360000200121042008417c6a22080d000b0b0f0b1018000b200541011019000b200841011019000b200841011019000b200841011019000bf30601087f02400240024002400240024002400240200141c0004f0d0020022001410274101f20010d010c020b024002400240024002400240024002400240024002400240024002402001418080014f0d00200241046a2802002203200241086a28020022046b41024f0d01200441026a22052004490d1020034101742206200520052006491b22074100480d102003450d0520022802002108200710002206450d122006200820072003200320074b1b10ce021a200810010c060b20014180808080044f0d01200241046a2802002203200241086a28020022046b41044f0d02200441046a22052004490d0f20034101742206200520052006491b22074100480d0f2003450d0720022802002108200710002206450d122006200820072003200320074b1b10ce021a200810010c080b200441026a2105200228020021060c050b20024103101f200241046a2802002203200241086a28020022046b41044f0d01200441046a22052004490d0d20034101742206200520052006491b22074100480d0d2003450d0820022802002108200710002206450d112006200820072003200320074b1b10ce021a200810010c090b200441046a2105200228020021060c060b200441046a2105200228020021060c080b200710002206450d0c0b20022006360200200241046a20073602000b200241086a2005360200200620046a20014102744101723b00000c060b200710002206450d0a0b20022006360200200241046a20073602000b200241086a2005360200200620046a20014102744102723600000c030b200710002206450d080b20022006360200200241046a20073602000b200241086a2005360200200620046a20013600000b200020016a2107200241046a22092802002101200241086a220828020021050340024002400240024020012005470d00200141016a22042001490d0620014101742206200420042006491b22034100480d062001450d012002280200210a200310002206450d072006200a20032001200120034b1b10ce021a200a10010c020b200541016a2104200228020021060c020b200310002206450d050b2002200636020020092003360200200321010b20082004360200200620056a20002d00003a000020042105200041016a2204210020072004470d000b0b0f0b1018000b200341011019000b200741011019000b200741011019000b200741011019000b3802017f017e230041106b220324002003200210e601200329030021042000200341086a29030037030820002004370300200341106a24000bbf0204047f017e017f017e230041206b22022400024002400240411410002203450d002002200336021020024214370214200241106a41d7aac20041141029200241086a220320022802183602002002200229031037030020012002101b20032802002104200228020421052002280200210142002106200241106a41086a220742003703002002420037031020012004200241106a10022003200729030037030020022002290310370300024002402002411041b8d6c200410041001004417f460d00200242003703182002420037031020024110200241106a4110410010042203417f460d012003410f4d0d01200241186a2903002108200229031021062005450d040c030b4200210820050d020c030b41b2eac10041331040000b411441011019000b200110010b2000200637030020002008370308200241206a24000bda0402027f017e23004180016b22052400200541106a41186a200241186a290000370300200541106a41106a200241106a290000370300200541106a41086a200241086a2900003703002005200229000037031002400240024002402004417f4c0d00024002402004450d002004100022020d01200441011019000b410121020b200520043602542005200236025020054100360258200541d0006a200320041029200541306a41086a2204200528025836020020052005290350370330200541d0006a41186a200541106a41186a290300370300200541d0006a41106a200541106a41106a290300370300200541d0006a41086a200541106a41086a29030037030020052005290310370350200541f0006a41086a200428020036020020052005290330370370200541c0006a200541d0006a200541f0006a10e80102400240024002400240200528024022032005280248220441b8d6c200410041001004417f460d00200520043602542005200336025020054100360258200541086a200541d0006a10352005280208450d07200528020c2204417f4c0d052004450d01200410002202450d0820024100200410d0021a0c020b2000410036020020052802440d020c030b410121020b200541d8006a2206200628020022062004410020052802502005280254200220042006100422062006417f461b2206200620044b1b6a360200200420064b0d032002450d0420002004ad2207422086200784370204200020023602002005280244450d010b200310010b20054180016a24000f0b102e000b200210010b41b2eac10041331040000b200441011019000b810701087f230041e0006b22032400200341c0006a41186a2204200141186a290000370300200341c0006a41106a2205200141106a290000370300200341c0006a41086a2206200141086a290000370300200320012900003703402003410036023820034201370330200341306a418debc1004108102902400240024002400240412010002201450d0020012003290340370000200141186a2004290300370000200141106a2005290300370000200141086a2006290300370000024002400240024020032802342206200341306a41086a28020022056b41204f0d00200541206a22042005490d0520064101742207200420042007491b22074100480d052006450d0120032802302108200710002204450d082004200820072006200620074b1b10ce021a200810010c020b20032802302104200621070c020b200710002204450d060b20032007360234200320043602300b200420056a22062001290000370000200641186a200141186a290000370000200641106a200141106a290000370000200641086a200141086a290000370000200341306a41086a200541206a220536020020011001200341106a41086a220142003703002003420037031020042005200341106a1002200341086a20012903003703002003200329031037030002402007450d00200410010b2003410036024820034201370340200228020022092002280208200341c0006a1020200328024421052003280248210620032802402104200341c0006a41186a22074200370300200341c0006a41106a22084200370300200341c0006a41086a220a42003703002003420037034020042006200341c0006a1011200341106a41186a2007290300370300200341106a41106a20082903003703002001200a2903003703002003200329034037031002402005450d00200410010b411010002204450d0220042003290300370000200441086a2205200341086a290300370000413010002201450d0320012004290000370000200141086a20052900003700002004100120002001360200200042b08080808006370204200141286a200341106a41186a290300370000200141206a200341206a290300370000200141186a200341106a41086a290300370000200120032903103700100240200241046a280200450d00200910010b200341e0006a24000f0b412041011019000b1018000b411041011019000b413041011019000b200741011019000bcb0c05027f017e0e7f027e097f23004190036b2202240020024188016a41086a2203200141086a2802003602002002200129020037038801200241086a20024188016a10ea01200241306a41206a200241086a41206a280200360200200241306a41186a200241086a41186a290300370300200241306a41106a200241086a41106a290300370300200241306a41086a200241086a41086a2903003703002002200229030837033020024188016a200241306a10eb010240024020022903a80122044202510d00200241cc016a2105200241b8016a2106200241b0016a2107200241c0016a2108200241c4016a2109200241c8016a210a20024188016a41206a210b200241ec026a210c200241f4026a210d0340200241e8006a41186a220120024188016a41186a220e290300370300200241e8006a41106a220f20024188016a41106a2210290300370300200241e8006a41086a22112003290300370300200241d8006a41086a2212200541086a28020036020020022002290388013703682002200529020037035820062903002113200729030021142008280200211520092802002116200a2802002117200241d8016a41186a22182001290300370300200241d8016a41106a2219200f290300370300200241d8016a41086a221a2011290300370300200220022903683703d801200241f8016a41086a22012012280200360200200220022903583703f8010240024020044201520d00200241d8016a2014201310ec01450d0002402015450d002016450d00201510010b20024188026a41086a2001280200360200200220022903f8013703880220024188016a20024188026a108e0120024188016a108f010c010b024002402015450d00410f1000220f450d052002200f360288012002420f37028c0120024188016a41d5c7c100410f102920024188026a41086a220f2003280200360200200220022903880137038802200241d8016a20024188026a101b200f280200211b200228028c02211c20022802880221112003410036020020024201370388012015201720024188016a102020032802002117200228028c01211d20022802880121122003420037030020024200370388012011201b20024188016a1002200f200329030037030020022002290388013703880220024188026a41102012201710030240201d450d00201210010b0240201c450d00201110010b4101211b2016450d01201510010c010b4100211b0b20032001280200360200200220022903f8013703880120024188026a20024188016a108e01200b20024188026a41206a280200360200200e20024188026a41186a290300370300201020024188026a41106a290300370300200320024188026a41086a290300370300200220022903880237038801200241e0026a20024188016a10ed01024020022802e002450d000340200241b0026a41086a2211200241e0026a41086a2201280200360200200220022903e0023703b002200c280200210f200241e0026a41106a22122802002110200d2802002117200241c0026a41086a220e2011280200360200200220022903b0023703c00202400240200f450d00200241e0026a41186a2018290300370300201220192903003703002001201a290300370300200220022903d8013703e00220024180036a41086a200e280200360200200220022903c00237038003200241d0026a200241e0026a20024180036a10e801200241d0026a41086a280200211220022802d002211120014100360200200242013703e002200f2017200241e0026a102020022802e402210e2011201220022802e0022217200128020010030240200e450d00201710010b024020022802d402450d00201110010b2010450d01200f10010c010b200241e0026a41186a2018290300370300201220192903003703002001201a290300370300200220022903d8013703e00220024180036a41086a200e280200360200200220022903c00237038003200241d0026a200241e0026a20024180036a10e80120022802d0022201200241d0026a41086a280200100a20022802d402450d00200110010b200241e0026a20024188016a10ed0120022802e0020d000b0b20024188016a108f01201b201545720d002016450d00201510010b20024188016a200241306a10eb01200b29030022044202520d000b0b200241306a10ee0120024190036a24000f0b410f41011019000bb00301097f23002102200141046a280200210320012802082104200241306b220241186a2205200128020022063602002002411c6a2207410036020020022003360214200220034100472208360210024002402003450d002003417f6a2101200241106a41047221092006210a03402005200a2802f806220a3602002007410036020020022001360214200220014100473602102001417f6a2201417f470d000c020b0b200241106a41047221090b200241086a200941086a28020036020020022009290200370300200241106a41086a220a20063602002002411c6a22054100360200200220033602142002200836021002402003450d002003417f6a21010340200a200620062f01064102746a41f8066a28020022063602002005410036020020022001360214200220014100473602102001417f6a2201417f470d000b0b200241106a41086a28020022012f010621062002411c6a280200210a200228021421052000410036020c20002005360210200041146a2001360200200041186a200a3602002000411c6a200636020020002004360220200041086a200241086a280200360200200020022903003702000b9c0d03097f017e017f230041e0016b220224000240024020012802202203450d00200141206a2003417f6a36020020012802082104200128020c2205200128020422032f01064f0d01200241306a41186a2206200320054105746a220741206a290000370300200241306a41106a2208200741186a290000370300200241306a41086a2209200741106a2900003703002002200741086a290000370330200141046a2003360200200141086a20043602002001410c6a200541016a360200200241d0006a41286a22072003200541306c6a22034190036a290300370300200241d0006a41206a220520034188036a290300370300200241d0006a41186a220120034180036a290300370300200241d0006a41106a2204200341f8026a290300370300200241d0006a41086a220a200341f0026a2903003703002002200341e8026a29030037035020024180016a41186a200629030037030020024180016a41106a200829030037030020024180016a41086a200929030037030020024180016a41286a200a29030037030020024180016a41306a2004290300370300200241b8016a2001290300370300200241c0016a2005290300370300200241c8016a20072903003703002002200229033037038001200220022903503703a001200020024180016a41d00010ce021a200241e0016a24000f0b20004202370320200241e0016a24000f0b200128020021070240024020032802002205450d002003330104210b20022005360284012002200741016a2207360280012002200b4220862004ad84220b370388010c010b2004ad210b410021050b20031001200241106a220420053602002002200736020c024002400240200b422088a7220320052f01064f0d00200241186a2003360200200241146a200b3e020020024100360208200241086a4104722108200241206a21050c010b200241146a2206200b37020020024101360208200241086a41047221080240200528020022030d004103210c0c020b4100210c0c010b4105210c0b03400240024002400240024002400240024002400240024002400240024002400240200c0e0a01030002040508090607070b2006200b37020020024101360208200322052802002203450d094100210c0c0f0b2005330104422086200b42ffffffff0f8384210b200741016a21070c090b200b42ffffffff0f83210b410021034101210c0c0d0b20051001200420033602002002200736020c200b422088a7220520032f01064f0d084104210c0c0c0b200241186a2005360200200241146a200b3e020020024100360208200241206a21054105210c0c0b0b20052008290200370200200541086a200841086a290200370200200241306a41086a20022802242206200228022c22084105746a220341106a290000370300200241306a41106a200341186a290000370300200241306a41186a200341206a2900003703002002200341086a290000370330200241f8006a2006200841306c6a22034190036a290300370300200241d0006a41206a20034188036a290300370300200241d0006a41186a20034180036a290300370300200241d0006a41106a200341f8026a290300370300200241d0006a41086a200341f0026a2903003703002002200341e8026a290300370350200528020021092002280228210720024180016a41086a2204200620084102746a41fc066a28020022053602002002418c016a2206200736020020022009417f6a22033602840120022003410047360280012003450d074108210c0c0a0b2009417e6a210320024180016a41047221084109210c0c090b200420052802f806220536020020062007360200200220033602840120022003410047360280012003417f6a2203417f470d060c070b20024180016a41047221084107210c0c070b200120082902003702002001410c6a4100360200200141086a200841086a28020036020020024180016a41186a200241306a41186a29030037030020024180016a41106a200241306a41106a29030037030020024180016a41086a200241306a41086a29030037030020024180016a41286a200241d0006a41086a290300370300200241b0016a200241d0006a41106a290300370300200241b8016a200241d0006a41186a290300370300200241c0016a200241f0006a290300370300200241c8016a200241d0006a41286a2903003703002002200229033037038001200220022903503703a001200020024180016a41d00010ce021a200241e0016a24000f0b4103210c0c050b4101210c0c040b4102210c0c030b4106210c0c020b4109210c0c010b4107210c0c000b0baa1704027f017e0b7f037e230041b0016b22032400200341a0016a41086a22044200370300200342003703a00141a1abc200411b200341a0016a100220034190016a41086a2004290300370300200320032903a00137039001024002400240024002400240024002400240024002400240024002400240024020034190016a411041b8d6c200410041001004417f460d002003420037032820034200370320024020034190016a4110200341206a4110410010042204417f460d002004410f4d0d0002402003290320200158200341286a290300220520025820052002511b0d0020002001200210b402200341b0016a240041010f0b411410002204450d032003200436022020034214370224200341206a41d7aac20041141029200341a0016a41086a22042003280228360200200320032903203703a0012000200341a0016a101b2004280200210620032802a401210720032802a001210820044200370300200342003703a00120082006200341a0016a100220034190016a41086a2004290300370300200320032903a0013703900120034190016a41101014210402402007450d00200810010b02402004450d0020002001200210b402200341b0016a240041000f0b200341a0016a41086a22044200370300200342003703a00141bbbfc2004114200341a0016a100220034190016a41086a2004290300370300200320032903a0013703900120034190016a411041b8d6c200410041001004417f460d042003410036022020034190016a4110200341206a41044100100441016a41044d0d0220032802202207410e744180807c71418080046a2204450d05200341106a200120022004ad420010d402410021092003280210220641ff017141e900470d0b411010002204450d062003200436022020034210370224200341206a419db0c20041101029200328022021040240024002400240200328022422082003280228220a6b41044f0d00200a41046a220b200a490d102008410174220c200b200b200c491b220c4100480d102008450d01200c1000220d450d0c200d2004200c20082008200c4b1b10ce02210820041001200821040c020b200a41046a210b0c020b200c10002204450d0a0b200c21080b2004200a6a2006410e76220c360000200341a0016a41086a220a4200370300200342003703a0012004200b200341a0016a100220034190016a41086a200a290300370300200320032903a001370390014100210a024020034190016a411041b8d6c200410041001004417f460d00200342103702a401200320034190016a3602a001200341206a200341a0016a10392003280220220b450d08200341286a280200210a2003280224210d200641087621062008450d0b0c0a0b4101210b4100210d2006410876210620080d090c0a0b41b2eac10041331040000b41c3d7c10041221040000b41b2eac10041331040000b411441011019000b41c3d7c10041221040000b41b8f5c000104d000b411041011019000b41b2eac10041331040000b200c41011019000b200410010b02402006200c4106746b2204200a4f0d002003200b20044105746a22041095022003290300200341086a290300844200510d050b41022109200d450d00200b10010b2007410674210c200341206a41086a210d411010002204450d0103402003200436022020034210370224200341206a419db0c2004110102920032802202104024002400240024002400240024020032802242208200d28020022066b41044f0d00200641046a220a2006490d082008410174220b200a200a200b491b220b4100480d082008450d01200b1000220e450d04200e2004200b20082008200b4b1b10ce02210820041001200821040c020b200641046a210a0c020b200b10002204450d020b200b21080b200420066a2007360000200341a0016a41086a22064200370300200342003703a0012004200a200341a0016a100220034190016a41086a2006290300370300200320032903a001370390010240024020034190016a411041b8d6c200410041001004417f460d00200342103702a401200320034190016a3602a001200341206a200341a0016a10392003280220220b450d01200d28020021062003280224210a2008450d040c030b4101210b410021064100210a20080d020c030b41b2eac10041331040000b200b41011019000b200410010b02402006413f4d0d000240200a450d00200b10010b200741016a2107200c41c0006a210c411010002204450d030c010b0b200341206a41186a220d200041186a290000370300200341206a41106a220e200041106a290000370300200341206a41086a220f200041086a290000370300200320002900003703200240024002402006200a470d00200641016a22042006490d0320064101742208200420042008491b220aad4205862205422088a70d032005a722044100480d032006450d01200410002208450d052008200b200420064105742210201020044b1b10ce021a200b10010c020b200b21080c010b200410002208450d030b200c20066a210b200820064105746a22042003290320370000200441186a200d290300370000200441106a200e290300370000200441086a200f2903003700000240200641016a220441c000470d002003200741016a360220200341a0016a41086a22064200370300200342003703a00141bbbfc2004114200341a0016a100220034190016a41086a2006290300370300200320032903a0013703900120034190016a4110200341206a410410030b2003200a36022420032008360220200320043602282007200341206a10c302200341206a41086a41003a0000200341c9006a20093a0000200341cc006a200b360200200341296a2000290000370000200341316a200041086a290000370000200341396a200041106a290000370000200341c1006a200041186a290000370000200341013a0020200341206a10a10120012105200221110c040b1018000b411041011019000b200441011019000b200341206a41186a200041186a22082900002205370300200341206a41106a200041106a22072900002211370300200341206a41086a220e200041086a22092900002212370300200420002900002213370000200441086a2012370000200441106a2011370000200441186a2005370000200320133703202003200d3602242003200b3602202003200a360228200c200341206a10c302200e41003a0000200341c9006a41013a0000200341cc006a2006360200200341296a2000290000370000200341316a2009290000370000200341396a2007290000370000200341c1006a2008290000370000200341013a0020200341206a10a101200341a0016a41086a22044200370300200342003703a00141cfbfc2004116200341a0016a100220034190016a41086a2004290300370300200320032903a00137039001024020034190016a411041b8d6c200410041001004417f460d002003420037032820034200370320024020034190016a4110200341206a4110410010042204417f460d002004410f4d0d00200341286a29030020027c2003290320221120017c2205201154ad7c21110c020b41b2eac10041331040000b41c3d7c10041221040000b20002005201110b402200341a0016a41086a22044200370300200342003703a00141bcabc2004116200341a0016a100220034190016a41086a2004290300370300200320032903a00137039001024020034190016a411041b8d6c200410041001004417f460d002003420037032820034200370320024020034190016a4110200341206a4110410010042204417f460d002004410f4d0d00024020032903202212200520017d7c22132012542204200341206a41086a2903002212201120027d2005200154ad7d7c2004ad7c220220125420022012511b0d002003201337032020032002370328200341a0016a41086a22044200370300200342003703a00141bcabc2004116200341a0016a100220034190016a41086a2004290300370300200320032903a0013703900120034190016a4110200341206a411010030b200341b0016a240041000f0b41b2eac10041331040000b41c3d7c10041221040000be80903067f017e037f230041f0006b220224000240024020012802202203450d00200141206a2003417f6a36020020012802082104200128020c2205200128020422032f01064f0d01200241186a41086a220620032005410c6c6a220741106a2802003602002002200741086a290200370318200141046a2003360200200141086a20043602002001410c6a200541016a360200200241086a220320074194016a28020036020020022007418c016a290200370300200241c8006a41086a22052006280200360200200241dc006a200328020036020020002002290318220837020020022002290300370254200041086a2005290300370200200041106a200241c8006a41106a29030037020020022008370348200241f0006a24000f0b20004100360200200241f0006a24000f0b200128020021070240024020032802002205450d00200333010421082002200536024c2002200741016a2207360248200220084220862004ad8422083703500c010b2004ad2108410021050b2003100120052f01062103200241086a22042005360200200220073602040240024002402008422088a7220620034f0d00200241106a20063602002002410c6a20083e02002002410036020020024104722109200241186a21050c010b2002410c6a2206200837020020024101360200200241047221090240200528020022030d004103210a0c020b4100210a0c010b4105210a0b03400240024002400240024002400240024002400240024002400240024002400240200a0e0a01030002040508090607070b20042003360200200620083702002002200736020420024101360200200322052802002203450d094100210a0c0f0b2005330104422086200842ffffffff0f83842108200741016a21070c090b200842ffffffff0f832108410021034101210a0c0d0b200510012008422088a7220520032f01064f0d084104210a0c0c0b200241086a20033602002002410c6a20083e0200200241106a20053602002002200736020420024100360200200241186a21054105210a0c0b0b20052009290200370200200541086a200941086a290200370200200241286a41086a200228021c22062002280224220b410c6c6a220341106a2802003602002002200341086a290200370328200241386a41086a20034194016a28020036020020022003418c016a2902003703382005280200210920022802202107200241c8006a41086a22042006200b4102746a4194026a2802002205360200200241c8006a410c6a2206200736020020022009417f6a220336024c200220034100473602482003450d074108210a0c0a0b2009417e6a2103200241c8006a41047221094109210a0c090b20042005280290022205360200200620073602002002200336024c200220034100473602482003417f6a2203417f470d060c070b200241c8006a41047221094107210a0c070b200120092902003702002001410c6a4100360200200141086a200941086a280200360200200241c8006a41086a2203200241286a41086a280200360200200241dc006a200241386a41086a28020036020020002002290328220837020020022002290338370254200041086a2003290300370200200041106a200241c8006a41106a29030037020020022008370348200241f0006a24000f0b4103210a0c050b4101210a0c040b4102210a0c030b4106210a0c020b4109210a0c010b4107210a0c000b0bb50302077f027e230041a0016b22012400200141086a200010eb01024020012903284202510d00200141d8006a4104722102200141c8006a2103200141c4006a2104200141c0006a2105200141286a21060340200141d8006a41086a200341086a29030037030020012003290300370358024020052802002207450d002004280200450d00200710010b20014190016a41086a200241086a2802003602002001200229020037039001200141e8006a20014190016a108e01200141e8006a108f01200141086a200010eb0120062903004202520d000b0b02400240024002402000280204220241a0a1c100460d0020022802002203450d0120002802082107200233010421082001200028020041016a2200360208200120084220862007ad8422083703102001200336020c2002100120032802002202450d02200333010421092001200236020c2001200041016a36020820012009422086200842ffffffff0f838437031020031001034020022802002203450d04200210012003210220030d000b0b200141a0016a24000f0b20021001200141a0016a24000f0b20031001200141a0016a24000f0b20021001200141a0016a24000b09002000200210b6010bd70301067f0240024002400240024002400240200141046a2802002202200141086a28020022036b41204f0d00200341206a22042003490d0420024101742205200420042005491b22054100480d042002450d0120012802002106200510002207450d052007200620052002200220054b1b10ce021a200610010c020b200341206a210420012802002107200221050c020b200510002207450d030b20012007360200200141046a20053602000b200141086a2004360200200720036a220341186a200041186a290000370000200341106a200041106a290000370000200341086a200041086a290000370000200320002900003700000240024002400240200520046b41204f0d00200441206a22022004490d0420054101742203200220022003491b22064100480d042006100021032005450d012003450d062003200720062005200520064b1b10ce021a200710010c020b200441206a2102200721030c020b2003450d040b20012003360200200141046a20063602000b200141086a2002360200200320046a220141186a200041386a290000370000200141106a200041306a290000370000200141086a200041286a290000370000200120002900203700000f0b1018000b200541011019000b200641011019000bcc0102057f017e2001280200210202400240412010002203450d0020032002290000370000200341186a2204200241186a290000370000200341106a2205200241106a290000370000200341086a2206200241086a2900003700002001290308210741c00010002202450d0120022003290000370000200241186a2004290000370000200241106a2005290000370000200241086a2006290000370000200310012000200236020020022007370020200042c080808080053702040f0b412041011019000b41c00041011019000b6401027f230041106b2202240041002103024002402000200141b8d6c200410041001004417f460d002002410036020c200020012002410c6a41044100100441016a41044d0d01200228020c21030b200241106a240020030f0b41b2eac10041331040000b7f01037f230041106b220124004100210202400240024041fdabc200411041b8d6c200410041001004417f460d002001410036020c4101210241fdabc20041102001410c6a41044100100441016a41044d0d02200128020c21030c010b0b2000200336020420002002360200200141106a24000f0b41b2eac10041331040000b6001017f0240412010002203450d0020032002290000370000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a29000037000020002001200341201003200310010f0b412041011019000bd31a06097f037e087f017e067f027e230041b0026b2202240020012802002103200241e8016a200128020422044120200441204922051b22066a41004100412020066b2006411f4b1b10d0021a200241e8016a2003200610ce021a2001200420066b22043602042001200320066a220636020002400240024002400240024002400240024002400240024002400240024020050d00200241a0016a41186a2203200241e8016a41186a2205290000370300200241a0016a41106a2207200241e8016a41106a2208290000370300200241a0016a41086a2209200241e8016a41086a220a290000370300200220022900e8013703a00120052003290300220b37030020082007290300220c370300200a2009290300220d370300200241186a41086a200d370300200241186a41106a200c370300200241186a41186a200b370300200220022903a001220b3703182002200b3703e801200242003703e801200241e8016a20062004410820044108491b220310ce021a200141046a2207200420036b22053602002001200620036a2203360200200441074d0d0120022903e801210d200241e8016a20054120200541204922081b22066a41004100412020066b2006411f4b1b10d0021a200241e8016a2003200610ce021a2007200520066b22043602002001200320066a220336020020080d02200241386a41186a200241e8016a41186a2205290000370300200241386a41106a200241e8016a41106a2207290000370300200241386a41086a200241e8016a41086a2208290000370300200220022900e801370338200241e8016a2004412020044120491b22066a41004100412020066b2006411f4b1b10d0021a200241e8016a2003200610ce021a200141046a200420066b3602002001200320066a3602002004411f4d0d03200241d8006a41186a2005290000370300200241d8006a41106a2007290000370300200241d8006a41086a2008290000370300200220022900e801370358200241106a200110332002280210450d092002280214220ead220b42247e220c422088a70d0c200ca72206417f4c0d0c2006450d0420061000220a450d0d200e0d050c060b200241e8016a41186a200241a0016a41186a290000370300200241e8016a41106a200241a0016a41106a290000370300200241e8016a41086a200241a0016a41086a290000370300200220022900a0013703e80120004100360208200241b0026a24000f0b20004100360208200241b0026a24000f0b20004100360208200241b0026a24000f0b20004100360208200241b0026a24000f0b4104210a200e450d010b200241f8006a41116a210f200241f7016a2110200241e8016a41106a2106200241e8016a4101722111200241a0016a4101722104200141046a2109200241e8016a41036a2112200241ef016a211341002114034020092802002103200241003a00e801200241e8016a200128020022072003410047220510ce021a2009200320056b22083602002001200720056a2207360200024002400240024002400240024002402003450d004103210520022d00e8012203450d0220034101460d0120034102470d07200241e8016a2008412020084120491b22036a41004100412020036b2003411f4b1b10d0021a200241e8016a2007200310ce021a2009200820036b3602002001200720036a3602002008411f4d0d03200241a8026a41026a200241e8016a41026a2d00003a000020024190026a41086a201041086a29000037030020024190026a41106a201041106a2d00003a0000200220022f00e8013b01a80220022010290000370390022012280000211520132900002116410121030c040b410321050c060b200241e8016a2001103b20022802e8012203450d0520022902ec01210c200241e4016a41026a20024190026a41026a2d00003a0000200241f8006a41086a200241e8016a41086a290200370300200241f8006a41106a2006280200360200200220022f0090023b01e401200220022902e80137037841002105200321170c050b200241086a200110332002280208450d04200228020c2203417f4c0d0c2003450d02200310002218450d0e20184100200310d0021a0c030b410021030b200241ac026a41026a2207200241a8026a41026a2d00003a0000200241e8016a41086a220820024190026a41086a290300370300200620024190026a41106a2d00003a0000200220022f01a8023b01ac0220022002290390023703e8012003450d02200241e4016a41026a20072d00003a0000200241f8006a41086a2008290300370300200241f8006a41106a20062d00003a0000200220022f01ac023b01e401200220022903e801370378200f41026a200241e8016a41026a2d00003a0000200f20022f00e8013b000041012105201521172016210c0c020b410121180b20182001280200221920092802002207200320072003491b220810ce0221182009200720086b3602002001201920086a3602000240200720034f0d00201810010c010b2018450d002003ad220c422086200c84210c41022105200241e4016a41026a20024190026a41026a2d00003a0000200241f8006a41086a200241e8016a41086a290200370300200241f8006a41106a2006280200360200200220022f0090023b01e401200220022902e801370378201821170b20024190026a41026a2218200241e4016a41026a2d00003a0000200241e8016a41086a2203200241f8006a41086a22072903003703002006200241f8006a41106a2208280200360200200220022f01e4013b019002200220022903783703e80120054103460d02200241e0016a41026a221920182d00003a0000200241c8016a41086a22182003290300370300200241c8016a41106a221a2006280200360200200220022f0190023b01e001200220022903e8013703c8012003200c370300201120022f01e0013b0000201141026a20192d00003a0000200620022903c801370000200641086a2018290300370000200641106a201a280200360000200220053a00e801200220173602ec01200241a0016a200241e8016a103720022d00a0012105200241e8016a41226a2218200441226a2d00003a0000200241e8016a41206a2219200441206a2f00003b0100200241e8016a41186a221a200441186a2900003703002006200441106a2900003703002003200441086a290000370300200220042900003703e80120054102460d03200241f8006a41226a221b20182d00003a0000200241f8006a41206a221820192f01003b0100200241f8006a41186a2219201a2903003703002008200629030037030020072003290300370300200220022903e8013703780240200b422088a72203200ba7470d00200341016a221a2003490d062003410174221c201a201a201c491bad221d42247e221e422088a70d06201ea7221a4100480d06024002402003450d00201a1000221c450d09201c200a201a200341246c22032003201a4b1b10ce022103200a10012003210a0c010b201a1000220a450d080b200b42808080807083201d84210b0b200a200b422088a741246c6a220320053a0000200341236a201b2d00003a0000200341216a20182f01003b0000200341196a2019290300370000200341116a2008290300370000200341096a200729030037000020032002290378370001200b4280808080107c210b201441016a2214200e490d000b0b200a450d02200241e8016a41186a2201200241186a41186a290300370300200241e8016a41106a2206200241186a41106a290300370300200241e8016a41086a2203200241186a41086a290300370300200241a0016a41086a2204200241386a41086a290300370300200241a0016a41106a2205200241386a41106a290300370300200241a0016a41186a2207200241386a41186a290300370300200241f8006a41086a2208200241d8006a41086a290300370300200241f8006a41106a2209200241d8006a41106a290300370300200241f8006a41186a2211200241d8006a41186a290300370300200220022903183703e801200220022903383703a001200220022903583703782000200a3602082000200d3703002000200b37020c200041146a20022903e8013702002000411c6a2003290300370200200041246a20062903003702002000412c6a2001290300370200200041346a20022903a0013702002000413c6a2004290300370200200041c4006a2005290300370200200041cc006a2007290300370200200041ec006a2011290300370200200041e4006a2009290300370200200041dc006a2008290300370200200041d4006a2002290378370200200241b0026a24000f0b200241023a00a001200241e8016a41226a200441226a2d00003a0000200241e8016a41206a200441206a2f00003b0100200241e8016a41186a200441186a290000370300200241e8016a41106a200441106a290000370300200241e8016a41086a200441086a290000370300200220042900003703e8010b0240200b422088a72201450d00200141246c2106200a21010340024020012d0000450d00200141086a280200450d00200141046a28020010010b200141246a21012006415c6a22060d000b0b200ba7450d00200a10010b20004100360208200241b0026a24000f0b1018000b201a41041019000b102e000b200641041019000b200341011019000bb50102027f027e230041106b220324000240200128020022044100480d00200441ffffffff07460d002001200441016a36020002400240200141046a200210f7012204450d002004280200450d00200441106a2903002105200441086a29030021060c010b200320012802102002200141146a280200280214110500200341086a2903002105200329030021060b20012001280200417f6a3602002000200537030820002006370300200341106a24000f0b10f801000bac0101067f20002802042102024003402000280200220341086a210420032f010622054105742106417f210002400240024003402006450d01200041016a2100417f410120012004412010d10222074100481b410020071b2207450d05200641606a2106200441206a210420074101460d000b20020d010c020b200521002002450d010b2002417f6a2102200320004102746a41f8066a21000c010b0b41000f0b2003200041306c6a41e8026a0b900101017f230041c0006b220024002000411836020c200041e5eac100360208200041286a410c6a4117360200200041106a410c6a4102360200200041246a41023602002000410136022c2000419888c10036021020004102360214200041a0d2c2003602182000200041086a3602282000200041386a3602302000200041286a360220200041106a41a888c1001065000b8e0b05027f017e0f7f027e067f230041a0036b22022400024020002802000d002000417f36020020024188016a41086a2203200141086a2802003602002002200129020037038801200241086a20024188016a10ea01200241306a41206a200241086a41206a280200360200200241306a41186a200241086a41186a290300370300200241306a41106a200241086a41106a290300370300200241306a41086a200241086a41086a2903003703002002200229030837033020024188016a200241306a10eb01024020022903a80122044202510d00200041046a2105200241a0026a41246a2106200241cc016a2107200241dc026a210120024188016a410472210820024188016a41306a210920024188016a41286a210a200241c0016a210b200241c4016a210c200241c8016a210d200241bc026a210e0340200241e8006a41186a220f20024188016a41186a290300370300200241e8006a41106a221020024188016a41106a2211290300370300200241e8006a41086a22122003290300370300200241d8006a41086a2213200741086a28020036020020022002290388013703682002200729020037035820092903002114200a2903002115200b2802002116200c2802002117200d2802002118200241d8016a41086a22192013280200360200200220022903583703d801200241e8016a41186a2213200f290300370300200241e8016a41106a221a2010290300370300200241e8016a41086a220f2012290300370300200220022903683703e80120024188016a2005200241e8016a108d0102400240024002402002280288014101470d002003280200201128020041306c6a221041e8026a2111024020044201520d0020114201370300201041f8026a2014370300201041f0026a20153703000b2016450d01024020104180036a2212280200221b450d00201241046a280200450d00201b10010b201220173602042012201636020020104188036a2018360200410121180c020b200241e8016a41306a200841306a280200360200200241e8016a41286a200841286a290200370300200241e8016a41206a200841206a2902003703002013200841186a290200370300201a200841106a290200370300200f200841086a290200370300200220082902003703e801200241a0026a41106a2014370300200241a0026a41086a2015370300200241a0026a41186a2016360200200e2017360200200241a0026a41206a2018360200200620022903d801370200200641086a2019280200360200200220043703a002200241e8016a200241a0026a1090011a0c020b410021180b200f2019280200360200200220022903d8013703e801200241a0026a200241e8016a108e01200241e8016a41206a200241a0026a41206a2802003602002013200241a0026a41186a290300370300201a200241a0026a41106a290300370300200f200241a0026a41086a290300370300200220022903a0023703e801200241e8026a200241e8016a10ed01024020022802e802450d00201141246a21120340200241d0026a41106a200241e8026a41106a290300370300200241d0026a41086a220f200241e8026a41086a2210290300370300200220022903e8023703d00220024190036a41086a200f280200360200200220022903d002370390032010200141086a280200360200200220012902003703e80220024180036a201220024190036a200241e8026a1091010240200228028003450d00200228028403220f450d0020024180036a41086a280200450d00200f10010b200241e8026a200241e8016a10ed0120022802e8020d000b0b200241e8016a108f012018201645720d002017450d00201610010b20024188016a200241306a10eb0120024188016a41206a29030022044202520d000b0b200241306a10ee012000200028020041016a360200200241a0036a24000f0b109201000bb50101027f230041106b220324000240200128020022044100480d00200441ffffffff07460d002001200441016a360200024002400240200141046a200210f7012204450d002004280218450d002003200441186a102d2003280200450d0120002003290300370200200041086a200341086a2802003602000c020b200341003602000b200020012802102002200141146a2802002802101105000b20012001280200417f6a360200200341106a24000f0b10f801000b34002000419becc10036020420004100360200200041086a4209370200200041106a4194b3c000360200200041146a41033602000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a41e0b4c000360200200041206a41013602000ba41102117f017e230041206b22022400200028020421032000280200210402402001280218220541222001411c6a280200220628021022071102000d00024002402003450d00200420036a21082006410c6a21092004210a41002101410021000240024002400340200a210b200a41016a210c02400240024002400240024002400240200a2c0000220d4100480d00200d41ff0171210d0c010b024002400240200c2008460d00200c2d0000413f71210e200a41026a220a210c200d411f71210f200d41ff0171220d41e001490d010c020b4100210e2008210a200d411f71210f200d41ff0171220d41e0014f0d010b200e200f41067472210d0c010b02400240200a2008460d00200a41016a220c2110200a2d0000413f71200e41067472210e200d41f001490d010c030b200821104100200e41067472210e200d41f0014f0d020b200e200f410c7472210d0b200c210a4102210c200d41776a220e411e4d0d010c020b0240024020102008460d00201041016a210a20102d0000413f71210d0c010b4100210d200c210a0b200e410674200f411274418080f0007172200d72220d418080c400460d0a4102210c200d41776a220e411e4b0d010b200d210f0240024002400240200e0e1f00020505010505050505050505050505050505050505050505060505050506000b41f400210f0c020b41f200210f0c010b41ee00210f0b0c020b200d210f200d41dc00460d010b0240200d10730d0002400240024002400240024002400240200d41ffff034b0d00200d4180fe0371410876211141caa3c100210f4100210e02400340200f41026a2112200e200f2d0001220c6a211002400240200f2d0000220f2011470d002010200e490d0a201041b0024f0d09200e419aa4c1006a210f0340200c450d02200c417f6a210c200f2d0000210e200f41016a210f200e200d41ff0171470d000c0d0b0b200f20114b0d022010210e2012210f2012419aa4c100470d010c020b2010210e2012210f2012419aa4c100470d000b0b200d41ffff037121104101210f41c9a6c100210c41caa6c100210e034002400240200c2d000022124118744118752211417f4c0d00200e210c201020126b221041004e0d010c040b200e4185a9c100460d06200e41016a210c2010201141ff0071410874200e2d0000726b22104100480d030b200c41016a210e200f410173210f200c4185a9c100470d000c020b0b200d41ffff074b0d06200d4180fe037141087621114185a9c100210f4100210e02400340200f41026a2112200e200f2d0001220c6a211002400240200f2d0000220f2011470d002010200e490d062010419f014f0d05200e41c7a9c1006a210f0340200c450d02200c417f6a210c200f2d0000210e200f41016a210f200e200d41ff0171470d000c0c0b0b200f20114b0d022010210e2012210f201241c7a9c100470d010c020b2010210e2012210f201241c7a9c100470d000b0b200d41ffff037121104101210f41e5aac100210c41e6aac100210e034002400240200c2d000022124118744118752211417f4c0d00200e210c201020126b22104100480d030c010b0240200e41e2adc100460d00200e41016a210c2010201141ff0071410874200e2d0000726b221041004e0d010c030b41a886c000104d000b200c41016a210e200f410173210f200c41e2adc100470d000b0b200f410171450d060c080b2010419e01106a000b200e2010106b000b41a886c000104d000b201041af02106a000b200e2010106b000b200d4190fc476a4190fc0b490d00200d41e28b746a41e28d2c490d00200d419fa8746a419f18490d00200d41dee2746a410e490d00200d41feffff0071419ef00a460d00200d41a9b2756a4129490d00200d41cb91756a410a4b0d020b200d41017267410276410773ad4280808080d0008421134103210c200d210f0b2002200336020420022004360200200220013602082002200036020c20002001490d0402402001450d0020012003460d00200120034f0d05200420016a2c000041bf7f4c0d050b02402000450d0020002003460d00200020034f0d05200420006a2c000041bf7f4c0d050b2005200420016a200020016b20092802001101000d030240034002400240024002400240200c41037122014101460d00024020014102460d0020014103470d072013422088a7410771417f6a220141044b0d07024020010e050006040503000b201342ffffffff8f60832113200541fd002007110200450d060c0a0b4101210c200541dc002007110200450d050c090b4100210c2005200f2007110200450d040c080b201342ffffffff8f60834280808080c000842113200541dc002007110200450d030c070b201342ffffffff8f6083428080808020842113200541fb002007110200450d020c060b201342ffffffff8f6083428080808030842113200541f5002007110200450d010c050b200f2013a7220e410274411c7176410f712201413072200141d7006a2001410a491b21010240200e450d002013427f7c42ffffffff0f83201342808080807083842113200520012007110200450d010c050b201342ffffffff8f6083428080808010842113200520012007110200450d000c040b0b410121010240200d418001490d0041022101200d418010490d0041034104200d41808004491b21010b200120006a21010b2000200b6b200a6a21002008200a470d000c050b0b200241206a240041010f0b200241206a240041010f0b2002200241086a3602142002200236021020022002410c6a360218200241106a1077000b410021010b2002200336020420022004360200200220013602082002200336020c0240024002402001450d0020032001460d00200320014d0d02200420016a22002c000041bf7f4c0d0220052000200320016b200628020c110100450d010c030b2005200420016a200320016b200628020c1101000d020b2005412220071102002100200241206a240020000f0b2002200241086a3602142002200236021020022002410c6a360218200241106a1077000b200241206a240041010ba50b01077f230041106b22022400200241003602082002420137030041ebefc10041042002102041efefc100410e200210200240024002400240024002400240024002400240024020022802042203200228020822046b41044f0d00200441046a22052004490d0420034101742206200520052006491b22074100480d042003450d0120022802002108200710002206450d072006200820072003200320074b1b10ce021a200810010c020b200441046a2105200228020021060c020b200710002206450d050b20022007360204200220063602000b200241086a22032005360200200620046a4101360000024002400240024020022802042207200328020022056b41044f0d00200541046a22032005490d0420074101742204200320032004491b22084100480d042008100021042007450d012004450d082004200620082007200720084b1b10ce021a200610010c020b200541046a2103200621040c020b2004450d060b20022008360204200220043602000b200241086a22062003360200200420056a4101360000024002400240024020022802042203200628020022066b41044f0d00200641046a22052006490d0420034101742207200520052007491b22084100480d042008100021072003450d012007450d092007200420082003200320084b1b10ce021a200410010c020b200641046a2105200421070c020b2007450d070b20022008360204200220073602000b200241086a22042005360200200720066a410036000002400240024002402002280204220620042802002205470d00200541016a22042005490d0420054101742206200420042006491b22064100480d042006100021032005450d012003450d0a2003200720062005200520064b1b10ce021a200710010c020b200541016a2104200228020021030c020b2003450d080b20022006360204200220033602000b200241086a2004360200200320056a41083a00000240024002400240200620046b41084f0d00200441086a22082004490d0420064101742205200820082005491b22054100480d042005100021072006450d012007450d052007200320052006200620054b1b10ce021a200310010c020b200441086a2108200321070c020b2007450d030b20022005360204200220073602000b200241086a22062008360200200720046a42e9dca1aba6ae99b7f400370000024002400240024020022802042207200628020022056b41044f0d00200541046a22062005490d0420074101742204200620062004491b22044100480d042007450d0120022802002108200410002203450d062003200820042007200720044b1b10ce021a200810010c020b200541046a210620022802002103200721040c020b200410002203450d040b20022004360204200220033602000b200241086a2006360200200320056a41013600000240024002400240200420066b41084f0d00200641086a22082006490d0420044101742205200820082005491b22054100480d042005100021072004450d012007450d052007200320052004200420054b1b10ce021a200310010c020b200641086a2108200321070c020b2007450d030b20022005360204200220073602000b200241086a22042008360200200720066a42f6c2b1cbc6ac98baf800370000024002400240024020022802042207200428020022036b41044f0d00200341046a22062003490d0420074101742204200620062004491b22044100480d042007450d0120022802002108200410002205450d062005200820042007200720044b1b10ce021a200810010c020b200341046a2106200228020021050c020b200410002205450d040b20022004360204200220053602000b200241086a2006360200200520036a4101360000200241106a24002006ad4220862005ad840f0b1018000b200541011019000b200441011019000b200741011019000b200841011019000b200841011019000b200641011019000bb410020b7f027e230041206b22022400200241003602182002420137031041c28cc2004105200241106a1020024002400240024002400240024002400240024002400240200228021420022802182203470d00200341016a22042003490d0420034101742205200420042005491b22064100480d042003450d0120022802102107200610002205450d0a2005200720062003200320064b1b10ce021a200710010c020b200341016a2104200228021021050c020b200610002205450d080b20022006360214200220053602100b200241106a41086a22082004360200200520036a41283a000041cccbc0002109034020092802002009280204200241106a1020200241086a200928020811000020022802082106024002400240024002400240024002400240024002400240024002400240024002400240024002400240200228020c2203413f4b0d00200228021420082802002204470d01200441016a22052004490d1620044101742207200520052007491b220a4100480d162004450d052002280210210b200a10002207450d172007200b200a20042004200a4b1b10ce021a200b10010c060b2003418080014f0d012002280214220a200828020022046b41024f0d02200441026a22052004490d15200a4101742207200520052007491b220b4100480d15200a450d092002280210210c200b10002207450d172007200c200b200a200a200b4b1b10ce021a200c10010c0a0b200441016a2105200228021021070c050b20034180808080044f0d012002280214220a200828020022046b41044f0d05200441046a22052004490d13200a4101742207200520052007491b220b4100480d13200a450d0a2002280210210c200b10002207450d162007200c200b200a200a200b4b1b10ce021a200c10010c0b0b200441026a2105200228021021070c080b200228021420082802002204470d04200441016a22052004490d1120044101742207200520052007491b220a4100480d112004450d0b2002280210210b200a10002207450d152007200b200a20042004200a4b1b10ce021a200b10010c0c0b200a10002207450d110b2002200a360214200220073602100b20082005360200200720046a20034102743a000020030d0b0c0c0b200441046a2105200228021021070c060b200441016a2105200228021021070c080b200b10002207450d0d0b2002200b360214200220073602100b20082005360200200720046a20034102744101723b00000c060b200b10002207450d0b0b2002200b360214200220073602100b20082005360200200720046a20034102744102723600000c030b200a10002207450d090b2002200a360214200220073602100b20082005360200200720046a41033a000002400240024002402002280214220a200828020022046b41044f0d00200441046a22052004490d07200a4101742207200520052007491b220b4100480d07200a450d012002280210210c200b10002207450d0c2007200c200b200a200a200b4b1b10ce021a200c10010c020b200441046a2105200228021021070c020b200b10002207450d0a0b2002200b360214200220073602100b20082005360200200720046a20033600000b2003412c6c2107410021040340200620046a220341046a280200200341086a280200200241106a1020200341106a2802002105024002402003410c6a2802004101470d002005200341186a280200200241106a10280c010b2005200341146a280200200241106a10280b200341206a280200210502402003411c6a2802004101470d002005200341286a280200200241106a102820072004412c6a2204470d010c020b2005200341246a280200200241106a102820072004412c6a2204470d000b0b2009410c6a220941c4ccc000470d000b02400240024002402002280214200241186a2802002203470d00200341016a22042003490d0420034101742205200420042005491b22064100480d042003450d0120022802102107200610002205450d0b2005200720062003200320064b1b10ce021a200710010c020b200341016a2104200228021021050c020b200610002205450d090b20022006360214200220053602100b200241106a41086a22062004360200200520036a41303a000041c78cc2004106200241106a1020200241106a41d0ccc0001022200241106a41fcccc000101e41cd8cc2004109200241106a1020200241106a41a8cdc0001022200241106a41d4cdc000101e41d68cc2004108200241106a1020200241106a4180cec0001022200241106a41accec000101e41de8cc2004109200241106a1020200241106a41d8cec0001022200241106a4184cfc000101e41e78cc2004107200241106a1020200241106a41b0cfc0001022200241106a41dccfc000101e41ee8cc2004107200241106a1020200241106a4188d0c0001022200241106a41b4d0c000101e41f58cc2004109200241106a1020200241106a41e0d0c0001022200241106a418cd1c000101e41fe8cc2004107200241106a1020200241106a41b8d1c0001022200241106a41e4d1c000101e41858dc200410e200241106a1020200241106a4190d2c0001022200241106a41bcd2c000101e41938dc200410f200241106a1020200241106a41e8d2c0001022200241106a4194d3c000101e41a28dc2004108200241106a1020200241106a41c0d3c0001022200241106a41ecd3c000101e41aa8dc2004108200241106a1020200241106a4198d4c0001022200241106a41c4d4c000101e2006350200210d2002350210210e200241206a2400200e200d422086840f0b1018000b200a41011019000b200b41011019000b200b41011019000b200a41011019000b200b41011019000b200641011019000b200641011019000b9705020a7f017e230041206b22022400024002400240024002400240410610002203450d002002200336021020024206370214200241106a41d1aac20041061029200241086a2203200228021836020020022002290310370300200241b7acc200410310292002280204210420022802002205200328020010f201210302402004450d00200510010b200241106a41002003103f200228021021060240024002400240024020022802182203413f4b0d0041012105410110002207450d06200720034102743a00004101210820030d010c020b02402003418080014f0d0041022105410210002207450d07200720034102744101723b00000c010b024020034180808080044f0d0041042105410410002207450d08200720034102744102723600000c010b410110002204450d08200441033a000041052105410510002207450d09200720042d00003a000020041001200720033600010b20034105742109200521042006210303400240024002400240200520046b41204f0d00200441206a22082004490d062005410174220a20082008200a491b220a4100480d062005450d01200a1000220b450d07200b2007200a20052005200a4b1b10ce02210520071001200521070c020b200441206a21080c020b200a10002207450d050b200a21050b200720046a22042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a29000037000020082104200341206a2103200941606a22090d000b0b2008ad4220862007ad84210c02402002280214450d00200610010b200241206a2400200c0f0b1018000b200a41011019000b410641011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000bd50201017f23004180026b22022400024002402001450d00200220003602000c010b200241b8d6c2003602000b2002200136020420024188016a200210f5010240200228029001450d00200241086a20024188016a41f80010ce021a20024188016a200241086a41f80010ce021a20024188016a2002419c016a200241dc016a108202024020024198016a2802002200450d002002280290012101200041246c21000340024020012d0000450d00200141086a280200450d00200141046a28020010010b200141246a21012000415c6a22000d000b0b024020024194016a280200450d0020024190016a28020010010b20024180026a240042010f0b200241146a41013602002002411c6a41013602002002410136028401200241c0b6c00036028001200241c8b6c0003602082002410136020c200241c0c5c200360210200220024180016a360218200241086a41d0b6c0001065000b801d03017f017e267f230041e00d6b220324002003410036022041fdabc2004110200341206a41041003200320002903002204370320200341106a41086a220042003703002003420037031041dcacc200410d200341106a1002200341086a220520002903003703002003200329031037030020034110200341206a41081003200042003703002003420037031041e9acc2004111200341106a100220052000290300370300200320032903103703002003411020014120100302400240024002400240411010002200450d002003200036022020034210370224200341206a41c7acc200411010292003280220210502400240024002400240024002400240024020032802242206200328022822006b41084f0d00200041086a22072000490d0320064101742208200720072008491b22084100480d032006450d01200810002209450d0d2009200520082006200620084b1b10ce0221092005100120082106200921050c020b200041086a21070c010b200810002205450d0b200821060b200520006a2004427f7c370000200341106a41086a220042003703002003420037031020052007200341106a1002200341086a22072000290300370300200320032903103703002003411020014120100302402006450d00200510010b200042003703002003420037031041faacc2004115200341106a1002200720002903003703002003200329031037030020034110200241201003200042003703002003420037031041dcacc200410d200341106a100220072000290300370300200320032903103703002003411041b8d6c200410041001004417f460d072003420037032020034110200341206a41084100100441016a41084d0d0420032903204200510d08200341106a41086a220042003703002003420037031041dcacc200410d200341106a1002200341086a2000290300370300200320032903103703002003411041b8d6c200410041001004417f460d092003420037032020034110200341206a41084100100441016a41084d0d0520032903202104200341206a410041e00c10d0021a2004427f7c2104200341c00d6a41186a210a410021094100210b4100210c4100210d4100210e4100210f410021104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f41002120410021214100212241002123410021244100212541002126410021274100212841002108410021290240034020292106411010002200450d03200320003602c00d200342103702c40d200341c00d6a41c7acc2004110102920032802c00d2100024002400240024020032802c40d2205200341c00d6a41086a220228020022016b41084f0d00200141086a22072001490d0620054101742229200720072029491b22294100480d062005450d0120291000222a450d09202a200020292005200520294b1b10ce02210520001001200521000c020b200141086a21070c020b202910002200450d070b202921050b200020016a42002004427f7c2004501b2204370000200341106a41086a220142003703002003420037031020002007200341106a1002200341086a2001290300370300200320032903103703002003411041b8d6c200410041001004417f460d04200a4200370300200341c00d6a41106a2201420037030020024200370300200342003703c00d20034110200341c00d6a4120410010042207417f460d012007411f4d0d01200341a00d6a41186a2207200a290300370300200341a00d6a41106a222a2001290300370300200341a00d6a41086a22012002290300370300200320032903c00d3703a00d02402005450d00200010010b200641016a2129200341800d6a41186a22052007290300370300200341800d6a41106a2207202a290300370300200341800d6a41086a22022001290300370300200320032903a00d3703800d200341206a20064103704105746a220041186a2005290300370000200041106a2007290300370000200041086a2002290300370000200020032903800d3700004100210541002107024003402006200641036e2201417d6c6a4102470d01200341206a20056a220041df006a2d000022082000411f6a2d000022027120082002722000413f6a2d000071722109200041de006a2d000022082000411e6a2d000022027120082002722000413e6a2d00007172210b200041dd006a2d000022082000411d6a2d000022027120082002722000413d6a2d00007172210c200041dc006a2d000022082000411c6a2d000022027120082002722000413c6a2d00007172210d200041db006a2d000022082000411b6a2d000022027120082002722000413b6a2d00007172210e200041da006a2d000022082000411a6a2d000022027120082002722000413a6a2d00007172210f200041d9006a2d00002208200041196a2d00002202712008200272200041396a2d000071722110200041d8006a2d00002208200041186a2d00002202712008200272200041386a2d000071722111200041d7006a2d00002208200041176a2d00002202712008200272200041376a2d000071722112200041d6006a2d00002208200041166a2d00002202712008200272200041366a2d000071722113200041d5006a2d00002208200041156a2d00002202712008200272200041356a2d000071722114200041d4006a2d00002208200041146a2d00002202712008200272200041346a2d000071722115200041d3006a2d00002208200041136a2d00002202712008200272200041336a2d000071722116200041d2006a2d00002208200041126a2d00002202712008200272200041326a2d000071722117200041d1006a2d00002208200041116a2d00002202712008200272200041316a2d000071722118200041d0006a2d00002208200041106a2d00002202712008200272200041306a2d000071722119200041cf006a2d000022082000410f6a2d000022027120082002722000412f6a2d00007172211a200041ce006a2d000022082000410e6a2d000022027120082002722000412e6a2d00007172211b200041cd006a2d000022082000410d6a2d000022027120082002722000412d6a2d00007172211c200041cc006a2d000022082000410c6a2d000022027120082002722000412c6a2d00007172211d200041cb006a2d000022082000410b6a2d000022027120082002722000412b6a2d00007172211e200041ca006a2d000022082000410a6a2d000022027120082002722000412a6a2d00007172211f200041c9006a2d00002208200041096a2d00002202712008200272200041296a2d000071722120200041c8006a2d00002208200041086a2d00002202712008200272200041286a2d000071722121200041c7006a2d00002208200041076a2d00002202712008200272200041276a2d000071722122200041c6006a2d00002208200041066a2d00002202712008200272200041266a2d000071722123200041c5006a2d00002208200041056a2d00002202712008200272200041256a2d000071722124200041c4006a2d00002208200041046a2d00002202712008200272200041246a2d000071722125200041c3006a2d00002208200041036a2d00002202712008200272200041236a2d000071722126200041c2006a2d00002208200041026a2d00002202712008200272200041226a2d000071722127200041c1006a2d00002208200041016a2d00002202712008200272200041216a2d000071722128200041c0006a2d0000220820002d00002202712008200272200041206a2d000071722108200541800c460d01200341206a20052001410574200641096e41e0006c6b6a6a220041e1006a20283a0000200041e0006a20083a0000200041e2006a20273a0000200041e3006a20263a0000200041e4006a20253a0000200041e5006a20243a0000200041e6006a20233a0000200041e7006a20223a0000200041e8006a20213a0000200041e9006a20203a0000200041ea006a201f3a0000200041eb006a201e3a0000200041ec006a201d3a0000200041ed006a201c3a0000200041ee006a201b3a0000200041ef006a201a3a0000200041f0006a20193a0000200041f1006a20183a0000200041f2006a20173a0000200041f4006a20153a0000200041f3006a20163a0000200041f5006a20143a0000200041f6006a20133a0000200041f7006a20123a0000200041f8006a20113a0000200041f9006a20103a0000200041fa006a200f3a0000200041fb006a200e3a0000200041fc006a200d3a0000200041fd006a200c3a0000200041fe006a200b3a0000200041ff006a20093a0000200541e0006a210520012106200741016a22074111490d000b0b202941d100490d000b200320283a00c10d200320083a00c00d200320273a00c20d200320263a00c30d200320253a00c40d200320243a00c50d200320233a00c60d200320223a00c70d200320213a00c80d200320203a00c90d2003201f3a00ca0d2003201e3a00cb0d2003201d3a00cc0d2003201c3a00cd0d2003201b3a00ce0d2003201a3a00cf0d200320193a00d00d200320183a00d10d200320173a00d20d200320153a00d40d200320163a00d30d200320143a00d50d200320133a00d60d200320123a00d70d200320113a00d80d200320103a00d90d2003200f3a00da0d2003200e3a00db0d2003200d3a00dc0d2003200c3a00dd0d2003200b3a00de0d200320093a00df0d200341106a41086a2200420037030020034200370310418fadc2004111200341106a1002200341086a220520002903003703002003200329031037030020034110200341c00d6a412010032000420037030020034200370310418dacc200410d200341106a1002200520002903003703002003200329031037030020034110100a200341e00d6a24000f0b41b2eac10041331040000b1018000b411041011019000b41c3d7c10041221040000b202941011019000b41b2eac10041331040000b41b2eac10041331040000b411041011019000b41c3d7c10041221040000b41ace9c000104d000b41c3d7c10041221040000b200841011019000b9307010a7f230041b00a6b22022400024002402001450d00200220003602100c010b200241b8d6c2003602100b20022001360214200241f8066a200241106a10a401024002400240024002400240024002400240024020022903e8074203510d00200241186a200241f8066a41a80310ce021a200241c0036a200241186a41a80310ce021a2002200241c0036a3602f806200241e8066a200241f8066a10cf0120022802ec06210320022802e806210420022802f0062105200241086a10f30120022802082106200228020c2107411410002201450d01200220013602f806200242143702fc06200241f8066a41eeadc2004114102920022802f806210102400240024020022802fc06220820022802800722006b41044f0d00200041046a22092000490d052008410174220a20092009200a491b220a4100480d052008450d01200a1000220b450d06200b2001200a20082008200a4b1b10ce02210820011001200821010c020b200041046a21092008210a0c010b200a10002201450d040b200120006a2007410020061b3600002002410036028007200242013703f80620042005200241f8066a102020022802fc062108200228028007210620022802f8062100200241f8066a41086a22074200370300200242003703f80620012009200241f8066a1002200241a00a6a41086a2007290300370300200220022903f8063703a00a200241a00a6a411020002006100302402008450d00200010010b0240200a450d00200110010b02402003450d00200410010b200241f8066a200241c0036a41a80310ce021a200241a00a6a200241f8066a20051084020240024020022802a00a4101470d00418286800820022802a40a41037441107376210841011000210141010d010c080b20022802a40a41004721084101100021014100450d070b2001450d04200141013a0000410210002200450d05200020012d00003a00000c070b200241cc036a4101360200200241d4036a41013602002002410136021c200241c0b6c000360218200241c8b6c0003602c003200241013602c403200241c0c5c2003602c8032002200241186a3602d003200241c0036a41d0b6c0001065000b411441011019000b1018000b200a41011019000b410141011019000b410241011019000b2001450d01200141003a0000410210002200450d02200020012d00003a00000b20011001200020083a0001200241b00a6a24002000ad428080808020840f0b410141011019000b410241011019000bcd0c05017f017e027f017e047f230041b00e6b22032400200341c80a6a200141a80310ce021a200341f0076a200341c80a6a10a701024020032802f0074101470d0020032902f4072104200341e0026a200341a8056a41c80210ce021a200041086a200437020020004201370200200341b00e6a24000f0b200341f0076a41086a2903002104200341a8056a200341f0076a41106a41c80210ce021a200341e0026a200341a8056a41c80210ce021a20032004370310410021050240024002400240200341106a41086a200341e0026a41c80210ce0222014100200329031022044201511b2206450d002006450d000240024002402006109002220420062903202207520d0020062002109302450d0220004281808080303702000c010b2000410136020020004101410220072004541b3602040b200341c0006a102c200341b00e6a24000f0b411310002202450d02200320023602c80a200342133702cc0a200341c80a6a41eaabc20041131029200341f0076a41086a220220032802d00a360200200320032903c80a3703f0072006200341f0076a101b2002280200210820032802f407210920032802f007210a200341c80a6a41086a220b4200370300200342003703c80a200a2008200341c80a6a10022002200b290300370300200320032903c80a3703f007024002400240200341f0076a411041b8d6c200410041001004417f460d00200342003703c80a200341f0076a4110200341c80a6a41084100100441016a41084d0d0420032903c80a42017c210420090d010c020b420121042009450d010b200a10010b411310002202450d03200320023602c80a200342133702cc0a200341c80a6a41eaabc20041131029200341f0076a41086a220220032802d00a360200200320032903c80a3703f0072006200341f0076a101b2002280200210a20032802f407210820032802f0072106200320043703a805200341c80a6a41086a22094200370300200342003703c80a2006200a200341c80a6a100220022009290300370300200320032903c80a3703f007200341f0076a4110200341a8056a4108100302402008450d00200610010b200329031021040b200341c80a6a200341386a41a80210ce021a200341f0076a200341c80a6a41086a41a00210ce021a200341a8056a41186a2206200141186a290300370300200341a8056a41106a200141106a290300370300200341a8056a41086a200141086a290300370300200320012903003703a805024020044201520d00200341e0026a41186a2006290300370300200341e0026a41106a200341a8056a41106a290300370300200341e0026a41086a200341a8056a41086a290300370300200320032903a8053703e002410121050b200341a8056a200341f0076a41a00210ce021a200341900e6a41186a220a200341e0026a41186a290300370300200341900e6a41106a2208200341e0026a41106a2201290300370300200341900e6a41086a2209200341e0026a41086a2202290300370300200320032903e0023703900e200341f0076a200341a8056a41a00210ce021a200341f00d6a41186a220b200a290300370300200341f00d6a41106a220a2008290300370300200341f00d6a41086a22082009290300370300200320032903900e3703f00d200341c80a6a200341f0076a41a00210ce021a2006200b290300370300200341a8056a41106a2209200a290300370300200341a8056a41086a220a2008290300370300200320032903f00d3703a8054102210602402005450d00200341e0026a41186a200341a8056a41186a290300370300200120092903003703002002200a290300370300200320032903a8053703e002410121060b200341b2056a2002290300370100200341ba056a2001290300370100200341c2056a200341f8026a290300370100200320063a00a905200341003a00a805200320032903e0023701aa05200341086a200341c80a6a200341a8056a10ab02200328020c210620032802082101200341003a00c80a200320014100473a00c90a200341c80a6a10a101200310f3012003200328020441016a410120032802001b3602c80a41fdabc2004110200341c80a6a41041003024002402001450d00200020013602040c010b200041003602040b20004100360200200041086a2006360200200341b00e6a24000f0b41b2eac10041331040000b411341011019000b411341011019000b921a06047f017e017f027e047f027e230041800d6b22022400024002402001450d00200220003602100c010b200241b8d6c2003602100b20022001360214200241d8096a200241106a10f501200241e8096a280200210320022802e409210420022802e009210520022903d8092106200241b0056a200241ec096a41e40010ce021a024002400240024002400240024002400240024002400240024002400240024002400240024002402005450d00200241b8046a200241b0056a41e40010ce021a200241086a200241106a103302402002280208450d00200228020c2207ad220842a8037e2209422088a70d092009a72201417f4c0d0902400240024002402001450d00200110002200450d1020070d010c020b410821002007450d010b200241d8096a41f8006a210a4100210b0340200241d8096a200241106a10a401200241e8086a200241d8096a41f00010ce021a200241d8096a41f0006a290300210920024188026a200a41b00210ce021a20094203510d0220024180016a200241e8086a41f00010ce021a200241b0056a20024188026a41b00210ce021a02402008422088a722012008a7470d00200141016a220c2001490d0a2001410174220d200c200c200d491bad220e42a8037e220f422088a70d0a200fa7220c4100480d0a024002402001450d00200c1000220d450d0d200d2000200c200141a8036c22012001200c4b1b10ce02210120001001200121000c010b200c10002200450d0c0b200842808080807083200e8421080b20002008422088a741a8036c6a20024180016a41f00010ce0222012009370370200141f8006a200241b0056a41b00210ce021a20084280808080107c2108200b41016a220b2007490d000b0b2000450d01200241d8096a200241b8046a41e40010ce021a2005450d022002411c6a200241d8096a41e40010ce021a2002418c016a200436020020024180016a41106a20033602002002200536028801200220063703800120024194016a2002411c6a41e40010ce02210c200241fc016a2008370200200220003602f80120024180016a200c200241d4016a22051082022002290380012208500d0f411010002201450d10200220013602d809200242103702dc09200241d8096a41c7acc2004110102920022802d809210120022802dc09220020022802e009220b6b41084f0d03200b41086a2207200b490d072000410174220a20072007200a491b220a4100480d072000450d04200a1000220d450d11200d2001200a20002000200a4b1b10ce02210020011001200021010c050b02402008422088a72201450d00200141a8036c210b20004188016a210103402001102c200141a8036a2101200b41d87c6a220b0d000b0b2008a7450d00200010010b02402003450d00200341246c2100200521010340024020012d0000450d00200141086a280200450d00200141046a28020010010b200141246a21012000415c6a22000d000b0b2004450d00200510010b200241bc056a4101360200200241c4056a41013602002002410136028c02200241c0b6c00036028802200241c8b6c0003602b005200241013602b405200241c0c5c2003602b805200220024188026a3602c005200241b0056a41d0b6c0001065000b200b41086a21070c020b200a10002201450d0c0b200a21000b2001200b6a2008427f7c370000200241d8096a41086a220b4200370300200242003703d80920012007200241d8096a100220024188026a41086a200b290300370300200220022903d8093703880220024188026a411041b8d6c200410041001004417f460d0b200241c8056a4200370300200241b0056a41106a4200370300200241b0056a41086a4200370300200242003703b00520024188026a4110200241b0056a412041001004220b417f460d07200b411f4d0d07200241d8096a41186a200241b0056a41186a290300370300200241d8096a41106a200241b0056a41106a290300370300200241d8096a41086a200241b0056a41086a290300370300200220022903b0053703d80902402000450d00200110010b200241d8096a200c412010d1020d0802400240024020024180026a280200220d450d00200dad420c7e2208422088a70d032008a722014100480d03200241f8016a280200210020011000220a450d0f200d41a8036c210c4100210b200a210103402002200036028802200241d8096a20024188026a10cf0120022802d809450d03200041a8036a2100200241b0056a41086a2207200241d8096a41086a280200360200200220022903d8093703b005200141086a2007280200360200200120022903b005370200200b41016a210b2001410c6a2101200c41d87c6a220c0d000c020b0b4104210a4100210d4100210b0b200241003602d8090b200241b0056a200a200a200b410c6c6a1041200241d8096a20022802b005220120022802b805105f024020022802b405450d00200110010b0240200b450d00200b410c6c2100200a210103400240200141046a280200450d00200128020010010b2001410c6a2101200041746a22000d000b0b0240200d450d00200a10010b02402005200241d8096a412010d102450d0041dfa0c100410e1006200541201012200241d8096a412010120b200241d4016a200241d8096a412010d1020d0d200241fc016a280200210d20024180016a41f8006a280200210a20024180026a280200210b200241b8046a20024180016a41f80010ce021a200a200b41a8036c6a2100200a21010240024002400240200b450d00200241b0056a41f8006a210c200241d8096a41086a2107200a21010340200241e8086a200141f00010ce021a200141f0006a290300210820024188026a200141f8006a41b00210ce021a20084203510d02200241b0056a200241e8086a41f00010ce021a200241b0056a41f0006a2008370300200c20024188026a41b00210ce021a2002200241b0056a3602d808200241d8096a200241d8086a10cf012007280200210b024020022802dc09450d0020022802d80910010b200241d8096a200241b0056a41a80310ce021a200241d8086a200241d8096a200b10840220022802d8084101460d07024020022802dc08220b450d00200b200241d8086a41086a28020010060b200141a8036a22012000470d000b200021010b20012000470d010c020b200141a8036a22012000460d010b200241e00a6a210b200241d8096a41f8006a210c034020024188026a200141f00010ce021a200141f0006a2903002108200241d8096a200141f8006a41b00210ce021a20084203510d01200241e8086a20024188026a41f00010ce021a200241b0056a200241d8096a41b00210ce021a200241d8096a200241e8086a41f00010ce021a200241d8096a41f0006a2008370300200c200241b0056a41b00210ce021a200b102c200141a8036a22012000470d000b0b0240200d450d00200a10010b10860220022903b804108702200241d8096a1088020240200241b8046a41106a2802002205200241d8096a41106a280200470d0020022802e009210a02402005450d0020022802c004210d410021070340200d200741246c22006a22012d0000220b200a20006a22002d0000470d02024002400240200b4101470d002001410c6a280200220c2000410c6a280200470d05200c450d02200141046a2802002201200041046a2802002200460d014100210b034020012000412010d1020d06200141206a2101200041206a2100200b41016a220b200c490d000c030b0b200d200a460d01200141016a200041016a412010d102450d010c040b410021010340200141016a2201200c490d000b0b200741016a22072005490d000b0b200241b0056a41186a22014200370300200241b0056a41106a22004200370300200241b0056a41086a220b4200370300200242003703b005200241b0056a101320024188026a41186a200129030037030020024188026a41106a200029030037030020024188026a41086a200b290300370300200220022903b005370388020240200241ec046a220120024188026a412010d102450d0041dfa0c100410e100620014120101220024188026a412010120b200120024188026a412010d1020d0f02402005450d00200541246c2100200a21010340024020012d0000450d00200141086a280200450d00200141046a28020010010b200141246a21012000415c6a22000d000b0b0240200241e4096a280200450d00200a10010b0240200241c8046a2802002200450d00200241b8046a41086a2802002101200041246c21000340024020012d0000450d00200141086a280200450d00200141046a28020010010b200141246a21012000415c6a22000d000b0b0240200241c4046a280200450d00200241c0046a28020010010b200241800d6a240042010f0b4180ffc000104d000b1018000b200c41081019000b20022802dc082201450d0120014103460d0241b8fec000104d000b102e000b41e8fec000104d000b41d0fec000104d000b200141081019000b41b2eac10041331040000b4188fec000104d000b411041011019000b200a41011019000b41c3d7c10041221040000b200141041019000b41a0fec000104d000b4198ffc000104d000bd40101037f230041306b2200240002400240024041fdabc200411041b8d6c200410041001004417f460d00200041003602204101210141fdabc2004110200041206a41044100100441016a41044d0d022000280220210241fdabc2004110100a0c010b410021010b20002002410020011b36020c200041206a41086a220142003703002000420037032041e0afc2004115200041206a1002200041106a41086a200129030037030020002000290320370310200041106a41102000410c6a41041003200041306a24000f0b41b2eac10041331040000b9d8b010a037f017e047f017e017f037e0e7f087e057f207e230041c00d6b2201240020014180036a41086a220242003703002001420037038003419aacc200411d20014180036a1002200141f0026a41086a200229030037030020012001290380033703f002024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141f0026a411041b8d6c200410041001004417f460d00200142103702f4052001200141f0026a3602f005200141f00a6a200141f0056a103620012802f00a2203450d0120012902f40a210420014180036a41086a220242003703002001420037038003419aacc200411d20014180036a100220014190036a41086a200229030037030020012001290380033703900320014190036a4110100a410610002202450d02200120023602f00a200142063702f40a200141f00a6a41d1aac20041061029200141f0056a41086a220220012802f80a360200200120012903f00a3703f005200141f0056a41b7acc2004103102920012802f405210520012802f0052206200228020010f201210202402005450d00200610010b200141d00a6a41002002103f0240024002400240024002400240024020012802d80a22062004422088a7470d0020012802d00a21072006450d0220072003460d01410021082007210220032105034020022005412010d1020d01200241206a2102200541206a2105200841016a22082006490d000c030b0b200141fb0a6a200141d00a6a41086a280200360000200120012903d00a3700f30a200120012900f00a3703d0032001200141f70a6a2900003700d7034200210920014190036a41086a22024200370300200142003703900341baacc200410d20014190036a100220014180036a41086a20022903003703002001200129039003370380030240024020014180036a411041b8d6c200410041001004417f460d00200142103702f405200120014180036a3602f005200141f00a6a200141f0056a103420012802f00a2205450d0d20012902f40a21090c010b410421050b200141f00a6a41086a2208200141f0056a41086a290200370300200141f00a6a41106a2207200141f0056a41106a280200360200200120012900d7033700b708200120012903d0033703b008200120012902f0053703f00a02402009422088a722022009a7470d00200241016a22062002490d292002410174220a20062006200a491bad220b42247e220c422088a70d29200ca7220a4100480d292002450d03200a10002206450d0d20062005200a200241246c22022002200a4b1b10ce021a200510010c040b200521060c040b410021020340200241016a22022006490d000b0b20012802d40a450d03200710012004a70d040c050b200a10002206450d090b200942808080807083200b8421090b20062009422088220ba741246c6a220241013a0000200241086a20012900b708370000200220012903b008370001200241106a20012903f00a370200200241186a2008290300370200200241206a20072802003602002001200942ffffffff0f83200b42017c220b422086843702b408200120063602b008200141003602f80a200142013703f00a200141f00a6a200141b0086a102420012802f40a210820012802f80a210520012802f00a210220014190036a41086a22074200370300200142003703900341baacc200410d20014190036a100220014180036a41086a200729030037030020012001290390033703800320014180036a4110200220051003200ba7210502402008450d00200210010b2009a7210802402005450d00200541246c2105200621020340024020022d0000450d00200241086a280200450d00200241046a28020010010b200241246a21022005415c6a22050d000b0b2008450d00200610010b2004a7450d010b200310010b20014180036a41086a2202420037030020014200370380034195ebc100411320014180036a1002200141f0026a41086a200229030037030020012001290380033703f0020240024002400240200141f0026a411041b8d6c200410041001004417f460d00200141003a00f00a200141f0026a4110200141f00a6a41014100100441016a41014d0d0120012d00f00a21054200210920014180036a41086a2202420037030020014200370380034195ebc100411320014180036a100220014190036a41086a200229030037030020012001290380033703900320014190036a4110100a2005450d0020024200370300200142003703800341e5d7c100411820014180036a1002200141f0026a41086a200229030037030020012001290380033703f00202400240200141f0026a411041b8d6c200410041001004417f460d00200142003703f00a200141f0026a4110200141f00a6a41084100100441016a41084d0d0120012903f00a21090b20014180036a41086a22024200370300200142003703800341fdd7c100411520014180036a1002200141f0026a41086a200229030037030020012001290380033703f002200141f0026a411041b8d6c200410041001004417f460d03200142003703f00a0240200141f0026a4110200141f00a6a41084100100441016a41084d0d0020012903f00a22044200510d0520014180036a41086a2202420037030020014200370380034192d8c100411920014180036a1002200141f0026a41086a200229030037030020012001290380033703f002200020097d200482210b0240200141f0026a411041b8d6c200410041001004417f460d00200141003a00f00a200141f0026a4110200141f00a6a41014100100441016a41014d0d0920012d00f00a210220014180036a41086a2205420037030020014200370380034192d8c100411920014180036a100220014190036a41086a200529030037030020012001290380033703900320014190036a4110100a200241004721050c0c0b200b4200520d0c410121050c0b0b41b2eac10041331040000b41b2eac10041331040000b41fcb2c000104d000b41b2eac10041331040000b41c3d7c10041221040000b4194a4c000104d000b41b2eac10041331040000b410641011019000b41b2eac10041331040000b41b2eac10041331040000b200a41041019000b20014180036a41086a22024200370300200142003703800341c6edc100410d20014180036a100220014190036a41086a200229030037030020012001290380033703900320014190036a411041b8d6c200410041001004417f460d0e200142003703f00a20014190036a4110200141f00a6a41084100100441016a41084d0d0620012903f00a210920014180036a41086a22024200370300200142003703800341abd8c100411420014180036a1002200141f0026a41086a200229030037030020012001290380033703f002200141f0026a411041b8d6c200410041001004417f460d0f200142003703f00a200141f0026a4110200141f00a6a41084100100441016a41084d0d0720012903f00a210c20014180036a41086a22024200370300200142003703800341bfd8c100411420014180036a1002200141f0026a41086a200229030037030020012001290380033703f002200141f0026a411041b8d6c200410041001004417f460d10200142003703f00a200141f0026a4110200141f00a6a41084100100441016a41084d0d08200141f00a6a41086a20012903f00a42017c2204370300200141023a00f00a200141f00a6a10a101200120043703f00a4200210420014180036a41086a22024200370300200142003703800341bfd8c100411420014180036a100220014190036a41086a2206200229030037030020012001290380033703900320014190036a4110200141f00a6a41081003200120093703f00a20024200370300200142003703800341abd8c100411420014180036a10022006200229030037030020012001290380033703900320014190036a4110200141f00a6a4108100320024200370300200142003703800341d3d8c100411920014180036a1002200141f0026a41086a200229030037030020012001290380033703f00202400240200141f0026a411041b8d6c200410041001004417f460d00200142003703f00a200141f0026a4110200141f00a6a41084100100441016a41084d0d0c20012903f00a210d20014180036a41086a22024200370300200142003703800341d3d8c100411920014180036a100220014190036a41086a200229030037030020012001290380033703900320014190036a4110100a420121040c010b0b2009200c7d21090240024002402004a74101470d002001200d3703f00a20014180036a41086a22024200370300200142003703800341fdd7c100411520014180036a100220014190036a41086a200229030037030020012001290380033703900320014190036a4110200141f00a6a410810030c010b200b500d010b200110ac013703f00a20014180036a41086a22024200370300200142003703800341e5d7c100411820014180036a100220014190036a41086a200229030037030020012001290380033703900320014190036a4110200141f00a6a410810030b2009200510940220014180036a41086a22024200370300200142003703800341ecd8c100411220014180036a1002200141f0026a41086a200229030037030020012001290380033703f002200141f0026a411041b8d6c200410041001004417f460d11200142103702f4052001200141f0026a3602f005200141f00a6a200141f0056a103920012802f00a220e450d12024020012902f40a220c422088a72202450d002002410574210f200e2107410021030340411210002202450d04200120023602f00a200142123702f40a200141f00a6a41fed8c10041121029200141f0056a41086a2202200141f00a6a41086a2205280200360200200120012903f00a3703f0052007200141f0056a101b2002280200211220012802f405211320012802f005210620014180036a41086a2208420037030020014200370380032006201220014180036a1002200141f0026a41086a200829030037030020012001290380033703f00202400240200141f0026a411041b8d6c200410041001004417f460d00200141b0086a41186a220a4200370300200141b0086a41106a22104200370300200141b0086a41086a22114200370300200142003703b008200141f0026a4110200141b0086a4120410010042214417f460d052014411f4d0d05200141f0056a41186a2214200a290300370300200141f0056a41106a2215201029030037030020022011290300370300200120012903b0083703f005200141f00a6a41186a221620142903002209370300200141f00a6a41106a22172015290300220437030020052002290300220b370300200141d0036a41086a2218200b370300200141d0036a41106a22192004370300200141d0036a41186a221a2009370300200120012903f00522093703d003200120093703f00a2008420037030020014200370380032006201220014180036a100220014190036a41086a2212200829030037030020012001290380033703900320014190036a4110100a20014190036a41186a2208201a29030037030020014190036a41106a221b201929030037030020122018290300370300200120012903d0033703900302402013450d00200610010b201a20082903003703002019201b2903003703002018201229030037030020012001290390033703d003200120033602b008410610002206450d08200120063602f00a200142063702f40a200141f00a6a41d1aac2004106102920022005280200360200200120012903f00a3703f005200141f0056a200141b0086a4104102920012802f405210802400240024020012802f00522062002280200221241b8d6c200410041001004417f470d00200a42003703002010420037030020114200370300200142003703b00820080d010c020b200a42003703002010420037030020114200370300200142003703b00820062012200141b0086a4120410010042212417f460d092012411f4d0d092016200a2903003703002017201029030037030020052011290300370300200120012903b0083703f00a200141b0036a41186a20162903002209370300200141b0036a41106a20172903002204370300200141b0036a41086a2005290300220b370300200141d00a6a41086a2212200b370300200141d00a6a41106a22132004370300200141d00a6a41186a22182009370300200120012903f00a22093703d00a200120093703b003201420182903003703002015201329030037030020022012290300370300200120012903d00a3703f005201620142903003703002017201529030037030020052002290300370300200120012903f0053703f00a20142016290300220937030020152017290300220437030020022005290300220b3703002011200b37030020102004370300200a2009370300200120012903f00a22093703f005200120093703b0082008450d010b200610010b200141b0086a200141d0036a412010d102450d01200141003602f00a200141f00a6a109902410610002206450d0d200120063602f00a200142063702f40a200141f00a6a41d1aac2004106102920022005280200360200200120012903f00a3703f005200141f0056a41b7acc2004103102920012802f405210620012802f005220a200228020010f201210802402006450d00200a10010b200820034d0d01200120033602d00a410610002206450d0f200120063602f00a200142063702f40a200141f00a6a41d1aac2004106102920022005280200360200200120012903f00a3703f005200141f0056a200141d00a6a4104102920012802f405210520012802f00522062002280200200141d0036a10f4012005450d0120061001200741206a2107200341016a2103200f41606a220f0d020c030b20014190036a41186a200141d0036a41186a29030037030020014190036a41106a200141d0036a41106a29030037030020014190036a41086a200141d0036a41086a290300370300200120012903d003370390032013450d00200610010b200741206a2107200341016a2103200f41606a220f0d000b0b200ca7450d00200e10010b20014180036a41086a22024200370300200142003703800341f5c7c100411620014180036a1002200141f0026a41086a200229030037030020012001290380033703f002200141f0026a411041b8d6c200410041001004417f460d0b200142003703f00a200141f0026a4110200141f00a6a41084100100441016a41084d0d0420012903f00a22094200510d0c20002009824200520d17200141d0036a10ba0120012802d0032110024002400240024020012802d8032211450d0041002108200141003602f005200120103602f405200141e0026a200141f0056a109e01024002400240201041c8026a22022010201141c8026c6a460d00200141e0026a41086a290300210920012903e0022104201141c8026c41b87d6a2107200141d0026a41086a210a41012105201021030340200120023602f40a200120053602f00a200141d0026a200141f00a6a109e012009200a290300220b200420012903d002220c562009200b562009200b511b22061b21092004200c20061b21042008200520061b21082003200220061b2103200541016a2105200241c8026a2102200741b87d6a22070d000b2003450d02201120084b0d0141c893c00020082011104a000b410021080b200141d0036a41086a22062011417f6a22053602002010200841c8026c6a220229001021092010200541c8026c6a220541c0026a290300210420052903a002210b200541a8026a290300210c200541b0026a290300210d200541b8026a290300211c20054180026a290300211d20054188026a290300211e20054190026a290300211f20054198026a2903002120200541e0016a2903002122200541e8016a2903002121200541f0016a2903002123200541f8016a2903002129200541c0016a290300212a200541c8016a290300212b200541d0016a290300212c200541d8016a290300212d200541a0016a290300212e200541a8016a290300212f200541b0016a2903002130200541b8016a290300213120054180016a290300213220054188016a290300213320054190016a290300213420054198016a2903002135200541e8006a2903002136200541f0006a2903002137200541e0006a2903002138200541f8006a2903002139200541c8006a290300213a200541d0006a290300213b200541d8006a290300213c200541286a290300213d200541306a290300213e200541386a290300213f200541186a2903002140200541c0006a2903002141200541206a290300214220052903002143200529030821442002200529031037001020022900082145200220443700082002290000214420022043370000200241206a2205290000214320052042370000200241c0006a2205290000214220052041370000200241186a2205290000214120052040370000200241386a220529000021402005203f370000200241306a2205290000213f2005203e370000200241286a2205290000213e2005203d370000200241d8006a2205290000213d2005203c370000200241d0006a2205290000213c2005203b370000200241c8006a2205290000213b2005203a370000200241f8006a2205290000213a20052039370000200241e0006a2205290000213920052038370000200241e8006a22052900002138200241f0006a22082900002146200820373700002005203637000020024180016a2205290000213620024188016a2208290000213720024190016a2203290000214720024198016a2207290000214820072035370000200320343700002008203337000020052032370000200241a0016a22052900002132200241a8016a22082900002133200241b0016a22032900002134200241b8016a2207290000213520072031370000200320303700002008202f3700002005202e370000200241c0016a2205290000212e200241c8016a2208290000212f200241d0016a22032900002130200241d8016a220729000021312007202d3700002003202c3700002008202b3700002005202a370000200241e0016a2205290000212a200241e8016a2208290000212b200241f0016a2203290000212c200241f8016a2207290000212d2007202937000020032023370000200820213700002005202237000020024180026a2205290000212220024188026a2208290000212120024190026a2203290000212320024198026a22072900002129200720203700002003201f3700002008201e3700002005201d37000020022800a0022107200241b8026a201c370000200241b0026a200d370000200241a8026a200c3700002002200b3700a002200241c0026a2004370000200141f0056a41386a2040370300200141f0056a41306a203f370300200141f0056a41286a203e370300200141f0056a41206a2043370300200141f0056a41186a2041370300200141f0056a41d8006a203d370300200141f0056a41d0006a203c370300200141f0056a41c8006a203b370300200141f0056a41c0006a2042370300200141f0056a41f8006a203a370300200141f0056a41f0006a2046370300200141f0056a41e8006a2038370300200141f0056a41e0006a2039370300200141f0056a4198016a2048370300200141f0056a4190016a2047370300200141f0056a4188016a2037370300200141f0056a4180016a2036370300200141f0056a41b8016a2035370300200141f0056a41b0016a2034370300200141f0056a41a8016a2033370300200141f0056a41a0016a2032370300200141f0056a41d8016a2031370300200141f0056a41d0016a2030370300200141f0056a41c8016a202f370300200141f0056a41c0016a202e370300200141f0056a41f8016a202d370300200141f0056a41f0016a202c370300200141f0056a41e8016a202b370300200141f0056a41e0016a202a370300200141f0056a4198026a2029370300200141f0056a4190026a2023370300200141f0056a4188026a2021370300200141f0056a4180026a20223703002001200937038006200120453703f805200120443703f005200141f00a6a41086a22022006280200360200200120012903d0033703f00a200141f00a6a10cb0120012802f00a2106024020022802002202450d00200241c8026c21052006210203402002102c200241c8026a2102200541b87d6a22050d000b0b024020012802f40a450d00200610010b411310002202450d18200120023602f00a200142133702f40a200141f00a6a41a0c8c1004113102920012802f00a2102024020012802f40a220520012802f80a22066b41044f0d00200641046a22082006490d1f20054101742203200820082003491b22034100480d1f2005450d0320031000220a450d1a200a200220032005200520034b1b10ce02210520021001200521020c040b200641046a21080c040b2011450d00201141c8026c21052010210203402002102c200241c8026a2102200541b87d6a22050d000b0b20012802d403450d1a201010010c1a0b200310002202450d160b200321050b200220066a2007360000200141f0026a41086a22064200370300200142003703f00220022008200141f0026a100220014190036a41086a2006290300370300200120012903f0023703900341002106024020014190036a411041b8d6c200410041001004417f460d00200120014190036a3602b008200141103602b408200142003703f80a200142003703f00a2001410020014190036a4110200141f00a6a41104100100422062006417f461b2206411020064110491b3602b8082006410f4d0d13200141f00a6a41086a2203290300210920012903f00a2104200141f00a6a200141b0086a103920012802f00a2206450d132003280200210320012802f40a210a200141f0026a41086a22104200370300200142003703f00220022008200141f0026a100220014180036a41086a2010290300370300200120012903f0023703800320014180036a4110100a2005450d170c160b20050d150c160b200141f00a6a41186a200141f0056a41186a290000370300200141f00a6a41106a200141f0056a41106a290000370300200141f00a6a41086a200141f0056a41086a290000370300200120012900f0053703f00a41b2eac10041331040000b411241011019000b200141b0036a41186a200141f00a6a41186a290000370300200141b0036a41106a200141f00a6a41106a290000370300200141b0036a41086a200141f00a6a41086a290000370300200120012900f00a3703b00341b2eac10041331040000b410641011019000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b410641011019000b41b2eac10041331040000b410641011019000b41c3d7c10041221040000b41b093c000104d000b41c3d7c10041221040000b41c3d7c10041221040000b41c3d7c10041221040000b41c3d7c10041221040000b41b2eac10041331040000b41b2eac10041331040000b411341011019000b200341011019000b200210010b0240024002402006450d0002402003450d002003410574210520062102034020022004200910b802200241206a2102200541606a22050d000b0b200141980b6a2009370300200141900b6a2004370300200141f00a6a41086a41003a0000200141fc0a6a2007360200200141f00a6a41106a2006360200200141840b6a200a360200200141880b6a2003360200200141043a00f00a200141f00a6a10a10120014180036a41086a22024200370300200142003703800341b3c8c100411620014180036a1002200141f0026a41086a200229030037030020012001290380033703f002200141f0026a411041b8d6c200410041001004417f460d02200142003703f00a200141f0026a4110200141f00a6a41084100100441016a41084d0d0120012903f00a2109200141f00a6a200141f0056a41a00210ce021a200141b0086a200920007c200141f00a6a4100109f0120012802b0084101470d0320012802b408200141b8086a2802001006200141d0036a21240c040b200141f0056a102c0c020b41b2eac10041331040000b41c3d7c10041221040000b200120003703d00a20014180036a41086a22024200370300200142003703800341c9c8c100411320014180036a1002200141f0026a41086a200229030037030020012001290380033703f0020240024002400240024002400240200141f0026a411041b8d6c200410041001004417f460d00200141003602f00a200141f0026a4110200141f00a6a41044100100441016a41044d0d0320012802f00a210220014180036a41086a22054200370300200142003703800341dcc8c100411920014180036a1002200141f0026a41086a200529030037030020012001290380033703f0020240200141f0026a411041b8d6c200410041001004417f460d00200141003602f00a200141f0026a4110200141f00a6a41044100100441016a41044d0d03200120012802f00a3602d403200120023602d00341002114200141003a00dc032001200141d00a6a3602d803200141f0056a200141d0036a104302400240024020012802f805410b470d004108210f41b00221194108410041b0026c6a211741000d010c080b200141f00a6a200141f0056a41b00210ce021a41b0021000220f450d01200f200141f00a6a41b00210ce022102200141b0086a41086a200141d0036a41086a290300370300200120012903d0033703b008200141f0056a200141b0086a1043024020012802f805410b470d004101211441b00221192002410141b0026c6a211741010d010c080b200141f0056a41086a210841b002210541012114410121020340200141f00a6a200141f0056a41b00210ce021a024020022014470d00201441016a22062014490d0d20144101742203200620062003491b2203ad42b0027e2209422088a70d0d2009a722064100480d0d024002402014450d00200610002207450d082007200f2006201441b0026c220a200a20064b1b10ce022106200f10012006210f0c010b20061000220f450d070b200321140b200f20056a200141f00a6a41b00210ce021a200541b0026a2105200241016a2102200141f0056a200141b0086a10432008280200410b470d000b41b0022119200f200241b0026c6a21172002450d070b200141f00a6a4104722105200141f0056a410472211a200141f00a6a41086a2115200141f90a6a211b200f2102024002400240034020022802082106200141d0036a2002410c6a419c0210ce021a200220196a21122006410b460d0120022802a802211020022d00ac022118200141b0086a200141d0036a419c0210ce021a200120063602f005201a200141b0086a419c0210ce021a02400240024002400240411310002202450d00200120023602f00a200142133702f40a200141f00a6a41f5c8c1004113102920012802f00a2102024002400240024020012802f40a2206201528020022086b41044f0d00200841046a22072008490d1720064101742203200720072003491b22034100480d172006450d0120031000220a450d06200a200220032006200620034b1b10ce02210620021001200621020c020b200841046a21070c020b200310002202450d040b200321060b200220086a201036000020014180036a41086a2203420037030020014200370380032002200720014180036a1002200141f0026a41086a2211200329030037030020012001290380033703f0020240200141f0026a411041b8d6c200410041001004417f460d00200142103702d4032001200141f0026a3602d003200141f00a6a200141d0036a103920012802f00a2216450d022015280200210820012802f40a21132006450d050c040b41002113410121164100210820060d030c040b411341011019000b41b2eac10041331040000b200341011019000b200210010b024002400240024002402008450d00200841057421074200210c4200210d4200210b4200211c201621020340200141c0026a2002109502200141c0026a41086a290300210420012903c0022109200120103602f00a200241086a290000211d200241106a290000211e2002290000211f200541186a200241186a290000370000200541106a201e370000200541086a201d3700002005201f370000411010002206450d02200120063602d003200142103702d403200141d0036a41a2c9c10041101029200141d00a6a41086a2206200141d0036a41086a280200360200200120012903d0033703d00a200141f00a6a200141d00a6a10a3012006280200210620012802d40a210a20012802d00a21082003420037030020014200370380032008200620014180036a10022011200329030037030020012001290380033703f002024002400240200141f0026a411041b8d6c200410041001004417f470d0041022106200a0d010c020b200141003a00d003200141f0026a4110200141d0036a41014100100441016a41014d0d0520012d00d0032106200a450d010b200810010b200241206a210242002004200641ff017141024720067122061b201c7c4200200920061b221c200b7c220b201c54ad7c211c2004420020061b200d7c2009420020061b2209200c7c220c200954ad7c210d200741606a22070d000b2013450d040c030b4200210b4200211c4200210c4200210d20130d020c030b411041011019000b41b2eac10041331040000b201610010b200141b0026a109702200141b0026a41086a290300210920012903b0022104201010a201024002400240200b200c7c221d420288201c200d7c201d200b54ad7c221e423e8684221f201e420288222084500d00201f201d852020201e8584500d004100210202400340200141a0026a201d201e200241046a41fe007110d902200241026a210220012903a002221f200141a0026a41086a290300222084500d01201f201d852020201e858450450d000b0b20014190026a201d201e200241fe007110d90220012903900220014190026a41086a29030084211f420021202002450d01201f420052ad211f0340200141f0016a201d201e41002002417e6a2206200620024b1b220241ff007110d90220014180026a201f420186222142018422222020420186201f423f888422202022202010d5022021202220012903800220012903f0015620014180026a41086a290300221f200141f0016a41086a290300222356201f2023511b1b211f20020d000c030b0b42002120201d201e84420052ad211f0c010b201f420052ad211f0b0240024002400240024020044202882009423e8684221d2009420288221e84500d00201d200485201e20098584500d004100210202400340200141e0016a20042009200241046a41fe007110d902200241026a210220012903e001221d200141e0016a41086a290300221e84500d01201d200485201e2009858450450d000b0b200141d0016a20042009200241fe007110d90220012903d001200141d0016a41086a29030084211d4200211e2002450d01201d420052ad211d0340200141b0016a2004200941002002417e6a2206200620024b1b220241ff007110d902200141c0016a201d42018622214201842222201e420186201d423f8884221e2022201e10d5022021202220012903c00120012903b00156200141c0016a41086a290300221d200141b0016a41086a290300222356201d2023511b1b211d20020d000b201f202084500d030c020b4200211e2004200984420052ad211d201f20208450450d010c020b201d420052ad211d201f202084500d010b02400240201841037122024102460d00024020024101470d00034020202120201f2122201d201e844200510d0820014190016a200c200d2022202010d202200141a0016a200b201c201d201e10d20220012903a001221f200129039001222154200141a0016a41086a290300220920014190016a41086a290300220454200920045122021b0d032021201f54200420095420021b0d0420014180016a201f2009201d201e10d502200141f0006a202120042022202010d502200c200129037022097d2204200d200141f0006a41086a2903007d200c200954ad7d220984500d04201c20014180016a41086a2903007d2121200b200129038001220c542102200b200c7d211f201d210c201e210d2004211d2009211e2022210b2020211c201f20212002ad7d22208450450d000c030b0b0340200141e0006a200b201c201f202010d202201d2222201e221e844200510d08200141e0006a41086a29030021092001290360211d200141d0006a200c200d2022201e10d202201d20012903502221542009200141d0006a41086a290300220454200920045122021b0d022021201d54200420095420021b0d03200141c0006a201d2009201f202010d502200141306a202120042022201e10d502200c200129033022097d2204200d200141306a41086a2903007d200c200954ad7d220984500d03201c200141c0006a41086a2903007d2121200b2001290340220c542102200b200c7d211d201f210c2020210d2004211f200921202022210b201e211c201d20212002ad7d221e8450450d000c020b0b200c200b56200d201c56200d201c511b450d010b201541023a0000200141f00a6a410c6a22022010360200200141043a00f00a200141f00a6a10a101200141f00a6a200141f0056a41a00210ce021a200141003b01d003200141286a200141f00a6a200141d0036a10ab0220012802282106201541053a0000201b2006453a000020022010360200200141043a00f00a200141f00a6a10a1012001201041016a3602f00a20034200370300200142003703800341c9c8c100411320014180036a10022011200329030037030020012001290380033703f002200141f0026a4110200141f00a6a410410032012210220122017470d020c010b201541033a0000200141f00a6a410c6a2010360200200141043a00f00a200141f00a6a10a1012001201041016a3602f00a20034200370300200142003703800341c9c8c100411320014180036a10022011200329030037030020012001290380033703f002200141f0026a4110200141f00a6a41041003200141f0056a102c2012210220122017470d010b0b201721120b20122017460d0a0c090b41ccb2c000104d000b41ccb2c000104d000b41b00241081019000b41c3d7c10041221040000b41c3d7c10041221040000b200641081019000b41b2eac10041331040000b41b2eac10041331040000b200f22122017460d010b200141f00a6a41086a2105200141f00a6a410c6a21060340201241086a280200210220122903002109200141f00a6a2012410c6a41a40210ce021a2002410b460d01200141f0056a200141f00a6a41a40210ce021a20052002360200200120093703f00a2006200141f0056a41a40210ce021a2005102c201241b0026a22122017470d000b0b200141d0036a21242014450d00200f10010b200010b702200141f00a6a4104722125200141f00a6a410572210f200141f00a6a41206a2105200141f00a6a419c026a2126200141f0056a419c026a2113200141b0086a410472211b200141b00d6a41086a2119200141b0086a410c6a21272001419c0b6a210e200141a00b6a212802400340200141b00d6a10c00120012802b00d2102410b2117024020192802002206450d0020022903002109200141b0036a41186a2208200241206a290000370300200141b0036a41106a2203200241186a290000370300200141b0036a41086a2207200241106a290000370300200120022900083703b003410b211720092000520d0002400240024002400240024002402006417f6a220aad42287e2209422088a70d002009a72210417f4c0d00024002402010450d002010100022140d010c040b410821140b024002400240200a200641286c41586a41286e22064f0d00200a4101742211200620062011491b2211ad42287e2209422088a70d0d2009a722154100480d0d200a450d01201510002212450d072012201420152010201020154b1b10ce021a201410010c020b20142112200a21110c010b201510002212450d050b2012200241286a200641286c10ce02210a200141f00a6a41086a22102006360200200120113602f40a2001200a3602f00a200141f00a6a10ca0102402011450d00200a10010b200141d00a6a41186a2008290300370300200141d00a6a41106a2003290300370300200141d00a6a41086a2007290300370300200120012903b0033703d00a411810002206450d01200120063602f00a200142183702f40a200141f00a6a41cfd6c20041181029200141b0086a41086a22062010280200360200200120012903f00a3703b008200141d00a6a200141b0086a101b2006280200211020012802b408211120012802b008210620014180036a41086a220a420037030020014200370380032006201020014180036a1002200141f0026a41086a200a29030037030020012001290380033703f0020240200141f0026a411041b8d6c200410041001004417f460d00200142103702b4082001200141f0026a3602b008200141f00a6a200141b0086a10bb0120012802f00a2217410b460d0420242025419c0210ce022112200a420037030020014200370380032006201020014180036a100220014190036a41086a200a29030037030020012001290380033703900320014190036a4110100a200141b0086a2012419c0210ce021a2011450d070c060b410b2117200141b0086a2024419c0210ce021a20110d050c060b102e000b411841011019000b201041081019000b41b2eac10041331040000b201541081019000b200610010b2017410b460d00200141f00a6a200141b0086a419c0210ce021a202641186a2008290300370000202641106a2003290300370000202641086a2007290300370000202620012903b003370000200141f0056a200141f00a6a41bc0210ce021a0b024020012802b40d450d00200210010b2017410b460d01200120173602b008201b200141f0056a419c0210ce021a200141d0036a41186a2214201341186a290000370300200141d0036a41106a2215201341106a290000370300200141d0036a41086a2216201341086a290000370300200120132900003703d003200141b00d6a10bd0120012802b00d2118024002400240024002402019280200221a41286c220a450d00410021124100211120182102034020052002290000370000200141f00a6a41186a2014290300370300200141f00a6a41106a2015290300370300200141f00a6a41086a2016290300370300200541086a200241086a290000370000200541106a200241106a290000370000200541186a200241186a290000370000200120012903d0033703f00a411b10002206450d02200120063602d00a2001421b3702d40a200141d00a6a418fdcc200411b1029200141b0036a41086a2206200141d00a6a41086a280200360200200120012903d00a3703b003200141f00a6a200141b0036a10f0012006280200210720012802b403211020012802b003210620014180036a41086a2208420037030020014200370380032006200720014180036a1002200141f0026a41086a200829030037030020012001290380033703f002024002400240200141f0026a411041b8d6c200410041001004417f470d004102210320100d010c020b200141003a00d00a200141f0026a4110200141d00a6a41014100100441016a41014d0d0520012d00d00a21032008420037030020014200370380032006200720014180036a100220014190036a41086a200829030037030020012001290380033703900320014190036a4110100a2010450d010b200610010b0240200341ff01714102460d00201220034101716a211220112003417f734101716a21110b200241286a2102200a41586a220a0d000b201120126a210220012802b40d450d040c030b4100211141002112410041006a210220012802b40d0d020c030b411b41011019000b41b2eac10041331040000b201810010b201a20026b210202400240024020174105470d00200141b0086a41086a2d000041ff01714106470d0020272802002106200141f00a6a41286a2012360200200e201136020020282002360200200f20012903d003370000200f41086a2016290300370000200f41106a2015290300370000200f41186a2014290300370000200141003a00f40a200141063a00f00a200141f00a6a10a10120110d0120020d01200141f00a6a41086a41043a0000200141f00a6a410c6a2006360200200141043a00f00a200141f00a6a10a101200610a2010c010b200141f00a6a41286a2012360200200e201136020020282002360200200f20012903d003370000200f41086a2016290300370000200f41106a2015290300370000200f41186a2014290300370000200141013a00f40a200141063a00f00a200141f00a6a10a1012012200220116a4b0d010b200141b0086a102c0c010b02400240411c10002206450d00200120063602f00a2001421c3702f40a200141f00a6a41e7d6c200411c1029200141d00a6a41086a2208200141f00a6a41086a280200360200200120012903f00a3703d00a200141d0036a200141d00a6a101b2008280200210320012802d40a210720012802d00a210620014190036a41086a220a420037030020014200370390032006200320014190036a100220014180036a41086a200a29030037030020012001290390033703800320014180036a4110100a02402007450d00200610010b02402002201172450d00200141f00a6a200141b0086a41a00210ce021a200141d00a6a200141f00a6a410210ab0120012802d00a4101470d030c020b200141f00a6a200141b0086a41a00210ce021a200141d00a6a200141f00a6a410110ab0120012802d00a4101460d010c020b411c41011019000b20012802d40a2202450d000b200828020021054183d7c200410f10062002200510060b20014190036a41086a22024200370300200142003703900341d7cac200411420014190036a100220014180036a41086a200229030037030020012001290390033703800320014180036a411041b8d6c200410041001004417f460d08200142003703f00a20014180036a4110200141f00a6a41084100100441016a41084d0d0920012903f00a22094200510d0720002009824200520d0e20014190036a41086a2202420037030020014200370390034195c9c200410c20014190036a100220014180036a41086a220520022903003703002001200129039003370380030240024020014180036a411041b8d6c200410041001004417f460d00200142003703f80a200142003703f00a20014180036a4110200141f00a6a4110410010042206417f460d082006410f4d0d08200141f80a6a290300210920012903f00a210b0c010b4200210b420021090b200141880b6a2009370300200141f00a6a41106a200b370300200141083a00f00a200141f00a6a41086a41013a0000200141f00a6a10a10120024200370300200142003703900341ebcac200411220014190036a10022005200229030037030020012001290390033703800320014180036a411041b8d6c200410041001004417f460d0a200142103702f405200120014180036a3602f005200141f00a6a200141f0056a103820012802f00a2212450d0520012802f40a2115200141f00a6a41086a22162802002205450d0b200141f90a6a2117200141f0086a2114200141d0086a2119200141f0056a41086a210a200141b0086a41186a211a200141a80b6a211b200141a00b6a210e2001419c0b6a2128410021104100210341002111410021020340024002400240024002402011450d00201220024102746a21062012200220106a4102746a21080340200220054f0d03200141f0056a2006280200220710bf0220012903f0054201520d02200141b0086a200a41e00010ce021a200b20012903b008220c542009200141b0086a41086a29030022045420092004511b450d05201020026a220320054f0d0420082006280200360200200641046a2106200841046a2108410121032005200241016a2202470d000c140b0b201220024102746a21060340200220054f0d02200141f0056a2006280200220710bf0220012903f0054201520d01200141b0086a200a41e00010ce021a200b20012903b008220c5a2009200141b0086a41086a29030022045a20092004511b0d04200641046a2106410121032005200241016a2202470d000c120b0b2010417f6a2110201141016a2111200241016a22022005470d030c110b41a080c00020022005104a000b41b080c00020032005104a000b200241016a2102411210002206450d02200120063602f00a200142123702f40a200141f00a6a418cd2c2004112102920012802f00a2106024002400240024020012802f40a22082016280200220f6b41044f0d00200f41046a2213200f490d0520084101742218201320132018491b22184100480d052008450d01201810002226450d072026200620182008200820184b1b10ce02210820061001200821060c020b200f41046a21130c020b201810002206450d050b201821080b2006200f6a200736000020014190036a41086a220f420037030020014200370390032006201320014190036a100220014180036a41086a2213200f29030037030020012001290390033703800320014180036a4110100a02402008450d00200610010b2019200141b0086a41106a290300201a29030010b802411410002206450d04200120063602f00a200142143702f40a200141f00a6a41d7aac20041141029200141d0036a41086a22062016280200360200200120012903f00a3703d0032014200141d0036a101b2006280200210820012802d403211820012802d00321064200210d200f420037030020014200370390032006200820014190036a10022013200f29030037030020012001290390033703800302400240024020014180036a411041b8d6c200410041001004417f460d00200142003703f80a200142003703f00a20014180036a4110200141f00a6a4110410010042208417f460d082008410f4d0d082016290300211c20012903f00a210d200920047d2109200b200c54ad211d2018450d020c010b4200211c200920047d2109200b200c54ad211d2018450d010b200610010b2009201d7d2109200b200c7d210b2014200d200c7c221d201c20047c201d200d54ad7c10ec011a201b2004370300200e200c3703002028200736020020172014290000370000201741106a201441106a290000370000201741186a201441186a290000370000200141083a00f00a201641023a0000201741086a201441086a290000370000200141f00a6a10a1012010417f6a2110201141016a211120022005470d000c0e0b0b1018000b411241011019000b201841011019000b411441011019000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b41c8ffc000104d000b41c3d7c10041221040000b41b2eac10041331040000b4100210541042112410021150b410021030b410021110b200141003602f80a200142013703f00a2012200520116b200141f00a6a10e30120012802f40a210520012802f80a210620012802f00a210220014190036a41086a22084200370300200142003703900341ebcac200411220014190036a100220014180036a41086a200829030037030020012001290390033703800320014180036a411020022006100302402005450d00200210010b02402015450d00201210010b0240200341ff01710d00200141186a200b200941fdcac200410d10bf01ad420010d502200141083a00f00a200141086a2001290318200141186a41086a29030042c0843d420010d202200141f00a6a41086a41033a0000200141880b6a2009200141086a41086a29030022042001290308220c200b56200420095620042009511b22021b220d370300200141800b6a200b200c20021b22043703002009200d7d200b200454ad7d2109200b20047d210b200141f00a6a10a1010b200141880b6a2009370300200141f00a6a41106a200b370300200141083a00f00a200141f00a6a41086a41043a0000200141f00a6a10a101200120093703f80a2001200b3703f00a20014190036a41086a2202420037030020014200370390034195c9c200410c20014190036a100220014180036a41086a200229030037030020012001290390033703800320014180036a4110200141f00a6a411010030b20014190036a41086a22024200370300200142003703900341e4c7c100411120014190036a100220014180036a41086a200229030037030020012001290390033703800320014180036a4110100a200141c00d6a24000b950c04037f027e057f027e230041b0016b2201240020014190016a41086a220242003703002001420037039001418fadc200411120014190016a1002200141e8006a41086a220320022903003703002001200129039001370368200141e8006a4110100a20024200370300200142003703900141e0afc200411520014190016a1002200320022903003703002001200129039001370368200141e8006a4110100a200342003703002001420037036841dcacc200410d200141e8006a1002200220032903003703002001200129036837039001024002400240024020014190016a411041b8d6c200410041001004417f460d002001420037036820014190016a4110200141e8006a41084100100441016a41084d0d0220012903682104200141e8006a41086a220242003703002001420037036841dcacc200410d200141e8006a100220014190016a41086a2002290300370300200120012903683703900120014190016a4110100a4201a7450d010c030b4200a70d020b41c3d7c10041221040000b41b2eac10041331040000b200141086a41e9acc200411110b80142002105200141e8006a41086a220242003703002001420037036841baacc200410d200141e8006a100220014190016a41086a20022903003703002001200129036837039001024002400240024020014190016a411041b8d6c200410041001004417f460d002001421037024c200120014190016a360248200141e8006a200141c8006a103420012802682206450d02200129026c2105200141e8006a41086a220242003703002001420037036841baacc200410d200141e8006a100220014190016a41086a2002290300370300200120012903683703900120014190016a4110100a0c010b410421060b200141286a41faacc200411510b801200141e8006a41186a22024200370300200141e8006a41106a22034200370300200141e8006a41086a2207420037030020014200370368200141e8006a101320014190016a41186a2208200229030037030020014190016a41106a2209200329030037030020014190016a41086a220a20072903003703002001200129036837039001200141c8006a41186a2008290300370300200141c8006a41106a2009290300370300200141c8006a41086a200a290300370300200120012903900137034820024200370300200342003703002007420037030020014200370368024002402004200141e8006a1016450d002008200229030037030020092003290300370300200a2007290300370300200120012903683703900120022008290300370300200320092903003703002007200a29030037030020012001290390013703682008200229030037030020092003290300370300200a2007290300370300200120012903683703900102402005422088a722022005a7470d00200241016a22032002490d0220024101742207200320032007491bad220b42247e220c422088a70d02200ca722034100480d02024002402002450d00200310002207450d06200720062003200241246c2202200220034b1b10ce02210220061001200221060c010b200310002206450d050b200542808080807083200b8421050b20062005422088a741246c6a220241003a0000200241196a200141a8016a290300370000200241116a200141a0016a290300370000200241096a20014198016a2903003700002002200129039001370001200241216a20012f008d013b0000200241236a2001418f016a2d00003a000020054280808080107c21050b2000200129030837001420002004370300200020012903483700342000412c6a200141086a41186a290300370000200041246a200141086a41106a2903003700002000411c6a200141086a41086a2903003700002000413c6a200141c8006a41086a290300370000200041c4006a200141c8006a41106a290300370000200041cc006a200141c8006a41186a290300370000200020063602082000410c6a2005370200200041ec006a200141286a41186a290300370000200041e4006a200141286a41106a290300370000200041dc006a200141286a41086a29030037000020002001290328370054200141b0016a24000f0b1018000b41b2eac10041331040000b200341041019000bcc0c04047f017e097f017e230041c0016b2202240010860210ac01108702200241b0016a41086a22034200370300200242003703b00141e0afc2004115200241b0016a1002200241a0016a41086a2003290300370300200220022903b0013703a00141002104024002400240024002400240024002400240024002400240024002400240200241a0016a411041b8d6c200410041001004417f460d002002410036020841042105200241a0016a4110200241086a41044100100441016a41044d0d0c20022802082204450d012004ad420c7e2206422088a70d042006a722034100480d04200310002205450d0e200241086a41086a210720052108410021090340411410002203450d06200220033602082002421437020c200241086a41eeadc200411410292002280208210a0240024002400240200228020c220b200728020022036b41044f0d00200341046a220c2003490d09200b410174220d200c200c200d491b220d4100480d09200b450d01200d1000220e450d10200e200a200d200b200b200d4b1b10ce02210b200a1001200b210a0c020b200341046a210c0c020b200d1000220a450d0e0b200d210b0b200a20036a2009360000200241a0016a41086a220e4200370300200242003703a001200a200c200241a0016a10022007200e290300370300200220022903a001370308200241086a411041b8d6c200410041001004417f460d0720024210370284012002200241086a36028001200220024180016a10352002280200450d0a20022802042203417f4c0d08024002402003450d0020031000220d450d0d200d4100200310d0021a0c010b4101210d0b20024180016a41086a220f200f280200220f20034100200228028001200228028401200d2003200f1004220f200f417f461b220f200f20034b1b6a3602002003200f4b0d09200d450d0a200941016a21092003ad22064220862006842106200e4200370300200242003703a001200a200c200241a0016a1002200241b0016a41086a200e290300370300200220022903a0013703b001200241b0016a4110100a0240200b450d00200a10010b2008200d360200200841046a20063702002008410c6a210820092004490d000c040b0b410421050c010b410021040b410021090b200241086a200520052009410c6c6a104120024180016a200228020822032002280210105f0240200228020c450d00200310010b02402009450d002009410c6c210a2005210303400240200341046a280200450d00200328020010010b2003410c6a2103200a41746a220a0d000b0b02402004450d00200510010b200241086a41186a20024180016a41186a290300370300200241086a41106a20024180016a41106a290300370300200241086a41086a20024180016a41086a2903003703002002200229038001370308200241b0016a41086a22034200370300200242003703b00141faacc2004115200241b0016a1002200241a0016a41086a2003290300370300200220022903b0013703a001200241a0016a4110200241086a41201003200241086a108802200241003602880120024201370380012002411c6a20024180016a101b200229030821060240024002400240200228028401220920022802880122036b41084f0d00200341086a220a2003490d042009410174220d200a200a200d491b220b4100480d042009450d012002280280012108200b1000220d450d0d200d2008200b20092009200b4b1b10ce021a200810010c020b200341086a210a200228028001210d0c020b200b1000220d450d0b0b2002200b360284012002200d360280010b20024180016a41086a2209200a360200200d20036a20063700002002413c6a20024180016a101b200241dc006a20024180016a101b20024180016a200241086a41086a10242009350200422086210620023502800121102002280210210d0240200241186a2802002203450d00200341246c210a200d21030340024020032d0000450d00200341086a280200450d00200341046a28020010010b200341246a2103200a415c6a220a0d000b0b200620108421060240200241146a280200450d00200d10010b200241c0016a240020060f0b1018000b411441011019000b41c3d7c10041221040000b102e000b200d10010b41b2eac10041331040000b200341011019000b200d41011019000b41b2eac10041331040000b200b41011019000b200341041019000bcf0603037f027e0a7f23004190036b22022400024020010d0041b8d6c20021000b2002200036020020024200370308200241086a200020014108200141084922031b220410ce021a2002200120046b3602042002200020046a360200024002400240024020030d0020022903082105200241086a2002103220022802082204450d00200229020c210641a80310002201450d01200141023602880120014202370370200142023703900120012005370398010240024020064280808080105a0d004101210702402006a7450d00200410010b200121084101210941011000220a0d010c040b41d00610002208450d042008200141a80310ce02210020011001200041a8036a200241a0026a41f00010ce021a2000420237039804200041003602b004200041033602b804200020043602bc04200020063703c00420002002290390023703a004200041a8046a20024198026a290300370300200041c8046a200241086a41880210ce021a410221074101210941011000220a450d030b200a20074102743a0000200741a8036c210b200241106a210c410121004101210120082104024002400340200220043602a002200241086a200241a0026a10cf012002280208210f024002400240200020016b200c280200220e4f0d002001200e6a22032001490d042000200974220d20032003200d491b220d4100480d040240024020000d00200d1000220a450d070c010b200d10002210450d062010200a200d20002000200d4b1b10ce022100200a10012000210a0b200d2100200a20016a200f200e10ce021a200228020c0d010c020b2001200e6a2103200a20016a200f200e10ce021a200228020c450d010b200228020810010b200441a8036a210420032101200b41d87c6a220b0d000b200741a8036c210020084188016a21012003ad422086200aad84210603402001102c200141a8036a2101200041d87c6a22000d000b2008100120024190036a240020060f0b1018000b200d41011019000b200241146a41013602002002411c6a4101360200200241013602a402200241c0b6c0003602a002200241c8b6c0003602082002410136020c200241c0c5c2003602102002200241a0026a360218200241086a41d0b6c0001065000b41a80341081019000b410141011019000b41d00641081019000bdf0102027f017e230041306b22022400200241206a41086a220342003703002002420037032041ecd8c1004112200241206a1002200241086a2003290300370300200220022903203703000240024002402002411041b8d6c200410041001004417f460d002002421037021420022002360210200241206a200241106a103920022802202203450d01024020022902242204a7450d00200310010b410410002203450d0220032004422088a7360000200241306a24002003ad4280808080c000840f0b41c3d7c10041221040000b41b2eac10041331040000b410441011019000ba30503037f027e077f230041306b22022400200241206a41086a220342003703002002420037032041ecd8c1004112200241206a1002200241086a20032903003703002002200229032037030002400240024002400240024002402002411041b8d6c200410041001004417f460d002002421037021420022002360210200241206a200241106a103920022802202204450d0102400240024002400240200229022422054220882206a72203413f4b0d0041012107410110002208450d07200820064202863c00004101210920030d010c020b02402003418080014f0d0041022107410210002208450d08200820034102744101723b00000c010b024020034180808080044f0d0041042107410410002208450d09200820034102744102723600000c010b41011000220a450d09200a41033a000041052107410510002208450d0a2008200a2d00003a0000200a1001200820033600010b2003410574210b2007210a20042103034002400240024002402007200a6b41204f0d00200a41206a2209200a490d062007410174220c20092009200c491b220c4100480d062007450d01200c1000220d450d07200d2008200c20072007200c4b1b10ce02210720081001200721080c020b200a41206a21090c020b200c10002208450d050b200c21070b2008200a6a220a2003290000370000200a41186a200341186a290000370000200a41106a200341106a290000370000200a41086a200341086a2900003700002009210a200341206a2103200b41606a220b0d000b0b2009ad4220862008ad84210602402005a7450d00200410010b200241306a240020060f0b1018000b200c41011019000b41c3d7c10041221040000b41b2eac10041331040000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000bc10102027f027e230041206b22022400200241106a41086a220342003703002002420037031041c6edc100410d200241106a1002200241086a20032903003703002002200229031037030002402002411041b8d6c200410041001004417f460d0020024200370310024020024110200241106a41084100100441016a41084d0d00200241106a200229031010de012002350218210420023502102105200241206a240020052004422086840f0b41b2eac10041331040000b41c3d7c10041221040000be40201057f230041d0006b22022400200241306a41086a2203420037030020024200370330418fadc2004111200241306a1002200241206a41086a20032903003703002002200229033037032002400240200241206a411041b8d6c200410041001004417f460d00200241c8006a4200370300200241306a41106a420037030020034200370300200242003703300240200241206a4110200241306a4120410010042203417f460d002003411f4d0d00200241186a2204200241306a41186a290300370300200241106a2205200241306a41106a290300370300200241086a2206200241306a41086a29030037030020022002290330370300412010002203450d0220032002290300370000200341186a2004290300370000200341106a2005290300370000200341086a2006290300370000200241d0006a24002003ad42808080808004840f0b41b2eac10041331040000b41c3d7c10041221040000b412041011019000bce0202057f027e230041c0006b22022400200241206a2001412020014120491b22036a41004100412020036b2003411f4b1b10d0021a200241206a200041b8d6c20020011b200310ce021a02402001411f4d0d00200241186a2201200241206a41186a2203290000370300200241106a2200200241206a41106a2204290000370300200241086a2205200241206a41086a22062900003703002002200229002037030020032001290300370300200420002903003703002006200529030037030020022002290300370320200241206a200241206a10900210de012002350228210720023502202108200241c0006a240020082007422086840f0b2002412c6a4101360200200241346a410136020020024101360204200241c0b6c000360200200241c8b6c00036022020024101360224200241c0c5c20036022820022002360230200241206a41d0b6c0001065000b8c0203047f017e017f230041206b220124000240411310002202450d002001200236021020014213370214200141106a41eaabc20041131029200141086a220220012802183602002001200129031037030020002001101b20022802002103200128020421042001280200210042002105200141106a41086a220642003703002001420037031020002003200141106a10022002200629030037030020012001290310370300024002402001411041b8d6c200410041001004417f460d002001420037031020014110200141106a41084100100441016a41084d0d01200129031021050b02402004450d00200010010b200141206a240020050f0b41b2eac10041331040000b411341011019000bfe05020a7f037e23004190016b22022400024002402001450d00200220003602000c010b200241b8d6c2003602000b20022001360204200241286a200210a50102400240024020022d002822034102460d00200241246a41026a220020022d002b3a0000200241086a41086a2204200241286a41106a2205290300370300200241086a41106a2206200241286a41186a2207290300370300200241086a41186a2208200241c8006a2209280200360200200220022f00293b01242002200241286a41086a220a290300370308200228022c2101200241ec006a41026a20002d00003a0000200241d0006a41086a220b2004290300370300200241d0006a41106a22042006290300370300200241d0006a41186a22062008280200360200200220022f01243b016c20022002290308370350410121000240024020034101470d00200241286a200110a80120022d002841014621000c010b200a2002290350220c370300200241f0006a41026a200241ec006a41026a2d000022033a0000200241ff006a200b290300220d37000020024187016a2004290300220e3700002002418f016a20062d000022043a0000200920043a00002007200e3703002005200d370300200220013600732002200136022c200220022f016c22013b01702002200c370077200220013b0029200220033a002b200241013a00280b2002410036027820024201370370410110002101024002402000450d002001450d03200141013a0000200220013602702002428180808010370274200241286a410172200241f0006a101b200241f8006a350200422086210c200228027021010c010b2001450d03200141003a0000200220013602702002428180808010370274428080808010210c0b20024190016a2400200c2001ad840f0b200241fc006a410136020020024184016a410136020020024101360254200241c0b6c000360250200241c8b6c00036027020024101360274200241c0c5c2003602782002200241d0006a36028001200241f0006a41d0b6c0001065000b410141011019000b410141011019000bd00d05027f017e017f017e077f230041b00f6b22022400024002402001450d00200220003602080c010b200241b8d6c2003602080b2002200136020c200241880c6a200241086a10a401024002400240024002400240024002400240024020022903f80c4203510d00200241106a200241880c6a41a80310ce021a200241b8036a200241106a41a80310ce021a2002200241b8036a3602b009200241880c6a200241b0096a10cf0120022802900c21030240200228028c0c450d0020022802880c10010b200241880c6a200241b8036a41a80310ce021a200241b0096a200241880c6a10a701024002400240024020022802b0094101470d0020022802b8094115470d01024020022802b40922004180c9c200460d004100210120004180c9c200411510d1020d030b410221010c020b200241e0066a200241b0096a41086a41d00210ce021a410021000240200241e0066a41086a410020022903e0064201511b2201450d002001450d00200120031093020d0020011090022104200141206a410020011b220529030022062004540d0041022100200620044280027c580d030b200220003602880c20024190076a102c0c060b410021010b200220013602880c0c040b02400240200420065a0d0041042109200241880c6a41086a210a4100210841002100410021070340200a2004370300200220013602880c200241b0096a200241880c6a10f101024020072000470d00200041016a220b2000490d082000410174220c200b200b200c491b220cad420c7e2206422088a70d082006a7220b4100480d08024002402000450d00200b1000220d450d07200d2009200b2000410c6c22002000200b4b1b10ce02210020091001200021090c010b200b10002209450d060b200c21000b200920086a220b20022903b009370200200b41086a200241b0096a41086a2802003602002008410c6a2108200741016a2107200442017c22042005290300540d000c020b0b4100210041042109410021070b410c10002208450d02200220013602b009200220052903003703b809200241880c6a200241b0096a10f101200841086a200241880c6a41086a2201280200360200200820022903880c370200200241a80c6a2003ad37030020012000360200200241880c6a410c6a2007360200200241980c6a20083602002002419c0c6a428180808010370200200241b00c6a427f3703002002200936028c0c200241013602880c20024190076a102c0c030b200241c4036a4101360200200241cc036a410136020020024101360214200241c0b6c000360210200241c8b6c0003602b803200241013602bc03200241c0c5c2003602c0032002200241106a3602c803200241b8036a41d0b6c0001065000b200b41041019000b410c41041019000b200241003602c003200242013703b803024002400240024002400240024020022802880c22014101460d0020014102470d0141012100410110002201450d08200220013602b80320024281808080103702bc03200141023a00000c060b410110002201450d08200220013602b80320024281808080103702bc03200141013a0000200241a80c6a2903002104410910002200450d09200020012d00003a000020011001200220003602b8032002428980808090013702bc0320002004370001200241b8036a200241880c6a4104721025200241b8036a200241980c6a1025200241b00c6a290300210420022802bc032207200241b8036a41086a28020022036b41084f0d01200341086a22002003490d0620074101742201200020002001491b22084100480d062007450d0220022802b8032109200810002201450d0b2001200920082007200720084b1b10ce021a200910010c030b41012100410110002201450d09200220013602b80320024281808080103702bc03200141003a00000c040b200341086a210020022802b80321010c020b200810002201450d080b200220083602bc03200220013602b8030b200241c0036a2000360200200120036a20043700000b2000ad4220862001ad842104024020022802880c4101470d000240200241880c6a410c6a2802002200450d00200228028c0c21012000410c6c210003400240200141046a280200450d00200128020010010b2001410c6a2101200041746a22000d000b0b0240200241900c6a280200450d00200228028c0c10010b0240200241a00c6a2802002200450d00200241980c6a28020021012000410c6c210003400240200141046a280200450d00200128020010010b2001410c6a2101200041746a22000d000b0b2002419c0c6a280200450d00200241980c6a28020010010b200241b00f6a240020040f0b1018000b410141011019000b410141011019000b410941011019000b410141011019000b200841011019000bd00904057f017e017f067e230041c0006b22022400024002400240411410002203450d002002200336023020024214370234200241306a41d7aac20041141029200241206a41086a22032002280238360200200220022903303703202000200241206a101b20032802002104200228022421052002280220210642002107200241306a41086a220842003703002002420037033020062004200241306a1002200320082903003703002002200229033037032002400240200241206a411041b8d6c200410041001004417f460d002002420037033820024200370330200241206a4110200241306a4110410010042203417f460d012003410f4d0d01200241386a2903002109200229033021072005450d040c030b4200210920050d020c030b41b2eac10041331040000b411441011019000b200610010b200241306a41086a220342003703002002420037033041ebaac200411b200241306a1002200241206a41086a20032903003703002002200229033037032002400240024002400240200241206a411041b8d6c200410041001004417f460d002002420037033820024200370330024002400240200241206a4110200241306a4110410010042203417f460d002003410f4d0d00200241306a41086a2203290300210a2002290330210b20034200370300200242003703304186abc200411b200241306a1002200241206a41086a200329030037030020022002290330370320200241206a411041b8d6c200410041001004417f460d042002420037033820024200370330200241206a4110200241306a4110410010042203417f460d012003410f4d0d0120022002290330200241306a41086a22032903002001ad420010d502200342003703002002420037033041a1abc200411b200241306a1002200241206a41086a200329030037030020022002290330370320200241086a290300210c2002290300210d200241206a411041b8d6c200410041001004417f460d052002420037033820024200370330200241206a4110200241306a4110410010042203417f460d022003410f4d0d0241b3cac200210302402007200d200b7c220b20022903307c220e542009200c200a7c200b200d54ad7c220d200241306a41086a22062903007c200e200b54ad7c220a542009200a511b0d0020002007200b7d2009200d7d2007200b54ad7d10b402200642003703002002420037033041bcabc2004116200241306a1002200241206a41086a200629030037030020022002290330370320200241206a411041b8d6c200410041001004417f460d082002420037033820024200370330200241206a4110200241306a4110410010042203417f460d072003410f4d0d074100210320022903302207200b7d220a200756200241306a41086a22062903002209200d7d2007200b54ad7d220b200956200b2009511b0d002002200a3703102002200b370318200642003703002002420037033041bcabc2004116200241306a1002200241206a41086a200629030037030020022002290330370320200241206a4110200241106a411010030b200241c0006a240020030f0b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b41c3d7c10041221040000b41c3d7c10041221040000b41b2eac10041331040000b41c3d7c10041221040000be2530b017f027e027f017e027f047e037f027e027f027e0b7f230041c0046b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d0020024180046a41086a2201420037030020024200370380044186ecc100411520024180046a1002200241f0036a41086a200129030037030020022002290380043703f003200241f0036a411041b8d6c200410041001004417f460d0f2002420037038003200241f0036a411020024180036a41084100100441016a41084d0d12200229038003210320024180046a41086a22014200370300200242003703800441fdd7c100411520024180046a100220024180036a41086a200129030037030020022002290380043703800320024180036a411041b8d6c200410041001004417f460d0e200242003703a00420024180036a4110200241a0046a41084100100441016a41084d0d1142002104200020022903a00420037e220320032000541b22004200510d0d20024180046a41086a22014200370300200242003703800441a8f0c100411c20024180046a1002200241f0036a41086a2205200129030037030020022002290380043703f003200241f0036a411041b8d6c200410041001004417f460d0120024200370388032002420037038003200241f0036a411020024180036a4110410010042206417f460d102006410f4d0d1020024188036a290300210720022903800321040c020b20024180046a21080c020b420021070b200241f0026a200420072003421086200080420010d50220014200370300200242003703800441ecd8c100411220024180046a10022005200129030037030020022002290380043703f003200241f0026a41086a290300210020022903f0022103200241f0036a411041b8d6c200410041001004417f460d09200242103702a4042002200241f0036a3602a00420024180036a200241a0046a10392002280280032209450d082003421088200042308684210a2000421088210b0240200229028403220c422088220da74105742201450d00200920016a210e2009210103402001220f450d01024002400240024002400240411c10002201450d0020022001360280032002421c3702840320024180036a41d6f0c100411c1029200241a0046a41086a220120024180036a41086a220528020036020020022002290380033703a004200f200241a0046a101b20022802a4042106200241d8026a20022802a0042210200128020010b901200241d8026a41086a290300210020022903d802210302402006450d00201010010b02400240200a2003200a2003200a542000200b542000200b511b22061b22117d2204200b2000200b20061b22127d200a201154ad7d220784500d00411c10002206450d0320022006360280032002421c3702840320024180036a41f2f0c100411c10292001200528020036020020022002290380033703a004200f200241a0046a101b2001280200210620022802a404211320022802a004210120024180046a41086a2210420037030020024200370380042001200620024180046a1002200241f0036a41086a201029030037030020022002290380043703f003200241f0036a411041b8d6c200410041001004417f460d01200242103702a4042002200241f0036a3602a00420024180036a200241a0046a10392002280280032214450d042005280200211020022802840321082013450d060c050b42002100420021040c060b41012114410021104100210820130d030c040b411c41011019000b411c41011019000b41b2eac10041331040000b200110010b200241c8026a200f109502200241c8026a41086a290300210020022903c8022103024002402010450d00201041057422062105201421010340200241b8026a2001109502200241b8026a41086a29030020007c20022903b802220020037c2203200054ad7c2100200141206a2101200541606a22050d000b20004200200342015620004200522000501b22011b21002003420120011b210302402010450d00201421012003200084500d080340200241a8026a200110950220024198026a20022903a802200241a8026a41086a2903002004200710d50220024188026a20022903980220024198026a41086a2903002003200010d202200120022903880220024188026a41086a290300109602200141206a2101200641606a22060d000b0b200241e8016a200f10950220032000844200510d06200241e8016a41086a290300211520022903e80121160c010b200241d8016a200f10950220004200200342015620004200522000501b22011b21002003420120011b2103200241d8016a41086a290300211520022903d80121160b200241c8016a201620152004200710d502200241b8016a20022903c801200241c8016a41086a2903002003200010d202200241b8016a41086a290300210420022903b80121002008450d00201410010b200f200020117c2203200420127c2003200054ad7c109602200f41206a2201200e470d000b0b42002100200241a8016a200a200b200d420010d50220024198036a200b37030020024180036a41106a200a37030020024180036a41086a41003a0000200241033a00800320024180036a10a10120024180046a41086a22014200370300200242003703800441c4f0c100411220024180046a1002200241f0036a41086a200129030037030020022002290380043703f003200241f0036a411041b8d6c2004100410010042101200241a8016a41086a290300210320022903a8012104024002402001417f460d0020024200370388032002420037038003200241f0036a411020024180036a4110410010042201417f460d0520014110490d0520024200370388032002420037038003200241f0036a411020024180036a4110411010042201417f460d052001410f4d0d0520024188036a290300210720022903800321000c010b420021070b20024198016a20002007200d420010d50202402004200384500d002002290398012200200241a0016a290300220784500d0020024188016a109702200241f8006a200229038801220a20007d20024188016a41086a29030020077d200a200054ad7d2000200710d202200241e8006a2002290378200241f8006a41086a2903002004200310d50220024180046a41086a2201420037030020024200370380044195c9c200410c20024180046a1002200241f0036a41086a2205200129030037030020022002290380043703f003200241f0036a411041b8d6c2004100410010042106200241e8006a41086a290300210320022903682104024002402006417f460d0020024200370388032002420037038003200241f0036a411020024180036a4110410010042206417f460d0a2006410f4d0d0a20024188036a290300210720022903800321000c010b42002100420021070b2002200020047c2204370380032002200720037c2004200054ad7c370388032001420037030020024200370380044195c9c200410c20024180046a10022005200129030037030020022002290380043703f003200241f0036a411020024180036a411010030b20024180046a2108200ca7450d00200910010b200841086a220142003700002008420037000041bfd8c100411420081002200241f0036a41086a2001290000370300200220082900003703f003200241f0036a411041b8d6c200410041001004417f460d032002420037038003024002400240200241f0036a411020024180036a41084100100441016a41084d0d00200229038003210342002100200241f0036a41086a22014200370300200242003703f003418ef1c1004115200241f0036a100220024180036a41086a2001290300370300200220022903f00337038003024020024180036a411041b8d6c200410041001004417f460d0020014200370300200242003703f003418ef1c1004115200241f0036a1002200841086a2001290300370000200820022903f00337000020084110100a0c130b200841086a220542003700002008420037000041a3f1c100411b2008100220012005290000370300200220082900003703f0030240200241f0036a411041b8d6c200410041001004417f460d002002420037038003200241f0036a411020024180036a41084100100441016a41084d0d0320022903800321000b200841086a220142003700002008420037000041bef1c100411620081002200241f0036a41086a2001290000370300200220082900003703f003200241f0036a411041b8d6c200410041001004417f460d072002420037038003200241f0036a411020024180036a41084100100441016a41084d0d0120022903800322044200510d08200320007d2004824200520d130c120b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b41e0b6c000104d000b200241f8016a201410950241e0b6c000104d000b41b2eac10041331040000b41c3d7c10041221040000b41c3d7c10041221040000b41f8b6c000104d000b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b41e0b6c000104d000b41c3d7c10041221040000b41c3d7c10041221040000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b200841086a220142003700002008420037000041d4f1c100411220081002200241f0036a41086a2001290000370300200220082900003703f0030240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200241f0036a411041b8d6c200410041001004417f460d0020024200370380030240024002400240200241f0036a411020024180036a41084100100441016a41084d0d00200220022903800342017c37038003200841086a220142003700002008420037000041d4f1c100411220081002200241f0036a41086a22052001290000370300200220082900003703f003200241f0036a411020024180036a41081003200142003700002008420037000041e6f1c100411a2008100220052001290000370300200220082900003703f0030240200241f0036a411041b8d6c200410041001004417f460d002002420037038003200241f0036a411020024180036a41084100100441016a41084d0d02200220022903800322003703a004200841086a220142003700002008420037000041bef1c100411620081002200241f0036a41086a2001290000370300200220082900003703f003200241f0036a411041b8d6c200410041001004417f460d062002420037038003200241f0036a411020024180036a41084100100441016a41084d0d032000200229038003510d002002200037038003200841086a220142003700002008420037000041bef1c100411620081002200241f0036a41086a22052001290000370300200220082900003703f003200241f0036a411020024180036a41081003200142003700002008420037000041bfd8c10041142008100220052001290000370300200220082900003703f003200241f0036a411041b8d6c200410041001004417f460d082002420037038003200241f0036a411020024180036a41084100100441016a41084d0d04200220022903800337038003200841086a220142003700002008420037000041a3f1c100411b20081002200241f0036a41086a2001290000370300200220082900003703f003200241f0036a411020024180036a410810030b200841086a22014200370000200842003700004180f2c100411220081002200241f0036a41086a2001290000370300200220082900003703f00302400240200241f0036a411041b8d6c200410041001004417f460d00200242103702a4042002200241f0036a3602a00420024180036a200241a0046a10392002280280032217450d082002280284032118410521054100211020024188036a2802004105742201450d010c0a0b41012117410021184105210541002110410041057422010d090b4108211a41002119201720016a221b2017460d0a0c090b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b41c3d7c10041221040000b41b2eac10041331040000b41c3d7c10041221040000b20012005752219ad42307e2200422088a70d0a2000a722054100480d0a20051000221a450d06201720016a221b2017460d010b2017210f201a210641002110034020024180036a41186a2213200f41186a29000037030020024180036a41106a220e200f41106a29000037030020024180036a41086a2209200f41086a2900003703002002200f29000037038003411510002201450d022002200136028004200242153702840420024180046a419bf3c10041151029200241f0036a41086a220120024180046a41086a221e28020036020020022002290380043703f00320024180036a200241f0036a101b2001280200211420022802f403211d20022802f0032105200841086a221c42003700002008420037000020052014200810022001201c290000370300200220082900003703f003024002400240200241f0036a411041b8d6c200410041001004417f470d004100211c4101211441002101201d0d010c020b20024210370294042002200241f0036a3602900420024180046a20024190046a10392002280280042214450d05201e2802002101200228028404211c201d450d010b200510010b200241d8006a20024180036a109502200241d8006a41086a29030021002002290358210302402001450d0020014105742105201421010340200241c8006a2001109502200241c8006a41086a29030020007c2002290348220020037c2203200054ad7c2100200141206a2101200541606a22050d000b0b200f41206a210f0240201c450d00201410010b200241a0046a41186a22012013290300370300200241a0046a41106a2205200e290300370300200241a0046a41086a2214200929030037030020022002290380033703a0042006200037030820062003370300200620022903a004370310200641186a2014290300370300200641206a2005290300370300200641286a2001290300370300201041016a2110200641306a2106200f201b470d000b0b02402018450d00201710010b200841086a22014200370000200842003700004192f2c100411d20081002200241f0036a41086a2001290000370300200220082900003703f00302400240200241f0036a411041b8d6c200410041001004417f460d002002410036028003200241f0036a411020024180036a41044100100441016a41044d0d0420102002280280034f0d010c280b20104104490d270b201a2010410041202010676b109802200841086a220142003700002008420037000041aff2c100411620081002200241f0036a41086a2001290000370300200220082900003703f003200241f0036a411041b8d6c200410041001004417f460d052002410036028003200241f0036a411020024180036a41044100100441016a41044d0d032002280280032113024002402010450d00201020102013201320104b1b417f6a22014d0d08201a41086a2903002100201a200141306c6a2201290300210b200141086a2903002111201a290300210341102101411010002205450d010c090b42002103420021004200210b42002111411021014110100022050d080b200141011019000b411541011019000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b200541081019000b41c3d7c10041221040000b4190b7c00020012010104a000b2005200337000020052000370008412010002201450d1920012005290000370000200141086a200541086a29000037000020051001200141186a20113700002001200b370010200841086a220542003700002008420037000041c4f0c100411220081002200241f0036a41086a2005290000370300200220082900003703f003200241f0036a4110200141201003200110014100211f0240024002402013201041306c220541306d2201200120134b1b2220450d002020ad4205862200422088a70d032000a722014100480d03200110002221450d1920130d010c020b41012121410021202013450d010b201a20056a210e20024180036a41106a21064100211f201a2101202121050340200e2001460d01200141086a2903002100200141106a2903002103200141186a2903002104200141206a29030021072001290300210a20024180036a41286a200141286a29030037030020024180036a41206a200737030020024180036a41186a20043703002006200337030020024180036a41086a2000370300200241a0046a41086a220f200641086a290000370300200241a0046a41106a2210200641106a290000370300200241a0046a41186a2214200641186a2900003703002002200a37038003200220062900003703a004200541186a2014290300370000200541106a2010290300370000200541086a200f290300370000200520022903a004370000200541206a2105200141306a21012013201f41016a221f470d000b0b02402019450d00201a10010b200841086a220142003700002008420037000041ecd8c100411220081002200241f0036a41086a2001290000370300200220082900003703f003200241f0036a411041b8d6c200410041001004417f460d18200242103702a4042002200241f0036a3602a00420024180036a200241a0046a1039200228028003221d450d1702402002290284032200422088a7410574220e450d00201d21060340411c10002201450d1e20022001360280032002421c3702840320024180036a41f2f0c100411c1029200241a0046a41086a220120024180036a41086a221028020036020020022002290380033703a0042006200241a0046a101b2001280200210520022802a404211320022802a0042114200841086a220f4200370000200842003700002014200520081002200241f0036a41086a2205200f290000370300200220082900003703f003200241f0036a4110100a02402013450d00201410010b411210002214450d1d2002201436028003200242123702840320024180036a41c5f2c100411210292001201028020036020020022002290380033703a0042006200241a0046a101b2001280200211320022802a404210920022802a004211420054200370300200242003703f00320142013200241f0036a100220102005290300370300200220022903f0033703800302400240024020024180036a411041b8d6c200410041001004417f470d004100410041001b211320090d010c020b200241003602a00420024180036a4110200241a0046a41044100100441016a41044d0d2120022802a004211c20054200370300200242003703f00320142013200241f0036a1002200f2005290300370000200820022903f00337000020084110100a201c410041011b21132009450d010b201410010b024020134102490d00411210002214450d1d2002201436028003200242123702840320024180036a41c5f2c100411210292001201028020036020020022002290380033703a0042006200241a0046a101b2001280200211020022802a404211420022802a004210120022013417f6a36028003200f42003700002008420037000020012010200810022005200f290000370300200220082900003703f003200241f0036a411020024180036a410410032014450d00200110010b200641206a2106200e41606a220e0d000b0b02402000a7450d00201d10010b2021201f4105746a21190240201f450d002021210903400240024002400240411510002201450d002002200136028003200242153702840320024180036a419bf3c10041151029200241a0046a41086a220520024180036a41086a220628020036020020022002290380033703a0042009200241a0046a101b2005280200210120022802a404211020022802a004210f200841086a221c420037000020084200370000200f200120081002200241f0036a41086a221b201c290000370300200220082900003703f0030240200241f0036a411041b8d6c200410041001004417f460d00200242103702a4042002200241f0036a3602a00420024180036a200241a0046a1039200228028003221e450d022006280200210120022802840321182010450d040c030b4101211e410021014100211820100d020c030b411541011019000b41b2eac10041331040000b200f10010b411c1000220f450d042002200f360280032002421c3702840320024180036a41f2f0c100411c10292005200628020036020020022002290380033703a0042009200241a0046a101b2005280200211a20022802a404211720022802a004211d0240024002402001413f4b0d00410110002210450d0a201020014102743a0000410121064101210f20010d010c020b02402001418080014f0d00410210002210450d0c41022106201020014102744101723b00000c010b024020014180808080044f0d00410410002210450d0e20102001410274410272360000410421060c010b410110002205450d0e200541033a0000410510002210450d0f201020052d00003a00002005100120102001360001410521060b200141057421132006210f201e211403402014210102400240024002402006200f22056b41204f0d00200541206a220f2005490d0820064101742214200f200f2014491b22144100480d082006450d0120141000220e450d09200e201020142006200620144b1b10ce02210620101001200621100c020b200541206a210f0c020b201410002210450d070b201421060b200141206a2114201020056a22052001290000370000200541186a200141186a290000370000200541106a200141106a290000370000200541086a200141086a290000370000201341606a22130d000b0b201c420037000020084200370000201d201a20081002201b201c290000370300200220082900003703f003200241f0036a41102010200f100302402006450d00201010010b02402017450d00201d10010b200941206a210902402018450d00201e10010b20092019470d000b0b201fad2200421b88a70d0c2000420586a72209417f4c0d0c024002402009450d002009100022010d01200941011019000b410121010b20012021201f41057410ce02211c024002400240201f413f4b0d0041012106410110002210450d142010201f4102743a00004101210f201f0d010c020b0240201f418080014f0d0041022106410210002210450d152010201f4102744101723b00000c010b0240201f4180808080044f0d0041042106410410002210450d162010201f4102744102723600000c010b410110002201450d16200141033a000041052106410510002210450d17201020012d00003a0000200110012010201f3600010b201f41057421132006210f201c211403402014210102400240024002402006200f22056b41204f0d00200541206a220f2005490d0620064101742214200f200f2014491b22144100480d062006450d0120141000220e450d09200e201020142006200620144b1b10ce02210620101001200621100c020b200541206a210f0c020b201410002210450d070b201421060b200141206a2114201020056a22052001290000370000200541186a200141186a290000370000200541106a200141106a290000370000200541086a200141086a290000370000201341606a22130d000b0b200841086a220142003700002008420037000041ecd8c100411220081002200241f0036a41086a2001290000370300200220082900003703f003200241f0036a41102010200f100302402006450d00201010010b4100210f024002400240201f450d00201c1001201f211e20091000221d450d1120212019470d010c020b4101211d4100211e20212019460d010b20024180036a41186a2210202141186a29000037030020024180036a41106a2214202141106a29000037030020024180036a41086a2213202141086a2900003703002002202129000037038003202141206a2105201f41057441606a21064101210f201d21010340200241a0046a41186a220e2010290300370300200241a0046a41106a22092014290300370300200241a0046a41086a221c201329030037030020022002290380033703a004200141186a200e290300370000200141106a2009290300370000200141086a201c290300370000200120022903a0043700002006450d012010200541186a2900003703002014200541106a2900003703002013200541086a2900003703002002200529000037038003200f41016a210f200641606a2106200541206a2105200141206a21010c000b0b410610002201450d0d2002200136028003200242063702840320024180036a41d1aac20041061029200241a8046a220120022802880336020020022002290380033703a004200241a0046a41b7acc2004103102920022802a404210520022802a0042210200128020010f201210602402005450d00201010010b4100210120024180046a41002006103f024002400240024002400240200228028804200f470d002002280280042114200f450d022014201d460d014100211020142105201d2106034020052006412010d1020d01200541206a2105200641206a2106201041016a2210200f490d000c030b0b20024180036a41086a221320024180046a41086a28020036020020022002290380043703800320024180036a1099020240200f450d00200f410574210641002101201d21050340200220013602f00341061000220f450d0b2002200f36028003200242063702840320024180036a41d1aac20041061029200241a0046a41086a220f201328020036020020022002290380033703a004200241a0046a200241f0036a4104102920022802a404211020022802a0042214200f280200200510f40102402010450d00201410010b200541206a2105200141016a2101200641606a22060d000b0b410610002205450d142002200536028003200242063702840320024180036a41d1aac20041061029200241a8046a220520022802880336020020022002290380033703a004200241a0046a41b7acc2004103102920022802a404210620022802a004220f200528020010f201210e02402006450d00200f10010b0240200e20014d0d00200121050340410610002206450d0d2002200636028003200242063702840320024180036a41d1aac20041061029200241a0046a41086a220620024180036a41086a221328020036020020022002290380033703a004200241a0046a41b7acc2004103102920022802a404210f20022802a0042214200628020010f20121100240200f450d00201410010b0240201020054d0d00200220053602f00341061000220f450d102002200f36028003200242063702840320024180036a41d1aac200410610292006201328020036020020022002290380033703a004200241a0046a200241f0036a4104102920022802a404210f20022802a00422102006280200100a200f450d00201010010b200e200541016a2205470d000b0b410610002205450d152002200536028003200242063702840320024180036a41d1aac20041061029200241a8046a220520022802880336020020022002290380033703a004200241a0046a41b7acc200410310292005280200210620022802a404210f20022802a004210520022001360280032005200620024180036a41041003200f450d0220051001201e0d030c040b410021010340200141016a2201200f490d000b0b200228028404450d00201410010b201e450d010b201d10010b200241386a200b201141d7f2c100411410bf01ad420010d502200241286a2002290338200241386a41086a290300428094ebdc03420010d2022002200241286a41086a290300370388032002200229032837038003200841086a220142003700002008420037000041ebf2c100411b20081002200241f0036a41086a22052001290000370300200220082900003703f003200241f0036a411020024180036a41101003200241186a200b20114186f3c100411510bf01ad420010d502200241086a2002290318200241186a41086a290300428094ebdc03420010d2022002200241086a41086a290300370388032002200229030837038003200142003700002008420037000041a8f0c100411c2008100220052001290000370300200220082900003703f003200241f0036a411020024180036a411010032020450d1f202110010c1f0b1018000b201441011019000b411c41011019000b201441011019000b410641011019000b410141011019000b410641011019000b410241011019000b410641011019000b410441011019000b410141011019000b410541011019000b102e000b410641011019000b200941011019000b410641011019000b410641011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000b200141011019000b41b2eac10041331040000b41c3d7c10041221040000b412041011019000b411241011019000b411241011019000b411c41011019000b41b2eac10041331040000b2019450d00201a1001200241c0046a24000f0b200241c0046a24000be50404057f017e017f037e230041206b22022400024002400240411410002203450d002002200336021020024214370214200241106a41d7aac20041141029200241086a220320022802183602002002200229031037030020012002101b20032802002104200228020421052002280200210642002107200241106a41086a220842003703002002420037031020062004200241106a10022003200829030037030020022002290310370300024002402002411041b8d6c200410041001004417f460d00200242003703182002420037031020024110200241106a4110410010042203417f460d012003410f4d0d01200241186a2903002109200229031021072005450d040c030b4200210920050d020c030b41b2eac10041331040000b411441011019000b200610010b024002400240411810002203450d002002200336021020024218370214200241106a41d2abc20041181029200241086a220320022802183602002002200229031037030020012002101b2003280200210620022802042104200228020021014200210a200241106a41086a220542003703002002420037031020012006200241106a10022003200529030037030020022002290310370300024002402002411041b8d6c200410041001004417f460d00200242003703182002420037031020024110200241106a4110410010042203417f460d012003410f4d0d01200241186a290300210b2002290310210a2004450d040c030b4200210b20040d020c030b41b2eac10041331040000b411841011019000b200110010b2000200a20077c22073703002000200b20097c2007200a54ad7c370308200241206a24000b980504057f017e017f027e230041c0006b22032400200320001095020240024002402003290300200341086a29030084500d00024002400240411410002204450d002003200436023020034214370234200341306a41d7aac20041141029200341206a41086a22042003280238360200200320032903303703202000200341206a101b20042802002105200328022421062003280220210742002108200341306a41086a220942003703002003420037033020072005200341306a1002200420092903003703002003200329033037032002400240200341206a411041b8d6c200410041001004417f460d002003420037033820034200370330200341206a4110200341306a4110410010042204417f460d012004410f4d0d01200341386a290300210a200329033021082006450d040c030b4200210a20060d020c030b41b2eac10041331040000b411441011019000b200710010b2000200820017c220b200a20027c200b200854ad7c10b402200341306a41086a220042003703002003420037033041bcabc2004116200341306a1002200341206a41086a200029030037030020032003290330370320200341206a411041b8d6c200410041001004417f460d022003420037033820034200370330200341206a4110200341306a4110410010042200417f460d012000410f4d0d012003290330220820017c220a2008542200200341306a41086a2204290300220820027c2000ad7c220120085420012008511b0d002003200a37031020032001370318200442003703002003420037033041bcabc2004116200341306a1002200341206a41086a200429030037030020032003290330370320200341206a4110200341106a411010030b200341c0006a24000f0b41b2eac10041331040000b41c3d7c10041221040000bc60102027f017e230041206b22012400200141106a41086a220242003703002001420037031041bcabc2004116200141106a1002200141086a20022903003703002001200129031037030002402001411041b8d6c200410041001004417f460d002001420037031820014200370310024020014110200141106a4110410010042202417f460d002002410f4d0d00200129031021032000200141186a29030037030820002003370300200141206a24000f0b41b2eac10041331040000b41c3d7c10041221040000bd22e09087f047e0f7f017e077f017e017f017e0b7f230041d0026b220424000240024020014115490d00410121054101210602400240024002400340200620057141017321070340024002402003450d0020054101710d0120002001109a022003417f6a21030c010b20002001109b02200441d0026a24000f0b2001410276220641036c2108200641017421094100210a024020014132490d00410241012000200641306c6a220b41506a290300220c200b290300220d54200b41586a290300220e200b41086a290300220f54200e200f511b22101b2010200c200d20101b220c200b41306a290300220d54200e200f20101b220e200b41386a290300220f54200e200f511b22111b200020062006417f6a221220101b221341306c6a220b290300200d200c20111b54200b41086a290300220c200f200e20111b220e54200c200e511b22146a2000200941306c6a220b41506a290300220c200b290300220d54200b41586a290300220e200b41086a290300220f54200e200f511b22156a200c200d20151b220c20002009410172221641306c6a220b290300220d54200e200f20151b220e200b41086a290300220f54200e200f511b22176a200020092009417f6a221820151b221941306c6a220b290300200d200c20171b54200b41086a290300220c200f200e20171b220e54200c200e511b221a6a2000200841306c6a220b41506a290300220c200b290300220d54200b41586a290300220e200b41086a290300220f54200e200f511b221b6a200c200d201b1b220c200b41306a290300220d54200e200f201b1b220e200b41386a290300220f54200e200f511b220b6a200020082008417f6a221c201b1b221d41306c6a220a290300200d200c200b1b54200a41086a290300220c200f200e200b1b220e54200c200e511b221e6a210a201d200841016a201c2008201b1b200b1b201e1b2108201920162018200920151b20171b201a1b21092013200641016a2012200620101b20111b20141b21060b200a2000200641306c6a220b290300220c2000200941306c6a2210290300220d54200b41086a290300220e201041086a290300220f54200e200f511b220b6a200c200d200b1b220c2000200841306c6a2210290300220d54200e200f200b1b220e201041086a290300220f54200e200f511b22106a210a0240024002400240200020092006200b1b221d41306c6a2215290300200d200c20101b5a201541086a290300220c200f200e20101b220e5a200c200e511b0d00200a41016a220a410b4d0d01024020014101762208450d002000200141306c6a41506a2106200021090340200441a0016a41286a220b200941286a2210290300370300200441a0016a41206a220a200941206a2215290300370300200441a0016a41186a221b200941186a2211290300370300200441a0016a41106a2217200941106a2212290300370300200441a0016a41086a2213200941086a2214290300370300200420092903003703a001200641086a2216290300210e200641106a2218290300210f200641186a2219290300210c200641206a221a290300210d2006290300211f2010200641286a221c2903003703002015200d3703002011200c3703002012200f3703002014200e3703002009201f370300201c200b290300370300201a200a2903003703002019201b2903003703002018201729030037030020162013290300370300200620042903a001370300200941306a2109200641506a21062008417f6a22080d000b0b2001201d417f736a211d4101452007724101710d030c020b200820062009200b1b20101b211d0b200a45452007724101710d010b20002001109c020d080b024002400240024002402002450d00201d20014f0d0a2000201d41306c6a2206290300200229030054200641086a2209290300220e200241086a290300220f54200e200f511b0d01200441a0016a41286a220a200041286a2212290300370300200441a0016a41206a2215200041206a2213290300370300200441a0016a41186a221b200041186a2214290300370300200441a0016a41106a2211200041106a2208290300370300200441a0016a41086a2217200041086a220b290300370300200420002903003703a0012009290300210e200641106a2210290300210f200641186a2216290300210c200641206a2218290300210d2006290300211f2012200641286a22192903003703002013200d3703002014200c3703002008200f370300200b200e3703002000201f3703002019200a290300370300201820152903003703002016201b2903003703002010201129030037030020092017290300370300200620042903a001370300200b290300210e2000290300210c200441186a22202012290300370300200441106a22212013290300370300200441086a2222201429030037030020042008290300370300200041506a2116200041306a211841002109410020012208417f6a220b4f0d02410621230c030b2001450d080b201d20014f0d06200441a0016a41286a222a200041286a2222290300370300200441a0016a41206a222b200041206a2205290300370300200441a0016a41186a222c200041186a2207290300370300200441a0016a41106a222d200041106a222e290300370300200441a0016a41086a222f200041086a2230290300370300200420002903003703a0012000201d41306c6a2206290300210e200641086a2209290300210f200641106a2208290300210c200641186a220b290300210d200641206a2210290300211f2022200641286a220a2903003703002005201f3703002007200d370300202e200c3703002030200f3703002000200e370300200a202a2903003703002010202b290300370300200b202c2903003703002008202d2903003703002009202f290300370300200620042903a0013703002030290300210e2000290300210f200441186a22312022290300370300200441106a22322005290300370300200441086a223320072903003703002004202e290300370300200041306a21154100211e02402001417f6a2208450d00201521060340200f20062903005a200e200641086a290300220c5a200e200c511b0d01200641306a2106201e41016a221e2008490d000b0b2000200141306c6a210620082109024003402006210b20092221201e4d0d012021417f6a2109200f200b41506a220629030054200e200b41586a290300220c54200e200c511b450d000b0b2021201e490d0520082021490d02418001211a4100210a410021164100211041002114418001211c2015201e41306c6a223421180340200b20186b220641306e21090240024002400240024002400240200641afe0004b221d0d00200941807f6a20092016200a49201420104922087222151b21062015450d01201c200620081b211c2006201a20081b211a0b20142010470d020c010b20062006410176221c6b211a20142010470d010b201c450d0141002109200441206a22142110201821060340201020093a00002010200f20062903005a200e200641086a290300220c5a200e200c511b6a2110200641306a2106200941016a2209201c490d000b0b2016200a470d020c010b200441206a221021142016200a470d010b0240201a450d00200b41506a210641002109200441a0016a2216210a0340200a20093a0000200a200f200629030054200e200641086a290300220c54200e200c511b6a210a200641506a2106200941016a2209201a490d000c020b0b200441a0016a220a21160b0240200a20166b2206201020146b2209200920064b1b2219450d00200441a0026a41286a2224201820142d000041306c6a220641286a290300370300200441a0026a41206a2225200641206a290300370300200441a0026a41186a2226200641186a290300370300200441a0026a41106a2228200641106a290300370300200441a0026a41086a2220200641086a290300370300200420062903003703a002201820142d000041306c6a2206200b20162d00002215417f7341306c6a2209290300370300200641286a200941286a290300370300200641206a200941206a290300370300200641186a200941186a290300370300200641106a200941106a290300370300200641086a200941086a290300370300024020194101460d00410021080340200b2015417f7341807e7241306c6a22092018201420086a41016a2d000041306c6a2206290300370300200941286a200641286a221b290300370300200941206a200641206a2211290300370300200941186a200641186a2217290300370300200941106a200641106a2212290300370300200941086a200641086a22132903003703002006200b201620086a41016a2d00002215417f7341306c6a2209290300370300201b200941286a2903003703002011200941206a2903003703002017200941186a2903003703002012200941106a2903003703002013200941086a290300370300200841026a2106200841016a221b210820062019490d000b2016201b6a21162014201b6a21140b200920042903a002370300200941286a2024290300370300200941206a2025290300370300200941186a2026290300370300200941106a2028290300370300200941086a2020290300370300201641016a2116201441016a21140b2018201c41306c6a201820142010461b2118200b4100201a6b41306c6a200b2016200a461b210b201d0d000b02400240201420104f0d00200b41506a2106201021080340200441a0026a41286a220a20182008417f6a22082d000041306c6a220941286a2215290300370300200441a0026a41206a221b200941206a2211290300370300200441a0026a41186a2217200941186a2212290300370300200441a0026a41106a2213200941106a2216290300370300200441a0026a41086a2219200941086a221a290300370300200420092903003703a002200641086a221c290300210c200641106a221d290300210d200641186a2224290300211f200641206a22252903002127200629030021292015200641286a2226290300370300201120273703002012201f3703002016200d370300201a200c370300200920293703002026200a2903003703002025201b29030037030020242017290300370300201d2013290300370300201c2019290300370300200620042903a002370300200641506a210620142008490d000b200b201420106b41306c6a21180c010b20182106200a21082016200a4f0d0003402008417f6a22082d00002109200441a0026a41286a2210200641286a2215290300370300200441a0026a41206a221b200641206a2211290300370300200441a0026a41186a2217200641186a2212290300370300200441a0026a41106a2213200641106a2214290300370300200441a0026a41086a2219200641086a221a290300370300200420062903003703a002200b2009417f7341306c6a2209290300210c200941086a221c290300210d200941106a221d290300211f200941186a22242903002127200941206a222529030021292015200941286a222629030037030020112029370300201220273703002014201f370300201a200d3703002006200c370300202620102903003703002025201b29030037030020242017290300370300201d2013290300370300201c2019290300370300200920042903a002370300200641306a210620162008490d000b2018200a20166b41306c6a21180b2000200e3703082000200f37030020222031290300370300200520322903003703002007203329030037030020002004290300370310024002402001201820346b41306e201e6a22094d0d00202a2022290300370300202b2005290300370300202c2007290300370300202d202e290300370300202f2030290300370300200420002903003703a0012000200941306c6a2206290300210e200641086a2208290300210f200641106a220b290300210c200641186a2210290300210d200641206a220a290300211f2022200641286a22152903003703002005201f3703002007200d370300202e200c3703002030200f3703002000200e3703002015202a290300370300200a202b2903003703002010202c290300370300200b202d2903003703002008202f290300370300200620042903a001370300200120096b2208450d0120082009200920084b1b210b20014103762110200641306a210a024020092008417f6a22014f0d00200020092002200310980220062102200a2100200b20104f21052021201e4d2106200141154f0d070c0c0b200a200120062003109802200b20104f21052021201e4d21062009220141154f0d060c0b0b41b0b7c00020092001104a000b41c0b7c000104d000b410021230b03400240024002400240024002400240024002400240024002400240024002400240024020230e09040507080603000102020b2018200941306c6a2106410721230c100b2006290300200c54200641086a290300220f200e54200f200e511b0d0a410821230c0f0b200641306a2106200941016a2209200b490d070c080b200a2018200941306c6a220641286a220b2903003703002015200641206a2219290300370300201b200641186a221a2903003703002011200641106a221c2903003703002017200641086a221d290300370300200420062903003703a001201041306a221e290300210f201041386a2224290300210d201041c0006a2225290300211f201041c8006a22262903002127201041d0006a22282903002129200b201041d8006a221029030037030020192029370300201a2027370300201c201f370300201d200d3703002006200f3703002010200a290300370300202820152903003703002026201b2903003703002025201129030037030020242017290300370300201e20042903a001370300200941016a22092008417f6a220b490d09410021230c0d0b2016200841306c6a2106410121230c0c0b20092008417f6a22084f0d0a410421230c0b0b2006290300210f200641086a210b200641506a22102106200f200c54200b290300220f200e54200f200e511b0d070c080b2000200c3703002000200e370308201220202903003703002013202129030037030020142022290300370300200020042903003703102001200941016a2206490d01410321230c090b2000200641306c6a2100200120066b220141154f0d0a0c100b20062001106b000b410721230c060b410021230c050b410021230c040b410621230c030b410121230c020b410521230c010b410221230c000b0b0b0b20212008106a000b201e2021106b000b41b0b7c000201d2001104a000b41a0b7c00041004100104a000b41d8b7c000201d2001104a000b20014102490d00200041a07f6a21104100210a410121090340200941016a210b02402000200941306c6a220841506a22062903002008290300220c5a200841586a290300220f200841086a2215290300220e5a200f200e511b0d00200441186a2211200841286a221b290300370300200441106a2217200841206a2212290300370300200441086a2213200841186a221429030037030020042008290310370300200820062903003703002015200641086a290300370300200841106a200641106a2903003703002014200641186a2903003703002012200641206a290300370300201b200641286a29030037030020002009417f6a221541306c6a211b02400240024002402015450d00200a210920102106200841a07f6a290300200c5a200841a87f6a290300220f200e5a200f200e511b0d03034020064188016a200641d8006a29030037030020064180016a200641d0006a290300370300200641f8006a200641c8006a290300370300200641f0006a200641c0006a290300370300200641e8006a200641386a290300370300200641e0006a200641306a29030037030020094101460d022006290300210f200641086a21082009417f6a2109200641506a2106200f200c542008290300220f200e54200f200e511b0d000c030b0b410021150c020b410021090b2000200941306c6a211b200921150b201b200c370300201b200e3703082000201541306c6a220641286a2011290300370300200641206a2017290300370300200641186a2013290300370300200620042903003703100b200a41016a210a201041306a2110200b2109200b2001490d000b0b200441d0026a24000bc80703037f017e067f230041306b22012400200141206a41086a2202420037030020014200370320419aacc200411d200141206a1002200141086a200229030037030020012001290320370300024002400240024002400240024002400240024002400240024002402001411041b8d6c200410041001004417f460d002001421037021420012001360210200141206a200141106a103620012802202202450d0102402001280224450d00200210010b20002802002202450d0a200041046a280200450d0a20021001200141306a24000f0b0240024020002802002203450d00200029020421042001200336021020012004370214200321052004422088a72200413f4b0d010c080b410610002200450d022001200036022020014206370224200141206a41d1aac20041061029200141086a2200200128022836020020012001290320370300200141b7acc200410310292001280204210220012802002206200028020010f201210002402002450d00200610010b200141106a41002000103f20012802102203210520012802182200413f4d0d070b02402000418080014f0d0041022106410210002207450d03200720004102744101723b00000c080b024020004180808080044f0d0041042106410410002207450d04200720004102744102723600000c080b410110002202450d04200241033a000041052106410510002207450d05200720022d00003a000020021001200720003600010c070b41b2eac10041331040000b410641011019000b410241011019000b410441011019000b410141011019000b410541011019000b41012106410110002207450d05200720004102743a0000410121082000450d010b200041057421092006210803402005210002400240024002402006200822026b41204f0d00200241206a22082002490d0720064101742205200820082005491b22054100480d072006450d0120051000220a450d08200a200720052006200620054b1b10ce02210620071001200621070c020b200241206a21080c020b200510002207450d060b200521060b200041206a2105200720026a22022000290000370000200241186a200041186a290000370000200241106a200041106a290000370000200241086a200041086a290000370000200941606a22090d000b0b200141206a41086a2200420037030020014200370320419aacc200411d200141206a1002200141086a2000290300370300200120012903203703002001411020072008100302402006450d00200710010b2001280214450d00200310010b200141306a24000f0b1018000b200541011019000b410141011019000b86090b107f017e017f017e017f017e017f017e017f017e017f230041306b22022400024002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d032001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200241286a22082000200441306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e2903003703002013201029030037030020052002290300370300200320014f0d022006410d7420067322044111762004732204410574200473220620077122044100200120042001491b6b220520014f0d01200241286a22082000200341306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e29030037030020132010290300370300200520022903003703002003410172220420014f0d032006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200241286a22032000200441306c6a220141286a2204290300370300200241206a2206200141206a2207290300370300200241186a2208200141186a2209290300370300200241106a220a200141106a220b290300370300200241086a220c200141086a220d290300370300200220012903003703002000200541306c6a22002903002112200041086a22052903002114200041106a220e2903002116200041186a220f2903002118200041206a2210290300211a2004200041286a22112903003703002007201a37030020092018370300200b2016370300200d2014370300200120123703002011200329030037030020102006290300370300200f2008290300370300200e200a2903003703002005200c290300370300200020022903003703000b200241306a24000f0b41b0b7c00020052001104a000b200321040b41a0b7c00020042001104a000bb50a090d7f017e037f017e017f017e017f027e027f230041306b2202240002400240024002400240024020014101762203450d0003402003417f6a22032104034020044101742211410172211a0240201141026a221120014f0d00201a20014f0d062011201a2000201141306c6a220e2903002000201a41306c6a221029030054200e41086a290300220f201041086a290300221354200f2013511b1b211a0b0240201a20014f0d00200420014f0d042000201a41306c6a22112903002000200441306c6a220429030054201141086a2210290300220f200441086a220e290300221354200f2013511b450d00200241286a2205200441286a2206290300370300200241206a2207200441206a2208290300370300200241186a2209200441186a220a290300370300200241106a220b200441106a220c290300370300200241086a220d200e290300370300200220042903003703002010290300210f201141106a22122903002113201141186a22142903002115201141206a22162903002117201129030021182006201141286a221929030037030020082017370300200a2015370300200c2013370300200e200f370300200420183703002019200529030037030020162007290300370300201420092903003703002012200b2903003703002010200d29030037030020112002290300370300201a21040c010b0b20030d000b0b024020014102490d002001210e0340200e417f6a220e20014f0d06200241286a2206200041286a2211290300370300200241206a2207200041206a221a290300370300200241186a2208200041186a2210290300370300200241106a2209200041106a2205290300370300200241086a220a200041086a220b290300370300200220002903003703002000200e41306c6a2204290300210f200441086a220c2903002113200441106a220d2903002115200441186a22122903002117200441206a221429030021182011200441286a2216290300370300201a20183703002010201737030020052015370300200b20133703002000200f370300201620062903003703002014200729030037030020122008290300370300200d2009290300370300200c200a2903003703002004200229030037030041002104034020044101742211410172211a0240201141026a2211200e4f0d00201a200e4f0d072011201a2000201141306c6a22102903002000201a41306c6a220529030054201041086a290300220f200541086a290300221354200f2013511b1b211a0b0240201a200e4f0d002004200e4f0d052000201a41306c6a22112903002000200441306c6a220429030054201141086a2205290300220f200441086a2210290300221354200f2013511b450d002006200441286a220b2903003703002007200441206a220c2903003703002008200441186a220d2903003703002009200441106a2212290300370300200a2010290300370300200220042903003703002005290300210f201141106a22142903002113201141186a22162903002115201141206a2219290300211720112903002118200b201141286a2203290300370300200c2017370300200d2015370300201220133703002010200f37030020042018370300200320062903003703002019200729030037030020162008290300370300201420092903003703002005200a29030037030020112002290300370300201a21040c010b0b200e41014b0d000b0b200241306a24000f0b41f8b7c00020042001104a000b41f8b7c0002004200e104a000b41e8b7c000201a2001104a000b41e8b7c000201a200e104a000b41b0b7c000200e2001104a000bf50b05087f027e107f017e017f230041306b22022400200041c07e6a2103200041506a21044100210520014132492106410121070240024002400340024002400240200720014f0d002004200741306c6a210803402008290300200841306a220929030054200841086a290300220a200841386a290300220b54200a200b511b0d0220092108200741016a22072001490d000b0b41002108200720014622090d030c010b41012108200720014622090d020b20060d012007417f6a220920014f0d022008450d032000200941306c6a2208290300210a20082000200741306c220c6a2209290300370300200241286a220d200841286a220e290300370300200241206a220f200841206a2210290300370300200241186a2211200841186a2212290300370300200241106a2213200841106a2214290300370300200241086a2215200841086a22162903003703002016200941086a22172903003703002014200941106a22182903003703002012200941186a22192903003703002010200941206a221a290300370300200e200941286a221b2903003703002002200a370300201b200d290300370300201a200f29030037030020192011290300370300201820132903003703002017201529030037030020092002290300370300024020074102490d0020002007417e6a220f41306c6a220d2903002008290300221c5a200d41086a221d290300220b2016290300220a5a200b200a511b0d002008200d2903003703002016201d2903003703002008290310210b2014200d41106a2903003703002011200e29030037030020132010290300370300201520122903003703002012200d41186a2903003703002010200d41206a290300370300200e200d41286a2903003703002002200b3703000240024002400240200f450d0020002007417d6a221641306c6a2208290300201c5a200841086a290300220b200a5a200b200a511b0d032003200c6a2108034020084188016a200841d8006a29030037030020084180016a200841d0006a290300370300200841f8006a200841c8006a290300370300200841f0006a200841c0006a290300370300200841e8006a200841386a290300370300200841e0006a200841306a2903003703002016450d022008290300210b200841086a210d200841506a21082016417f6a2116200b201c54200d290300220b200a54200b200a511b0d000b201641016a210f0c020b4100210f0c020b4100210f0b2000200f41306c6a210d0b200d201c370300200d200a3703082000200f41306c6a22082002290300370310200841286a2011290300370300200841206a2013290300370300200841186a20152903003703000b200541016a21050240200120076b220e4102490d002009290300220b20092903305a2017290300220a200941386a290300221c5a200a201c511b0d002009200941306a22082903003703002017200841086a2903003703002009290310211c2018200841106a2903003703002011201b2903003703002013201a290300370300201520192903003703002019200841186a290300370300201a200841206a290300370300201b200841286a2903003703002002201c370300410121120240200e4103490d00200b20092903605a200a200941e8006a290300221c5a200a201c511b0d00200941e0006a21164103210d41022117034020092017221241306c6a220841786a201641286a290300370300200841706a201641206a290300370300200841686a201641186a290300370300200841606a201641106a290300370300200841586a201641086a290300370300200841506a2016290300370300200d200e4f0d01200d41016a2216200d490d01200d41306c2110200d21172016210d200b200920106a221629030054200a201641086a290300221c54200a201c511b0d000b0b2008200b3703002008200a3703082009201241306c6a22082002290300370310200841286a2011290300370300200841206a2013290300370300200841186a20152903003703000b20054105490d000b410021090b200241306a240020090f0b41a0b7c00020092001104a000b41b0b7c00020072001104a000b9e0204047f017e017f017e230041206b220124000240410f10002202450d00200120023602102001420f370214200141106a41c9f5c100410f1029200141086a220220012802183602002001200129031037030020002001101b20022802002103200128020421042001280200210042002105200141106a41086a220642003703002001420037031020002003200141106a10022002200629030037030020012001290310370300024002402001411041b8d6c200410041001004417f460d002001420037031020014110200141106a41084100100441016a41084d0d01200129031021050b02402004450d00200010010b10ac012107200141206a240041d8f5c100410020052007561b0f0b41b2eac10041331040000b410f41011019000b3400200041f6f5c10036020420004100360200200041086a4207370200200041106a4188b8c000360200200041146a41153602000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a418cc3c000360200200041206a410a3602000b130020004103360204200041a4c9c0003602000bb05b05077f027e027f027e027f23004190026b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417e6a220441094b0d0002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020040e0a00060304010708050902000b200241096a2800002104200241056a280000210520022d0001210620022d00002101200341c8016a41026a2207200241046a2d00003a0000200341e8016a41086a2208200241156a290000370300200341e8016a410d6a22092002411a6a2900003700002003200241026a2f01003b01c80120032002410d6a2900003703e80120010d10200341c8006a41026a20072d00003a000020034188016a41086a200829030037030020034188016a410d6a2009290000370000200320032f01c8013b0148200320032903e80137038801200641ff01714101470d10200341db016a20034188016a41086a290300220a370000200341e0016a20034188016a410d6a290000220b370000200341e8006a41026a200341c8006a41026a2d000022023a0000200341e8016a41086a200a370300200341e8016a410d6a200b370000200320053600cb01200320043600cf01200320032f014822013b01c8012003200329038801220a3700d301200320013b01682003200a3703e801200320023a00ca01410021020c110b200141106a290300210a200141086a290300210b200141186a280200210c200141046a2802002107200241096a2800002104200241056a280000210520022d0001210620022d00002101200341c8016a41026a2208200241046a2d00003a0000200341e8016a41086a2209200241156a290000370300200341e8016a410d6a220d2002411a6a2900003700002003200241026a2f01003b01c80120032002410d6a2900003703e80120010d09200341c8006a41026a20082d00003a000020034188016a41086a200929030037030020034188016a410d6a200d290000370000200320032f01c8013b0148200320032903e80137038801200641ff01714101470d09200341c8016a41026a200341c8006a41026a2d000022023a0000200341db016a20034188016a41086a290300220e370000200341e0016a20034188016a410d6a290000220f370000200341e8006a41026a20023a0000200341e8016a41086a200e370300200341e8016a410d6a200f370000200320053600cb01200320043600cf01200320032f014822023b01c8012003200329038801220e3700d301200320023b01682003200e3703e801410021020c0a0b4128210441d2a9c20041d2a9c2004100410320022d000120022d00001b41ff017122021b20024103461b22050d4e2003200141046a2802003602e801200341c8016a41086a22024200370300200342003703c80141bf87c2004119200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368200341e8006a4110200341e8016a410410030c070b200341246a41026a200141076a2d00003a0000200341086a41086a200141186a290200370300200341086a410d6a2001411d6a2900003700002003200141056a2f00003b01242003200141106a290200370308200141046a2d00002108200141086a28020021062001410c6a2802002101200241096a2800002104200241056a280000210520022d0001210920022d00002107200341c8016a41026a220d200241046a2d00003a0000200341e8016a41086a220c200241156a290000370300200341e8016a410d6a22102002411a6a2900003700002003200241026a2f01003b01c80120032002410d6a2900003703e80120070d09200341286a41026a200d2d00003a0000200341a8016a41086a200c290300370300200341a8016a410d6a2010290000370000200320032f01c8013b0128200320032903e8013703a801200941ff01714101470d09200341db016a200341a8016a41086a290300220a370000200341e0016a200341a8016a410d6a290000220b370000200341e8006a41026a200341286a41026a2d000022023a0000200341e8016a41086a200a370300200341e8016a410d6a200b370000200320053600cb01200320043600cf01200320032f012822073b01c801200320032903a801220a3700d301200320073b01682003200a3703e801200320023a00ca01410021070c0a0b200141046a2802002107200241096a2800002104200241056a280000210520022d0001210620022d00002101200341c8016a41026a2208200241046a2d00003a0000200341e8016a41086a2209200241156a290000370300200341e8016a410d6a220d2002411a6a2900003700002003200241026a2f01003b01c80120032002410d6a2900003703e80120010d0a200341286a41026a20082d00003a0000200341c8006a41086a2009290300370300200341c8006a410d6a200d290000370000200320032f01c8013b0128200320032903e801370348200641ff01714101470d0a200341c8016a41026a200341286a41026a2d000022023a0000200341db016a200341c8006a41086a290300220a370000200341e0016a200341c8006a410d6a290000220b370000200341e8006a41026a20023a0000200341e8016a41086a200a370300200341e8016a410d6a200b370000200320053600cb01200320043600cf01200320032f012822023b01c80120032003290348220a3700d301200320023b01682003200a3703e801410021020c0b0b4128210441d2a9c20041d2a9c2004100410320022d000120022d00001b41ff017122021b20024103461b22050d4b2003200141046a2802003602e801200341c8016a41086a22024200370300200342003703c80141aff2c1004116200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368200341e8006a4110200341e8016a410410030c040b200141046a280200210d200241096a2800002104200241056a280000210520022d0001210620022d00002101200341a8016a41026a2207200241046a2d00003a0000200341c8016a41086a2208200241156a290000370300200341c8016a410d6a22092002411a6a2900003700002003200241026a2f01003b01a80120032002410d6a2900003703c80120010d0c200341c8006a41026a20072d00003a000020034188016a41086a200829030037030020034188016a410d6a2009290000370000200320032f01a8013b0148200320032903c80137038801200641ff01714101470d0c200341db016a20034188016a41086a290300220a370000200341e0016a20034188016a410d6a290000220b370000200341e8006a41026a200341c8006a41026a2d000022023a0000200341a8016a41086a200a370300200341a8016a410d6a200b370000200320053600cb01200320043600cf01200320032f014822013b01c8012003200329038801220a3700d301200320013b01682003200a3703a801200320023a00ca01410021020c0d0b4128210441d2a9c20041d2a9c2004100410320022d000120022d00001b41ff017122021b20024103461b22050d492003200141086a2903003703e801200341c8016a41086a22024200370300200342003703c80141e6f1c100411a200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368200341e8006a4110200341e8016a410810030c020b4128210441d2a9c20041d2a9c2004100410320022d000120022d00001b41ff017122021b20024103461b22050d482003200141086a2903003703e801200341c8016a41086a22024200370300200342003703c80141e286c2004117200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368200341e8006a4110200341e8016a410810030c010b4128210441d2a9c20041d2a9c2004100410320022d000120022d00001b41ff017122021b20024103461b22050d4720012d00012101200341c8016a41086a22024200370300200342003703c801418ef1c1004115200341c8016a1002200341e8006a41086a22042002290300370300200320032903c801370368200341e8006a411041b8d6c20041001003200320013a00e80120024200370300200342003703c8014192d8c1004119200341c8016a100220042002290300370300200320032903c801370368200341e8006a4110200341e8016a410110030b410021050c460b41012102412a210441faa9c20021050b200341c4006a41026a2201200341e8006a41026a2d00003a0000200341286a41086a2206200341e8016a41086a290300370300200341286a41106a200341e8016a41106a290300370300200320032f01683b0144200320032903e80137032820020d44200341bb016a2006290300370000200341c0016a200341356a290000370000200320032f01443b01a801200320053600ab01200320043600af01200320032903283700b301200320012d00003a00aa01200341c8016a41086a22024200370300200342003703c8014180f2c1004112200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368200341e8006a411041b8d6c200410041001004417f460d42200342103702cc012003200341e8006a3602c801200341e8016a200341c8016a103920032802e8012202450d2620032802ec012101200341f0016a28020020074d0d0e200341a8016a200220074105746a2204460d132004200341a8016a412010d1024521042001450d410c400b4101210741faa9c2002105412a21040b20034184016a41026a2202200341e8006a41026a2d00003a0000200341c8006a41086a2209200341e8016a41086a290300370300200341c8006a41106a200341e8016a41106a290300370300200320032f01683b018401200320032903e80137034820070d4220034188016a41136a200929030037000020034188016a41186a200341c8006a410d6a2207290000370000200320032f0184013b0188012003200536008b012003200436008f012003200329034837009301200320022d00003a008a012002200341246a41026a2d00003a0000200341e8006a41086a200341086a41086a290300370300200341e8006a410d6a2204200341086a410d6a290000370000200320032f01243b0184012003200329030837036841012102200841ff01714101470d06200341e8016a200610a80120032d00e8014101470d0d200341e6006a20032d00eb013a0000200341e0016a20034181026a290000220a370300200341d8016a200341f9016a290000370300200341c8016a41086a200341f1016a290000370300200341c8006a41086a200341fc016a290200370300200341d5006a200a370000200320032900e9013703c801200320032f00e9013b01642003200341f4016a290200370348200341e8016a41086a28020021014100210220032802ec0121060c0e0b4101210241faa9c2002105412a21040b200341086a41026a2201200341e8006a41026a2d00003a0000200341a8016a41086a2206200341e8016a41086a290300370300200341a8016a41106a200341e8016a41106a290300370300200320032f01683b0108200320032903e8013703a80120020d402003419b016a2006290300370000200341a0016a200341b5016a290000370000200320032f01083b0188012003200536008b012003200436008f01200320032903a80137009301200320012d00003a008a01411210002202450d20200320023602e801200342123702ec01200341e8016a419885c20041121029200341c8016a41086a220220032802f001360200200320032903e8013703c80120034188016a200341c8016a101b2002280200210420032802cc01210620032802c801210120024200370300200342003703c80120012004200341c8016a1002200341e8006a41086a2002290300370300200320032903c80137036841002102200341e8006a411041b8d6c200410041001004417f460d0820034180026a4200370300200341e8016a41106a4200370300200341e8016a41086a4200370300200342003703e801200341e8006a4110200341e8016a4120410010042202417f460d1e2002411f4d0d1e200341c8016a41186a2202200341e8016a41186a290300370300200341c8016a41106a200341e8016a41106a290300370300200341c8016a41086a200341e8016a41086a2204290300370300200320032903e8013703c8012003410a6a20032d00ca013a00002004200341db016a290000370300200341f5016a2002290000370000200320032f01c8013b0108200320032900d3013703e80120032800cb01210520032800cf012104410121022006450d3b0c3a0b4101210241faa9c2002105412a21040b200341c4006a41026a2201200341e8006a41026a2d00003a0000200341286a41086a2206200341e8016a41086a290300370300200341286a41106a200341e8016a41106a290300370300200320032f01683b0144200320032903e80137032820020d3e200341bb016a2006290300370000200341c0016a200341356a290000370000200320032f01443b01a801200320053600ab01200320043600af01200320032903283700b301200320012d00003a00aa01411210002202450d1f200320023602e801200342123702ec01200341e8016a419885c20041121029200341c8016a41086a220220032802f001360200200320032903e8013703c801200341a8016a200341c8016a101b2002280200210420032802cc01210520032802c801210120024200370300200342003703c80120012004200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368410021020240200341e8006a411041b8d6c200410041001004417f460d0020034180026a4200370300200341e8016a41106a4200370300200341e8016a41086a4200370300200342003703e801200341e8006a4110200341e8016a4120410010042202417f460d1e2002411f4d0d1e200341c8016a41186a200341e8016a41186a290300370300200341c8016a41106a200341e8016a41106a290300370300200341c8016a41086a200341e8016a41086a290300370300200320032903e8013703c801410121020b02402005450d00200110010b2002450d0341c985c2002105412321040c3e0b4101210241faa9c2002105412a21040b200341c4006a41026a2201200341e8006a41026a2d00003a0000200341286a41086a2206200341a8016a41086a290300370300200341286a41106a200341a8016a41106a290300370300200320032f01683b0144200320032903a80137032820020d3c200341fb016a200629030037000020034180026a200341356a290000370000200320032f01443b01e801200320053600eb01200320043600ef01200320032903283700f301200320012d00003a00ea01200341c8016a41086a22024200370300200342003703c8014180f2c1004112200341c8016a1002200341e8006a41086a2002290300370300200320032903c80137036841002102200341e8006a411041b8d6c200410041001004417f460d02200342103702ac012003200341e8006a3602a801200341c8016a200341a8016a103920032802c8012205450d1f200341d0016a280200210220032802cc0121040c030b200341e8016a41026a20034184016a41026a2d000022023a0000200341e8016a41136a200341e8006a41086a290300220a370000200341e8016a41186a2004290000220b370000200341e4006a41026a20023a0000200341c8006a41086a200a3703002007200b370000200320063600eb01200320013600ef01200320032f01840122023b01e80120032003290368220a3700f301200320023b01642003200a370348410021020c070b200341c8016a41086a22024200370300200342003703c8014180f2c1004112200341c8016a1002200341e8006a41086a2002290300370300200320032903c8013703684100210c200341e8006a411041b8d6c200410041001004417f460d07200342103702cc012003200341e8006a3602c801200341e8016a200341c8016a103920032802e8012206450d20200341f0016a280200210c20032802ec0121100c080b41012105410021040b200341c8016a41086a22014200370300200342003703c8014192f2c100411d200341c8016a1002200341e8006a41086a2001290300370300200320032903c801370368200341e8006a411041b8d6c200410041001004417f460d01200341003602c801200341e8006a4110200341c8016a41044100100441016a41044d0d1520032802c80121012004450d310c300b20060d310c320b4104210120040d2e0c2f0b2001450d33200210010c330b4180c9c2002106411521010b200341c4006a41026a2204200341e4006a41026a2d00003a0000200341286a41086a2205200341c8006a41086a290300370300200341286a41106a200341c8006a41106a290300370300200320032f01643b01442003200329034837032802402002450d0020012104200621050c340b200341bb016a2005290300370000200341c0016a200341356a290000370000200320032f01443b01a801200320063600ab01200320013600af01200320032903283700b301200320042d00003a00aa01411210002202450d18200320023602e801200342123702ec01200341e8016a419885c20041121029200341c8016a41086a220220032802f001360200200320032903e8013703c80120034188016a200341c8016a101b2002280200210420032802cc01210520032802c801210120024200370300200342003703c80120012004200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368410021020240200341e8006a411041b8d6c200410041001004417f460d0020034180026a4200370300200341e8016a41106a4200370300200341e8016a41086a4200370300200342003703e801200341e8006a4110200341e8016a4120410010042202417f460d182002411f4d0d18200341c8016a41186a200341e8016a41186a290300370300200341c8016a41106a200341e8016a41106a290300370300200341c8016a41086a200341e8016a41086a290300370300200320032903e8013703c801410121020b02402005450d00200110010b02402002450d0041ec85c2002105412621040c340b200341c8016a41086a22024200370300200342003703c8014180f2c1004112200341c8016a1002200341e8006a41086a2002290300370300200320032903c80137036841002102200341e8006a411041b8d6c200410041001004417f460d03200342103702cc012003200341e8006a3602c801200341e8016a200341c8016a103920032802e8012206450d1b200341f0016a280200210220032802ec01210c0c040b41012106410021100b200341a8016a20066b220541606a2108200541406a2109200541a07f6a210d2006200c41057422116a210741002102200621040340200720046b41ff004d0d0420052002460d05200620026a2201200341a8016a412010d102450d0520082002460d05200141206a200341a8016a412010d102450d0520092002460d05200141c0006a200341a8016a412010d102450d05200d2002460d0520014180016a210420024180016a2102200141e0006a200341a8016a412010d1020d000c050b0b4101210420010d2c0c2d0b410121064100210c0b20034188016a20066b220541606a2108200541406a2109200541a07f6a210d2006200241057422106a210741002102200621040340200720046b41ff004d0d0320052002460d04200620026a220120034188016a412010d102450d0420082002460d04200141206a20034188016a412010d102450d0420092002460d04200141c0006a20034188016a412010d102450d04200d2002460d0420014180016a210420024180016a2102200141e0006a20034188016a412010d1020d000c040b0b200620026a2101201120026b210203402002450d04200341a8016a2001460d01200241606a21022001200341a8016a412010d1022104200141206a210120040d000b0b41aa85c2002105411f21042010450d2c200610010c2c0b200620026a2101201020026b210203402002450d0320034188016a2001460d01200241606a2102200120034188016a412010d1022104200141206a210120040d000b0b419286c200210541222104200c450d2a200610010c2a0b410f10002202450d12200320023602e8012003420f3702ec01200341e8016a41c9f5c100410f1029200341c8016a41086a220220032802f001360200200320032903e8013703c801200341a8016a200341c8016a101b2002280200210420032802cc01210520032802c80121012003427f3703e80120024200370300200342003703c80120012004200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368200341e8006a4110200341e8016a4108100302402005450d00200110010b200341e8016a41186a2201200341a8016a41186a290300370300200341e8016a41106a200341a8016a41106a290300370300200341e8016a41086a200341a8016a41086a290300370300200320032903a8013703e801200c2010470d01200c41016a2202200c490d1d200c4101742204200220022004491b2210ad420586220a422088a70d1d200aa722024100480d1d200c450d0320021000220d450d14200d20062002200c4105742204200420024b1b10ce021a200610010c040b0240200c450d00200610010b411510002202450d12200320023602e801200342153702ec01200341e8016a419bf3c10041151029200341c8016a41086a220220032802f001360200200320032903e8013703c801200341a8016a200341c8016a101b2002280200210420032802cc01210520032802c801210120024200370300200342003703c80120012004200341c8016a1002200341e8006a41086a2002290300370300200320032903c80137036841002102200341e8006a411041b8d6c200410041001004417f460d01200342103702cc012003200341e8006a3602c801200341e8016a200341c8016a103920032802e8012206450d15200341f0016a280200210220032802ec0121042005450d1b0c1a0b2006210d0c020b410121064100210420050d180c190b20021000220d450d100b200d200c4105746a220220032903e801370000200241186a2001290300370000200241106a200341e8016a41106a290300370000200241086a200341e8016a41086a290300370000024002400240200c41016a2202413f4b0d00410110002206450d13200620024102743a0000410121044101210520020d010c020b02402002418080014f0d0041022104410210002206450d15200620024102744101723b00000c010b024020024180808080044f0d0041042104410410002206450d16200620024102744102723600000c010b410110002201450d16200141033a000041052104410510002206450d17200620012d00003a000020011001200620023600010b200c41057441206a210820042105200d210703402007210202400240024002402004200522016b41204f0d00200141206a22052001490d1e20044101742207200520052007491b22074100480d1e2004450d01200710002209450d112009200620072004200420074b1b10ce02210420061001200421060c020b200141206a21050c020b200710002206450d0f0b200721040b200241206a2107200620016a22012002290000370000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a290000370000200841606a22080d000b0b200341c8016a41086a22024200370300200342003703c8014180f2c1004112200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368200341e8006a411020062005100302402004450d00200610010b2010450d23200d10010c230b4180cbc000104d000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b411241011019000b411241011019000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b411241011019000b41b2eac10041331040000b200741011019000b41b2eac10041331040000b410f41011019000b411541011019000b200241011019000b410141011019000b41b2eac10041331040000b410241011019000b410441011019000b410141011019000b410541011019000b200110010b200341e8016a41186a220720034188016a41186a290300370300200341e8016a41106a220820034188016a41106a290300370300200341e8016a41086a220920034188016a41086a29030037030020032003290388013703e80102400240024020022004470d00200241016a22012002490d0320024101742204200120012004491b2204ad420586220a422088a70d03200aa722014100480d032002450d01200110002205450d062005200620012002410574220d200d20014b1b10ce021a200610010c020b200621050c010b200110002205450d040b200520024105746a220120032903e801370000200141186a2007290300370000200141106a2008290300370000200141086a2009290300370000200320043602ec01200320053602e8012003200241016a3602f001200341a8016a200341e8016a10a202411210002202450d01200320023602e801200342123702ec01200341e8016a419885c20041121029200341c8016a41086a220220032802f001360200200320032903e8013703c80120034188016a200341c8016a101b2002280200210420032802cc01210520032802c801210120024200370300200342003703c80120012004200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368200341e8006a4110200341a8016a4120100302402005450d00200110010b410f10002202450d02200320023602e8012003420f3702ec01200341e8016a41c9f5c100410f1029200341c8016a41086a220220032802f001360200200320032903e8013703c80120034188016a200341c8016a101b2002280200210420032802cc01210520032802c80121012003427f3703e80120024200370300200342003703c80120012004200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368200341e8006a4110200341e8016a410810032005450d0b200110010c0b0b1018000b411241011019000b410f41011019000b200141011019000b200510010b0240200220014d0d00200341e8016a200d10a3022105410d21040c070b41f986c2002105413921040c060b200110010b024002402002450d00200341c4006a41026a200341086a41026a2d00003a0000200341286a41086a200341e8016a41086a290300370300200341286a410d6a200341e8016a410d6a290000370000200320032f01083b0144200320032903e801370328410021020c010b41012102411a210441b486c20021050b20034184016a41026a2201200341c4006a41026a2d00003a0000200341c8006a41086a2206200341286a41086a290300370300200341c8006a41106a200341286a41106a290300370300200320032f01443b0184012003200329032837034820020d04200341bb016a2006290300370000200341c0016a200341d5006a290000370000200320032f0184013b01a801200320053600ab01200320043600af01200320032903483700b301200320012d00003a00aa010240024002400240411510002202450d00200320023602e801200342153702ec01200341e8016a419bf3c10041151029200341c8016a41086a220220032802f001360200200320032903e8013703c801200341a8016a200341c8016a101b2002280200210420032802cc01210620032802c801210120024200370300200342003703c80120012004200341c8016a1002200341e8006a41086a2002290300370300200320032903c801370368410021020240200341e8006a411041b8d6c200410041001004417f460d00200342103702cc012003200341e8006a3602c801200341e8016a200341c8016a103920032802e8012204450d02200341f0016a280200210220032802ec0121052006450d040c030b410121044100210520060d020c030b411541011019000b41b2eac10041331040000b200110010b02400240200220074d0d0020034188016a200420074105746a2201460d01200120034188016a412010d102450d010b02402005450d00200410010b41ce86c2002105411421040c050b20042002417f6a22064105746a2202290000210a2002290008210b2002290010210e200141186a200241186a2900003700002001200e3700102001200b3700082001200a370000200320053602ec01200320043602e801200320063602f001200341a8016a200341e8016a10a202024002400240411210002202450d00200320023602e801200342123702ec01200341e8016a419885c20041121029200341c8016a41086a220220032802f001360200200320032903e8013703c80120034188016a200341c8016a101b2002280200210420032802cc01210520032802c801210120024200370300200342003703c80120012004200341c8016a1002200341e8006a41086a22042002290300370300200320032903c801370368200341e8006a4110100a02402005450d00200110010b200341e8016a41186a20034188016a41186a290300370300200341e8016a41106a20034188016a41106a290300370300200341e8016a41086a20034188016a41086a29030037030020032003290388013703e80110ac01210a20024200370300200342003703c80141e286c2004117200341c8016a100220042002290300370300200320032903c801370368200341e8006a411041b8d6c200410041001004417f460d01200342003703c8010240200341e8006a4110200341c8016a41084100100441016a41084d0d0020032903c801210b410f10002202450d03200320023602c8012003420f3702cc01200341c8016a41c9f5c100410f1029200341c8006a41086a220220032802d001360200200320032903c801370348200341e8016a200341c8006a101b20022802002101200328024c2104200328024821022003200b200a7c370348200341c8016a41086a22054200370300200342003703c80120022001200341c8016a1002200341e8006a41086a2005290300370300200320032903c801370368200341e8006a4110200341c8006a410810032004450d07200210010c070b41b2eac10041331040000b411241011019000b41c3d7c10041221040000b410f41011019000b200210010b2004450d00200341e8016a41186a200341a8016a41186a290300370300200341e8016a41106a200341a8016a41106a290300370300200341e8016a41086a200341a8016a41086a290300370300200320032903a8013703e801411c10002202450d03200320023602c8012003421c3702cc01200341c8016a41d6f0c100411c102920034188016a41086a220220032802d001360200200320032903c80137038801200341e8016a20034188016a101b20022802002105200328028c0121062003280288012104410410002201450d042001200c360000411410002202450d0520022001280000360000200110012002410c6a200a3700002002200b370004200341c8016a41086a22014200370300200342003703c80120042005200341c8016a1002200341e8006a41086a2001290300370300200320032903c801370368200341e8006a4110200241141003200210012006450d01200410010c010b41b287c2002105410d21040c010b410021050b200020043602042000200536020020034190026a24000f0b411c41011019000b410441011019000b411441011019000bc605010b7f230041206b22022400024002400240024002400240411510002203450d002002200336021020024215370214200241106a419bf3c10041151029200241086a220320022802183602002002200229031037030020002002101b200328020021042002280204210520022802002106200128020021070240024002400240024020012802082200413f4b0d0041012108410110002209450d06200920004102743a00004101210a20000d010c020b02402000418080014f0d0041022108410210002209450d07200920004102744101723b00000c010b024020004180808080044f0d0041042108410410002209450d08200920004102744102723600000c010b410110002203450d08200341033a000041052108410510002209450d09200920032d00003a000020031001200920003600010b2000410574210b2008210a03402007210002400240024002402008200a22036b41204f0d00200341206a220a2003490d0620084101742207200a200a2007491b22074100480d062008450d0120071000220c450d07200c200920072008200820074b1b10ce02210820091001200821090c020b200341206a210a0c020b200710002209450d050b200721080b200041206a2107200920036a22032000290000370000200341186a200041186a290000370000200341106a200041106a290000370000200341086a200041086a290000370000200b41606a220b0d000b0b200241106a41086a220042003703002002420037031020062004200241106a1002200241086a200029030037030020022002290310370300200241102009200a100302402008450d00200910010b02402005450d00200610010b0240200141046a280200450d00200128020010010b200241206a24000f0b1018000b200741011019000b411541011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000b980c03067f037e047f230041306b22022400200241206a41086a22034200370300200242003703204180f2c1004112200241206a1002200241086a20032903003703002002200229032037030002400240024002400240024002400240024002400240024002400240024002402002411041b8d6c200410041001004417f460d002002421037021420022002360210200241206a200241106a103920022802202204450d06200228022421050240200241286a280200220620014d0d00200420014105746a22032000460d0220032000412010d102450d020b41b287c20021032005450d0220041001200241306a240041b287c2000f0b200241306a240041b287c2000f0b20042006417f6a22014105746a22072900002108200729000821092007290010210a200341186a200741186a2900003700002003200a37001020032009370008200320083700000240024002402001413f4b0d004101210741011000220b450d0c200b20014102743a00004101210c20010d010c020b02402001418080014f0d004102210741021000220b450d0d200b20014102744101723b00000c010b024020014180808080044f0d004104210741041000220b450d0e200b20014102744102723600000c010b410110002203450d0e200341033a00004105210741051000220b450d0f200b20032d00003a000020031001200b20013600010b200641057441606a210d2007210c2004210603402006210302400240024002402007200c22016b41204f0d00200141206a220c2001490d0720074101742206200c200c2006491b22064100480d072007450d0120061000220e450d08200e200b20062007200720064b1b10ce022107200b10012007210b0c020b200141206a210c0c020b20061000220b450d060b200621070b200341206a2106200b20016a22012003290000370000200141186a200341186a290000370000200141106a200341106a290000370000200141086a200341086a290000370000200d41606a220d0d000b0b200241206a41086a22034200370300200242003703204180f2c1004112200241206a1002200241086a20032903003703002002200229032037030020024110200b200c100302402007450d00200b10010b02402005450d00200410010b411c10002203450d05200220033602202002421c370224200241206a41d6f0c100411c1029200241086a220320022802283602002002200229032037030020002002101b200328020021072002280204210c20022802002101200241206a41086a220b42003703002002420037032020012007200241206a10022003200b2903003703002002200229032037030020024110100a0240200c450d00200110010b411210002203450d062002200336022020024212370224200241206a41c5f2c10041121029200241086a220320022802283602002002200229032037030020002002101b2003280200210c2002280204210b20022802002107200241206a41086a22014200370300200242003703202007200c200241206a1002200320012903003703002002200229032037030020024110100a0240200b450d00200710010b10ac012108200142003703002002420037032041e286c2004117200241206a100220032001290300370300200220022903203703002002411041b8d6c200410041001004417f460d072002420037032020024110200241206a41084100100441016a41084d0d0320022903202109410f10002203450d08200220033602202002420f370224200241206a41c9f5c100410f1029200241086a220320022802283602002002200229032037030020002002101b200328020021072002280204210c200228020021012002200920087c370310200241206a41086a220b42003703002002420037032020012007200241206a10022003200b2903003703002002200229032037030020024110200241106a4108100341002103200c450d00200110010b200241306a240020030f0b1018000b200641011019000b41b2eac10041331040000b41b2eac10041331040000b411c41011019000b411241011019000b41c3d7c10041221040000b410f41011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000bc71403037f067e077f230041f0016b2208240002400240024002400240024002400240024002400240200728020022094100480d00200941ffffffff07460d002007200941016a36020002400240200741046a220a200410f7012209450d002009280200450d00200941106a290300210b200941086a290300210c0c010b200841c0006a20072802102004200741146a280200280214110500200841c8006a290300210b2008290340210c0b20072007280200417f6a360200200841d0006a41086a2209420037030020084200370350024002402002450d0041accbc1004114200841d0006a100220084188016a41086a2009290300370300200820082903503703880120084188016a411041b8d6c200410041001004417f460d06200842003703582008420037035020084188016a4110200841d0006a4110410010042209417f460d032009410f4d0d03200841d8006a290300210d0c010b0240200c200b844200510d004189b0c2004114200841d0006a100220084188016a41086a200841d0006a41086a290300370300200820082903503703880120084188016a411041b8d6c200410041001004417f460d08200842003703582008420037035020084188016a4110200841d0006a4110410010042209417f460d052009410f4d0d05200841d8006a290300210d0c010b41f5afc2004114200841d0006a100220084188016a41086a200841d0006a41086a290300370300200820082903503703880120084188016a411041b8d6c200410041001004417f460d08200842003703582008420037035020084188016a4110200841d0006a4110410010042209417f460d062009410f4d0d06200841d8006a290300210d0b2008290350210e2001290310220f200141186a2903002210844200510d02200841306a200e200d200f201010d202200142002001290308220e20082903307d220d200d200e56200d507222091b370308024002402009450d0041c789c2002101412221090c010b200728020022014100480d01200141ffffffff07460d012007200141016a36020002400240200a200310f7012201450d002001280200450d00200141106a290300210d200141086a290300210e0c010b200841206a20072802102003200741146a280200280214110500200841286a290300210d2008290320210e0b20072007280200417f6a3602000240200e20057d220f200e56200d20067d200e200554ad7d220e200d56200e200d511b4101470d0041d1c4c2002101411d21090c010b0240200c200b8450450d00200841106a10a5022008290310200556200841186a290300220d200656200d2006511b450d0041eec4c2002101411f21090c010b411e21092003109d0222010d00200728020022014100480d01200141ffffffff07460d012007200141016a36020002400240200a200410f7012201450d002001280200450d00200141106a290300210d200141086a29030021100c010b200820072802102004200741146a280200280214110500200841086a290300210d200829030021100b20072007280200417f6a22093602000240201020057c220b2010542201200d20067c2001ad7c2210200d542010200d511b450d00418dc5c2002101412d21090c010b41002101024020032004460d0020032004412010d102450d0020090d0a2007417f36020020084188016a41186a2209200341186a29000037030020084188016a41106a2202200341106a29000037030020084188016a41086a2211200341086a2900003703002008200329000037038801200841d0006a200a20084188016a108d010240024020082802504101470d00200841d0006a41086a2802002109200841d0006a41106a2802002102200841a0a1c1003602c001200842003702c4012009200241306c6a41e8026a210920084188016a200841c0016a108e0120084188016a108f010c010b200841b8016a20084184016a28020036020020084188016a41286a200841fc006a290200370300200841a8016a200841f4006a2902003703002009200841ec006a2902003703002002200841e4006a2902003703002011200841dc006a2902003703002008200829025437038801200841c0016a41286a4200370300200841003602d801200842003703c001200841a0a1c1003602e40120084188016a200841c0016a10900121090b2009200f37030820094201370300200941106a200e3703002007200728020041016a220936020020090d0a2007417f36020020084188016a41186a2209200441186a29000037030020084188016a41106a200441106a29000037030020084188016a41086a2202200441086a2900003703002008200429000037038801200841d0006a200a20084188016a108d010240024020082802504101470d00200841d0006a41086a2802002109200841e0006a2802002102200841a0a1c1003602c001200842003702c4012009200241306c6a41e8026a210920084188016a200841c0016a108e0120084188016a108f010c010b200841b8016a20084184016a28020036020020084188016a41286a200841fc006a290200370300200841a8016a200841f4006a2902003703002009200841ec006a29020037030020084198016a200841e4006a2902003703002002200841dc006a2902003703002008200829025437038801200841c0016a41286a4200370300200841003602d801200842003703c001200841a0a1c1003602e40120084188016a200841c0016a10900121090b2009200b37030820094201370300200941106a20103703002007200728020041016a360200200841d0006a41186a2202200341186a290000370300200841d0006a41106a220a200341106a290000370300200841d0006a41086a2211200341086a29000037030020084188016a41086a2212200441086a29000037030020084188016a41106a2213200441106a29000037030020084188016a41186a2214200441186a2900003703002008200329000037035020082004290000370388010240200741246a22042802002209200741206a280200470d00200941016a22032009490d0c20094101742215200320032015491b2216ad42d0007e220d422088a70d0c200da722034100480d0c024002402009450d002007411c6a2802002117200310002215450d0f201520172003200941d0006c2209200920034b1b10ce021a201710010c010b200310002215450d0e0b200741206a20163602002007411c6a2015360200200741246a28020021090b2007411c6a280200200941d0006c6a2207200637030820072005370300200720082903503703102007200829038801370330200741186a2011290300370300200741206a200a290300370300200741286a2002290300370300200741c8006a2014290300370300200741c0006a2013290300370300200741386a20122903003703002004200428020041016a3602000b0b2000200936020420002001360200200841f0016a24000f0b10f801000b41b2eac10041331040000b41b0ffc000104d000b41b2eac10041331040000b41c3d7c10041221040000b41b2eac10041331040000b41c3d7c10041221040000b41c3d7c10041221040000b109201000b1018000b200341081019000bc60102027f017e230041206b22012400200141106a41086a220242003703002001420037031041a1abc200411b200141106a1002200141086a20022903003703002001200129031037030002402001411041b8d6c200410041001004417f460d002001420037031820014200370310024020014110200141106a4110410010042202417f460d002002410f4d0d00200129031021032000200141186a29030037030820002003370300200141206a24000f0b41b2eac10041331040000b41c3d7c10041221040000b4501017f230041c0006b22012400200141386a2000410c6a28020036020020012000290204370330200141086a200141306a10ea01200141086a10ee01200141c0006a24000b960101027f230041e0066b22012400200141a0026a200010bb0120012802a0022100200141c4046a200141a0026a410472419c0210ce021a02402000410b470d00200141e0066a240041000f0b200141046a200141c4046a419c0210ce021a024041a00210002202450d0020022000360200200241046a200141046a419c0210ce021a200141e0066a240020020f0b41a00241081019000ba20801067f230041f0006b22022400200241003a00502001200128020822032001280200220420012802042205200241d0006a41012003100441016a220341014b6a220636020802400240024020034102490d0020022d0050220341f0014f0d01410121010c020b200041023a0000200241f0006a24000f0b024002400240024002400240200341847e6a220341034b0d0002400240024020030e0400040102000b200241003b0150200141086a410020042005200241d0006a41022006100422012001417f461b2203410220034102491b20066a36020041012101200341014d0d0641ef01210320022f015041ef014b0d08200041023a0000200241f0006a24000f0b20024100360250200141086a410020042005200241d0006a41042006100422012001417f461b2201410420014104491b20066a360200200041023a0000200241f0006a24000f0b200241d0006a41186a4200370300200241d0006a41106a4200370300200241d0006a41086a42003703002002420037035041002107200141086a410020042005200241d0006a41202006100422012001417f461b2201412020014120491b20066a3602002001411f4d0d022002412e6a20022d00523a0000200241106a41086a200241df006a290000370300200241106a41106a200241e7006a290000370300200241106a41186a200241d0006a411f6a2d00003a0000200220022f01503b012c2002200229005737031020022800532103410121070c030b200041023a0000200241f0006a24000f0b20024100360250200141086a410020042005200241d0006a41042006100422012001417f461b2201410420014104491b20066a360200200141034d0d0341ffff03210341012101200228025041ffff034b0d04200041023a0000200241f0006a24000f0b0b200241cc006a41026a22012002412c6a41026a2d00003a0000200241306a41086a2206200241106a41086a290300370300200241306a41106a2204200241106a41106a290300370300200241306a41186a2205200241106a41186a2d00003a0000200220022f012c3b014c2002200229031037033002402007450d002002410c6a41026a20012d00003a0000200241d0006a41086a2006290300370300200241d0006a41106a2004290300370300200241d0006a41186a20052d00003a0000200220022f014c3b010c20022002290330370350410021010c030b200041023a0000200241f0006a24000f0b200041023a0000200241f0006a24000f0b200041023a0000200241f0006a24000f0b200020022f010c3b0001200020013a0000200041046a2003360200200041086a2002290350370200200041036a2002410e6a2d00003a0000200041106a200241d0006a41086a290300370200200041186a200241d0006a41106a290300370200200041206a200241d0006a41186a280200360200200241f0006a24000bd70101027f024002400240024002402000280200220141054b0d0020010e06040404010203040b02402000410c6a2802002202450d0020002802042101200241186c210203400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141186a2101200241686a22020d000b0b200041086a280200450d03200041046a28020010010f0b200041086a280200450d02200028020410010f0b200041086a280200450d01200028020410010f0b200041086a280200450d00200028020410010f0b0b960101027f230041e0066b22012400200141a0026a200010a60120012802a0022100200141c4046a200141a0026a410472419c0210ce021a02402000410b470d00200141e0066a240041000f0b200141046a200141c4046a419c0210ce021a024041a00210002202450d0020022000360200200241046a200141046a419c0210ce021a200141e0066a240020020f0b41a00241081019000bb4b40208057f047e0f7f017e017f017e067f047e230041b00c6b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280200417f6a220441094b0d0002400240024002400240024002400240024020040e0a00060304010708050a02000b200341e0026a41026a22052001410f6a2d00003a0000200341e8036a41086a2206200141206a290300370300200341e8036a410d6a2207200141256a290000370000200320012f000d3b01e0022003200141186a2903003703e803200141386a2903002108200141306a2903002109200141c8006a290300210a200141c0006a290300210b2001410c6a2d0000210c200141106a280200210d200141146a280200210e200141086a2802002104200341e4026a41026a220f200241046a2d00003a000020034188046a41086a2210200241156a29000037030020034188046a410d6a22112002411a6a2900003700002003200241026a2f01003b01e40220032002410d6a2900003703880420022d0001211220022d00002113200441037122044102460d0c20044103470d69200341e8046a41026a2214200341e0026a41026a2d00003a0000200341d0056a41086a2205200341e8036a41086a290300370300200341d0056a410d6a2206200341e8036a410d6a290000370000200320032f01e0023b01e804200320032903e8033703d00541d2a9c20041d2a9c200410041032012201341ff01711b41ff017122021b20024103461b22040d262003419c036a41026a20142d00003a0000200341b0056a41086a2005290300370300200341b0056a410d6a2006290000370000200320032f01e8043b019c03200320032903d0053703b00541012102200c41ff01714101470d42200341900a6a200d10a80120032d00900a4101470d7d200341ea026a20032d00930a3a0000200341c8046a41086a200341a40a6a290200370300200341d5046a200341a90a6a290000370000200320032f00910a3b01e80220032003419c0a6a2902003703c804200341900a6a41086a28020021144100210220032802940a210d0c7e0b200141186a2903002108200141106a29030021092001410c6a280200210d200141086a2d0000210520012d00092113200341a8046a41026a200241046a2d00003a000020034188056a41086a200241156a29000037030020034188056a410d6a2002411a6a2900003700002003200241026a2f01003b01a80420032002410d6a290000370388052005410771417e6a220641044b0d67200241096a2800002114200241056a280000210420022d0001210720022d00002102024020060e05001c1a1b19000b200341b0056a41026a2206200341a8046a41026a2d00003a0000200341900a6a41086a221320034188056a41086a290300370300200341900a6a410d6a220e20034188056a410d6a290000370000200320032f01a8043b01b00520032003290388053703900a200241ff01710d2b200341e8046a41026a20062d00003a0000200341d0056a41086a2013290300370300200341d0056a410d6a200e290000370000200320032f01b0053b01e804200320032903900a3703d005200741ff01714101470d2b200341b3036a200341d0056a41086a290300220a370000200341b8036a200341d0056a410d6a290000220b370000200341b0056a41026a200341e8046a41026a2d000022023a0000200341900a6a41086a200a370300200341900a6a410d6a200b370000200320043600a303200320143600a703200320032f01e80422063b01a003200320032903d005220a3700ab03200320063b01b0052003200a3703900a200320023a00a203410021020c2c0b200320012f000a3b018003200141c0006a290300210b200141386a29030021092001410c6a2802002107200141106a2802002105200141146a2802002112200141186a28020021132001411c6a2802002106200141206a2903002108200141286a28020021102001412c6a280200210f200141306a280200210e200141346a2802002111200141c8006a290300210a200141086a2d0000210d20012d0009210c200341e8026a41026a2215200241046a2d00003a0000200341a8046a41086a2216200241156a290000370300200341a8046a410d6a22172002411a6a2900003700002003200241026a2f01003b01e80220032002410d6a2900003703a804200241096a2800002114200241056a280000210420022d0001211820022d00002102200d41037122194102460d0820194103470d65200320053602ec03200320073602e803200320123602f0032003200636028c04200320133602880420032008a7221736029004200341d0056a41026a220c200341e8026a41026a2d00003a0000200341900a6a41086a2215200341a8046a41086a290300370300200341900a6a410d6a2216200341a8046a410d6a290000370000200320032f01e8023b01d005200320032903a8043703900a200241ff01710d0b20034188056a41026a200c2d00003a0000200341f0076a41086a2015290300370300200341f0076a410d6a2016290000370000200320032f01d0053b018805200320032903900a3703f007201841ff01714101470d0b200341a0036a41026a20034188056a41026a2d000022023a0000200341b3036a200341f0076a41086a2903002208370000200341b8036a200341f0076a410d6a290000220a370000200341d0056a41026a20023a0000200341900a6a41086a2008370300200341900a6a410d6a200a370000200320043600a303200320143600a703200320032f01880522023b01a003200320032903f00722083700ab03200320023b01d005200320083703900a410021020c0c0b200320012f010a3b0188042001410c6a2801002112200141106a2903002108200141186a280200210f2001411c6a2802002110200141206a2903002109200141286a2d00002111200141086a2d0000210420012d0009210e200341a8046a41026a2206200241046a2d00003a0000200341d0056a41086a2207200241156a290000370300200341d0056a410d6a22132002411a6a2900003700002003200241026a2f01003b01a80420032002410d6a2900003703d00520022d0001210520022d0000210d200441077122044102460d1420044103460d1320044104470d6341d2a9c20041d2a9c200410041032005200d41ff01711b41ff017122021b20024103461b22040d232003200e3a00900a200341d0036a41086a22024200370300200342003703d0034192d8c1004119200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c0034101210d200341c0036a4110200341900a6a410110030c430b200341900a6a41206a200141286a290300370300200341900a6a41186a200141206a290300370300200341900a6a41106a200141186a290300370300200341900a6a41086a200141106a2903003703002003200141086a2903003703900a200341f0076a41206a200241206a280200360200200341f0076a41186a200241186a290200370300200341f0076a41106a200241106a290200370300200341f0076a41086a200241086a290200370300200320022902003703f007200341d0016a200341900a6a200341f0076a10a10220032802d401211420032802d00121044101210d4101210e0c9f010b20034180036a41026a200141076a2d00003a000020034188046a41086a200141186a29020037030020034188046a410d6a2001411d6a290000370000200320012f00053b0180032003200141106a29020037038804200141086a28020021062001410c6a280200210d200141286a280200211020012d0025211120012d00042105200341e8026a41026a2207200241046a2d00003a0000200341a8046a41086a2213200241156a290000370300200341a8046a410d6a220e2002411a6a2900003700002003200241026a2f01003b01e80220032002410d6a2900003703a804200241096a2800002114200241056a280000210420022d0001210f20022d00002102200541037122124102460d0620124103470d60200341c3056a20034188046a41086a290300370000200341c8056a20034188046a410d6a290000370000200320063600b3052003200d3600b705200320032f0180033b01b00520032003290388043700bb05200320034180036a41026a2d00003a00b205200341d0056a41026a2206200341e8026a41026a2d00003a0000200341900a6a41086a2207200341a8046a41086a290300370300200341900a6a410d6a2213200341a8046a410d6a290000370000200320032f01e8023b01d005200320032903a8043703900a200241ff01710d0a200341e8036a41026a20062d00003a0000200341f0076a41086a2007290300370300200341f0076a410d6a2013290000370000200320032f01d0053b01e803200320032903900a3703f007200f41ff01714101470d0a200341e8046a41026a200341e8036a41026a2d000022023a0000200341fb046a200341f0076a41086a290300220837000020034180056a200341f0076a410d6a2900002209370000200341d0056a41026a20023a0000200341900a6a41086a2008370300200341900a6a410d6a2009370000200320043600eb04200320143600ef04200320032f01e80322023b01e804200320032903f00722083700f304200320023b01d005200320083703900a410021020c0b0b200141086a2903004202520d5e412d21144101210d41a4aac200410041a4aac200410320022d000120022d00001b41ff017122024102461b20024103461b2204450d0f4101210e0c9d010b200341900a6a41386a200141c0006a290300370300200341900a6a41306a200141386a290300370300200341900a6a41286a200141306a290300370300200341900a6a41206a200141286a290300370300200341900a6a41186a200141206a290300370300200341900a6a41106a200141186a290300370300200341900a6a41086a200141106a2903003703002003200141086a2903003703900a200341f0076a41206a200241206a280200360200200341f0076a41186a200241186a290200370300200341f0076a41106a200241106a290200370300200341f0076a41086a200241086a290200370300200320022902003703f007200341f8016a200341900a6a200341f0076a10ac0220032802fc01211420032802f8012104410021054101210d4101210e0c9d010b200341900a6a41206a200141286a290300370300200341900a6a41186a200141206a290300370300200341900a6a41106a200141186a290300370300200341900a6a41086a200141106a2903003703002003200141086a2903003703900a200341f0076a41206a200241206a280200360200200341f0076a41186a200241186a290200370300200341f0076a41106a200241106a290200370300200341f0076a41086a200241086a290200370300200320022902003703f00720034180026a200341900a6a200341f0076a10ad0220032802840221142003280280022104410021064101210d4101210e410121050c9d010b200141086a280200221a410771417e6a220441044b0d5a200241056a2800002105200141146a2802002118200141106a28020021192001410c6a280200211720022d0001211420022d00002102024020040e05001c171915000b4101210e4100210d410021040240200241ff017145201441ff01714101467122020d00200541faa9c20020021b21040b412a21140c9a010b200341e0036a41026a2001410b6a2d00003a0000200341e8026a41086a200141186a290300370300200341e8026a41106a200141206a290300370300200320012f00093b01e0032003200141106a2903003703e802200141386a2903002108200141306a29030021092001410c6a2802002106200141286a290300210a200141086a2d00002104200341e4036a41026a200241046a2d00003a000020034180036a41086a200241156a29000037030020034180036a410d6a2002411a6a2900003700002003200241026a2f01003b01e40320032002410d6a290000370380032004410771417e6a221441044b0d58200241056a280000210420022d0001210520022d0000210d024020140e05001c171915000b200241096a280000211420034188046a41026a200341e0036a41026a2d00003a000020034188056a41086a200341e8026a41086a29030037030020034188056a41106a200341e8026a41106a290300370300200320032f01e0033b018804200320032903e80237038805200341d0056a41026a2202200341e4036a41026a2d00003a0000200341900a6a41086a220720034180036a41086a290300370300200341900a6a410d6a221320034180036a410d6a290000370000200320032f01e4033b01d00520032003290380033703900a200d41ff01710d26200341e8046a41026a20022d00003a0000200341b0056a41086a2007290300370300200341b0056a410d6a2013290000370000200320032f01d0053b01e804200320032903900a3703b005200541ff01714101470d26200341e3056a200341b0056a41086a290300220b370000200341e8056a200341b0056a410d6a290000221b370000200341a8046a41026a200341e8046a41026a2d000022023a0000200341900a6a41086a200b370300200341900a6a410d6a201b370000200320043600d305200320143600d705200320032f01e804220d3b01d005200320032903b005220b3700db052003200d3b01a8042003200b3703900a200320023a00d205410021020c270b2003200c3a00e804200320073600eb04200320053600ef04200320123600f304200320133600f704200320063600fb04200320083700ff04200320103a008705200320032f0180033b00e9042003200e36028c042003200f360288042003201136029004200320032f0180033b01c003200341d0056a41026a20152d00003a0000200341900a6a41086a2016290300370300200341900a6a410d6a2017290000370000200320032f01e8023b01d005200320032903a8043703900a200241ff01710d0620034188056a41026a2202200341d0056a41026a22152d00003a0000200341f0076a41086a2216200341900a6a41086a2217290300370300200341f0076a410d6a2219200341900a6a410d6a221c290000370000200320032f01d0053b018805200320032903900a3703f007201841ff01714101470d06200341a0036a41026a20022d000022023a0000200341b3036a2016290300221b370000200341b8036a2019290000221d370000201520023a00002017201b370300201c201d370000200320043600a303200320143600a703200320032f01880522023b01a003200320032903f007221b3700ab03200320023b01d0052003201b3703900a410021020c070b200341d0056a41026a20072d00003a0000200341900a6a41086a2013290300370300200341900a6a410d6a200e290000370000200320032f01e8023b01d005200320032903a8043703900a200241ff01710d07200341b0056a41026a2202200341d0056a41026a22052d00003a0000200341f0076a41086a2207200341900a6a41086a2213290300370300200341f0076a410d6a220e200341900a6a410d6a2212290000370000200320032f01d0053b01b005200320032903900a3703f007200f41ff01714101470d07200341e8046a41026a20022d000022023a0000200341fb046a2007290300220837000020034180056a200e2900002209370000200520023a00002013200837030020122009370000200320043600eb04200320143600ef04200320032f01b00522023b01e804200320032903f00722083700f304200320023b01d005200320083703900a410021020c080b200241096a2800002114200241056a2800002104200341e0036a41026a20052d00003a0000200341a8046a41086a2006290300370300200341a8046a410d6a2007290000370000200320032f01e0023b01e003200320032903e8033703a804200341e4036a41026a20052d00003a0000200341e8046a41086a2006290300370300200341e8046a410d6a2007290000370000200320032f01e0023b01e403200320032903e8033703e804200341b0056a41026a200f2d00003a0000200341900a6a41086a2010290300370300200341900a6a410d6a2011290000370000200320032f01e4023b01b00520032003290388043703900a201341ff0171450d1a410121020c1b0b41012102412a211441faa9c20021040b2003419c036a41026a220c200341d0056a41026a2d00003a0000200341c8046a41086a2215200341900a6a41086a2216290300370300200341c8046a41106a200341900a6a41106a290300370300200320032f01d0053b019c03200320032903900a3703c80420020d24200341fb046a2015290300370000200341e8046a41186a2202200341d5046a290000370000200320032f019c033b01e804200320043600eb04200320143600ef04200320032903c8043700f3042003200c2d00003a00ea04200341900a6a200341e8046a200910ae024101210c2016280200211420032802900a4101470d2320032802940a210420060d250c260b41012102412a211441faa9c20021040b2003419c036a41026a2206200341d0056a41026a2d00003a0000200341c8046a41086a2207200341900a6a41086a290300370300200341c8046a41106a200341900a6a41106a290300370300200320032f01d0053b019c03200320032903900a3703c8042002450d070cae010b41012102412a211441faa9c20021040b2003419c036a41026a2215200341d0056a41026a2d00003a0000200341c8046a41086a2216200341900a6a41086a2217290300370300200341c8046a41106a200341900a6a41106a290300370300200320032f01d0053b019c03200320032903900a3703c80420020d25200341c3056a2016290300370000200341b0056a41186a2202200341d5046a290000370000200320032f019c033b01b005200320043600b305200320143600b705200320032903c8043700bb05200320152d00003a00b205200341900a6a200341b0056a200a10ae02410121152017280200211420032802900a4101470d2420032802940a2104200e0d260c270b41012102412a211441faa9c20021040b2003419c036a41026a2205200341d0056a41026a2d00003a0000200341c8046a41086a2207200341900a6a41086a290300370300200341c8046a41106a200341900a6a41106a290300370300200320032f01d0053b019c03200320032903900a3703c80420020dab012003419b056a200729030037000020034188056a41186a200341d5046a290000370000200320032f019c033b0188052003200436008b052003201436008f05200320032903c80437009305200320052d00003a008a0520034188056a10af02450d27200341003602980a200342013703900a200d200341900a6a10a00120032802940a210420032802980a211420032802900a2102200341e8046a41186a4200370300200341e8046a41106a4200370300200341e8046a41086a4200370300200342003703e80420022014200341e8046a1011200320032f00e9043b01c00320032800eb04211420032d00e804210520032d008705210720032900ff04210820032900ef042109200320032900f7043700af03200320093700a703200341d0056a41086a2213200341a0036a41086a290300370300200320083700b703200320073a00bf03200341d0056a41186a200341a0036a41186a290300370300200341d0056a41106a2207200341a0036a41106a290300370300200320053a00a003200320143600a303200320032f01c0033b00a103200320032903a0033703d00502402004450d00200210010b200341900a6a41186a200341d0056a41186a290300370300200341900a6a41106a2007290300370300200341900a6a41086a2013290300370300200320032903d0053703900a411910002202450d40200320023602f007200342193702f407200341f0076a41e3e6c10041191029200341b0056a41086a220220032802f807360200200320032903f0073703b005200341900a6a200341b0056a101b2002280200210420032802b405211420032802b0052102200341d0036a41086a22054200370300200342003703d00320022004200341d0036a1002200341c0036a41086a2005290300370300200320032903d0033703c003200341c0036a41101014210402402014450d00200210010b2004450d6641c0ddc2002104411f21140cab010b200141106a2903002108200341d0036a41086a22024200370300200342003703d0034195ebc1004113200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a411010140d49200341c8016a10f30120032802c8014101470d4b20032802cc010d4b200341d0036a41086a22024200370300200342003703d00341c6edc100410d200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a411041b8d6c200410041001004417f460d48200342003703900a200341c0036a4110200341900a6a41084100100441016a41084d0d56024020032903900a500d00200341d0036a41086a22024200370300200342003703d00341c6edc100410d200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a411041b8d6c200410041001004417f460d48200342003703900a200341c0036a4110200341900a6a41084100100441016a41084d0d5620032903900a2109200341d0036a41086a22024200370300200342003703d0034186ecc1004115200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a411041b8d6c200410041001004417f460d47200342003703900a200341c0036a4110200341900a6a41084100100441016a41084d0d5520032903900a20097c2008560d460b200320083703900a200341d0036a41086a22024200370300200342003703d00341c6edc100410d200341d0036a1002200341c0036a41086a22042002290300370300200320032903d0033703c003200341c0036a4110200341900a6a410810034101210d200341013a00900a20024200370300200342003703d0034195ebc1004113200341d0036a100220042002290300370300200320032903d0033703c003200341c0036a4110200341900a6a41011003410021044101210e0c8d010b41d2a9c20041d2a9c200410041032005200d41ff01711b41ff017122021b20024103461b22040d0f200320083703900a200341d0036a41086a22024200370300200342003703d00341d3d8c1004119200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a4110200341900a6a410810034101210d0c2f0b200241096a2800002114200241056a2800002104200320032f0188043b01c00320034188056a41026a20062d00003a0000200341900a6a41086a2007290300370300200341900a6a410d6a2013290000370000200320032f01a8043b018805200320032903d0053703900a02400240200d41ff01710d00200341e8046a41026a220220034188056a41026a220d2d00003a0000200341f0076a41086a2206200341900a6a41086a2207290300370300200341f0076a410d6a2213200341900a6a410d6a220c290000370000200320032f0188053b01e804200320032903900a3703f007200541ff01714101470d00200341b3036a2006290300220a370000200341b8036a2013290000220b370000200d20022d000022023a00002007200a370300200c200b370000200320043600a303200320143600a703200320032f01e804220d3b01a003200320032903f007220a3700ab032003200d3b0188052003200a3703900a200320023a00a203410021020c010b41012102412a211441faa9c20021040b2003419c036a41026a220d20034188056a41026a2d00003a0000200341c8046a41086a2205200341900a6a41086a290300370300200341c8046a41106a200341900a6a41106a290300370300200320032f0188053b019c03200320032903900a3703c80420020d8a01200341e8026a41026a2202200d2d00003a0000200341b0056a41086a220d2005290300370300200341b0056a410d6a2205200341c8046a410d6a290000370000200320032f019c033b01e802200320032903c8043703b005200341a30a6a200d290300370000200341a80a6a2005290000370000200320043600930a200320143600970a200320022d00003a00920a200320032f01e8023b01900a200320032903b00537009b0a200320032f01c0033b01c804411210002202450d40200320023602f007200342123702f407200341f0076a41fed8c1004112102920034188056a41086a220220032802f807360200200320032903f00737038805200341900a6a20034188056a101b2002280200210d200328028c0521052003280288052104412010002202450d3f2002200e3a0000200220032f01c8043b000120022012360003200220083700072002200f36000f2002201036001320022009370017200220113a001f200341d0036a41086a22064200370300200342003703d0032004200d200341d0036a1002200341e8046a41086a2006290300370300200320032903d0033703e804200341e8046a41102002412010032002100102402005450d00200410010b410021044101210d4101210e0c8b010b2003419b056a2007290300370000200341a0056a200341d5046a290000370000200320032f019c033b0188052003200436008b052003201436008f05200320032903c80437009305200320062d00003a008a0520034188056a10af02450d1d411510002202450d3b200320023602900a200342153702940a200341900a6a41c7e7c10041151029200341f0076a41086a220220032802980a360200200320032903900a3703f007200341b0056a200341f0076a101b2002280200210420032802f407211420032802f0072102200341d0036a41086a22064200370300200342003703d00320022004200341d0036a1002200341e8046a41086a2006290300370300200320032903d0033703e80441002106200341e8046a411041b8d6c200410041001004417f460d632003200341e8046a3602d005200341103602d405200341003602900a20034100200341e8046a4110200341900a6a41044100100422042004417f461b2204410420044104491b22063602d805200441034d0d3620032802900a2117200341003602900a200341d8056a4100200341e8046a4110200341900a6a41042006100422042004417f461b2204410420044104491b20066a360200200441034d0d3620032802900a211c200341f0076a200341d0056a103920032802f0072206450d36200341f0076a41086a280200211220032802f4072116200341900a6a200341d0056a103920032802900a220e450d35200341900a6a41086a280200210c20032802940a21152014450d93010c92010b4128211441d2a9c20041d2a9c200410041032007200241ff01711b41ff017122021b20024103461b22040d7c200d10a201410021040c7c0b200341b0056a41026a2206200341a8046a41026a2d00003a0000200341900a6a41086a220e20034188056a41086a290300370300200341900a6a410d6a221220034188056a410d6a290000370000200320032f01a8043b01b00520032003290388053703900a200241ff01710d0f200341e8046a41026a20062d00003a0000200341d0056a41086a200e290300370300200341d0056a410d6a2012290000370000200320032f01b0053b01e804200320032903900a3703d005200741ff01714101470d0f200341b3036a200341d0056a41086a2903002208370000200341b8036a200341d0056a410d6a2900002209370000200341b0056a41026a200341e8046a41026a2d000022023a0000200341900a6a41086a2008370300200341900a6a410d6a2009370000200320043600a303200320143600a703200320032f01e80422063b01a003200320032903d00522083700ab03200320063b01b005200320083703900a200320023a00a203410021020c100b41d2a9c20041d2a9c200410041032007200241ff01711b41ff017122021b20024103461b2204450d27200d102c200d1001412821140c7a0b200341b0056a41026a2205200341a8046a41026a2d00003a0000200341900a6a41086a220620034188056a41086a290300370300200341900a6a410d6a221320034188056a410d6a290000370000200320032f01a8043b01b00520032003290388053703900a200241ff01710d11200341e8046a41026a20052d00003a0000200341d0056a41086a2006290300370300200341d0056a410d6a2013290000370000200320032f01b0053b01e804200320032903900a3703d005200741ff01714101470d11200341b3036a200341d0056a41086a2903002208370000200341b8036a200341d0056a410d6a2900002209370000200341b0056a41026a200341e8046a41026a2d000022023a0000200341900a6a41086a2008370300200341900a6a410d6a2009370000200320043600a303200320143600a703200320032f01e80422053b01a003200320032903d00522083700ab03200320053b01b005200320083703900a200320023a00a203410021020c120b41d2a9c20041d2a9c200410041032014200241ff01711b41ff017122021b20024103461b2204450d2602402018450d00201841186c21142017210203400240200241046a280200450d00200228020010010b0240200241106a280200450d002002410c6a28020010010b200241186a2102201441686a22140d000b0b02402019450d00201710010b412821144101210e4100210d201a41077122024107460d5241012105410121064101210741012113024020020e078c018c018c015454008c018c010b4100210d4100450d530c85010b200341f0076a41026a2202200341e4036a41026a2d00003a0000200320032f01e4033b01f007200320043600910a200320022d00003a00900a200d41ff0171450d0420032802900a4104490d04411210002202450d2d200320023602900a200342123702940a200341900a6a418cd2c2004112102920032802900a210220032802940a220420032802980a22146b41044f0d59201441046a220d2014490d8e0120044101742205200d200d2005491b22054100480d8e012004450d4e200510002207450d502007200220052004200420054b1b10ce02210420021001200421020c4f0b200241ff017145201441ff01714101467122024101470d1e4100210420190d1f0c200b41d2a9c20041d2a9c200410041032005200d41ff01711b41ff017122021b20024103461b22040d05200341e8026a41106a290300210820032802e802210420032903f002210941d4d5c2004115200610cc01200320083703980a200320093703900a200341c0036a41086a22024200370300200342003703c00341b8d5c200411c200341c0036a1002200341e8046a41086a22142002290300370300200320032903c0033703e804200341e8046a4110200341900a6a411010032003200a3703900a20024200370300200342003703c00341d7cac2004114200341c0036a100220142002290300370300200320032903c0033703e804200341e8046a4110200341900a6a4108100341fdcac200410d200410cc010c280b200320193602940a200320173602900a200320183602980a41d2a9c20041d2a9c200410041032014200241ff01711b41ff017122021b20024103461b2204450d2302402019450d00201710010b412821140c1f0b200341f0076a41026a2202200341e4036a41026a2d00003a0000200320032f01e4033b01f007200320043600910a200320022d00003a00900a200d41ff0171450d0020032802900a41024f0d740b41c00021144183d7c10021044101210d4101210e0c7f0b41a4aac200410041a4aac20041032014200241ff01711b41ff017122024102461b20024103461b2204450d2202402019450d00201710010b412d21140c1c0b41d2a9c20041d2a9c200410041032005200d41ff01711b41ff017122021b20024103461b2204450d220b412821144101210d4101210e0c7c0b200341c8046a41026a2205200341b0056a41026a22062d00003a000020034188056a41086a2207200341900a6a41086a221329030037030020034188056a410d6a220f200341900a6a410d6a2210290000370000200320032f01b0053b01c804200320032903900a3703880541012102201241ff01714101470d00200620052d00003a0000201320072903003703002010200f290000370000200320032f01c8043b01b00520032003290388053703900a410021020c010b412a211441faa9c20021040b200341a0036a41026a2205200341b0056a41026a2d00003a0000200341f0076a41086a2206200341900a6a41086a290300370300200341f0076a41106a200341900a6a41106a290300370300200320032f01b0053b01a003200320032903900a3703f00720020d78200341d0056a41136a2006290300370000200341d0056a41186a200341f0076a410d6a290000370000200320032f01a0033b01d005200320043600d305200320143600d705200320032903f0073700db05200320052d00003a00d2052003419c036a41026a200341e4036a41026a2d00003a0000200341b0056a41086a200341e8046a41086a290300370300200341b0056a410d6a2204200341e8046a410d6a290000370000200320032f01e4033b019c03200320032903e8043703b00541012102200c41ff01714101470d13200341900a6a200d10a80120032d00900a4101470d74200341ea026a20032d00930a3a0000200341c8046a41086a200341a40a6a290200370300200341d5046a200341a90a6a290000370000200320032f00910a3b01e80220032003419c0a6a2902003703c804200341900a6a41086a280200210e4100210220032802940a210d0c750b41012102412a211441faa9c20021040b2003419c036a41026a2206200341b0056a41026a2d00003a0000200341c8046a41086a2207200341900a6a41086a290300370300200341c8046a41106a200341900a6a41106a290300370300200320032f01b0053b019c03200320032903900a3703c80420020d6a20034183086a200729030037000020034188086a200341d5046a290000370000200320032f019c033b01f007200320043600f307200320143600f707200320032903c8043700fb07200320062d00003a00f207411a10002202450d27200320023602900a2003421a3702940a200341900a6a4188c9c100411a102920032802900a210220032802940a220420032802980a22146b41044f0d58201441046a22062014490d810120044101742207200620062007491b22074100480d81012004450d4920071000220e450d4b200e200220072004200420074b1b10ce02210420021001200421020c4a0b41012102412a211441faa9c20021040b2003419c036a41026a2206200341b0056a41026a2d00003a0000200341c8046a41086a2207200341900a6a41086a290300370300200341c8046a41106a200341900a6a41106a290300370300200320032f01b0053b019c03200320032903900a3703c80420020d5220034183086a2007290300370000200341f0076a41186a200341d5046a290000370000200320032f019c033b01f007200320043600f307200320143600f707200320032903c8043700fb07200320062d00003a00f207200341d0036a41086a22024200370300200342003703d003419bd5c1004118200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a411041b8d6c200410041001004417f460d24200342003703980a200342003703900a200341c0036a4110200341900a6a4110410010042202417f460d2c2002410f4d0d2c20032903900a200956200341980a6a290300220a200856200a2008511b450d5141b3d5c1002104410d21140c520b41012102412a211441faa9c20021040b2003419c036a41026a2205200341b0056a41026a2d00003a0000200341c8046a41086a2206200341900a6a41086a290300370300200341c8046a41106a200341900a6a41106a290300370300200320032f01b0053b019c03200320032903900a3703c80420020d66200341f0076a41136a200629030037000020034188086a200341d5046a290000370000200320032f019c033b01f007200320043600f307200320143600f707200320032903c8043700fb07200320052d00003a00f207411310002202450d21200320023602900a200342133702940a200341900a6a41a0c8c1004113102920032802900a210220032802940a221420032802980a22056b41044f0d52200541046a22062005490d7d20144101742207200620062007491b22074100480d7d2014450d42200710002213450d442013200220072014201420074b1b10ce02211420021001201421020c430b41012102412a211441faa9c20021040b2003419c036a41026a220d200341a8046a41026a2d00003a0000200341c8046a41086a2205200341900a6a41086a290300370300200341c8046a41106a200341900a6a41106a290300370300200320032f01a8043b019c03200320032903900a3703c80420020d7020034183086a200529030037000020034188086a200341d5046a290000370000200320032f019c033b01f007200320043600f307200320143600f707200320032903c8043700fb072003200d2d00003a00f207200341c0036a41086a22024200370300200342003703c00341b8d5c200411c200341c0036a1002200341e8046a41086a2002290300370300200320032903c0033703e804200341e8046a411041b8d6c200410041001004417f460d1e200342003703980a200342003703900a200341e8046a4110200341900a6a4110410010042202417f460d272002410f4d0d27200341900a6a41086a290300210b20032903900a211b200341a8026a2009200841d4d5c200411510bf01ad420010d50220034198026a20032903a802200341a8026a41086a29030042c0843d420010d202200341b8026a200341f0076a201b200329039802221d201d201b5420034198026a41086a290300221d200b54201d200b511b22021b221b200b201d20021b220b10b00220032802b802450d4841ffd5c2002104411a21144101210d4101210e0c710b200341900a6a410c6a2902002108200341b40a6a2802002104200341900a6a41206a2802002115200341ac0a6a2802002116200341900a6a41186a22192802002118200341b0056a410c6a200341900a6a41146a3502003e0200200320083702b405200320143602b005200320183602c005200320163602c405200320153602c805200320043602cc05200341d0056a41086a22164200370300200341d0056a41146a41e0a3c000360200200341d0056a41206a420037030020034180066a200341e8046a41086a221429030037030020034188066a200341e8046a41106a221529030037030020034190066a2002290300370300200341a0a1c1003602d40541002104200341003602d005200341b8d6c2003602e0052003428080808080013703e805200320032903e8043703f80520192002290300370300200341900a6a41106a2015290300370300200341900a6a41086a22022014290300370300200320032903e8043703900a20034188056a200341d0056a200341900a6a200fad4220862010ad842011ad422086200ead84200341b0056a2007201220132017109801024020032d00880522110d0020022016290300370300200341f0076a41086a2003419c0a6a280200360200200320032903d0053703900a200320032902940a3703f007200341d0036a200341f0076a10e901200341f0056a2802002116200341ec056a28020021150240200341f4056a2802002202450d00200241d0006c2114200341900a6a4101722112200341f7076a21102015210203402010200241d00010cf021a200341093a00900a2012200341f0076a41d70010ce021a200241d0006a2102200341900a6a10a101201441b07f6a22140d000b0b4100210c2016450d00201510010b200341e8046a20032903b00520032903b805200341b0056a41106a290300200341c8056a29030010b10220034188056a41086a2802002114024020114101470d00200328028c0521040b200c450d00200341f0076a41086a200341d0056a410472220241086a280200360200200320022902003703f007200341900a6a200341f0076a10ea01200341900a6a10ee01200341f0056a280200450d00200341ec056a28020010010b2006450d010b201310010b02402005450d00200710010b410021120c050b41dce7c10021044114211420054102460d89010c8a010b200341900a6a410c6a290200210a200341b40a6a2802002104200341900a6a41206a2802002116200341ac0a6a2802002117200341900a6a41186a280200211920034188056a410c6a200341900a6a41146a3502003e02002003200a37028c05200320143602880520032019360298052003201736029c05200320163602a005200320043602a405200341d0056a41086a22164200370300200341d0056a41146a41e0a3c000360200200341d0056a41206a420037030020034180066a200341b0056a41086a220429030037030020034188066a200341b0056a41106a221429030037030020034190066a2002290300370300200341a0a1c1003602d405200341003602d005200341b8d6c2003602e0052003428080808080013703e805200320032903b0053703f805200341003602d004200342013703c804200341f0076a41186a2002290300370300200341f0076a41106a2014290300370300200341f0076a41086a22022004290300370300200320032903b0053703f0072003200c3a00900a200320073600930a20032012ad4220862005ad843700970a2003201336009f0a200320063600a30a200320083700a70a200320103a00af0a200320032f01c0033b00910a200341d8026a200341d0056a200341f0076a200341900a6a2009200b20034188056a200f2011200341c8046a10960120032802dc022114024020032802d80222040d00200341900a6a41086a201629030037030020022003419c0a6a280200360200200320032903d0053703900a200320032902940a3703f007200341d0036a200341f0076a10e901200341f0056a2802002116200341ec056a280200210c0240200341f4056a2802002202450d00200241d0006c2112200341900a6a4101722110200341f7076a2111200c210203402011200241d00010cf021a200341093a00900a2010200341f0076a41d70010ce021a200241d0006a2102200341900a6a10a101201241b07f6a22120d000b0b410021152016450d00200c10010b200341b0056a20032903880520032903900520034188056a41106a290300200341a0056a29030010b102024020032802cc04450d0020032802c80410010b2015450d00200341f0076a41086a200341d0056a410472220241086a280200360200200320022902003703f007200341900a6a200341f0076a10ea01200341900a6a10ee01200341f0056a280200450d00200341ec056a28020010010b200e450d010b200f10010b410121120b0240200d41037122024102460d0020024103470d6f2012450d6f02402005450d00200710010b2006450d6f201310010c6f0b2012200e45720d6e200f10010c6e0b41fce6c1002104411721140c83010b200341a0036a41136a200341b0056a41086a290300220a370000200341a0036a41186a2004290000220b370000200341e8026a41026a2003419c036a41026a2d000022023a0000200341c8046a41086a200a370300200341c8046a410d6a200b3700002003200d3600a3032003200e3600a703200320032f019c0322043b01a003200320032903b005220a3700ab03200320043b01e8022003200a3703c804200320023a00a203410021020c610b200541faa9c20020021b21042019450d010b201710010b412a21140b4101210e4100210d0c610b200341b3036a200341b0056a41086a290300221b370000200341b8036a200341b0056a410d6a290000221d370000200341e8026a41026a2003419c036a41026a2d000022023a0000200341c8046a41086a201b370300200341c8046a410d6a201d3700002003200d3600a3032003200e3600a703200320032f019c0322043b01a003200320032903b005221b3700ab03200320043b01e8022003201b3703c804200320023a00a20341002102200e21140c3b0b10ac012108200341d0036a41086a22024200370300200342003703d00341b3c8c1004116200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a411041b8d6c200410041001004417f460d09200342003703900a200341c0036a4110200341900a6a41084100100441016a41084d0d1c20032903900a2109200341900a6a200d41a00210ce021a200341f0076a200920087c200341900a6a2013109f01200341f8076a280200211420032802f407210220032802f0072104200d10012002410020044101461b21040c520b02402018450d002017201841186c6a21042017210203402002280200200241086a2802002002410c6a280200200241146a2802001003200241186a22022004470d000b2018450d00201841186c21042017210203400240200241046a280200450d00200228020010010b0240200241106a280200450d002002410c6a28020010010b200241186a2102200441686a22040d000b0b410021122019450d620c610b41e4c5c200410520172018100302402019450d00201710010b4100210d0b4101210e410121054101210641012107410121130c610b200341c0016a10f30120032802c0014101470d0e20032802c4014101470d0e2018450d03201720184102746a211c200341b90a6a2116200341990a6a210e200341c80a6a211e200341c00a6a211f200341bc0a6a2120201721100c020b20032903e80221082003200341e8026a41086a2903003703980a200320083703900a200341c0036a41086a22024200370300200342003703c0034195c9c200410c200341c0036a1002200341e8046a41086a2002290300370300200320032903c0033703e804200341e8046a4110200341900a6a411010030b410021044101210d4101210e0c590b034020102802002102200341d0036a41086a22044200370300200342003703d00341ecd8c1004112200341d0036a1002200341c0036a41086a22052004290300370300200320032903d0033703c003024002400240024002400240200341c0036a411041b8d6c200410041001004417f460d00200342103702f4072003200341c0036a3602f007200341900a6a200341f0076a103920032802900a2214450d01200220032902940a2208422088a7220d4f0d02200341f0076a41186a2211201420024105746a220241186a290000370300200341f0076a41106a220c200241106a290000370300200341f0076a41086a2215200241086a290000370300200320022900003703f00702402008a7450d00201410010b411210002202450d03200320023602900a200342123702940a200341900a6a41c5f2c10041121029200341d0056a41086a2206200341900a6a41086a220d280200360200200320032903900a3703d005200341f0076a200341d0056a101b2006280200211420032802d405210720032802d005210220044200370300200342003703d00320022014200341d0036a100220052004290300370300200320032903d0033703c00302400240200341c0036a411041b8d6c200410041001004417f460d00200341003602900a200341c0036a4110200341900a6a41044100100441016a41044d0d0120032802900a21132007450d070c060b4100211320070d050c060b41b2eac10041331040000b41c3d7c10041221040000b41b2eac10041331040000b4190b7c0002002200d104a000b411241011019000b200210010b200341900a6a41186a22122011290300370300200341900a6a41106a220f200c290300370300200d2015290300370300200320032903f0073703900a0240024002400240024002400240411210002202450d00200320023602d005200342123702d405200341d0056a41c5f2c1004112102920034188056a41086a22022006280200360200200320032903d00537038805200341900a6a20034188056a101b20022802002114200328028c05210720032802880521022003201341016a3602d00520044200370300200342003703d00320022014200341d0036a100220052004290300370300200320032903d0033703c003200341c0036a4110200341d0056a4104100302402007450d00200210010b20044200370300200342003703d00341bf87c2004119200341d0036a100220052004290300370300200320032903d0033703c0030240024002400240200341c0036a411041b8d6c200410041001004417f460d00200341003602900a200341c0036a4110200341900a6a41044100100441016a41044d0d02201320032802900a22024f0d010c090b4100210220134100490d080b4200210820044200370300200342003703d00341ebf2c100411b200341d0036a100220052004290300370300200320032903d0033703c00302400240200341c0036a411041b8d6c200410041001004417f460d00200342003703980a200342003703900a200341c0036a4110200341900a6a4110410010042214417f460d052014410f4d0d05200d290300210920032903900a21080c010b420021090b200341b0016a20082009201320026b222341ff007110da0220044200370300200342003703d0034180f2c1004112200341d0036a100220052004290300370300200320032903d0033703c00320032903b001210a200341b0016a41086a290300210b02400240200341c0036a411041b8d6c200410041001004417f460d00200342103702d4052003200341c0036a3602d005200341900a6a200341d0056a103920032802900a2221450d06200d280200210220032802940a21140c010b4101212141002102410021140b20044200370300200342003703d0034192f2c100411d200341d0036a100220052004290300370300200320032903d0033703c0030240200341c0036a411041b8d6c200410041001004417f460d00200341003602900a200341c0036a4110200341900a6a41044100100441016a41044d0d0220032802900a21072014450d070c060b4104210720140d050c060b41b2eac10041331040000b41b2eac10041331040000b411241011019000b41b2eac10041331040000b41b2eac10041331040000b202110010b0240024002400240024002400240024002400240200220074d0d0020034198016a200341f0076a200a200b10b202200329039801a74101470d0020034198016a41106a290300211d20032903a001211b411c10002202450d01200320023602900a2003421c3702940a200341900a6a41f2f0c100411c10292006200d280200360200200320032903900a3703d005200341f0076a200341d0056a101b2006280200210220032802d405210720032802d005211420044200370300200342003703d00320142002200341d0036a100220052004290300370300200320032903d0033703c003024002400240200341c0036a411041b8d6c200410041001004417f470d0041012121410021024100212220070d010c020b200342103702d4052003200341c0036a3602d005200341900a6a200341d0056a103920032802900a2221450d05200d280200210220032802940a21222007450d010b201410010b02402002450d00420021082002410574220721144200210920212102034020034188016a200210950220034188016a41086a29030020097c200329038801220920087c2208200954ad7c2109200241206a2102201441606a22140d000b2008200984500d00202121020340200341f8006a2002109502200341d0006a2003290378200341f8006a41086a290300201b201d10d502200341c0006a2003290350200341d0006a41086a2903002008200910d202200341e0006a20022003290340200341c0006a41086a29030010b202200241206a2102200741606a22070d000b0b2022450d00202110010b02400240411c10002202450d00200320023602900a2003421c3702940a200341900a6a41d6f0c100411c10292006200d280200360200200320032903900a3703d005200341f0076a200341d0056a101b20032802d4052102200341286a20032802d0052207200628020010b9012003280238211402402002450d00200710010b202320144f0d07411510002202450d01200320023602900a200342153702940a200341900a6a419bf3c100411510292006200d280200360200200320032903900a3703d005200341f0076a200341d0056a101b2006280200210220032802d405210720032802d005211420044200370300200342003703d00320142002200341d0036a100220052004290300370300200320032903d0033703c0030240200341c0036a411041b8d6c200410041001004417f460d00200342103702d4052003200341c0036a3602d005200341900a6a200341d0056a103920032802900a2206450d04200d280200210220032802940a21232007450d070c060b41012106410021024100212320070d050c060b411c41011019000b411541011019000b411c41011019000b41b2eac10041331040000b41b2eac10041331040000b201410010b200a423f88211b200b420186211d200341186a200341f0076a109502200341186a41086a29030021082003290318210902402002450d0020024105742114200621020340200341086a2002109502200341086a41086a29030020087c2003290308220820097c2209200854ad7c2108200241206a2102201441606a22140d000b0b201d201b84211b200a420186211d02402023450d00200610010b2009201d5a2008201b5a2008201b511b0d010b20044200370300200342003703d0034180f2c1004112200341d0036a100220052004290300370300200320032903d0033703c0030240200341c0036a411041b8d6c200410041001004417f460d00200342103702d4052003200341c0036a3602d005200341900a6a200341d0056a103920032802900a2223450d0220032802940a21210240200d2802002202450d00200241057421074100211420232102024003402012200241186a290000370300200f200241106a290000370300200d200241086a290000370300200320022900003703900a2014200341900a6a200341f0076a412010d10222064100476a21142006450d01200241206a2102200741606a22070d000c020b0b200341f0076a201410a30222020d040b2021450d00202310010b20044200370300200342003703d003418ef1c1004115200341d0036a100220052004290300370300200320032903d0033703c003200341c0036a411041b8d6c20041001003200341003a00900a20044200370300200342003703d0034192d8c1004119200341d0036a100220052004290300370300200320032903d0033703c003200341c0036a4110200341900a6a410110030b200341a0036a41186a2011290300370300200341a0036a41106a200c290300370300200341a0036a41086a2015290300370300200320032903f0073703a003410221020c030b41b2eac10041331040000b200210b302000b200341a0036a41186a2011290300370300200341a0036a41106a200c290300370300200341a0036a41086a2015290300370300200320032903f0073703a003410121020b201e200b370300201f200a370300200d20023a0000200e20032903a003370000201620032f019c033b000020202013360200200e41086a200341a0036a41086a290300370000200e41106a200341a0036a41106a290300370000200e41186a200341a0036a41186a290300370000201641026a2003419c036a41026a2d00003a0000200341033a00900a200341900a6a10a101201041046a2210201c470d000b0b4101211220190d5a0c5b0b411241011019000b41c3d7c10041221040000b2016450d00200610010b41b2eac10041331040000b41c3d7c10041221040000b411341011019000b41c3d7c10041221040000b411a41011019000b411541011019000b411941011019000b2003419c0a6a4101360200200341a40a6a4101360200200341033602f407200341bcc5c2003602f007200341e8fdc0003602900a200341023602940a200341c0c5c2003602980a2003200341f0076a3602a00a200341900a6a41f8fdc0001065000b412041011019000b411241011019000b41b2eac10041331040000b41b2eac10041331040000b41a8b6c000104d000b41c3d7c10041221040000b41c3d7c10041221040000b41c3d7c10041221040000b41f0b5c000104d000b41b2eac10041331040000b2003419c0a6a4101360200200341a40a6a4101360200200341033602f407200341d8acc2003602f00720034188b6c0003602900a200341023602940a200341c0c5c2003602980a2003200341f0076a3602a00a200341900a6a4198b6c0001065000b41fc8ac100104d000b41d0fdc000104d000b41d8b5c000104d000b41a4b2c000104d000b418cb2c000104d000b41c8a3c000104d000b41fca3c000104d000b41b8fdc000104d000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b200510002202450d010b200521040c0a0b200541011019000b2018450d00201841186c21052017210203400240200241046a280200450d00200228020010010b0240200241106a280200450d002002410c6a28020010010b200241186a2102200541686a22050d000b0b2019450d31201710010c310b200710002202450d010b200721140c0f0b200741011019000b200710002202450d010b200721040c0e0b200741011019000b201441046a210d0b200220146a2006360000200341c0036a41086a22144200370300200342003703c0032002200d200341c0036a1002200341e8046a41086a2014290300370300200320032903c0033703e804200341e8046a41101014211402402004450d00200210010b2014450d1e200341c0036a41086a22024200370300200342003703c00341ebcac2004112200341c0036a1002200341e8046a41086a2002290300370300200320032903c0033703e8044100210d02400240024002400240200341e8046a411041b8d6c200410041001004417f460d00200342103702f4072003200341e8046a3602f007200341900a6a200341f0076a103820032802900a2214450d04200341980a6a280200220d20032802940a2202460d010c020b41042114410021020b200241016a22042002490d3620024101742205200420042005491b2205ad4202862208422088a70d362008a722044100480d36024002402002450d00200410002207450d0320072014200420024102742202200220044b1b10ce02210220141001200221140c010b200410002214450d020b200521020b2014200d4102746a200636020041002104200341003602980a200342013703900a2014200d41016a200341900a6a10e30120032802940a210520032802980a210620032802900a210d200341c0036a41086a22074200370300200342003703c00341ebcac2004112200341c0036a1002200341e8046a41086a2007290300370300200320032903c0033703e804200341e8046a4110200d2006100302402005450d00200d10010b2002450d29201410010c290b200441041019000b41b2eac10041331040000b200341c0036a41086a22024200370300200342003703c00341e9d5c2004116200341c0036a1002200341e8046a41086a2002290300370300200320032903c0033703e80441002104024002400240024002400240200341e8046a411041b8d6c200410041001004417f460d00200341003602900a200341e8046a4110200341900a6a41044100100441016a41044d0d0120032802900a21040b2003200441016a3602900a200341c0036a41086a22024200370300200342003703c00341e9d5c2004116200341c0036a1002200341e8046a41086a2002290300370300200320032903c0033703e804200341e8046a4110200341900a6a41041003200341d30a6a2006360000200341c80a6a200341f0076a41186a290300370300200341c00a6a200341f0076a41106a290300370300200341b80a6a200341f0076a41086a290300370300200341d20a6a2003418a046a2d00003a0000200341d70a6a200329038805370000200341df0a6a20034188056a41086a290300370000200341e70a6a20034188056a41106a290300370000200320083703980a200320093703900a200320032903f0073703b00a200320032f0188043b01d00a200341900a6a41186a200b370300200341ef0a6a200aa73a00002003201b3703a00a411210002202450d01200320023602d005200342123702d405200341d0056a418cd2c2004112102920032802d005210202400240024020032802d405220d20032802d80522146b41044f0d00201441046a22132014490d3a200d4101742205201320132005491b22074100480d3a200d450d01200710002205450d05200520022007200d200d20074b1b10ce02210d20021001200d21020c020b201441046a2113200d21070c010b200710002202450d030b200220146a2004360000200341003602d805200342013703d005200341b00a6a200341d0056a101b200341980a6a290300210820032903900a2109024002400240024020032802d405220620032802d80522146b41104f0d00201441106a220d2014490d3b20064101742205200d200d2005491b220e4100480d3b2006450d0120032802d0052112200e10002205450d0720052012200e20062006200e4b1b10ce021a201210010c020b201441106a210d20032802d00521050c020b200e10002205450d050b2003200e3602d405200320053602d0050b200520146a2214200837000820142009370000200341d8056a2214200d360200200341d00a6a200341d0056a101b200341a80a6a2903002108200341900a6a41106a2903002109024002400240024020032802d4052206201428020022056b41104f0d00200541106a220e2005490d3b20064101742214200e200e2014491b220d4100480d3b2006450d0120032802d0052112200d10002214450d0820142012200d20062006200d4b1b10ce021a201210010c020b200541106a210e20032802d00521142006210d0c020b200d10002214450d060b2003200d3602d405200320143602d0050b201420056a2205200837000820052009370000200341c0036a41086a22054200370300200342003703c00320022013200341c0036a1002200341e8046a41086a2005290300370300200320032903c0033703e804200341e8046a41102014200e10030240200d450d00201410010b02402007450d00200210010b2003419c0a6a2004360200200341083a00900a41002104200341900a6a41086a41003a0000200341900a6a10a1010c2b0b41b2eac10041331040000b411241011019000b200741011019000b200e41011019000b200d41011019000b024002400240024002400240024002400240024002400240024002400240200641014b0d00200341900a6a200d41a00210ce021a200341013a00f007200341013602f40720034188026a200341900a6a200341f0076a10ab02200341b50a6a200328028802453a00002003419d0a6a200341d8056a290300370000200341a50a6a200341e0056a290300370000200341ad0a6a200341e8056a290300370000200341043a00940a200341073a00900a200320032903d0053700950a200341900a6a10a1010c010b200341d0036a41086a22024200370300200342003703d0034193e7c100411c200341d0036a1002200341e8046a41086a2002290300370300200320032903d0033703e804410021100240200341e8046a411041b8d6c200410041001004417f460d00200341003602900a200341e8046a4110200341900a6a41044100100441016a41044d0d0320032802900a21100b200341d0036a41086a22024200370300200342003703d0034193e7c100411c200341d0036a1002200341e8046a41086a2002290300370300200320032903d0033703e80402400240200341e8046a411041b8d6c200410041001004417f460d00200341003602900a200341e8046a4110200341900a6a41044100100441016a41044d0d0520032802900a41016a21020c010b410121020b200320023602900a200341d0036a41086a22024200370300200342003703d0034193e7c100411c200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a4110200341900a6a4104100320024200370300200342003703d00341afe7c1004118200341d0036a1002200341e8046a41086a2002290300370300200320032903d0033703e8044100210202400240024002400240200341e8046a411041b8d6c200410041001004417f460d00200342103702f4072003200341e8046a3602f007200341900a6a200341f0076a103920032802900a220f450d0c200341900a6a41086a280200210220032802940a211120032902940a2108200341f0076a41186a200341d0056a41186a290300370300200341f0076a41106a200341d0056a41106a290300370300200341f0076a41086a200341d0056a41086a290300370300200320032903d0053703f0072008422088a72008a7470d02200341f0076a210420112002460d010c040b200341f0076a41186a200341d0056a41186a290300370300200341f0076a41106a200341d0056a41106a290300370300200341f0076a41086a200341d0056a41086a290300370300200320032903d0053703f0074101210f200341f0076a21040b200241016a22142002490d4220024101742205201420142005491b2211ad4205862208422088a70d422008a722144100480d422002450d01201410002205450d0b2005200f201420024105742207200720144b1b10ce022114200f10012014210f0c020b200341f0076a21040c010b20141000220f450d090b200f20024105746a22142004290000370000201441186a200441186a290000370000201441106a200441106a290000370000201441086a200441086a290000370000024002400240200241016a2204413f4b0d00410110002207450d0c200720044102743a0000410121144101210520040d010c020b02402004418080014f0d0041022114410210002207450d0d200720044102744101723b00000c010b024020044180808080044f0d0041042114410410002207450d0e200720044102744102723600000c010b410110002205450d0e200541033a000041052114410510002207450d0f200720052d00003a000020051001200720043600010b200241057441206a210e20142105200f211303402013210202400240024002402014200522046b41204f0d00200441206a22052004490d4520144101742213200520052013491b22134100480d452014450d01201310002212450d072012200720132014201420134b1b10ce02211420071001201421070c020b200441206a21050c020b201310002207450d050b201321140b200241206a2113200720046a22042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a290000370000200e41606a220e0d000b0b200341d0036a41086a22024200370300200342003703d00341afe7c1004118200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a411020072005100302402014450d00200710010b02402011450d00200f10010b200341f0076a41186a200341d0056a41186a290300370300200341f0076a41106a200341d0056a41106a290300370300200341f0076a41086a200341d0056a41086a290300370300200320032903d0053703f007200341900a6a200d41a00210ce021a411910002202450d04200320023602b005200342193702b405200341b0056a41e3e6c10041191029200341e8046a41086a220220032802b805360200200320032903b0053703e804200341f0076a200341e8046a101b2002280200211420032802ec04210520032802e8042102200341003602b805200342013703b005200341900a6a200341b0056a10a00120032802b405210720032802b805211320032802b0052104200341d0036a41086a220e4200370300200342003703d00320022014200341d0036a1002200341c0036a41086a200e290300370300200320032903d0033703c003200341c0036a411020042013100302402007450d00200410010b02402005450d00200210010b200341900a6a102c200341f0076a41186a200341d0056a41186a290300370300200341f0076a41106a200341d0056a41106a290300370300200341f0076a41086a200341d0056a41086a290300370300200320032903d0053703f007412010002202450d052003419c0a6a428180808010370200200341ac0a6a410036020020034188056a41086a290300210820034188056a41106a2903002109200329038805210a200241186a20034188056a41186a290300370000200241106a2009370000200241086a20083700002002200a370000200320103602900a200320063602940a200320023602980a200342013702a40a411510002204450d06200320043602b005200342153702b405200341b0056a41c7e7c10041151029200341e8046a41086a221420032802b805360200200320032903b0053703e804200341f0076a200341e8046a101b20032802ec04210520032802e8042104200320142802003602b405200320043602b005200341900a6a200341b0056a101c02402005450d00200410010b200210012003419d0a6a20034188056a41086a290300370000200341a50a6a20034188056a41106a290300370000200341ad0a6a20034188056a41186a290300370000200341b50a6a20032903d005370000200341bd0a6a200341d0056a41086a290300370000200341c50a6a200341d0056a41106a290300370000200341cd0a6a200341d0056a41186a290300370000200341003a00940a200341073a00900a20032003290388053700950a200341dc0a6a2006360200200341d80a6a2010360200200341900a6a10a1010b200d1001410021040c520b201341011019000b41b2eac10041331040000b41b2eac10041331040000b411941011019000b412041011019000b411541011019000b41b2eac10041331040000b201441011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000b20140d2e0c2f0b411521144180c9c200210d0b20034180036a41026a2204200341e8026a41026a2d00003a000020034188056a41086a2205200341c8046a41086a29030037030020034188056a41106a200341c8046a41106a290300370300200320032f01e8023b018003200320032903c8043703880502402002450d00200d21044101210d4101210e0c250b20034183086a200529030037000020034188086a20034195056a290000370000200320032f0180033b01f0072003200d3600f307200320143600f70720032003290388053700fb07200320042d00003a00f207200341f0076a2009200810b402200341f0076a200b200a10b502410021044101210d4101210e0c240b200341d8016a200341f0076a2009200810b00220032802d801450d0141d9d5c1002104411a21140b200d102c200d10010c150b200341d0036a41086a22024200370300200342003703d00341c0d5c1004119200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003410021060240024002400240200341c0036a411041b8d6c200410041001004417f460d00200341003602900a200341c0036a4110200341900a6a41044100100441016a41044d0d0120032802900a21060b2003200641016a3602900a200341d0036a41086a22024200370300200342003703d00341c0d5c1004119200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a4110200341900a6a41041003412010002202450d01200220032903f007370000200341a40a6a428180808010370200200241186a200341f0076a41186a290300370000200241106a200341f0076a41106a290300370000200241086a200341f0076a41086a290300370000200320093703900a200320023602a00a200320083703980a2006200341900a6a10b701200341d0056a10ba01200341900a6a200d10b101200320032f00f1073b01c00320032d008f0821072003290087082108200328008308211320032800ff07210e20032900f707210920032d00f0072112024020032802d805221420032802d405470d00201441016a22022014490d2f2014410174220f20022002200f491b2210ad42c8027e220a422088a70d2f200aa722024100480d2f024002402014450d0020032802d005211120021000220f450d05200f20112002201441c8026c220c200c20024b1b10ce021a201110010c010b20021000220f450d040b200320103602d4052003200f3602d0050b20032802d005201441c8026c6a200341900a6a41a00210ce02220220123a00a402200220063602a002200241a7026a2004360000200241ab026a2009370000200241b3026a200e360000200241b7026a2013360000200241bb026a2008370000200341d0056a41086a2204201441016a360200200241a5026a20032f01c0033b0000200241c3026a20073a0000200341900a6a41086a22022004280200360200200320032903d0053703900a200341900a6a10cb0120032802900a2114024020022802002202450d00200241c8026c21042014210203402002102c200241c8026a2102200441b87d6a22040d000b0b024020032802940a450d00201410010b200d102c200d1001410021060c070b41b2eac10041331040000b412041011019000b200241081019000b200541046a21060b200220056a200d360000200341d0036a41086a22054200370300200342003703d00320022006200341d0036a1002200341c0036a41086a2005290300370300200320032903d0033703c003410021050240024002400240200341c0036a411041b8d6c200410041001004417f460d002003200341c0036a3602d005200341103602d405200342003703980a200342003703900a20034100200341c0036a4110200341900a6a41104100100422052005417f461b2205411020054110491b3602d8052005410f4d0d01200341980a6a2206290300210920032903900a210a200341900a6a200341d0056a103920032802900a2205450d01200a4220882009422086842108200942208821092006280200210720032802940a2106200aa721132014450d030c020b20140d010c020b41b2eac10041331040000b200210010b024002402005450d00200341e0016a200341f0076a20084220862013ad84220a2009422086200842208884220810b00220032802e001450d014197d6c1002104411a21142006450d14200510010c140b41f3d5c1002104412421140c130b200320032f00f1073b01c00320032d008f0821142003290087082109200328008308211320032800ff07210e20032900f707210b20032d00f0072112024002400240024020072006470d00200641016a22022006490d2d2006410174220f20022002200f491b220fad420586221b422088a70d2d201ba722024100480d2d2006450d01200210002210450d0320102005200220064105742206200620024b1b10ce02210220051001200221050c020b2006210f0c010b200210002205450d010b200520074105746a220220123a0000200220043600032002200b3700072002200e36000f2002201336001320022009370017200220032f01c0033b0001200220143a001f200341a40a6a200f360200200341a80a6a200741016a360200200320083703980a2003200a3703900a200320053602a00a200d200341900a6a10b701410021040c120b200241011019000b201441046a21060b200220146a200d360000200341d0036a41086a22144200370300200342003703d00320022006200341d0036a1002200341c0036a41086a2014290300370300200320032903d0033703c003200341c0036a41101014211402402004450d00200210010b02400240024002400240024002402014450d00200341e8016a200341f0076a10950220032903e801200341e8016a41086a290300844200510d012003419c0a6a200341f0076a41086a290300370200200341a40a6a200341f0076a41106a290300370200200341ac0a6a20034188086a2903003702002003200d3602900a200320032903f0073702940a411010002202450d09200320023602d005200342103702d405200341d0056a41a2c9c10041101029200341b0056a41086a220220032802d805360200200320032903d0053703b005200341900a6a200341b0056a10a3012002280200210420032802b405211420032802b0052102200341d0036a41086a22064200370300200342003703d00320022004200341d0036a1002200341c0036a41086a2006290300370300200320032903d0033703c003200341c0036a41101014210402402014450d00200210010b20040d06411310002202450d0b200320023602900a200342133702940a200341900a6a41f5c8c1004113102920032802900a210220032802940a220420032802980a22146b41044f0d02201441046a22062014490d2e20044101742207200620062007491b22074100480d2e2004450d0320071000220e450d0d200e200220072004200420074b1b10ce02210420021001200421020c040b41b1d6c1002104412221140c160b41d3d6c1002104413021140c150b201441046a21060c020b200710002202450d090b200721040b200220146a200d360000200341d0056a2002200610be0102402004450d00200210010b200341900a6a41186a2204200341f0076a41186a290300370300200341900a6a41106a2214200341f0076a41106a290300370300200341900a6a41086a2206200341f0076a41086a290300370300200320032903f0073703900a024020032802d805220220032802d405470d00200241016a22072002490d292002410174220e20072007200e491b2212ad4205862208422088a70d292008a722074100480d29024002402002450d0020032802d005210f20071000220e450d0b200e200f200720024105742210201020074b1b10ce021a200f10010c010b20071000220e450d0a0b200320123602d4052003200e3602d0050b200341d0056a41086a200241016a36020020032802d00520024105746a220220032903900a370000200241086a2006290300370000200241106a2014290300370000200241186a2004290300370000411310002202450d06200320023602900a200342133702940a200341900a6a41f5c8c1004113102920032802900a211002400240024020032802940a220420032802980a22026b41044f0d00200241046a220c2002490d2b20044101742214200c200c2014491b22114100480d2b2004450d01201110002214450d0c2014201020112004200420114b1b10ce02210420101001200421100c020b200241046a210c200421110c010b201110002210450d0a0b201020026a200d36000020032802d0052115024002400240200341d8056a2802002202413f4b0d0041012114410110002207450d0d200720024102743a00004101210620020d010c020b02402002418080014f0d0041022114410210002207450d0e200720024102744101723b00000c010b024020024180808080044f0d0041042114410410002207450d0f200720024102744102723600000c010b410110002204450d0f200441033a000041052114410510002207450d10200720042d00003a000020041001200720023600010b20024105742112201421062015210e0340200e210202400240024002402014200622046b41204f0d00200441206a22062004490d2e2014410174220e20062006200e491b220e4100480d2e2014450d01200e1000220f450d08200f2007200e20142014200e4b1b10ce02211420071001201421070c020b200441206a21060c020b200e10002207450d060b200e21140b200241206a210e200720046a22042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a290000370000201241606a22120d000b0b200341d0036a41086a22024200370300200342003703d0032010200c200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a411020072006100302402014450d00200710010b02402011450d00201010010b20032802d405450d00201510010b2003419c0a6a200341f0076a41086a290300370200200341a40a6a200341f0076a41106a290300370200200341ac0a6a20034188086a2903003702002003200d3602900a200320032903f0073702940a200320133a00e804411010002202450d03200320023602d005200342103702d405200341d0056a41a2c9c10041101029200341b0056a41086a220220032802d805360200200320032903d0053703b005200341900a6a200341b0056a10a3012002280200210420032802b405211420032802b0052102200341d0036a41086a22064200370300200342003703d00320022004200341d0036a1002200341c0036a41086a2006290300370300200320032903d0033703c00341012106200341c0036a4110200341e8046a410110032014450d00200210010b410021040240200541077122024102460d0020024105470d0f0c0e0b20060d0d0c0e0b200e41011019000b411041011019000b411041011019000b411341011019000b411341011019000b200741011019000b200741011019000b201141011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000b200d102c200d10010b0b4100210e4101210d0c0c0b411210002202450d01200320023602f007200342123702f407200341f0076a418cd2c2004112102920032802f0072102024002400240024020032802f407220420032802f807220d6b41044f0d00200d41046a2214200d490d1920044101742205201420142005491b22054100480d192004450d01200510002207450d092007200220052004200420054b1b10ce02210420021001200421020c020b200d41046a21140c020b200510002202450d070b200521040b2002200d6a200636000042002108200341e8046a41086a220d4200370300200342003703e80420022014200341e8046a1002200341d0036a41086a200d290300370300200320032903e8043703d00302400240200341d0036a411041b8d6c200410041001004417f460d00200341b8036a4200370300200341a0036a41106a4200370300200341a0036a41086a4200370300200342003703a0034100200341d0036a4110200341a0036a412041001004220d200d417f461b220d41204922050d04200320032f00a1033b01d00520032d00bf03210620032900b703210820032900af03210920032900a703210a20032800a3032107200320032d00a0033a00f007200320073600f3072003200a3700f707200320093700ff072003200837008708200320063a008f08200320032f01d00522063b01c003200320063b00f107200342003703d805200342003703d0054100200341d0036a4110200341d0056a4110200d412020051b22051004220d200d417f461b220d410f4d0d06200341d8056a2206290300210820032903d005210b200341e8056a4200370300200341d0056a41106a420037030020064200370300200342003703d0054100200341d0036a4110200341d0056a4120200d4110200d4110491b20056a22051004220d200d417f461b220d411f4d0d05200320032f00d1053b01880520032d00ef05210620032900e705210920032900df05210a20032900d705211b20032800d3052107200320032d00d0053a00e804200320073600eb042003201b3700ef042003200a3700f704200320093700ff04200320063a008705200320032f01880522063b01c003200320063b00e904200342003703d805200342003703d005200341d0036a4110200341d0056a4110200d4120200d4120491b20056a1004220d417f460d06200d410f4d0d06200341d0056a41086a220d290300210920032903d005210a200341d0056a41186a2206200341f0076a41186a2207290000370300200341d0056a41106a2213200341f0076a41106a220e290000370300200d200341f0076a41086a221229000037030020034188056a41086a220f200341e8046a41086a220529000037030020034188056a41106a2210200341e8046a41106a29000037030020034188056a41186a2211200341e8046a41186a290000370300200320032900f0073703d005200320032900e8043703880520072006290300370300200e20132903003703002012200d290300370300200341b0056a41086a200f290300370300200341b0056a41106a2010290300370300200341b0056a41186a2011290300370300200320032903d0053703f00720032003290388053703b00520054200370300200342003703e80420022014200341e8046a1002200341c0036a41086a2005290300370300200320032903e8043703c003200341c0036a4110100a200b422088200842208684211b2008422088211d200ba72114420121080c010b0b200341c8046a41186a200341f0076a41186a290300370300200341c8046a41106a200341f0076a41106a290300370300200341c8046a41086a200341f0076a41086a290300370300200341a8046a41086a200341b0056a41086a290300370300200341a8046a41106a200341b0056a41106a290300370300200341a8046a41186a200341b0056a41186a290300370300200320032903f0073703c804200320032903b0053703a80402402004450d00200210010b20084200510d0020034188046a41186a2202200341c8046a41186a29030037030020034188046a41106a2204200341c8046a41106a29030037030020034188046a41086a220d200341c8046a41086a290300370300200341e8036a41086a2205200341a8046a41086a290300370300200341e8036a41106a2206200341a8046a41106a290300370300200341e8036a41186a2207200341a8046a41186a290300370300200320032903c80437038804200320032903a8043703e803200341900a6a41186a20093703002003419c0a6a201d3e0200200341b80a6a200d290300370300200341c00a6a2004290300370300200341c80a6a2002290300370300200341d80a6a2005290300370300200341e00a6a2006290300370300200341e80a6a20072903003703002003200a3703a00a2003201b3702940a200320143602900a20032003290388043703b00a200320032903e8033703d00a200341c0026a200341b00a6a200a200910b6020c080b4199d6c2002104411921144101210d4101210e0c0a0b411241011019000b200320032f01d0053b01c00341b2eac10041331040000b200320032f0188053b01c0030b41b2eac10041331040000b200541011019000b4115210e4180c9c200210d0b20034180036a41026a2204200341e8026a41026a2d00003a000020034188056a41086a2214200341c8046a41086a29030037030020034188056a41106a200341c8046a41106a290300370300200320032f01e8023b018003200320032903c8043703880502402002450d00200e2114200d21044101210d4101210e0c040b20034183086a201429030037000020034188086a20034195056a290000370000200320032f0180033b01f0072003200d3600f3072003200e3600f70720032003290388053700fb07200320042d00003a00f207024002400240411410002202450d00200320023602900a200342143702940a200341900a6a41d7aac2004114102920034188056a41086a220220032802980a360200200320032903900a37038805200341d0056a20034188056a101b20022802002104200328028c05211420032802880521024200210a200341d0036a41086a220d4200370300200342003703d00320022004200341d0036a1002200341c0036a41086a200d290300370300200320032903d0033703c00302400240200341c0036a411041b8d6c200410041001004417f460d00200342003703980a200342003703900a200341c0036a4110200341900a6a4110410010042204417f460d012004410f4d0d01200341980a6a290300210b20032903900a210a2014450d040c030b4200210b20140d020c030b41b2eac10041331040000b411441011019000b200210010b024002400240411410002202450d00200320023602900a200342143702940a200341900a6a41d7aac2004114102920034188056a41086a220220032802980a360200200320032903900a37038805200341f0076a20034188056a101b20022802002104200328028c05211420032802880521024200211d200341d0036a41086a220d4200370300200342003703d00320022004200341d0036a1002200341c0036a41086a200d290300370300200320032903d0033703c00302400240200341c0036a411041b8d6c200410041001004417f460d00200342003703980a200342003703900a200341c0036a4110200341900a6a4110410010042204417f460d012004410f4d0d01200341980a6a290300212420032903900a211d2014450d040c030b4200212420140d020c030b41b2eac10041331040000b411441011019000b200210010b200341d0036a41086a22024200370300200342003703d00341f5afc2004189b0c200201d2024845022041b4114200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c00302400240024002400240200341c0036a411041b8d6c200410041001004417f460d00200342003703980a200342003703900a0240200341c0036a4110200341900a6a4110410010042202417f460d002002410f4d0d000240200a20032903900a222520097c221b7d2226200a56200b200341980a6a290300222720087c201b202554ad7c7d200a201b54ad7d220a200b56200a200b511b450d0041d1c4c2002104411d21144101210d4101210e0c0a0b02402004450d00200341d0036a41086a22024200370300200342003703d00341a1abc200411b200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a411041b8d6c200410041001004417f460d04200342003703980a200342003703900a200341c0036a4110200341900a6a4110410010042202417f460d032002410f4d0d0320032903900a200956200341980a6a290300220b200856200b2008511b450d0041eec4c2002104411f21144101210d4101210e0c0a0b411e2114200341d0056a109d0222040d080240201d20097c221b201d542202202420087c2002ad7c220b202454200b2024511b450d00418dc5c2002104412d21144101210d4101210e0c0a0b200341d0056a200341f0076a412010d102450d06200341d0056a2026200a10b402200341d0036a41086a22024200370300200342003703d00341bcabc2004116200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a411041b8d6c200410041001004417f460d05200342003703980a200342003703900a200341c0036a4110200341900a6a4110410010042202417f460d042002410f4d0d04024020032903900a220a20257d2224200a56200341900a6a41086a2202290300221d20277d200a202554ad7d220a201d56200a201d511b0d00200320243703900a2003200a3703980a200341d0036a41086a22044200370300200342003703d00341bcabc2004116200341d0036a1002200341c0036a41086a2004290300370300200320032903d0033703c003200341c0036a4110200341900a6a411010030b200341f0076a201b200b10ec011a200241023a0000200341990a6a20032903d005370000200341a10a6a200341d0056a41086a290300370000200341a90a6a200341d0056a41106a290300370000200341b10a6a200341d0056a41186a290300370000200341b90a6a20032903f007370000200341c10a6a200341f0076a41086a290300370000200341c90a6a200341f0076a41106a290300370000200341d10a6a200341f0076a41186a290300370000200341013a00900a200341e80a6a2008370300200341e00a6a2009370300200341f80a6a2027370300200341f00a6a2025370300200341900a6a10a1010c060b41b2eac10041331040000b41c3d7c10041221040000b41b2eac10041331040000b41c3d7c10041221040000b41b2eac10041331040000b41c3d7c10041221040000b410021040b0b4101210d4101210e0b410121050b410121060b41012107410121130c030b201710010b412d21144101210e024002400240024002400240201a41077122024107460d004100210d41012105410121064101210741012113410021040240024020020e0709090901000003090b4100210d41000d0620190d040c060b4100210d201220194572450d030c050b2018450d01201841186c21042017210203400240200241046a280200450d00200228020010010b0240200241106a280200450d002002410c6a28020010010b200241186a2102200441686a22040d000c020b0b4100210d2012450d032018450d00201841186c21042017210203400240200241046a280200450d00200228020010010b0240200241106a280200450d002002410c6a28020010010b200241186a2102200441686a22040d000b0b2019450d010b201710010b4100210d0b410121054101210641012107410121130b410021042001280200220241094d0d190c1a0b2001280200220241094d0d180c190b410021134101210d4101210e4101210541012106410121072001280200220241094d0d170c180b200210010b0240024002400240024002402006450d002003200e3602c80420102017470d0120034188056a20066b221341606a2110201341406a2119201341a07f6a211820062012410574221e6a210f4100210220062107410021040340200f20076b41ff004d0d0320132002460d042004200620026a221420034188056a412010d10222074100476a21042007450d0420102002460d042004201441206a20034188056a412010d10222074100476a21042007450d0420192002460d042004201441c0006a20034188056a412010d10222074100476a21042007450d0420182002460d0420144180016a210720024180016a21022004201441e0006a20034188056a412010d10222144100476a210420140d000c040b0b41f0e7c10021044113211420054102460d180c190b4183e8c1002104411021142016450d150c140b200620026a2114201e20026b210203402002450d0220034188056a2014460d01200441016a2104200241606a2102201420034188056a412010d1022107201441206a211420070d000b20074541016a41017120046a417f6a21040b4101211f0c010b4100211f0b20034188056a200e6b220f41606a2119200f41406a2118200f41a07f6a211e200e200c41057422206a211041002114200e21134100210202400240024002400240024002400340201020136b41ff004d0d01200f2014460d022002200e20146a220720034188056a412010d10222134100476a21022013450d0220192014460d022002200741206a20034188056a412010d10222134100476a21022013450d0220182014460d022002200741c0006a20034188056a412010d10222134100476a21022013450d02201e2014460d0220074180016a211320144180016a21142002200741e0006a20034188056a412010d10222074100476a210220070d000c020b0b200e20146a2107202020146b211403402014450d0220034188056a2007460d01200241016a2102201441606a2114200720034188056a412010d1022113200741206a210720130d000b20134541016a41017120026a417f6a21020b41012114201141ff0171450d010c020b41002114201141ff01710d010b20140d01200341900a6a41186a221420034188056a41186a290300370300200341900a6a41106a220720034188056a41106a290300370300200341900a6a41086a221320034188056a41086a29030037030020032003290388053703900a024002400240024002400240200c2015470d00201541016a22022015490d092015410174220f20022002200f491b220fad4205862208422088a70d092008a722104100480d092015450d01201010002202450d042002200e201020154105742215201520104b1b10ce021a200e10010c020b200e21022015210f0c020b201010002202450d020b200320023602c8042002200c4105746a21100b201020032903900a370000201041186a2014290300370000201041106a2007290300370000201041086a2013290300370000200c41016a210c0240201f450d00201220044d0d0220062012417f6a22124105746a22142900002108201429000821092014290010210a200620044105746a220441186a201441186a2900003700002004200a37001020042009370008200420083700000b2002210e2006211020162119200f21150c040b201041011019000b41bcb2c00020042012104a000b201f0d00200341900a6a41186a220720034188056a41186a290300370300200341900a6a41106a221320034188056a41106a290300370300200341900a6a41086a220f20034188056a41086a29030037030020032003290388053703900a02400240024020122016470d00201641016a22042016490d0520164101742210200420042010491b2219ad4205862208422088a70d052008a722044100480d052016450d01200410002210450d0a20102006200420164105742216201620044b1b10ce021a200610010c020b20062110201621190c010b200410002210450d080b201020124105746a220420032903900a370000200441186a2007290300370000200441106a2013290300370000200441086a200f290300370000201241016a21122014450d01200c20024d0d08200e200c417f6a220c4105746a22042900002108200429000821092004290010210a200e20024105746a220241186a200441186a2900003700002002200a37001020022009370008200220083700000c010b4193e8c10021044116211420160d110c120b200341b50a6a20032903b0053700002003419d0a6a20034188056a41086a290300370000200341a50a6a20034188056a41106a290300370000200341ad0a6a20034188056a41186a290300370000200341bd0a6a200341b0056a41086a290300370000200341c50a6a200341b0056a41106a290300370000200341cd0a6a200341b0056a41186a290300370000200341013a00940a200341073a00900a20032003290388053700950a200341d80a6a2012360200200341d50a6a20113a0000200341dc0a6a200c360200200341900a6a10a101200341900a6a10bd0120032802980a2102024020032802940a450d0020032802900a10010b02400240024002402012201c4f22040d0041002002200c6b2214201420024b1b201c490d002003419c0a6a2019360200200341a00a6a2012360200200341a80a6a2015360200200341ac0a6a200c3602002003201c3602940a200320173602900a200320103602980a2003200e3602a40a411510002202450d08200320023602f007200342153702f407200341f0076a41c7e7c10041151029200341d8056a220420032802f807360200200320032903f0073703d005200341b0056a200341d0056a101b20032802d405211420032802d0052102200320042802003602f407200320023602f007200341900a6a200341f0076a101c2014450d012002100120190d020c030b02400240024002402004450d002003419d0a6a200341b0056a41086a290300370000200341a50a6a200341b0056a41106a290300370000200341ad0a6a200341c8056a290300370000200341023a00940a200341073a00900a200320032903b0053700950a200341900a6a10a101411910002202450d0f200320023602900a200342193702940a200341900a6a41e3e6c10041191029200341f0076a41086a220220032802980a360200200320032903900a3703f007200341b0056a200341f0076a101b2002280200210420032802f407210620032802f0072102200341d0036a41086a22144200370300200342003703d00320022004200341d0036a1002200341e8046a41086a2014290300370300200320032903d0033703e804200341e8046a411041b8d6c200410041001004417f460d01200342103702d4052003200341e8046a3602d005200341900a6a200341d0056a10bb0120032802900a2214410b460d11200341f0076a200341900a6a410472419c0210ce021a200341d0036a41086a22074200370300200342003703d00320022004200341d0036a1002200341c0036a41086a2007290300370300200320032903d0033703c003200341c0036a4110100a0c020b2003419d0a6a200341b8056a290300370000200341a50a6a200341c0056a290300370000200341ad0a6a200341c8056a290300370000200341033a00940a200341073a00900a200320032903b0053700950a200341900a6a10a101411521024115100022040d020c150b410b21140b200341d0056a200341f0076a419c0210ce021a02402006450d00200210010b02402014410b460d00200320143602900a200341900a6a410472200341d0056a419c0210ce021a200341013a00f0072003201c3602f40720034190026a200341900a6a200341f0076a10ab02200341b50a6a200328029002453a00002003419d0a6a200341b8056a290300370000200341a50a6a200341c0056a290300370000200341ad0a6a200341c8056a290300370000200341043a00940a200341073a00900a200320032903b0053700950a200341900a6a10a1010b41152102411510002204450d130b200320043602900a200342153702940a200341900a6a41c7e7c10020021029200341f0076a41086a220220032802980a360200200320032903900a3703f007200341b0056a200341f0076a101b2002280200211420032802f407210620032802f0072104200341d0036a41086a22024200370300200342003703d00320042014200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a4110100a02402006450d00200410010b20024200370300200342003703d00341afe7c1004118200341d0036a1002200341e8046a41086a2002290300370300200320032903d0033703e8040240024002400240200341e8046a411041b8d6c200410041001004417f460d00200342103702f4072003200341e8046a3602f007200341900a6a200341f0076a103920032802900a2211450d0e20032902940a2208422088a722130d010c020b42002108410121114200422088a72213450d010b4100210641002112410021040340024002402012450d00201120044105746a21022011200420066a4105746a21140340200420134f0d0a200341b0056a2002460d022002200341b0056a412010d102450d02200620046a220720134f0d0c20142002290000370000201441186a200241186a290000370000201441106a200241106a290000370000201441086a200241086a290000370000200241206a2102201441206a21142013200441016a2204470d000c050b0b201120044105746a21020340200420134f0d09200341b0056a2002460d012002200341b0056a412010d102450d01200241206a21022013200441016a2204470d000c030b0b2006417f6a2106201241016a2112200441016a22042013470d000c020b0b410021120b024002400240201320126b2202413f4b0d0041012114410110002207450d0f200720024102743a00004101210620020d010c020b02402002418080014f0d0041022114410210002207450d11200720024102744101723b00000c010b024020024180808080044f0d0041042114410410002207450d12200720024102744102723600000c010b410110002204450d12200441033a000041052114410510002207450d13200720042d00003a000020041001200720023600010b201341057420124105746b2112201421062011211303402013210202400240024002402014200622046b41204f0d00200441206a22062004490d0920144101742213200620062013491b22134100480d092014450d0120131000220f450d0b200f200720132014201420134b1b10ce02211420071001201421070c020b200441206a21060c020b201310002207450d090b201321140b200241206a2113200720046a22042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a290000370000201241606a22120d000b0b200341d0036a41086a22024200370300200342003703d00341afe7c1004118200341d0036a1002200341c0036a41086a2002290300370300200320032903d0033703c003200341c0036a411020072006100302402014450d00200710010b2008a7450d00201110010b2019450d010b201010010b02402015450d00200e10010b4100210420054102470d140c130b1018000b41a080c00020042013104a000b201341011019000b41b080c00020072013104a000b411541011019000b200441011019000b41bcb2c0002002200c104a000b41b2eac10041331040000b411941011019000b410141011019000b41b2eac10041331040000b410241011019000b410441011019000b410141011019000b410541011019000b200241011019000b200610010b2015450d0020032802c804100120054102460d010c020b20054102470d010b200d102c200d10010b410021074101210d4101210e4101210541012106410121132001280200220241094b0d010b02400240024002400240024020020e0a00070707070302040107000b200d450d06200141086a10a9020c060b2007450d0520012d00044102470d052001410c6a220128020010bc01200128020010010c050b2005450d04200141086a2802004102470d04200141106a280200450d042001410c6a28020010010c040b200e450d03200141086a2d000022024107714105460d0120024102470d032001410c6a220128020010bc01200128020010010c030b2006450d02200141086a2d00004102470d022001410c6a220128020010bc01200128020010010c020b2001410c6a220128020010bc01200128020010010c010b2013450d00200141086a2d00002202411e74411e75417f4a0d00024020024102470d00200141306a280200450d012001412c6a28020010010c010b0240200141106a280200450d002001410c6a28020010010b2001411c6a280200450d00200141186a28020010010b2000201436020420002004360200200341b00c6a24000bcfbc01070c7f047e037f037e067f027e107f230041e0036b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802002204417e6a220541084b0d0002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e09000502030106070408000b2001410c6a2802002106200141086a2802002107200141106a280200210820012802042109200241096a280000210a200241056a280000210520022d0001210b20022d00002104200341b8036a41026a220c200241046a2d00003a0000200341c8016a41086a220d200241156a290000370300200341c8016a410d6a220e2002411a6a2900003700002003200241026a2f01003b01b80320032002410d6a2900003703c80120040d0f200341d8026a41026a200c2d00003a0000200341b8026a41086a200d290300370300200341b8026a410d6a200e290000370000200320032f01b8033b01d802200320032903c8013703b802200b41ff01714101470d0f200341cb036a200341b8026a41086a290300220f370000200341d0036a200341b8026a410d6a2900002210370000200341f8026a41026a200341d8026a41026a2d000022023a0000200341c8016a41086a200f370300200341c8016a410d6a2010370000200320053600bb032003200a3600bf03200320032f01d80222043b01b803200320032903b802220f3700c303200320043b01f8022003200f3703c801200320023a00ba03410021020c100b200141386a2903002111200141306a2903002112200141286a2802002106200341a4016a41026a200141076a2d00003a000020034188016a41086a200141186a29020037030020034188016a410d6a2001411d6a290000370000200320012f00053b01a4012003200141106a29020037038801200141086a28020021072001410c6a280200210920012d0004210b200241096a280000210a200241056a280000210520022d0001210c20022d00002104200341b8036a41026a220d200241046a2d00003a0000200341c8016a41086a220e200241156a290000370300200341c8016a410d6a22082002411a6a2900003700002003200241026a2f01003b01b80320032002410d6a2900003703c80120040d08200341a8016a41026a200d2d00003a0000200341d8026a41086a200e290300370300200341d8026a410d6a2008290000370000200320032f01b8033b01a801200320032903c8013703d802200c41ff01714101470d08200341cb036a200341d8026a41086a290300220f370000200341d0036a200341d8026a410d6a2900002210370000200341f8026a41026a200341a8016a41026a2d000022023a0000200341c8016a41086a200f370300200341c8016a410d6a2010370000200320053600bb032003200a3600bf03200320032f01a80122043b01b803200320032903d802220f3700c303200320043b01f8022003200f3703c801200320023a00ba03410021040c090b2001280204210d200241096a280000210a200241056a280000210520022d0001210720022d0000210420034190036a41026a2209200241046a2d00003a0000200341b8036a41086a220b200241156a290000370300200341b8036a410d6a220c2002411a6a2900003700002003200241026a2f01003b01900320032002410d6a2900003703b80320040d09200341d8026a41026a20092d00003a0000200341b8026a41086a200b290300370300200341b8026a410d6a200c290000370000200320032f0190033b01d802200320032903b8033703b802200741ff01714101470d09200341cb036a200341b8026a41086a290300220f370000200341d0036a200341b8026a410d6a2900002210370000200341f8026a41026a200341d8026a41026a2d000022023a000020034190036a41086a200f37030020034190036a410d6a2010370000200320053600bb032003200a3600bf03200320032f01d80222043b01b803200320032903b802220f3700c303200320043b01f8022003200f37039003200320023a00ba03410021020c0a0b20012802042107200241096a280000210a200241056a280000210520022d0001210920022d00002104200341b8036a41026a220b200241046a2d00003a0000200341c8016a41086a220c200241156a290000370300200341c8016a410d6a220d2002411a6a2900003700002003200241026a2f01003b01b80320032002410d6a2900003703c80120040d0a200341d8026a41026a200b2d00003a0000200341b8026a41086a200c290300370300200341b8026a410d6a200d290000370000200320032f01b8033b01d802200320032903c8013703b802200941ff01714101470d0a200341cb036a200341b8026a41086a290300220f370000200341d0036a200341b8026a410d6a2900002210370000200341f8026a41026a200341d8026a41026a2d000022023a0000200341c8016a41086a200f370300200341c8016a410d6a2010370000200320053600bb032003200a3600bf03200320032f01d80222043b01b803200320032903b802220f3700c303200320043b01f8022003200f3703c801200320023a00ba03410021020c0b0b4100210541d2a9c20041d2a9c2004100410320022d000120022d00001b41ff017122021b20024103461b22020d042003200141086a2903003703c801200341b8036a41086a22024200370300200342003703b80341b58ec200411c200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a4110200341c8016a41081003410121040c7f0b200141306a28020021062001412c6a280200211320012802042114200341a4016a41026a2001410b6a2d00003a000020034188016a41086a2001411c6a29020037030020034188016a410d6a200141216a290000370000200320012f00093b01a4012003200141146a29020037038801200141086a2d0000210b2001410c6a2802002107200141106a2802002109200241096a280000210a200241056a280000210520022d0001210c20022d00002104200341b8036a41026a220d200241046a2d00003a0000200341c8016a41086a220e200241156a290000370300200341c8016a410d6a22082002411a6a2900003700002003200241026a2f01003b01b80320032002410d6a2900003703c80120040d0c200341a8016a41026a200d2d00003a0000200341d8026a41086a200e290300370300200341d8026a410d6a2008290000370000200320032f01b8033b01a801200320032903c8013703d802200c41ff01714101470d0c200341cb036a200341d8026a41086a290300220f370000200341d0036a200341d8026a410d6a2900002210370000200341f8026a41026a200341a8016a41026a2d000022023a0000200341c8016a41086a200f370300200341c8016a410d6a2010370000200320053600bb032003200a3600bf03200320032f01a80122043b01b803200320032903d802220f3700c303200320043b01f8022003200f3703c801200320023a00ba03410021040c0d0b4100210541d2a9c20041d2a9c2004100410320022d000120022d00001b41ff017122021b20024103461b22020d02200320012802043602c801200341b8036a41086a22024200370300200342003703b80341e48dc2004114200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a4110200341c8016a41041003410121040c7d0b200341f4026a41026a2204200141076a2d00003a0000200341f8026a41086a2207200141186a290200370300200341f8026a410d6a22092001411d6a290000370000200320012f00053b01f4022003200141106a2902003703f80241d2a9c20041d2a9c2004100410320022d000120022d00001b41ff017122021b20024103461b2205450d0c4128210a0c7d0b4100210541d2a9c20041d2a9c2004100410320022d000120022d00001b41ff017122021b20024103461b2202450d0c0b4128210a024020044102470d00200141086a280200450d00200128020410010b200221050c7b0b41012104412a210a41faa9c20021050b200341b4036a41026a2202200341f8026a41026a2d00003a000020034190036a41086a220c200341c8016a41086a29030037030020034190036a41106a200341c8016a41106a290300370300200320032f01f8023b01b403200320032903c8013703900320040d72200341b8026a41136a200c290300370000200341b8026a41186a20034190036a410d6a290000370000200320032f01b4033b01b802200320053600bb022003200a3600bf0220032003290390033700c302200320022d00003a00ba022002200341a4016a41026a2d00003a0000200341f8026a41086a20034188016a41086a290300370300200341f8026a410d6a220520034188016a410d6a290000370000200320032f01a4013b01b40320032003290388013703f80241012102200b41ff01714101470d0a200341c8016a200710a80120032d00c8014101470d10200341f6026a20032d00cb013a0000200341d0036a200341e1016a290000220f370300200341c8036a200341d9016a290000370300200341b8036a41086a200341d1016a290000370300200341d8026a41086a200341dc016a290200370300200341e5026a200f370000200320032900c9013703b803200320032f00c9013b01f4022003200341d4016a2902003703d802200341c8016a41086a28020021094100210220032802cc0121070c110b4101210241faa9c2002105412a210a0b200341c4016a41026a2204200341f8026a41026a2d00003a0000200341a8016a41086a220720034190036a41086a290300370300200341a8016a41106a20034190036a41106a290300370300200320032f01f8023b01c40120032003290390033703a80120020d70200341db016a2007290300370000200341e0016a200341b5016a290000370000200320032f01c4013b01c801200320053600cb012003200a3600cf01200320032903a8013700d301200320042d00003a00ca01200341b8036a41086a22024200370300200342003703b803418d8ec2004114200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a41101014450d0a41bfa5c2002105411e210a0c700b4101210241faa9c2002105412a210a0b200341c4016a41026a2204200341f8026a41026a2d00003a0000200341a8016a41086a2209200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200320032f01f8023b01c401200320032903c8013703a80120020d6e200341a3036a2009290300370000200341a8036a200341b5016a290000370000200320032f01c4013b01900320032005360093032003200a36009703200320032903a80137009b03200320042d00003a009203411610002202450d30200320023602c801200342163702cc01200341c8016a419c8fc20041161029200341b8036a41086a220220032802d001360200200320032903c8013703b80320034190036a200341b8036a101b2002280200210a20032802bc03210420032802b803210520024200370300200342003703b8032005200a200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a41101014210202402004450d00200510010b2002450d0a41a6a6c2002105411e210a0c6e0b4101210241faa9c2002105412a210a0b200341c4016a41026a2204200341f8026a41026a2d00003a0000200341a8016a41086a220b200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200320032f01f8023b01c401200320032903c8013703a801024020020d00200341a3036a200b290300370000200341a8036a200341b5016a290000370000200320032f01c4013b01900320032005360093032003200a36009703200320032903a80137009b03200320042d00003a009203200341b8036a41086a22024200370300200342003703b803418d8ec2004114200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a41101014450d0841e9a2c2002105412e210a0b410021042007450d720c710b4101210441faa9c2002105412a210a0b200341b4036a41026a2202200341f8026a41026a2d00003a000020034190036a41086a220c200341c8016a41086a29030037030020034190036a41106a200341c8016a41106a290300370300200320032f01f8023b01b403200320032903c8013703900320040d6a200341b8026a41136a200c290300370000200341b8026a41186a20034190036a410d6a290000370000200320032f01b4033b01b802200320053600bb022003200a3600bf0220032003290390033700c302200320022d00003a00ba022002200341a4016a41026a2d00003a0000200341f8026a41086a20034188016a41086a290300370300200341f8026a410d6a220520034188016a410d6a290000370000200320032f01a4013b01b40320032003290388013703f80241012102200b41ff01714101470d03200341c8016a200710a80120032d00c8014101470d0a200341f6026a20032d00cb013a0000200341d0036a200341e1016a290000220f370300200341c8036a200341d9016a290000370300200341b8036a41086a200341d1016a290000370300200341d8026a41086a200341dc016a290200370300200341e5026a200f370000200320032900c9013703b803200320032f00c9013b01f4022003200341d4016a2902003703d802200341c8016a41086a28020021094100210220032802cc0121070c0b0b2001410c6a280200210a200141086a280200210520012d0004210b20034188016a41026a20042d00003a0000200341d8026a41086a2007290300370300200341d8026a410d6a2009290000370000200320032f01f4023b018801200320032903f8023703d80241012102200b41ff01714101470d06200341c8016a200510a80120032d00c8014101470d0d200341b6036a20032d00cb013a0000200341d0036a200341e1016a290000220f370300200341c8036a200341d9016a290000370300200341b8036a41086a200341d1016a290000370300200341b8026a41086a200341dc016a290200370300200341c5026a200f370000200320032900c9013703b803200320032f00c9013b01b4032003200341d4016a2902003703b802200341c8016a41086a280200210a4100210220032802cc0121050c0e0b2003200141086a2903003703c801200341b8036a41086a22024200370300200342003703b80341a18ec2004114200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a4110200341c8016a41081003410121040c6e0b200341c8016a41026a200341b4036a41026a2d000022023a0000200341c8016a41136a200341f8026a41086a290300220f370000200341c8016a41186a20052900002210370000200341f4026a41026a20023a0000200341d8026a41086a200f370300200341d8026a410d6a2010370000200320073600cb01200320093600cf01200320032f01b40322023b01c801200320032903f802220f3700d301200320023b01f4022003200f3703d802410021020c060b200341c8016a41026a200341b4036a41026a2d000022023a0000200341c8016a41136a200341f8026a41086a290300220f370000200341c8016a41186a20052900002210370000200341f4026a41026a20023a0000200341d8026a41086a200f370300200341d8026a410d6a2010370000200320073600cb01200320093600cf01200320032f01b40322023b01c801200320032903f802220f3700d301200320023b01f4022003200f3703d802410021020c070b411410002202450d2b200320023602b803200342143702bc03200341b8036a41aba3c2004114102920034190036a41086a220220032802c003360200200320032903b80337039003200341c8016a20034190036a101b20022802002105200328029403210a2003280290032102200341b8036a41086a22044200370300200342003703b80320022005200341b8036a1002200341d8026a41086a2004290300370300200320032903b8033703d802200341d8026a4110101421050240200a450d00200210010b4118210a2005450d0c200341b8036a41086a22024200370300200342003703b80341d18ec200410e200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a411041b8d6c200410041001004417f460d1420034210370294032003200341d8026a36029003200341b8036a20034190036a103920032802b8032202450d3620032802bc032104200341c0036a2802002205200d4d0d152002200d4105746a220a200341c8016a460d1d200a200341c8016a412010d102450d1d418da6c20021054119210a20040d160c650b200341b8036a41086a22024200370300200342003703b80341da8fc2004111200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802410021020240200341d8026a411041b8d6c200410041001004417f460d00200341003602c801200341d8026a4110200341c8016a41044100100441016a41044d0d2520032802c80121020b20022008470d0a411410002202450d30200320023602c801200342143702cc01200341c8016a41aba3c20041141029200341b8036a41086a220220032802d001360200200320032903c8013703b80320034190036a200341b8036a101b2002280200210a20032802bc03210420032802b803210520024200370300200342003703b8032005200a200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a41101014210202402004450d00200510010b2002450d160c650b200341b8036a41086a22024200370300200342003703b80341c48fc2004116200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d8024100210d0240200341d8026a411041b8d6c200410041001004417f460d00200341003602c801200341d8026a4110200341c8016a41044100100441016a41044d0d2520032802c801210d0b200341b8036a41086a22024200370300200342003703b80341b28fc2004112200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d80241002102200341d8026a411041b8d6c200410041001004417f460d0b200342103702bc032003200341d8026a3602b803200341c8016a200341b8036a103920032802c8012204450d2d200341d0016a280200210220032802cc01210e200d2007460d0c0c0d0b200341c8016a41026a20034188016a41026a2d000022023a0000200341db016a200341d8026a41086a290300220f370000200341e0016a200341d8026a410d6a2900002210370000200341b4036a41026a20023a0000200341b8026a41086a200f370300200341b8026a410d6a2010370000200320053600cb012003200a3600cf01200320032f01880122023b01c801200320032903d802220f3700d301200320023b01b4032003200f3703b802410021020c070b411521094180c9c20021070b200341c4016a41026a2205200341f4026a41026a2d00003a0000200341a8016a41086a220a200341d8026a41086a2204290300370300200341a8016a41106a200341d8026a41106a290300370300200320032f01f4023b01c401200320032903d8023703a80102402002450d00410121042009210a200721050c670b200341a3036a200a290300370000200341a8036a200341b5016a290000370000200320032f01c4013b01900320032007360093032003200936009703200320032903a80137009b03200320052d00003a009203200341b8036a41086a22024200370300200342003703b80341da8fc2004111200341b8036a100220042002290300370300200320032903b8033703d802410021020240200341d8026a411041b8d6c200410041001004417f460d00200341003602c801200341d8026a4110200341c8016a41044100100441016a41044d0d1f20032802c80121020b20022006470d02200341b8036a41086a22024200370300200342003703b803418d8ec2004114200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a411041b8d6c200410041001004417f460d0d2003200341d8026a3602b803200341103602bc03200342003703c80120034100200341d8026a4110200341c8016a41084100100422022002417f461b22024108200241084922051b22023602c00320050d25200341003602c801200341c0036a4100200341d8026a4110200341c8016a41042002100422052005417f461b22054104200541044922051b20026a36020020050d25200341c8016a200341b8036a103920032802c8012214450d25200341c8016a41086a280200210620032802cc01210e200341b8036a41086a22024200370300200342003703b80341df8ec2004118200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a411041b8d6c200410041001004417f460d2e200342103702bc032003200341d8026a3602b80320034180016a200341b8036a1035200328028001450d1d2003280284012209ad220f421c88a70d43200f420486a72202417f4c0d432002450d132002100022040d14200241081019000b4180c9c2002107411521090b200341c4016a41026a2205200341f4026a41026a2d00003a0000200341a8016a41086a220a200341d8026a41086a2204290300370300200341a8016a41106a200341d8026a41106a290300370300200320032f01f4023b01c401200320032903d8023703a80102402002450d00410121042009210a200721050c650b200341a3036a200a290300370000200341a8036a200341b5016a290000370000200320032f01c4013b01900320032007360093032003200936009703200320032903a80137009b03200320052d00003a009203200341b8036a41086a22024200370300200342003703b803418d8ec2004114200341b8036a100220042002290300370300200320032903b8033703d802200341d8026a41101014450d0141e4a3c20021054126210a0c5e0b41f8a6c20021054111210a0c5d0b411410002202450d29200320023602c801200342143702cc01200341c8016a41aba3c20041141029200341b8036a41086a220220032802d001360200200320032903c8013703b803200341b8026a200341b8036a101b2002280200210a20032802bc03210420032802b803210520024200370300200342003703b8032005200a200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802410021020240200341d8026a411041b8d6c200410041001004417f460d00200341003602c80141012102200341d8026a4110200341c8016a41044100100441016a41044d0d210b02402004450d00200510010b2002450d0a411410002202450d31200320023602c801200342143702cc01200341c8016a41aba3c20041141029200341b8036a41086a220220032802d001360200200320032903c8013703b80320034190036a200341b8036a101b2002280200210a20032802bc03210420032802b803210520024200370300200342003703b8032005200a200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d80241002102200341d8026a411041b8d6c200410041001004417f460d15200341003602c80141012102200341d8026a4110200341c8016a41044100100441016a41044d0d2520032802c80121072004450d5b0c5a0b4115210a4180c9c20021050b200341c4016a41026a2204200341b4036a41026a2d00003a0000200341a8016a41086a2207200341b8026a41086a290300370300200341a8016a41106a200341b8026a41106a290300370300200320032f01b4033b01c401200320032903b8023703a80120020d5a200341a3036a200729030037000020034190036a41186a200341b5016a290000370000200320032f01c4013b01900320032005360093032003200a36009703200320032903a80137009b03200320042d00003a009203200341c8016a10bd0120032802cc01211520032802c8012113024020032802d0012202450d00200241286c41b07f6a2105201321020340200341c8016a41206a200241206a290300370300200341c8016a41186a200241186a290300370300200341c8016a41106a200241106a290300370300200341c8016a41086a200241086a290300370300200320022903003703c801200341c8016a20034190036a412010d1020d07200241286a2102200541586a220541b07f470d000b0b4100210c4108210e2015450d06201310014100210d0c110b4197a3c20021054114210a4100210420070d5e0c5f0b41dda5c20021050c580b410121044100210e200d2007470d010b20022007460d3f0b41c4a6c20021054116210a0240200220074d0d00200341e0016a4200370300200341d8016a4200370300200341d0016a4200370300200342003703c801200420074105746a2209200341c8016a460d3f2009200341c8016a412010d102450d3f0b200e450d550c3f0b200341b8036a41206a220a200341c8016a41206a290300370300200341b8036a41186a2204200341c8016a41186a290300370300200341b8036a41106a2207200341c8016a41106a290300370300200341b8036a41086a2209200341c8016a41086a290300370300200320032903c8013703b80341281000220e450d27200e20032903b803370300200e41206a200a290300370300200e41186a2004290300370300200e41106a2007290300370300200e41086a200929030037030020054158460d09200241286a21024101210c4101210d0340200341c8016a41206a2204200241206a290300370300200341c8016a41186a2207200241186a290300370300200341c8016a41106a2209200241106a290300370300200341c8016a41086a220b200241086a290300370300200320022903003703c80102400240024002400240200341c8016a20034190036a412010d102450d00200341b8036a41206a220a2004290300370300200341b8036a41186a22082007290300370300200341b8036a41106a22062009290300370300200341b8036a41086a2214200b290300370300200320032903c8013703b8032004200a2903003703002007200829030037030020092006290300370300200b2014290300370300200320032903b8033703c801200d200c470d03200c41016a220a200c490d55200c4101742208200a200a2008491b2208ad42287e220f422088a70d55200fa7220a4100480d55200c450d01200a10002206450d1d2006200e200a200c41286c220c200c200a4b1b10ce02210a200e1001200a210e0c020b20050d030c0f0b200a1000220e450d1b0b2008210c0b200e200d41286c6a220a20032903c801370300200a41206a2004290300370300200a41186a2007290300370300200a41106a2009290300370300200a41086a200b290300370300200d41016a210d2005450d0c0b200241286a2102200541586a21050c000b0b4100210d0c0a0b4189a7c2002105412d210a0c520b418aa4c20021054118210a0c510b41f5a5c20021050c500b41f5a5c20021054118210a2004450d4f0b200210010c4e0b200341b8036a41086a22024200370300200342003703b80341bfa3c2004112200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a411041b8d6c200410041001004417f460d24200342003703d001200342003703c801200341d8026a4110200341c8016a4110410010042202417f460d1f2002410f4d0d1f200341086a20034190036a20032903c801200341c8016a41086a29030010b00220032802082205450d07200328020c210a4100210420070d520c530b410821040b02402009450d00200341b8036a41086a280200210520032802bc03210b20032802b803210c4100210a0340200342003703d001200342003703c8014100200c200b200341c8016a41102005100422022002417f461b22024110200241104922021b20056a210520020d09200341c8016a41086a290300211020032903c80121160240200f422088a7200fa72202470d00200241016a22072002490d492002410174220d20072007200d491bad22174204862218422088a70d492018a722074100480d49024002402002450d0020071000220d450d0f200d2004200720024104742202200220074b1b10ce02210220041001200221040c010b200710002204450d0e0b200f42808080807083201784210f0b2004200f422088a74104746a2202201037030820022016370300200f4280808080107c210f200a41016a220a2009490d000b200341c0036a20053602000b20042207450d08200341b8036a41086a22024200370300200342003703b80341d18ec200410e200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d8024100210b02400240200341d8026a411041b8d6c200410041001004417f460d00200342103702bc032003200341d8026a3602b803200341c8016a200341b8036a103920032802c8012208450d21200341d0016a280200210920032802cc01210b0c010b41012108410021090b200341b8036a41086a22024200370300200342003703b8034191a9c200411c200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a411041b8d6c200410041001004417f460d1a200342003703d001200342003703c801200341d8026a4110200341c8016a4110410010042202417f460d132002410f4d0d1342002117200341f0006a20032903c801200341c8016a41086a2903002009ad420010d502200341f0006a41086a2903002110411410002202450d1b20032903702118200320023602c801200342143702cc01200341c8016a41d7aac20041141029200341b8036a41086a220220032802d001360200200320032903c8013703b803200341b8026a200341b8036a101b2002280200210c20032802bc03210a20032802b803210520024200370300200342003703b8032005200c200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d8020240200341d8026a411041b8d6c200410041001004417f460d00200342003703d001200342003703c801200341d8026a4110200341c8016a4110410010042202417f460d172002410f4d0d17200341d0016a290300211620032903c8012117200a450d2e0c2d0b42002116200a0d2c0c2d0b4101210c4101210d0b2015450d00201310010b2003200c3602cc012003200e3602c8012003200d3602d001200341c8016a10cd01200c450d28200e10010c280b200320043602bc03200320023602b803200320053602c003200341c8016a200d200341b8036a10bc02200341b8036a41086a22024200370300200342003703b80341bfa3c2004112200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a411041b8d6c200410041001004417f460d1f200342003703c003200342003703b803200341d8026a4110200341b8036a4110410010042202417f460d1d2002410f4d0d1d200341c8016a20032903b803200341c0036a29030010b8020c270b20040d440c450b200341b8036a41086a22024200370300200342003703b80341d18ec200410e200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d80241002102024002400240200341d8026a411041b8d6c200410041001004417f460d00200342103702bc032003200341d8026a3602b803200341c8016a200341b8036a103920032802c8012214450d22200341c8016a41086a2205280200210220032802cc012113200341c8016a41186a20034190036a41186a290300370300200341c8016a41106a20034190036a41106a290300370300200520034190036a41086a29030037030020032003290390033703c801200341c8016a210520022013460d010c020b200341c8016a41186a20034190036a41186a290300370300200341c8016a41106a20034190036a41106a290300370300200341c8016a41086a20034190036a41086a29030037030020032003290390033703c80141012114200341c8016a21050b200241016a220a2002490d4120024101742204200a200a2004491b2213ad420586220f422088a70d41200fa7220a4100480d4102402002450d00200a10002204450d2020042014200a2002410574220b200b200a4b1b10ce02210a20141001200a21140c010b200a10002214450d1f0b201420024105746a220a2005290000370000200a41186a200541186a290000370000200a41106a200541106a290000370000200a41086a200541086a290000370000024002400240200241016a2205413f4b0d0041011000220b450d23200b20054102743a00004101210a4101210420050d010c020b02402005418080014f0d004102210a41021000220b450d24200b20054102744101723b00000c010b024020054180808080044f0d004104210a41041000220b450d25200b20054102744102723600000c010b410110002204450d25200441033a00004105210a41051000220b450d26200b20042d00003a000020041001200b20053600010b200241057441206a210d200a21042014210c0340200c21020240024002400240200a200422056b41204f0d00200541206a22042005490d46200a410174220c20042004200c491b220c4100480d46200a450d01200c1000220e450d12200e200b200c200a200a200c4b1b10ce02210a200b1001200a210b0c020b200541206a21040c020b200c1000220b450d100b200c210a0b200241206a210c200b20056a22052002290000370000200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a290000370000200d41606a220d0d000b0b200341b8036a41086a22024200370300200342003703b80341d18ec200410e200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a4110200b200410030240200a450d00200b10010b2013450d4620141001411421024114100022050d470c480b4194e9c000104d000b200341c0036a2005360200200fa7450d00200410010b41b2eac10041331040000b41b2eac10041331040000b200741081019000b41b2eac10041331040000b41b2eac10041331040000b411641011019000b200a41081019000b41b2eac10041331040000b41b2eac10041331040000b411441011019000b200c41011019000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b411441011019000b411441011019000b41c3d7c10041221040000b41c3d7c10041221040000b411441011019000b41b2eac10041331040000b41b2eac10041331040000b412841081019000b41b2eac10041331040000b411441011019000b41b2eac10041331040000b41c3d7c10041221040000b41c3d7c10041221040000b200a41011019000b41b2eac10041331040000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000b41002105410121040c250b200510010b024002400240024002400240024002400240024002402017201854201620105420162010511b450d0041b6a7c2002105412e210a200b0d010c020b200341b8036a41086a22024200370300200342003703b80341898fc2004113200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802024002400240024002400240200341d8026a411041b8d6c200410041001004417f460d00200342103702bc032003200341d8026a3602b803200341c8016a200341b8036a103c20032802c8012213450d0d200341c8016a41086a2802002219450d0c20032802cc01211a41cba8c20021054123210a2013290300201254201341086a290300221620115420162011511b450d05200341c8016a10bd0120032802c801221b20032802d00141286c220c6a2115201b2105410021020340201520056b419f014d0d0220034190036a2005460d032002200520034190036a412010d102220d4100476a2102200d450d0320034190036a200541286a2205460d032002200520034190036a412010d102220d4100476a2102200d450d0320034190036a200541286a2205460d032002200520034190036a412010d102220d4100476a2102200d450d0320034190036a200541286a220d460d03200d41286a2105200c41e07e6a210c2002200d20034190036a412010d102220d4100476a2102200d0d000c030b0b41e4a7c20021054131210a200b0d050c060b0340200c450d0220034190036a2005460d01200241016a2102200c41586a210c200520034190036a412010d102210d200541286a2105200d0d000b200d4541016a41017120026a417f6a21020b200220064f0d010b024020032802cc01450d00201b10010b411610002202450d06200320023602c801200342163702cc01200341c8016a419c8fc20041161029200341b8036a41086a220220032802d001360200200320032903c8013703b80320034190036a200341b8036a101b20032802bc032105200341c8016a20032802b803220c200228020010c70102402005450d00200c10010b41eea8c200210520032802c8014101470d01200f422088a722022009200920024b1b221c450d04200341c8016a41086a280200211d20032802cc01211e200821054100210d4200211f420021200340411410002202450d0c200320023602c801200342143702cc01200341c8016a41aba3c20041141029200341b8036a41086a2202200341c8016a41086a2215280200360200200320032903c8013703b8032005200341b8036a101b2002280200210a20032802bc03210620032802b803210920024200370300200342003703b8032009200a200341b8036a1002200341d8026a41086a221b2002290300370300200320032903b8033703d8024100210a0240200341d8026a411041b8d6c200410041001004417f460d00200341003602c801200341d8026a4110200341c8016a41044100100441016a41044d0d0f20032802c801210c4101210a0b02402006450d00200910010b0240200a450d00200c201e490d0041131000220a450d0c2003200a3602c801200342133702cc01200341c8016a41d1a3c2004113102920022015280200360200200320032903c8013703b8032005200341b8036a101b2002280200210c20032802bc03210920032802b803210a20024200370300200342003703b803200a200c200341b8036a1002201b2002290300370300200320032903b8033703d802024002400240200341d8026a411041b8d6c200410041001004417f470d004100210c410121024100210620090d010c020b200342103702bc032003200341d8026a3602b803200341c8016a200341b8036a103a20032802c8012202450d0b2015280200210620032802cc01210c2009450d010b200a10010b420021164200211702402006201d4d0d00200741086a29030042002002201d6a2d0000220a1b211720072903004200200a1b21160b0240200c450d00200210010b201720207c2016201f7c221f201654ad7c21200b200741106a2107200541206a2105200d41016a220d201c490d000c060b0b024020032802cc01450d00201b10010b4195a8c20021054136210a0b0240201a450d00201310010b200b450d010b200810010b200fa7450d0d0c0c0b4200211f420021200b20034190036a20136b220241706a2109200241406a210c200241907f6a210d200241e07e6a21062013201941306c22156a2107410021022013210a02400240024003402007200a6b41bf014d0d0120092002460d02201320026a220541106a20034190036a412010d102450d02200c2002460d02200541c0006a20034190036a412010d102450d02200d2002460d02200541f0006a20034190036a412010d102450d0220062002460d02200541c0016a210a200241c0016a2102200541a0016a20034190036a412010d1020d000c020b0b201320026a2105201520026b210203402002450d02200541106a220a20034190036a460d01200241506a2102200541306a2105200a20034190036a412010d1020d000b0b200341c0006a200341b8026a2018201010b2024116210a41ada9c2002105201a450d0a0c090b024002400240024002400240024002400240024002400240201f2012852020201185844200520d0020034190036a41086a290300211020034190036a41106a290300211620034190036a41186a290300211720032903900321182013201137030820132012370300200341c8016a41186a2017370300200341c8016a41106a2016370300200341c8016a41086a201037030020132018370310201341186a2010370300201341206a2016370300201341286a2017370300200320183703c801201941144b0d01201941014d0d022019417f6a210d03402019200d2202417f6a220d490d0a02402019200d6b220c4102490d002013200241306c6a22052903002013200d41306c6a220729030022175a200541086a22022903002216200741086a220a29030022105a20162010511b0d00200341b8036a41186a221c200741286a2209290300370300200341b8036a41106a221d200741206a2206290300370300200341b8036a41086a221e200741186a2215290300370300200320072903103703b80320072005290300370300200a2002290300370300200741106a200541106a2903003703002015200541186a2903003703002006200541206a2903003703002009200541286a2903003703004101211b0240200c4103490d004103210a410221064101211b034020062209200c4f0d0f2007200941306c6a220229030020175a200241086a2206290300221620105a20162010511b0d012009417f6a2205200c4f0d0e02402007200541306c6a22052002290300370300200541286a200241286a290300370300200541206a200241206a290300370300200541186a200241186a290300370300200541106a200241106a290300370300200541086a2006290300370300200a200c4f0d00200a2106200a41016a2205200a4921152005210a2009211b200221052015450d010c020b0b2009211b200221050b20052017370300200520103703082007201b41306c6a220241286a201c290300370300200241206a201d290300370300200241186a201e290300370300200220032903b8033703100b200d0d000c030b0b200341d8006a200341b8026a2018201010b202410f210a41c3a9c2002105201a0d130c140b20194101762221ad42307e2210422088a70d102010a72202417f4c0d10024002402002450d00200210002222450d08202221060c010b41082122410821060b201341506a2123201341f07e6a21244104211d410021254100212620192127034020272115410021274101210a024002400240024002400240024002400240024002402015417f6a2207450d0002400240024002402013200741306c6a22022903002013201541306c220d6a220541a07f6a290300221654200241086a2903002217200541a87f6a29030022105420172010511b450d002024200d6a2102034020074101460d022016200229030022185421052010200241086a290300221751210a20102017542109200241506a21022007417f6a2107201821162017211020052009200a1b0d000c030b0b2015417e6a210c2024200d6a210241002127410021050340200c2005460d0c2016200229030022185a210a2010200241086a2903002217512107201020175a2109200241506a2102200541016a21052018211620172110200a200920071b0d000b200541016a210a201520056b417f6a22070d020c0a0b410021070b20152007490d04201520194b0d070240201520076b220a4101762209450d002023200d6a21022013200741306c6a21050340200341c8016a41286a220c200541286a220d290300370300200341c8016a41206a221b200541206a221c290300370300200341c8016a41186a221e200541186a2228290300370300200341c8016a41106a2229200541106a2227290300370300200341c8016a41086a222a200541086a222b290300370300200320052903003703c801200241086a222c2903002110200241106a222d2903002116200241186a222e2903002117200241206a222f290300211820022903002111200d200241286a2230290300370300201c20183703002028201737030020272016370300202b2010370300200520113703002030200c290300370300202f201b290300370300202e201e290300370300202d2029290300370300202c202a290300370300200220032903c801370300200541306a2105200241506a21022009417f6a22090d000b0b2007450d080b0240200a41094d0d002007212720262025470d0b0c0a0b201520194b0d04034020152007417f6a2227490d060240201520276b220a4102490d002013200741306c6a22052903002013202741306c6a220929030022175a200541086a22022903002216200941086a220729030022105a20162010511b0d00200341b8036a41186a221e200941286a220c290300370300200341b8036a41106a2228200941206a220d290300370300200341b8036a41086a2229200941186a221b290300370300200320092903103703b8032009200529030037030020072002290300370300200941106a200541106a290300370300201b200541186a290300370300200d200541206a290300370300200c200541286a2903003703004101211c0240200a4103490d00410321074102210d4101211c0340200d220c200a4f0d052009200c41306c6a220229030020175a200241086a220d290300221620105a20162010511b0d01200c417f6a2205200a4f0d0602402009200541306c6a22052002290300370300200541286a200241286a290300370300200541206a200241206a290300370300200541186a200241186a290300370300200541106a200241106a290300370300200541086a200d2903003703002007200a4f0d002007210d200741016a2205200749211b20052107200c211c20022105201b450d010c020b0b200c211c200221050b20052017370300200520103703082009201c41306c6a220241286a201e290300370300200241206a2028290300370300200241186a2029290300370300200220032903b8033703100b2027450d0120272107200a410a490d000b0b20262025470d090c080b419093c100200c200a104a000b41a093c1002005200a104a000b20072015106b000b20152007417f6a22274f0d010b20272015106b000b20152019106a000b2007212720262025460d010c020b2015210a20262025470d010b202541016a22022025490d2a20254101742205200220022005491b2205ad4203862210422088a70d2a2010a722024100480d2a024002402025450d00200210002207450d092007201d200220254103742209200920024b1b10ce022102201d10012002211d0c010b20021000221d450d080b200521250b201d20264103746a2202200a360204200220273602000240202641016a22264102490d00024003400240024002400240201d2026221b417f6a22264103746a2202280200450d00201d201b4103746a220941746a2802002207200228020422054d0d00201b41024d0d05201d201b417d6a22024103746a280204220a200520076a4d0d01201b41034d0d05200941646a280200200a20076a4d0d010c050b201b4103490d0120022802042105201d201b417d6a22024103746a280204210a0b200a2005490d010b201b417e6a21020b201b200241016a222a4d0d05201b20024d0d06201d20024103746a221e280204222b201e2802006a2202201d202a4103746a22282802002229490d07200220194b0d08201e41046a212c2013202941306c6a22152028280204221c41306c22056a2107200241306c210a02400240024002400240200220296b220c201c6b2202201c4f0d0020222007200241306c220510ce021a200620056a2109201c4101480d0120024101480d012023200a6a210a200721020340200a200241506a2207200941506a220c200c290300200729030054200941586a2903002210200241586a29030022165420102016511b220d1b2205290300370300200a41286a200541286a290300370300200a41206a200541206a290300370300200a41186a200541186a290300370300200a41106a200541106a290300370300200a41086a200541086a2903003703002009200c200d1b2109201520072002200d1b22024f0d04200a41506a210a2006210520062009490d000c050b0b20222015200510ce021a200620056a2109201c4101480d01200c201c4c0d012013200a6a210d200621052015210203402002200720052007290300200529030054200741086a2903002210200541086a29030022165420102016511b220c1b220a290300370300200241286a200a41286a290300370300200241206a200a41206a290300370300200241186a200a41186a290300370300200241106a200a41106a290300370300200241086a200a41086a2903003703002005200541306a200c1b2105200241306a2102200741306a2007200c1b2207200d4f0d04200920054b0d000c040b0b200721020c010b201521020b200621050b20022005200920056b220a200a4130706b10ce021a202c202b201c6a360200201e20293602002028202841086a201b202a417f736a41037410cf021a202641014b0d000c020b0b201b21260b20270d000b02402025450d00201d10010b2021450d00202210010b2003201a3602cc01200320133602c801200320193602d001200341c8016a10c9010240201a450d00201310010b0240200b450d00200810010b0240200fa7450d00200410010b410021050240200e450d00201410010b0c2c0b418093c100202a201b104a000b418093c1002002201b104a000b20292002106b000b20022019106a000b200241041019000b200241081019000b200d2019106b000b41a093c1002005200c104a000b419093c1002009200c104a000b411641011019000b41b2eac10041331040000b41fcd4c00041004100104a000b41b2eac10041331040000b411341011019000b411441011019000b102e000b41b2eac10041331040000b201310010b0240200b450d00200810010b200fa7450d010b200410010b200e450d17201410010c170b200341b8036a41086a22054200370300200342003703b80341eb8fc2004115200341b8036a1002200341d8026a41086a2005290300370300200320032903b8033703d802200341d8026a411041b8d6c200410041001004417f460d04200342003703d001200342003703c801200341d8026a4110200341c8016a4110410010042205417f460d022005410f4d0d02200341386a20034190036a20032903c801200341c8016a41086a29030010b0022003280238450d0141daa6c2002105411e210a200e450d160b200410010c150b200341b8036a41086a22054200370300200342003703b80341da8fc2004111200341b8036a1002200341d8026a41086a2005290300370300200320032903b8033703d802410021050240200341d8026a411041b8d6c200410041001004417f460d00200341003602c801200341d8026a4110200341c8016a41044100100441016a41044d0d0220032802c80121050b41161000220a450d032003200a3602c801200342163702cc01200341c8016a419c8fc20041161029200341b8036a41086a220a20032802d001360200200320032903c8013703b80320034190036a200341b8036a101b200a280200210b20032802bc03210c20032802b803210941041000220a450d04200a2005360000410810002205450d052005200a280000360000200a100120052007360004200341b8036a41086a220a4200370300200342003703b8032009200b200341b8036a1002200341d8026a41086a200a290300370300200320032903b8033703d802200341d8026a4110200541081003200510010240200c450d00200910010b0240024002400240024020022007470d00200341c8016a41186a220520034190036a41186a290300370300200341c8016a41106a220a20034190036a41106a290300370300200341c8016a41086a220920034190036a41086a29030037030020032003290390033703c801200e2007470d01200741016a22022007490d142007410174220b20022002200b491b220ead420586220f422088a70d14200fa722024100480d142007450d02200210002208450d0c2008200420022007410574220b200b20024b1b10ce021a200410010c030b200341c8016a41186a220a20034190036a41186a290300370300200341c8016a41106a220920034190036a41106a290300370300200341c8016a41086a220b20034190036a41086a29030037030020032003290390033703c801200220074d0d0a200420074105746a220520032903c801370000200541186a200a290300370000200541106a2009290300370000200541086a200b2903003700002004220821092002413f4b0d030c100b200421080c010b200210002208450d090b200820074105746a220220032903c801370000200241186a2005290300370000200241106a200a290300370000200241086a200929030037000020082109200741016a2202413f4d0d0d0b02402002418080014f0d004102210a410210002207450d09200720024102744101723b00000c0e0b024020024180808080044f0d004104210a410410002207450d0a200720024102744102723600000c0e0b410110002205450d0a200541033a00004105210a410510002207450d0b200720052d00003a000020051001200720023600010c0d0b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b411641011019000b410441011019000b410841011019000b41a4d5c00020072002104a000b200241011019000b410241011019000b410441011019000b410141011019000b410541011019000b4101210a410110002207450d04200720024102743a0000410121042002450d010b2002410574210b200a21040340200921020240024002400240200a200422056b41204f0d00200541206a22042005490d06200a4101742209200420042009491b22094100480d06200a450d0120091000220c450d07200c20072009200a200a20094b1b10ce02210a20071001200a21070c020b200541206a21040c020b200910002207450d050b2009210a0b200241206a2109200720056a22052002290000370000200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a290000370000200b41606a220b0d000b0b200341b8036a41086a22024200370300200342003703b80341b28fc2004112200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a41102007200410030240200a450d00200710010b0240200e450d00200810010b410121042003200d41016a3602c801200341b8036a41086a22024200370300200342003703b80341c48fc2004116200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a4110200341c8016a41041003410021050c0b0b1018000b200941011019000b410141011019000b200510010b02400240024002400240024002400240024002400240024002402002450d00200341b8036a41086a22024200370300200342003703b80341da8fc2004111200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802410021020240200341d8026a411041b8d6c200410041001004417f460d00200341003602c801200341d8026a4110200341c8016a41044100100441016a41044d0d0620032802c80121020b20022006470d01200341b8036a41086a22024200370300200342003703b8034182a5c200411b200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a411041b8d6c200410041001004417f460d07200341003602c801200341d8026a4110200341c8016a41044100100441016a41044d0d062007200620032802c8016b4f0d02200341b8036a41086a22024200370300200342003703b80341d18ec200410e200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a411041b8d6c200410041001004417f460d03200342103702bc032003200341d8026a3602b803200341c8016a200341b8036a103920032802c8012204450d0820032802cc01210941ada5c20021054112210a0240200341d0016a280200220c20144d0d000240200420144105746a2202200341b8026a460d002002200341b8026a412010d1020d010b419da5c20021054110210a200c20134d0d00200420134105746a220220034190036a460d05200220034190036a412010d102450d050b2009450d0d200410010c0d0b41d6a4c2002105412c210a0c0c0b41a2a4c20021054116210a0c0b0b41b8a4c2002105411e210a0c0a0b41ada5c20021054112210a0c090b411310002202450d04200320023602c801200342133702cc01200341c8016a41d1a3c20041131029200341b8036a41086a220220032802d001360200200320032903c8013703b80320034190036a200341b8036a101b2002280200210a20032802bc03210b20032802b803210520024200370300200342003703b8032005200a200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802410021020240200341d8026a411041b8d6c200410041001004417f460d00200342103702bc032003200341d8026a3602b803200341c8016a200341b8036a103a20032802c801220a450d06200341d0016a280200210220032802cc01211d200b450d080c070b4101210a4100211d200b0d060c070b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b41b2eac10041331040000b411341011019000b41b2eac10041331040000b200510010b200341b8036a41086a22054200370300200342003703b80341b28fc2004112200341b8036a1002200341d8026a41086a2005290300370300200320032903b8033703d80202400240024002400240024002400240024002400240024002400240200341d8026a411041b8d6c200410041001004417f460d00200342103702bc032003200341d8026a3602b803200341c8016a200341b8036a103920032802c801221c450d0720032802cc01211e200341d0016a28020022052002200220054b1b220b0d010c020b4101211c4100211e41002002200241004b1b220b450d010b41002105200341e0016a210e200341d8016a2108200341c8016a41086a210d201c210203400240200a20056a2d0000450d00200e420037030020084200370300200d4200370300200342003703c801200341c8016a2002460d002002200341c8016a412010d102450d00411610002206450d04200320063602c801200342163702cc01200341c8016a419c8fc20041161029200341b8036a41086a2206200d280200360200200320032903c8013703b8032002200341b8036a101b20032802bc032115200341c8016a20032802b803221b200628020010c70102402015450d00201b10010b4101210620032802c8014101470d0020032802cc0120074d0d030b200241206a2102200541016a2205200b490d000b0b410021060b0240201e450d00201c10010b0240201d450d00200a10010b200320093602cc01200320043602c8012003200c3602d001200341b8026a20034190036a20061b2014201320061b200341c8016a10bc02200341b8036a41086a22024200370300200342003703b80341bfa3c2004112200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a411041b8d6c200410041001004210202402006450d002002417f460d05200342003703d001200342003703c801200341d8026a4110200341c8016a4110410010042202417f460d022002410f4d0d02200341106a200341b8026a20032903c801200341c8016a41086a29030010b602200341d5016a200341b8026a41086a290300370000200341dd016a200341c8026a290300370000200341e5016a200341d0026a29030037000041012104200341013a00cc01200341053a00c801200320032903b8023700cd01200341c8016a10a101410021050c110b2002417f460d05200342003703d001200342003703c801200341d8026a4110200341c8016a4110410010042202417f460d022002410f4d0d02200341c8016a41086a290300211620032903c8012118200341286a200341b8026a109502024002402003290328200341286a41086a29030084500d00411810002202450d09200320023602c801200342183702cc01200341c8016a41d2abc20041181029200341b8036a41086a220220032802d001360200200320032903c8013703b80320034190036a200341b8036a101b2002280200210a20032802bc03210420032802b80321054200210f20024200370300200342003703b8032005200a200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a411041b8d6c200410041001004417f460d01200342003703d001200342003703c801200341d8026a4110200341c8016a4110410010042202417f460d082002410f4d0d08200341d0016a290300211020032903c801210f2004450d0b0c0a0b4199bfc20021054122210a0c0b0b4200211020040d080c090b411641011019000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b41c3d7c10041221040000b41b2eac10041331040000b411841011019000b200510010b0240411410002202450d00200320023602c801200342143702cc01200341c8016a41d7aac20041141029200341b8036a41086a220220032802d001360200200320032903c8013703b803200341b8026a200341b8036a101b2002280200210a20032802bc03210420032802b80321054200211720024200370300200342003703b8032005200a200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802024002400240200341d8026a411041b8d6c200410041001004417f460d00200342003703d001200342003703c801200341d8026a4110200341c8016a4110410010042202417f460d022002410f4d0d02200341d0016a290300211220032903c80121170c010b420021120b20162010200f201856201020165620102016511b22021b21112018200f20021b211602402004450d00200510010b200341b8026a201720167c2218201220117c2018201754ad7c10b40220034190036a200f20167d201020117d200f201654ad7d10b502200341d5016a20034190036a41086a290300370000200341dd016a20034190036a41106a290300370000200341e5016a20034190036a41186a290300370000200341ed016a20032903b802370000200341f5016a200341b8026a41086a290300370000200341fd016a200341b8026a41106a29030037000020034185026a200341b8026a41186a29030037000041002105200341003a00cc01200341053a00c80120032003290390033700cd01200341c8016a10a101410121040c080b41b2eac10041331040000b411441011019000b410121040c050b41142102411410002205450d010b200320053602c801200342143702cc01200341c8016a41aba3c20020021029200341b8036a41086a220220032802d001360200200320032903c8013703b80320034190036a200341b8036a101b2002280200210a20032802bc03210420032802b8032105200320083602c80120024200370300200342003703b8032005200a200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a4110200341c8016a4104100302402004450d00200510010b411310002202450d01200320023602c801200342133702cc01200341c8016a41d1a3c20041131029200341b8036a41086a220220032802d001360200200320032903c8013703b80320034190036a200341b8036a101b2002280200210420032802bc03210b20032802b8032105200341003602d001200342013703c80120092006200341c8016a10e40120032802cc01210c20032802d001210d20032802c801210a20024200370300200342003703b80320052004200341b8036a1002200341d8026a41086a2002290300370300200320032903b8033703d802200341d8026a4110200a200d10030240200c450d00200a10010b0240200b450d00200510010b02402007450d00200910010b41002104410021050c030b200241011019000b411341011019000b200910010b024020012802002207417e6a220241064b0d00024020020e0700020101020102000b2004450d01200141086a280200450d01200128020410010c010b20074102470d00200141086a280200450d00200128020410010b2000200a36020420002005360200200341e0036a24000bcb7005087f027e037f027e117f230041f0036b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00002204417e6a220541044b0d00024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e050005020301000b200141046a2802002106200241096a2800002105200241056a280000210720022d0001210820022d00002101200341a8036a41026a2204200241046a2d00003a0000200341c8006a41086a2209200241156a290000370300200341c8006a410d6a220a2002411a6a2900003700002003200241026a2f01003b01a80320032002410d6a29000037034820010d07200341086a41026a20042d00003a0000200341d0036a41086a2009290300370300200341d0036a410d6a200a290000370000200320032f01a8033b0108200320032903483703d003200841ff01714101470d07200341db006a200341d0036a41086a290300220b370000200341e0006a200341d0036a410d6a290000220c37000020034198036a41026a200341086a41026a2d000022023a0000200341a8036a41086a200b370300200341a8036a410d6a200c3700002003200736004b2003200536004f200320032f010822013b0148200320032903d003220b370053200320013b0198032003200b3703a803200320023a004a410021010c080b4100210841d2a9c20041d2a9c2004100410320022d000120022d00001b41ff017122021b20024103461b22070d022003200141086a290300370348200341286a41086a22024200370300200342003703284186ddc200411a200341286a100220034198036a41086a2002290300370300200320032903283703980320034198036a4110200341c8006a4108100320012d00004102470d290c280b200341206a200141196a290000370300200341186a200141116a290000370300200341086a41086a200141096a29000037030020032001290001370308200241096a2800002105200241056a280000210820022d0001210420022d00002107200341a8036a41026a2209200241046a2d00003a0000200341c8006a41086a220a200241156a290000370300200341c8006a410d6a220d2002411a6a2900003700002003200241026a2f01003b01a80320032002410d6a29000037034820070d0320034198036a41026a20092d00003a0000200341d0036a41086a200a290300370300200341d0036a410d6a200d290000370000200320032f01a8033b019803200320032903483703d003200441ff01714101470d03200341db006a200341d0036a41086a290300220b370000200341e0006a200341d0036a410d6a290000220c370000200341e8026a41026a20034198036a41026a2d000022023a0000200341a8036a41086a200b370300200341a8036a410d6a200c3700002003200836004b2003200536004f200320032f01980322073b0148200320032903d003220b370053200320073b01e8022003200b3703a803200320023a004a410021020c040b4100210841d2a9c20041d2a9c2004100410320022d000120022d00001b41ff017122021b20024103461b2207450d080b4128210520044102470d27200141046a2802002202102c200210010c270b200141216a2d0000210e20034190036a200141196a29000037030020034188036a200141116a290000370300200341f8026a41086a200141096a290000370300200320012900013703f802200241096a2800002105200241056a280000210820022d0001210420022d00002107200341a8036a41026a2209200241046a2d00003a0000200341c8006a41086a220a200241156a290000370300200341c8006a410d6a220d2002411a6a2900003700002003200241026a2f01003b01a80320032002410d6a29000037034820070d0420034198036a41026a20092d00003a0000200341086a41086a200a290300370300200341086a410d6a200d290000370000200320032f01a8033b01980320032003290348370308200441ff01714101470d04200341db006a200341086a41086a290300220b370000200341e0006a200341086a410d6a290000220c370000200341e8026a41026a20034198036a41026a2d000022023a0000200341a8036a41086a200b370300200341a8036a410d6a200c3700002003200836004b2003200536004f200320032f01980322073b014820032003290308220b370053200320073b01e8022003200b3703a803200320023a004a410021020c050b41012102412a210541faa9c20021080b200341c4006a41026a2207200341e8026a41026a2d00003a0000200341286a41086a2204200341a8036a41086a290300370300200341286a41106a200341a8036a41106a290300370300200320032f01e8023b0144200320032903a80337032820020d212003418b036a200429030037000020034190036a200341356a290000370000200320032f01443b01f802200320083600fb02200320053600ff022003200329032837008303200320072d00003a00fa02200341f8026a10af02450d05411c10002202450d11200320023602482003421c37024c200341c8006a41f1ddc200411c1029200341a8036a41086a22022003280250360200200320032903483703a803200341086a200341a8036a101b2002280200210520032802ac03210720032802a8032102200341286a41086a220842003703002003420037032820022005200341286a100220034198036a41086a2008290300370300200320032903283703980320034198036a41101014210502402007450d00200210010b2005450d08411c10002202450d13200320023602a8032003421c3702ac03200341a8036a41e7d6c200411c1029200341d8036a220220032802b003360200200320032903a8033703d003200341086a200341d0036a101b20032802d4032105200341c8006a20032802d0032207200228020010c80102402005450d00200710010b20032802502204450d0b2003290254220b422088220ca72209450d0c0c1a0b4101210141faa9c2002107412a21050b200341c4006a41026a220820034198036a41026a2d00003a0000200341286a41086a2202200341a8036a41086a290300370300200341286a41106a200341a8036a41106a290300370300200320032f0198033b0144200320032903a80337032820010d152003418b036a200229030037000020034190036a200341356a290000370000200320032f01443b01f802200320073600fb02200320053600ff022003200329032837008303200320082d00003a00fa0210ac01210b20024200370300200342003703284186ddc200411a200341286a100220034198036a41086a2002290300370300200320032903283703980320034198036a411041b8d6c200410041001004417f460d0e2003420037034820034198036a4110200341c8006a41084100100441016a41084d0d0d2003290348200b7c210b200341c8006a10bd0120032802482204200328025041286c22056a2108200421020340200820026b419f014d0d09200341f8026a2002460d062002200341f8026a412010d102450d06200241286a2101200341f8026a200241286a2207460d142007200341f8026a412010d102450d14200241d0006a2101200341f8026a200741286a2207460d142007200341f8026a412010d102450d14200241f8006a2101200341f8026a200741286a2207460d14200741286a2102200541e07e6a21052007200341f8026a412010d1020d000c140b0b41012102412a210541faa9c20021080b200341c4006a41026a2207200341e8026a41026a2d00003a0000200341286a41086a2204200341a8036a41086a290300370300200341286a41106a200341a8036a41106a290300370300200320032f01e8023b0144200320032903a80337032820020d1d200341e3036a2004290300370000200341d0036a41186a2202200341356a290000370000200320032f01443b01d003200320083600d303200320053600d703200320032903283700db03200320072d00003a00d203200341d0036a10af02450d02200341c8006a41186a200341f8026a41186a290300370300200341c8006a41106a200341f8026a41106a290300370300200341c8006a41086a200341f8026a41086a290300370300200341f0006a200341d0036a41086a290300370300200341f8006a200341d0036a41106a29030037030020034180016a2002290300370300200320032903f802370348200320032903d003370368411b10002202450d0e200320023602a8032003421b3702ac03200341a8036a418fdcc200411b1029200341086a41086a220220032802b003360200200320032903a803370308200341c8006a200341086a10f00120022802002105200328020c210820032802082102200341286a41086a220742003703002003420037032820022005200341286a100220034198036a41086a2007290300370300200320032903283703980320034198036a411041b8d6c200410041001004417f460d05200341003a00a80320034198036a4110200341a8036a41014100100441016a41014d0d1020032d00a80321052008450d150c140b2003200141086a290300370348200341286a41086a22024200370300200342003703284186dfc200411b200341286a100220034198036a41086a2002290300370300200320032903283703980320034198036a4110200341c8006a4108100320012d00004102470d1e0c1d0b41bbdec2002108412b210520012d00004102460d1c0c1d0b418ddec2002108412e210520012d00004102460d1b0c1c0b200221010c0d0b41e6dec20021084120210520012d00004102460d190c1a0b4102210520080d0e0c0f0b0340200221012005450d03200341f8026a2001460d0b200541586a2105200141286a21022001200341f8026a412010d1020d000c0b0b0b4200210b410121044200422088220ca722090d0e0b200341c8006a41186a200341f8026a41186a290300370300200341c8006a41106a200341f8026a41106a290300370300200341c8006a41086a200341f8026a41086a290300370300200320032903f80237034841002107200341c8006a21050c0e0b410221020c080b41c893c100104d000b41b2eac10041331040000b41c3d7c10041221040000b411c41011019000b411b41011019000b411c41011019000b41b2eac10041331040000b200141206a290300200b5621020b200241024720027121020240200328024c450d00200410010b0240024002400240024002402002450d0020034100360250200342013703482006200341c8006a10a001200328024c21082003280250210420032802482107200341c8006a41186a22024200370300200341c8006a41106a22014200370300200341c8006a41086a220542003703002003420037034820072004200341c8006a1011200341d0036a41186a22042002290300370300200341d0036a41106a22092001290300370300200341d0036a41086a220a2005290300370300200320032903483703d00302402008450d00200710010b20022004290300370300200120092903003703002005200a290300370300200320032903d003370348411810002202450d02200320023602a803200342183702ac03200341a8036a41cfd6c20041181029200341086a41086a220220032802b003360200200320032903a803370308200341c8006a200341086a101b20022802002101200328020c210520032802082102200341286a41086a220742003703002003420037032820022001200341286a100220034198036a41086a2007290300370300200320032903283703980320034198036a41101014210102402005450d00200210010b2001450d0141c0ddc2002107411f21050c060b41a0ddc2002107412021050c050b0240411c10002202450d00200320023602a8032003421c3702ac03200341a8036a41e7d6c200411c1029200341106a220220032802b003360200200320032903a803370308200341d0036a200341086a101b200328020c2101200341c8006a20032802082205200228020010c80102402001450d00200510010b024020032802502202450d002003290348210c2003280254210110ac01211002402001450d00200210010b2010200c5a0d0041dfddc2002107411221050c060b200341e8026a10c001200341c8006a41186a2201200341d0036a41186a290300370300200341c8006a41106a2205200341d0036a41106a290300370300200341c8006a41086a2207200341d0036a41086a290300370300200320032903d00337034802400240024020032802f002220420032802ec02470d00200441016a22022004490d1620044101742208200220022008491b2209ad42287e220c422088a70d16200ca722024100480d16024002402004450d0020032802e802210a200210002208450d032008200a2002200441286c220d200d20024b1b10ce021a200a10010c010b200210002208450d020b200320093602ec02200320083602e8020b200341e8026a41086a200441016a221736020020032802e8022218200441286c6a2202200b37030020022003290348370308200241106a2007290300370300200241186a2005290300370300200241206a200129030037030002400240024002400240024002400240024002400240024002400240201741144b0d0020174102490d010340201720042202417f6a2204490d130240201720046b22084102490d002018200241286c6a22012903002018200441286c6a2209290300220b5a0d00200341c8006a41186a220f200941206a2202290300370300200341c8006a41106a2215200941186a2205290300370300200341c8006a41086a2212200941106a22072903003703002003200929030837034820092001290300370300200941086a200141086a2903003703002007200141106a2903003703002005200141186a2903003703002002200141206a2903003703004101210e024020084103490d00410321054102210a4101210e0340200a220720084f0d182009200741286c6a2202290300200b5a0d012007417f6a220120084f0d1702402009200141286c6a22012002290300370300200141206a200241206a290300370300200141186a200241186a290300370300200141106a200241106a290300370300200141086a200241086a290300370300200520084f0d002005210a200541016a2201200549210d200121052007210e20022101200d450d010c020b0b2007210e200221010b2001200b3703002009200e41286c6a22022003290348370308200241206a200f290300370300200241186a2015290300370300200241106a20122903003703000b20040d000c020b0b20174101762219ad42287e220b422088a70d0e200ba72202417f4c0d0e024002402002450d0020021000221a450d0e201a210a0c010b4108211a4108210a0b201841586a211b201841887f6a211c4100211d4100211e410421152017211603402016210d4100211641012105024002400240024002400240024002400240024002400240200d417f6a2207450d0002400240024002402018200741286c6a2903002018200d41286c22046a41b07f6a290300220b5a0d00201c20046a2102034020074101460d022007417f6a2107200b2002290300220c542101200241586a2102200c210b20010d000c030b0b200d417e6a2107201c20046a21014100211641002102034020072002460d05200241016a2102200b2001290300220c5a2105200141586a2101200c210b20050d000b200d20026b417f6a2107200241016a220541094d0d020c0c0b410021070b200d2007490d06200d20174b0d090240200d20076b22054101762208450d002018200741286c6a2102201b20046a21010340200341c8006a41206a2204200241206a2209290300370300200341c8006a41186a220e200241186a220f290300370300200341c8006a41106a2212200241106a2213290300370300200341c8006a41086a2214200241086a221629030037030020032002290300370348200141086a221f290300210b200141106a2220290300210c200141186a22212903002110200129030021112009200141206a2222290300370300200f20103703002013200c3703002016200b37030020022011370300202220042903003703002021200e29030037030020202012290300370300201f201429030037030020012003290348370300200241286a2102200141586a21012008417f6a22080d000b0b200541094b0d0a0b2007450d02200d20174b0d060340200d2007417f6a2216490d080240200d20166b22054102490d002018200741286c6a22012903002018201641286c6a2204290300220b5a0d00200341c8006a41186a2212200441206a2202290300370300200341c8006a41106a2213200441186a2207290300370300200341c8006a41086a2214200441106a22082903003703002003200429030837034820042001290300370300200441086a200141086a2903003703002008200141106a2903003703002007200141186a2903003703002002200141206a2903003703004101210f024020054103490d0041032107410221094101210f03402009220820054f0d072004200841286c6a2202290300200b5a0d012008417f6a220120054f0d0802402004200141286c6a22012002290300370300200141206a200241206a290300370300200141186a200241186a290300370300200141106a200241106a290300370300200141086a200241086a290300370300200720054f0d0020072109200741016a2201200749210e200121072008210f20022101200e450d010c020b0b2008210f200221010b2001200b3703002004200f41286c6a22022003290348370308200241206a2012290300370300200241186a2013290300370300200241106a20142903003703000b2016450d01201621072005410a490d000b0b201d201e470d0a0c090b200d2105201d201e460d080c090b20072116201d201e460d070c080b419093c10020082005104a000b41a093c10020012005104a000b2007200d106b000b200d2007417f6a22164f0d010b2016200d106b000b200d2017106a000b20072116201d201e470d010b201d41016a2202201d490d24201d4101742201200220022001491b221ead420386220b422088a70d24200ba722024100480d240240201d450d00200210002201450d09200120152002201d4103742207200720024b1b10ce02210220151001200221150c010b200210002215450d080b02402015201d4103746a220220053602042002201636020002400240201d41016a221d4102490d00034002400240024002402015201d220e417f6a221d4103746a2202280200450d002015200e4103746a220841746a2802002207200228020422014d0d00200e41024d0d062015200e417d6a22024103746a2802042205200120076a4d0d01200e41034d0d06200841646a280200200520076a4d0d010c060b200e4103490d01200228020421012015200e417d6a22024103746a28020421050b20052001490d010b200e417e6a21020b200e200241016a221f4d0d06200e20024d0d07201520024103746a2212280204222020122802006a22022015201f4103746a22132802002214490d08200220174b0d09201241046a21212018201441286c6a220d2013280204220f41286c22016a2107200241286c210502400240024002400240200220146b2204200f6b2202200f4f0d00201a2007200241286c220110ce021a200a20016a2108200f4101480d0120024101480d01201b20056a21052007210203402005200241586a2207200841586a2204200429030020072903005422091b2201290300370300200541206a200141206a290300370300200541186a200141186a290300370300200541106a200141106a290300370300200541086a200141086a2903003703002008200420091b2108200d2007200220091b22024f0d04200541586a2105200a2101200a2008490d000c050b0b201a200d200110ce021a200a20016a2108200f4101480d012004200f4c0d01201820056a2109200a2101200d21020340200220072001200729030020012903005422041b2205290300370300200241206a200541206a290300370300200241186a200541186a290300370300200241106a200541106a290300370300200241086a200541086a2903003703002001200141286a20041b2101200241286a2102200741286a200720041b220720094f0d04200820014b0d000c040b0b200721020c010b200d21020b200a21010b20022001200820016b220520054128706b10ce021a20212020200f6a360200201220143602002013201341086a200e201f417f736a41037410cf021a201d41014b0d000b0b20160d020c010b200e211d20160d010b0b0240201e450d00201510010b2019450d00201a10010b200341e8026a10ca01200341a8036a41186a200341d0036a41186a290300370300200341a8036a41106a200341d0036a41106a290300370300200341a8036a41086a200341d0036a41086a290300370300200320032903d0033703a803200341c8006a200641a00210ce021a411810002202450d06200320023602082003421837020c200341086a41cfd6c20041181029200341286a41086a2202200328021036020020032003290308370328200341a8036a200341286a101b20022802002107200328022c2108200328022821012003410036021020034201370308200341c8006a200341086a10a001200328020c21042003280210210920032802082105200242003703002003420037032820012007200341286a100220034198036a41086a2002290300370300200320032903283703980320034198036a411020052009100302402004450d00200510010b02402008450d00200110010b200341c8006a102c200341c8006a41186a200341d0036a41186a290300370300200341c8006a41106a200341d0036a41106a290300370300200341c8006a41086a200341d0036a41086a290300370300200320032903d003370348412010002209450d07200341f8026a41086a290300210b200341f8026a41106a290300210c20032903f8022110200941186a200341f8026a41186a290300370000200941106a200c370000200941086a200b37000020092010370000411c10002202450d08200320023602a8032003421c3702ac03200341a8036a41f1ddc200411c1029200341086a41086a220220032802b003360200200320032903a803370308200341c8006a200341086a101b2002280200210e200328020c210f2003280208210d410110002204450d09200441043a0000410021084101210541012107034002400240024002402005200722026b41204f0d00200241206a22072002490d2620054101742201200720072001491b22014100480d262005450d0120011000220a450d09200a200420012005200520014b1b10ce02210520041001200521040c020b200241206a21070c020b200110002204450d070b200121050b200420026a2202200920086a2201290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a290000370000200841206a22084120470d000b200341286a41086a2202420037030020034200370328200d200e200341286a100220034198036a41086a2002290300370300200320032903283703980320034198036a411020042007100302402005450d00200410010b0240200f450d00200d10010b20091001200341c8006a41186a200341d0036a41186a290300370300200341c8006a41106a200341d0036a41106a290300370300200341c8006a41086a200341d0036a41086a290300370300200341f0006a200341f8026a41086a290300370300200341f8006a200341f8026a41106a29030037030020034180016a200341f8026a41186a290300370300200320032903d003370348200320032903f802370368200341013a0044411b10002202450d0a200320023602a8032003421b3702ac03200341a8036a418fdcc200411b1029200341086a41086a220220032802b003360200200320032903a803370308200341c8006a200341086a10f00120022802002101200328020c210520032802082102200341286a41086a220742003703002003420037032820022001200341286a100220034198036a41086a2007290300370300200320032903283703980320034198036a4110200341c4006a4101100302402005450d00200210010b024020032802ec02450d0020032802e80210010b20061001410021070c200b418093c100201f200e104a000b418093c1002002200e104a000b20142002106b000b20022017106a000b200141011019000b200241041019000b411841011019000b412041011019000b411c41011019000b410141011019000b411b41011019000b200241081019000b200241081019000b102e000b411c41011019000b411841011019000b20042017106b000b41a093c10020012008104a000b419093c10020072008104a000b2006102c200610010c0c0b200210010b02400240024002400240024002400240024002400240200541ff01714102470d00200341a8036a41186a200341f8026a41186a290300370300200341a8036a41106a200341f8026a41106a290300370300200341a8036a41086a200341f8026a41086a290300370300200320032903f8023703a803411c10002202450d03200320023602482003421c37024c200341c8006a41f1ddc200411c1029200341086a41086a2202200328025036020020032003290348370308200341a8036a200341086a101b200328020c2105200341e8026a20032802082207200228020010be0102402005450d00200710010b200341c8006a41186a2208200341d0036a41186a290300370300200341c8006a41106a2204200341d0036a41106a290300370300200341c8006a41086a2209200341d0036a41086a290300370300200320032903d003370348024020032802f002220220032802ec02220f470d00200241016a22052002490d1720024101742207200520052007491b220fad420586220b422088a70d17200ba722054100480d17024002402002450d0020032802e802210a200510002207450d082007200a20052002410574220d200d20054b1b10ce021a200a10010c010b200510002207450d070b2003200f3602ec02200320073602e8020b200341e8026a41086a200241016a220536020020032802e802221220024105746a22072003290348370000200741086a2009290300370000200741106a2004290300370000200741186a2008290300370000411c10002207450d04200320073602482003421c37024c200341c8006a41f1ddc200411c1029200341106a2207200328025036020020032003290348370308200341a8036a200341086a101b20072802002113200328020c2114200328020821150240024002402005413f4b0d0041012107410110002204450d09200420054102743a00004101210820050d010c020b02402005418080014f0d0041022107410210002204450d0a200420054102744101723b00000c010b024020054180808080044f0d0041042107410410002204450d0b200420054102744102723600000c010b410110002208450d0b200841033a000041052107410510002204450d0c200420082d00003a000020081001200420053600010b200241057441206a210a200721082012210903402009210202400240024002402007200822056b41204f0d00200541206a22082005490d1c20074101742209200820082009491b22094100480d1c2007450d0120091000220d450d07200d200420092007200720094b1b10ce02210720041001200721040c020b200541206a21080c020b200910002204450d050b200921070b200241206a2109200420056a22052002290000370000200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a290000370000200a41606a220a0d000b0b200341286a41086a220242003703002003420037032820152013200341286a100220034198036a41086a2002290300370300200320032903283703980320034198036a411020042008100302402007450d00200410010b02402014450d00201510010b200f450d00201210010b200341c8006a41186a200341f8026a41186a290300370300200341c8006a41106a200341f8026a41106a290300370300200341c8006a41086a200341f8026a41086a290300370300200341f0006a200341d0036a41086a290300370300200341f8006a200341d0036a41106a29030037030020034180016a200341d0036a41186a290300370300200320032903f802370348200320032903d0033703682003200e3a00e802411b10002202450d01200320023602a8032003421b3702ac03200341a8036a418fdcc200411b1029200341086a41086a220220032802b003360200200320032903a803370308200341c8006a200341086a10f00120022802002105200328020c210720032802082102200341286a41086a220842003703002003420037032820022005200341286a100220034198036a41086a2008290300370300200320032903283703980320034198036a4110200341e8026a410110032007450d10200210010c100b200941011019000b411b41011019000b411c41011019000b411c41011019000b200541011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000b41002102024020094101460d002009210541002102034020022005410176220720026a2208200420084105746a200341f8026a412010d10241004a1b2102200520076b220541014b0d000b0b200420024105746a200341f8026a412010d1022207450d01200341c8006a41186a200341f8026a41186a290300370300200341c8006a41106a200341f8026a41106a290300370300200341c8006a41086a200341f8026a41086a290300370300200320032903f802370348200341c8006a210520022007411f766a220720094d0d0041d881c000104d000b02402009200ba7470d00200941016a22022009490d0a200ca7220a4101742208200220022008491bad22104205862211422088a70d0a2011a722024100480d0a2009450d0220021000220e450d14200e20042002200a410574220820022008491b10ce021a200410010c030b2004210e0c030b41a1dfc2002108412a2105200ba7450d042004100120012d00004102460d050c060b20021000220e450d110b200b42808080807083201084210b0b200e20074105746a220241206a2002200920076b41057410cf021a200241186a200541186a290000370000200241106a200541106a290000370000200241086a200541086a2900003700002002200529000037000010ac012110200341286a41086a22024200370300200342003703284186dfc200411b200341286a100220034198036a41086a2002290300370300200320032903283703980320034198036a411041b8d6c200410041001004417f460d0a2003420037034820034198036a4110200341c8006a41084100100441016a41084d0d0820032903482111411c10002202450d0b200320023602482003421c37024c200341c8006a41e7d6c200411c1029200341a8036a41086a22022003280250360200200320032903483703a803200341086a200341a8036a101b2002280200211520032802ac03211220032802a803210f410810002205450d0c2005201120107c370000024002400240200c42017ca72202413f4b0d0041102107411010002204450d132004200529000037000020051001200420024102743a00084109210820020d010c020b02402002418080014f0d00411010002204450d152004200529000037000020051001200420024102744101723b0008410a21080c010b411010002104024020024180808080044f0d002004450d16200420052900003700002005100120042002410274410272360008410c21080c010b2004450d16200420052900003700002005100120042002360009200441033a0008410d21080b2002410574210a41102107200e210903402009210202400240024002402007200822056b41204f0d00200541206a22082005490d0b20074101742209200820082009491b22094100480d0b2007450d0120091000220d450d0d200d200420092007200720094b1b10ce02210720041001200721040c020b200541206a21080c020b200910002204450d0b0b200921070b200241206a2109200420056a22052002290000370000200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a290000370000200a41606a220a0d000b0b200341286a41086a2202420037030020034200370328200f2015200341286a100220034198036a41086a2002290300370300200320032903283703980320034198036a411020042008100302402007450d00200410010b200ba7210202402012450d00200f10010b02402002450d00200e10010b200341c8006a10c001200328024c21162003280248211402400240024020032802502202450d00200241286c41b07f6a2107200341c8006a41086a2105201421020340200341c8006a41206a200241206a290300370300200341c8006a41186a200241186a290300370300200341c8006a41106a200241106a2903003703002005200241086a29030037030020032002290300370348200341d0036a41186a200541186a290000370300200341d0036a41106a200541106a290000370300200341d0036a41086a200541086a290000370300200320052900003703d003200341d0036a200341086a412010d1020d02200241286a2102200741586a220741b07f470d000b0b200341003602502003420837034802402016450d00201410010b200341c8006a10ca010c010b200341a8036a41206a2205200341c8006a41206a290300370300200341a8036a41186a2208200341c8006a41186a290300370300200341a8036a41106a2204200341c8006a41106a290300370300200341a8036a41086a2209200341c8006a41086a290300370300200320032903483703a80341281000220f450d12200f20032903a803370300200f41206a2005290300370300200f41186a2008290300370300200f41106a2004290300370300200f41086a20092903003703000240024020074158460d00200241286a2102200341c8006a41086a21054101210e4101210d0340200341c8006a41206a2204200241206a290300370300200341c8006a41186a2209200241186a290300370300200341c8006a41106a220a200241106a2903003703002005200241086a29030037030020032002290300370348200341d0036a41186a200541186a290000370300200341d0036a41106a200541106a290000370300200341d0036a41086a200541086a290000370300200320052900003703d00302400240024002400240200341d0036a200341086a412010d102450d00200341a8036a41206a22082004290300370300200341a8036a41186a22152009290300370300200341a8036a41106a2212200a290300370300200341a8036a41086a22132005290300370300200320032903483703a8032004200829030037030020092015290300370300200a201229030037030020052013290300370300200320032903a803370348200d200e470d03200e41016a2208200e490d0e200e4101742215200820082015491b2215ad42287e220b422088a70d0e200ba722084100480d0e200e450d01200810002212450d122012200f2008200e41286c220e200e20084b1b10ce022108200f10012008210f0c020b20070d030c060b20081000220f450d100b2015210e0b200f200d41286c6a22082003290348370300200841206a2004290300370300200841186a2009290300370300200841106a200a290300370300200841086a2005290300370300200d41016a210d2007450d030b200241286a2102200741586a21070c000b0b4101210e4101210d0b02402016450d00201410010b2003200e36024c2003200f3602482003200d360250200341c8006a10ca01200e450d00200f10010b200341c8006a41186a200341086a41186a290300370300200341c8006a41106a200341086a41106a290300370300200341c8006a41086a200341086a41086a29030037030020032003290308370348411c10002202450d0d200320023602a8032003421c3702ac03200341a8036a41f1ddc200411c1029200341d0036a41086a220220032802b003360200200320032903a8033703d003200341c8006a200341d0036a101b2002280200210520032802d403210720032802d0032102200341286a41086a220842003703002003420037032820022005200341286a100220034198036a41086a2008290300370300200320032903283703980320034198036a4110100a02402007450d00200210010b200341c8006a41186a200341086a41186a290300370300200341c8006a41106a200341086a41106a290300370300200341c8006a41086a200341086a41086a29030037030020032003290308370348411810002202450d0e200320023602a803200342183702ac03200341a8036a41cfd6c20041181029200341d0036a41086a220220032802b003360200200320032903a8033703d003200341c8006a200341d0036a101b2002280200210520032802d403210720032802d0032102200341286a41086a220842003703002003420037032820022005200341286a100220034198036a41086a2008290300370300200320032903283703980320034198036a4110100a02402007450d00200210010b200341c8006a10bd01200328024c210e2003280248210d024020032802502202450d00200241286c2108200341e8006a2105200d2102034020052002290000370000200341c8006a41186a200341086a41186a290300370300200341c8006a41106a200341086a41106a290300370300200341c8006a41086a200341086a41086a290300370300200541086a200241086a290000370000200541106a200241106a290000370000200541186a200241186a29000037000020032003290308370348411b10002207450d08200320073602a8032003421b3702ac03200341a8036a418fdcc200411b1029200341d0036a41086a2207200341a8036a41086a280200360200200320032903a8033703d003200341c8006a200341d0036a10f0012007280200210420032802d403210920032802d0032107200341286a41086a220a42003703002003420037032820072004200341286a100220034198036a41086a200a290300370300200320032903283703980320034198036a4110100a02402009450d00200710010b200241286a2102200841586a22080d000b0b200e450d00200d10014100210820012d00004102470d030c020b410021080b20012d00004102470d010b200141046a2802002202102c200210010b200821070b2000200536020420002007360200200341f0036a24000f0b1018000b411b41011019000b200941011019000b41b2eac10041331040000b200841081019000b41c3d7c10041221040000b411c41011019000b410841011019000b411c41011019000b411841011019000b200241011019000b411041011019000b412841081019000b411041011019000b411041011019000b411041011019000b9a0902027f087e230041f0006b22032400200341d0006a41086a220442003703002003420037035041d4cbc1004116200341d0006a1002200341c0006a41086a20042903003703002003200329035037034002400240024002400240200341c0006a411041b8d6c200410041001004417f460d002003420037036002400240200341c0006a4110200341e0006a41084100100441016a41084d0d002003290360210542002106200341d0006a41086a220442003703002003420037035041e4c7c1004111200341d0006a1002200341c0006a41086a2004290300370300200320032903503703400240200341c0006a411041b8d6c200410041001004417f460d0020034200370360200341c0006a4110200341e0006a41084100100441016a41084d0d02200329036021060b02400240200520067d20025a0d00200041f2c9c200360204200041086a411a360200410121040c010b200341d0006a41086a220442003703002003420037035041a2ccc1004111200341d0006a1002200341c0006a41086a200429030037030020032003290350370340200341c0006a411041b8d6c200410041001004417f460d052003420037036820034200370360200341c0006a4110200341e0006a4110410010042204417f460d042004410f4d0d04200341206a2002420020032903602206200341e0006a41086a290300220510d502200341106a20032903202207200341206a41086a29030022084201200620062005845022041b4200200520041b10d202200341306a200110e601024041002003290310200285200341106a41086a2903008442005220041b450d002000418ccac200360204200041086a4127360200410121040c010b200341306a41086a29030021092003290330210a200310a5020240200a2003290300220b20077c220c542009200341086a29030020087c200c200b54ad7c220b542009200b511b450d00200041b3cac200360204200041086a4124360200410121040c010b2001200a20077d200920087d200a200754ad7d10b402200341d0006a41086a220442003703002003420037035041bcabc2004116200341d0006a1002200341c0006a41086a200429030037030020032003290350370340200341c0006a411041b8d6c200410041001004417f460d072003420037036820034200370360200341c0006a4110200341e0006a4110410010042204417f460d062004410f4d0d0602402003290360220920077d220b200956200341e0006a41086a290300220a20087d2009200754ad7d2207200a562007200a511b0d002003200b37036020032007370368200341d0006a41086a220442003703002003420037035041bcabc2004116200341d0006a1002200341c0006a41086a200429030037030020032003290350370340200341c0006a4110200341e0006a411010030b200041206a2005370300200041186a2006370300200041106a2002370300200041086a2002370300410021040b20002004360200200341f0006a24000f0b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b41b2eac10041331040000b41c3d7c10041221040000b41b2eac10041331040000b41c3d7c10041221040000bfe0101077f230041106b22012400200110bd0120012802002202200128020841286c22036a210420022105024002400340200420056b419f014d0d014101210620002005460d0220052000412010d102450d02200541286a22052000460d0220052000412010d102450d02200541286a22052000460d0220052000412010d102450d02200541286a22072000460d02200741286a2105200341e07e6a210320072000412010d1020d000c020b0b024003402003450d014101210620002005460d0220052000412010d1022107200341586a2103200541286a210520070d000c020b0b410021060b02402001280204450d00200210010b200141106a240020060bbe0506057f017e017f027e017f027e230041206b22042400024002400240411410002205450d002004200536021020044214370214200441106a41d7aac20041141029200441086a220520042802183602002004200429031037030020012004101b20052802002106200428020421072004280200210842002109200441106a41086a220a42003703002004420037031020082006200441106a10022005200a29030037030020042004290310370300024002402004411041b8d6c200410041001004417f460d00200442003703182004420037031020044110200441106a4110410010042205417f460d012005410f4d0d01200441186a290300210b200429031021092007450d040c030b4200210b20070d020c030b41b2eac10041331040000b411441011019000b200810010b0240024020092002542206200b200354200b2003511b450d0041a9c0c2002105411521080c010b411e21082001109d0222050d00024002400240411810002205450d002004200536021020044218370214200441106a41d2abc20041181029200441086a220520042802183602002004200429031037030020012004101b200528020021072004280204210a200428020021084200210c200441106a41086a220d42003703002004420037031020082007200441106a10022005200d29030037030020042004290310370300024002402004411041b8d6c200410041001004417f460d00200442003703182004420037031020044110200441106a4110410010042205417f460d012005410f4d0d01200441186a290300210e2004290310210c200a450d040c030b4200210e200a0d020c030b41b2eac10041331040000b411841011019000b200810010b2001200c20027c220f200e20037c200f200c54ad7c10b5022001200920027d200b20037d2006ad7d10b402410021050b2000200836020420002005360200200441206a24000be60402037f017e230041d0006b22052400200541306a41086a220642003703002005420037033041e4c7c1004111200541306a1002200541206a41086a2207200629030037030020052005290330370320420021080240024002400240200541206a411041b8d6c200410041001004417f460d0020054200370340200541206a4110200541c0006a41084100100441016a41084d0d01200529034021080b2005200242002003200410d5022005200820017c20027d370340200642003703002005420037033041e4c7c1004111200541306a10022007200629030037030020052005290330370320200541206a4110200541c0006a41081003200541106a200010e60120002005290300220220052903107c2208200541086a2903002201200541106a41086a2903007c2008200254ad7c10b402200642003703002005420037033041bcabc2004116200541306a10022007200629030037030020052005290330370320200541206a411041b8d6c200410041001004417f460d022005420037034820054200370340200541206a4110200541c0006a4110410010042206417f460d012006410f4d0d0102402005290340220820027c22032008542206200541c0006a41086a290300220220017c2006ad7c220820025420082002511b0d002005200337034020052008370348200541306a41086a220642003703002005420037033041bcabc2004116200541306a1002200541206a41086a200629030037030020052005290330370320200541206a4110200541c0006a411010030b200541d0006a24000f0b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b8b0602057f077e230041d0006b22042400024002400240411410002205450d002004200536024020044214370244200441c0006a41d7aac20041141029200441306a41086a22052004280248360200200420042903403703302001200441306a101b20052802002106200428023421072004280230210842002109200542003703002004420037033020082006200441306a1002200441206a41086a20052903003703002004200429033037032002400240200441206a411041b8d6c200410041001004417f460d002004420037034820044200370340200441206a4110200441c0006a4110410010042205417f460d012005410f4d0d01200441c8006a290300210a200429034021092007450d040c030b4200210a20070d020c030b41b2eac10041331040000b411441011019000b200810010b20012009200220092009200256200a200356200a20035122051b22081b220b7d200a2003200a20081b220c7d2009200b54ad7d10b402200441306a41086a220842003703002004420037033041bcabc2004116200441306a1002200441206a41086a2008290300370300200420042903303703200240200441206a411041b8d6c200410041001004417f460d0020044200370348200442003703400240200441206a4110200441c0006a4110410010042208417f460d002008410f4d0d0002402004290340220d200b7d220e200d56200441c0006a41086a290300220f200c7d200d200b54ad7d220d200f56200d200f511b0d002004200e3703402004200d370348200441306a41086a220842003703002004420037033041bcabc2004116200441306a1002200441206a41086a200829030037030020042004290330370320200441206a4110200441c0006a411010030b02400240200920025a200a20035a20051b0d00200441086a20012002200b7d2003200c7d2002200b54ad7d10b602200441186a29030021092004290310210a200429030821030c010b420021030b2000200a37030820002003370300200041106a2009370300200441d0006a24000f0b41b2eac10041331040000b41c3d7c10041221040000b9f0101017f230041c0006b22012400200141ff0036020c200141d887c200360208200120003602102001410d360214200141306a410c6a4118360200200141186a410c6a41023602002001412c6a4102360200200141013602342001419888c1003602182001410236021c200141a0d2c2003602202001200141086a3602302001200141106a3602382001200141306a360228200141186a41a888c1001065000b9b1205027f027e047f017e017f230041d0006b22032400200341086a220442003703002003420037030041a1abc200411b20031002200341106a41086a20042903003703002003200329030037031002400240024002400240024002400240200341106a411041b8d6c200410041001004417f460d0020034200370328200342003703200240200341106a4110200341206a4110410010042204417f460d002004410f4d0d00200341206a41086a290300210520032903202106411410002204450d022003200436022020034214370224200341206a41d7aac20041141029200341106a41086a22042003280228360200200320032903203703102000200341106a101b2004280200210720032802142108200328021021092003200237032820032001370320200341086a220a42003703002003420037030020092007200310022004200a29030037030020032003290300370310200341106a4110200341206a4110100302402008450d00200910010b2006200158200520025820052002511b0d07411410002204450d042003200436022020034214370224200341206a41d7aac20041141029200341106a41086a22042003280228360200200320032903203703102000200341106a101b20042802002107200328021421082003280210210942002102200341086a220a42003703002003420037030020092007200310022004200a290300370300200320032903003703100240200341106a411041b8d6c200410041001004417f460d002003420037032820034200370320200341106a4110200341206a4110410010042204417f460d042004410f4d0d04200341286a2903002106200329032021022008450d070c060b4200210620080d050c060b41b2eac10041331040000b41c3d7c10041221040000b411441011019000b41b2eac10041331040000b411441011019000b200910010b200341086a220442003703002003420037030041bcabc200411620031002200341106a41086a2004290300370300200320032903003703100240024002400240024002400240024002400240200341106a411041b8d6c200410041001004417f460d00200342003703282003420037032002400240200341106a4110200341206a4110410010042204417f460d002004410f4d0d0002402003290320220120027d220b200156200341206a41086a290300220520067d2001200254ad7d220220055620022005511b0d002003200b37032020032002370328200341086a220442003703002003420037030041bcabc200411620031002200341106a41086a200429030037030020032003290300370310200341106a4110200341206a411010030b411410002204450d032003200436022020034214370224200341206a41d7aac20041141029200341106a41086a22042003280228360200200320032903203703102000200341106a101b200428020021072003280214210820032802102109200341086a220a42003703002003420037030020092007200310022004200a29030037030020032003290300370310200341106a4110100a02402008450d00200910010b410f10002204450d04200320043602202003420f370224200341206a41c9f5c100410f1029200341106a41086a22042003280228360200200320032903203703102000200341106a101b200428020021072003280214210820032802102109200341086a220a42003703002003420037030020092007200310022004200a29030037030020032003290300370310200341106a4110100a02402008450d00200910010b410f10002204450d05200320043602202003420f370224200341206a41d5c7c100410f1029200341106a41086a22042003280228360200200320032903203703102000200341106a101b200428020021072003280214210820032802102109200341086a220a42003703002003420037030020092007200310022004200a29030037030020032003290300370310200341106a4110100a02402008450d00200910010b200341206a41186a2209200041186a290000370300200341206a41106a200041106a290000370300200341206a41086a200041086a290000370300200320002900003703202003410036024820034201370340200341c0006a418debc10041081029412010002204450d0620042003290320370000200441186a2009290300370000200441106a200341206a41106a290300370000200441086a200341206a41086a290300370000024002400240024020032802442208200341c0006a41086a28020022076b41204f0d00200741206a22092007490d0b2008410174220a20092009200a491b220a4100480d0b2008450d012003280240210c200a10002209450d0d2009200c200a20082008200a4b1b10ce021a200c10010c020b200328024021092008210a0c020b200a10002209450d0b0b2003200a360244200320093602400b200920076a22082004290000370000200841186a200441186a290000370000200841106a200441106a290000370000200841086a200441086a290000370000200341c0006a41086a200741206a220736020020041001200341086a22044200370300200342003703002009200720031002200341106a41086a2004290300370300200320032903003703100240200a450d00200910010b200341106a41101015411810002204450d082003200436022020034218370224200341206a41d2abc20041181029200341106a41086a22042003280228360200200320032903203703102000200341106a101b20042802002107200328021421082003280210210942002102200341086a220a42003703002003420037030020092007200310022004200a290300370300200320032903003703100240200341106a411041b8d6c200410041001004417f460d002003420037032820034200370320200341106a4110200341206a4110410010042204417f460d022004410f4d0d02200341286a2903002101200329032021022008450d0c0c0b0b4200210120080d0a0c0b0b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b411441011019000b410f41011019000b410f41011019000b412041011019000b1018000b411841011019000b200a41011019000b200910010b20022001844200510d010b200341d0006a24000f0b200010be02200341d0006a24000bac0b04027f027e037f017e230041306b22032400200341106a41086a220442003703002003420037031041a1abc200411b200341106a1002200341086a200429030037030020032003290310370300024002400240024002400240024002402003411041b8d6c200410041001004417f460d002003420037032820034200370320024020034110200341206a4110410010042204417f460d002004410f4d0d00200341206a41086a290300210520032903202106411810002204450d022003200436022020034218370224200341206a41d2abc20041181029200341106a41086a22042003280228360200200320032903203703102000200341106a101b2004280200210720032802142108200328021021092003200237032820032001370320200442003703002003420037031020092007200341106a1002200341086a20042903003703002003200329031037030020034110200341206a4110100302402008450d00200910010b2006200158200520025820052002511b0d07411810002204450d042003200436022020034218370224200341206a41d2abc20041181029200341106a41086a22042003280228360200200320032903203703102000200341106a101b20042802002107200328021421082003280210210942002102200442003703002003420037031020092007200341106a1002200341086a20042903003703002003200329031037030002402003411041b8d6c200410041001004417f460d00200342003703282003420037032020034110200341206a4110410010042204417f460d042004410f4d0d04200341286a2903002106200329032021022008450d070c060b4200210620080d050c060b41b2eac10041331040000b41c3d7c10041221040000b411841011019000b41b2eac10041331040000b411841011019000b200910010b200341106a41086a220442003703002003420037031041bcabc2004116200341106a1002200341086a200429030037030020032003290310370300024002400240024002402003411041b8d6c200410041001004417f460d0020034200370328200342003703200240024020034110200341206a4110410010042204417f460d002004410f4d0d0002402003290320220120027d220a200156200341206a41086a290300220520067d2001200254ad7d220220055620022005511b0d002003200a37032020032002370328200341106a41086a220442003703002003420037031041bcabc2004116200341106a1002200341086a20042903003703002003200329031037030020034110200341206a411010030b411810002204450d032003200436022020034218370224200341206a41d2abc20041181029200341106a41086a22042003280228360200200320032903203703102000200341106a101b200428020021072003280214210820032802102109200442003703002003420037031020092007200341106a1002200341086a20042903003703002003200329031037030020034110100a02402008450d00200910010b411410002204450d042003200436022020034214370224200341206a41d7aac20041141029200341106a41086a22042003280228360200200320032903203703102000200341106a101b20042802002107200328021421082003280210210942002102200442003703002003420037031020092007200341106a1002200341086a20042903003703002003200329031037030002402003411041b8d6c200410041001004417f460d00200342003703282003420037032020034110200341206a4110410010042204417f460d022004410f4d0d02200341286a2903002101200329032021022008450d070c060b4200210120080d050c060b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b411841011019000b411441011019000b200910010b20022001844200510d010b200341306a24000f0b200010be02200341306a24000bcb0504057f017e017f067e230041306b22042400024002400240411810002205450d002004200536022020044218370224200441206a41d2abc20041181029200441106a41086a22052004280228360200200420042903203703102001200441106a101b20052802002106200428021421072004280210210842002109200441206a41086a220a42003703002004420037032020082006200441206a10022005200a2903003703002004200429032037031002400240200441106a411041b8d6c200410041001004417f460d002004420037032820044200370320200441106a4110200441206a4110410010042205417f460d012005410f4d0d01200441286a290300210b200429032021092007450d040c030b4200210b20070d020c030b41b2eac10041331040000b411841011019000b200810010b20012009200220092009200256200b200356200b20035122051b22081b220c7d200b2003200b20081b220d7d2009200c54ad7d10b502200441206a41086a220142003703002004420037032041bcabc2004116200441206a1002200441106a41086a2001290300370300200420042903203703100240200441106a411041b8d6c200410041001004417f460d0020044200370328200442003703200240200441106a4110200441206a4110410010042201417f460d002001410f4d0d0002402004290320220e200c7d220f200e56200441206a41086a22012903002210200d7d200e200c54ad7d220e201056200e2010511b0d002004200f3703002004200e370308200142003703002004420037032041bcabc2004116200441206a1002200441106a41086a200129030037030020042004290320370310200441106a41102004411010030b20002002200c7d370308200041106a2003200d7d2002200c54ad7d37030020002009200254200b20035420051bad370300200441306a24000f0b41b2eac10041331040000b41c3d7c10041221040000ba4a90109027f017e057f017e047f017e037f027e1f7f230041f0026b2201240020014188016a41086a22024200370300200142003703880141d08dc200411420014188016a1002200141c8026a41086a200229030037030020012001290388013703c8020240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141c8026a411041b8d6c200410041001004417f460d00200142003703880102400240200141c8026a411020014188016a41084100100441016a41084d0d0020012903880122034200510d0320002003824200520d2e20014188016a41086a22024200370300200142003703880141e48dc200411420014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a411041b8d6c200410041001004417f460d052001410036028801200141c8026a411020014188016a41044100100441016a41044d0d012001280288012202450d2e200141f8016a10bd0120014188016a41086a220442003703002001420037038801418d8ec200411420014188016a1002200141c8026a41086a200429030037030020012001290388013703c802410021040240200141c8026a411041b8d6c200410041001004417f460d002001200141c8026a3602a002200141103602a402200142003703880120014100200141c8026a411020014188016a41084100100422042004417f461b2204410820044108491b220d3602a802200441074d0d05200129038801210e2001410036028801200141a8026a4100200141c8026a411020014188016a4104200d100422042004417f461b2204410420044104491b200d6a360200200441034d0d05200128028801210420014188016a200141a0026a1039200128028801220f450d05200128028002220d20046a200129028c012203422088a76b211002402003a7450d00200f10010b20102002490d080c070b10ac01210e200128028002220d20024f0d060c070b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b41e4d4c000104d000b41b2eac10041331040000b41c3d7c10041221040000b0240200420024f0d00200d200420026b6a2202200d4f0d0820012802f801200241286c6a290320210e0c010b20014188016a41086a22024200370300200142003703880141a18ec200411420014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a411041b8d6c200410041001004417f460d082001420037038801200141c8026a411020014188016a41084100100441016a41084d0d01200129038801200e7c210e0b20014188016a41086a22024200370300200142003703880141d08dc200411420014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a411041b8d6c200410041001004417f460d032001420037038801024002400240200141c8026a411020014188016a41084100100441016a41084d0d0020012903880122034200510d07200e20037c427f7c220e200e2003827d2103024020012802fc01450d0020012802f80110010b20032000520d29200141e8006a10bd0120014188016a41086a22024200370300200142003703880141e48dc200411420014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a411041b8d6c200410041001004417f460d082001410036028801200141c8026a411020014188016a41044100100441016a41044d0d02200128028801211510ac012103200128026821160240024020012802702217450d00201641206a2903002003520d00200141f8016a41186a2204201641186a290000370300200141f8016a41106a220d201641106a290000370300200141f8016a41086a2210201641086a290000370300200120162900003703f801412010002211450d10201641286a2102201120012903f801370000201141186a2004290300370000201141106a200d290300370000201141086a20102903003700004120210d4101211841012119201741286c41586a2210450d010340200241206a2903002003520d02200141a0026a41186a200241186a2204290000370300200141a0026a41106a200241106a220f290000370300200141a0026a41086a200241086a221a290000370300200120022900003703a00220014188016a41186a2214200429000037030020014188016a41106a221b200f29000037030020014188016a41086a220f201a2900003703002001200229000037038801024020192018470d00201841016a22042018490d1a2018410174221a20042004201a491b221aad420586220e422088a70d1b200ea722044100480d1c02402018450d0020041000221c450d0a201c2011200420184105742218201820044b1b10ce0221042011100120042111201a21180c010b201a2118200410002211450d090b200241286a21022011200d6a2204200129038801370000200441186a2014290300370000200441106a201b290300370000200441086a200f290300370000200d41206a210d201941016a2119201041586a22100d000c020b0b4101211141002119410021180b0240024002400240201720196b20154f0d0020014188016a41086a22024200370300200142003703880141b58ec200411c20014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a411041b8d6c200410041001004417f460d0f2001420037038801200141c8026a411020014188016a41084100100441016a41084d0d08200129038801210e410810002202450d102002200e20037c37000041101000220f450d11200f200229000037000020021001200f201920176b20156a221b360008201941c0004f0d01200f20194102743a000c410d21104110210d20190d020c030b2018450d2120111001200128026c0d220c2c0b02402019418080014f0d00200f20194102744101723b000c410e21104110210d0c010b024020194180808080044f0d00200f201941027441027236000c4110210d411021100c010b200f41033a000c4120210d412010002202450d132002200f290000370000200241086a200f41086a290000370000200f10012002201936000d411121102002210f0b2019410574211a201121190340201921020240024002400240200d201022046b41204f0d00200441206a22102004490d1f200d4101742219201020102019491b22194100480d20200d450d01201910002214450d072014200f2019200d200d20194b1b10ce02210d200f1001200d210f0c020b200441206a21100c020b20191000220f450d050b2019210d0b200241206a2119200f20046a22042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a290000370000201a41606a221a0d000b0b20014188016a41086a220242003703002001420037038801418d8ec200411420014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a4110200f201010030240200d450d00200f10010b02402018450d00201110010b4108211120014188016a41086a22024200370300200142003703880141d18ec200410e20014188016a1002200141c8026a41086a200229030037030020012001290388013703c8024100210202400240024002400240200141c8026a411041b8d6c200410041001004417f460d00200142103702a4022001200141c8026a3602a00220014188016a200141a0026a1039200128028801221c450d1441082111200128028c01211720014188016a41086a2802002214450d012014ad4204862203422088a70d202003a722024100480d21200210002211450d152014410574220d41606a410576210f200141086a2110201c210420112102034020012004109502200129030021032002201029030037030820022003370300200241106a2102200441206a2104200d41606a220d0d000b200f41016a2202413f4d0d022002418080014f0d044102211041021000220f450d17200f20024102744101723b00000c220b4101211c41002117410021144101211041011000220f0d020c2c0b41002102410021140b4101211041011000220f450d2a0b200f20024102743a00000c1e0b024020024180808080044f0d004104211041041000220f450d14200f20024102744102723600000c1e0b410110002204450d14200441033a00004105211041051000220f450d15200f20042d00003a000020041001200f20023600010c1d0b41b2eac10041331040000b201941011019000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b200441011019000b41c3d7c10041221040000b418cd5c000104d000b41c3d7c10041221040000b41fcd4c0002002200d104a000b41c3d7c10041221040000b41c3d7c10041221040000b410841011019000b411041011019000b412041011019000b41b2eac10041331040000b200241081019000b412041011019000b410241011019000b410441011019000b410141011019000b410541011019000b410921200c130b410921200c120b410921200c110b410921200c100b410921200c0f0b410921200c0e0b410921200c0d0b024002402011201120024104746a221a460d002010210d201121020340200241086a29030021032002290300210e0240024002400240200d201022046b41104f0d00200441106a22102004490d0d200d4101742219201020102019491b22194100480d0e200d450d01201910002218450d092018200f2019200d200d20194b1b10ce02210d200f1001200d210f0c020b200441106a21100c020b20191000220f450d070b2019210d0b200f20046a220420033700082004200e370000201a200241106a2202470d000c020b0b4101210d0b20014188016a41086a22024200370300200142003703880141df8ec200411820014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a4110200f201010030240200d450d00200f10010b02402014450d00201110010b20014188016a41086a22024200370300200142003703880141f78ec200411220014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a411041b8d6c200410041001004417f460d042001410036028801200141c8026a411020014188016a41044100100441016a41044d0d032001280288012102200141e0026a4200370300200141d8026a4200370300200141d0026a4200370300200142003703c8022002201b6a220dad42307e2203422088a70d082003a72202417f4c0d09024002402002450d0020021000221a450d07201a21020c010b4108211a410821020b20014188016a41186a2210200141c8026a41186a29030037030020014188016a41106a220f200141c8026a41106a29030037030020014188016a41086a200141c8026a41086a290300370300200120012903c80237038801024002400240200d4102490d0020014190016a21194101210403402002420037030820024200370300200241286a2010290300370300200241206a200f290300370300200241186a2019290300370300200241106a200129038801370300200241306a2102200441016a2204200d490d000b2004417f6a21040c010b41002104200d450d010b20024200370308200242003703002002200129038801370310200241186a20014190016a290300370300200241206a20014198016a290300370300200241286a20014188016a41186a290300370300200441016a21040b2001200d36028c012001201a36028801200120043602900120014188016a10c9010240200d450d00201a10010b20014190016a201b360200200141023a008c01200141053a00880120014188016a10a1012017450d00201c10010b200128026c450d0a0b201610010c090b201941011019000b41b2eac10041331040000b41c3d7c10041221040000b200241081019000b410921200c050b410921200c040b412521200c030b412521200c020b410141011019000b20014188016a41086a220242003703002001420037038801418d8ec200411420014188016a1002200141c8026a41086a200229030037030020012001290388013703c8020240200141c8026a411041b8d6c200410041001004417f460d002001200141c8026a3602a002200141103602a402200142003703880120014100200141c8026a411020014188016a41084100100422022002417f461b2202410820024108491b22043602a80202400240024002400240024002400240024002400240200241074d0d0020012903880121032001410036028801200141a8026a4100200141c8026a411020014188016a41042004100422022002417f461b22024104200241044922021b20046a36020020020d0020014188016a200141a0026a10392001280288012205450d00200128028c01210620032000520d0a20014188016a41086a22024200370300200142003703880141df8ec200411820014188016a1002200141c8026a41086a2204200229030037030020012001290388013703c802200141c8026a4110100a20044200370300200142003703c802418d8ec2004114200141c8026a100220022004290300370300200120012903c8023703880102400240024020014188016a411041b8d6c200410041001004417f460d00200120014188016a3602a002200141103602a402200142003703c8022001410020014188016a4110200141c8026a41084100100422022002417f461b22024108200241084922041b22023602a80220040d05200141003602c802200141a8026a410020014188016a4110200141c8026a41042002100422042004417f461b2204410420044104491b20026a360200200441034d0d0520012802c8022107200141c8026a200141a0026a103920012802c8022208450d0520012902cc0221094108210a200141c8026a41086a22024200370300200142003703c802418d8ec2004114200141c8026a100220014188016a41086a22042002290300370300200120012903c8023703880120014188016a4110100a20024200370300200142003703c80241898fc2004113200141c8026a100220042002290300370300200120012903c802370388014100210b20014188016a411041b8d6c200410041001004417f460d01200142103702a402200120014188016a3602a002200141c8026a200141a0026a103c20012802c802220a450d0920012902cc022100200141c8026a41086a22024200370300200142003703c80241898fc2004113200141c8026a100220014188016a41086a2002290300370300200120012903c8023703880120014188016a4110100a2000422088a7210b2000a7210c0c020b02402006450d00200510010b4183d7c200410f1006418090c20041351006200141f0026a24000f0b4100210c0b10ac01210020014188016a41086a22024200370300200142003703880141a18ec200411420014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a411041b8d6c200410041001004417f460d042001420037038801200141c8026a411020014188016a41084100100441016a41084d0d01200120012903880120007c37031020014188016a41086a22024200370300200142003703880141eb8fc200411520014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a411041b8d6c200410041001004417f460d0520014200370390012001420037038801200141c8026a411020014188016a4110410010042202417f460d032002410f4d0d03200a200b41306c6a211120014188016a41086a29030021122001290388012113024002400240024002402007450d002007417f6a211041002104200a2011460d01200a200b41306c6a220241506a2211290300200241586a29030084500d03200141e0026a200241786a290000370300200141d8026a200241706a290000370300200141d0026a200241686a2900003703002001200241606a2900003703c802410121040c020b4100211441002110410021040c030b200a21110b410021140c010b410121140b20014191016a200141c8026a41086a29030037000020014199016a200141c8026a41106a290300370000200141a1016a200141c8026a41186a290300370000200120043a008801200120012903c802370089014101211d20014188016a410172210202402004450d0020022013201210b802200141f8016a41186a200241186a290000370300200141f8016a41106a200241106a290000370300200141f8016a41086a2204200241086a290000370300200120022900003703f80141201000221d450d08201d20012903f801370000201d41186a200141f8016a41186a290300370000201d41106a200141f8016a41106a290300370000201d41086a200429030037000020014188016a41017221024120210d4101211e4101211f20100d0a0c090b200141f8016a41186a200241186a290000370300200141f8016a41106a200241106a290000370300200141f8016a41086a200241086a290000370300200120022900003703f8014100211f20014188016a21214100211e411021200c0c0b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b41b2eac10041331040000b41c3d7c10041221040000b41c3d7c10041221040000b41b2eac10041331040000b412041011019000b410521200c030b410021200c020b41d70021200c010b41d90021200b03400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020200eb50209101100080f01020395020405069d0207121314151617191a1b1c2e2f3031329e019f01a001a101a201a401a501a102a601a701aa01ae01af01b001b101b201b301b401b501b901ce01cf01d001d101d201d301d401d501d601d701e201e301e401ea01eb01e701ef01f201f501f801f901fa01fb01fc018202850286028702880289028a028b028c028e028f0290029102920293029402a3028d02fd01fe01ff018002810284029c028302b402b302f601f701b202f301f401af02f001f101ad02ec01ed01ee01e501d801d901e601da01db01e801dc01dd01e901de01df01e001e1019e02ba01bc01bd01be01bf01c001c101c201cd01c301c401c501c601c701b002c801c901ca01cb01cc01a402b601b701b801bb01ab01ac01ad01a801a901ac02a3011d1e1f202133343536373848494a4b4c4e595a5e5f6061577b99019a019b019c019d017c7d820185018601980287019902880189018a01900196019701980191019201930194018b0195018c018d018e018f019b029a02830184017e4f7f800181017374757677787aa602796263646570727166676e6f686996026a6b97026c6da902a802aa02585b5c5d515253545556a70250b1024d393a3b3c473d3e45463f409f024142a0024344a20222232d2425262728292a2ca5022bae02ab02180a0b0c0e0d0d0b20014188016a41186a2218200f29030037030020014188016a41106a220f201929030037030020014188016a41086a2219201a290300370300200120012903a00237038801201f201e470dbc02410621200ca9040b201e41016a2204201e490dbc02410721200ca8040b201e410174221a20042004201a491b221aad4205862200422088a70dbc02410821200ca7040b2000a722044100480dbe02410a21200ca6040b201e450dc602410b21200ca5040b20041000221b450dc602410c21200ca4040b201b201d2004201e4105742216201620044b1b10ce022104201d10012004211d201a211e0cb4020b201a211e20041000221d450db402410421200ca2040b201d200d6a2204200129038801370000200441186a2018290300370000200441106a200f290300370000200441086a2019290300370000200d41206a210d201f41016a211f2010450dac02410021200ca1040b2010417f6a2110201441ff01710daf0241b00221200ca0040b2011200a460d9d0441b10221200c9f040b201141506a220f290300201141586a290300844200510d9d0441b20221200c9e040b201141606a2900002100201141686a2900002103201141706a290000210e200141c8026a41186a2204201141786a290000370300200141c8026a41106a2219200e370300200141c8026a41086a221a2003370300200120003703c802200220012903c802370000200241086a201a290300370000200241106a2019290300370000200241186a200429030037000041012104200141013a00880120022013201210b80241002114200f21110cab020b41002114200a21110ca8020b41012114200f21110ca8020b41002110410121200c9a040b200220012903c802370000200241086a200141c8026a41086a290300370000200241106a200141c8026a41106a290300370000200241186a200141c8026a41186a29030037000041002104200141003a008801410221200c99040b200141a0026a41186a220f200241186a290000370300200141a0026a41106a2219200241106a290000370300200141a0026a41086a221a200241086a290000370300200120022900003703a00220040da802410f21200c98040b20014188016a21210cba020b200141186a10bd012001280218210f410021222009422088a7221020012802202202200220104b1b2223450dba02411121200c96040b2023ad4205862200422088a70dae02411221200c95040b2000a722044100480dae02411321200c94040b200410002224450db802411421200c93040b200f200241286c6a211920100db9020cb8020b4101212441002123200f200241286c6a21192010450db902411521200c91040b200241286c210d41002122200f210220242104411621200c90040b200d450db902411721200c8f040b200141a0026a41186a200241186a2900002203370300200141a0026a41106a200241106a290000220e370300200141a0026a41086a200241086a290000221237030020022900002100200441186a2003370000200441106a200e370000200441086a201237000020042000370000200120003703a002200d41586a210d200441206a2104200241286a21022010202241016a2222470db702411821200c8e040b200128021c21022001201d36028c0220014190026a2204201d201f4105746a360200200120023602fc012001200f3602f8012001200f360280022001201936028402200120103602880220014194026a200141106a360200200141003a00980220014188016a200141f8016a10422001290388014201520db80241a10121200c8d040b417f417f410020014184026a280200200141f8016a41086a2802006b41286d220220014188026a2802006b220d200d20024b1b22022004280200200128028c026b4105766a220420042002491b220241016a220420042002491b2225ad42287e2200422088a70dc40241a20121200c8c040b2000a72202417f4c0dc40241a30121200c8b040b410821262002450da80341a40121200c8a040b200210002226450da80341a50121200c89040b202620014188016a41086a2202290300370300202641206a200241206a290300370300202641186a200241186a290300370300202641106a200241106a290300370300202641086a200241086a290300370300200141a0026a41206a200141f8016a41206a280200360200200141a0026a41186a2211200141f8016a41186a290300370300200141a0026a41106a2214200141f8016a41106a290300370300200141a0026a41086a200141f8016a41086a290300370300200120012903f8013703a00220014188016a200141a0026a10422001290388014201520da80341a00221200c88040b20014188016a41086a2102200141ac026a211b200141b4026a21164128210d4101212741a10221200c87040b200141c8026a41206a2210200241206a290300370300200141c8026a41186a220f200241186a290300370300200141c8026a41106a2219200241106a290300370300200141c8026a41086a221a200241086a290300370300200120022903003703c80220272025470dfe0341a30221200c86040b417f417f4100201b280200200141a0026a41086a2802006b41286d220420142802006b2218201820044b1b2204201128020020162802006b4105766a221820182004491b220441016a221820182004491b2204450dfe0341a40221200c85040b202520046a22042025490d9f0241a50221200c84040b20254101742218200420042018491b2218ad42287e2200422088a70d9f0241a60221200c83040b2000a722044100480d9f0241a70221200c82040b2025450dfb0341a80221200c81040b20041000221c450dfb0341a90221200c80040b201c20262004202541286c2217201720044b1b10ce02210420261001200421260cfb030b200410002226450dfb0341aa0221200cfe030b2018212541a20221200cfd030b2026200d6a220420012903c802370300200441206a2010290300370300200441186a200f290300370300200441106a2019290300370300200441086a201a290300370300200d41286a210d202741016a212720014188016a200141a0026a10422001290388014201510d9d030c9e030b20014180026a2204280200220220014184026a280200220d460da702411a21200cfb030b20042002200d20026b41586a41286e41286c6a41286a360200411b21200cfa030b20012802fc01450da602411c21200cf9030b20012802f8011001411d21200cf8030b4100212541082126410021270ca5020b4101212741a70121200cf6030b200141a8026a22042802002202200141ac026a280200220d460d980341a80121200cf5030b20042002200d20026b41586a41286e41286c6a41286a36020041a90121200cf4030b20012802a402450d970341aa0121200cf3030b20012802a002100141ab0121200cf2030b202741144b0d9603418e0221200cf1030b202741014d0d9f02418f0221200cf0030b2027417f6a210f41900221200cef030b2027200f2202417f6a220f490ddc0341910221200cee030b2027200f6b22104102490ddc0341930221200ced030b2026200241286c6a221a41206a22022903002026200f41286c6a221941206a220429030022005a0ddc0341940221200cec030b20212019290300370300202141186a2211201941186a220d290300370300202141106a2214201941106a2218290300370300202141086a221b201941086a22162903003703002019201a2903003703002016201a41086a2903003703002018201a41106a290300370300200d201a41186a2903003703002004200229030037030020104103490ddd0341970221200ceb030b4103210d4102210441980221200cea030b200420104f0ddf03419a0221200ce9030b2019200441286c6a220241206a221829030020005a0dd903419b0221200ce8030b2004417f6a220420104f0dde03419d0221200ce7030b2019200441286c6a22042002290300370300200441206a2018290300370300200441186a200241186a290300370300200441106a200241106a290300370300200441086a200241086a290300370300200d20104f0ddb03419e0221200ce6030b200d2104200d41016a221a200d492118201a210d2002211a2018450dd9030cd8030b201a210241960221200ce4030b20022021290300370300200241186a2011290300370300200241106a2014290300370300200241086a201b2903003703002002200037032041920221200ce3030b200f0d93020c92020b20274101762228ad42287e2200422088a70d9b0241ad0121200ce1030b2000a72202417f4c0d9b0241ae0121200ce0030b2002450d850341af0121200cdf030b200210002229450d850341b00121200cde030b2029211a0c85030b410821294108211a41b10121200cdc030b202641586a212a202641a87f6a212b410421164100212c4100212d2027212e0c84030b2014212d202e0d86030c85030b4100211041840221200cd9030b20112010490dc30341850221200cd8030b201120274b0dbe0341860221200cd7030b201120106b220d410176220f450dc20341870221200cd6030b202a20196a21022026201041286c6a210441880221200cd5030b20014188016a41206a2219200441206a221829030037030020014188016a41186a2214200441186a221b29030037030020014188016a41106a221c200441106a221729030037030020014188016a41086a2215200441086a222e2903003703002001200429030037038801200241086a222f2903002100200241106a22302903002103200241186a2231290300210e200229030021122018200241206a2232290300370300201b200e37030020172003370300202e20003703002004201237030020322019290300370300203120142903003703002030201c290300370300202f20152903003703002002200129038801370300200241586a2102200441286a2104200f417f6a220f0dc10341890221200cd4030b20100d840341b80121200cd3030b2010212e202d202c460d89030c8a030b2011210d202d202c460d86030c87030b202e21114100212e4101210d2011417f6a2210450dfd0241b30121200cd0030b2026201041286c6a41206a2903002026201141286c22026a41506a29030022005a0dfd0241810221200ccf030b202b201141056c41037422196a210241820221200cce030b20104101460db70341830221200ccd030b2010417f6a2110200020022903002203542104200241586a21022003210020040db4030cb5030b2011417e6a2110202b20026a21044100212e4100210241b50121200ccb030b20102002460dfa0241b60121200cca030b200241016a21022000200429030022035a210d200441586a210420032100200d0df80241b70121200cc9030b200241016a210d201120026b417f6a2210450dfa0241ea0121200cc8030b200d41094b0dfa0241eb0121200cc7030b201120274b0da00341ec0121200cc6030b20112010417f6a222e490da00341ed0121200cc5030b2011202e6b220d4102490da00341f10121200cc4030b2026201041286c6a221941206a22022903002026202e41286c6a220f41206a220429030022005a0da00341f20121200cc3030b2021200f290300370300202141186a2214200f41186a2210290300370300202141106a221b200f41106a2218290300370300202141086a221c200f41086a2217290300370300200f20192903003703002017201941086a2903003703002018201941106a2903003703002010201941186a29030037030020042002290300370300200d4103490da20341f50121200cc2030b410321104102210441f60121200cc1030b2004200d4f0da40341f80121200cc0030b200f200441286c6a220241206a221829030020005a0d9e0341f90121200cbf030b2004417f6a2204200d4f0da30341fb0121200cbe030b200f200441286c6a22042002290300370300200441206a2018290300370300200441186a200241186a290300370300200441106a200241106a290300370300200441086a200241086a2903003703002010200d4f0da00341fc0121200cbd030b20102104201041016a2219201049211820192110200221192018450d9e030c9d030b2019210241f40121200cbb030b20022021290300370300200241186a2014290300370300200241106a201b290300370300200241086a201c2903003703002002200037032041ee0121200cba030b202e450d970341f00121200cb9030b202e2110200d410a490d910341ef0121200cb8030b202d202c470deb0241e10121200cb7030b202c41016a2202202c490dd60141e20121200cb6030b202c4101742204200220022004491b2204ad4203862200422088a70dd40141e30121200cb5030b2000a722024100480dd20141e40121200cb4030b202c450d880341e50121200cb3030b200210002210450d880341e60121200cb2030b201020162002202c410374220f200f20024b1b10ce02210220161001200221160c88030b200210002216450d880341e70121200cb0030b2004212c41b90121200caf030b2016202d4103746a2202200d3602042002202e360200202d41016a222d4102490de70241bf0121200cae030b2016202d2214417f6a222d4103746a2202280200450de90241c00121200cad030b201620144103746a220f41746a2802002210200228020422044d0de90241dc0121200cac030b201441024d0dfe0241de0121200cab030b20162014417d6a22024103746a280204220d200420106a4d0dfc0241df0121200caa030b201441034d0dfd0241e00121200ca9030b200f41646a280200200d20106a4d0df9020cf8020b20144103490de50241da0121200ca7030b2002280204210420162014417d6a22024103746a280204210d41db0121200ca6030b200d2004490de40241c20121200ca5030b2014417e6a210241c30121200ca4030b2014200241016a222f4d0de30241c50121200ca3030b201420024d0de30241c70121200ca2030b201620024103746a221c2802042230201c2802006a22022016202f4103746a22172802002215490de30241c80121200ca1030b200220274b0de30241c90121200ca0030b201c41046a21312026201541286c6a22112017280204221b41286c22046a210f200241286c210d200220156b2219201b6b2202201b4f0de30241d20121200c9f030b2029200f200241286c220410ce021a201a20046a2110201b4101480dec0241d40121200c9e030b20024101480dec0241d50121200c9d030b202a200d6a210d200f210241d60121200c9c030b200d200241586a2219201041586a2218201041786a290300200241786a29030054220f1b2204290300370300200d41206a200441206a290300370300200d41186a200441186a290300370300200d41106a200441106a290300370300200d41086a200441086a29030037030020102018200f1b2110201120192002200f1b22024f0de20241d70121200c9b030b200d41586a210d201a2104201a2010490de5020ce6020b20292011200410ce021a201a20046a2110201b4101480dde0241ce0121200c99030b2019201b4c0dde0241cf0121200c98030b2026200d6a2118201a21042011210241d00121200c97030b2002200f2004200f41206a290300200441206a2903005422191b220d290300370300200241206a200d41206a290300370300200241186a200d41186a290300370300200241106a200d41106a290300370300200241086a200d41086a2903003703002004200441286a20191b2104200241286a2102200f41286a200f20191b220f20184f0de30241d10121200c96030b201020044b0dde020cdf020b200f21020cdc020b2011210241cc0121200c93030b201a210441cd0121200c92030b20022004201020046b220d200d4128706b10ce021a20312030201b6a360200201c20153602002017201741086a2014202f417f736a41037410cf021a202d41014b0dcb0241ba0121200c91030b202e0dba0241bb0121200c90030b202c450dca0241bc0121200c8f030b2016100141bd0121200c8e030b2028450dbf0141be0121200c8d030b20291001411e21200c8c030b2001202536028c012001202636028801200120273602900120014188016a10cd012025450dbe01411f21200c8b030b20261001412021200c8a030b20014188016a41086a22024200370300200142003703880141b28fc200411220014188016a1002200141c8026a41086a200229030037030020012001290388013703c80241002111200141c8026a411041b8d6c200410041001004417f460dbd01412121200c89030b200142103702a4022001200141c8026a3602a00220014188016a200141a0026a10392001280288012214450dbd01412221200c88030b20014190016a2802002111200128028c0121310cbd010b4101211441002131412321200c86030b200141e0026a4200370300200141d8026a4200370300200141d0026a4200370300200142003703c8022011ad2200421b88a70dbc01412421200c85030b2000420586a72202417f4c0dc001412621200c84030b2002450dc001412721200c83030b2002100022180dc001419d0121200c82030b200241011019000b41012118412821200c80030b20014188016a41186a220d200141c8026a41186a29030037030020014188016a41106a2210200141c8026a41106a29030037030020014188016a41086a220f200141c8026a41086a290300370300200120012903c8023703880120114102490dbe01419a0121200cff020b2018210241012104419b0121200cfe020b2002200129038801370000200241186a200d290300370000200241106a2010290300370000200241086a200f290300370000200241206a2102200441016a22042011490d9a02419c0121200cfd020b2004417f6a211c0cbd010b4100211c201821022011450dbb01412a21200cfb020b2002200129038801370000200241186a20014188016a41186a290300370000200241106a20014188016a41106a290300370000200241086a20014188016a41086a290300370000201c41016a211c412b21200cfa020b200a200b41306c6a21022007450dbb01412c21200cf9020b2002200a460dbb01412d21200cf8020b200b41306c21042007417f732119200141f8016a41186a210d200141f8016a41106a2110200141f8016a41086a210f412e21200cf7020b200a20046a220241586a2903002100200241506a2903002103200d200241786a2903003703002010200241706a290300370300200f200241686a2903003703002001200241606a2903003703f80120032000844200510dbc01412f21200cf6020b200141c8026a41186a221a200d290300370300200141c8026a41106a221b2010290300370300200141c8026a41086a2216200f290300370300200120012903f8013703c802200141a0026a41186a2217201a290300370300200141a0026a41106a221a201b290300370300200141a0026a41086a221b2016290300370300200120012903c8023703a00220014188016a41186a201729030037030020014188016a41106a201a29030037030020014188016a41086a201b290300370300200120012903a00237038801201941016a2219450dbc01413021200cf5020b200441506a22040db9010cb8010b2002200a460dbb0141970121200cf3020b200141c8026a41086a2204200241686a220d290300370300200141c8026a41106a2210200241706a220f290300370300200141c8026a41186a2219200241786a221a2903003703002001200241606a221b2903003703c802200241586a2903002100200241506a2216290300210320014188016a41186a201a29030037030020014188016a41106a200f29030037030020014188016a41086a200d2903003703002001201b29030037038801200141f8016a41186a22022019290300370300200141f8016a41106a220d2010290300370300200141f8016a41086a22102004290300370300200120012903c8023703f8012003200084500d8e0241980121200cf2020b200141e8006a41186a2002290300370300200141e8006a41106a200d290300370300200141e8006a41086a2010290300370300200120012903f8013703684100212741002130420150450dfa010cfb010b41002130200c0dbb010cba010b200141e8006a41186a20014188016a41186a290300370300200141e8006a41106a20014188016a41106a290300370300200141e8006a41086a20014188016a41086a2903003703002001200129038801370368200241506a2116410021270cf6010b41012127410021304200500df60141820121200cee020b4100213041830121200ced020b201621022027211641840121200cec020b200141c8006a41186a220d200141e8006a41186a222f290300370300200141c8006a41106a2210200141e8006a41106a2226290300370300200141c8006a41086a220f200141e8006a41086a222d29030037030020012001290368370348200141c8026a41186a2204200d290300370300200141c8026a41106a220d2010290300370300200141c8026a41086a2210200f290300370300200120012903483703c80241161000220f450dfd0141850121200ceb020b2001200f360288012001421637028c0120014188016a419c8fc20041161029200141f8016a41086a220f20014188016a41086a221928020036020020012001290388013703f801200141c8026a200141f8016a101b20012802fc01211a200141e8006a20012802f801221b200f28020010c701201a450dfd0141860121200cea020b201b100141870121200ce9020b20014188016a41186a221a200429030037030020014188016a41106a221b200d29030037030020192010290300370300200120012903c8023703880120012802684101460dfc0141880121200ce8020b201641ff01710dfc01418a0121200ce7020b200a2002460dfc01418b0121200ce6020b200241586a2903002100200241506a221729030021032004200241786a2216290300370300200d200241706a22152903003703002010200241686a222e2903003703002001200241606a22022903003703c802201a2016290300370300201b20152903003703002019202e2903003703002001200229030037038801200141f8016a41186a22022004290300370300200141f8016a41106a2204200d290300370300200f2010290300370300200120012903c8023703f8012003200084500dfe01418c0121200ce5020b202f200229030037030020262004290300370300202d200f290300370300200120012903f801370368410021162017210242014200520df4010cf5010b41012127410121162017210242004200520df1010cf2010b200141a0026a41086a22172019290300370300200141a0026a41106a2215201b290300370300200141a0026a41186a222e201a29030037030020012001290388013703a002202d2802002116200141286a41186a2232202e290300370300200141286a41106a222e2015290300370300200141286a41086a22152017290300370300200120012903a002370328201a2032290300370300201b202e290300370300201920152903003703002001200129032837038801201c20164d0dfc0141900121200ce2020b201820164105746a2216200129038801370000201641186a201a290300370000201641106a201b290300370000201641086a2019290300370000203041016a2130202741ff01710df80141910121200ce1020b200a2002460df80141920121200ce0020b200241586a2903002100200241506a221629030021032004200241786a2217290300370300200d200241706a22152903003703002010200241686a222e2903003703002001200241606a22022903003703c802201a2017290300370300201b20152903003703002019202e2903003703002001200229030037038801200141f8016a41186a22022004290300370300200141f8016a41106a2204200d290300370300200f2010290300370300200120012903c8023703f8012003200084500dfa0141930121200cdf020b202f200229030037030020262004290300370300202d200f290300370300200120012903f8013703684100212742014200520de9010cea010b4101212742004200520dea0141890121200cdd020b200c450da501413221200cdc020b200a1001413321200cdb020b201c20112011201c4b1b2219450da601413421200cda020b4100210d2014210220182104413521200cd9020b20142018460da601413621200cd8020b20022004412010d102450da601413721200cd7020b411610002210450da601413821200cd6020b20012010360288012001421637028c0120014188016a419c8fc20041161029200141c8026a41086a221020014188016a41086a220f28020036020020012001290388013703c8022002200141c8026a101b2010280200211b20012802cc02211620012802c802211a200f42003703002001420037038801201a201b20014188016a10022010200f29030037030020012001290388013703c802200141c8026a4110100a2016450da601413921200cd5020b201a1001413a21200cd4020b200241206a2102200441206a2104200d41016a220d2019490da001413b21200cd3020b2009a72116200141a0016a210d20014198016a211020014190016a210f201c21192018201c41057422046a220220186b41ff004d0da40141f30021200cd2020b200d420037030020104200370300200f42003703002001420037038801200241606a221a20014188016a460dd10141f40021200cd1020b201a20014188016a412010d1020dd10141f60021200cd0020b200d420037030020104200370300200f42003703002001420037038801200241406a221a20014188016a460dd10141f70021200ccf020b201a20014188016a412010d1020dd10141f90021200cce020b200d420037030020104200370300200f42003703002001420037038801200241a07f6a221a20014188016a460dd10141fa0021200ccd020b201a20014188016a412010d1020dd10141fc0021200ccc020b200d420037030020104200370300200f420037030020014200370388012019417c6a2119200241807f6a220220014188016a460dd10141fd0021200ccb020b2002211a200220014188016a412010d1020da50141fe0021200cca020b200441807f6a2104201a20186b41ff004b0d9d010c9e010b200441807f6a210420014188016a20186b41ff004b0d9b01413c21200cc8020b20014188016a20186b41206a210d200141a0016a211020014198016a210f20014190016a211a410121022004450d9d01413d21200cc7020b20104200370300200f4200370300201a42003703002001420037038801200d2004460d9f01413e21200cc6020b201820046a41606a20014188016a412010d1020d9f0141f20021200cc5020b200241016a2102200441606a22040d9c010c9b010b4101210d2019417f6a41016a2202201c490da00141c10021200cc3020b201c21190ca5010b4101210d2019417e6a41016a2202201c490d9f010ca0010b4101210d2019417d6a41016a2202201c490da0010ca1010b201920026b211941c00021200cbf020b4101210d201941016a2202201c4f0d9a0141ef0021200cbe020b201c211941f00021200cbd020b2002200d6a22042002490da00141f10021200cbc020b2019417f6a2119200421022004201c490d9d0141c20021200cbb020b20014190016a201d36020020014194016a201e36020020014198016a201f3602002001419c016a2024360200200141a0016a2023360200200141a4016a2022360200200141033a008c01200141053a00880120014188016a10a1012019413f4b0d9f0141ec0021200cba020b4101210d41011000220f450db80141ed0021200cb9020b200f20194102743a00004101211020190da5010ca4010b2019418080014f0d9d0141e90021200cb7020b4102210d41021000220f450db40141ea0021200cb6020b200f20194102744101723b00000ca0010b20194180808080044f0d9b0141e60021200cb4020b4104210d41041000220f450db00141e70021200cb3020b200f20194102744102723600000c9c010b410110002202450d990141c60021200cb1020b200241033a00004105210d41051000220f450d990141c70021200cb0020b200f20022d00003a000020021001200f201936000141c80021200caf020b2019410574211a200d21102018211941c90021200cae020b20192102200d201022046b41204f0d9c0141dc0021200cad020b200441206a22102004490d4241dd0021200cac020b200d4101742219201020102019491b22194100480d4241de0021200cab020b200d450da30141df0021200caa020b20191000221b450da30141e00021200ca9020b201b200f2019200d200d20194b1b10ce02210d200f1001200d210f0ca4010b200441206a21100c97010b20191000220f450da10141e10021200ca6020b2019210d41cb0021200ca5020b200241206a2119200f20046a22042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a290000370000201a41606a221a0d920141cc0021200ca4020b20014188016a41086a22024200370300200142003703880141b28fc200411220014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a4110200f20101003200d450d940141cd0021200ca3020b200f100141ce0021200ca2020b2011450d930141cf0021200ca1020b2018100141d00021200ca0020b200120303602a00220014188016a41086a22024200370300200142003703880141c48fc200411620014188016a1002200141c8026a41086a2204200229030037030020012001290388013703c802200141c8026a4110200141a0026a4104100320024200370300200142003703880141da8fc200411120014188016a10022004200229030037030020012001290388013703c802200141c8026a411041b8d6c200410041001004417f460d920141d10021200c9f020b2001410036028801200141c8026a411020014188016a41044100100441016a41044d0d920141d20021200c9e020b20012802880141016a21020c92010b4101210241d30021200c9c020b200120023602a00220014188016a41086a22024200370300200142003703880141da8fc200411120014188016a1002200141c8026a41086a200229030037030020012001290388013703c802200141c8026a4110200141a0026a410410032031450d910141d40021200c9b020b2014100141d50021200c9a020b2016450d900141d60021200c99020b2008100141d70021200c98020b2006450d8f0141d80021200c97020b2005100141d90021200c96020b200141f0026a24000f0b1018000b419093c1002004200d104a000b41a093c1002004200d104a000b418093c100202f2014104a000b418093c10020022014104a000b20152002106b000b20022027106a000b201941011019000b200441011019000b411641011019000b419093c10020042010104a000b41a093c10020042010104a000b102e000b200f2027106b000b41b2eac10041331040000b411641011019000b200441081019000b200241041019000b20102011106b000b20112010417f6a222e4f0de70141fd0121200c81020b202e2011106b000b20112027106a000b200441011019000b41b2eac10041331040000b410141011019000b200241081019000b410241011019000b41a4d5c0002016201c104a000b200241081019000b410441011019000b410141011019000b410541011019000b410521200cf4010b410121200cf3010b410121200cf2010b410221200cf1010b410121200cf0010b410321200cef010b410421200cee010b410d21200ced010b410421200cec010b410921200ceb010b410921200cea010b410921200ce9010b410921200ce8010b410921200ce7010b410921200ce6010b410921200ce5010b410921200ce4010b410921200ce3010b410921200ce2010b410921200ce1010b410921200ce0010b410921200cdf010b410e21200cde010b410d21200cdd010b411021200cdc010b41af0221200cdb010b41ae0221200cda010b411821200cd9010b411521200cd8010b411821200cd7010b411621200cd6010b411821200cd5010b411921200cd4010b411b21200cd3010b411d21200cd2010b411e21200cd1010b411e21200cd0010b411e21200ccf010b41900221200cce010b411e21200ccd010b412021200ccc010b41a00121200ccb010b419f0121200cca010b412321200cc9010b412521200cc8010b412521200cc7010b412521200cc6010b412521200cc5010b412521200cc4010b412521200cc3010b419e0121200cc2010b412821200cc1010b412921200cc0010b412b21200cbf010b412a21200cbe010b41960121200cbd010b413121200cbc010b413121200cbb010b412e21200cba010b413121200cb9010b41810121200cb8010b413121200cb7010b413321200cb6010b413321200cb5010b413221200cb4010b413b21200cb3010b413521200cb2010b413a21200cb1010b413a21200cb0010b41800121200caf010b413a21200cae010b413c21200cad010b41f30021200cac010b41f30021200cab010b413c21200caa010b41c10021200ca9010b41c10021200ca8010b413d21200ca7010b41f20021200ca6010b413f21200ca5010b41c00021200ca4010b41c10021200ca3010b41ef0021200ca2010b41ef0021200ca1010b41c10021200ca0010b41ef0021200c9f010b41c10021200c9e010b41f00021200c9d010b41c20021200c9c010b41c20021200c9b010b41c30021200c9a010b41c40021200c99010b41c50021200c98010b41e50021200c97010b41e40021200c96010b41c80021200c95010b41c80021200c94010b41cc0021200c93010b41c80021200c92010b41c90021200c91010b41ca0021200c90010b41cb0021200c8f010b41ce0021200c8e010b41d00021200c8d010b41db0021200c8c010b41da0021200c8b010b41d30021200c8a010b41d50021200c89010b41d70021200c88010b41d90021200c87010b41e30021200c86010b41e20021200c85010b41e20021200c84010b41e10021200c83010b41e80021200c82010b41eb0021200c81010b41ee0021200c80010b41f60021200c7f0b41f50021200c7e0b41f90021200c7d0b41f80021200c7c0b41fc0021200c7b0b41fb0021200c7a0b41ff0021200c790b41820121200c780b41890121200c770b41820121200c760b41890121200c750b41830121200c740b41890121200c730b41830121200c720b41840121200c710b41890121200c700b41840121200c6f0b41890121200c6e0b41950121200c6d0b41870121200c6c0b418e0121200c6b0b41890121200c6a0b41890121200c690b41890121200c680b41890121200c670b418d0121200c660b418f0121200c650b41940121200c640b41990121200c630b419b0121200c620b41a50121200c610b41ad0221200c600b41a60121200c5f0b41a10221200c5e0b41a70121200c5d0b41a90121200c5c0b41ab0121200c5b0b41ac0121200c5a0b418d0221200c590b418c0221200c580b41b10121200c570b41b20121200c560b41b20121200c550b41bb0121200c540b41b20121200c530b41ef0121200c520b41b40121200c510b41b50121200c500b41800221200c4f0b41ea0121200c4e0b41b80121200c4d0b41b80121200c4c0b41b90121200c4b0b41e10121200c4a0b41b90121200c490b41e10121200c480b41b90121200c470b41ba0121200c460b41bf0121200c450b41bd0121200c440b41c10121200c430b41c10121200c420b41c20121200c410b41c30121200c400b41c40121200c3f0b41c60121200c3e0b41d90121200c3d0b41d80121200c3c0b41ca0121200c3b0b41cb0121200c3a0b41cb0121200c390b41cc0121200c380b41cc0121200c370b41d00121200c360b41cd0121200c350b41d60121200c340b41cd0121200c330b41cd0121200c320b41d30121200c310b41d30121200c300b41dd0121200c2f0b41db0121200c2e0b41db0121200c2d0b41dd0121200c2c0b41dd0121200c2b0b41e90121200c2a0b41e80121200c290b41e70121200c280b41e80121200c270b41ec0121200c260b41fe0121200c250b41fd0121200c240b41ee0121200c230b41ee0121200c220b41ef0121200c210b41f30121200c200b41f30121200c1f0b41f40121200c1e0b41f60121200c1d0b41f40121200c1c0b41f70121200c1b0b41fa0121200c1a0b41ff0121200c190b41ff0121200c180b41820221200c170b41840221200c160b418b0221200c150b418a0221200c140b41890221200c130b41880221200c120b419f0221200c110b41920221200c100b41920221200c0f0b41950221200c0e0b41950221200c0d0b41960221200c0c0b41980221200c0b0b41960221200c0a0b41990221200c090b419c0221200c080b41a20221200c070b41a20221200c060b41ac0221200c050b41ab0221200c040b41aa0221200c030b41ab0221200c020b41b40221200c010b41b30221200c000b0b930504057f017e017f047e230041206b22032400024002400240411810002204450d002003200436021020034218370214200341106a41d2abc20041181029200341086a220420032802183602002003200329031037030020002003101b20042802002105200328020421062003280200210742002108200341106a41086a220942003703002003420037031020072005200341106a10022004200929030037030020032003290310370300024002402003411041b8d6c200410041001004417f460d00200342003703182003420037031020034110200341106a4110410010042204417f460d012004410f4d0d01200341186a290300210a200329031021082006450d040c030b4200210a20060d020c030b41b2eac10041331040000b411841011019000b200710010b0240411410002204450d002003200436021020034214370214200341106a41d7aac20041141029200341086a220420032802183602002003200329031037030020002003101b2004280200210520032802042106200328020021074200210b200341106a41086a220942003703002003420037031020072005200341106a100220042009290300370300200320032903103703000240024002402003411041b8d6c200410041001004417f460d00200342003703182003420037031020034110200341106a4110410010042204417f460d022004410f4d0d02200341186a290300210c2003290310210b0c010b4200210c0b2002200a2008200156200a200256200a2002511b22041b210d2001200820041b210202402006450d00200710010b2000200b20027c2201200c200d7c2001200b54ad7c10b4022000200820027d200a200d7d2008200254ad7d10b502200341206a24000f0b41b2eac10041331040000b411441011019000b3400200041f991c20036020420004100360200200041086a4207370200200041106a41b4d5c000360200200041146a41143602000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a418ce0c000360200200041206a41093602000b13002000410436020420004184e7c0003602000ba40803057f037e047f230041206b22032400024002400240024002400240024002402002280208220420014d0d00200241086a2004417f6a22053602002002280200220620054105746a22072900002108200729000821092007290010210a200620014105746a220141186a200741186a2900003700002001200a37001020012009370008200120083700002002280204210b024002400240024002402005413f4b0d004101210741011000220c450d08200c20054102743a00004101210120050d010c020b02402005418080014f0d004102210741021000220c450d09200c20054102744101723b00000c010b024020054180808080044f0d004104210741041000220c450d0a200c20054102744102723600000c010b410110002202450d0a200241033a00004105210741051000220c450d0b200c20022d00003a000020021001200c20053600010b200441057441606a210d200721012006210403402004210502400240024002402007200122026b41204f0d00200241206a22012002490d0620074101742204200120012004491b22044100480d062007450d0120041000220e450d07200e200c20042007200720044b1b10ce022107200c10012007210c0c020b200241206a21010c020b20041000220c450d050b200421070b200541206a2104200c20026a22022005290000370000200241186a200541186a290000370000200241106a200541106a290000370000200241086a200541086a290000370000200d41606a220d0d000b0b200341106a41086a220542003703002003420037031041d18ec200410e200341106a1002200341086a20052903003703002003200329031037030020034110200c2001100302402007450d00200c10010b0240200b450d00200610010b411310002205450d032003200536021020034213370214200341106a41d1a3c20041131029200341086a220520032802183602002003200329031037030020002003101b200528020021072003280204210120032802002102200341106a41086a220c42003703002003420037031020022007200341106a10022005200c2903003703002003200329031037030020034110100a02402001450d00200210010b411410002205450d042003200536021020034214370214200341106a41aba3c20041141029200341086a220520032802183602002003200329031037030020002003101b200528020021072003280204210120032802002102200341106a41086a220c42003703002003420037031020022007200341106a10022005200c2903003703002003200329031037030020034110100a02402001450d00200210010b200341206a24000f0b1018000b200441011019000b41a4d5c00020012004104a000b411341011019000b411441011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000bc35b05077f017e047f0c7e027f230041b0016b22022400200241003a009001410121032001200128020822042001280200200128020420024190016a41012004100441016a220541014b6a220436020802400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020054102490d000240024020022d0090012205450d0020054101460d010c020b200141046a2802002105410021032002410036029001200141086a41002001280200200520024190016a41042004100422052005417f461b22054104200541044922051b20046a220436020020050d0120022802900121060b200241003a009001200141086a20042001280200200141046a28020020024190016a41012004100441016a220541014b6a220436020020054102490d3220022d009001220541094b0d32024020050e0a00020304050809060a07000b41002105200241003a009001200141086a20042001280200200141046a28020020024190016a41012004100441016a220141014b6a36020020014102490d32024020022d0090012201450d0020014101462201450d334101410220011b21050b200220022f0190013b010c2005410171210741002108420021090c310b20004102360270200241b0016a24000f0b200241003a009001200141086a20042001280200200141046a28020020024190016a41012004100441016a220541014b6a220436020020054102490d3020022d0090012205450d0b20054101460d0c20054102470d30200241d0006a41186a220a4200370300200241e0006a4200370300200241d0006a41086a220b420037030020024200370350200141086a220c41002001280200200141046a220d280200200241d0006a41202004100422052005417f461b2205412020054120491b20046a22043602002005411f4d0d30200b290300210e2002290350210f20022903602110200241f0006a41186a200a29030037030020022010370380012002200e3703782002200f370370200a4200370300200b42003703002002420037036020024200370350200c41002001280200200d280200200241d0006a41202004100422052005417f461b22054120200541204922051b20046a220436020020050d30200241d0006a41086a220a290300210e2002290350210f2002290360211020024190016a41186a200241d0006a41186a290300370300200220103703a0012002200e370398012002200f370390012002420037035820024200370350200141086a220b41002001280200200141046a220c280200200241d0006a41102004100422052005417f461b2205411020054110491b20046a22043602002005410f4d0d30200a2903002111200229035021122002420037035820024200370350200b41002001280200200c280200200241d0006a41102004100422012001417f461b2201411020014110491b20046a3602002001410f4d0d30200241d0006a41086a290300211320022903502114200241306a41186a200241f0006a41186a290300370300200241306a41106a200241f0006a41106a290300370300200241306a41086a200241f0006a41086a290300370300200241106a41086a20024190016a41086a290300370300200241106a41106a20024190016a41106a290300370300200241106a41186a20024190016a41186a29030037030020022002290370370330200220022903900137031020023502302002330134200231003642108684422086842109200241236a3500002115200241cf006a31000021102002413f6a290000210f200229001b2116200229004721172002290037210e200231002f2118200229002721192002280017210b2002280013210520022f0011211a20022d0010210d4102210c0c0d0b200241003a009001200141086a20042001280200220a200141046a280200220b20024190016a41012004100441016a220541014b6a220436020020054102490d2f20022d0090010d2f2002420037039001200141086a4100200a200b20024190016a41082004100422012001417f461b2201410820014108491b20046a360200200141074d0d2f200229039001210e200220022f0190013b010c200e4208882109200ea7210c410221080c290b200241003a009001200141086a20042001280200220a200141046a280200220b20024190016a41012004100441016a220541014b6a220436020020054102490d2e20022d0090012205450d0c20054101460d0d20054102470d2e200241d0006a41186a22054200370300200241d0006a41106a4200370300200241d0006a41086a220c420037030020024200370350200141086a220d4100200a200b200241d0006a41202004100422012001417f461b2201412020014120491b20046a22043602002001411f4d0d2e200c290300210e2002290350210f2002290360211020024190016a41186a2005290300370300200220103703a0012002200e370398012002200f370390012002420037035820024200370350200d4100200a200b200241d0006a41102004100422012001417f461b22014110200141104922011b20046a36020020010d2e200241d0006a41086a290300210e20022903502111200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a29030037030020022002290390013703702011422088200e422086842116200e4220882115200235027020023301742002310076421086844220868421092002418f016a3100002110200241ff006a290000210f20022900870121172002290077210e2011a7210b4102210c0c0e0b200241003a009001200141086a20042001280200200141046a28020020024190016a41012004100441016a220541014b6a220436020020054102490d2d20022d009001220541054b0d2d024020050e06002021222324000b200141046a220b28020021052002410036029001200141086a220c41002001280200200520024190016a41042004100422052005417f461b2205410420054104491b20046a220a360200200541034d0d2d200228029001210420024200370398012002420037039001200c41002001280200200b28020020024190016a4110200a100422052005417f461b2205411020054110491b200a6a3602002005410f4d0d2d20024198016a2903002110200229039001211720024190016a200110392002280290012201450d2d200229029401220e422088210f200e4220862001ad84210e2010422088a721052010421088a7211a2010420888a7210d4100210c0c240b200241003a009001200141086a20042001280200200141046a28020020024190016a41012004100441016a220541014b6a220436020020054102490d2c20022d009001220541044b0d2c024020050e050019141517000b200241d0006a41186a220a4200370300200241e0006a4200370300200241d0006a41086a220b420037030020024200370350200141086a220c41002001280200200141046a220d280200200241d0006a41202004100422052005417f461b2205412020054120491b20046a22043602002005411f4d0d2c200b290300210f2002290350210e20022903602110200241f0006a41186a200a290300220937030020022010370380012002200f3703782002200e370370200d28020021052002410036029001200c41002001280200200520024190016a41042004100422052005417f461b22054104200541044922051b20046a220436020020050d2c2002280290012107200241d0006a41186a220a4200370300200241e0006a4200370300200241d0006a41086a220b420037030020024200370350200141086a220c41002001280200200141046a220d280200200241d0006a41202004100422052005417f461b2205412020054120491b20046a22043602002005411f4d0d2c200b2903002117200229035021102002290360211120024190016a41186a200a2903002212370300200220113703a00120022017370398012002201037039001200d280200210520024100360250200c410020012802002005200241d0006a41042004100422012001417f461b2201410420014104491b20046a360200200141034d0d2c200e421888200f42288684211120094218882109200e420888a7210a200ea721012010422888201742188684a7211a2010423888201742088684a72105201242188821122010420888a7210c2010422088a7210d2017421888a7210b2002280250211b200241a7016a350000211520024183016a290000210f200229009f012116200229007b210e2010a7210841002104420021100c280b200241003a009001200141086a20042001280200220a200141046a280200220b20024190016a41012004100441016a220541014b6a220436020020054102490d2b20022d0090010d2b200241d0006a41186a220c4200370300200241e0006a4200370300200241d0006a41086a220d420037030020024200370350200141086a22074100200a200b200241d0006a41202004100422052005417f461b2205412020054120491b20046a22043602002005411f4d0d2b200d290300210e2002290350210f20022903602110200241f0006a41186a200c29030037030020022010370380012002200e3703782002200f370370200c4200370300200d4200370300200242003703602002420037035020074100200a200b200241d0006a41202004100422052005417f461b22054120200541204922051b20046a220436020020050d2b200241d0006a41086a2205290300210e2002290350210f2002290360211020024190016a41186a220c200241d0006a41186a290300370300200220103703a0012002200e370398012002200f37039001420021112002420037035820024200370350200141086a4100200a200b200241d0006a41102004100422012001417f461b2201411020014110491b20046a3602002001410f4d0d2b2005290300210e20022903502114200241306a41186a2201200241f0006a41186a290300370300200241306a41106a2204200241f0006a41106a290300370300200241306a41086a2205200241f0006a41086a290300370300200241106a41086a220a20024190016a41086a290300370300200241106a41106a220b20024190016a41106a290300370300200241106a41186a220d200c2903003703002002200229037037033020022002290390013703102004310000211020052903002117200d2903002112200b2903002118200a29030021192001280200210b2002280244210520022f0142211a20022d0041210d200235024c2116200229031021132002290330210f200220143703502002200f3703602002200e370358200220022f0190013b010c2014420888210920134220882115201620134220868421162014a7210c410921080c240b200241003a009001200141086a20042001280200220a200141046a280200220b20024190016a41012004100441016a220541014b6a220436020020054102490d2a20022d009001220541034b0d2a024020050e04000c0d0e000b200241d0006a41186a22054200370300200241e0006a4200370300200241d0006a41086a220c420037030020024200370350200141086a220d4100200a200b200241d0006a41202004100422012001417f461b2201412020014120491b20046a22043602002001411f4d0d2a200c290300210e2002290350210f20022903602110200241f0006a41186a200529030037030020022010370380012002200e3703782002200f37037020054200370300200c42003703002002420037036020024200370350200d4100200a200b200241d0006a41202004100422012001417f461b22014120200141204922011b20046a36020020010d2a200241d0006a41086a290300210f2002290350210e20022903602110200241106a41186a200241d0006a41186a2903002209370300200241306a41086a200241f0006a41086a290300370300200241306a41106a200241f0006a41106a290300370300200241306a41186a200241f0006a41186a290300370300200220103703202002200f3703182002200e37031020022002290370370330200f422886200e421888842110200e422886200235004b200241cf006a31000042208684842117200e423888200f42088684a72105200e422888200f42188684a7211a20094218882119200e422088a7210d200f421888a7210b200241276a3500002115200241c3006a290000210f200229001f2116200229003b210e200228003721072002280033210c20022f0031210a20022d00302101410021040c0f0b200241003a009001200141086a20042001280200200141046a28020020024190016a41012004100441016a220541014b6a220a3602004102210420054102490d0220022d0090012205450d0120054101470d02200241d0006a41186a220b4200370300200241e0006a4200370300200241d0006a41086a220c420037030020024200370350200141086a220d41002001280200200141046a2207280200200241d0006a4120200a100422052005417f461b2205412020054120491b200a6a220a3602002005411f4d0d02200c290300210e2002290350210f2002290360211020024190016a41186a200b290300370300200220103703a0012002200e370398012002200f370390012007280200210520024100360250200d410020012802002005200241d0006a4104200a100422052005417f461b22054104200541044922051b200a6a220a36020020050d022002280250210c200141046a220b280200210520024100360250200141086a220d410020012802002005200241d0006a4104200a100422052005417f461b2205410420054104491b200a6a220a360200200541034d0d0220022802502105200b280200210b20024100360250200d41002001280200200b200241d0006a4104200a100422012001417f461b2201410420014104491b200a6a360200200141034d0d022002280250210b200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a2903003703002002200229039001370370200235008b012002418f016a31000042208684211020024183016a290000210f200229007b210e2002290073211120022f0071210a20022d00702101410121040c030b200241003a009001200141086a20042001280200200141046a28020020024190016a41012004100441016a220541014b6a220436020020054102490d2820022d009001220541044b0d28024020050e050016171814000b200141046a28020021054100210c2002410036029001200141086a41002001280200200520024190016a41042004100422012001417f461b2201410420014104491b20046a360200200141034d0d2820022802900121014200210942002116420021150c190b200241d0006a41186a220b4200370300200241e0006a4200370300200241d0006a41086a220c420037030020024200370350200141086a220d41002001280200200141046a2207280200200241d0006a4120200a100422052005417f461b2205412020054120491b200a6a220a3602002005411f4d0d00200c290300210e2002290350210f20022903602110200241306a41186a200b290300370300200220103703402002200e3703382002200f370330200728020021052002410036029001200d41002001280200200520024190016a4104200a100422052005417f461b22054104200541044922051b200a6a220a36020020050d00200228029001210c200141046a220b28020021052002410036029001200141086a220d41002001280200200520024190016a4104200a100422052005417f461b2205410420054104491b200a6a220a360200200541034d0d002002280290012105200b280200210b2002410036029001200d41002001280200200b20024190016a4104200a100422012001417f461b2201410420014104491b200a6a360200200141034d0d00200228029001210b200241106a41186a200241306a41186a290300370300200241106a41106a200241306a41106a290300370300200241106a41086a200241306a41086a29030037030020022002290330370310200235002b2002412f6a310000422086842110200241236a290000210f200229001b210e2002290013211120022f0011210a20022d00102101410021040c010b0b2002200c3602582002201037035020044102460d25200241d0006a41086a310000211020022903502117200220022f01503b010c20114208882109200c410876210d200c411076211a2011a7210c410621080c0b0b200241e8006a220a4200370300200241e0006a4200370300200241d0006a41086a220b420037030020024200370350200141086a220c41002001280200200141046a220d280200200241d0006a41202004100422052005417f461b2205412020054120491b20046a22043602002005411f4d0d24200a290300210e200b29030021102002290360210f20022903502109200d28020021052002410036029001200c41002001280200200520024190016a41042004100422052005417f461b22054104200541044922051b20046a220436020020050d242002280290012105200241003a009001200141086a20042001280200200141046a28020020024190016a41012004100441016a220141014b6a36020020014102490d2420022d009001220d41034f0d242002200f3703800120024188016a200e3703002002201037037820022009370370200f423888200e420886842117200e4238882110200241ff006a290000210f2002290077210e4100210c0c010b200241d0006a41186a22054200370300200241e0006a4200370300200241d0006a41086a220a420037030020024200370350200141086a41002001280200200141046a280200200241d0006a41202004100422012001417f461b2201412020014120491b20046a3602002001411f4d0d23200a2903002110200229035021092002290360210e20024190016a41186a2005290300220f3703002002200e3703a00120022010370398012002200937039001200e423888200f420886842117200f42388821102002419f016a290000210f200229009701210e4101210c0b200220022f0190013b010c410121080c1c0b4200210920024200370378200242003703704100210c200141086a4100200a200b200241f0006a41102004100422012001417f461b2201411020014110491b20046a3602002001410f4d0d21200241f0006a41086a290300210f2002290370210e20022903a0012211422088200241a8016a29030022104220868421162010422088211520024190016a41086a31000021102002290390012117200228029c01210520022f019a01211a20022d009901210d2011a7210b0c010b200241d0006a41186a22054200370300200241e0006a4200370300200241d0006a41086a220c420037030020024200370350200141086a220d4100200a200b200241d0006a41202004100422012001417f461b2201412020014120491b20046a22043602002001411f4d0d20200c290300210e2002290350210f20022903602110200241306a41186a2005290300370300200220103703402002200e3703382002200f3703302002410036029001200d4100200a200b20024190016a41042004100422012001417f461b22014104200141044922011b20046a36020020010d202002280290012105200241106a41186a200241306a41186a290300370300200241106a41106a200241306a41106a290300370300200241106a41086a200241306a41086a29030037030020022002290330370310200235021020023301142002310016421086844220868421092002412f6a31000021102002411f6a290000210f200229002721172002290017210e420021164101210c420021150b200220022f0190013b010c410321080c170b42002110200241d0006a41186a22054200370300200241e0006a4200370300200241d0006a41086a220c420037030020024200370350200141086a4100200a200b200241d0006a41202004100422012001417f461b2201412020014120491b20046a3602002001411f4d0d1e200c290300210e200229035021092002290360210f20024190016a41186a200529030022113703002002200f3703a0012002200e3703980120022009370390012009423888200e42088684a72107201142188821172009421888a7210c2009420888a7210a200241a3016a290000210f200229009b01210e2009a72101410121040c030b2002410036029001200141086a4100200a200b20024190016a41042004100422012001417f461b2201410420014104491b20046a360200200141034d0d1d200228029001210c410221040c010b20024190016a20011039200228029001220c450d1c200229029401210e20024190016a20011039200ea721072002280290012201450d17200229029401220f42808080807083200f4220862001ad84221042208884210f2010422086200e42208884210e410321040b0b200220022f0190013b010c2007ad422086200cad844208882109410521080b0c160b42002110200241d0006a41186a22054200370300200241e0006a4200370300200241d0006a41086a220a420037030020024200370350200141086a41002001280200200141046a280200200241d0006a41202004100422012001417f461b2201412020014120491b20046a3602002001411f4d0d18200a290300210e200229035021122002290360210f200241106a41186a200529030022093703002002200f3703202002200e370318200220123703102012421888200e422886842111200942188821092012420888a7210a200241236a290000210f200229001b210e2012a72101410221040c010b42002110200241d0006a41186a22054200370300200241e0006a4200370300200241d0006a41086a220a420037030020024200370350200141086a41002001280200200141046a280200200241d0006a41202004100422012001417f461b2201412020014120491b20046a3602002001411f4d0d17200a290300210e200229035021122002290360210f200241306a41186a200529030022093703002002200f3703402002200e370338200220123703302012421888200e422886842111200942188821092012420888a7210a200241c3006a290000210f200229003b210e2012a72101410321040b0c120b200241d0006a41186a220a4200370300200241e0006a4200370300200241d0006a41086a220b420037030020024200370350200141086a220c41002001280200200141046a220d280200200241d0006a41202004100422052005417f461b2205412020054120491b20046a22043602002005411f4d0d15200b290300210e2002290350210f2002290360211020024190016a41186a200a290300370300200220103703a0012002200e370398012002200f37039001200241003a0050200c20042001280200200d280200200241d0006a41012004100441016a220141014b6a36020020014102490d1520022d00502108200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a2903003703002002200229039001370370200235008b012002418f016a31000042208684210920024183016a290000210f200229007b210e2002290073211120022f0071210a20022d0070210141042104420021100c110b4200210920024200370378200242003703704104210c200141086a41002001280200200141046a280200200241f0006a41102004100422012001417f461b2201411020014110491b20046a3602002001410f4d0d14200241f0006a41086a290300210f2002290370210e20022903a0012211422088200241a8016a29030022104220868421162010422088211520024190016a41086a31000021102002290390012117200228029c01210520022f019a01211a20022d009901210d2011a7210b0c040b200241e8006a220a4200370300200241e0006a4200370300200241d0006a41086a220b420037030020024200370350200141086a220c41002001280200200141046a220d280200200241d0006a41202004100422052005417f461b2205412020054120491b20046a22043602002005411f4d0d13200a290300210e200b290300210f2002290360211020022903502117200a4200370300200b42003703002002420037036020024200370350200c41002001280200200d280200200241d0006a41202004100422052005417f461b2205412020054120491b20046a22043602002005411f4d0d13200241d0006a41086a2903002109200229035021112002290360211220024190016a41186a200241d0006a41186a290300370300200220123703a00120022009370398012002201137039001200241003a0050200141086a220a20042001280200200141046a220b280200200241d0006a41012004100441016a220541014b6a220436020020054102490d1320023100502109200b280200210520024100360250200a410020012802002005200241d0006a41042004100422052005417f461b2205410420054104491b20046a2204360200200541034d0d1320022802502107200141046a280200210520024100360250200141086a410020012802002005200241d0006a41042004100422012001417f461b2201410420014104491b20046a360200200141034d0d132002280250211b20024188016a200e3703002002201037038001200220173703702002200f3703782017421888200f42288684211120094228862110200e421888210920023500ab01200241af016a31000042208684211220022f00910120022d00930141107472210c2017420888a7210a200241a7016a3500002115200229009f01211620022d009001210820022d009401210d20022f009501211a2002280097012105200228009b01210b20024183016a290000210f200229007b210e2017a72101410121040c0f0b4200210920024200370398012002420037039001200141086a41002001280200200141046a28020020024190016a41102004100422012001417f461b2201411020014110491b20046a3602002001410f4d0d1220024190016a41086a290300210f200229039001210e20022903202211422088200241286a290300221042208684211620104220882115200241106a41086a310000211020022903102117200228021c210520022f011a211a20022d0019210d2011a7210b4101210c0c020b200141046a220a28020021052002410036029001200141086a220b41002001280200200520024190016a41042004100422052005417f461b2205410420054104491b20046a2204360200200541034d0d11200228029001210520024200370398012002420037039001200b41002001280200200a28020020024190016a411020041004220a200a417f461b220a4110200a4110491b20046a2204360200200a410f4d0d1120024190016a41086a290300210e2002290390012111200241d0006a41186a220a4200370300200241d0006a41106a4200370300200241d0006a41086a220b420037030020024200370350200141086a41002001280200200141046a280200200241d0006a41202004100422012001417f461b2201412020014120491b20046a3602002001411f4d0d11200b29030021092002290350210f20022903602110200241306a41186a200a290300221237030020022010370340200220093703382002200f3703302011422088200e42208684211620104238882012420886842117200f42ffffff07832109200e422088211520124238882110200f421888a721012002413f6a290000210f2002290037210e2011a7210b4102210c0c020b4200210920024200370398012002420037039001200141086a41002001280200200141046a28020020024190016a41102004100422012001417f461b2201411020014110491b20046a3602002001410f4d0d1020024190016a41086a290300210f200229039001210e200229038001221142208820024188016a290300221042208684211620104220882115200241f0006a41086a310000211020022903702117200228027c210520022f017a211a20022d0079210d2011a7210b4103210c0b0b200220022f0190013b010c2001ad4218862009842109410821080c060b200141046a220b28020021052002410036029001200141086a220c41002001280200200520024190016a41042004100422052005417f461b2205410420054104491b20046a220a360200200541034d0d0d2002280290012104200241003a009001200c200a2001280200200b28020020024190016a4101200a100441016a220141014b6a36020020014102490d0d20022d009001220141034f0d0d200241c8006a2903002210422088a721052010421088a7211a2010420888a7210d200241386a290300210f200229034021172002290330210e4101210c0c040b200141046a28020021052002410036029001200141086a41002001280200200520024190016a41042004100422012001417f461b2201410420014104491b20046a360200200141034d0d0c200228029001210420024188016a2903002210422088a721052010421088a7211a2010420888a7210d200241f0006a41086a290300210f20022903800121172002290370210e4102210c0c030b200141046a280200210520024100360270200141086a410020012802002005200241f0006a41042004100422012001417f461b2201410420014104491b20046a3602004103210c200141034d0d0b20022802702104200241a8016a2903002210422088a721052010421088a7211a2010420888a7210d20024190016a41086a290300210f20022903a0012117200229039001210e0c020b4104210c200141046a28020021054100210d2002410036029001200141086a41002001280200200520024190016a41042004100422012001417f461b2201410420014104491b20046a360200200141034d0d0a20022802900121044100211a410021050c010b200141046a220b28020021052002410036029001200141086a220c41002001280200200520024190016a41042004100422052005417f461b2205410420054104491b20046a220a360200200541034d0d092002280290012104200241003a009001200c200a2001280200200b28020020024190016a4101200a100441016a41014b22016a3602002001450d0920022d0090012101200241e8006a2903002210422088a721052010421088a7211a2010420888a7210d200241d8006a290300210f200229036021172002290350210e4105210c0b200220022f0190013b010c2004ad4218862001ad42ff0183842109410421080b0b0b0c030b2007450d04200c10010c040b200220022f0190013b010c200cad4230862008ad42ff018342288684200942ffffffffff1f83842117201142088821092010201242ffffffffff1f83842119201bad4220862007ad842118200c411076ad21102011a7210c410721080b0b0b200220022f010c221b3b010e2002201b3b010a200041186a200f3700002000200e370010200041286a20103c0000200020173700202000413c6a20153e000020002016370034200041d8006a201137000020002012370050200041e8006a201337000020002014370060200020073a0001200020083a0000200020043a0004200020013a00052000200a3b000620002009420886200cad42ff0183843700082000200d3a00292000201a3b002a2000200536002c2000200b3600302000201937004020002018370048200020022f010a3b00022000200636027420002003360270200241b0016a24000f0b200220022f010c3b010e20004102360270200241b0016a24000b940201067f23004180016b220124000240411310002202450d002001200236020020014213370204200141eaabc20041131029200141f0006a41086a22022001280208360200200120012903003703702000200141f0006a101b200228020021032001280274210420012802702105200141086a220642003703002001420037030020052003200110022002200629030037030020012001290300370370200141f0006a4110100a02402004450d00200510010b200641013a0000200141096a2000290000370000200141116a200041086a290000370000200141196a200041106a290000370000200141216a200041186a290000370000200141013a0000200110a10120014180016a24000f0b411341011019000bbf0c030a7f057e047f23004190016b220224000240024002400240024002400240411210002203450d002002200336027020024212370274200241f0006a418cd2c200411210292002280270210302400240024020022802742204200228027822056b41044f0d00200541046a22062005490d0420044101742207200620062007491b22074100480d042004450d01200710002208450d072008200320072004200420074b1b10ce0221082003100120072104200821030c020b200541046a21060c010b200710002203450d05200721040b200320056a2001360000200241f0006a41086a220542003703002002420037037020032006200241f0006a1002200241086a200529030037030020022002290370370300024002402002411041b8d6c200410041001004417f460d00200241f0006a41186a22064200370300200241f0006a41106a42003703002005420037030020024200370370410020024110200241f0006a41204100100422052005417f461b220141204922080d04200241d0006a41186a22092006290300370300200241d0006a41106a220a200241f0006a41106a2207290300370300200241d0006a41086a220b200241f0006a41086a22052903003703002002200229037037035020062009290300220c3703002007200a290300220d3703002005200b290300220e370300200241106a41086a200e370300200241106a41106a200d370300200241106a41186a200c37030020022002290350220c3703102002200c3703702002420037037820024200370370410020024110200241f0006a41102001412020081b2201100422062006417f461b2206410f4d0d052005290300210c2002290370210d200241f0006a41186a2208420037030020074200370300200542003703002002420037037020024110200241f0006a41202006411020064110491b20016a220510042206417f460d012006411f4d0d01200241d0006a41186a2206200241f0006a41186a2207290300370300200241d0006a41106a2201200241f0006a41106a2208290300370300200241d0006a41086a2209200241f0006a41086a220a2903003703002002200229037037035020072006290300220e37030020082001290300220f370300200a20092903002210370300200241306a41086a2010370300200241306a41106a200f370300200241306a41186a200e37030020022002290350220e3703302002200e370370200242003703782002420037037020024110200241f0006a4110200541206a10042205417f460d052005410f4d0d05200241f0006a41086a2205290300210e2002290370210f200241f0006a41186a220b200241106a41186a2206290300370300200241f0006a41106a2211200241106a41106a22072903003703002005200241106a41086a2201290300370300200241d0006a41086a2212200241306a41086a2208290300370300200241d0006a41106a2213200241306a41106a2209290300370300200241d0006a41186a2214200241306a41186a220a2903003703002002200229031037037020022002290330370350200a200b29030037030020092011290300370300200820052903003703002001201229030037030020072013290300370300200620142903003703002002200229037037033020022002290350370310200041206a200e370300200041186a200f370300200041106a200c3703002000200d370308200041286a2002290330370300200041306a2008290300370300200041386a2009290300370300200041c0006a200a290300370300200041c8006a2002290310370300200041d0006a2001290300370300200041d8006a2007290300370300200041e0006a2006290300370300200042013703002004450d080c070b2000420037030020040d060c070b2008200241d0006a41186a290000370300200241f0006a41106a200241d0006a41106a290000370300200241f0006a41086a200241d0006a41086a2900003703002002200229005037037041b2eac10041331040000b411241011019000b1018000b2006200241d0006a41186a290000370300200241f0006a41106a200241d0006a41106a290000370300200241f0006a41086a200241d0006a41086a290000370300200220022900503703700b41b2eac10041331040000b200741011019000b200310010b20024190016a24000b340020004182aec20036020420004100360200200041086a4206370200200041106a41c4e9c000360200200041146a410a3602000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a41b8d6c200360200200041206a41003602000b3400200041d2b0c20036020420004100360200200041086a4208370200200041106a41a4eec000360200200041146a410b3602000bad06010b7f230041206b220224000240024002400240024002400240411010002203450d002002200336021020024210370214200241106a419db0c20041101029200228021021040240024002400240024020022802142205200228021822036b41044f0d00200341046a22062003490d0320054101742207200620062007491b22084100480d032005450d01200810002207450d062007200420082005200520084b1b10ce02210520041001200521040c020b200341046a2106200521080c010b200810002204450d040b200420036a20003600002001280200210902400240024020012802082203413f4b0d004101210041011000220a450d07200a20034102743a00004101210720030d010c020b02402003418080014f0d004102210041021000220a450d08200a20034102744101723b00000c010b024020034180808080044f0d004104210041041000220a450d09200a20034102744102723600000c010b410110002205450d09200541033a00004105210041051000220a450d0a200a20052d00003a000020051001200a20033600010b2003410574210b2000210703402009210302400240024002402000200722056b41204f0d00200541206a22072005490d0620004101742209200720072009491b22094100480d062000450d0120091000220c450d07200c200a20092000200020094b1b10ce022100200a10012000210a0c020b200541206a21070c020b20091000220a450d050b200921000b200341206a2109200a20056a22052003290000370000200541186a200341186a290000370000200541106a200341106a290000370000200541086a200341086a290000370000200b41606a220b0d000b0b200241106a41086a220342003703002002420037031020042006200241106a1002200241086a20032903003703002002200229031037030020024110200a2007100302402000450d00200a10010b02402008450d00200410010b0240200141046a280200450d00200128020010010b200241206a24000f0b1018000b200941011019000b411041011019000b200841011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a41d0f5c000360200200041206a41023602000b34002000418dc1c20036020420004100360200200041086a4209370200200041106a41c0f7c000360200200041146a41013602000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a41fcf7c000360200200041206a41053602000b130020004103360204200041dcfbc0003602000b3400200041c9cbc20036020420004100360200200041086a4208370200200041106a41e0ffc000360200200041146a41083602000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a418884c100360200200041206a41053602000b130020004105360204200041b888c1003602000b340020004192d7c20036020420004100360200200041086a420d370200200041106a41948bc100360200200041146a41073602000b4b0020004181d9c20036020420004100360200200041086a4206370200200041106a4187d9c200360200200041146a42043702002000411c6a41b88ec100360200200041206a41053602000b130020004102360204200041e891c1003602000b3601017f02402002450d00200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000b0b20000b6901017f02400240200120004f0d002002450d010340200020026a417f6a200120026a417f6a2d00003a00002002417f6a22020d000c020b0b2002450d00200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000b0b20000b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b4401037f024002402002450d00410021030340200020036a2d00002204200120036a2d00002205470d02200341016a22032002490d000b41000f0b41000f0b200420056b0b3e01017f230041106b2205240020052001200220032004410010d302200529030021012000200541086a29030037030820002001370300200541106a24000bd80502037f067e230041306b220624000240024002400240024002400240024002400240024002400240024002400240024020024200510d002003500d012004500d03200479a7200279a76b2207413f4b0d0241ff0020076b2108200741016a21070c0c0b200450450d012005450d0520034200510d0c20054200370308200520012003823703000c060b2004500d0b20014200510d032004427f7c2209200483500d07200479a7200279a76b2207413e4d0d090b2005450d012005200137030020052002370308420021010c070b2003427f7c2209200383500d044100200379a741c1006a200279a76b22076b21080c080b420021010c050b02402005450d0020054200370300200520022004823703080b200220048021010c040b20034200510d060b200120038021010c020b02402005450d0020054200370308200520092001833703000b20034201510d07200641206a2001200220037aa710d902200641286a2903002102200629032021010c070b02402005450d0020052001370300200520092002833703080b200220047a423f838821010b420021020c050b41ff0020076b2108200741016a21070b200620012002200841ff007110da02200641106a20012002200741ff007110d902200641086a2903002102200641106a41086a290300210a200629030021012006290310210902402007450d004200210b4200210c0340200a4201862009423f8884220d200d427f8520047c2002423f882009420186842209427f85220d20037c200d54ad7c423f87220d2004837d2009200d200383220e54ad7d210a2009200e7d210920024201862001423f888442008421022001420186200c842101200d420183220d210c2007417f6a22070d000b2005450d030c020b4200210d4200210b20050d010c020b00000b200520093703002005200a3703080b200b20024201862001423f8884842102200d20014201868421010b2000200137030020002002370308200641306a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a10d302200529031021012000200529031837030820002001370300200541206a24000b3c01017f230041106b220524002005200120022003200410d602200529030021012000200541086a29030037030820002001370300200541106a24000b7501027e200020034220882205200142208822067e200320027e7c200420017e7c200342ffffffff0f832203200142ffffffff0f8322017e2204422088200320067e7c22034220887c200342ffffffff0f83200520017e7c22034220887c37030820002003422086200442ffffffff0f83843703000b5701017e02400240200341c000710d002003450d012001410020036b413f71ad8820022003413f71ad220486842102200120048621010c010b20012003413f71ad862102420021010b20002001370300200020023703080b5701017e02400240200341c000710d002003450d0120012003413f71ad2204882002410020036b413f71ad86842101200220048821020c010b20022003413f71ad882101420021020b20002001370300200020023703080b3a01017f230041106b22042400200420012002200310d802200429030021012000200441086a29030037030820002001370300200441106a24000b3a01017f230041106b22042400200420012002200310d702200429030021012000200441086a29030037030820002001370300200441106a24000b0bd59003b20600418080c0000b1d2f636865636b6f75742f7372632f6c6962616c6c6f632f7665632e72730041a080c0000bc09301000010001d000000a80a000025000000000010001d000000ae0a00002c0000002aae100028000000df8510003f00000076000000090000002aae100028000000df8510003f0000007f00000009000000d04a1000640000002201000017000000a24a100025000000004c100012000000124c10000f000000d34b10000a000000dd4b100014000000f14b10000f000000304c1000570000008800000016000000964c10001c000000874c10000f000000a804000009000000b24c10001e000000874c10000f0000005003000009000000804e100022000000030800000a000000e04d10006b000000c800000011000000574f100012000000694f10000c000000994f10000b00000000000000a44f1000100000000000000038ab100000000000000000000000000080011000010000000000000000000000b44f10000f0000000000000038ab1000000000000000000000000000880110000100000000000000d84f100025000000c34f1000150000000050100019000000205010003f00000052000000220000001900000004000000040000001a0000001b0000001c0000008f501000110000000761100013000000f502000005000000e0501000200000008201000013000000e256100006000000e8561000220000001f7a10001400000091070000050000000a57100016000000205710000d0000001f7a10001400000097070000050000008a5910000b000000ec59100016000000c95910000100000078591000120000002e08000009000000ca5910000e000000d859100004000000dc59100010000000c959100001000000785910001200000032080000050000008a5910000b0000009559100026000000bb59100008000000c359100006000000c95910000100000078591000120000003f08000005000000105a10001c0000003100000019000000105a10001c0000003200000020000000105a10001c0000003400000019000000105a10001c0000003500000018000000105a10001c000000360000002000000038ab1000000000002c5a100002000000505a1000120000005704000011000000625a10002b000000d2601000110000005901000015000000505a1000120000004b04000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000f8030000000000000000000000000000000000000000000000000000000000000000feffffffffbfb6000000000000000000ff070000000000f8ffff0000010000000000000000000000c09f9f3d0000000002000000ffffff0700000000000000000000c0ff01000000000000f80f20985a10004a000000e85c100000020000e85e10003700000000010203040506070809080a0b0c0d0e0f10111213140215161718191a1b1c1d1e1f2002020202020202020202210202020202020202020202020202222324252602270228020202292a2b022c2d2e2f300202310202023202020202020202023302023402020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023502360237020202020202020238023902020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023a3b3c020202023d02023e3f4041424344454602020247020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202024802020202020202020202024902020202023b0200010202020203020202020402050602020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202070202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202a060100020000000c0601000120000001900000000000000010000001d00000038ab100000000000d260100011000000e803000005000000e36010002400000007611000130000004b020000090000002aae1000280000002f611000390000005800000008000000306510003900000070651000220000001a0200002d0000000065100022000000090800000e00000000000000787410000400000000000000380a100005000000000000000000000038ab100000000000000000000000000000000000006610000600000000000000b00a100005000000000000000000000038ab100000000000000000000100000000000000c3ac10000600000000000000c9ac1000090000000000000089a01000040000000000000000a910000c00000000000000f0a810000500000000000000f7a510000a000000000000000666100009000000000000000f66100006000000000000001e6610000400000000000000409710000700000000000000c3ac10000600000000000000c9ac10000900000000000000f0a810000500000000000000f7a510000a000000000000000666100009000000000000000f66100006000000000000001566100009000000000000004097100007000000000000001e66100004000000000000004097100007000000000000003c6610000f00000000000000000000004b6610000900000000000000000000000000000000000000bc0d100001000000000000000100000000000000546610000b00000000000000000000005f6610002b00000000000000000000000000000000000000c40d1000010000000000000001000000000000008a6610000900000001000000000000004b6610000900000000000000936610001f00000000000000cc0d100001000000000000000000000000000000b26610000c0000000000000000000000acab10000e00000000000000000000000000000000000000d40d100001000000000000000200000000000000be6610000e0000000000000000000000f7a510000a00000000000000000000000000000000000000dc0d100001000000000000000200000000000000baab10000c0000000000000000000000acab10000e000000000000000000000000000000000000009c2f100001000000000000000200000000000000cc6610000f0000000000000000000000db6610000f00000000000000000000000000000000000000e40d100001000000000000000200000000000000ea661000090000000000000000000000db6610000f00000000000000000000000000000000000000ec0d100001000000000000000200000000000000f3661000100000000100000000000000db6610000f00000000000000036710002c00000000000000f40d1000010000000000000000000000000000002f671000090000000100000000000000db6610000f0000000000000017ac10001100000000000000fc0d100001000000000000000100000000000000386710000600000001000000000000003e6710001f000000000000004cac10000400000000000000040e10000100000000000000000000001b6910003d000000fb68100020000000da68100021000000a168100039000000546810004d000000066810004e000000d467100032000000a76710002d0000007e671000290000005d67100021000000000000008bac10000700000000000000fc0e100003000000000000000000000038ab100000000000000000000000000000000000586910000600000000000000440f100002000000000000000000000038ab10000000000000000000010000000000000092ac10000400000000000000740f100003000000000000000000000038ab1000000000000000000002000000000000005e6910001000000000000000bc0f100002000000000000000000000038ab1000000000000000000003000000000000006e6910001100000000000000ec0f100001000000000000000000000038ab100000000000000000000400000000000000c3ac10000600000000000000c9ac10000900000000000000dfac10000800000000000000eeac10001000000000000000f0a810000500000000000000f7a510000a00000000000000c3ac10000600000000000000c9ac10000900000000000000dfac100008000000000000004b6610000900000000000000c3ac10000600000000000000c9ac100009000000000000007f6910000900000000000000db6610000f0000000000000092a8100010000000000000004cac10000400000000000000dfac10000800000000000000eeac10001000000000000000886910000e00000000000000966910000d000000000000007f6910000900000000000000db6610000f00000000000000cea1100008000000000000003010100003000000000000000000000048101000010000000000000035aa10000900000035aa1000090000002eaa100007000000a36910005d00000000000000006a100006000000000000005811100003000000000000000000000038ab1000000000000000000000000000066a100007000000000000007011100002000000000000000000000038ab10000000000000000000000000000d6a100006000000000000008011100001000000000000000000000038ab1000000000000000000000000000136a100009000000000000008011100001000000000000000000000038ab10000000000000000000000000001c6a100009000000000000008011100001000000000000000000000038ab1000000000000000000000000000a771100008000000000000008811100002000000000000000000000038ab100000000000000000004b661000090000002eaa100007000000c79010000e000000db6610000f000000966910000d000000db6610000f000000db6610000f0000004cac1000040000002aae100028000000366a1000320000009c000000010000002aae100028000000686a1000330000004100000001000000cbaf100023000000366a1000320000009c000000010000001900000000000000010000001e0000001f0000002000000021000000cbaf100023000000686a1000330000004100000001000000906c100039000000d06c1000220000001a0200002d00000000000000f96c10000a000000000000000000000017ac100011000000000000000000000000000000000000000c14100001000000000000000200000000000000036d10000d0000000000000000000000acab10000e000000000000000000000000000000000000001414100001000000000000000200000000000000106d10000c0000000000000000000000acab10000e000000000000000000000000000000000000001c141000010000000000000002000000000000001c6d10000c00000000000000000000002776100009000000000000000000000000000000000000002414100001000000000000000200000000000000286d10001100000000000000000000004cac100004000000000000000000000000000000000000002c14100002000000000000000000000000000000396d1000100000000000000000000000acab10000e000000000000000000000000000000000000003c14100001000000000000000000000000000000496d10000a000000010000000000000000a910000c00000000000000536d10000d000000000000004414100001000000000000000000000000000000606d1000110000000000000000000000acab10000e000000000000000000000000000000000000004c141000010000000000000000000000016f10001f000000e26e10001f000000c46e10001e0000009c6e100028000000de6d10005e0000003c6e100060000000ae6d1000300000008a6d100024000000716d10001900000000000000206f10000700000000000000e414100002000000000000000000000038ab100000000000000000000000000000000000276f10000a000000000000005c24100001000000000000000000000038ab100000000000000000000100000000000000316f100011000000000000008c24100001000000000000000000000038ab100000000000000000000200000000000000c3ac10000600000000000000c9ac10000900000000000000426f10000300000000000000536d10000d00000000000000c6ab1000090000000000000000000000536f10000c000000000000000000000000000000000000000416100001000000000000000100000000000000edab10000a0000000100000000000000f7ab100007000000000000005f6f100016000000000000000c16100001000000000000000000000000000000756f1000060000000100000000000000f7ab100007000000000000007b6f10003a00000000000000141610000100000000000000000000000000000013a610000d0000000000000000000000bbad100003000000000000000000000000000000000000001c16100001000000000000000100000043701000260000001070100033000000c76f100049000000b56f100012000000000000008bac100007000000000000008416100003000000000000000000000038ab10000000000000000000000000000000000092ac10000400000000000000cc16100004000000000000000000000038ab100000000000000000000100000000000000c3ac10000600000000000000697010001c00000000000000857010000900000000000000bbad10000300000000000000dfac100008000000000000008e7010001b00000000000000c3ac10000600000000000000697010001c00000000000000dfac10000800000000000000f7ab1000070000000000000001901000050000000000000020a610000d00000000000000e7ac100007000000000000004cac10000400000000000000d27010000a0000000000000058171000010000000000000000000000601710000200000000000000537110000b000000dc7010005500000031711000220000002aae1000280000005e711000310000004900000001000000000000007ba91000080000000000000064181000040000000000000000000000841810000100000000000000000000008f71100005000000000000008c181000050000000000000000000000b4181000020000000000000000000000947110000800000000000000c4181000010000000000000000000000cc1810000100000000000000000000009c7110000b00000000000000c4181000010000000000000000000000d4181000010000000000000000000000a77110000800000000000000dc181000020000000000000000000000ec181000010000000000000035aa10000900000020a610000d000000b7ad100004000000bbad100003000000d57210005900000035aa100009000000b7ad1000040000004cac100004000000bbad100003000000bbad1000030000005672100042000000987210003d000000b7ad1000040000002572100031000000f071100035000000b7ad1000040000004cac100004000000af711000410000002aae1000280000002e731000350000004300000001000000cbaf1000230000005e711000310000004900000001000000cbaf1000230000002e731000350000004300000001000000b070100022000000090800000e00000030741000190000005074100022000000c50100002d000000f0741000190000001075100022000000c50100002d000000a87510002b000000d37510003300000083000000030000000000000024761000030000000000000000000000277610000900000000000000000000000000000000000000481a100001000000000000000200000000000000307610000b0000000000000000000000277610000900000000000000000000000000000000000000501a1000010000000000000002000000000000003b7610000900000000000000000000004cac10000400000000000000000000000000000000000000581a1000010000000000000001000000a2761000240000007176100031000000447610002d00000000000000d37610000300000000000000901a100002000000000000000000000038ab100000000000000000000000000000000000c3ac10000600000000000000c9ac10000900000000000000d6761000030000000000000027761000090000002aae100028000000d3751000330000004500000001000000cbaf100023000000d3751000330000004500000001000000bb77100030000000d3751000330000006b00000003000000937710002800000014a310000d000000d3751000330000006c00000003000000487710004b000000d37510003300000071000000030000002278100006000000077810001b000000fd7710000a000000ea00000002000000b07a100019000000807a100022000000c50100002d000000407a100039000000807a1000220000001a0200002d000000b079100022000000030800000a000000b079100022000000c001000023000000b079100022000000c101000023000000037a10001c0000001f7a1000140000004a0300000d000000e079100023000000910200001d000000e079100023000000a70000003a000000e079100023000000ae0000003000000000000000fd7a10000e0000000000000000000000bbad10000300000000000000000000000000000000000000f4201000010000000000000002000000000000000b7b1000150000000000000000000000bbad10000300000000000000000000000000000000000000fc20100001000000000000000000000000000000207b10000e0000000000000000000000acab10000e0000000000000000000000000000000000000004211000010000000000000002000000000000002e7b10000d00000000000000000000003b7b100007000000000000000000000000000000000000000c21100001000000000000000200000000000000427b10000c00000000000000000000003b7b1000070000000000000000000000000000000000000014211000010000000000000002000000000000004e7b1000110000000000000000000000bbad100003000000000000000000000000000000000000001c211000010000000000000001000000000000005f7b10000f0000000000000000000000acab10000e0000000000000000000000000000000000000024211000010000000000000002000000000000006e7b10000a0000000000000000000000acab10000e000000000000000000000000000000000000002c21100001000000000000000200000000000000787b100014000000010000000000000000a910000c000000000000008c7b10001a000000000000003421100001000000000000000100000000000000a67b10000a000000000000000000000017ac100011000000000000000000000000000000000000003c21100001000000000000000100000000000000b07b10000a000000010000000000000000a910000c0000000000000000a910000c000000000000004421100001000000000000000000000000000000ba7b10000d000000010000000000000000a910000c0000000000000017ac100011000000000000004c21100001000000000000000100000000000000c77b100014000000010000000000000000a910000c0000000000000017ac100011000000000000005421100001000000000000000100000000000000db7b1000140000000000000000000000f7a510000a000000000000000000000000000000000000000c21100001000000000000000100000000000000ef7b1000130000000000000000000000f7a510000a000000000000000000000000000000000000001421100001000000000000000100000000000000027c1000120000000000000000000000acab10000e000000000000000000000000000000000000005c21100001000000000000000000000000000000147c1000130000000000000000000000acab10000e000000000000000000000000000000000000006421100001000000000000000100000000000000277c10000a0000000000000000000000317c100012000000000000000000000000000000000000006c21100001000000000000000100000000000000437c100007000000010000000000000000a910000c00000000000000acab10000e0000000000000074211000010000000000000001000000000000004a7c10000a000000010000000000000000a910000c00000000000000bbad100003000000000000007c21100001000000000000000100000000000000547c10000d0000000000000000000000617c1000020000000000000000000000000000000000000084211000010000000000000000000000478010002a000000f77f100050000000ce7f100029000000867f100048000000327f100054000000e47e10004e000000b67e10002e0000009f7e1000170000007d7e100022000000547e1000290000002c7e100028000000077e100025000000c67d100041000000a27d1000240000006a7d1000380000002e7d10003c000000f17c10003d0000007d7c100074000000637c10001a000000000000007180100005000000000000006c23100001000000000000000000000038ab1000000000000000000000000000000000007680100007000000000000008423100002000000000000000000000038ab1000000000000000000001000000000000007d8010000800000000000000b423100002000000000000000000000038ab100000000000000000000200000000000000858010000a00000000000000e423100002000000000000000000000038ab1000000000000000000003000000000000008f80100014000000000000001424100003000000000000000000000038ab100000000000000000000400000000000000a380100014000000000000005c24100001000000000000000000000038ab100000000000000000000500000000000000b780100014000000000000005c24100001000000000000000000000038ab100000000000000000000600000000000000cb80100013000000000000007424100001000000000000000000000038ab100000000000000000000700000000000000de8010000d000000000000008c24100001000000000000000000000038ab100000000000000000000800000000000000eb80100017000000000000007424100001000000000000000000000038ab100000000000000000000900000000000000c3ac10000600000000000000c9ac10000900000000000000c3ac10000600000000000000c9ac100009000000000000000f8110001000000000000000bbad10000300000000000000c3ac10000600000000000000c9ac10000900000000000000308110000600000000000000cd8f10002600000000000000c3ac10000600000000000000c9ac10000900000000000000248110000c00000000000000bbad10000300000000000000c3ac10000600000000000000c9ac100009000000000000000f8110001000000000000000bbad100003000000000000001f81100005000000000000008c7b10001a0000000000000004a110000300000000000000acab10000e0000000000000004a110000300000000000000bbad10000300000000000000028110000d000000000000004cac1000040000000000000036811000060000000000000024451000010000000000000000000000282510000100000000000000000000003c8110000e000000000000003025100002000000000000000000000040251000020000000000000000000000427b10000c00000000000000502510000200000000000000000000006025100001000000000000002f8210003800000035aa100009000000bbad1000030000009581100055000000ea8110004500000035aa1000090000002eaa1000070000004a8110004b0000002aae10002800000067821000310000006800000001000000cbaf10002300000067821000310000006800000001000000220000001800000004000000230000002400000025000000260000002aae100028000000df8510003f00000025010000090000004786100006000000270000005686100008000000280000006786100007000000290000006e861000070000002a00000075861000090000002b0000007e861000070000002c000000858610000e0000002d000000938610000f0000002e000000a2861000080000002f000000aa861000080000003000000000000000478610000600000000000000310000000000000000000000000000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000004d861000090000000000000033000000000000000000000000000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000568610000800000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000005e86100009000000000000003700000000000000000000000000000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000067861000070000000000000039000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000006e86100007000000000000003b000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000007586100009000000000000003d000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000007e86100007000000000000003f000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000858610000e0000000000000041000000000000000000000000000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000938610000f0000000000000043000000000000000000000000000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000a2861000080000000000000045000000000000000000000000000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000aa8610000800000000000000470000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c08810003900000090881000220000001a0200002d0000004088100022000000030800000a00000070881000190000009088100022000000c50100002d0000004088100022000000090800000e00000000000000008910000d0000000000000000000000f7a510000a00000000000000000000000000000000000000642f1000010000000000000002000000000000000d8910000a0000000000000000000000f7a510000a000000000000000000000000000000000000006c2f10000100000000000000020000000000000017891000140000000000000000000000f7a510000a00000000000000000000000000000000000000742f1000010000000000000002000000000000002b8910000a0000000000000000000000bbad100003000000000000000000000000000000000000007c2f10000100000000000000020000000000000035891000140000000000000000000000acab10000e00000000000000000000000000000000000000842f100001000000000000000200000000000000498910001300000000000000000000005c89100009000000000000000000000000000000000000008c2f100002000000000000000200000000000000baab10000c0000000000000000000000acab10000e000000000000000000000000000000000000009c2f100001000000000000000200000000000000658910000c0000000000000000000000acab10000e00000000000000000000000000000000000000a42f100001000000000000000200000000000000718910000c0000000000000000000000bbad10000300000000000000000000000000000000000000ac2f1000010000000000000002000000000000007d8910000d00000000000000000000008a8910002300000000000000000000000000000000000000b42f100002000000000000000100000000000000ad8910000900000000000000000000005c8910000900000000000000000000000000000000000000c42f100001000000000000000100000000000000b68910000b000000010000000000000000a910000c00000000000000c18910000900000000000000cc2f100001000000000000000100000000000000ca8910000e000000010000000000000000a910000c00000000000000d88910001000000000000000d42f100002000000000000000000000000000000e88910000c000000010000000000000000a910000c000000000000005c8910000900000000000000cc2f100001000000000000000000000000000000f489100006000000000000000000000017ac10001100000000000000000000000000000000000000e42f100001000000000000000100000000000000fa8910000a000000000000000000000017ac10001100000000000000000000000000000000000000ec2f100001000000000000000100000000000000048a10000e0000000000000000000000bbad1000030000000000000000000000000000000000000038ab100000000000000000000100000000000000128a10000c00000000000000000000001e8a10002800000000000000000000000000000000000000f42f100001000000000000000000000000000000468a1000100000000000000000000000568a10000f00000000000000000000000000000000000000fc2f100001000000000000000200000000000000658a10000b0000000000000000000000708a10001f0000000000000000000000000000000000000004301000010000000000000000000000f48e100041000000b28e1000420000006f8e100043000000228e10004d000000d38d10004f000000658d10005a000000bf8d100014000000378d10002e000000118d100026000000d78c10003a000000738c10005b000000ce8c100009000000328c100041000000f28b1000400000007d8b10005f000000dc8b100016000000658b100018000000498b10001c000000018b100048000000c78a10003a0000008f8a10003800000000000000358f10000d00000000000000bc31100003000000000000000000000038ab100000000000000000000000000000000000428f100013000000000000000432100005000000000000000000000038ab100000000000000000000100000000000000558f10000d000000000000007c32100002000000000000000000000038ab100000000000000000000200000000000000628f10001000000000000000ac32100002000000000000000000000038ab100000000000000000000300000000000000728f10000e00000000000000dc32100004000000000000000000000038ab100000000000000000000400000000000000808f100011000000000000003c33100001000000000000000000000038ab100000000000000000000500000000000000918f10000d000000000000005433100001000000000000000000000038ab1000000000000000000006000000000000009e8f100019000000000000006c33100001000000000000000000000038ab100000000000000000000700000000000000b78f100011000000000000006c33100001000000000000000000000038ab100000000000000000000800000000000000c3ac10000600000000000000c9ac10000900000000000000339010000500000000000000c189100009000000000000000190100005000000000000005c8910000900000000000000c3ac10000600000000000000c9ac100009000000000000000a9010000e00000000000000bbad1000030000000000000051a010000300000000000000cd8f10002600000000000000189010000900000000000000bbad100003000000000000002190100012000000000000005c8910000900000000000000c3ac10000600000000000000c9ac10000900000000000000019010000500000000000000bbad10000300000000000000c3ac10000600000000000000c9ac10000900000000000000069010000400000000000000bbad10000300000000000000c3ac10000600000000000000c9ac10000900000000000000f38f10000900000000000000cd8f10002600000000000000fc8f10000500000000000000f7a510000a000000000000000190100005000000000000005c8910000900000000000000c88f10000500000000000000bbad1000030000000000000051a010000300000000000000cd8f10002600000000000000c88f10000500000000000000acab10000e00000000000000389010000b000000000000003434100002000000000000000000000044341000010000000000000000000000439010001000000000000000803e10000100000000000000000000004c341000010000000000000000000000539010000c00000000000000543410000100000000000000000000005c3410000100000000000000000000005f9010000e000000000000006434100002000000000000000000000074341000010000000000000035aa10000900000035aa1000090000002191100015000000129110000f000000bbad100003000000d59010003d000000c79010000e000000c79010000e0000006d9010005a0000002aae10002800000036911000330000005700000001000000cbaf10002300000036911000330000005700000001000000a09610001e000000be961000300000002e0100000300000000000000089710000c000000010000000000000000a910000c0000000000000014971000080000000000000038ab1000000000000000000001000000000000001c9710000e0000000000000000000000bbad1000030000000000000000000000000000000000000038ab1000000000000000000000000000000000002a971000090000000100000000000000acab10000e00000000000000f7ab1000070000000000000038ab100000000000000000000200000000000000339710000d0000000100000000000000bbad1000030000000000000040971000070000000000000038ab100000000000000000000200000000000000479710000a0000000000000000000000f7ab1000070000000000000000000000000000000000000038ab10000000000000000000020000000000000051971000060000000000000000000000acab10000e000000000000000000000000000000000000001c37100001000000000000000200000000000000579710000a0000000000000000000000f7ab1000070000000000000000000000000000000000000038ab100000000000000000000200000000000000619710000e0000000000000000000000f7ab1000070000000000000000000000000000000000000038ab1000000000000000000002000000000000006f97100006000000000000000000000075971000090000000000000000000000000000000000000038ab1000000000000000000001000000000000007e971000060000000000000000000000849710001a0000000000000000000000000000000000000038ab10000000000000000000010000009e97100042000000000000005a9810000d0000000000000000000000f7a510000a00000000000000000000000000000000000000b83910000100000000000000020000000000000067981000120000000000000000000000f7a510000a00000000000000000000000000000000000000c039100001000000000000000200000000000000799810000d0000000000000000000000f7a510000a00000000000000000000000000000000000000c839100001000000000000000200000000000000869810000b0000000000000000000000f7a510000a00000000000000000000000000000000000000d039100001000000000000000200000000000000919810000b0000000000000000000000f7a510000a00000000000000000000000000000000000000d8391000010000000000000002000000000000009c9810000b0000000000000000000000a79810000f00000000000000000000000000000000000000e039100001000000000000000200000000000000b6981000070000000100000000000000a79810000f0000000000000017ac10001100000000000000e839100001000000000000000100000000000000bd9810000b000000010000000000000000a910000c00000000000000f7a510000a00000000000000f03910000b000000000000000100000000000000c89810000f000000010000000000000000a910000c00000000000000f7a510000a00000000000000483a10000c000000000000000100000000000000d7981000120000000000000000000000f7a510000a00000000000000000000000000000000000000a83a100001000000000000000200000000000000e9981000120000000000000000000000f7a510000a00000000000000000000000000000000000000b03a1000010000000000000002000000709f1000290000003c9f100034000000f29e10004a000000cd9e100025000000849e100049000000659e10001f0000004f9e1000160000001b9c10002700000038ab100000000000429c100053000000959c10005a000000ef9c100055000000449d10004f000000939d100050000000e39d10001500000038ab100000000000f89d100057000000d69b100045000000759910005c000000d19910002700000038ab100000000000f89910005b000000539a10005c000000af9a10004a00000038ab100000000000f99a10005d000000569b10002d00000038ab100000000000839b100053000000d69b1000450000003e99100037000000fb98100043000000f09f10003900000030981000220000001a0200002d000000000000003ea010000800000000000000303b100003000000000000000000000038ab10000000000000000000000000000000000046a010000b00000000000000783b100003000000000000000000000038ab100000000000000000000100000000000000c3ac10000600000000000000c9ac1000090000000000000089a01000040000000000000054a010002900000000000000f0a810000500000000000000f7a510000a0000000000000051a01000030000000000000054a0100029000000000000007da010000400000000000000f7a510000a0000000000000081a010000800000000000000f7a510000a0000000000000096a01000130000000000000000000000a9a01000120000000000000000000000000000000000000038ab100000000000000000000000000000000000bba010001200000000000000ec3c100002000000000000000000000038ab100000000000000000000000000000000000cda010000c000000000000001c3d100002000000000000000000000038ab100000000000000000000100000000000000d9a0100006000000000000004c3d100002000000000000000000000038ab100000000000000000000200000000000000dfa0100008000000000000007c3d100001000000000000000000000038ab100000000000000000000300000000000000e7a010000b00000000000000943d100001000000000000000000000038ab100000000000000000000400000000000000c3ac10000600000000000000c9ac1000090000000000000022a11000060000000000000028a110002a00000000000000c3ac10000600000000000000c9ac1000090000000000000007a1100013000000000000001aa110000800000000000000c3ac10000600000000000000c9ac10000900000000000000d9a01000060000000000000040971000070000000000000004a110000300000000000000409710000700000000000000f2a010000500000000000000f7a010000d0000002aae10002800000052a110003200000083000000010000002aae10002800000084a11000330000007e0000000100000000000000b7a110000a00000000000000603e1000030000000000000000000000783e1000010000000000000000000000c1a110000d00000000000000803e1000010000000000000000000000883e1000010000000000000000000000cea110000800000000000000903e1000040000000000000000000000b03e1000010000000000000035aa10000900000034a210000c00000040a210001100000019a210001b00000035aa10000900000002a210001700000035aa10000900000035aa1000090000002eaa1000070000002eaa100007000000d6a110002c000000cbaf10002300000052a11000320000008300000001000000cbaf10002300000084a11000330000007e00000001000000e9a210002b00000014a310000d00000084a1100033000000a80000000300000064a410001c00000049a31000330000006a0000000300000040a410002400000049a3100033000000720000000300000014a410002c00000049a3100033000000ac0000004c000000dca310003800000049a3100033000000aa0000002a000000b4a310002800000049a3100033000000ab000000320000007ca310003800000049a3100033000000d40000000300000021a310002800000049a3100033000000d900000003000000b0a4100019000000d0a4100022000000c50100002d00000090a5100039000000d0a41000220000001a0200002d00000000000000d1a510000c0000000000000000000000dda510000700000000000000000000000000000000000000c041100002000000000000000200000000000000e4a51000130000000000000000000000f7a510000a00000000000000000000000000000000000000d04110000100000000000000020000000000000001a610000b0000000000000000000000acab10000e00000000000000000000000000000000000000d8411000010000000000000002000000000000000ca61000040000000000000000000000dda510000700000000000000000000000000000000000000e04110000100000000000000020000000000000010a61000030000000000000000000000f7a510000a00000000000000000000000000000000000000e84110000100000000000000010000000000000013a610000d000000000000000000000020a610000d00000000000000000000000000000000000000f041100001000000000000000100000000000000c6ab100009000000010000000000000020a610000d000000000000002da610002200000000000000f8411000010000000000000000000000000000004fa6100009000000000000000000000058a61000120000000000000000000000000000000000000000421000010000000000000001000000dba71000540000002fa810003700000089a710005200000067a710002200000023a7100044000000f0a6100033000000c7a6100029000000a8a610001f0000006aa610003e0000000000000066a810000d00000000000000f842100003000000000000000000000038ab10000000000000000000000000000000000073a8100007000000000000004043100001000000000000000000000038ab1000000000000000000001000000000000007aa8100009000000000000005843100004000000000000000000000038ab10000000000000000000020000000000000083a810000f00000000000000b843100002000000000000000000000038ab10000000000000000000030000000000000092a810001000000000000000e843100002000000000000000000000038ab100000000000000000000400000000000000c3ac10000600000000000000c9ac10000900000000000000f0a810000500000000000000f7a510000a00000000000000f5a810000b0000000000000000a910000c00000000000000e9a810000700000000000000f7a510000a00000000000000b7a810000d00000000000000dda510000700000000000000c4a810001500000000000000f7a510000a00000000000000d9a810000c00000000000000acab10000e00000000000000e5a810000400000000000000dda510000700000000000000c3ac10000600000000000000c9ac10000900000000000000ada810000a0000000000000020a610000d00000000000000c3ac10000600000000000000c9ac10000900000000000000a2a810000b0000000000000020a610000d00000038ab10000000000079a910000200000068a9100011000000d703000005000000000000007ba910000800000000000000144510000100000000000000000000001c45100001000000000000000000000083a910000800000000000000244510000100000000000000000000002c4510000100000000000000000000008ba910000700000000000000344510000300000000000000000000004c45100001000000000000000000000092a910000500000000000000244510000100000000000000000000005445100001000000000000000000000097a910000800000000000000244510000100000000000000000000005c451000010000000000000020a610000d00000078aa10000e0000002eaa1000070000003eaa10003a00000020a610000d0000002eaa10000700000035aa1000090000000eaa100020000000eba91000230000009fa910004c0000002aae10002800000086aa1000320000004700000001000000cbaf10002300000086aa1000320000004700000001000000000000009fab10000d0000000000000000000000acab10000e0000000000000000000000000000000000000038ab100000000000000000000200000000000000baab10000c0000000000000000000000acab10000e0000000000000000000000000000000000000038ab100000000000000000000200000000000000c6ab1000090000000000000000000000cfab10001e0000000000000000000000000000000000000038ab100000000000000000000200000000000000edab10000a0000000100000000000000f7ab10000700000000000000feab10000b0000000000000038ab10000000000000000000000000000000000009ac10000e0000000100000000000000f7ab1000070000000000000017ac1000110000000000000038ab10000000000000000000010000000000000028ac10000d000000010000000000000035ac100017000000000000004cac1000040000000000000038ab10000000000000000000000000000000000050ac10000e0000000100000000000000f7ab100007000000000000005eac1000230000000000000038ab1000000000000000000000000000000000008bac100007000000000000002848100002000000000000000000000038ab10000000000000000000000000000000000092ac100004000000000000005848100003000000000000000000000038ab10000000000000000000010000000000000096ac10000400000000000000a048100002000000000000000000000038ab1000000000000000000002000000000000009aac10001200000000000000d048100001000000000000000000000038ab100000000000000000000300000000000000acac10001100000000000000d048100001000000000000000000000038ab100000000000000000000400000000000000c3ac10000600000000000000c9ac10000900000000000000dfac10000800000000000000eeac10001000000000000000c3ac10000600000000000000c9ac10000900000000000000dfac10000800000000000000f7ab10000700000000000000e7ac100007000000000000004cac10000400000000000000c3ac10000600000000000000c9ac10000900000000000000d2ac10000d00000000000000f7ab10000700000000000000bdac10000600000000000000acab10000e00000000000000feac1000100000000000000040491000040000000000000000000000604910000200000000000000000000000ead10000f0000000000000040491000040000000000000000000000704910000200000000000000b7ad100004000000bbad100003000000bbad100003000000bbad10000300000078ad10003f00000050ad1000280000001dad10003300000050ad100028000000c0ad100022000000030800000a000000f0ad10001f000000ab0200001e000000f0ad10001f000000ae020000360000002aae10002800000052ae1000340000002100000001000000cbaf10002300000052ae10003400000021000000010000000041e093c1000b4c66756e635f737461636b5f636f7374732069736e27742079657420636f6d70757465643b0a0909090944696420796f752063616c6c2060636f6d707574655f737461636b5f636f737473603f0041ac94c1000b2c546869732073686f756c64206265206120696e646578206f66206120646566696e65642066756e6374696f6e0041d894c1000b2c44756520746f2076616c69646174696f6e20636f64652073656374696f6e2073686f756c642065786973747300418495c1000b1e46756e6374696f6e20626f6479206973206f7574206f6620626f756e64730041a295c1000b2543616c6c20746f2066756e6374696f6e2074686174206f75742d6f662d626f756e64733a200041d095c1000b642f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e332e312f7372632f737461636b5f6865696768742f6d6f642e72730041b496c1000b4266756e6374696f6e20696d706f727420636f756e74206973206e6f74207a65726f3b20696d706f72742073656374696f6e206d757374206578697374733b207165640041f696c1000b5d66756e635f696478206973206c657373207468616e2066756e6374696f6e20696d706f72747320636f756e743b0a090909096e74682066756e6374696f6e20696d706f7274206d7573742062652060536f6d65603b0a090909097165640041d397c1000b0a5369676e6174757265200041dd97c1000b1420287370656369666965642062792066756e63200041f197c1000b0f292069736e277420646566696e656400418098c1000b1246756e6374696f6e20617420696e6465782000419298c1000b0f206973206e6f7420646566696e65640041b098c1000b572f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e332e312f7372632f6761732e727300418799c1000b0f6c6962616c6c6f632f7665632e727300419699c1000b1c617373657274696f6e206661696c65643a20656e64203c3d206c656e0041b299c1000b1e617373657274696f6e206661696c65643a20696e646578203c3d206c656e0041d099c1000b134e6f2066756e6374696f6e2073656374696f6e0041e399c1000b0f4e6f20636f64652073656374696f6e0041f299c1000b0f4e6f20747970652073656374696f6e0041819ac1000b2546756e6374696f6e206973206e6f7420666f756e6420696e2066756e632073656374696f6e0041a69ac1000b2746756e6374696f6e20626f647920666f722074686520696e6465782069736e277420666f756e640041cd9ac1000b16636f6e74726f6c20737461636b20697320656d7074790041e39ac1000b17737461636b206d757374206265206e6f6e2d656d7074790041fa9ac1000b0e737461636b206f766572666c6f770041889bc1000b1b636f6e74726f6c20737461636b206f75742d6f662d626f756e64730041a39bc1000b274172697479206f6620616c6c206a756d702d74617267657473206d75737420626520657175616c0041ca9bc1000b0e54797065206e6f7420666f756e640041e09bc1000b6b2f55736572732f6761762f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e332e312f7372632f737461636b5f6865696768742f6d61785f6865696768742e72730041cb9cc1000b25747279696e6720746f20706f70206d6f72652076616c756573207468616e207075736865640041f09cc1000b0f737461636b20756e646572666c6f770041809dc1000b222f636865636b6f75742f7372632f6c6962636f72652f736c6963652f6d6f642e72730041a29dc1000b80016066756e635f696478602073686f756c6420636f6d652066726f6d20606e6565645f7468756e6b73603b0a09090909606e6565645f7468756e6b736020697320706f70756c617465642077697468207468652073616d65206974656d73207468617420696e20607265706c6163656d656e745f6d6170603b0a090909097165640041a29ec1000b354174207468697320706f696e7420616e20696e646578206d7573742062652061737369676e656420746f2065616368207468756e6b0041d79ec1000b1266756e6374696f6e207769746820696478200041e99ec1000b0c2069736e277420666f756e640041f59ec1000b0c547261696c696e67446174610041819fc1000b0d556e6578706563746564456f6600418e9fc1000b0b496e76616c6964446174610041999fc1000b0b492f4f204572726f723a200041a49fc1000b1045787472696e736963537563636573730041b49fc1000b0f45787472696e7369634661696c65640041c39fc1000b1520416e2065787472696e736963206661696c65642e0041d89fc1000b2520416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e004180a0c1000b19617474656d707420746f20646976696465206279207a65726f0041a0a0c1000b3f2f55736572732f6761762f436f72652f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f67656e657269632f6572612e72730041dfa0c1000b0e48617368206e6f7420657175616c0041eda0c1000b2252756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e6700418fa1c1000b116361706163697479206f766572666c6f770041a0a1c1000b0800000000000000000041a8a1c1000b336120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f720041e0a1c1000b202f636865636b6f75742f7372632f6c6962636f72652f666d742f6d6f642e7273004180a2c1000b023078004182a2c1000bc80130303031303230333034303530363037303830393130313131323133313431353136313731383139323032313232323332343235323632373238323933303331333233333334333533363337333833393430343134323433343434353436343734383439353035313532353335343535353635373538353936303631363236333634363536363637363836393730373137323733373437353736373737383739383038313832383338343835383638373838383939303931393239333934393539363937393839390041caa3c1000b5000010305050606030706080809110a1c0b190c140d120e160f0410031212130916011705180219031a071c021d011f1620032b062c022d0b2e01300331023202a902aa04ab08fa02fb05fd04fe03ff0900419aa4c1000baf02ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f0040d1145496465808184b2bcbebfd5d7f0f1838586898b8c98a0a4a6a8a9acbabebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f74759697c9ff2f5f262e2fa7afb7bfc7cfd7df9a409798308f1fffceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff0041c9a6c1000bbc0200205f2282df048244081b04061181ac0e80ab351e1580e003190801042f043404070301070607110a500f1207550802041c0a090308030703020303030c0405030b06010e15053a0311070605100856070207150d500443032d03010411060f0c3a041d250d064c206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a061f414c042d0374083c030f033c0738082a0682ff1118082f112d032010210f808c048297190b158894052f053b07020e180980af31740c80d61a0c0580ff0580b605240c9bc60ad23010848d033709815c1480b80880ba3d35040a06380846080c06740b1e035a0459098083181c0a1609460a808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d004185a9c1000b420006010103010402080809020a050b0210011104120513111402150217021a021c051d0824016a036b02bc02d102d40cd509d602d702da01e005e802ee20f004f9040041c7a9c1000b9e010c273b3e4e4f8f9e9e9f060709363d3e56f3d0d104141836375657bd35cecfe01287898e9e040d0e11122931343a4546494a4e4f64655a5cb6b71b1c848509379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a2225c5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d03f71727b0041e5aac1000bfd025e227b0503042d036504012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a81261f808128082a80a64e041e0f430e19070a0647092709750b3f412a063b050a0651060105100305808b5f2148080a80a65e22450b0a060d1338080a362c041080c03c64530c0181004808531d398107460a1d03474937030e080a0639070a8136198107839a66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b65450b2f101140021e97f20e82f3a50d811f51818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b87d580d7294b050a0402831144814b3c06010455051b3402810e2c04640c560a0d035c043d391d0d2c040907020e06809a83d50b0d030a06740c59270c0438080a0628081e520c046703290d0a06030d30600e85920041e2adc1000b06696e646578200041e8adc1000b22206f7574206f662072616e676520666f7220736c696365206f66206c656e6774682000418aaec1000b16736c69636520696e64657820737461727473206174200041a0aec1000b0d2062757420656e6473206174200041adaec1000b8002010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202020202020202020202020202020202020202020203030303030303030303030303030303040404040400000000000000000000000041adb0c1000b055b2e2e2e5d0041b4b0c1000b90010100000000000000200000000000000003000000000000000300000000000000030000000100000001000000200000000000000003000000000000000300000000000000030000000100000002000000200000000000000003000000000000000300000000000000030000000100000003000000200000000000000003000000000000000300000000000000030000000041c4b1c1000bb4010100000000000000200000000000000003000000000000000300000000000000030000000100000001000000200000000000000003000000000000000300000000000000030000000100000002000000200000000000000003000000000000000300000000000000030000000100000003000000200000000000000003000000000000000300000000000000030000000100000004000000200000000000000003000000000000000300000000000000030000000041f8b2c1000b126c6962636f72652f7374722f6d6f642e727300418ab3c1000b0b6279746520696e64657820004195b3c1000b26206973206e6f742061206368617220626f756e646172793b20697420697320696e73696465200041bbb3c1000b0820286279746573200041c3b3c1000b0629206f6620600041c9b3c1000b01600041cab3c1000b0e626567696e203c3d20656e6420280041d8b3c1000b04203c3d200041dcb3c1000b1029207768656e20736c6963696e6720600041ecb3c1000b16206973206f7574206f6620626f756e6473206f662060004190b4c1000b1c6c6962636f72652f756e69636f64652f626f6f6c5f747269652e72730041acb4c1000b022e2e0041aeb4c1000b0b426f72726f774572726f720041b9b4c1000b0e426f72726f774d75744572726f720041d0b4c1000b126c6962636f72652f666d742f6d6f642e72730041e2b4c1000b2b63616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c756500418db5c1000b054572726f72004198b5c1000bd0040000c0fbef3e00000000000e0000000000000000000000000000f8fffbffffff0700000000000014fe21fe000c00000002000000000000501e2080000c00004006000000000000108639020000002300be2100000c0000fc02000000000000d01e20c0000c0000000400000000000040012080000000000011000000000000c0c13d60000c0000000200000000000090443060000c00000003000000000000581e2080000c00000000845c8000000000000000000000f207807f000000000000000000000000f21b003f000000000000000000030000a002000000000000fe7fdfe0fffeffffff1f40000000000000000000000000e0fd66000000c301001e006420002000000000000000e00000000000001c0000001c0000000c0000000c00000000000000b03f40fe0f200000000000380000000000006000000000020000000000008701040e00008009000000000000407fe51ff89f000000000000ff7f0f0000000000d0170400000000f80f00030000003c3b00000000000040a303000000000000f0cf000000f7fffd211003fffffffffffffffb00100000000000000000ffffffff01000000000000800300000000000000008000000000ffffffff0000000000fc00000000000600000000000000000080f73f000000c0000000000000000000000300440800006000000030000000ffff038000000000c03f000080ff030000000000070000000000c813000000002000000000000000007e660008100000000000100000000000009dc1020000000030400000000000202100000000004000000000ffff0000ffff00000041e8b9c1000b80040000000000000001000000020003000000000000000000000000000000000000000000000000000004000005000000000000000006000000000000000007000008090a000b0c0d0e0f000010111200001314151600001718191a1b001c0000001d000000000000001e1f20000000000021002200232425000000002600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027280000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000002b2c00002d0000000000000000000000000000000000000000000000000000000000002e2f3000000000000000000000000000000000000000000031000000000000000000000000000000000000000000000000000000000000000000003200330000000000000000000000000000000000000000000000000000343500003535353600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041e8bdc1000bb803000000000000000000000000000000200000000001000000000000000000c0076ef0000000000087000000006000000000000000f0000000c0ff01000000000002000000000000ff7f0000000000008003000000000078060700000080ef1f000000000000000800030000000000c07f001e000000000000000000000080d34000000080f8070000030000000000005801008000c01f1f0000000000000000ff5c00004000000000000000000000f9a50d000000000000000000000000803cb00100003000000000000000000000f8a70100000000000000000000000028bf00000000e0bc0f0000000000000080ff06fe0700000000f87980007e0e0000000000fc7f03000000000000000000007fbf0000fcfffffc6d000000000000007eb4bf000000000000000000a3000000000000000000000018000000000000001f000000000000007f000080070000000000000000600000000000000000a0c307f8e70f0000003c00001c00000000000000ffffffffffff7ff8ffffffffff1f2000100000f8feff00007ffffff9db07000000007f0000000000f00700000000000000000000ffffffffffffffffffffffffffffffffffff00000041a0c1c1000b20696e646578206f7574206f6620626f756e64733a20746865206c656e206973200041c0c1c1000b12206275742074686520696e646578206973200041d2c1c1000b116c6962636f72652f6f7074696f6e2e72730041e3c1c1000b24547269656420746f20736872696e6b20746f2061206c6172676572206361706163697479004187c2c1000b136c6962616c6c6f632f7261775f7665632e727300419ac2c1000b15746f6f206d616e7920696e737472756374696f6e730041afc2c1000b392f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f636f6e74726163742f7372632f766d2f72756e74696d652e72730041e8c2c1000b036761730041ebc2c1000b0f6578745f7365745f73746f726167650041fac2c1000b0f6578745f6765745f73746f72616765004189c3c1000b086578745f63616c6c004191c3c1000b0a6578745f63726561746500419bc3c1000b0a6578745f72657475726e0041a5c3c1000b0e6578745f696e7075745f73697a650041b3c3c1000b0e6578745f696e7075745f636f70790041c1c3c1000b106578745f736372617463685f73697a650041d1c3c1000b106578745f736372617463685f636f70790041e1c3c1000bf403707265636f6e646974696f6e3a20616c6c20696d706f7274732073686f756c6420626520636865636b656420616761696e737420746865207369676e617475726573206f6620636f72726573706f6e64696e670a09090909090966756e6374696f6e7320646566696e65642062792060646566696e655f656e762160206d6163726f206279207468652075736572206f6620746865206d6163726f3b0a0909090909097369676e617475726573206f662074686573652066756e6374696f6e7320646566696e6564206279206024706172616d73603b0a09090909090963616c6c7320616c77617973206d616465207769746820617267756d656e7473207479706573206f662077686963682061726520646566696e65642062792074686520636f72726573706f6e64696e6720696d706f7274733b0a09090909090974687573207479706573206f6620617267756d656e74732073686f756c6420626520657175616c20746f2074797065206c69737420696e206024706172616d736020616e640a0909090909096c656e677468206f6620617267756d656e74206c69737420616e642024706172616d732073686f756c6420626520657175616c3b0a0909090909097468757320746869732063616e206e6576657220626520604e6f6e65603b0a0909090909097165643b0a0909090909090041d5c7c1000b0f436f6e747261637420436f64654f660041e4c7c1000b11436f6e7472616374204761735370656e740041f5c7c1000b1644656d6f6372616379204c61756e6368506572696f6400418bc8c1000b1544656d6f6372616379205075626c696350726f70730041a0c8c1000b1344656d6f6372616379204465706f7369744f660041b3c8c1000b1644656d6f637261637920566f74696e67506572696f640041c9c8c1000b1344656d6f6372616379204e65787454616c6c790041dcc8c1000b1944656d6f6372616379205265666572656e64756d436f756e740041f5c8c1000b1344656d6f637261637920566f74657273466f72004188c9c1000b1a44656d6f6372616379205265666572656e64756d496e666f4f660041a2c9c1000b1044656d6f637261637920566f74654f660041b2c9c1000b4743616e6e6f7420696e6a6563742061207265666572656e64756d207468617420656e6473206561726c696572207468616e2070726563656564696e67207265666572656e64756d004180cac1000b222f636865636b6f75742f7372632f6c6962636f72652f736c6963652f6d6f642e72730041b0cac1000b39617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f0041f0cac1000b222f636865636b6f75742f7372632f6c6962636f72652f6f70732f61726974682e7273004192cbc1000b1a626164207369676e617475726520696e2065787472696e7369630041accbc1000b14436f6e747261637420436f6e74726163744665650041c0cbc1000b14436f6e74726163742043616c6c426173654665650041d4cbc1000b16436f6e747261637420426c6f636b4761734c696d69740041eacbc1000b16436f6e74726163742043726561746542617365466565004180ccc1000b06637265617465004186ccc1000b096761735f6c696d697400418fccc1000b06543a3a476173004195ccc1000b09696e69745f636f646500419eccc1000b04646174610041a2ccc1000b11436f6e74726163742047617350726963650041b3ccc1000b0944656d6f63726163790041bcccc1000b0f5075626c696350726f70436f756e740041cbccc1000b0950726f70496e6465780041d4ccc1000b0b5075626c696350726f70730041dfccc1000b2b5665633c2850726f70496e6465782c20543a3a50726f706f73616c2c20543a3a4163636f756e744964293e00418acdc1000b094465706f7369744f66004193cdc1000b1f28543a3a42616c616e63652c205665633c543a3a4163636f756e7449643e290041b2cdc1000b0c4c61756e6368506572696f640041becdc1000b0e4d696e696d756d4465706f7369740041cccdc1000b0f5265666572656e64756d436f756e740041dbcdc1000b0f5265666572656e64756d496e6465780041eacdc1000b094e65787454616c6c790041f3cdc1000b105265666572656e64756d496e666f4f66004183cec1000b2c28543a3a426c6f636b4e756d6265722c20543a3a50726f706f73616c2c20566f74655468726573686f6c64290041afcec1000b09566f74657273466f720041b8cec1000b06566f74654f660041becec1000b1f285265666572656e64756d496e6465782c20543a3a4163636f756e744964290041ddcec1000b21204765742074686520766f74652c20696620536f6d652c206f66206077686f602e0041fecec1000b29204765742074686520766f7465727320666f72207468652063757272656e742070726f706f73616c2e0041a7cfc1000b2d20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e0041d4cfc1000b3220546865206e657874207265666572656e64756d20696e64657820746861742073686f756c642062652074616c6c6965642e004186d0c1000b4e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e64756d73207374617274656420736f206661722e0041d4d0c1000b4d20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e0041a1d1c1000b3920486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e0041dad1c1000b212054686f73652077686f2068617665206c6f636b65642061206465706f7369742e0041fbd1c1000b2020546865207075626c69632070726f706f73616c732e20556e736f727465642e00419bd2c1000b3d20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e0041d8d2c1000b067365636f6e640041ded2c1000b1073746172745f7265666572656e64756d0041eed2c1000b1163616e63656c5f7265666572656e64756d0041ffd2c1000b097265665f696e646578004188d3c1000b0e766f74655f7468726573686f6c64004196d3c1000b0d566f74655468726573686f6c640041a3d3c1000b5d205472616e736665722068617070656e6564206066726f6d60202d3e2060746f60207769746820676976656e206076616c7565602061732070617274206f66206120606d6573736167652d63616c6c60206f722060637265617465602e004180d4c1000b065461626c6564004186d4c1000b075374617274656400418dd4c1000b06506173736564004193d4c1000b094e6f7450617373656400419cd4c1000b0943616e63656c6c65640041a5d4c1000b11436f6e7472616374204d617844657074680041b6d4c1000b322f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f636f6e74726163742f7372632f6c69622e72730041e8d4c1000b332f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f64656d6f63726163792f7372632f6c69622e727300419bd5c1000b1844656d6f6372616379204d696e696d756d4465706f7369740041b3d5c1000b0d76616c756520746f6f206c6f770041c0d5c1000b1944656d6f6372616379205075626c696350726f70436f756e740041d9d5c1000b1a70726f706f73657227732062616c616e636520746f6f206c6f770041f3d5c1000b2463616e206f6e6c79207365636f6e6420616e206578697374696e672070726f706f73616c004197d6c1000b1a7365636f6e64657227732062616c616e636520746f6f206c6f770041b1d6c1000b22766f746520676976656e20666f7220696e76616c6964207265666572656e64756d2e0041d3d6c1000b307472616e736163746f72206d75737420686176652062616c616e636520746f207369676e616c20617070726f76616c2e004183d7c1000b40626164206f726967696e3a20657870656374656420746f2062652061207468726573686f6c64206e756d626572206f6620636f756e63696c206d656d626572730041c3d7c1000b2252657175697265642076616c756573206d75737420626520696e2073746f726167650041e5d7c1000b1853657373696f6e204c6173744c656e6774684368616e67650041fdd7c1000b1553657373696f6e2053657373696f6e4c656e677468004192d8c1000b1953657373696f6e20466f7263696e674e657753657373696f6e0041abd8c1000b1453657373696f6e2043757272656e7453746172740041bfd8c1000b1453657373696f6e2043757272656e74496e6465780041d3d8c1000b1953657373696f6e204e65787453657373696f6e4c656e6774680041ecd8c1000b1253657373696f6e2056616c696461746f72730041fed8c1000b1253657373696f6e204e6578744b6579466f72004190d9c1000b39617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f0041d0d9c1000b222f636865636b6f75742f7372632f6c6962636f72652f6f70732f61726974682e72730041f2d9c1000b0753657373696f6e0041f9d9c1000b0a56616c696461746f7273004183dac1000b0d53657373696f6e4c656e677468004190dac1000b0c43757272656e74496e64657800419cdac1000b0c43757272656e7453746172740041a8dac1000b11466f7263696e674e657753657373696f6e0041b9dac1000b104c6173744c656e6774684368616e67650041c9dac1000b0a4e6578744b6579466f720041d3dac1000b0d543a3a53657373696f6e4b65790041e0dac1000b114e65787453657373696f6e4c656e6774680041f1dac1000b1920546865206e6578742073657373696f6e206c656e6774682e00418adbc1000b2420546865206e657874206b657920666f72206120676976656e2076616c696461746f722e0041aedbc1000b3020426c6f636b206174207768696368207468652073657373696f6e206c656e677468206c617374206368616e6765642e0041dedbc1000b5e204e65772073657373696f6e206973206265696e6720666f72636564206973207468697320656e747279206578697374733b20696e20776869636820636173652c2074686520626f6f6c65616e2076616c756520697320776865746865720041bcdcc1000b6020746865206e65772073657373696f6e2073686f756c6420626520636f6e736964657265642061206e6f726d616c20726f746174696f6e202872657761726461626c6529206f7220657863657074696f6e616c2028736c61736861626c65292e00419cddc1000b282054696d657374616d70207768656e2063757272656e742073657373696f6e20737461727465642e0041c4ddc1000b1e2043757272656e7420696e646578206f66207468652073657373696f6e2e0041e2ddc1000b1f2043757272656e74206c656e677468206f66207468652073657373696f6e2e004181dec1000b1f205468652063757272656e7420736574206f662076616c696461746f72732e0041a0dec1000b077365745f6b65790041a7dec1000b0a7365745f6c656e6774680041b1dec1000b11666f7263655f6e65775f73657373696f6e0041c2dec1000b036b65790041c5dec1000b0e436f756e63696c4d6f74696f6e730041d3dec1000b0c5665633c543a3a486173683e0041dfdec1000b163c542061732054726169743e3a3a50726f706f73616c0041f5dec1000b06566f74696e670041fbdec1000b3a2850726f706f73616c496e6465782c207533322c205665633c543a3a4163636f756e7449643e2c205665633c543a3a4163636f756e7449643e290041b5dfc1000b122050726f706f73616c7320736f206661722e0041c7dfc1000b4920566f74657320666f72206120676976656e2070726f706f73616c3a202872657175697265645f7965735f766f7465732c207965735f766f746572732c206e6f5f766f74657273292e004190e0c1000b332041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e0041c3e0c1000b26205468652028686173686573206f662920746865206163746976652070726f706f73616c732e0041e9e0c1000b1c3c542061732073797374656d3a3a54726169743e3a3a4f726967696e004185e1c1000b097468726573686f6c6400418ee1c1000b1b426f783c3c542061732054726169743e3a3a50726f706f73616c3e0041b0e1c1000b222f636865636b6f75742f7372632f6c6962636f72652f736c6963652f6d6f642e72730041d2e1c1000b0a4e657753657373696f6e0041dce1c1000b55204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b0041b1e2c1000b22206e756d626572206173207468652074797065206d6967687420737567676573742e0041d3e2c1000b0b426c6f636b4e756d6265720041dee2c1000b312f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f73657373696f6e2f7372632f6c69622e727300418fe3c1000b05566f746564004194e3c1000b08417070726f76656400419ce3c1000b0b446973617070726f7665640041a7e3c1000b0845786563757465640041afe3c1000b412041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e0041f0e3c1000b352041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e0041a5e4c1000b312041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e0041d6e4c1000b422041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e67004198e5c1000b3d20612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e206173207533327320726573706563746976656c79292e0041d5e5c1000b592041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20753332292e0041aee6c1000b352f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f636f756e63696c2f7372632f6d6f74696f6e732e72730041e3e6c1000b19436f756e63696c4d6f74696f6e732050726f706f73616c4f660041fce6c1000b1770726f706f736572206e6f74206f6e20636f756e63696c004193e7c1000b1c436f756e63696c4d6f74696f6e732050726f706f73616c436f756e740041afe7c1000b18436f756e63696c4d6f74696f6e732050726f706f73616c730041c7e7c1000b15436f756e63696c4d6f74696f6e7320566f74696e670041dce7c1000b14766f746572206e6f74206f6e20636f756e63696c0041f0e7c1000b1370726f706f73616c206d757374206578697374004183e8c1000b106d69736d61746368656420696e646578004193e8c1000b166475706c696361746520766f74652069676e6f7265640041b0e8c1000b19617474656d707420746f20646976696465206279207a65726f0041d0e8c1000b222f636865636b6f75742f7372632f6c6962636f72652f6f70732f61726974682e72730041f2e8c1000b066d656d6f72790041f8e8c1000b0463616c6c0041fce8c1000b046e616d65004180e9c1000b344f6e20656e74727920746f207468652066756e6374696f6e20606d6f64756c65602063616e2774206265204e6f6e653b207165640041b4e9c1000b364f6e20656e74727920746f207468652066756e6374696f6e20606d6f64756c65602063616e277420626520604e6f6e65603b207165640041eae9c1000b03656e760041f0e9c1000b19617474656d707420746f20646976696465206279207a65726f004190eac1000b222f636865636b6f75742f7372632f6c6962636f72652f6f70732f61726974682e72730041b2eac1000b3373746f72616765206973206e6f74206e756c6c2c207468657265666f7265206d75737420626520612076616c696420747970650041e5eac1000b18616c7265616479206d757461626c7920626f72726f7765640041fdeac1000b10616c726561647920626f72726f77656400418debc1000b08636f6e3a73746f3a004195ebc1000b1354696d657374616d70204469645570646174650041a8ebc1000b2b54696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b0041d3ebc1000b332f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f74696d657374616d702f7372632f6c69622e7273004186ecc1000b1554696d657374616d7020426c6f636b506572696f6400419becc1000b0954696d657374616d700041a4ecc1000b034e6f770041a7ecc1000b09543a3a4d6f6d656e740041b0ecc1000b0b426c6f636b506572696f640041bbecc1000b094469645570646174650041c4ecc1000b2d20446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f0041f1ecc1000b3120546865206d696e696d756d2028616e6420616476697365642920706572696f64206265747765656e20626c6f636b732e0041a2edc1000b242043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e0041c6edc1000b0d54696d657374616d70204e6f770041d3edc1000b037365740041d6edc1000b036e6f770041dcedc1000b6c0100000000000000200000000000000003000000000000000300000000000000030000000100000001000000200000000000000003000000000000000300000000000000030000000100000002000000200000000000000003000000000000000300000000000000030000000041c8eec1000b4b54696d657374616d702062757420696e6372656d656e74206279206174206c65617374203c426c6f636b506572696f643e206265747765656e2073657175656e7469616c20626c6f636b73004193efc1000b2854696d657374616d702065787472696e736963206d75737420626520617420706f736974696f6e200041bbefc1000b3054696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b0041ebefc1000b046e6f64650041efefc1000b0e7375627374726174652d6e6f64650041fdefc1000b0a7372632f6c69622e7273004187f0c1000b1b42616420696e70757420646174612070726f766964656420746f200041a2f0c1000b0624206e616d650041a8f0c1000b1c5374616b696e672043757272656e7453657373696f6e5265776172640041c4f0c1000b125374616b696e67205374616b6552616e67650041d6f0c1000b1c5374616b696e672056616c696461746f72507265666572656e6365730041f2f0c1000b1c5374616b696e672043757272656e744e6f6d696e61746f7273466f7200418ef1c1000b155374616b696e6720466f7263696e674e65774572610041a3f1c1000b1b5374616b696e67204c6173744572614c656e6774684368616e67650041bef1c1000b165374616b696e672053657373696f6e735065724572610041d4f1c1000b125374616b696e672043757272656e744572610041e6f1c1000b1a5374616b696e67204e65787453657373696f6e73506572457261004180f2c1000b125374616b696e6720496e74656e74696f6e73004192f2c1000b1d5374616b696e67204d696e696d756d56616c696461746f72436f756e740041aff2c1000b165374616b696e672056616c696461746f72436f756e740041c5f2c1000b125374616b696e6720536c617368436f756e740041d7f2c1000b145374616b696e67204f66666c696e65536c6173680041ebf2c1000b1b5374616b696e672043757272656e744f66666c696e65536c617368004186f3c1000b155374616b696e672053657373696f6e52657761726400419bf3c1000b155374616b696e67204e6f6d696e61746f7273466f720041b0f3c1000b222f636865636b6f75742f7372632f6c6962636f72652f736c6963652f6d6f642e72730041e0f3c1000b232f636865636b6f75742f7372632f6c6962636f72652f736c6963652f736f72742e7273004183f4c1000b1c617373657274696f6e206661696c65643a206d6964203c3d206c656e00419ff4c1000b146c6962636f72652f736c6963652f6d6f642e72730041c0f4c1000b39617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f004180f5c1000b222f636865636b6f75742f7372632f6c6962636f72652f6f70732f61726974682e72730041b0f5c1000b19617474656d707420746f20646976696465206279207a65726f0041c9f5c1000b0f5374616b696e6720426f6e646167650041d8f5c1000b1e63616e6e6f74207472616e7366657220696c6c69717569642066756e64730041f6f5c1000b075374616b696e670041fdf5c1000b0e56616c696461746f72436f756e7400418bf6c1000b154d696e696d756d56616c696461746f72436f756e740041a0f6c1000b0e53657373696f6e735065724572610041aef6c1000b0d53657373696f6e5265776172640041bbf6c1000b0750657262696c6c0041c2f6c1000b0c4f66666c696e65536c6173680041cef6c1000b114f66666c696e65536c61736847726163650041dff6c1000b0f426f6e64696e674475726174696f6e0041eef6c1000b0a43757272656e744572610041f8f6c1000b1456616c696461746f72507265666572656e63657300418cf7c1000b1a56616c696461746f7250726566733c543a3a42616c616e63653e0041a6f7c1000b0a496e74656e74696f6e730041b0f7c1000b0a4e6f6d696e6174696e670041baf7c1000b0d4e6f6d696e61746f7273466f720041c7f7c1000b1443757272656e744e6f6d696e61746f7273466f720041dbf7c1000b1443757272656e7453657373696f6e5265776172640041eff7c1000b1343757272656e744f66666c696e65536c617368004182f8c1000b124e65787453657373696f6e73506572457261004194f8c1000b134c6173744572614c656e6774684368616e67650041a7f8c1000b0a5374616b6552616e67650041b1f8c1000b12506169724f663c543a3a42616c616e63653e0041c3f8c1000b07426f6e646167650041caf8c1000b0a536c617368436f756e740041d4f8c1000b0d466f7263696e674e65774572610041e1f8c1000b0228290041e3f8c1000b1a2057652061726520666f7263696e672061206e6577206572612e0041fdf8c1000b7420546865206e756d626572206f662074696d6573206120676976656e2076616c696461746f7220686173206265656e207265706f72746564206f66666c696e652e205468697320676574732064656372656d656e746564206279206f6e652065616368206572612074686174207061737365732e0041f1f9c1000b3d2054686520626c6f636b20617420776869636820746865206077686f6027732066756e6473206265636f6d6520656e746972656c79206c69717569642e0041aefac1000b3c20546865206869676865737420616e64206c6f77657374207374616b65642076616c696461746f7220736c61736861626c652062616c616e6365732e0041eafac1000b38205468652073657373696f6e20696e6465782061742077686963682074686520657261206c656e677468206c617374206368616e6765642e0041a2fbc1000b2420546865206e6578742076616c7565206f662073657373696f6e7320706572206572612e0041c6fbc1000b41204e6f6d696e61746f727320666f72206120706172746963756c6172206163636f756e74207468617420697320696e20616374696f6e207269676874206e6f772e004187fcc1000b25204e6f6d696e61746f727320666f72206120706172746963756c6172206163636f756e742e0041acfcc1000b2820416c6c206e6f6d696e61746f72202d3e206e6f6d696e65652072656c6174696f6e73686970732e0041d4fcc1000b2920416c6c20746865206163636f756e7473207769746820612064657369726520746f207374616b652e0041fdfcc1000b2220507265666572656e636573207468617420612076616c696461746f72206861732e00419ffdc1000b17205468652063757272656e742065726120696e6465782e0041b6fdc1000b2e20546865206c656e677468206f662074686520626f6e64696e67206475726174696f6e20696e20626c6f636b732e0041e4fdc1000b4e204e756d626572206f6620696e7374616e636573206f66206f66666c696e65207265706f727473206265666f726520736c617368696e6720626567696e7320666f722076616c696461746f72732e0041b2fec1000b5420536c6173682c207065722076616c696461746f7220746861742069732074616b656e20666f72207468652066697273742074696d6520746865792061726520666f756e6420746f206265206f66666c696e652e004186ffc1000b48204d6178696d756d207265776172642c207065722076616c696461746f722c20746861742069732070726f7669646564207065722061636365707461626c652073657373696f6e2e0041ceffc1000b2920546865206c656e677468206f662061207374616b696e672065726120696e2073657373696f6e732e0041f7ffc1000b50204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e0041c780c2000b2a2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e0041f180c2000b057374616b650041f680c2000b07756e7374616b650041fd80c2000b086e6f6d696e61746500418581c2000b0a756e6e6f6d696e61746500418f81c2000b1472656769737465725f707265666572656e6365730041a381c2000b147365745f73657373696f6e735f7065725f6572610041b781c2000b147365745f626f6e64696e675f6475726174696f6e0041cb81c2000b137365745f76616c696461746f725f636f756e740041de81c2000b0d666f7263655f6e65775f6572610041eb81c2000b177365745f6f66666c696e655f736c6173685f677261636500418282c2000b0d6170706c795f7265776172647300418f82c2000b10696e74656e74696f6e735f696e64657800419f82c2000b0570726566730041a482c2000b0c7461726765745f696e6465780041b082c2000b067461726765740041b682c2000b065265776172640041bc82c2000b0e4f66666c696e655761726e696e670041ca82c2000b4b204f6e652076616c696461746f722028616e64207468656972206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e00419583c2000b55204f6e652076616c696461746f722028616e64207468656972206e6f6d696e61746f72732920686173206265656e20676976656e2061206f66666c696e652d7761726e696e67202874686579277265207374696c6c0041ea83c2000b452077697468696e207468656972206772616365292e205468652061636372756564206e756d626572206f6620736c6173686573206973207265636f726465642c20746f6f2e0041af84c2000b3820416c6c2076616c696461746f72732068617665206265656e2072657761726465642062792074686520676976656e2062616c616e63652e0041e784c2000b312f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f7374616b696e672f7372632f6c69622e727300419885c2000b125374616b696e67204e6f6d696e6174696e670041aa85c2000b1f43616e6e6f74207374616b6520696620616c7265616479207374616b65642e0041c985c2000b2343616e6e6f74207374616b6520696620616c7265616479206e6f6d696e6174696e672e0041ec85c2000b2643616e6e6f74206e6f6d696e61746520696620616c7265616479206e6f6d696e6174696e672e00419286c2000b2243616e6e6f74206e6f6d696e61746520696620616c7265616479207374616b65642e0041b486c2000b1a4163636f756e74206d757374206265206e6f6d696e6174696e670041ce86c2000b14496e76616c69642074617267657420696e6465780041e286c2000b175374616b696e6720426f6e64696e674475726174696f6e0041f986c2000b3963616e6e6f7420756e7374616b65207768656e2074686572652061726520746f6f20666577207374616b6564207061727469636970616e74730041b287c2000b0d496e76616c696420696e6465780041bf87c2000b195374616b696e67204f66666c696e65536c61736847726163650041d887c2000b7f706f73206465726976656420636f72726563746c792066726f6d2053656c663a3a696e74656e74696f6e7328293b206170706c795f756e7374616b652063616e206f6e6c79206661696c20696620706f732077726f6e673b2053656c663a3a696e74656e74696f6e73282920646f65736e2774206368616e67653b207165640041d788c2000b2972656163686564206d6178696d756d2064657074682c2063616e6e6f74206d616b6520612063616c6c00418089c2000b236e6f7420656e6f7567682067617320746f2070617920626173652063616c6c206665650041a389c2000b24766d20657865637574652072657475726e6564206572726f72207768696c652063616c6c0041c789c2000b226e6f7420656e6f7567682067617320746f20706179207472616e73666572206665650041e989c2000b2472656163686564206d6178696d756d2064657074682c2063616e6e6f742063726561746500418d8ac2000b256e6f7420656e6f7567682067617320746f20706179206261736520637265617465206665650041b28ac2000b17636f6e747261637420616c7265616479206578697374730041c98ac2000b26766d20657865637574652072657475726e6564206572726f72207768696c65206372656174650041ef8ac2000b7073657269616c697a656420617267732073686f756c642062652070726f7669646564206279207468652072756e74696d653b0a090909636f72726563746c792073657269616c697a656420646174612073686f756c6420626520646573657269616c697a61626c653b0a0909097165640041df8bc2000b3f2f55736572732f6761762f436f72652f7375627374726174652f636f72652f73722d73616e64626f782f7372632f2e2e2f776974686f75745f7374642e727300419e8cc2000b2452657475726e207479706573206c656e6774682073686f756c642062652030206f7220310041c28cc2000b054576656e740041c78cc2000b0673797374656d0041cd8cc2000b09636f6e73656e7375730041d68cc2000b0862616c616e6365730041de8cc2000b0974696d657374616d700041e78cc2000b0773657373696f6e0041ee8cc2000b077374616b696e670041f58cc2000b0964656d6f63726163790041fe8cc2000b07636f756e63696c0041858dc2000b0e636f756e63696c5f766f74696e670041938dc2000b0f636f756e63696c5f6d6f74696f6e730041a28dc2000b0874726561737572790041aa8dc2000b08636f6e74726163740041b28dc2000b1e6e6f7420616c6c6f77656420746f206661696c20696e2072756e74696d650041d08dc2000b14436f756e63696c20566f74696e67506572696f640041e48dc2000b14436f756e63696c204465736972656453656174730041f88dc2000b15436f756e63696c20416374697665436f756e63696c00418d8ec2000b14436f756e63696c204e65787446696e616c6973650041a18ec2000b14436f756e63696c205465726d4475726174696f6e0041b58ec2000b1c436f756e63696c2050726573656e746174696f6e4475726174696f6e0041d18ec2000b0e436f756e63696c20566f746572730041df8ec2000b18436f756e63696c20536e617073686f7465645374616b65730041f78ec2000b12436f756e63696c204361727279436f756e740041898fc2000b13436f756e63696c204c6561646572626f61726400419c8fc2000b16436f756e63696c205265676973746572496e666f4f660041b28fc2000b12436f756e63696c2043616e646964617465730041c48fc2000b16436f756e63696c2043616e646964617465436f756e740041da8fc2000b11436f756e63696c20566f7465436f756e740041eb8fc2000b15436f756e63696c2043616e646964616379426f6e6400418090c2000b3566696e616c6973652063616e206f6e6c792062652063616c6c656420616674657220612074616c6c7920697320737461727465642e0041c090c2000b222f636865636b6f75742f7372632f6c6962636f72652f736c6963652f6d6f642e72730041f090c2000b19617474656d707420746f20646976696465206279207a65726f00419091c2000b222f636865636b6f75742f7372632f6c6962636f72652f6f70732f61726974682e72730041c091c2000b39617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f0041f991c2000b07436f756e63696c00418092c2000b0d43616e646964616379426f6e6400418d92c2000b0a566f74696e67426f6e6400419792c2000b1450726573656e74536c617368506572566f7465720041ab92c2000b0a4361727279436f756e740041b592c2000b1450726573656e746174696f6e4475726174696f6e0041c992c2000b13496e6163746976654772616365506572696f640041dc92c2000b09566f7465496e6465780041e592c2000b0c5465726d4475726174696f6e0041f192c2000b0c4465736972656453656174730041fd92c2000b0d416374697665436f756e63696c00418a93c2000b235665633c28543a3a4163636f756e7449642c20543a3a426c6f636b4e756d626572293e0041ad93c2000b09566f7465436f756e740041b693c2000b0b417070726f76616c734f660041c193c2000b095665633c626f6f6c3e0041ca93c2000b0e5265676973746572496e666f4f660041d893c2000b1028566f7465496e6465782c20753332290041e893c2000b0c4c6173744163746976654f660041f493c2000b06566f746572730041fa93c2000b0a43616e6469646174657300418494c2000b0e43616e646964617465436f756e7400419294c2000b0c4e65787446696e616c69736500419e94c2000b2828543a3a426c6f636b4e756d6265722c207533322c205665633c543a3a4163636f756e7449643e290041c694c2000b10536e617073686f7465645374616b65730041d694c2000b0f5665633c543a3a42616c616e63653e0041e594c2000b0b4c6561646572626f6172640041f094c2000b1f5665633c28543a3a42616c616e63652c20543a3a4163636f756e744964293e00418f95c2000b382047657420746865206c6561646572626f6172642069662077653b726520696e207468652070726573656e746174696f6e2070686173652e0041c795c2000b3a20546865207374616b6573206173207468657920776572652061742074686520706f696e7420746861742074686520766f746520656e6465642e00418196c2000b4820546865206163636f756e747320686f6c64696e672074686520736561747320746861742077696c6c206265636f6d652066726565206f6e20746865206e6578742074616c6c792e0041c996c2000b1c205468652070726573656e742063616e646964617465206c6973742e0041e596c2000b18205468652070726573656e7420766f746572206c6973742e0041fd96c2000b5f2054686520766f746520696e64657820616e64206c69737420736c6f742074686174207468652063616e646964617465206077686f60207761732072656769737465726564206f7220604e6f6e6560206966207468657920617265206e6f740041dc97c2000b162063757272656e746c7920726567697374657265642e0041f297c2000b4020546865206c61737420636c656172656420766f746520696e6465782074686174207468697320766f74657220776173206c617374206163746976652061742e0041b298c2000b412054686520746f74616c206e756d626572206f6620766f746573207468617420686176652068617070656e6564206f722061726520696e2070726f67726573732e0041f398c2000b5b205468652063757272656e7420636f756e63696c2e205768656e2074686572652773206120766f746520676f696e67206f6e2c20746869732073686f756c64207374696c6c206265207573656420666f72206578656375746976650041ce99c2000b09206d6174746572732e0041d799c2000b3a204e756d626572206f66206163636f756e747320746861742073686f756c642062652073697474696e67206f6e2074686520636f756e63696c2e0041919ac2000b2620486f77206c6f6e67206561636820706f736974696f6e2069732061637469766520666f722e0041b79ac2000b2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e0041e59ac2000b5a20486f77206d616e7920766f746573206e65656420746f20676f206279206166746572206120766f7465722773206c61737420766f7465206265666f726520746865792063616e206265207265617065642069662074686569720041bf9bc2000b1420617070726f76616c7320617265206d6f6f742e0041d39bc2000b4f20486f77206c6f6e6720746f2067697665206561636820746f702063616e64696461746520746f2070726573656e74207468656d73656c7665732061667465722074686520766f746520656e64732e0041a29cc2000b4d20486f77206d616e792072756e6e6572732d75702073686f756c64206861766520746865697220617070726f76616c73207065727369737420756e74696c20746865206e65787420766f74652e0041ef9cc2000b43205468652070756e6973686d656e742c2070657220766f7465722c20696620796f752070726f7669646520616e20696e76616c69642070726573656e746174696f6e2e0041b29dc2000b4220486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f2062652061626c6520746f207375626d697420766f7465732e0041f49dc2000b4120486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e0041b59ec2000b0d7365745f617070726f76616c730041c29ec2000b13726561705f696e6163746976655f766f7465720041d59ec2000b0d726574726163745f766f7465720041e29ec2000b107375626d69745f63616e6469646163790041f29ec2000b0e70726573656e745f77696e6e65720041809fc2000b117365745f646573697265645f73656174730041919fc2000b0d72656d6f76655f6d656d62657200419e9fc2000b197365745f70726573656e746174696f6e5f6475726174696f6e0041b79fc2000b117365745f7465726d5f6475726174696f6e0041c89fc2000b05636f756e740041cd9fc2000b26416464726573733c543a3a4163636f756e7449642c20543a3a4163636f756e74496e6465783e0041f39fc2000b0963616e6469646174650041fc9fc2000b05746f74616c004181a0c2000b05696e646578004186a0c2000b04736c6f7400418aa0c2000b0e7265706f727465725f696e646578004198a0c2000b0977686f5f696e6465780041a1a0c2000b12617373756d65645f766f74655f696e6465780041b3a0c2000b05766f7465730041b8a0c2000b0b566f7465725265617065640041c3a0c2000b10426164526561706572536c61736865640041d3a0c2000b0c54616c6c79537461727465640041dfa0c2000b0e54616c6c7946696e616c697365640041eda0c2000b5a20412074616c6c792028666f7220617070726f76616c20766f746573206f6620636f756e63696c2073656174287329292068617320656e646564202877697468206f6e65206f72206d6f7265206e6577206d656d62657273292e0041c7a1c2000b0e5665633c4163636f756e7449643e0041d5a1c2000b3d20412074616c6c792028666f7220617070726f76616c20766f746573206f6620636f756e63696c2073656174287329292068617320737461727465642e004192a2c2000b0f20736c6173686564207265617065720041a1a2c2000b152072656170656420766f7465722c207265617065720041b6a2c2000b332f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f636f756e63696c2f7372632f73656174732e72730041e9a2c2000b2e6e6f20617070726f76616c206368616e67657320647572696e672070726573656e746174696f6e20706572696f64004197a3c2000b14696e636f727265637420766f746520696e6465780041aba3c2000b14436f756e63696c204c6173744163746976654f660041bfa3c2000b12436f756e63696c20566f74696e67426f6e640041d1a3c2000b13436f756e63696c20417070726f76616c734f660041e4a3c2000b2663616e6e6f74207265617020647572696e672070726573656e746174696f6e20706572696f6400418aa4c2000b187265706f72746572206d757374206265206120766f7465720041a2a4c2000b16766f746520696e646578206e6f742063757272656e740041b8a4c2000b1e63616e6e6f74207265617020647572696e672067726163652070657269640041d6a4c2000b2c74617267657420666f7220696e616374697669747920636c65616e7570206d75737420626520616374697665004182a5c2000b1b436f756e63696c20496e6163746976654772616365506572696f6400419da5c2000b106261642074617267657420696e6465780041ada5c2000b12626164207265706f7274657220696e6465780041bfa5c2000b1e63616e6e6f742072657472616374207768656e2070726573656e74696e670041dda5c2000b1863616e6e6f742072657472616374206e6f6e2d766f7465720041f5a5c2000b1872657472616374696f6e20696e64657820696e76616c696400418da6c2000b1972657472616374696f6e20696e646578206d69736d617463680041a6a6c2000b1e6475706c69636174652063616e646964617465207375626d697373696f6e0041c4a6c2000b16696e76616c69642063616e64696461746520736c6f740041daa6c2000b1e63616e64696461746520686173206e6f7420656e6f7567682066756e64730041f8a6c2000b11696e646578206e6f742063757272656e74004189a7c2000b2d63616e6e6f742070726573656e74206f757473696465206f662070726573656e746174696f6e20706572696f640041b6a7c2000b2e70726573656e746572206d75737420686176652073756666696369656e7420736c61736861626c652066756e64730041e4a7c2000b316c6561646572626f617264206d757374206578697374207768696c652070726573656e7420706861736520616374697665004195a8c2000b3663616e646964617465206d757374206e6f7420666f726d2061206475706c696361746564206d656d62657220696620656c65637465640041cba8c2000b2363616e646964617465206e6f7420776f72746879206f66206c6561646572626f6172640041eea8c2000b2370726573656e7465642063616e646964617465206d7573742062652063757272656e74004191a9c2000b1c436f756e63696c2050726573656e74536c617368506572566f7465720041ada9c2000b166475706c69636174652070726573656e746174696f6e0041c3a9c2000b0f696e636f727265637420746f74616c0041d2a9c2000b28626164206f726967696e3a20657870656374656420746f206265206120726f6f74206f726967696e0041faa9c2000b2a626164206f726967696e3a20657870656374656420746f2062652061207369676e6564206f726967696e0041a4aac2000b2d626164206f726967696e3a20657870656374656420746f20626520616e20696e686572656e74206f726967696e0041d1aac2000b063a617574683a0041d7aac2000b1442616c616e636573204672656542616c616e63650041ebaac2000b1b42616c616e636573205472616e73616374696f6e42617365466565004186abc2000b1b42616c616e636573205472616e73616374696f6e427974654665650041a1abc2000b1b42616c616e636573204578697374656e7469616c4465706f7369740041bcabc2000b1642616c616e63657320546f74616c49737375616e63650041d2abc2000b1842616c616e63657320526573657276656442616c616e63650041eaabc2000b1353797374656d204163636f756e744e6f6e63650041fdabc2000b103a65787472696e7369635f696e64657800418dacc2000b0d53797374656d204576656e747300419aacc2000b1d436f6e73656e737573204f726967696e616c417574686f7269746965730041b7acc2000b036c656e0041baacc2000b0d53797374656d204469676573740041c7acc2000b1053797374656d20426c6f636b486173680041d8acc2000b04000000000041dcacc2000b0d53797374656d204e756d6265720041e9acc2000b1153797374656d20506172656e74486173680041faacc2000b1553797374656d2045787472696e73696373526f6f7400418fadc2000b1153797374656d2052616e646f6d536565640041a0adc2000b1e426c6f636b206e756d626572206d6179206e65766572206265207a65726f0041beadc2000b302f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f73797374656d2f7372632f6c69622e72730041eeadc2000b1453797374656d2045787472696e73696344617461004182aec2000b0653797374656d004188aec2000b0c4163636f756e744e6f6e6365004194aec2000b08543a3a496e64657800419caec2000b0e45787472696e736963436f756e740041aaaec2000b09426c6f636b486173680041b3aec2000b0d45787472696e736963446174610041c0aec2000b075665633c75383e0041c7aec2000b0a52616e646f6d536565640041d1aec2000b064e756d6265720041d7aec2000b0a506172656e74486173680041e1aec2000b0e45787472696e73696373526f6f740041efaec2000b064469676573740041f5aec2000b09543a3a4469676573740041feaec2000b064576656e7473004184afc2000b1a5665633c4576656e745265636f72643c543a3a4576656e743e3e00419eafc2000b42205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e0041e0afc2000b1553797374656d2045787472696e736963436f756e740041f5afc2000b1442616c616e636573204372656174696f6e466565004189b0c2000b1442616c616e636573205472616e7366657246656500419db0c2000b1042616c616e63657320456e756d5365740041b0b0c2000b222f636865636b6f75742f7372632f6c6962636f72652f6f70732f61726974682e72730041d2b0c2000b0842616c616e6365730041dab0c2000b0d546f74616c49737375616e63650041e7b0c2000b124578697374656e7469616c4465706f7369740041f9b0c2000b0d5265636c61696d526562617465004186b1c2000b0b5472616e73666572466565004191b1c2000b0b4372656174696f6e46656500419cb1c2000b0b4e657874456e756d5365740041a7b1c2000b0f543a3a4163636f756e74496e6465780041b6b1c2000b07456e756d5365740041bdb1c2000b0b4672656542616c616e63650041c8b1c2000b0f526573657276656442616c616e63650041d7b1c2000b125472616e73616374696f6e426173654665650041e9b1c2000b125472616e73616374696f6e427974654665650041fbb1c2000b43205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e0041beb2c2000b37205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b2074686520626173652e0041f5b2c2000b5c2054686520616d6f756e74206f66207468652062616c616e6365206f66206120676976656e206163636f756e742074686174206973206578746572616c6c792072657365727665643b20746869732063616e207374696c6c206765740041d1b3c2000b2720736c61736865642c20627574206765747320736c6173686564206c617374206f6620616c6c2e0041f8b3c2000b5b20546869732062616c616e63652069732061202772657365727665272062616c616e63652074686174206f746865722073756273797374656d732075736520696e206f7264657220746f2073657420617369646520746f6b656e730041d3b4c2000b5c207468617420617265207374696c6c20276f776e65642720627920746865206163636f756e7420686f6c6465722c206275742077686963682061726520756e7370656e6461626c652e20285468697320697320646966666572656e740041afb5c2000b4a20616e642077686f6c6c7920756e72656c6174656420746f207468652060426f6e64616765602073797374656d207573656420696e20746865207374616b696e67206d6f64756c652e290041f9b5c2000b5d205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e2074686973202772657365727665206163636f756e74270041d6b6c2000b2d2069732064656c657465643a207370656369666963616c6c792c2060526573657276656442616c616e6365602e004183b7c2000b53206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c6574656420696620604672656542616c616e63656020697320616c736f207a65726f2028697420616c736f20676574730041d6b7c2000b4520636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e00419bb8c2000b2720546865202766726565272062616c616e6365206f66206120676976656e206163636f756e742e0041c2b8c2000b53205468697320697320746865206f6e6c792062616c616e63652074686174206d61747465727320696e207465726d73206f66206d6f7374206f7065726174696f6e73206f6e20746f6b656e732e204974206973004195b9c2000b5a20616c6f6e65207573656420746f2064657465726d696e65207468652062616c616e6365207768656e20696e2074686520636f6e747261637420657865637574696f6e20656e7669726f6e6d656e742e205768656e20746869730041efb9c2000b552062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e20746865202763757272656e74206163636f756e74272069730041c4bac2000b4f2064656c657465643a207370656369666963616c6c7920604672656542616c616e6365602e20467572746865726d6f72652c20604f6e4672656542616c616e63655a65726f602063616c6c6261636b004193bbc2000b5020697320696e766f6b65642c20676976696e672061206368616e636520746f2065787465726e616c206d6f64756c657320746f20636c65616e75702064617461206173736f63696174656420776974680041e3bbc2000b15207468652064656c65746564206163636f756e742e0041f8bbc2000b57206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c657465642069662060526573657276656442616c616e63656020697320616c736f207a65726f2028697420616c736f20676574730041cfbcc2000b162054686520656e756d65726174696f6e20736574732e0041e5bcc2000b1f20546865206e657874206672656520656e756d65726174696f6e207365742e004184bdc2000b49205468652066656520726571756972656420746f2063726561746520616e206163636f756e742e204174206c6561737420617320626967206173205265636c61696d5265626174652e0041cdbdc2000b25205468652066656520726571756972656420746f206d616b652061207472616e736665722e0041f2bdc2000b4a2054686520616d6f756e7420637265646974656420746f20612064657374696e6174696f6e2773206163636f756e742077686f736520696e64657820776173207265636c61696d65642e0041bcbec2000b3420546865206d696e696d756d20616d6f756e7420616c6c6f77656420746f206b65657020616e206163636f756e74206f70656e2e0041f0bec2000b292054686520746f74616c20616d6f756e74206f66207374616b65206f6e207468652073797374656d2e004199bfc2000b2262656e6566696369617279206163636f756e74206d757374207072652d65786973740041bbbfc2000b1442616c616e636573204e657874456e756d5365740041cfbfc2000b1642616c616e636573205265636c61696d5265626174650041f0bfc2000b39617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f0041a9c0c2000b156e6f7420656e6f75676820667265652066756e64730041bec0c2000b087472616e736665720041c6c0c2000b0b7365745f62616c616e63650041d1c0c2000b0377686f0041d4c0c2000b29526177416464726573733c543a3a4163636f756e7449642c20543a3a4163636f756e74496e6465783e0041fdc0c2000b0466726565004181c1c2000b087265736572766564004189c1c2000b046465737400418dc1c2000b09436f6e73656e737573004196c1c2000b134f726967696e616c417574686f7269746965730041a9c1c2000b125665633c543a3a53657373696f6e4b65793e0041bbc1c2000b127265706f72745f6d69736265686176696f720041cdc1c2000b0c6e6f74655f6f66666c696e650041d9c1c2000b0672656d61726b0041dfc1c2000b087365745f636f64650041e7c1c2000b0b7365745f73746f726167650041f2c1c2000b056974656d730041f7c1c2000b0d5665633c4b657956616c75653e004184c2c2000b036e6577004187c2c2000b136f66666c696e655f76616c5f696e646963657300419ac2c2000b085665633c7533323e0041a2c2c2000b067265706f72740041a8c2c2000b2a4d69736265686176696f725265706f72743c543a3a486173682c20543a3a426c6f636b4e756d6265723e0041d2c2c2000b322f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f62616c616e6365732f7372632f6c69622e7273004184c3c2000b332f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f636f6e73656e7375732f7372632f6c69622e72730041b7c3c2000b0a4e65774163636f756e740041c1c3c2000b0d5265617065644163636f756e740041cec3c2000b085472616e736665720041d6c3c2000b2c205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c75652c2066656573292e004182c4c2000b1720416e206163636f756e7420776173207265617065642e004199c4c2000b1b2041206e6577206163636f756e742077617320637265617465642e0041b4c4c2000b0c4163636f756e74496e6465780041c0c4c2000b114e65774163636f756e744f7574636f6d650041d1c4c2000b1d62616c616e636520746f6f206c6f7720746f2073656e642076616c75650041eec4c2000b1f76616c756520746f6f206c6f7720746f20637265617465206163636f756e7400418dc5c2000b2d64657374696e6174696f6e2062616c616e636520746f6f206869676820746f20726563656976652076616c75650041bcc5c2000b04010000000041c0c5c2000b240100000000000000200000000000000003000000000000000300000000000000030000000041e4c5c2000b053a636f64650041e9c5c2000b2b6e6f74655f6f66666c696e652065787472696e736963206d75737420626520617420706f736974696f6e20004194c6c2000b0d20696e2074686520626c6f636b0041a1c6c2000b2853746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e0041c9c6c2000b332f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f6578656375746976652f7372632f6c69622e72730041fcc6c2000b38617373657274696f6e206661696c65643a206865616465722e6469676573742829203d3d206e65775f6865616465722e64696765737428290041b4c7c2000b28416c6c2065787472696e736963732073686f756c642062652070726f7065726c79207369676e65640041dcc7c2000b38416c6c2065787472696e736963732073686f756c6420686176652073656e6465722061626c6520746f207061792074686569722066656573004194c8c2000b2c416c6c2065787472696e736963732073686f756c6420686176652074686520636f7272656374206e6f6e63650041c0c8c2000b245472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642e0041e4c8c2000b1c506172656e7420686173682073686f756c642062652076616c69642e004180c9c2000b15696e76616c6964206163636f756e7420696e646578004195c9c2000b0c547265617375727920506f740041b0c9c2000b19617474656d707420746f20646976696465206279207a65726f0041d0c9c2000b222f636865636b6f75742f7372632f6c6962636f72652f6f70732f61726974682e72730041f2c9c2000b1a626c6f636b20676173206c696d6974206973207265616368656400418ccac2000b276f766572666c6f77206d756c7469706c79696e6720676173206c696d69742062792070726963650041b3cac2000b246e6f7420656e6f7567682066756e647320666f72207472616e73616374696f6e206665650041d7cac2000b145472656173757279205370656e64506572696f640041ebcac2000b12547265617375727920417070726f76616c730041fdcac2000b0d5472656173757279204275726e004190cbc2000b39617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f0041c9cbc2000b0854726561737572790041d1cbc2000b0c50726f706f73616c426f6e640041ddcbc2000b075065726d696c6c0041e4cbc2000b1350726f706f73616c426f6e644d696e696d756d0041f7cbc2000b0a543a3a42616c616e6365004181ccc2000b0b5370656e64506572696f6400418cccc2000b044275726e004190ccc2000b03506f74004193ccc2000b0d50726f706f73616c436f756e740041a0ccc2000b0d50726f706f73616c496e6465780041adccc2000b2250726f706f73616c3c543a3a4163636f756e7449642c20543a3a42616c616e63653e0041cfccc2000b09417070726f76616c730041d8ccc2000b125665633c50726f706f73616c496e6465783e0041eaccc2000b3e2050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e0041a8cdc2000b1f2050726f706f73616c7320746861742068617665206265656e206d6164652e0041c7cdc2000b29204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e0041f0cdc2000b3320546f74616c2066756e647320617661696c61626c6520746f2074686973206d6f64756c6520666f72207370656e64696e672e0041a3cec2000b442050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e0041e7cec2000b2220506572696f64206265747765656e2073756363657373697665207370656e64732e004189cfc2000b52204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e0041dbcfc2000b542050726f706f7274696f6e206f662066756e647320746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c61636520612070726f706f73616c2e20416e2061636365707465640041afd0c2000b372070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f65736e27742e0041e6d0c2000b0d70726f706f73655f7370656e640041f3d0c2000b077365745f706f740041fad0c2000b09636f6e666967757265004183d1c2000b0f72656a6563745f70726f706f73616c004192d1c2000b10617070726f76655f70726f706f73616c0041a2d1c2000b0b70726f706f73616c5f69640041add1c2000b0a726f706f73616c5f69640041b7d1c2000b0d70726f706f73616c5f626f6e640041c4d1c2000b1570726f706f73616c5f626f6e645f6d696e696d756d0041d9d1c2000b0c7370656e645f706572696f640041e5d1c2000b046275726e0041e9d1c2000b076e65775f706f740041f0d1c2000b0576616c75650041f5d1c2000b0b62656e6566696369617279004180d2c2000b0c543a3a4163636f756e74496400418cd2c2000b1254726561737572792050726f706f73616c730041a0d2c2000b480100000000000000200000000000000003000000000000000300000000000000030000000100000001000000200000000000000003000000000000000300000000000000030000000041e8d2c2000b116c6962636f72652f726573756c742e72730041f9d2c2000b023a200041fbd2c2000b0850726f706f736564004183d3c2000b085370656e64696e6700418bd3c2000b0741776172646564004192d3c2000b054275726e74004197d3c2000b08526f6c6c6f76657200419fd3c2000b4c205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e0041ebd3c2000b2320536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e00418ed4c2000b2020536f6d652066756e64732068617665206265656e20616c6c6f63617465642e0041aed4c2000b0742616c616e63650041b5d4c2000b094163636f756e7449640041bed4c2000b3a205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e0041f8d4c2000b0e204e65772070726f706f73616c2e004186d5c2000b322f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f74726561737572792f7372632f6c69622e72730041b8d5c2000b1c54726561737572792050726f706f73616c426f6e644d696e696d756d0041d4d5c2000b1554726561737572792050726f706f73616c426f6e640041e9d5c2000b1654726561737572792050726f706f73616c436f756e740041ffd5c2000b1a50726f706f73657227732062616c616e636520746f6f206c6f77004199d6c2000b194e6f2070726f706f73616c206174207468617420696e6465780041b8d6c2000b000041b8d6c2000b17436f756e63696c566f74696e672050726f706f73616c730041cfd6c2000b18436f756e63696c566f74696e672050726f706f73616c4f660041e7d6c2000b1c436f756e63696c566f74696e67205665746f656450726f706f73616c004183d7c2000b0f47757275206d656469746174696f6e004192d7c2000b0d436f756e63696c566f74696e6700419fd7c2000b0d436f6f6c6f6666506572696f640041acd7c2000b0e543a3a426c6f636b4e756d6265720041bad7c2000b0c566f74696e67506572696f640041c6d7c2000b0950726f706f73616c730041cfd7c2000b1e5665633c28543a3a426c6f636b4e756d6265722c20543a3a48617368293e0041edd7c2000b0a50726f706f73616c4f660041f7d7c2000b07543a3a486173680041fed7c2000b0b543a3a50726f706f73616c004189d8c2000b0e50726f706f73616c566f74657273004197d8c2000b115665633c543a3a4163636f756e7449643e0041a8d8c2000b0d436f756e63696c566f74654f660041b5d8c2000b1728543a3a486173682c20543a3a4163636f756e744964290041ccd8c2000b04626f6f6c0041d0d8c2000b0e5665746f656450726f706f73616c0041ded8c2000b2328543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e29004181d9c2000b064d6f64756c65004187d9c2000b0443616c6c00418bd9c2000b0770726f706f7365004192d9c2000b04766f7465004196d9c2000b047665746f00419ad9c2000b127365745f636f6f6c6f66665f706572696f640041acd9c2000b117365745f766f74696e675f706572696f640041bdd9c2000b06626c6f636b730041c3d9c2000b066f726967696e0041c9d9c2000b09543a3a4f726967696e0041d2d9c2000b0d70726f706f73616c5f686173680041dfd9c2000b0870726f706f73616c0041e7d9c2000b07617070726f76650041eed9c2000b10426f783c543a3a50726f706f73616c3e0041fed9c2000b1054616c6c7943616e63656c6174696f6e00418edac2000b0f54616c6c795265666572656e64756d00419ddac2000b33204120766f74696e672074616c6c79206861732068617070656e656420666f722061207265666572656e64756d20766f74652e0041d0dac2000b28204c61737420746872656520617265207965732c206e6f2c206162737461696e20636f756e74732e0041f8dac2000b3f204120766f74696e672074616c6c79206861732068617070656e656420666f722061207265666572656e64756d2063616e63656c6174696f6e20766f74652e0041b7dbc2000b04486173680041bbdbc2000b037533320041c0dbc2000b222f636865636b6f75742f7372632f6c6962636f72652f736c6963652f6d6f642e72730041f0dbc2000b1f2f636865636b6f75742f7372632f6c6962616c6c6f632f736c6963652e727300418fdcc2000b1b436f756e63696c566f74696e6720436f756e63696c566f74654f660041aadcc2000b28696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64650041d2dcc2000b342f55736572732f6761762f436f72652f7375627374726174652f73726d6c2f636f756e63696c2f7372632f766f74696e672e7273004186ddc2000b1a436f756e63696c566f74696e6720566f74696e67506572696f640041a0ddc2000b2070726f706f73657220776f756c64206e6f74206265206f6e20636f756e63696c0041c0ddc2000b1f6475706c69636174652070726f706f73616c73206e6f7420616c6c6f7765640041dfddc2000b1270726f706f73616c206973207665746f65640041f1ddc2000b1c436f756e63696c566f74696e672050726f706f73616c566f7465727300418ddec2000b2e6f6e6c7920636f756e63696c6c6f7273206d617920766f7465206f6e20636f756e63696c2070726f706f73616c730041bbdec2000b2b6f6e6c7920636f756e63696c6c6f7273206d6179207665746f20636f756e63696c2070726f706f73616c730041e6dec2000b2070726f706f73616c206d75737420657869737420746f206265207665746f6564004186dfc2000b1b436f756e63696c566f74696e6720436f6f6c6f6666506572696f640041a1dfc2000b2a6120636f756e63696c6c6f72206d6179206e6f74207665746f20612070726f706f73616c2074776963650041cbdfc2000b235f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e00b685020b2e64656275675f696e666fd00100000400000000000401000000001c00410000000000000051000000025f000000310000000503a80110005f000000033c0000005f000000000404450000006900000005660000000700065f000000310000005f000000065f000000310000005f000000065f000000310000005f000000076d000000077200000008be010000870000000404097d000000000982000000010008c5010000870000000101097d000000000982000000010000078e00000008be010000af0000000404099300000000099800000001099d0000000209a7000000030008c5010000e5000000010109930000000009c50000000109d00000000209d60000000309e000000004099d00000005000007f800000008cc0100000a01000002020903010000000906010000010008c50100000a01000001010903010000000906010000010ac11c0000111d000001260301000007110100000715010000071801000008be010000230100000404091b010000000920010000010008c5010000460100000101092c01000000093101000001093701000002093e010000030008be0100006b010000040409500100000009530100000109590100000209630100000300000000000579000000070405c2000000070105ff000000070200ba010000040000000000040b000000001c00410000004100000051000000260100000f000000076d0000000c72000000070e04000007180f00000a452100009021000002160c010aa0210000e721000002a209010a79250000c125000002130b01000007e10100000dd319000004040ee50100008c00000004000e74020000a50000000100000007ed0100000db019000004040ff5010000192e000004000000077c02000010c319000000010007ab15000007af15000007180f00000ac82300002d24000003670301000007302400000a342400005d24000003d90101000a682400005d2400000306030100000771010000077701000011c50100009d0100000101098301000000099401000001000007580c000012260100000f000000525e00008b5e000001f4020deb19000008040ee10100006800000004000fde190000222e000004040ee21900007e01000001000af32100005222000001b001010a7e220000db2200000184020113d92000002821000001d7010000077101000010e41900000001138d240000b924000004710107180f000013c1240000b924000004a30113c31b0000710100000499010013991b000071010000044d010000005d0000000400000000000401000000001c0041000000da00000051000000065f0000002b0000005f00000003360000005f000000000414c5010000b0010000076d000000071101000007150100000c1801000000000c720000000cf80000000000c4090000040000000000040b000000001c0041000000f800000051000000ee230100a30100000771010000077701000007b401000007ba01000015bf0100004f00000001740503a05010009e0300000d8d03000008040ecf0100009603000004000f74030000cc01000002040f7f030000cc01000002060e83030000fc08000001080e88030000fc0800000108000d2203000038040ed60100004f00000004000edb0100009f0300000408000dfc02000004040ee1010000b603000004000000000007580c00000deb19000008040ee10100000104000004000fde190000222e000004040ee21900000e0100000100130c1a0000641a00000b5a0113891a0000da1a00000b95010000077101000010e4190000000113991b0000710100000a4d0107180f000013c31b0000710100000a9901000007ec1a00000df01a00000c040ef0080000c700000004000f7f030000222e000004080af81a0000da1a000012680101000007421b00000d491b00000c040eec1a00003901000004000a501b00008b1b00000cab01010000071101000016ee230100a30100009d5e0000a20c0000023702176706000000000000023802188e0700002024010001000000037d0118e6030000202401000100000005270219d9030000202401000100000004710300001834080000212401002d000000037d01181b080000212401002d0000000fd60818f0070000212401002d0000000e0b0318a8070000212401002d0000000d8505179b0700001800000005cc0918d7070000262401000b00000005870919f3030000262401000b00000005570900001802080000312401000c00000005cd09193907000031240100070000000d8505186b08000038240100050000000d85051a530800003824010005000000109c0000000000001889080000772401001200000003820118b5080000802401000900000007a5031896080000802401000900000011490618c2070000802401000900000007a50319b5070000802401000900000005680f0000000018dc0800008a2401000c000000038b0119cf0800008a2401000c00000008cb090000177c010000300000000239021756010000500000000cac0117fb00000070000000126a011bef000000900000000b961cef040000b00000000b5f1d26010000be240100080000000b6a1a15010000be240100080000000a9a001e4c5b0000ca2401000b0000000b6e00000000194d070000f424010052000000023a021f3c010000c8000000023a02000000048e0000003703000020ac00000021f5080000000c00076d00000007e10100000dc202000004040ee50100002504000004000e740200005104000001000007180f00000a210f00006c0f0000049402010a790f0000c10f0000046e03010a210f00006c0f000004940201000dd319000004040ee50100003804000004000e74020000660400000100000007ed0100000d3202000004040ef5010000ec0800000400000db019000004040ff5010000192e000004000000077c0200001083020000000110670d0000000110b90d0000000110c3190000000100077200000022200d000008040e800c0000860400000400000d8200000008040ef50100004e09000004000022a00d0000080423b10400000820200024c40400000400000d7d00000008040faa0b00007d0000000400000d8200000008040faa0b00007d00000004000ff5010000222e00000404000007f800000025e218000001010a151900006e19000009e9020100000711010000071501000007180100000dd50c000024040e990c00002b05000004000ea20c0000740500000408002223010000080423430500000820200024560500000400000d1b01000008040faa0b00005a0100000400000d2001000008040faa0b00005a01000004000ff5010000222e00000404000dca0c00001c040fa90c00002d53000004000fae0c00007201000001180fb40c0000be01000004040eba0c0000b305000004080ec40c0000b3050000041000226b010000080424db050000040024f90500000400231706000008202000232a06000008202000000d5001000008040faa0b00009601000004000ff5010000222e00000404000d5301000008040faa0b00009601000004000ff5010000222e00000404000d5901000008040faa0b0000960100000400000d6301000008040faa0b00009601000004000000000dbc0e000018040e600c00000909000004000e110100007304000004080e470d00007509000004100ac60e0000050f0000037c0101000d7b0e000008040e4c0d00009c09000004000e960d0000a50900000404000d800d000000010f520d00004500000001000e580d0000580400000100000df90d000034040fb40c0000be01000004000fa90c00002d53000004040fae0c00007201000001300ec40c00009904000004080eba0c00009904000004100ef00800001107000004180eae0d00006007000004200e470d0000750900000428000d08090000080426e50100006f4f00000400265f000000784f000004040007180f000007050f00000a83130000e0130000037e0101000007691c0000136f1c0000a01c000003cd010000073a0600000ddd0d000008040ee10100009309000004000eb50d00009309000004040e740200005f04000001000007180f00000acb0f000012100000051f02010a1d10000097100000057d09010aa21000001c11000005c609010a48160000ac16000005a20f010ab61600002f17000005670f0100270813000008040a131300006e130000055009010000076905000007180f00000a35110000a81100000d81050107ec1300000af1130000821400000d850501000007f411000007180f00000afb1100004a1200000e0a030100000781120000078a1200000a93120000cb1200000fd2080100000007d514000007d914000007180f000013df1400002c150000066e01000007301500000739150000133f15000078150000109c0100000007ab15000007af15000007180f00000ab51500003c16000007a503010a39170000c017000007a50301000000076d06000007f411000007180f00000ace1700003118000011480601000000070e04000007180f00000a341800007f180000084f0c010a8f180000d618000008ca0901000000044f000000f9010000280e0300000807294500000021f5080000000b000d780c000008040e420600002709000004000f55060000222e000004040004300900006c0c00000d670c000008040f42060000192e000004000f55060000222e00000404000d010d000008040e420600006c09000004000f55060000222e0000040400040d050000de0c00000da30e000008040e420600009309000004000f55060000222e00000404000475060000860e00000493060000850d000004ae0900001d0e00002a250100002b9c0900002bbe0900000004b1060000030e0000003c0000000400000000000401000000001c0041000000f003000051000000076d0000000c72000000071101000007150100000c1801000000000cf80000000000550000000400000000000401000000001c00410000000e04000051000000076d000000071101000007150100000c1801000000000cf80000000c72000000073a06000007180f00000a051e0000581e000001510601000000003f0000000400000000000401000000001c00410000005204000051000000077101000007e503000011be010000fb030000040409ec0300000009f50300000100000000f7030000040000000000040b000000001c0041000000700400005100000058910100a8000000076d0000000711010000071501000007180100000dd50c000024040e990c00005800000004000ea20c0000a10000000408002223010000080423700000000820200024830000000400000d1b01000008040faa0b00005a0100000400000d2001000008040faa0b00005a01000004000ff5010000222e00000404000dca0c00001c040fa90c00002d53000004000fae0c00007201000001180fb40c0000be01000004040eba0c0000e000000004080ec40c0000e0000000041000226b01000008042408010000040024260100000400234401000008202000235701000008202000000d5001000008040faa0b00009601000004000ff5010000222e00000404000d5301000008040faa0b00009601000004000ff5010000222e00000404000d5901000008040faa0b0000960100000400000d6301000008040faa0b00009601000004000000000dbc0e000018040e600c00003c03000004000e110100008802000004080e470d0000a803000004100a2d1d00006a1d0000026b0101000d7b0e000008040e4c0d0000cf03000004000e960d0000d80300000404000d800d000000010f520d00004500000001000e580d0000fd0200000100000df90d000034040fb40c0000be01000004000fa90c00002d53000004040fae0c00007201000001300ec40c0000ae02000004080eba0c0000ae02000004100ef00800003e02000004180eae0d00001103000004200e470d0000a80300000428000d08090000080426e50100006f4f00000400265f000000784f00000404000007f80000002c58910100a8000000c65e0000f95e000001d6031c94010000e0000000031a0000077200000022200d000008040e800c00009b0200000400000d8200000008040ef50100008103000004000022a00d0000080423c60200000820200024d90200000400000d7d00000008040faa0b00007d0000000400000d8200000008040faa0b00007d00000004000ff5010000222e000004040000077c02000010670d0000000110b90d0000000100073a0600000ddd0d000008040ee1010000c603000004000eb50d0000c603000004040e740200000403000001000000000d780c000008040e420600005a03000004000f55060000222e000004040004630300006c0c00000d670c000008040f42060000192e000004000f55060000222e00000404000d010d000008040e420600009f03000004000f55060000222e0000040400043a000000de0c00000da30e000008040e42060000c603000004000f55060000222e000004040004a2010000860e000004c0010000850d000004e10300001d0e00002a250100002bcf0300002bf10300000004de010000030e0000003f0000000400000000000401000000001c00410000002a05000051000000076d000000077200000011cc010000870000000202097d0000000009820000000100000000d0070000040000000000042d000000001c0041000000480500005100000000000000d8030000076d0000000cf8000000071101000007150100000c180100000007691c000007e529000007180f00002e63920100a2020000955f00001b60000001da1bd00600000001000001db17b00600001801000008f3082fb205000030010000082c04170e07000048010000082d04199e070000a192010007000000032f04171b0700006801000003300417aa0700008801000003d0013032030000a801000004f6013125030000ab9201001f000000049c02311b020000ab9201000a00000004b401320e020000ab9201000a00000005a3090031b2020000bc9201000e00000004b80131a4020000bc9201000e0000000607031f90020000c801000006db01000000316a030000d99201002c00000004a5021e59030000d99201002c00000007a90031760300003f9401000800000004a7021e830300003f94010008000000079a00324c5b0000ed9401000b00000004ab020000001862070000699401000500000003330419b7070000699401000500000003e1060018040600006e9401000300000003330419f70500006e9401000300000009630600192c06000071940100050000000334040019bf05000019930100aa000000082e041728070000e0010000082e04175507000000020000037a05171b0700002002000003aa0717aa0700004002000003d00130320300006802000004f601323f030000c4930100070000000495023228020000d2930100030000000495023125030000da9301001f000000049c02311b020000da9301000a00000004b401320e020000da9301000a00000005a3090031b2020000eb9301000e00000004b80131a4020000eb9301000e0000000607031f900200009002000006db01000000316a030000089401002c00000004a5021e59030000089401002c00000007a90031760300008b9401000800000004a7021e830300008b94010008000000079a00324c5b0000f99401000c00000004ab020000001862070000359401000900000003ae0719b7070000359401000900000003e106002f42070000a802000003ad071884060000c29401000500000003ae071877060000c2940100050000000a6f01186a060000c2940100050000000a8208181e060000c2940100050000000a2e081911060000c2940100050000000963060000000032430e0000c79401000e00000003ae071935070000aa9401000a00000003ac0700000000002ecd940100740000003d600000a01c000001de1c90050000c002000001df002e32950100ec000000c16000004561000001d61bdd060000d802000001d717bd060000f002000008ed08172807000008030000082803175507000020030000037a05171b0700003803000003aa0717aa0700005803000003d00130320300008003000004f601323f03000046950100050000000495023228020000529501000300000004950231250300005a9501001f000000049c02311b0200005a9501000a00000004b401320e0200005a9501000a00000005a3090031b20200006b9501000e00000004b80131a40200006b9501000e0000000607031f90020000a803000006db01000000316a030000889501002c00000004a5021e59030000889501002c00000007a9003176030000bf9501000800000004a7021e83030000bf95010008000000079a00324c5b0000129601000c00000004ab020000001862070000b59501000900000003ae0719b7070000b59501000900000003e106002f42070000c003000003ad071884060000f69501000500000003ae071877060000f6950100050000000a6f01186a060000f6950100050000000a8208181e060000f6950100050000000a2e081911060000f6950100050000000963060000000032430e0000fb9501000d00000003ae071935070000de9501000a00000003ac0700000000000000136f1c0000a01c000001cd0100000c72000000078e00000007931f000007180f00000a9b1f0000e61f0000026901010a1e2500006d25000002b6010100000007e10100000dd319000004040ee50100003f06000004000e740200005806000001000007180f00000ab3260000fc260000097405010a072700004d270000096006010ab3260000fc260000097405010a072700004d27000009600601000a552700007c270000097701010007ed0100000db019000004040ff5010000192e000004000000077c02000010c3190000000100073a06000007180f00000a1c280000ac2800000a2d08010ac2280000ac2800000a8108010a57290000ac2900000a6c0101000000077101000007421b00000d491b00000c040eec1a0000f106000004000aef1f000020200000082b04010aef290000242a0000082703010007180f00000a252000008520000008f208010a2d2a00008b2a000008ec0801000007ec1a00000df01a00000c040ef00800007607000004000f7f030000222e000004080a90200000d0200000032c04010a79230000bc23000003cf01010a2f1f00007d1f0000037905010a86270000c527000003d904010acd27000010280000031603010007180f00000a6c1e00001f1f000003a807010a3a260000a526000003df0601000007580c00000deb19000008040ee1010000d405000004000fde190000222e000004040ee2190000ca070000010013d92000002821000004d7010a052300005823000004f5010113ce2500001d26000004cf010000077101000010e4190000000100000008010000040000000000040b000000001c00ff030000f109000051000000ad5801006a010000076d000000071101000007150100000c1801000000070e04000007180f000033952a0000e12a000001290134ad5801006a010000cb0000001a45000000c55801001700000001001aee000000145901000100000001e11aee000000325901000100000001e21cfb000000f803000001ee1aee0000009d5901000700000001ee1cfb0000001004000001f81aee000000c65901000700000001f81cfb0000002804000001f40033d23500001101000001c9010000000cf80000000c7200000007e101000007180f00000ae82a0000fc260000029402010a332b0000fc2600000274050100000000280100000400000000000401000000001c00ff030000740b000051000000076d000000070e0400003512040000db00000001d81226040000355c040000db00000001ff127004000035a6040000f0000000013313e504000011c5010000d1040000010109bc0400000009be0400000109c10400000209c30400000309c50400000409c70400000509ca0400000609cc0400000709cf040000080011c5010000430500000101091d050000000923050000010930050000020939050000030000071101000007150100000c1801000000000cf80000000c720000000029c501000036e900000000000100280e0300000807205800000021e9000000008000065f0000000a0100005f00000003150100005f0000000004049a00000050050000065f0000000a0100005f000000005a0000000400000000000401000000001c00ff030000a80b000051000000076d000000076905000011be0100007d0500000404096e050000000977050000010000071101000007150100000c1801000000000cf80000000c720000000000120300000400000000000401000000001c00ff030000c60b000051000000065f0000002b0000005f00000003360000005f000000000414be01000087050000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000076d000000070e040000078c05000011c50100009c0500000101091d05000000099405000001000000077200000007180f0000079e5800000aa558000019590000057e03010000252959000004040a3559000079590000059c01010a8d590000e3590000057d030100227a5a00000201231b01000002080800242e01000001000a855a0000cc5a000005560101000d7d00000002010faa0b0000950000000100000d8200000002010faa0b00009500000001000ff5010000c50100000101000007f800000011be0100000a01000004040903010000000906010000010000079a3c0000076f5500003379550000b655000001320113c3550000f8550000010e01000007e101000007180f00000afe55000049560000029402010ae82a0000fc260000029402010a612e00004d270000026e03010ae82a0000fc260000029402010000073a0600000d8a56000008040ee1010000ee02000004000eb50d0000ee02000004040e74020000a702000001000a99560000f4560000035009010007180f00000a0d57000087570000037d09010a1638000099380000033208010a965700000b580000037e07010a133a0000162f0000032808010a43320000bd320000037d09010a43320000bd320000037d0901000da533000008040fe1010000192e000004000fb50d0000192e000004040e74020000ae02000001000aae33000009340000035009010aae33000009340000035009010000077c020000107356000000011094330000000100073458000007af15000007180f0000133a5800003458000004a601000000076905000007180f00000aee5900005b5a0000060b020100000004f7020000635600000d5a56000002010ff5010000c501000001000fdc050000c50100000101000067040000040000000000042d000000001c00ff0300005e0c0000510000000000000080040000065f000000330000005f000000033e0000005f00000000040447000000af05000005ab0500000502065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000076d000000077200000022200d000008040e800c0000920000000400000d8200000008040ef5010000f103000004000022a00d0000080423bd0000000820200024d00000000400000d7d00000008040faa0b00007d0000000400000d8200000008040faa0b00007d00000004000ff5010000222e0000040400000711010000071501000007180100000dd50c000024040e990c00001c01000004000ea20c0000650100000408002223010000080423340100000820200024470100000400000d1b01000008040faa0b00005a0100000400000d2001000008040faa0b00005a01000004000ff5010000222e00000404000dca0c00001c040fa90c00002d53000004000fae0c00007201000001180fb40c0000be01000004040eba0c0000a401000004080ec40c0000a4010000041000226b010000080424cc010000040024ea0100000400230802000008202000231b02000008202000000d5001000008040faa0b00009601000004000ff5010000222e00000404000d5301000008040faa0b00009601000004000ff5010000222e00000404000d5901000008040faa0b0000960100000400000d6301000008040faa0b00009601000004000000000dbc0e000018040e600c0000ac03000004000e110100007f00000004080e470d00001804000004100a2d1d00006a1d0000026b0101000d7b0e000008040e4c0d00003f04000004000e960d0000480400000404000d800d000000010f520d00004500000001000e580d00002b0300000100000df90d000034040fb40c0000be01000004000fa90c00002d53000004040fae0c00007201000001300ec40c0000a500000004080eba0c0000a500000004100ef00800000203000004180eae0d00003f03000004200e470d0000180400000428000d08090000080426e50100006f4f00000400265f000000784f0000040400000cf8000000077c02000010670d0000000110b90d0000000100073a0600000ddd0d000008040ee10100003604000004000eb50d00003604000004040e7402000032030000010000375d970100a0000000666100009f6100000190072f58020000400400000191070037e8970100a0000000b4610000ef6100000196072f58020000600400000197070000000d780c000008040e42060000ca03000004000f55060000222e000004040004d30300006c0c00000d670c000008040f42060000192e000004000f55060000222e00000404000d010d000008040e420600000f04000004000f55060000222e000004040004fe000000de0c00000da30e000008040e420600003604000004000f55060000222e00000404000466020000860e00000484020000850d000004510400001d0e00002a250100002b3f0400002b610400000004a2020000030e000000ab0000000400000000000401000000001c00ff0300003e0d000051000000076d000000070e04000007b405000007bc05000007c505000038cb0500006a000000012501f405000000000000077200000008a0000000870000000808097d00000000098200000001000000207700000021a70000000051000de405000010080ef5010000a000000008000fdc0500009c20000002080fe00500009c200000020a0005d80500000708280e0300000807003f0a0000040000000000042d000000001c00ff030000850d0000510000000000000048070000065f000000330000005f000000033e0000005f00000000040451000000b7070000076d00000007690500000d350700000c040e690500006f00000004000e22070000760100000100000dce0600000c040e690500009300000004000eb90600006f01000001000000073a0600000d910600000c040e400600008c08000004000e680600006801000001000e83060000ba08000001080007180f00000a482d0000aa2d000004e107010ab22d0000f82d0000042101010aa92e0000162f000004f707010aaf310000f6310000041f02010a43320000bd320000047d0901000ddd0d000008040ee10100000e0a000004000eb50d00000e0a000004040e740200005d0800000100000da533000008040ee1010000aa08000004000eb50d0000aa08000004040e740200006408000001000aae33000009340000045009010000076d0600001071060000000110c30600000001102407000000013946080000901c0000010e0605032d571000560800000a7c2b0000b22b00000198050116739801002b0300000662000031620000015301189301000073980100bb0200000154011828080000c59801000500000001f1051916080000c59801000500000002ef0400002f0208000098040000015401000af22c00002e2d00000119080107180f00000a062e0000502e0000018b08010aff3100003d32000001470a010a1f3300008f330000013a02010007f411000007180f00000a282f0000cb2f000001b707010ad92f00007130000001a707010a753000000f31000001c307010a153100000f31000001c9060100000ac6320000f832000001f601010a1c3400004a34000001eb01010a563400008b34000001e30101379f9b0100190500003b6200006e62000001260818f3010000ca9b01005e0000000128081705020000b0040000011d0818ce000000d69b01001500000001900819c1000000d69b0100150000000424010000001805020000849c01002200000001360817ce000000c804000001900817c1000000e004000004240118db0000009b9c01000500000004e40718420800009b9c01000500000004f80719350800009b9c01000500000002710300000000001705020000f804000001390818ce000000c19c01001200000001900819c1000000c19c0100120000000424010000175e02000010050000013d0817510200003005000001ca0617440200005005000001c50717370200007005000001a90717420800009005000001b8072f35080000b005000002710300000000001712020000d0050000013d0817e8000000f005000001480a1742080000100600000427022f3508000030060000027103000000171f02000050060000013d08176d02000080060000013b022ff5000000b006000001f80118f5000000e29e01000c0000000101021854010000e79e0100070000000487091935080000e79e0100070000000457090000197a020000ee9e01000d00000001010218f5000000179f0100100000000106021854010000209f0100070000000487091935080000209f0100070000000457090000197a020000279f01000a0000000106021987020000329f01000a00000001070219f50000004c9f010009000000010c02197a020000559f01000a000000010c022f87020000d0060000010d02000019a40500007b9f010011000000013d08197b080000b09f010022000000013e082f2f070000e8060000013f082f2f07000008070000012e082f2f070000280700000132080000077200000022200d000008040e800c0000360500000400000d8200000008040ef5010000c909000004000022a00d0000080423610500000820200024740500000400000d7d00000008040faa0b00007d0000000400000d8200000008040faa0b00007d00000004000ef5010000b3080000040400229e34000004040e800c0000b205000004000aab340000f234000006560101000d8200000004040ff50100002d530000040000000711010000071501000007180100000dd50c000024040e990c0000f305000004000ea20c00003c06000004080022230100000804230b06000008202000241e0600000400000d1b01000008040faa0b00005a0100000400000d2001000008040faa0b00005a01000004000ef5010000b30800000404000dca0c00001c040fa90c00002d53000004000fae0c00007201000001180fb40c0000be01000004040eba0c00007b06000004080ec40c00007b060000041000226b010000080424a3060000040024c1060000040023df0600000820200023f206000008202000000d5001000008040faa0b00009601000004000ef5010000b30800000404000d5301000008040faa0b00009601000004000ef5010000b30800000404000d5901000008040faa0b0000960100000400000d6301000008040faa0b00009601000004000000000dbc0e000018040e600c00008409000004000e110100002305000004080e470d0000f009000004100a2d1d00006a1d0000056b0101000d7b0e000008040e4c0d0000170a000004000e960d0000200a00000404000d800d000000010f520d00004500000001000e580d0000560800000100000df90d000034040fb40c0000be01000004000fa90c00002d53000004040fae0c00007201000001300ec40c00004905000004080eba0c00004905000004100ef0080000d907000004180eae0d00000301000004200e470d0000f00900000428000d08090000080426e50100006f4f00000400265f000000784f00000404000007f800000007180f00000a582c0000cc2c000003e20401000007e10100000ac62b0000f52b00000218090107180f00000a062c0000f52b000002ea04010ae82a0000fc260000029402010a612e00004d270000026e03010000077c02000010670d0000000110b90d000000011094330000000100078e00000007931f000007180f00000a9b1f0000e61f000007690101000000000d6206000008040e42060000aa08000004000e55060000b308000004040014c50100004b060000055c0600000704058c0600000201065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f0000000d780c000008040e42060000a209000004000e55060000b308000004040004ab0900006c0c00000d670c000008040e42060000aa08000004000e55060000b30800000404000d010d000008040e42060000e709000004000e55060000b308000004040004d5050000de0c00000da30e000008040e420600000e0a000004000e55060000b3080000040400043d070000860e0000045b070000850d000004290a00001d0e00002a250100002b170a00002b390a0000000479070000030e000000b9070000040000000000042d000000001c00ff0300005c130000510000000000000038090000065f000000330000005f0000003a932000005f0000000004065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000065f000000330000005f000000076d000000076d060000078808000011be010000970800000404091d05000000099008000001000000071101000007150100000c18010000000df90d000034040fb40c0000be01000004000fa90c00002d53000004040fae0c00007201000001300ec40c00008a04000004080eba0c00008a04000004100ef00800000202000004180eae0d0000fd04000004200e470d00003707000004283bff340000e529000002b105013b3a3500007635000002a506013b86350000c235000002a706013bcd3b00008b2a0000029a05013b4f3c0000883c000002cf0601000d08090000080426e50100006f4f00000400265f000000784f00000404000d7b0e000008040e4c0d00000c07000004000e960d0000150700000404000d800d000000010f520d00004500000001000e580d000073050000010000070e04000007180f0000333136000011010000038e013354370000a137000003270133a73700001038000003790133023b000011010000038e0133643b0000103800000379012ea8a601008f020000ef62000011010000039a1acd010000bda601001e000000039b1ada010000e4a6010005000000039d3c741b00006007000003a01e971b00002aa701000100000003e11e971b000048a701000100000003e23da41b0000a007000003ee1e971b0000c2a801000700000003ee3da41b0000b807000003f81e971b0000e8a801000700000003f83da41b0000d007000003f4001b66020000e8070000039c1b530400000008000003b61cc005000018080000034a1a720200008fa7010009000000034b1a7e02000098a701000d000000034b1b4505000030080000035f173805000050080000067f07172b050000700800000687081852050000dea70100030000000639081960050000dea70100030000000629080000000000001b8a02000090080000039e1b5f040000a808000003b61cc0050000c0080000034a1a7202000008a8010009000000034b1a9602000011a801000c000000034b1b45050000d8080000035f1738050000f8080000067f07172b05000018090000068708185205000056a8010003000000063908196005000056a8010003000000062908000000000000000007e436000013f13600002c370000033d01139f3a0000da3a0000033d01000007e708000013023c00003e3c000008600100000cf8000000077200000022a00d0000080423a20400000820200024b50400000400000d7d00000008040faa0b00007d0000000400000d8200000008040faa0b00007d00000004000ff5010000222e00000404000007a708000007ac08000011c5010000bf080000010109b10800000009b708000001000000073a0600000ddd0d000008040ee10100000307000004000eb50d00000307000004040e740200007a05000001000007180f00000a1638000099380000063208010aa338000099380000068608010a2b390000a0390000067e07010a133a0000162f000006280801000acd390000003a0000062a0f0100077c02000010670d0000000110b90d000000010007d5140000073435000007180f00002e11a60100af0000007f620000e4620000015d1ac001000052a6010060000000015e00000007d914000007180f00000a93360000e036000005c5010100000007953c000007180f00001609a90100210000004e63000011010000074d0218f401000009a9010020000000074e02187204000009a901002000000002d0061ae701000009a901002000000008630000001626a9010021000000a86300001101000007610218f401000026a9010020000000076202187204000026a901002000000002d0061ae701000026a901002000000008630000000000079a3c000007a23c000013ac3c0000ec3c0000094a013e203d0000f805080efc3c00005507000008003fff3c0000690700000118013f023d00007707000004000140173d0000901c000001f8043f1a3d00009e0700000408013f1d3d0000770700000410012e44a90100350100000564000044640000092c1a720600000eaa01000a00000009361a7206000018aa010001000000092f00000000000420020000860e0000043e020000850d0000041e0700001d0e00002a250100002b0c0700002b2e070000000461010000030e00000da30e000008040e420600000307000004000f55060000222e000004040029602500002162070000002000280e030000080729c5010000366207000000e003000d103d000008040e420600009507000004000f55060000222e00000404001460250000053d00000d6206000008040f42060000192e000004000f55060000222e000004040000b80000000400000000000401000000001c00ff030000bb17000051000000065f0000002b0000005f00000003360000005f0000000004043f000000c808000005c40800000408065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f00000000900000000400000000000401000000001c00ff030000d917000051000000065f0000002b0000005f00000003360000005f000000000414222e0000cd080000065f0000002b0000005f000000065f0000002b0000005f000000076d000000070e04000007b405000011cc010000e2080000020209d40800000009d90800000109dd080000020000000c720000000cf800000000005e170000040000000000042d000000001c00ff030000f71700005100000000000000a0100000065f000000330000005f000000034d0000005f0000000004076d000000071101000007e70800000d1e0900000c040ef00800007800000004000f13090000292e000001080013575c0000925c000012c201000d08090000080441e5010000b01600000400415f000000b9160000040400071501000007180100000dd50c000024040e990c0000be00000004000ea20c0000070100000408002223010000080423d60000000820200024e90000000400000d1b01000008040faa0b00005a0100000400000d2001000008040faa0b00005a01000004000ff5010000222e00000404000dca0c00001c040fa90c00002d53000004000fae0c00007201000001180fb40c0000be01000004040eba0c00004601000004080ec40c000046010000041000226b0100000804246e0100000400248c010000040023aa0100000820200023bd01000008202000000d5001000008040faa0b00009601000004000ff5010000222e00000404000d5301000008040faa0b00009601000004000ff5010000222e00000404000d5901000008040faa0b0000960100000400000d6301000008040faa0b00009601000004000000000df90d000034040fb40c0000be01000004000fa90c00002d53000004040fae0c00007201000001300ec40c00007e11000004080eba0c00007e11000004100ef00800007800000004180eae0d00009e13000004200e470d00001317000004280a4944000078440000014004010a7c440000b0440000015204013b994a0000ce4a0000015506013bd84a00000d4b0000018806013bd44b0000144c0000019f06010a284c0000614c0000011405010a774c0000614c000001140501165686010005040000bc640000b04d0000018e04194b0200008d8601000a0000000198042f58020000e80a0000019d04182b150000e38601003a000000019e04175c130000000b00000848021832140000068701000700000003870919ce12000006870100070000000357090000197a150000fe86010005000000084902001965020000718701000500000001b8041772020000180b000001c2042f10160000380b000001250517f0140000500b00000127051af1150000c18901000e0000000bd6001923090000ed89010026000000012b0518f0140000198a01000e000000012d051af1150000198a01000c0000000bd60000177f020000680b000001bc0418f0140000638801000e0000000127051af1150000638801000e0000000bd6001916090000fc88010017000000012b0500000a1c520000614c000001140501161dad01009c0500004c6500005552000001e60418a111000038ad01002600000001e8041a9511000038ad01002600000004d80017d7140000880b000001f10417c4140000b00b00000608011745150000d00b000006020a1738150000f00b0000089e021787150000080c0000083b02186913000083ad01000b00000008f801183f14000083ad01000b00000003870919db12000083ad01000b00000003570900001769130000200c0000080102183f140000b4ad01000900000003870919db120000b4ad01000900000003570900001994150000a7ad01000d0000000801021769130000380c0000080602183f140000dbad01000b00000003870919db120000dbad01000b00000003570900001994150000d1ad01000a000000080602186913000044ae010012000000080c02183f1400004fae01000700000003870919db1200004fae0100070000000357090000199415000056ae01000c000000080c022fa1150000500c0000080d020000000017c4140000680c00000608011745150000800c000006020a1738150000980c0000089e021787150000b00c0000083b021769130000c80c000008f801173f140000e80c000003870919db120000a8ae01000700000003570900001769130000000d0000080102183f140000d2ae01000500000003870919db120000d2ae01000500000003570900001994150000c8ae01000a0000000801021769130000180d0000080602183f14000018af01000900000003870919db12000018af010009000000035709000019941500000eaf01000a00000008060218691300004eaf010012000000080c02183f14000059af01000700000003870919db12000059af0100070000000357090000199415000060af01000c000000080c022fa1150000300d0000080d0200000000002f52150000480d000001f104186c150000a3af01003600000001f60418b8150000a3af010036000000080509185f150000a3af01002f000000087b071783130000600d00000890081776130000780d00000324011890130000c7af01000500000003e40718e8120000c7af01000500000003f80719ce120000c7af01000500000002710300000000000000193e120000daaf01001200000001f604182b150000f7af01003a000000010405175c130000900d000008480218321400001ab001000700000003870919ce1200001ab00100070000000357090000197a15000012b001000500000008490200182b15000042b001003d000000010b05197a15000065b0010005000000084902175c130000a80d000008480218321400006db001000700000003870919ce1200006db001000700000003570900000017be030000c00d0000010b05191016000038b10100c500000001250517f0140000e00d00000127051af115000018b20100120000000bd600195b09000048b2010017000000012b0518f014000076b2010010000000012d051af115000076b201000e0000000bd60000003bcd3b00008b2a0000019a05013ba25c0000da5c000001ee0601000d7b0e000008040e4c0d0000e816000004000e960d0000f116000004040ad04500000646000001460101425caa01006a01000078640000b1640000012e0130741b0000700a0000012f011eee1a000074aa01001700000007001e971b0000c3aa01000100000007e11e971b0000e1aa01000100000007e23da41b0000a00a000007ee1e971b00004cab01000700000007ee3da41b0000b80a000007f81e971b000075ab01000700000007f83da41b0000d00a000007f40000000d800d000000010f520d00004500000001000e580d00000415000001000007180f000007b04400000a0f460000e0130000015a04010007b04d00000abd4d0000e013000001bc04010a144e0000e013000001c2040142b3ab010080010000f5640000e013000001a2041910160000f7ab0100ce00000001a404000007555200000a59520000e0130000010b0501003ba652000085200000016407011666a00100ff0500002f6600001101000001c207196909000071a001001f00000001c3071829160000bba001000504000001c4071d1d160000bba00100050400000af81d35160000fba00100080000000aca199f160000fba00100080000000aca02001d4216000006a10100190000000acb1a741200000ba10100030000000ab3003cb41e0000f80d00000acd3cc01e0000180e00000e363c4e1f0000380e00000e12313b1f000061a101000b00000003870932d81e000061a101000b00000003570900003c681f0000500e00000e15305b1f0000680e0000037f0731751f000097a101000b00000003390831f21e000097a101000b00000003290832e51e000097a101000b0000000271030000000043821f0000b7a10100050000000e1531c51f0000b7a101000500000003870932e51e0000b7a101000500000003570900003c1d200000800e00000e2331271e000018a2010017000000050c02311a1e000018a2010017000000047e0331041e000018a2010017000000049e01320420000018a2010017000000047e03000000308f1f0000a00e0000050c0231d21f000071a201000700000003870932ff1e000071a20100070000000357090000003c1d200000b80e00000e25318f1f000045a2010012000000050c0231d21f000050a201000700000003870932ff1e000050a2010007000000035709000031271e000062a2010005000000050c02311a1e000062a2010005000000047e0331041e000062a2010005000000049e01320420000062a2010005000000047e03000000001e4c1e0000a5a401000d0000000e25003cc01e0000d00e00000e383c4e1f0000f00e00000e12313b1f0000b7a201000b00000003870932d81e0000b7a201000b00000003570900003c681f0000080f00000e15305b1f0000200f0000037f0731751f0000eda201000b00000003390831f21e0000eda201000b00000003290832e51e0000eda201000b0000000271030000000043821f00000da30100050000000e1531c51f00000da301000500000003870932e51e00000da301000500000003570900003c1d200000380f00000e2331271e00006ea3010017000000050c02311a1e00006ea3010017000000047e0331041e00006ea3010017000000049e0132042000006ea3010017000000047e03000000308f1f0000580f0000050c0231d21f0000c7a301000700000003870932ff1e0000c7a30100070000000357090000003c1d200000700f00000e25318f1f00009ba3010012000000050c0231d21f0000a6a301000700000003870932ff1e0000a6a3010007000000035709000031271e0000b8a3010005000000050c02311a1e0000b8a3010005000000047e0331041e0000b8a3010005000000049e013204200000b8a3010005000000047e03000000001e4c1e0000b3a401000d0000000e2500001d4216000054a40100170000000ace1a7412000059a40100030000000ab30000001762160000880f000001c4071755160000c80f0000107001176f160000081000001015011a81160000e8a501000f00000010ac0000002f690900004010000001c507196909000052a601000f00000001c7070044e991010021000000766600001101000001691d14080000e9910100200000000169186b000000e99101002000000001ef061a07080000e99101002000000012c30000003be65c00001101000001bb0701420692010014000000c96600001e670000017b072f400e000088100000017b070000163c8d0100620400004b6400007264000001ff031801130000898d010008000000010804189a120000898d010008000000032702198d120000898d0100080000000271030000180e130000cc8d010003000000010b0418b4120000cc8d01000300000003270219a7120000cc8d01000300000002710300002f1b130000680900000118041765140000800900000118041758140000980900000540042f28130000b0090000057e04185d110000358e010005000000057e041877140000358e010005000000046e0218b7140000358e010005000000057f041935130000358e01000500000006020a00000000001731020000c8090000011a04183e0200007f8e0100ba0000000145041842130000b28e010019000000015a0418c6130000c18e01000a000000038709198d120000c38e010005000000035709000018f1110000cb8e01001a000000015a041803090000cb8e01001a000000046e02193f080000cb8e01001a000000015a040000193f080000ff8e01001e00000001570400183e020000588f0100b40000000146041842130000888f010019000000015a0418c6130000978f01000a000000038709198d120000998f010005000000035709000018f1110000a18f01001a000000015a041803090000a18f01001a000000046e02193f080000a18f01001a000000015a040000193f080000d28f01001e0000000157040018421300005590010019000000014a0418c6130000649001000a000000038709198d1200006690010005000000035709000019fe110000bd9001000d000000014a0400179f140000e00900000110041792140000f80900000540041942130000dd90010007000000057e04170b120000100a0000057e041784140000280a0000046e0217b7140000400a0000057f041735130000580a000006020a18fc1300001a9101000700000003870919c11200001a9101000700000003570900000000000000194f1300004d9101000a00000001200400000772000000228643000004040e800c00006b11000004000aab430000f4430000046c0201000d8200000004040ef5010000d616000004000022a00d0000080423ae1100000820200024c11100000400136b4e0000b34e000004c10113c24e00000a4f000004d701000d7d00000008040faa0b00007d0000000400000d8200000008040faa0b00007d00000004000ff5010000222e0000040400227846000004040e800c00001912000004000a97460000e0460000046c02010a0f47000056470000045601010a99490000e2490000046c0201000d8200000004040ef50100003117000004000022b551000008040e800c00004c12000004000ac25100000c520000046d0101000d8200000008040ef501000043170000040000000cf8000000070e0400000cb405000007180f00000a1a550000615500000d920801000007e101000007180f00000a293d0000743d0000029402010a923d0000da3d0000026e03010a583e00006c0f0000029402010aa33e0000c10f0000026e03010a583e00006c0f0000029402010ae82a0000fc260000029402010ae82a0000fc260000029402010a612e00004d270000026e03010000073a06000007180f00000af53d00003c3e0000031f02010aeb3e000012100000031f02010a323f0000793f0000031f02010a9b3f000015400000037d09010a7641000097100000037d09010ab944000033450000037d09010a7641000097100000037d09010a43320000bd320000037d09010a43320000bd320000037d09010a482d0000aa2d000003e107010ab22d0000f82d0000032101010aa92e0000162f000003f70701000ddd0d000008040ee1010000df16000004000eb50d0000df16000004040e740200000b15000001000a4f450000aa45000003500901000d0813000008040ee10100003a17000004000eb50d00003a17000004040e740200001215000001000a3e4a00006e13000003500901000da533000008040fe1010000192e000004000fb50d0000192e000004040e740200001915000001000aae33000009340000035009010aae33000009340000035009010000076905000007180f00000a37400000b1400000057d04010a03410000b1400000053f0401078f3300000a7842000010430000057e04010aae48000046490000057e0401000a75470000ef470000057d04010a3b480000ef470000053f040100078112000007180f00000af04100005a42000006020a010a8f4f0000f94f000006020a0100078a1200000a165000004e500000060701010000073435000007180f000013184d0000a44d00000bd501000000077c02000010670d0000000110b90d00000001102b4a000000011094330000000100076d06000007180f00000a174b0000884b0000084402010a1f3300008f330000083a02010a194f00008f330000089c02010a6a500000b0500000087e0a010a062e0000502e0000088b08010a535100008f51000008040901000a8e4b0000c24b000008e801010ac6320000f832000008f601010a1c3400004a34000008eb01010a563400008b34000008e3010107f411000007180f00000abd50000071300000087a0701070f3100004582b201002a0000007b650000e01300000866070000000007ab15000007af15000007180f00000ab04c0000154d000009630301000000078e00000007931f000007180f00000a1e2500006d2500000ab601011313530000675300000ac4011378530000c85300000af7010a4c540000a45400000ac9020113b95400000b5500000aad01000007180f00003bd75a00008f330000100a01013b425b00008f3300001070010133ab5b00008f330000109c010007290c00000a165c00004c5c0000112101010000079a3c000007d553000007dc5300003bed5300003c5400000cb202010000000014c5010000f408000004c2160000fc08000029222e000021cf160000000600280e030000080704a0000000694300000422080000860e000004db080000850d000004fa1600001d0e00002a250100002be81600002b0a1700000004d2010000030e00000da30e000008040e42060000df16000004000f55060000222e000004040004220800006146000004431700006c0c00000d670c000008040f42060000192e000004000f55060000222e000004040000060100000400000000000401000000001c00ff030000702a000051000000065f0000002b0000005f00000003360000005f0000000004044900000053090000076d000000077c02000010290900000001000c720000000cf8000000071101000007150100000c18010000000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f00000000540200000400000000000401000000001c00ff0300008e2a000051000000076d000000070e04000007b405000007bc050000078c09000046930900008c01000001189909000046d80900008c010000011ae109000046230a0000a0010000011e2d0a000046700a0000ad010000011f7a0a000046bd0a0000ba0100000120c70a0000460a0b0000c70100000121150b0000465a0b0000d40100000124650b000000000000078e00000022c70b0000100424d30000000400232b01000010602000235401000010404000237201000010206000000db90b000010040eaa0b00000701000004000ef50100000202000004040edc0500000202000004080ee005000002020000040c0011be010000c70b0000040409b90b00000009bf0b00000109c30b00000209d408000003000dbf0b000010040eaa0b00000701000004000ef50100000202000004040edc050000020200000408000dc30b000010040eaa0b00000701000004000ef5010000020200000404000dd408000010040eaa0b000007010000040000000c720000000029be0100002199010000000a00280e030000080729be010000219901000000020029be010000219901000000040029be010000219901000000070029be0100002199010000000e0029be0100002199010000001b00065f000000ee0100005f00000003f90100005f000000000404a9000000d70b0000058e0000000804065f000000ee0100005f000000065f000000ee0100005f000000065f000000ee0100005f000000065f000000ee0100005f000000065f000000ee0100005f000000065f000000ee0100005f00000000410000000400000000000401000000001c00ff030000d62a000051000000076d0000000c69050000071101000007150100000c1801000000000cf80000000c7200000000001b0100000400000000000401000000001c00ff030000f42a000051000000065f0000002b0000005f00000003360000005f00000000040449000000100c0000076d000000070e0400000d030c000004040ef5010000620000000400000007ed0100000df40b000004040ff5010000222e000004000000078e00000007290c000011c50100004a0c0000010109310c000000093d0c0000010000000c720000000cf8000000071101000007150100000c18010000000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f000000065f0000002b0000005f0000000039060000040000000000042d000000001c00ff030000122b0000510000000000000060110000025f000000390000000503580910005f0000003a613800005f0000000004065f000000390000005f000000065f000000390000005f000000065f000000390000005f000000065f000000390000005f000000065f000000390000005f000000065f000000390000005f000000065f000000390000005f000000065f000000390000005f000000065f000000390000005f000000065f000000390000005f000000065f000000390000005f000000065f000000390000005f000000065f000000390000005f000000076d0000000711010000071501000007180100000dd50c000024040e990c00001f01000004000ea20c00006801000004080022230100000804233701000008202000244a0100000400000d1b01000008040faa0b00005a0100000400000d2001000008040faa0b00005a01000004000ff5010000222e00000404000dca0c00001c040fa90c00002d53000004000fae0c00007201000001180fb40c0000be01000004040eba0c0000a701000004080ec40c0000a7010000041000226b010000080424cf010000040024ed0100000400230b02000008202000231e02000008202000000d5001000008040faa0b00009601000004000ff5010000222e00000404000d5301000008040faa0b00009601000004000ff5010000222e00000404000d5901000008040faa0b0000960100000400000d6301000008040faa0b00009601000004000000000dbc0e000018040e600c00005805000004000e110100003b03000004080e470d0000c405000004100a2d1d00006a1d0000026b01010a195e00004b5e000002590101000d7b0e000008040e4c0d0000eb05000004000e960d0000f40500000404000d800d000000010f520d00004500000001000e580d0000fc0300000100000df90d000034040fb40c0000be01000004000fa90c00002d53000004040fae0c00007201000001300ec40c00006103000004080eba0c00006103000004100ef00800001203000004180eae0d00001004000004200e470d0000c40500000428000d08090000080426e50100006f4f00000400265f000000784f0000040400000cf8000000077200000022200d000008040e800c00004e0300000400000d8200000008040ef50100009d05000004000022a00d00000804237903000008202000248c0300000400000d7d00000008040faa0b00007d0000000400000d8200000008040faa0b00007d00000004000ff5010000222e000004040022795d000004040e800c0000bd0300000400000d8200000004040ef50100003306000004000037f7be000085000000b0680000e368000006e7032f5b0200004011000006e80300000c69050000077c02000010670d0000000110b90d0000000100073a0600000ddd0d000008040ee1010000e205000004000eb50d0000e205000004040e740200000304000001000000072e5d0000470c2201009c000000276700006267000001391c5b020000f0100000013b0047179201005800000075670000a667000001401cca04000010110000014900476c2501007500000083680000385d0000012c1c68020000281100000134000007385d00000db75d00001c040e3e5d00000605000004000e5b5d0000aa03000004080e975d0000d7040000040c13c15d0000045e0000033a01000dae5d000010040ea05d00007f05000004000fa55d0000be01000004080faa5d0000be010000040c000007465d00000d565d0000080426e50100006f4f00000400415f0000001606000004040007180f000048acb201000c000000f46700003f6800000573000007e101000048a9b2010002000000b0670000e0670000043b00000d780c000008040e420600007605000004000f55060000222e0000040400047f0500006c0c00000d670c000008040f42060000192e000004000f55060000222e00000404000d010d000008040e42060000bb05000004000f55060000222e00000404000401010000de0c00000da30e000008040e42060000e205000004000f55060000222e00000404000476020000860e00000494020000850d000004fd0500001d0e00002a250100002beb0500002b0d0600000004b2020000030e0000041f0600004a5d000029222e0000212c060000000400280e03000008070433020000635d000000330000000400000000000401000000001c0041000000b72c00005100000007710100000771010000491e1c0000561c000001e00100000040020000040000000000040b000000001c0041000000ea2c0000510000009a1c01005f000000076d00000007f800000025e218000001010a151900006e19000002e90201000007e10100000dd319000004040ee50100006f00000004000e74020000880000000100000007ed0100000db019000004040ff5010000192e000004000000077c02000010c319000000010000077101000007580c00000deb19000008040ee10100004b00000004000fde190000222e000004040ee2190000e20000000100130c1a0000641a0000035a0113891a0000da1a00000395010000077101000010e4190000000113991b000071010000044d0107180f000013c31b000071010000049901000007ec1a00000df01a00000c040ef00800009b00000004000f7f030000222e000004080af81a0000da1a0000066801010a2f1f00007d1f0000067905010007180f00000a6c1e00001f1f000006a807010000073a060000077b1d000013801d0000b01d000001a4010007180f00000abb1d0000b01d0000016d0101429a1c01005f000000195f0000885f00000164021775010000981100000165021763010000b01100000171011b2a010000c811000001a717cf000000e0110000066a011bc3000000f811000003961c3700000010120000035f1dfa000000af1c010008000000036a1ae9000000af1c010008000000049a001e4c5b0000bb1c01000b000000036e0000001d37010000cc1c01000e00000001a8184a010000cc1c01000e000000067a0532430e0000cc1c01000e00000006ae070000000000000000007b0000000400180400000401f16800001c0032690000ef2d00007569000000000000281200000283690000029569000003115608003600000099690000996900000109034856080069000000a0690000a0690000011603b25608002c000000a8690000a8690000012d03df56080044000000af690000af6900000137000000760700000400490400000401b66900001c00f76900004a2f00003a6a0000000000002813000002486a0000024d6a000002516a0000035a6a0000a16a00000392080103af6a0000f56a000003130b0103146c0000596c0000030d0a0103cd6c0000356d000003611201033a6d0000836d000003960d0103fc6d0000416e000003de090103b56e0000fd6e000003a70801030c6f0000f56a000003130b0103946f0000a16a00000392080103db6f0000596c0000030d0a01037b700000836d000003960d0103c4700000416e000003de09010364710000fd6e000003a7080103ac710000f56a000003130b0100000002026b000004146b0000456b0000042801024b6b0000024f6b00000502000000ad000000620100000635000000170000000300000002a906350000001a0000000500000002a906420000001f0000000700000002a906420000006d0000000a00000002cc06f3000000ac0000000300000002a20007546b0000546b000001fe010802000000b1000000497200004972000001fe09620100005012000002d90635000000170000000300000002a906350000001a0000000500000002a906420000001f0000000700000002a906420000006b0000000a00000002cc06f3000000b00000000300000002a200000802000000c0000000537200005372000001fe09620100006812000002e20635000000170000000300000002a906350000001a0000000500000002a906420000001f0000000700000002a906420000006b0000000a00000002cc06f3000000bf0000000300000002a200000a010000000e000000607200006072000001fe0a01000000400000006a7200006a72000001fe0b245708004d000000aa0600000b3d5a08005b000000d706000008020000002e020000747200007472000001fe0c0a070000020000002d0000000207010c0a07000034000000080000000207010c160700003c000000030000000207010c3500000049000000030000000207010c350000004c000000030000000207010c420000004f000000050000000207010c1607000099000000030000000207010d690000009f0000000a0000000207010c420000009f0000000500000003970d000c35000000ac000000030000000207010c35000000af000000030000000207010c42000000b2000000050000000207010d69000000e20000000a0000000207010c42000000e20000000500000003970d000c35000000f1000000050000000207010c35000000f7000000030000000207010d220700001d01000005000000020701064f0000001d010000050000000585000c2e07000022010000040000000207010d3a0700002a0100000500000002070106760000002a010000050000000581000c5c0000002f010000010000000207010c1607000051010000030000000207010c5c00000055010000010000000207010c2e070000730100000e0000000207010c8300000087010000050000000207010c5c0000008e010000010000000207010c90000000d00100000a0000000207010c8300000015020000030000000207010c1607000076000000050000000207010c1607000087000000030000000207010e2207000080120000020701064f0000008a0000000300000005850f5f0700001c02000002000000058506f30000001c02000002000000055500000c5c0000008d000000010000000207010e3a070000981200000207011076000000b01200000581000c1607000038010000030000000207010c5c0000003e01000003000000020701000864570800ed020000817200008172000001fe0c9d000000ad57080004000000020f010c9d000000b157080004000000020f010c42000000b557080005000000020f010db7000000015808000b000000020f010c90000000015808000500000003970d000c9d0000000e58080004000000020f010c9d0000001258080004000000020f010c420000001658080005000000020f010db7000000395808000b000000020f010c90000000395808000500000003970d000c9d0000004858080007000000020f010c9d0000005058080004000000020f010d460700007458080005000000020f0106aa00000074580800050000000585000d520700007d58080009000000020f0106c40000007d580800090000000581000cd1000000c258080003000000020f010cd1000000fb58080005000000020f0111de000000c8120000020f010e46070000e0120000020f0106aa000000ea5708000500000005850f6b0700000a5a080002000000058506f30000000a5a080002000000055500000d520700008c5808000c000000020f0106c40000008c5808000c0000000581000007357200003572000001fe0112010000004d0000008e720000d172000001250111aa060000f812000002160100073f7200003f72000001fe0112010000005b000000df7200002273000001250111d706000010130000021a01000002516a0000075e6b0000b56b000005d80107ba6b0000106c000005d20107656c0000c06c000005840107936d0000f16d000005de01074d6e0000a86e00000580010720700000c06c00000584010709710000a86e00000580010013526f0000886f000005520113f3710000297200000552010000005a0c00000400670500000401307300001c00717300009a380000b473000000000000a817000002c273000002d473000002d873000003e17300003774000002d20103387500002b7500000270010393750000ea75000002d8010302770000f5760000026c01035d770000bb77000002de01034f7b0000aa7b000002800103d27e0000aa7b000002800103b67f00002b75000002700103bc820000aa7b000002800103938400002b75000002700103348500002b75000002700103d6860000f5760000026c010332880000aa7b000002800103248900002b75000002700100023b740000023f74000004437400007e74000006070104ff8300003a84000006070100050100000077000000278a0000278a000001fe06e8000000010000007600000006590735000000010000000a000000060a07120a00000b00000001000000061206410000001600000003000000061507370b00001600000003000000027100084100000088130000061609370b0000a0130000027100074d0000001b00000006000000061607d20a000022000000010000000614074d0000002300000006000000061706410000002900000003000000061707370b0000290000000300000002710007d20a00002c00000001000000061506590000005000000001000000061607440b00005000000001000000026d0007120a00005100000007000000061006410000005800000005000000061207370b0000580000000500000002710007d20a00005d00000005000000061207120a00006200000001000000061406590000006300000001000000061607440b00006300000001000000026d000965000000b81300000618072b0a00006800000005000000061307d20a00007400000001000000061307120a00001500000001000000060d06410000004500000005000000060d07370b0000450000000500000002710007d20a00004a00000005000000060d07120a00004f00000001000000060f07380a00006d00000007000000060c07120a00004400000001000000060b07350000000c00000009000000060a071f0a00002d00000009000000060a071f0a00003600000007000000060a06410000003d00000007000000060a07370b00003d000000070000000271000000027e7800000483780000c078000006200104307c00006d7c000006200104128000004f800000062001000502000000cc000000308a0000308a000001fe0842030000d0130000066207d70b00000c0000000f000000062307d70b0000320000000b000000062907450a00005400000005000000063007520a00005900000005000000063107df0a00005e00000007000000063107e40b00006500000001000000063507d70b00007c00000007000000063807f10b0000850000000c0000000639087100000000140000063d09510b000020140000028106c0090000cb00000003000000028107f1090000cb000000030000000255000009f10b000038140000063d00000502000000e00000003a8a00003a8a000001fe084e03000050140000066607fe0b00000c00000014000000062307fe0b000037000000100000000629075f0a00005e000000050000000630076c0a00006300000005000000063107eb0a000068000000070000000631070b0c00006f00000001000000063507fe0b00008600000007000000063807180c00008f000000110000000639087d00000080140000063d095e0b0000a0140000028106cc090000df00000003000000028107f1090000df000000030000000255000009180c0000b8140000063d00000a02000000dc01000018080000085a030000d0140000066b0889000000e81400000622096b0b00000015000002710007250c0000430000001a000000062307250c00007600000014000000062907790a0000a400000005000000063009860a000018150000063109f70a000030150000063109320c000048150000063507250c0000000100000f0000000638073f0c00002a0100001b0000000639089500000060150000063d09780b000090150000028106d8090000db01000003000000028107f1090000db010000030000000255000007030b00005c01000005000000063d093f0c0000b8150000063d000003448400004484000001fe010bc75a080075000000448a0000868a00000125010806060000d8150000067208f4000000f0150000065e07930a0000cc5a080007000000061206a1000000d85a080003000000061507850b0000d85a08000300000002710006ad000000db5a080005000000061607920b0000db5a08000500000002710007100b0000e05a080001000000061406ad000000e15a080005000000061707920b0000e15a08000500000002710007100b0000e65a080001000000061506b90000000e5b0800010000000616079f0b00000e5b080001000000026d0007930a00000f5b080009000000061006a1000000185b080005000000061207850b0000185b080005000000027100071d0b00001d5b080005000000061207930a0000225b080001000000061406b9000000235b0800010000000616079f0b0000235b080001000000026d0007ac0a0000295b0800050000000613071d0b0000375b080001000000061307930a0000d35a080005000000060d06a1000000035b080005000000060d07850b0000035b080005000000027100071d0b0000085b080005000000060d07930a00000d5b080001000000060f07b90a00002e5b080009000000060c07930a0000025b080001000000060b07a00a0000e75a08000b000000060a07a00a0000f25a080009000000060a06a1000000fb5a080007000000060a07850b0000fb5a08000700000002710000000003e2870000e287000001fe010b02000000ce010000948a0000d78a000001250106180800001c000000920100000677065a0300001c00000092010000066b06890000001c000000240000000622076b0b00001c0000002400000002710007250c00004000000018000000062307250c00006d00000016000000062907790a00009c00000005000000063009860a000008160000063109f70a000020160000063109320c000038160000063507250c0000f80000000f0000000638073f0c0000220100001f0000000639089500000050160000063d09780b000080160000028106d8090000ac01000002000000028107f1090000ac010000020000000255000007030b00004e01000005000000063d093f0c0000a8160000063d000000028e8800000494880000d2880000064a01000b020000008d000000e68a0000298b00000125010839090000c8160000068108c5000000f8160000064d09ac0b000028170000028106e40900008c00000003000000028107f10900008c0000000300000002550000094c0c000050170000064d08d100000068170000064c09b90b00008817000002710000000004ee7b0000247c0000025201042d7f0000637f000002520104688300009e83000002520104e48900001a8a0000025201000cb77b0000e87b0000082801000287740000028c740000029074000002d87300000d94740000dd740000030202010459760000a87600000391010dc67700000f780000039501010d1378000070780000036e02010d39790000dd740000030202010d8d790000dc790000033c01010dd97c0000dd740000030202010d2d7d0000dc790000033c01010dbd800000dd740000030202010d12810000dc790000033c01010dab830000dd7400000302020104e8850000a87600000391010d318700000f780000039501010d8587000070780000036e0201000002ef75000002d87300000df57500004e76000005b5020104e37900002e7a000005d001047c7d00002e7a000005d00104628100002e7a000005d0010d1883000064830000057002010d8f8500004e76000005b502010d378600004e76000005b5020100000002e174000002d87300000de57400002b750000042a0b010daf760000f576000004fd0a010dfe7a0000437b0000048a02010d8d7e0000437b0000048a02010d6f7f00002b750000040d04010d76820000437b0000048a02010d4d8400002b750000042a0b010dee8400002b750000040d04010d90860000f576000004e003010dec870000437b000004de09010ddd8800002b750000042a0b01000002ca78000002ce78000002d87300000dd478000036790000071303010d327a0000957a0000076303010d987a0000fb7a0000076903010d777c000036790000071303010dc77d0000957a0000076303010d2a7e0000fb7a0000076903010d5a80000036790000071303010dae810000957a0000076303010d12820000fb7a0000076903010d80890000fb7a0000076903010000000000c406000004002f0600000401388b00001c00798b00007b400000bc8b000000000000f819000002ca8b000002dc8b000002e08b000002e68b000003eb8b00002a8c0000020501035190000090900000020501000401000000500000008c9300008c93000001fe053a000000e8170000024706fe0500001400000007000000020e065d06000020000000020000000210060a0600002200000006000000020f076a06000000180000020e066a0600002d00000003000000020f06770600003000000001000000020f071606000018180000020e06fe0500004300000003000000020a066a0600004600000006000000020a06160600004c00000004000000020a000002568e0000035b8e00009a8e0000021a0103ec9100002b920000021a010004010000005c000000969300009693000001fe0506010000301800000251062206000014000000080000000224075d060000481800000225068306000021000000030000000226072e060000601800000225063a06000028000000030000000225076a0600007818000002250677060000390000000100000002250622060000430000000a000000021f06830600004d000000010000000220072e06000090180000021f06830600005200000008000000021f0000020390000003089000004790000002300103e69200002593000002300100040100000050000000a0930000a093000001fe05d9010000a8180000025b060a06000014000000080000000239075d060000c0180000023a065d0600002100000003000000023b0716060000d8180000023906fe0500002800000003000000023a076a060000f01800000239067706000039000000010000000239060a06000043000000060000000235065d0600004900000006000000023506160600004f0000000100000002350000089b9000009b90000001fe01093d5b080057000000150300000a9c0200003d5b08004700000002660a460000003d5b080047000000024b0790060000081900000210079d06000020190000020f079d06000038190000020e06aa060000685b080003000000020f069d060000755b08000f000000020a0000000b9a910000de910000012501010c0100000070000000aa930000ef9300000125010a15030000120000003b000000026a0a9c020000120000003b00000002660a46000000120000003b000000024b0790060000501900000210079d06000068190000020f079d06000080190000020e06aa0600003100000003000000020f069d0600003e0000000f000000020a0000000008369200003692000001fe01090100000063000000360400000aa6030000010000005300000002770a12010000010000005300000002550690060000170000000b0000000225079d06000098190000022506aa0600002e00000003000000022506b60600003100000009000000022606b60600003b00000007000000022006b6060000420000000d000000021f0000000b94920000d8920000012501010c010000007c000000fe930000439400000125010a360400001400000045000000027b0aa6030000140000004500000002770a120100001400000045000000025506900600001c0000000b0000000225079d060000b0190000022506aa0600003300000003000000022506b60600003600000009000000022606b60600004000000007000000022006b6060000470000000d000000021f0000000008309300003093000001fe0109955b0800570000005f0500000ade040000955b080047000000027f0ae5010000955b080047000000025f0690060000a95b08000b000000023a079d060000c8190000023906aa060000c05b08000300000002390690060000c35b080009000000023b0690060000cd5b08000f00000002350000000b3a9300007e930000012501010c010000007000000052940000979400000125010a5f050000120000003b00000002830ade040000120000003b000000027f0ae5010000120000003b000000025f06900600001a0000000b000000023a079d060000e0190000023906aa0600003100000003000000023906900600003400000009000000023b06900600003e0000000f0000000235000000000002348c0000083d8c0000938c000003d20108f18c0000488d000003d80108ed8d00004b8e000003de0108a48e0000488d000003d801084f8f00004b8e000003de0108ad8f0000938c000003d20100000002978c0000029c8c000002a08c000002348c00000da48c0000ed8c0000040202010d4d8d0000968d000004950101039a8d0000e78d000004e5010dfb8e0000ed8c0000040202010da5900000ed8c0000040202010df9900000968d000004950101034d910000e78d000004e5010d40920000ed8c0000040202010000000000e80900000400f60600000401a69400001c00e7940000d74500002a95000000000000a01f00000238950000023d95000002419500000245950000034e950000a295000002020201030a96000059960000023c01010399980000a295000002020201033299000059960000023c01010330a00000a29500000202020103d4a0000059960000023c0101000002cb970000024595000004d19700001c98000004d00104c29a00001c98000004d0010469a200001c98000004d001000000026096000002459500000364960000aa96000003f7030103129700005797000003de09010381990000aa96000003f7030103229a00005797000003de0901034f9b0000949b0000030d0a0103539c0000949b0000030d0a0103179e00005d9e0000030d0401038f9f00005d9e0000030d04010324a10000aa96000003f7030103c7a100005797000003de090103f8a20000949b0000030d0a0100000002a695000002b895000002bc95000002c195000004c59500000196000006050104ed980000299900000605010485a00000c1a000000605010005010000003a000000ce040000066b010000481a0000063e073a000000010000000a000000060707470000000b00000005000000060d08340900001000000003000000060d07c500000010000000030000000775000640090000601a0000061009d2000000801a0000078108b90900003800000003000000078107de09000038000000030000000755000007470000003000000003000000061107940000003300000003000000061107470000002f00000001000000060e07470000001d00000005000000060c08340900002200000003000000060c07c50000002200000003000000077500000005010000003c000000460600000677010000981a000006430754000000010000000a000000060707610000000b00000005000000060d084c0900001000000007000000060d07df00000010000000070000000775000658090000b01a0000061009ec000000d01a0000078108c50900003a00000003000000078107de0900003a000000030000000755000007610000003200000003000000061107a00000003500000003000000061107610000003100000001000000060e07610000001f00000005000000060c084c0900002400000003000000060c07df0000002400000003000000077500000002089c0000040c9c0000499c0000061b0104f39c0000309d0000061b01049aa30000d7a30000061b01000a0100000032000000eba30000eba3000001fe0665030000e81a0000064f0664090000001b0000062209f9000000201b0000078508b90900003000000003000000078507de09000030000000030000000755000007470000002800000003000000062307940000002b00000003000000062307470000001d00000005000000062008340900002200000003000000062007c5000000220000000300000007750000000a0100000034000000f4a30000f4a3000001fe0671030000381b000006540670090000501b000006220906010000701b0000078508c50900003200000003000000078507de09000032000000030000000755000007610000002a00000003000000062307a00000002d00000003000000062307610000001f000000050000000620084c0900002400000003000000062007df000000240000000300000007750000000b3a9d00003a9d000001fe0102439d0000044f9d0000ae9d0000065f010002ba9d000004c19d0000039e0000062d0104399f00007b9f0000062d01000a0100000049000000439d0000439d000001fe06f1040000881b0000065f06df040000a01b0000063006ce040000c01b0000065f066b010000e01b0000063e073a000000010000000a000000060707470000000b00000005000000060d08340900001000000003000000060d07c500000010000000030000000775000640090000001c0000061009d2000000201c0000078108b90900004700000003000000078107de09000047000000030000000755000007470000003400000003000000061107940000003700000003000000061107470000003300000001000000060e07470000002100000005000000060c08340900002600000003000000060c07c500000026000000030000000775000000000994000000381c00000633087c0900003a00000005000000063307130100003a0000000500000007710000000bc59e0000c59e000001fe0102ce9e000004da9e0000ae9d0000066401000a010000004b000000ce9e0000ce9e000001fe06fd040000501c000006640657060000681c000006300646060000881c000006640677010000a81c000006430754000000010000000a000000060707610000000b00000005000000060d084c0900001000000007000000060d07df00000010000000070000000775000658090000c81c0000061009ec000000e81c0000078108c50900004900000003000000078107de09000049000000030000000755000007610000003600000003000000061107a00000003900000003000000061107610000003500000001000000060e07610000002300000005000000060c084c0900002800000003000000060c07df000000280000000300000007750000000009a0000000001d0000063308880900003c00000005000000063307200100003c0000000500000007710000000bcba00000cba0000001fe010c02000000ae000000fda3000040a4000001250106a0070000181d0000066b0683010000401d00000648076e00000018000000070000000607097b000000681d0000060d0694090000801d0000060d092d010000981d000007750006a0090000b01d00000610093a010000e01d0000078108d1090000ad00000003000000078107de090000ad0000000300000007550000097b000000081e0000061109ac000000201e00000611077b0000007a00000001000000060e097b000000381e0000060c0694090000501e0000060c092d010000681e00000775000000000be2a30000e2a3000001fe010c02000000a60000004ea4000091a400000125010687080000801e0000066f067d030000a81e0000065906ac090000d01e000006220947010000001f0000078508d1090000a500000003000000078507de090000a50000000300000007550000097b000000281f0000062309ac000000401f00000623097b000000581f000006200694090000701f00000620092d010000881f00000775000000000002459500000bb7960000aa9600000774010b63970000be9700000780010bc7990000aa9600000774010b679a0000be9700000780010ba09b0000fb9b00000784010b989c0000fb9b00000784010b6a9e00005d9e00000770010bd59f00005d9e00000770010b6ba10000aa9600000774010b0da20000be9700000780010b3ea30000fb9b00000784010004579800008d980000075201040d9b0000439b000007520104b5a20000eba20000075201000d2098000051980000052801000000150e2e64656275675f6d6163696e666f000000000000009c3d0f2e64656275675f7075627479706573a8000000020000000000d401000025010000526573756c7400d7000000457363617065556e69636f646553746174650096010000436f756e7400c5010000753800450000002829005a010000506f736974696f6e003c00000026282900b300000045736361706544656661756c74537461746500950000004f7074696f6e00be01000075333200cc0100007531360031000000767461626c650072010000416c69676e6d656e7400000000008f0000000200d4010000be010000f7000000436f6c6c656374696f6e416c6c6f63457272007e010000476c6f62616c008c0000004e6f6e5a65726f3c2a636f6e73742075383e00a50000005068616e746f6d446174613c75383e00290100005261775665633c75382c20616c6c6f633a3a616c6c6f633a3a476c6f62616c3e0068000000556e697175653c75383e0000000000210000000200920300006100000036000000267538002b000000767461626c650000000000bf0400000200f3030000c809000075090000265b636f72653a3a666d743a3a417267756d656e7456315d006c0900002a636f6e737420636f72653a3a666d743a3a72743a3a76313a3a417267756d656e7400510400005068616e746f6d446174613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4c6561664e6f64653c28292c2028293e3e002a060000496d706c696564004f0000004c6561664e6f64653c28292c2028293e0011070000266d757420577269746500be090000266d757420636f72653a3a666d743a3a466f726d617474657200580400005068616e746f6d446174613c2a6d757420466e3c28293e3e00960300002a636f6e737420616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a496e7465726e616c4e6f64653c28292c2028293e00270900002a636f6e73742026737472009c09000026636f72653a3a666d743a3a566f696400930900002a636f6e737420636f72653a3a666d743a3a417267756d656e74563100c4040000536f6d65002b050000506f736974696f6e005605000041740074050000466f726d61745370656300660400005068616e746f6d446174613c75383e00b1060000466f726d617474657200db05000049730009090000265b267374725d00430500004e65787400ac000000426f7865644e6f64653c28292c2028293e00730400004f7074696f6e3c265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d3e00a5090000666e2826636f72653a3a666d743a3a566f69642c20266d757420636f72653a3a666d743a3a466f726d617474657229202d3e20636f72653a3a726573756c743a3a526573756c743c28292c20636f72653a3a666d743a3a4572726f723e000d050000417267756d656e7400990400004f7074696f6e3c7573697a653e00b10400004e6f6e6500380400004e6f6e5a65726f3c2a636f6e73742075383e00390100005665633c75383e00b6030000556e697175653c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4c6561664e6f64653c28292c2028293e3e00ec0800002a636f6e737420616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4c6561664e6f64653c28292c2028293e008e000000496e7465726e616c4e6f64653c28292c2028293e00b3050000436f756e740075060000417267756d656e74563100250400004e6f6e5a65726f3c2a636f6e737420616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4c6561664e6f64653c28292c2028293e3e004e090000265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d00170600004e657874506172616d00f9050000506172616d0093060000566f69640060070000497465723c636f72653a3a666d743a3a417267756d656e7456313e005f0400005068616e746f6d446174613c26636f72653a3a666d743a3a417267756d656e7456313e003f060000417267756d656e7473000e010000476c6f62616c00c70000005261775665633c75382c20616c6c6f633a3a616c6c6f633a3a476c6f62616c3e006a010000537472696e670001040000556e697175653c75383e00300900002673747200000000000e0000000200bb0d000040000000000000000e0000000200fb0d00005900000000000000160000000200540e00004300000028000000436f770000000000b50200000200970e0000fb030000a8030000265b636f72653a3a666d743a3a417267756d656e7456315d009f0300002a636f6e737420636f72653a3a666d743a3a72743a3a76313a3a417267756d656e740057010000496d706c696564003e020000266d757420577269746500f1030000266d757420636f72653a3a666d743a3a466f726d617474657200fd0200005068616e746f6d446174613c2a6d757420466e3c28293e3e005a0300002a636f6e7374202673747200cf03000026636f72653a3a666d743a3a566f696400c60300002a636f6e737420636f72653a3a666d743a3a417267756d656e74563100d9020000536f6d650058000000506f736974696f6e0083000000417400a1000000466f726d61745370656300de010000466f726d617474657200080100004973003c030000265b267374725d00d8030000666e2826636f72653a3a666d743a3a566f69642c20266d757420636f72653a3a666d743a3a466f726d617474657229202d3e20636f72653a3a726573756c743a3a526573756c743c28292c20636f72653a3a666d743a3a4572726f723e00700000004e65787400880200004f7074696f6e3c265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d3e003a000000417267756d656e7400ae0200004f7074696f6e3c7573697a653e00c60200004e6f6e6500e0000000436f756e7400a2010000417267756d656e7456310081030000265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d00440100004e657874506172616d0026010000506172616d00c0010000566f69640011030000497465723c636f72653a3a666d743a3a417267756d656e7456313e00040300005068616e746f6d446174613c26636f72653a3a666d743a3a417267756d656e7456313e006c010000417267756d656e747300630300002673747200000000001900000002009212000043000000280000004f7074696f6e00000000008f0000000200d5120000d4070000ca070000476c6f62616c003f0600004e6f6e5a65726f3c2a636f6e73742075383e00f10600005665633c75383e009e060000537472696e6700580600005068616e746f6d446174613c75383e00760700005261775665633c75382c20616c6c6f633a3a616c6c6f633a3a476c6f62616c3e00d4050000556e697175653c75383e00000000000e0000000200a91a00000c010000000000005f0000000200b51b00002c0100001501000026636f72653a3a6e756d3a3a496e744572726f724b696e64009a000000496e744572726f724b696e6400580000004173636969436861726163746572436c617373000a010000767461626c6500000000001c0000000200e11c00005e000000280000004c6f6f7053746174650000000000d200000002003f1d000016030000360000002675333200f60000004f7074696f6e3c75383e0052010000526573756c7400d4010000497465723c2875382c207538293e009c000000466c6f61744572726f724b696e6400ee0200002a636f6e7374202875382c2075382900a70200005068616e746f6d446174613c262875382c207538293e001b0100004e6f6e65002e010000536f6d6500f70200002875382c20753829005e020000497465723c75383e00ae0200005068616e746f6d446174613c2675383e002b000000767461626c650000000000d10200000200552000006b04000018040000265b636f72653a3a666d743a3a417267756d656e7456315d000f0400002a636f6e737420636f72653a3a666d743a3a72743a3a76313a3a417267756d656e74001b020000496d706c6965640002030000266d75742057726974650061040000266d757420636f72653a3a666d743a3a466f726d6174746572002b0300005068616e746f6d446174613c2a6d757420466e3c28293e3e003f04000026636f72653a3a666d743a3a566f696400ca0300002a636f6e7374202673747200360400002a636f6e737420636f72653a3a666d743a3a417267756d656e74563100d0000000536f6d65001c010000506f736974696f6e003e000000266931360065010000466f726d6174537065630047010000417400a2020000466f726d617474657200cc010000497300ac030000265b267374725d0033000000767461626c6500340100004e657874007f0000004f7074696f6e3c265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d3e0048040000666e2826636f72653a3a666d743a3a566f69642c20266d757420636f72653a3a666d743a3a466f726d617474657229202d3e20636f72653a3a726573756c743a3a526573756c743c28292c20636f72653a3a666d743a3a4572726f723e00fe000000417267756d656e7400a50000004f7074696f6e3c7573697a653e00bd0000004e6f6e6500a4010000436f756e740066020000417267756d656e74563100f1030000265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d004700000069313600ea010000506172616d0084020000566f696400080200004e657874506172616d00320300005068616e746f6d446174613c26636f72653a3a666d743a3a417267756d656e7456313e0030020000417267756d656e7473003f030000497465723c636f72653a3a666d743a3a417267756d656e7456313e00d3030000267374720000000000350000000200c0240000af00000077000000287536342c206931362c206931362900500000004f7074696f6e00a00000007536340000000000f504000002006f250000430a0000f0090000265b636f72653a3a666d743a3a417267756d656e7456315d00e70900002a636f6e737420636f72653a3a666d743a3a72743a3a76313a3a417267756d656e7400f2060000496d706c69656400d9070000266d757420577269746500390a0000266d757420636f72653a3a666d743a3a466f726d617474657200560800005068616e746f6d446174613c2a6d757420466e3c28293e3e00ba080000626f6f6c00b30800007573697a65003e00000026636f72653a3a697465723a3a4d61703c636f72653a3a697465723a3a46696c7465723c636f72653a3a736c6963653a3a53706c69743c75382c20636f72653a3a7374723a3a49734173636969576869746573706163653e2c20636f72653a3a7374723a3a49734e6f74456d7074793e2c20636f72653a3a7374723a3a556e736166654279746573546f5374723e0068010000497341736369695768697465737061636500a20900002a636f6e7374202673747200b2050000536f6d6500f3050000506f736974696f6e001e0600004174003c060000466f726d617453706563000e0a00002a636f6e737420636f72653a3a666d743a3a417267756d656e74563100170a000026636f72653a3a666d743a3a566f6964009300000053706c69743c75382c20636f72653a3a7374723a3a49734173636969576869746573706163653e00a306000049730084090000265b267374725d00aa0800002a636f6e7374207538000b0600004e65787400920500004f7074696f6e3c636861723e00230500004f7074696f6e3c265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d3e00200a0000666e2826636f72653a3a666d743a3a566f69642c20266d757420636f72653a3a666d743a3a466f726d617474657229202d3e20636f72653a3a726573756c743a3a526573756c743c28292c20636f72653a3a666d743a3a4572726f723e00d5050000417267756d656e740033000000767461626c650076010000556e736166654279746573546f53747200510000004d61703c636f72653a3a697465723a3a46696c7465723c636f72653a3a736c6963653a3a53706c69743c75382c20636f72653a3a7374723a3a49734173636969576869746573706163653e2c20636f72653a3a7374723a3a49734e6f74456d7074793e2c20636f72653a3a7374723a3a556e736166654279746573546f5374723e00640800005068616e746f6d446174613c2675383e007b060000436f756e74003d070000417267756d656e745631008c080000265b75385d00610500004e6f6e6500490500004f7074696f6e3c7573697a653e006f00000046696c7465723c636f72653a3a736c6963653a3a53706c69743c75382c20636f72653a3a7374723a3a49734173636969576869746573706163653e2c20636f72653a3a7374723a3a49734e6f74456d7074793e00c9090000265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d00df0600004e657874506172616d00c1060000506172616d005b070000566f69640003010000497465723c636f72653a3a666d743a3a417267756d656e7456313e005d0800005068616e746f6d446174613c26636f72653a3a666d743a3a417267756d656e7456313e0007070000417267756d656e74730079070000466f726d6174746572002c010000497465723c75383e006f01000049734e6f74456d70747900ab090000267374720000000000f80100000200b22f0000bd07000037070000265b636f72653a3a666d743a3a417267756d656e7456315d007e060000426f6f6c54726965008a0400004f7074696f6e3c7573697a653e0002020000266d7574205772697465002e070000266d757420636f72653a3a666d743a3a466f726d61747465720020020000417267756d656e74563100730500005068616e746f6d446174613c2a6d757420466e3c28293e3e009e070000265b75385d00a20400004e6f6e6500fd040000497465723c636f72653a3a666d743a3a417267756d656e7456313e003e020000566f696400030700002a636f6e737420636f72653a3a666d743a3a417267756d656e7456310061010000466f726d617474657200b5040000536f6d65000c07000026636f72653a3a666d743a3a566f696400de040000506f6c6c00370100005374725365617263686572496d706c007a0500005068616e746f6d446174613c26636f72653a3a666d743a3a417267756d656e7456313e00950700002a636f6e7374207536340015070000666e2826636f72653a3a666d743a3a566f69642c20266d757420636f72653a3a666d743a3a466f726d617474657229202d3e20636f72653a3a726573756c743a3a526573756c743c28292c20636f72653a3a666d743a3a4572726f723e0077070000265b7536345d0033000000767461626c6500000000002a00000002006f370000bc0000003f000000663634003600000026663634002b000000767461626c6500000000002d00000002002b3800009400000036000000267573697a65006800000050617274002b000000767461626c6500000000003d0300000200bf3800006217000013170000265b636f72653a3a666d743a3a417267756d656e7456315d00431700002673747200bd010000496d706c6965640078000000266d7574205772697465000a170000266d757420636f72653a3a666d743a3a466f726d6174746572003117000026636f72653a3a666d743a3a417267756d656e74563100041500005068616e746f6d446174613c2a6d757420466e3c28293e3e00b01600002a6d757420753800e816000026636f72653a3a666d743a3a566f696400ae1100004e6f6e65002c1200004f7074696f6e3c267374723e00df1600002a636f6e737420636f72653a3a666d743a3a417267756d656e745631004c120000536f6d6500be000000506f736974696f6e00e900000041740007010000466f726d61745370656300d2010000466f726d6174746572006e010000497300f1160000666e2826636f72653a3a666d743a3a566f69642c20266d757420636f72653a3a666d743a3a466f726d617474657229202d3e20636f72653a3a726573756c743a3a526573756c743c28292c20636f72653a3a666d743a3a4572726f723e0033000000767461626c6500d60000004e65787400191500005068616e746f6d446174613c2675383e00a0000000417267756d656e74007e1100004f7074696f6e3c7573697a653e003a1700002a636f6e73742026737472004b1100004f7074696f6e3c26636f72653a3a666d743a3a72743a3a76313a3a417267756d656e743e0046010000436f756e740022080000417267756d656e74563100121500005068616e746f6d446174613c26267374723e00d4130000497465723c267374723e009e130000497465723c636f72653a3a666d743a3a417267756d656e7456313e00aa0100004e657874506172616d008c010000506172616d00db080000566f6964000b1500005068616e746f6d446174613c26636f72653a3a666d743a3a417267756d656e7456313e004d0000005061644164617074657200d616000026636f72653a3a666d743a3a72743a3a76313a3a417267756d656e7400df1100004f7074696f6e3c26636f72653a3a666d743a3a417267756d656e7456313e000a140000497465723c75383e00b9160000265b7573697a653b20365d0000000000840000000200215000000a0100003600000026636f72653a3a6d61726b65723a3a5068616e746f6d446174613c636f72653a3a686173683a3a7369703a3a5369703133526f756e64733e00490000005068616e746f6d446174613c636f72653a3a686173683a3a7369703a3a5369703133526f756e64733e002b000000767461626c6500000000007a00000002002b51000058020000720100005a65726f00f901000026636f72653a3a636861723a3a436173654d617070696e674974657200540100004f6e6500d30000005468726565002b01000054776f0007010000436173654d617070696e674974657200ee010000767461626c6500020200006368617200000000000e00000002008353000045000000000000006c0000000200c85300001f0100003600000026636f72653a3a6e756d3a3a4e6f6e5a65726f5573697a6500620000004e6f6e5a65726f3c7573697a653e00490000004e6f6e5a65726f5573697a65002b000000767461626c650080000000436861724572726f724b696e640000000000300300000200e75400003d060000c4050000265b636f72653a3a666d743a3a417267756d656e7456315d00bb0500002a636f6e737420636f72653a3a666d743a3a72743a3a76313a3a417267756d656e74001e020000496d706c6965640012030000266d7574205772697465000d060000266d757420636f72653a3a666d743a3a466f726d617474657200fc0300005068616e746f6d446174613c2a6d757420466e3c28293e3e000605000026416e7900760500002a636f6e7374202673747200eb05000026636f72653a3a666d743a3a566f696400e20500002a636f6e737420636f72653a3a666d743a3a417267756d656e74563100bd030000536f6d65001f010000506f736974696f6e004a01000041740068010000466f726d61745370656300a204000050616e6963496e666f00b2020000466f726d617474657200cf01000049730058050000265b267374725d0039000000767461626c6500370100004e657874003b0300004f7074696f6e3c265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d3e00f4050000666e2826636f72653a3a666d743a3a566f69642c20266d757420636f72653a3a666d743a3a466f726d617474657229202d3e20636f72653a3a726573756c743a3a526573756c743c28292c20636f72653a3a666d743a3a4572726f723e0001010000417267756d656e7400610300004f7074696f6e3c7573697a653e00790300004e6f6e6500aa0300004f7074696f6e3c26636f72653a3a666d743a3a417267756d656e74733e00a7010000436f756e740076020000417267756d656e745631009d050000265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d000b0200004e657874506172616d00ed010000506172616d0094020000566f69640010040000497465723c636f72653a3a666d743a3a417267756d656e7456313e00030400005068616e746f6d446174613c26636f72653a3a666d743a3a417267756d656e7456313e0033020000417267756d656e7473003306000026636f72653a3a666d743a3a417267756d656e747300d70400004c6f636174696f6e0016060000265b7573697a653b20345d007f0500002673747200000000000e0000000200245b000037000000000000008400000002005b5b000044020000e2000000476c6f62616c006f0000004e6f6e5a65726f3c2a636f6e73742075383e000d0100005665633c75383e00880000005068616e746f6d446174613c75383e009b0000005261775665633c75382c20616c6c6f633a3a616c6c6f633a3a476c6f62616c3e004b000000556e697175653c75383e00000000000e00000002009f5d00007f000000000000000e00000002001e5e00007a070000000000000e0000000200986500005e0c0000000000000e0000000200f6710000c8060000000000000e0000000200be780000ec0900000000000000f63f0d2e64656275675f72616e67657314000000a8000000890100009a010000000000000000000033000000430000004f000000600000000000000000000000bb000000c2000000d0000000060100009b010000a30100000000000000000000bb000000c2000000d0000000e70000009b010000a30100000000000000000000bb000000c2000000d0000000e70000009b010000a30100000000000000000000bb000000c2000000d0000000e70000009b010000a30100000000000000000000bb000000c20000009b010000a30100000000000000000000580100005a01000081010000880100000000000000000000380000004f0000005a000000770000008b0000009500000000000000000000007e920100d5940100e59401000595010000000000000000007e920100d5940100e59401000595010000000000000000007e9201009c9201000d9301001993010000000000000000009c920100059301003f9401008a940100e5940100f89401000000000000000000ab920100059301003f9401005e940100e5940100f89401000000000000000000ab920100059301003f9401005e940100e5940100f89401000000000000000000ab920100059301003f9401005e940100ed940100f89401000000000000000000bc920100be920100c0920100c59201000000000000000000c49301003e9401008b940100d5940100f9940100059501000000000000000000c49301003e9401008b940100d5940100f9940100059501000000000000000000c4930100349401008b940100aa940100f9940100059501000000000000000000c4930100cb930100d2930100349401008b940100aa940100f9940100059501000000000000000000c4930100cb930100d2930100349401008b940100aa940100f9940100059501000000000000000000eb930100ed930100ef930100f49301000000000000000000b5940100ba940100bf940100c29401000000000000000000e1940100e3940100e894010033950100000000000000000046950100089601000a9601001e960100000000000000000046950100089601000a9601001e960100000000000000000046950100089601000a9601001e960100000000000000000046950100089601000a9601001e960100000000000000000046950100b4950100bf950100de9501000a9601001e9601000000000000000000469501004b95010052950100b4950100bf950100de9501000a9601001e9601000000000000000000469501004b95010052950100b4950100bf950100de950100129601001e96010000000000000000006b9501006d9501006f950100749501000000000000000000e9950100ee950100f3950100f695010000000000000000006392010005950100cd94010041950100329501001e9601000000000000000000d2000000d7000000dc000000ef0000000000000000000000050100000a0100000f010000140100000000000000000000290100002e0100003301000038010000000000000000000090970100a7970100b2970100cf970100e0970100ea97010000000000000000001b980100329801003d9801005a9801006b9801007598010000000000000000005d970100fd970100e8970100889801000000000000000000889b01008a9b0100939b0100969b01000000000000000000d69b0100f99b0100079c0100229c01000000000000000000949c0100999c01009b9c0100a09c01000000000000000000949c0100999c01009b9c0100a09c01000000000000000000b59c0100e39c0100ef9c0100089d01000000000000000000089d01000d9d0100dd9d0100df9d0100e19d0100e49d01000000000000000000089d01000d9d0100dd9d0100df9d0100e19d0100e49d01000000000000000000089d01000d9d0100dd9d0100df9d0100e19d0100e49d01000000000000000000089d01000d9d0100dd9d0100df9d0100e19d0100e49d01000000000000000000089d01000d9d0100dd9d0100df9d0100e19d0100e49d01000000000000000000089d01000d9d0100dd9d0100df9d0100e19d0100e49d010000000000000000000d9d0100149d0100229d0100279d0100e49d0100eb9d010000000000000000000d9d0100149d0100229d0100279d0100e49d0100eb9d010000000000000000000d9d0100149d0100229d0100279d0100e49d0100eb9d010000000000000000000d9d0100149d0100229d0100279d0100e49d0100eb9d01000000000000000000149d0100229d0100279d01002e9d0100eb9d0100f29d0100b69e0100c49e0100e29e01007b9f01000000000000000000149d0100229d0100279d01002e9d0100eb9d0100f29d0100b69e0100c49e0100e29e01007b9f01000000000000000000149d0100229d0100279d01002e9d0100eb9d0100f29d01000000000000000000609f0100659f0100709f0100719f0100000000000000000026a0010040a001004ba0010068a001009aa00100a5a0010000000000000000005f9d0100799d0100849d0100a19d0100bf9d0100ca9d01000000000000000000269e0100409e01004b9e0100689e0100909e01009b9e01000000000000000000739801009e9b01009f9b0100b8a001000000000000000000efa6010008a701000aa7010017a701001ea7010036a7010041a7010078a7010076a801008ca80100a7a80100b1a80100c1a8010028a901000000000000000000a7a80100a9a80100aea80100b1a801000000000000000000d7a80100d9a80100dea80100e3a801000000000000000000f8a80100faa80100ffa8010004a90100000000000000000079a70100e9a701008da8010099a80100000000000000000084a70100e9a701008da8010099a80100000000000000000084a701008fa70100afa70100b4a701000000000000000000b9a70100c7a70100dea70100e1a701008da8010099a801000000000000000000b9a70100c7a70100dea70100e1a701008da8010099a801000000000000000000b9a70100c7a70100dea70100e1a701008da8010099a801000000000000000000fda7010061a801009aa80100a6a801000000000000000000fda7010061a801009aa80100a6a801000000000000000000fda7010008a8010027a801002ca80100000000000000000031a801003fa8010056a8010059a801009aa80100a6a80100000000000000000031a801003fa8010056a8010059a801009aa80100a6a80100000000000000000031a801003fa8010056a8010059a801009aa80100a6a80100000000000000000011a60100c0a60100a8a6010037a9010009a901002aa9010026a9010047a9010044a9010079aa01000000000000000000ef8d0100f18d0100fb8d01002a8e010000000000000000002a8e01003a8e01004b9101004d91010000000000000000002a8e01003a8e01004b9101004d91010000000000000000002a8e0100358e01004b9101004d91010000000000000000005d8e01006e9001008b900100ca9001000000000000000000dd900100e99001001a910100219101000000000000000000dd900100e99001001a910100219101000000000000000000e4900100e99001001a910100219101000000000000000000e4900100e99001001a910100219101000000000000000000e4900100e99001001a910100219101000000000000000000e4900100e99001001a91010021910100000000000000000074aa0100a1aa0100a3aa0100b0aa0100b7aa0100cfaa0100daaa01003bab01004bab0100b8ab010000000000000000002eab010033ab010038ab01003bab0100000000000000000061ab010066ab01006bab010070ab0100000000000000000085ab01008aab01008fab010094ab01000000000000000000ae860100b7860100d2860100d98601000000000000000000e3860100ea8601000687010018870100000000000000000081870100a78701008b880100fb880100228901003c8a01000000000000000000bd880100fb88010022890100a68901000000000000000000c1890100d1890100eb890100ed89010000000000000000003b88010042880100638801008b880100fc88010013890100000000000000000083ad0100e6ad010027ae010099ae01009fae0100a1ae0100a3ae0100a3af0100000000000000000083ad0100e6ad010027ae010084ae010092ae010099ae0100000000000000000083ad0100e6ad010027ae010084ae010092ae010099ae0100000000000000000083ad0100e6ad010027ae010081ae0100000000000000000083ad0100e6ad010027ae010081ae010000000000000000009ead0100a7ad0100b4ad0100bdad01000000000000000000caad0100d1ad0100dbad0100e6ad0100000000000000000068ae01006dae010078ae010079ae010000000000000000009fae0100a1ae0100a3ae01009eaf010000000000000000009fae0100a1ae0100a3ae01009eaf010000000000000000009fae0100a1ae0100a3ae01008baf010000000000000000009fae0100a1ae0100a3ae01008baf010000000000000000009fae0100a1ae0100a3ae0100afae0100d7ae0100dbae01000000000000000000a8ae0100afae0100d7ae0100dbae01000000000000000000bdae0100c8ae0100d2ae0100d7ae0100000000000000000003af01000eaf010018af010021af0100000000000000000072af010077af010082af010083af0100000000000000000099ae01009fae0100a1ae0100a3ae01000000000000000000c0af0100c5af0100c7af0100ccaf01000000000000000000c0af0100c5af0100c7af0100ccaf01000000000000000000f7af0100feaf01001ab001002cb00100000000000000000046b001004db001006db001007fb0010000000000000000008bb00100adb0010006b1010062b2010076b201009cb20100000000000000000018b201002cb2010046b2010048b20100000000000000000030a10100e6a30100f1a301004da4010073a40100c0a4010000000000000000004aa101008ca2010073a401008ba40100a5a40100b2a40100000000000000000061a101006ca10100eea10100fba10100000000000000000088a10100a2a1010073a401008ba40100000000000000000088a10100a2a1010073a401008ba40100000000000000000018a201002fa2010071a2010078a201007fa201008ca20100000000000000000071a2010078a201007fa201008ca20100000000000000000045a2010057a2010062a2010067a201000000000000000000a0a20100e6a301008ca40100a4a40100b3a40100c0a401000000000000000000b7a20100c2a2010044a3010051a301000000000000000000dea20100f8a201008ca40100a4a401000000000000000000dea20100f8a201008ca40100a4a4010000000000000000006ea3010085a30100c7a30100cea30100d5a30100e0a301000000000000000000c7a30100cea30100d5a30100e0a3010000000000000000009ba30100ada30100b8a30100bda301000000000000000000c2a40100e6a4010015a5010049a501005da5010071a5010085a5010098a50100aca50100bfa50100d3a5010016a6010029a601003ca601000000000000000000c2a40100e6a4010015a5010049a501005da5010071a5010085a5010098a50100aca50100bfa50100d3a5010016a6010029a601003ca60100000000000000000015a5010049a501005da5010071a5010085a5010098a50100aca50100bfa50100d3a5010016a6010029a601003ca601000000000000000000eaa40100f7a4010001a501000fa5010049a5010057a5010071a501007fa5010098a50100a6a50100bfa50100cda5010016a6010023a601003ca6010049a6010000000000000000000692010009920100139201001992010000000000000000003c8d01009e9101005caa0100c6ab0100568601005b8a0100b3ab010033ad01001dad0100b9b2010082b20100acb2010066a0010065a60100e99101000a920100069201001a92010000000000000000003f22010056220100612201007e2201008f22010099220100000000000000000034920100399201003e92010065920100000000000000000097250100a1250100a8250100c4250100000000000000000019bf00002dbf000038bf000055bf00005fbf000069bf000000000000000000000c220100a8220100179201006f920100a9b20100abb20100acb20100b8b201006c250100e1250100f7be00007cbf000000000000000000000000000055000000570000005f00000000000000000000000000000055000000570000005f0000000000000000000000000000002c000000570000005f0000000000000000000000000000002c000000570000005f0000000000000000000000000000002c000000570000005f0000000000000000000000000000000c000000570000005f0000000000000000000000115608004756080048560800b1560800b2560800de560800df56080023570800000000000000000002000000a5000000b0000000b3000000000000000000000002000000a5000000bf000000c200000000000000000000008a0000008d0000001c0200001e020000000000000000000032010000370100003b0100003e010000000000000000000032010000370100003b0100003e0100000000000000000000865908008e5908009d590800aa5908000000000000000000ea570800ef5708000a5a08000c5a08000000000000000000150000002e00000030000000380000000000000000000000150000003f0000004100000046000000000000000000000002000000af00000002000000b300000002000000c2000000010000000f000000010000004100000024570800715708003d5a0800985a0800020000003002000064570800515a0800010000004e000000010000005c0000000000000000000000190000001b00000021000000220000000000000000000000190000001b0000002100000022000000000000000000000064000000680000007500000077000000000000000000000002000000300000003200000052000000540000009f000000a3000000c3000000cb000000ce0000000000000000000000a3000000ab000000b8000000b9000000cb000000ce0000000000000000000000a3000000ab000000b8000000b90000000000000000000000ab000000b8000000b9000000ba00000000000000000000000200000035000000370000005c0000005e000000ae000000b2000000d7000000df000000e20000000000000000000000b2000000ba000000cc000000cd000000df000000e20000000000000000000000b2000000ba000000cc000000cd0000000000000000000000ba000000cc000000cd000000ce000000000000000000000018000000bf010000db010000de0100000000000000000000180000002b00000032000000430000000000000000000000180000002b00000032000000430000000000000000000000a9000000ae000000b8000000bd0000000000000000000000ae000000b7000000bd000000cb0000000000000000000000b7000000b8000000cb000000d00000000000000000000000540100005c010000610100009a0100009c010000a1010000a4010000ac010000db010000de0100000000000000000000540100005c010000610100009a0100009c010000a1010000a4010000ac01000000000000000000009a0100009c010000a1010000a4010000ac010000b50100000000000000000000cc5a0800245b0800295b0800385b08000000000000000000cc5a0800245b0800295b0800385b08000000000000000000a1000000a6000000b0000000b50000000000000000000000a6000000af000000b5000000c30000000000000000000000af000000b0000000c3000000c80000000000000000000000460100004e010000530100008c0100008e01000093010000960100009e010000ac010000ae0100000000000000000000460100004e010000530100008c0100008e01000093010000960100009e01000000000000000000008c0100008e01000093010000960100009e010000ab01000000000000000000001600000045000000470000004f00000054000000590000005e0000007c0000008c0000008f0000000000000000000000160000002200000032000000450000005e0000006300000066000000710000008c0000008f0000000000000000000000160000002200000032000000450000005e00000063000000660000007100000000000000000000006300000066000000710000007c00000000000000000000002200000032000000470000004f000000540000005900000000000000000000002200000032000000470000004f00000054000000590000000000000000000000010000007800000002000000ce00000002000000e200000002000000de010000c75a08003c5b080002000000d0010000020000008f0000000000000000000000010000003e00000043000000500000000000000000000000280000002d000000350000003a000000000000000000000031000000350000003a0000003e0000000000000000000000010000003e000000430000005c00000000000000000000001c000000210000002b0000002e000000000000000000000024000000280000003a0000003e00000000000000000000002e00000032000000370000003900000000000000000000004e000000520000005a0000005c0000000000000000000000010000003e000000430000005000000000000000000000001c000000210000002b0000002e000000000000000000000024000000280000003a0000003e00000000000000000000002e0000003200000037000000390000000000000000000000515b0800555b08005a5b08005d5b080000000000000000005d5b08005f5b0800655b0800685b080000000000000000005f5b0800655b08006b5b0800745b080000000000000000001a0000001e0000002300000026000000000000000000000026000000280000002e000000310000000000000000000000280000002e000000340000003d000000000000000000000022000000260000002b0000002e0000000000000000000000270000002b00000030000000330000000000000000000000b45b0800b85b0800bd5b0800c05b0800000000000000000025000000290000002e0000003100000000000000000000000100000051000000010000005d00000001000000510000003d5b0800945b080001000000710000000100000064000000010000007d000000955b0800ec5b0800010000007100000000000000000000000100000036000000380000003b00000000000000000000001300000018000000250000002f000000380000003b00000000000000000000001300000018000000250000002f000000000000000000000001000000380000003a0000003d0000000000000000000000170000001a00000027000000310000003a0000003d0000000000000000000000170000001a00000027000000310000000000000000000000130000002e000000300000003300000000000000000000001300000018000000250000002800000030000000330000000000000000000000130000001800000025000000280000000000000000000000170000003000000032000000350000000000000000000000170000001a000000270000002a00000032000000350000000000000000000000170000001a000000270000002a00000000000000000000000100000043000000470000004a00000000000000000000000100000018000000210000003a000000470000004a00000000000000000000000100000018000000210000003a000000470000004a00000000000000000000000100000018000000210000003a000000470000004a000000000000000000000013000000180000002900000033000000470000004a00000000000000000000001300000018000000290000003300000000000000000000001a000000210000003f0000004000000000000000000000000100000045000000490000004c0000000000000000000000010000001a000000230000003c000000490000004c0000000000000000000000010000001a000000230000003c000000490000004c0000000000000000000000010000001a000000230000003c000000490000004c0000000000000000000000170000001a0000002b00000035000000490000004c0000000000000000000000170000001a0000002b0000003500000000000000000000001c0000002300000041000000420000000000000000000000180000006c0000006e00000083000000880000009d000000ad000000b00000000000000000000000180000006c0000006e00000083000000880000009d000000ad000000b000000000000000000000001f00000024000000290000003000000000000000000000002400000029000000300000003a00000000000000000000002400000029000000300000003a00000000000000000000003a00000049000000620000006c0000006e0000007a0000008800000090000000ad000000b000000000000000000000003a00000049000000620000006c0000006e0000007a000000880000009000000000000000000000007b0000007e000000900000009300000000000000000000007e00000083000000930000009d0000000000000000000000490000004e000000530000005800000000000000000000004e00000053000000580000006200000000000000000000004e00000053000000580000006200000000000000000000003a0000006c0000006e0000007b0000008000000095000000a5000000a800000000000000000000003a0000006c0000006e0000007b0000008000000095000000a5000000a800000000000000000000003a00000049000000620000006c0000006e000000730000008000000088000000a5000000a800000000000000000000003a00000049000000620000006c0000006e00000073000000800000008800000000000000000000007300000076000000880000008b0000000000000000000000760000007b0000008b000000950000000000000000000000490000004e000000530000005800000000000000000000004e00000053000000580000006200000000000000000000004e0000005300000058000000620000000000000000000000010000003b000000010000003d00000001000000330000000100000035000000010000004a000000010000004c00000002000000b000000002000000a8000000000000000000000000cc0f0d2e64656275675f616262726576011101250e1305030e10171b0eb442190000023400030e491302186e0e00000313001d13030e0b0b88010f0000040f004913030e0000052400030e3e0b0b0b0000063400030e49136e0e0000073901030e00000804014913030e0b0b88010f0000092800030e1c0f00000a2e006e0e030e3a0b3b05200b00000b1101250e1305030e10171b0eb442191101120600000c3900030e00000d1301030e0b0b88010f00000e0d00030e491388010f380b00000f0d00030e491088010f380b0000101300030e0b0b88010f00001104014910030e0b0b88010f0000122e00110112066e0e030e3a0b3b053f198701190000132e006e0e030e3a0b3b0b200b0000140f004910030e0000153400030e49133f193a0b3b0b02186e0e0000162e01110112066e0e030e3a0b3b053f190000171d0131135517580b59050000181d01311311011206580b59050000191d00311311011206580b590500001a1d00311311011206580b590b00001b1d0131135517580b590b00001c1d0031135517580b590b00001d1d01311311011206580b590b00001e1d00311011011206580b590b00001f1d0031105517580b59050000200101491300002121004913220b370b0000221701030e0b0b88010f0000230d0049130b0b0d0b0c0b380b0000240d00491388010f380b0000251701030e0b0b3c1988010f0000260d00030e491088010f380b34190000271301030e0b0b3c1988010f0000282400030e0b0b3e0b0000290101491000002a1501491000002b0500491300002c2e01110112066e0e030e3a0b3b0587011900002d1101250e1305030e10171b0eb442191101551700002e2e01110112066e0e030e3a0b3b0b00002f1d0031135517580b59050000301d0131105517580b59050000311d01311011011206580b59050000321d00311011011206580b59050000332e006e0e030e3a0b3b0b3f19200b0000342e011101120631130000353400030e49133f193a0b3b056e0e00003621004913220b37050000372e01110112066e0e030e3a0b3b053f198701190000383400030e49133f193a0b3b0b88010f6e0e0000393400030e49103f193a0b3b0502186e0e00003a13001d10030e0b0b88010f00003b2e006e0e030e3a0b3b053f19200b00003c1d0131105517580b590b00003d1d0031105517580b590b00003e1301030e0b0588010f00003f0d00030e491388010f38050000400d00030e491088010f38050000410d00030e491388010f380b34190000422e01110112066e0e030e3a0b3b050000431d01311011011206580b590b0000442e01110112066e0e030e3a0b3b0b3f190000452e00110112066e0e030e3a0b3b050000463400030e49133a0b3b0b6e0e0000472e01110112066e0e030e3a0b3b0b3f198701190000482e00110112066e0e030e3a0b3b0b0000492e006e0e030e3a0b3b0b3f19870119200b000000011101250e1305030e10171b0eb44219110155170000023901030e0000032e00110112066e0e030e3a0b3b0b3f19000000011101250e1305030e10171b0eb44219110155170000023901030e0000032e006e0e030e3a0b3b05200b0000042e006e0e030e3a0b3b0b870119200b0000052e011101120631130000061d00311311011206580b590b0000072e006e0e030e3a0b3b0b3f19200b0000082e01110112066e0e030e3a0b3b0b3f190000091d0131135517580b590b00000a2e00110112066e0e030e3a0b3b0b3f1900000b2e0011011206311300000c1d00311311011206580b590500000d1d01311311011206580b590500000e1d0131135517580b590500000f1d01311311011206580b590b0000101d0031135517580b590b0000111d0031135517580b59050000122e01110112066e0e030e3a0b3b053f190000132e006e0e030e3a0b3b0b200b000000011101250e1305030e10171b0eb44219110155170000023901030e0000032e006e0e030e3a0b3b0b3f19200b0000042e006e0e030e3a0b3b0b200b0000052e01110112066e0e030e3a0b3b0b3f190000061d01311311011206580b590b0000071d00311311011206580b590b0000081d0131135517580b590b0000091d0031135517580b590b00000a2e0111011206311300000b2e01110112066e0e030e3a0b3b053f1900000c2e006e0e030e3a0b3b0b870119200b00000d2e006e0e030e3a0b3b05200b000000011101250e1305030e10171b0eb44219110155170000023901030e0000032e006e0e030e3a0b3b0b200b0000042e01110112066e0e030e3a0b3b0b3f190000051d0131135517580b590b0000061d00311311011206580b590b0000071d0031135517580b590b0000082e006e0e030e3a0b3b0b3f19200b0000092e0111011206311300000a1d01311311011206580b590b00000b2e006e0e030e3a0b3b053f19200b00000c2e01110112066e0e030e3a0b3b053f1900000d2e006e0e030e3a0b3b05200b000000011101250e1305030e10171b0eb44219110155170000023901030e0000032e006e0e030e3a0b3b05200b0000042e006e0e030e3a0b3b0b200b0000052e011101120631130000061d0131135517580b590b0000071d00311311011206580b590b0000081d01311311011206580b590b0000091d0031135517580b590b00000a2e01110112066e0e030e3a0b3b0b3f1900000b2e006e0e030e3a0b3b0b3f19200b00000c2e01110112066e0e030e3a0b3b053f1900000d2e006e0e030e3a0b3b0b870119200b000000008d96010b2e64656275675f6c696e653d000000040037000000010101fb0e0d0001010101000000010000012f636865636b6f75742f7372632f6c6962636f72650000726573756c742e727300010000009500000004007b000000010101fb0e0d0001010101000000010000016c6962616c6c6f63002f636865636b6f75742f7372632f6c6962636f72652f6e756d002f636865636b6f75742f7372632f6c6962636f726500007261775f7665632e7273000100006d6f642e727300020000636d702e727300030000616c6c6f632e727300010000000005022601000003f3050105040a21020e0001011a000000040014000000010101fb0e0d0001010101000000010000010000f40200000400bd010000010101fb0e0d0001010101000000010000016c6962616c6c6f632f636f6c6c656374696f6e732f6274726565006c6962616c6c6f63002f636865636b6f75742f7372632f6c6962636f72652f666d74002f636865636b6f75742f7372632f6c6962636f7265002f636865636b6f75742f7372632f6c6962636f72652f736c696365002f636865636b6f75742f7372632f6c6962636f72652f6f7073002f636865636b6f75742f7372632f6c6962636f72652f6e756d002f636865636b6f75742f7372632f6c6962636f72652f69746572002f636865636b6f75742f7372632f6c6962636f72652f73747200006e6f64652e727300010000666d742e7273000200006d6f642e7273000300007074722e7273000400006d6f642e72730005000061726974682e727300060000636d702e7273000400006d6f642e727300070000726573756c742e727300040000616c6c6f632e7273000200007261775f7665632e727300020000737472696e672e7273000200006d6f642e7273000800007472616974732e7273000800006974657261746f722e72730008000066756e6374696f6e2e7273000600006d6f642e7273000900007665632e727300020000000402000502ee23010003b60401040305230a03c67e083c0404050803980208c80405051403ef0d2004040508039172580403051503e97dac0406052c03f07d740405051703c21158051403d400ba0403050b03fc6f580508068203807d58050b0380035805088203807d2e051206038203820407053d03a304580405050803fe17900603dd6090040805100603d118200603af67ba040205080603b904900603c77b900409050e0603ea05200402050803cf7e74040a050403957cd6040b0514031f82040a050d03f9004a06039a7eac040c05080603ac039e0403051303b77e084a0522069e05080230120409050c0603c50408740402050403957e2e050108910603c27bba040905160603a906200603d779740403051206038203200603fe7c0812040905160603ec052002080001011a000000040014000000010101fb0e0d00010101010000000100000100004000000004003a000000010101fb0e0d0001010101000000010000012f636865636b6f75742f7372632f6c6962636f72652f736c69636500006d6f642e727300010000001a000000040014000000010101fb0e0d0001010101000000010000010000b6000000040068000000010101fb0e0d0001010101000000010000012f636865636b6f75742f7372632f6c6962636f7265002f636865636b6f75742f7372632f6c6962636f72652f666d740000726573756c742e7273000100006d6f642e7273000200006d6163726f732e727300010000000005025891010003d50701050b0a0227130402050803977b08120401050b03e90408660402050803977bac0401050b03e90408ba0402050803977b083c040303ac7d9e02130001011a000000040014000000010101fb0e0d0001010101000000010000010000a504000004000f010000010101fb0e0d0001010101000000010000012f636865636b6f75742f7372632f6c6962636f72652f666d74002f636865636b6f75742f7372632f6c6962636f72652f63686172006c6962616c6c6f63002f636865636b6f75742f7372632f6c6962636f72652f6e756d002f636865636b6f75742f7372632f6c6962636f7265002f636865636b6f75742f7372632f6c6962636f72652f736c69636500006d6f642e7273000100006d6574686f64732e7273000200007665632e7273000300007261775f7665632e7273000300006d6f642e727300040000636d702e727300050000616c6c6f632e727300030000737472696e672e7273000300007074722e7273000500006d6f642e727300060000000005026392010003d9010105100a083d0402050b0390017405080608ac0403050b0603c4052e0404050c03ac79580403050b03d4067405080620040505140603e90f2e0404051b039c6b9e0519300406053303b103580500060399792e053303e7062e0500039979580404050c0603a0055805103f05315a0407050403cd7b7406038e7f022c01040805400603ae08200402051203bf7a74050f069e05100603d2002e052c062e0510820649052d062e052c7405104a03c27c9e05160603c103200510af052c062e0510820649052d062e052c7405104a0649052d062e052c7405104a03be7c9e0603c70320052d062e051082064d052c062e0510820648052d062e052c7405104a064b052d062e052c7405104a03b77c820404050c0603db01200403051903f501740405051403c512740404050f03806f3c050c063c04050514060383132e0404051b039c6b9e0519300406053303b103580500060399792e053303e7062e0500039979580404050c0603a0055805103f05315a0407050403cd7b7406038e7f022c01040405080603d001200603b07e90040705040603ce00200404051103dd04820603d57a58050c0603af0520750403052c0383039e0603cd779e040405080603d00120040903a5095805290383783c0403050c03bd05580603cb77083c040705040603ce00200404051103dd04820603d57a58050c0603af0520750403050803aa049e0603a6769e0603970620051903960958050803ea7658040903de043c040a050c03e001580603ab73d60401050d0603dc01200603a47ed6040405250603f703200603897c740407050d0603e6012006039a7eac03e60120020c000101000502cd94010003dd010105130a084105102a05135c0522063c0508023012050d060871020e0001010005023295010003d5010105100a3d0404050c08160403051903f501580405051403c512740404050f03806f3c050c063c04050514060383132e0404051b039c6b9e0519300406053303b103580500060399792e053303e7062e0500039979580404050c0603a0055805103f05315a0407050403cd7b7406038e7f022c01040405080603d001200603b07e90040705040603ce00200404051103dd04820603d57a58050c0603af0520750403050803aa049e0603a6769e0603970620051903960958050803ea7658040903de043c040a050c03e001580401050d038375c80603a87e20040405250603f703200603897c740407050d0603e60120020c0001017f01000004003c000000010101fb0e0d0001010101000000010000016c6962636f72652f666d74006c6962636f726500006e756d2e7273000100007074722e72730002000000000502ad58010003c8010105220a03e07e0874051a03b101086605101e0603a87e2e05180603e1014afb0521083e0402050803b703ba0401051803cc7c20670521ef0402050803b603740401051803cd7c2064051a037a7405000603a67e9e051403da014a05130603109e0510066603967e4a051303ea01c805102003967e2e05130603f2017405100620038e7e4a040205080603f50a200401051403f8765804020508038809580401051d03f676082e0402050803aa03200401051403d97c7405136a05100658038e7e2e040205080603f50a2004010514038277580402050803fe08580401051d0381775804020508039f03580401051403e37c740603887e82040205080603f50a200401051403fe765804020508038209580401051403ff765806038c7e82050c06038002200540f0050c3e050983020e0001013000000004002a000000010101fb0e0d0001010101000000010000016c6962636f72652f6e756d00006d6f642e727300010000001a000000040014000000010101fb0e0d00010101010000000100000100009400000004008e000000010101fb0e0d0001010101000000010000016c6962636f72652f756e69636f6465006c6962636f7265006c6962636f72652f736c696365006c6962636f72652f6974657200007072696e7461626c652e7273000100007074722e7273000200006d6f642e727300030000636c6f6e652e7273000200006f7074696f6e2e7273000200006d6f642e72730004000000dc000000040042000000010101fb0e0d0001010101000000010000016c6962636f72652f736c696365006c6962636f72652f666d7400006d6f642e7273000100006d6f642e727300020000000005025d970100038f0f0105040a0222130402050803dd7308120401050403a30c08660402050803dd73ac0401050403a30c08ba0402050803dd7308120401050403a30c9e0213000101000502e897010003950f0105040a0222130402050803d77308120401050403a90c08660402050803d773ac0401050403a90c08ba0402050803d77308120401050403a90c9e02130001014300000004003d000000010101fb0e0d0001010101000000010000016c6962636f72652f6e756d2f666c74326465632f7374726174656779000067726973752e72730001000000d305000004009f000000010101fb0e0d0001010101000000010000016c6962636f72652f737472006c6962636f7265006c6962636f72652f736c696365006c6962636f72652f666d74006c6962636f72652f6368617200006d6f642e7273000100007074722e727300020000726573756c742e7273000200006d6f642e7273000300006d6f642e7273000400006f7074696f6e2e7273000200006d6574686f64732e727300050000000005027398010003d2020105040a03cd08740603e074082e05140603b40b082e050b0222130508062004020510060397072e0401050c03a77958051003123c050a039b7f580504065803e0744a05140603b60b90051003140812051806f203b674ba03ca0b081203b674083c05160603f40b200510067405330632ad49051b5a05180682051406320516037658051006580518063405163505250690051406e50516570603ff7374050a0603a00b2e0504065803e0744a05220603da0b58051908590603a574ac03db0bba03a5743c052803db0b20051906d70603a4742e03dc0bac03a4743c03dc0b9e03a4743c05280603dd0b200519066603a3749003dd0b9e03a3743c05170603e00b200603a07408c80603e30b4a06039d7408e405220603ce0b58051908590603b174ac03cf0bba03b1743c052803cf0b20051906d70603b0744a03d00bac03b0743c03d00b9e03b0743c05280603d10b200519068203af749003d10b9e03af743c0603d20b200603ae74f203d20b9e03ae743c05170603d50b580603ab7408c8050c0603e90b20050a03b77f58050406580603b5774a050108750603aa7d20040305080603e3090241010401051a03f1782e04030508038f07900401050403f2783c05017502010001010005029f9b010003a510010a03da6f022701062e050706039a102e0504068203e66f2e0404050b0603e20f2e0401050c03af01084a051230051806ac050806038a7f200603e36f2e050c06039e1020050b03f100ac0508038e7f089e05000603e36f6605140603a810580533d70513066605333c050003d76f3c051303a9102e050003d76fe405070603ac103c050c02221805040658050b0603dd002e040403d37ef20401050c03af0158040205080384742e0401051203fe0b580518065805100603a37f200603ca6f2e050b06038f11c8040403d37eba0401050c03af010820051230051806c805040603a67f200603c76f2e05080603ba1020050b03d500900603f16e0866038f112004020508060386742006580404051706039b0d74051403d4003c0603fc6c4a05170603b012580402050803e5722e04040517039b0d58051403d4003c0603fc6c4a040105080603ae10c8040503c072022401040103c00d0890040503c072ac040103c00d08ba040503c07208c8040103c00dac0603d26f082004020603950520040105000603eb7a2e040205080395052e3c0404051706039b0d74051403d4003c0603fc6c4a040105040603b210200405050803bc720233010401050403c40d08900405050803bc72ac0401050403c40d08ba0405050803bc720228010401050403c40dac0603ce6f0820050c0603f803900507ad05040620050d0603c40c2e0603c36fc8040405170603b0120812051403d4003c040205080391722e0401050e03d87e7405049d0603947c3c050706038304820504069e03fd7b2e040405170603b01282051403d40074040205080391722e0401050e03d87e740504730603947c3c05320603e30320050b03269e0508069e03f77b2e040405170603b0124a051403d400740401050e03e9702e0504730603947c3c05320603e303200511032a5805320356ac050c032a200406050e03ca7e9e050c210603a87d2e05140603d902200603a77dc80401050d0603bd1008820407050b03ae72ac0508066603957d2e05120603ed024a050f066603937d2e05120603ef024a050f067403917d3c040105150603be1020052306900515580504063d0405050803af720242010401050403d10d08900405050803af72ac0401050403d10d08ba0405050803af720232010401050403d10dac02130001015b0400000400bc000000010101fb0e0d0001010101000000010000016c6962636f72652f6f7073006c6962636f72652f666d74006c6962636f7265006c6962636f72652f736c696365006c6962636f72652f756e69636f6465000072616e67652e7273000100006d6f642e7273000200006e756d2e7273000200007074722e72730003000061726974682e7273000100006d6f642e72730004000063656c6c2e7273000300006275696c646572732e727300020000626f6f6c5f747269652e7273000500000000050211a6010003dc000105080a083d052e060225120508580402050e0603d40a3c05180608120508023e12040105050603ad750812020e0001010403000502a8a6010003990101040205280a038b0c084a0403051003f67308c805000603e57e2e040205280603a70d740403051703f673580603e37e2e051a0603da014a0510720603a87e2e05180603e1014a051403bf7fba0518033c2e05140344c80521033e740404050803b703ba0403051803cc7c2067051403be7f580521033fac0404050803b603740403051803cd7c2064051a037a7405000603a67e9e051403da014a05130603109e0510066603967e4a051f06038f01200405052c03b602ac0403052003e27cac052e03de00902105226505100346663e0405052c03f802740403051003887d580406050b03e60f58050806ba04030603ad702e0406050403cc1d08660403050803b4623c050d03c200820603de7ee40405052c0603c503580403052003e27cac052e03e000902105225705100344663e0405052c03f802740403051003887d580406050b03e60f58050806ba04030603ad702e0406050403cc1d08660403050803b4623c050d03c200820603de7ee405130603ea01c80510062003967e2e05130603f2017405100620038e7e4a0406050c0603b410200603cc6fba03b4102003cc6fba040405080603f50a200403051403f8762e04040508038809580403051403ab763c051d03cb00f20404050803aa03200403051403d97c7405136a05100658038e7e2e040405080603f50a20040305140382772e0404050803fe08580403051d0381775804040508039f03580403051403e37c740603887e82040405080603f50a200403051403fe762e04040508038209580403051403ff765806038c7e82050c06038002200540f0050c3e050d03a27f82020f000101040700050209a9010003cc0401040205080a03ce06200407050503b47908d60201000101040700050226a9010003e00401040205080a03ba06200407050503c87908d60201000101040900050244a90100032b01050b0a3e050806083c051f062f052706ac051f200351ac051206033020050f06900520062f051806c8051f06084b06034e0820052006033420051806c8051f060813053a0620053974051f20051766051f06083d06034af205050603cb0082050406664a050506036d200603482005180603312006034f0820051f0603322006034e082005180603342006034c082005170603352006034b0820051f0603362002120001011a000000040014000000010101fb0e0d00010101010000000100000100001a000000040014000000010101fb0e0d00010101010000000100000100007512000004004e010000010101fb0e0d0001010101000000010000016c6962636f72652f666d74006c6962636f7265006c6962636f72652f736c696365006c6962636f72652f69746572006c6962636f72652f737472006c6962636f72652f63686172006c6962636f72652f756e69636f6465006c6962636f72652f6e756d00006d6f642e7273000100007074722e7273000200006d6f642e7273000300006f7074696f6e2e7273000200006d6f642e7273000400006974657261746f722e7273000400006e756d2e7273000100006d6f642e727300050000636d702e7273000200006d6574686f64732e72730006000072616e67652e7273000400007461626c65732e7273000700006d6f642e7273000800007072696e7461626c652e727300070000636c6f6e652e7273000200006d6f642e727300060000636f6e766572742e7273000600006275696c646572732e727300010000000005023c8d010003fe070105180a084b050e08350518037982050e084304020508038e7d900401051803eb02820515030b02320104020508038a7d900401051503f6023c050a760508c90520030a580403050c03927c740401050d03eb032e0403050c03957c9e051703860e022f01051403d40090062e040105100603957558052806580510c8050806032a08120515062e050858063b0514062e050858063e0515062e050858050c06031074051e0602261203ac77ba0403051c060380132005205a051703ae7f74051403d4002003532e0402050803be722e0403051403c20d580401050b03f06f3c050806ba051c062f051a065803b87d7405210603d60820051083050b03f07908120508060820051c062f051a065803b87d5805100603d708ac0603a977081205080603c50820050c030f08c8051e0602261203ac77900403051c060380132005205a051703ae7f74051403d4002003532e0402050803be722e0403051403c20d580401050b03f06f3c050806ba051c062f051a065803b87d7405210603d60820051059050b03f07908120508060820051c062f051a065803b87d5805100603d708ac0603a977081205080603c60820050c085c0521d70527068203b577089e0403051c060380132005205a051703ae7f74051403d4002003532e0402050803be722e0403051403c20d580603a96d3c0401051006039a08e405000603e677d605080603cf085805000603b1779e050803cf083c03b177ba05270603cb08200603b5770820040405140603d902200603a77dc80401052006039008200403051403f40a082006740401051006038d7558052806580510c80608130402050803837dd60401052003fd027405100674050003ee77ba05100392082e040305140603f20a084a051703ac7f2e051403d4008204010508039d752e0520068205089e03df77084a05010603a508200603db77e403a50820020f0001010005025caa010003ad0201040705220a03fb7d0874051a03b101086605101e0603a87e2e05180603e1014a0401050803ce00e40407051803ad7f2e0401050803d300c80407052103af7f740402050803b703ba0407051803cc7c20670401050803cd00580407052103b07fac0402050803b603740407051803cd7c2064051a037a7405000603a67e9e051403da014a05130603109e0510066603967e4a051303ea01c805102003967e2e05130603f2017405100620038e7e4a040205080603f50a200407051403f876580402050803880958040103ba773c0407051d03bc7ff20402050803aa03200407051403d97c7405136a05100658038e7e2e040205080603f50a2004070514038277580402050803fe08580407051d0381775804020508039f03580407051403e37c740603887e82040205080603f50a200407051403fe765804020508038209580407051403ff765806038c7e82050c06038002200540f0050c3e04010505033082020e00010100050256860100038d090105170a02221905089f052603bf03ac050f03c37c9e05000603e8762e050c0603970974051e067405260603f103740603f87290050c0603990920051e067403e77674051b06039c0958052603ec0374050803957c74050c3d0403051403e609740603fc6c740408050c0603c90482050d49052903a07f82050c03e100580402050803cc003c04030517039b0d74051403d400580408050803c771660401051d03d304580603e27658050c0603ae0920051b037474050c030c089e051108bf0522065805193c05080603ed0374051903987c580522030a2e051a03d60090050c75cd0603e2753c039e0a4a050003e2755805100603af0974052506e4050506031808ba0603b976d605100603b40920052506e4050506031308ba0603b976d605100603ba09207376051703e900e4052203987f740409053303a77d08f20401050c03c503d603760890052a310537067403df75ba05170603a40a9e051375040a050f039579ba05103d0603c57cc805160603bd0320051084052c062e0510820649052d062e052c7405104a03c27c9e040105140603bd09200505030a08660603b976d6040a05160603c103200510af052c062e0510820649052d062e052c7405104a0649052d062e052c7405104a03be7c9e0603c70320052d062e051082064d052c062e0510820648052d062e052c7405104a064b052d062e052c7405104a03b77c82040905330603e306089e040b050803f37ad60401050c03d2082e040b050803ae7708900401051403ed072e052606e405080603e80008660603d5752e040905330603e3064a040b050803f37aba0401050c03d8082e0603d275084a05050603c7092e0603b976d603c70920020e000101000502b3ab010003a10901051d0a083d05130608580510062f0533060812040a050f0603967a740510bb0603c57cc805160603bd03200510a0052c062e0510820649052d062e052c7405104a03c27c9e05160603c103200510af052c062e0510820649052d062e052c7405104a0649052d062e052c7405104a03be7c9e0603c70320052d062e051082064d052c062e0510820648052d062e052c7405104a064b052d062e052c7405104a03b77c8204010603a409580603dc760866050f0603a60920050c0682051a3c052a58051ae403da76083c05090603a809200603d876d603a80920020e0001010005021dad010003e509010a039a76083c062e3c0404050c0603c3012e0401050b03a5080226010517330603937666050b0603e809200603987658040205080603950508660408050c03e37eac0507910504062003877c2e040305170603b0124a051403d400740408050e03e9702e05049d0402050803a9013c0603eb7a900408050706038304200504069e040305170603ad0e2e051403d400580408050e03e9702e0504730402050803a9013c0603eb7aac040105130603e909200505032708ba0603f075d60408050b06038904084a0508069e03f77b2e040305170603b0120812051403d40090040205080391722e0408050e03d87e740504730603947c5805320603e303660511032a5805320356ac050c032a20050e03910182050c210603e17a2e0406060389022004080525039a03c8050803dc0f740403051703b17d660408050803cf022e0403051703b17d2e051403d4003c040205080391722e0408050c03e37e740507ad05040620040305170603b70e2e051403d400900408050e03e9702e0504730402050803a9013c0403051403c20d580408050703ac714a050406ba03fd7b4a0507038304900504ba03fd7b2e040305170603b01220051403d400900408050e03e9702e0504730402050803a9013c0408050b03f47e900508066603f77b4a050b0389049005086603f77b2e040305170603b0120820051403d40090040205080391722e0408050e03d87e740504730603947c5805320603e303660511032a5805320356ac050c032a20050e03910182050c210603e17a2e05250603a30520051006580406050c0603e67c9e0408050b03860f580603f16e74038f117403f16e3c038f112003f16e7404030603e20f4a0408050c03af0158040205080384742e0408051203fe0b5805180658050c0603e87d20060385712e04040603ef02660603917d08200403051406038413ac0603fc6c740408050c0603c90482050d49052903a07f82050c03e100580402050803cc003c04030517039b0d74051403d400580408050803c771660401053003b90558051b068203fc75580403051406038413820603fc6c740408050c0603c904ba050d49052903a07f82050c03e100580402050803cc003c04030517039b0d74051403d400580401052203877766051a030dba050c75cd05000603e2758205140603810a740505030f08ba0603f075d605100603850a200505030b08ba0603f075d6052a0603a10a200537067403df75ba05170603a40a9e051375040a050f039579d605103d0603c57cc805160603bd03200510a0052c062e0510820649052d062e052c7405104a03c27c9e05160603c103200510af052c062e0510820649052d062e052c7405104a0649052d062e052c7405104a03be7c9e0603c70320052d062e051082064d052c062e0510820648052d062e052c7405104a064b052d062e052c7405104a03b77c82040905330603e306089e040b050803f37a08200401050c03d2082e040b050803ae7708900401051403b6082e0508031f08660603d5753c05050603900a200603f075d6040905330603e30658040b050803f37ad60401050c03d8082e0505036208580603f075d603900a20020e000101040800050282b2010003e50e0105460a3c054d06e4055482052e82020800010100050266a0010003c10f0105080a03a37fac03de0008d60603bd702e05110603c40f4a040a050c0382720225010603ba7e8203c601022f0103ba7e82040c05080603b30520040a051103977c82051703693c040d051903e00f58040a051b03a3703c05084b0603c97ec8040e05070603350812050406e40510062d0511035c90040205080385050866040e051703fe7aac05112d051759050a57050b92050806580403050b06039f102e0508065805120630050f0666040205080603e0742e0603eb7aac040e0510060316740511730402050803800574040e051a03807b5805132f0510065805080648051234050f065803662e031a820366c8040305170603b01290051403d40090040e0510039c6d4a040f051803870108ba040e051503fd7e0866051206200515062b050852050b9106035658040305170603b01220051403d40090040205080391722e040e03947b74050c2a040f051803820190040e050c03fe7e58050824050b590508062003562e04020603950520040e03987b740403051703831274051403d40090040e050403b16d4a050e30050b06740510062b0511035c90040205080385050866040e051703fe7aac05112d051759050a57050b92050806580403050b06039f102e0508065805120630050f0666040205080603e0742e0603eb7aac040e0510060316740511730402050803800574040e051a03807b5805132f05088e051234050f065803662e031a820366c8040305170603b01290051403d40090040e0510039c6d4a040f051803870108ba040e051503fd7e0866051206200515062b050852050b9106035658040305170603b01220051403d40090040205080391722e040e03947b74050c2a040f051803820190040e050c03fe7e58050824050b590508062003562e04020603950520040e03987b740403051703831274051403d40090040e050803a66d2e040a051103a301660603b37e9e040e050b0603cc00200508036eba0603462e033aac03463c033a9e03463c033a9003463c033aba03463c033a9003463c033a9003463c040a05170603b30174040d051903e00f58040a051b03a3703c05084b0603c97eac0403050c0603b410820603cc6fac0603b610200603ca6fba0603b410200603cc6fac0603b610200603ca6fba040405140603d902200603a77dc803d9022003a77dc80410050c06038c022e0603f47d022401040105080603e50e4a050c03e000c80603bb705805080603e50e58050c03e000d60603bb70580410050e06039d0120050cad0603e27e8205100603b501084a0401050803b00dba050c03e000d60603bb70580410051006039f01200401050803c60d083c050c03e000d60603bb7058041005100603a701200401050803be0d082e050c03e000d60603bb7058041005100603a301200401050803c20d082e050c03e000d60603bb7058041005200603ab01200535062e05347405203c041105110603fd009022050b6305080658041005100603867f3c0514770401050803b50d0874050c03e000c80603bb7058041005140603ae01200401050803b70d082e050c03e000c80505770603b8702005080603e50e2006039b71e405050603c80f200203000101000502e991010003e8000105080a03b20a20051b03ce7508d602010001010005020692010003fa0e0105080a03c10020054203bf7f2e050803c1009e054f03bf7f6602010001011a000000040014000000010101fb0e0d00010101010000000100000100004400000004003e000000010101fb0e0d0001010101000000010000016c6962636f72652f6e756d2f666c74326465632f73747261746567790000647261676f6e2e727300010000001a000000040014000000010101fb0e0d00010101010000000100000100001a000000040014000000010101fb0e0d0001010101000000010000010000a101000004006f000000010101fb0e0d0001010101000000010000016c6962636f7265006c6962636f72652f666d74000070616e69636b696e672e7273000100006d6f642e72730002000070616e69632e7273000100007074722e727300010000616e792e7273000100006f7074696f6e2e727300010000000005020c220100033801050e0a0222140402050803b30208120401050e03cd7d08660402050803b302ac0401050e03cd7d08ba0402050803b30208120401050403cd7d9e020f00010100050217920100033f0105090a0860040305080376740401050f030a58040305080376580401050d030f022701020a0001010404000502a9b20100033a010a2002010001010405000502acb2010003f2000105390aac02010001010005026c250100032b0105150a085f050f0674050974040205080603a802740401052603d97d9e0402050803a702740401053503d97d08ac050406d6020f0001010406000502f7be000003e60701040205080a03877b0222010406050403fa04083c0402050803867bac0406050403fa0408ba0402050803867b9e0406050403fa049e02130001012f000000040029000000010101fb0e0d0001010101000000010000016c6962616c6c6f630000616c6c6f632e7273000100000001010000040096000000010101fb0e0d0001010101000000010000016c6962616c6c6f63002f636865636b6f75742f7372632f6c6962636f7265002f636865636b6f75742f7372632f6c6962636f72652f736c6963650000736c6963652e727300010000726573756c742e7273000200007261775f7665632e727300010000616c6c6f632e7273000100006d6f642e7273000300007665632e727300010000000005029a1c010003e304010402050e0a0386013c050c750403051603f77a2e04040504036c9004030514031f820404050d03f9004a06039a7eac0405050c0603d50c660401050803d474d6050503bd03084a06039a7b20040205160603ec052002080001015701000004005a000000010101fb0e0d00010101010000000100000172757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f73726300006d656d2e72730001000000000502115608001a05040a4106037274050806030f4a0523064a050858050a063b050406082e0501066b02030001010005024856080003150105070a400504069005080631050c5a0527069e050cac063b0508570504630508030a2e06035c58050c0603254a0527064a050c58050e063b0508037908660501030d2e0203000101000502b2560800032c0105040a3e0603517405080603304a050a8f050406ba0501066b0203000101000502df56080003360105040a3e06034790051006033a4a9f050b9f0508063c03442e050a06033958050406580501060309580603be7f2003c2003c03be7f20051306033d2005015d02010001014c0900000400e0000000010101fb0e0d00010101010000000100000172757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372630072757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372632f696e74002f636865636b6f75742f7372632f6c6962636f72652f6e756d00006d6163726f732e727300010000756469762e7273000200006d6f642e7273000300006c69622e7273000100006d6f642e727300020000000005020200000003fd0101040205080a03a17f3c0603e17e740603a5014a0403051903ee0f74063c051406038205580402050b03976b7405080620050b063305080674050003cf7e2e04010509060380022e0603807e200402050c0603c00120051403799e05082a051478490519064a051458051006030b82051b0674050c58040305140603d2143c040203b76b9e051122050c06580603763c0510062e050c5805140603093c050e03729005080658060312580603af7e9e0401050906038002200603807e3c0404050d0603292002030001010005020200000003fd0101040205080a03a17f3c0603e17e740603a5014a0403051903ee0f74063c051406038205580402050b03976b7405080620050003d47e2e050b0603b1014a05080658050c06030f2e051403799e05082a051478490519064a051458051006030b82051b0674050c58040305140603d2143c040203b76b9e051122050c06580603763c0510062e050c5805140603093c050e03729005080658060312580603af7e9e0603da0120050c062e05085804010509060326200603807e200404050d0603292002030001010005020200000003fd0101040205080a03a17f3c0603e17e740603a5014a0403051903ee0f74063c051406038205580402050b03976b7405080620050003d47e2e050b0603b1014a05080658050c06030f2e051403799e05082a051478490519064a051458051006030b82051b0674050c58040305140603d2143c040203b76b9e051122050c06580603763c0510062e050c5805140603093c050e03729005080658060312580603af7e9e050f0603e30120050c750517064a050c58039c7e4a0401050906038002200603807e3c0404050d0603292002030001010005020100000003fd0101040205080a036e20040105090314ba02010001010005020100000003fd0101040205160a0374083c050875f304010509030c74020e0001010005022457080003fd0101040205080a083804010509088804020508037a2e040105098802160001010005023d5a080003fd0101040205160a083e0508d7084b04010509720402050830040105095602160001010005020200000003fd0101040505100a035b5804020508032e02280104050510035258037a820402050803343c04030519038c0f9e063c0514060382053c0402050803f26b580603f97d3c0387024a5804010509060379900603807e2004020508060387022004050510034cac040205080334580603f97d58038702580405051006034c2e0403052203be123c051003d1103c0402050803a55d200603f97d58038702200405051006034c580402050803343c04030514038e143c0510038205580402050803f0665804030519038c0f3c063c0514060382053c0402050803f26b580603f97d3c0387024a5804010509060379900603807e20040205080603870258065804010509060379900603807e200403051406039516200510038205580402050803f066580603f97d3c04030519060393112e0402050803f4705804030519038c0f200402050803f4703c0603f97d820387023c03f97dd603870220740403052206038a122e0405051e03ce6d58051d063c04020508060328200603f97d3c040305290603e1132005100381115804010509039e5d200603807e20040305140603e013200603a06c58040505100603d3012004030529038e123c05100381113c06039e5b3c0401050906038002200603807e3c04020508060387022006740405051006034c4a0402050803343c0403051003db22200402050803a55d200603f97d3c0387022074040105090603792e0603807e2004020508060387022006740405051e06035874051d063c05102005179004020508060328200603f97d3c03870220040305240603910e2e0402050803ef71580403051003db222e04010509039e5d200603807e2004020508060387023c0603f97dba03870220085803f97d740387024a0403051406038e14e40402050803f26b9e0620829e9003f97d08120387025803f97d6603870220040305240603910e2e0402050803ef713c0401050903792e0603807e200404050d060329200603572e0402050806038702200603f97d7403870220040105090603798202010001010005026457080003fd0101040205080a0311085806022912040305190603840f9e064a0514060382054a0402050803fa6b580603f17d3c038f023c03f17dd6038f0220050003f17dac0508038f02740403052206038212900402050803fe6d580603f17d58038f02200403051406038614ba0510038205580402050803f866660403051903840f2e064a0514060382054a0402050803fa6b580603f17d3c038f02205803f17d083c0403051406039516200510038205580402050803f866660603f17d2e04030519060393112e0402050803fc70740403051903840f200402050803fc704a0603f17d82038f0282740403052206038212900402050803fe6d580603f17d3c040305290603e1132006039f6c9005140603e013660603a06c2e05290603e1132006039f6c900402050806038f0220067403f17d0812038f022074040305240603890e900402050803f7713c0603f17d0890038f02207403f17d0812038f0220040305240603890e2e0402050803f771580603f17d4a038f02ac03f17dba038f022003f17d025301038f02820403051406038614e40402050803fa6b8204030514038614e40402050803fa6bc80620089e08909003f17d90038f02081203f17d660404050d060329200603572e0402050806038f02200603f17dd6038f022003f17d0890040105090603800220021a0001010005020100000003a40201040205080a0355083c04010509032d08820402050803532e04010509032d8202160001010005020100000003a40201040205160a035b083c0508d7084b0401050903257404020508035b2e040105090325580216000101dd07000004002f010000010101fb0e0d00010101010000000100000172757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372630072757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372632f696e74002f636865636b6f75742f7372632f6c6962636f72652f6f7073002f636865636b6f75742f7372632f6c6962636f72652f6e756d002f636865636b6f75742f7372632f6c6962636f726500006d6163726f732e7273000100006d6f642e7273000200006269742e7273000300006d6f642e72730004000061726974682e7273000300006d756c2e727300020000636d702e7273000500006c69622e727300010000000005020100000003fd0101040205100a03553c040303b00274040203d07d20040303b00290040403a91220063c04020603ad6b2e040403d314660405053203896f200402051003a47c20040403d314660405053203896f3c0403052d03dc7b2006900404051006039b1574040303d76d74040403a912200405053203896f580403051003ce7e580404051403fc11200403051003846e20040403a912740405053203896f580403051003ce7e580404051403fc11200402051e03e06b20051d063c040305100603b70120053503d801580405053203c700740402051003aa7c2005170620040105090603212002010001010005020200000003fd0101040605080a03a37e3c0407053303f205740406050803907ae4050f2f0510750401050903db01ba0603807e200407053306039306200406050803967aac050f2f0510750401050903d501ba0603807e20040305100603830420052f03b97e580405052c03947f5804070533039305740406050b03d2792006034b2e03350812040705330603de053c0406050803a57a740407053303b1062e0406050c03d079ba05102f0401050903c601ba0603807e200404051306038b053c0407053303de01820404052203a57ec80407053303db01200406050c03d4792005102f060342740401050906038002660603807e200408050d0603292002030001010005020200000003fd0101040605080a03a37e3c0407053303f205740406050803907a083c050f2f0510750401050903db01ba0603807e200407053306039306200406050803967af2050f2f0510750401050903d501ba0603807e20040305100603830420052f03b97e580405052c03947f5804070533039305740406050b03d2792006034b2e03350812040705330603de053c0406050803a57a740407053303b1062e0406050c03d079081205102f0401050903c601ba0603807e200404051306038b053c0407053303de01820404052203a57e08200407053303db01200406050c03d4792005102f060342740401050906038002660603807e200408050d0603292002030001010005020200000003fd0101040405140a039106085804060508039278082e0404051403ee07740407053303847e08120406050803907a0890050f2f0510c906035b900407053306039306200406050803967a083c050f3d0510c90603559004030603830420052f03b97e580405052c03947f5804070533039305900403052f03d97b200405052c03947f5804070533039305d60406050b03d2795806034b2e0335082e040705330603de05089e0406050803a57ae40603482e040705330603e90608820406050c03d079089e05103d060346900404051306038b053c0405052a036d8204040513031358052208310407053303db010226010404052203a57e2e0407053303db01580404052203a57e3c0407053303db01820406050c03d4799005103d060342740401050906038002200603807e08900408050d060329200203000101000502c75a080003a4020105090a3e0403051003dc012e067404040603a91258051403e3713c0405053203a67d580404051403da02200405053203a67d580403052d03dc7b2006ac0404051006039b1590040303d76d74040403a912200405053203896f580403051003ce7e580404051403df03200403051003a17c20040403a912900405053203896f580403051003ce7e580404051403df03200401050903c57a200403051003ef0058053503d801580405053203c700900401050903f27c2002040001010005020200000003a40201040405140a03ea0508900407053303847e0224010406050803907a0874050f2f06035c08200407053306039306200406050803967a0858050f2f0603560820040305100603830458052f03b97e580405052c03947f5804070533039305900403052f03d97b200405052c03947f5804070533039305d60406050b03d2795806034b2e0335082e040705330603de05089e0406050803a57ae40603482e040705330603e90608820603977908d60404051306038b05580405052a036d8204040513031358052208310407053303db010226010404052203a57e2e0407053303db01580404052203a57e3c0407053303db018206039779c80408050d060329200603572e040105090603a7022002210001010005020200000003a40201040405140a03bb11083c051003cc02ba052903b57df20401050903c66e082e040405100385142e0401050903fb6b8204040510038514580401050903fb6b580404052903ba115804070533038873580404052903f80c3c04070533038873ac0401050903be7bac0603d97de40408050d060329200203000101580500000400d7000000010101fb0e0d00010101010000000100000172757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372630072757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372632f696e74002f636865636b6f75742f7372632f6c6962636f72652f6f707300006d6163726f732e72730001000073686966742e7273000200006d6f642e7273000200006269742e727300030000000005020100000003fd01010402050b0a038b7e3c05080674050f06300403051003c801740402052f03bd7e740404051003f30358040303d67d2e040403bd01660658052c0603cf7e3c0403051e037a20051d063c040405100603b70120040303c97e580517062003a17e3c0401050906038002200603807e3c040305100603d30120040403c3013c0403051e03c97e66051d063c040105090603212002010001010005020100000003fd01010402050b0a03a07e3c05080674050f06310403051003b80174040403aa028206580403051e0603dc7d3c051d063c051006037420040403b0023c03937f3c0402052f038f7d4a0404051003f10258052c03cf7e2e04030510037a200517062003a17e3c0401050906038002200603807e3c040305100603d90120040403aa029e0403051e03dc7d20051d063c040405100603a40220040303dc7d8205170620040105090603212002010001010005020100000003fd01010402050b0a03b67e3c05080674050f06300403051003a30174040403aa028206580403051e0603dc7d3c051d063c051006037420040403b0023c03937f3c0402052d03a37d4a0404051003dd0258052c03cf7e2e04030510037a200517062003a17e3c0401050906038002200603807e3c040305100603d90120040403aa0266040303dc7d660401050903212002010001010005023d5b080003a402010402050b0a03e47d3c0508069e050f06300404051003f803580402052f038d7c4a0404051003f3035803937f3c062e66052c0603cf7e3c051003b1013c0603ea7c900396032003ea7ce4040105090603a70220020f0001010005020100000003a402010402051a0a03c57e58050b039f7fba05080620050f06300404051003f803580402052f038d7c4a0404051003f3035803937f3c062e66052c0603cf7e3c051003b1013c0603ea7c900396032003ea7ce4040105090603a702200402052303c37ef20401050903bd01e402040001010005020100000003a402010402050b0a03f97d3c050806ba050f06310404051003e2035803937fac0402052f038f7d4a0404051003f10258052c03cf7e3c0510039e023c0603fd7b90038304207403fd7bc8040105090603a70266020f0001010005020100000003a402010402051a0a03d67e58050b03a37fd605080620050f06310404051003e2035803937fac0402052f038f7d4a0404051003f10258052c03cf7e3c0510039e023c0603fd7b90038304207403fd7bc8040105090603a702660402052303d47ef20401050903ac01e40204000101000502955b080003a402010402050b0a038f7e3c0508069e050f06300404051003cd035803937fac0402052d03a37d4a0404051003dd0258052c03cf7e3c0510039e023c0603fd7b900383042003fd7be4040105090603a70220020f0001010005020100000003a402010402051a0a03de7e58050b03b17fba05080620050f06300404051003cd035803937fac0402052d03a37d4a0404051003dd0258052c03cf7e3c0510039e023c0603fd7b900383042003fd7be4040105090603a702200402052303dc7ef20401050903a401e4020400010126050000040010010000010101fb0e0d00010101010000000100000172757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f737263002f636865636b6f75742f7372632f6c6962636f72652f6f7073002f636865636b6f75742f7372632f6c6962636f72652f6e756d0072757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372632f696e7400006d6163726f732e7273000100006269742e7273000200006d6f642e72730003000061726974682e7273000200006c69622e727300010000736469762e7273000400006d6f642e727300040000000005020100000003fd0101040205100a0385023c052f03b97e740403051403bd055803e70b3c0603a06c580402052f0603bc02580403051403bd0558052903e80b3c0402052f03db6e9e06200404052c0603947f3c0401050903303c0603807e200405050d0603292002030001010005020100000003fd0101040205100a0385023c052f03b97e740403051403bd055803e70b740603a06c3c0402052f0603bc02580403051403bd0558052903e80b3c0402052f03db6e9e06200404052c0603947f3c0401050903303c0603807e200405050d0603292002030001010005020100000003fd0101040305100a03901208200603f26b580402052f0603bc02580403051403bd0558052203980c3c0402052f03ab6e3c0404052c03947f3c0401050903303c0603807e200405050d0603292002030001010005020100000003fd0101040305130a03901208580510062003f26b2e0402052f0603bc02580403051403bd0558052203980c3c0402052f03ab6e3c0404052c03947f3c0401050903303c0603807e200405050d0603292002030001010005020100000003fd0101040205100a0385023c052f03b97e740403051403bd055803e70b3c0406050803d36c580404052c039d012e0402052f03ec00740403051403bd0558052903e80b3c0402052f03db6e9e06200404052c0603947f3c0403051403bf063c0404052c03c179580406050803e37e200401050903cd013c0603807e3c0405050d0603292002030001010005020100000003fd0101040205100a0385023c052f03b97e740403051403bd055803e70b740406050803d36c3c0404052c039d012e0402052f03ec00740403051403bd0558052903e80b3c0402052f03db6e9e06200404052c0603947f3c0403051403bf063c0404052c03c179580406050803e37e200401050903cd013c0603807e3c0405050d0603292002030001010005020200000003a40201040205100a03de010858052f03b97e740403051403bd05580402052f03c37a580403051403bd057403e70b9e0529830402052f03db6e740403051403bd05580402052f03c37a580403051403bd0558052903e80b9e0401050903c66e9e0403052903ba112e0402052f03db6eba06200404052c0603947f3c0401050903d700580403052903ba11580402052f03db6e820404052c03947f3c0401050903d7009e0603d97de40405050d0603292002030001010005020200000003a40201040305130a03e91102380105100666052206310402052f03ab6e740403051403bd05580402052f03c37a580403051403bd0558052203980c9e0401050903966e9e0403052203ea112e0402052f03ab6e580404052c03947f3c0401050903d700580403052203ea11580402052f03ab6e820404052c03947f3c0401050903d7009e0603d97de40405050d06032920020300010100aac9020a2e64656275675f737472636c616e67204c4c564d202872757374632076657273696f6e20312e33302e302d6e696768746c79202837303631623237373520323031382d30382d32382929006c6962616c6c6f632f6c69622e7273002f636865636b6f75742f73726300767461626c650028290026282900636f7265006f7074696f6e00753332004e6f6e6500536f6d65004f7074696f6e006368617200446f6e650043686172004261636b736c61736800556e69636f64650045736361706544656661756c74537461746500753800526967687442726163650056616c7565004c6566744272616365005479706500457363617065556e69636f6465537461746500726573756c7400753136004f6b0045727200526573756c7400666d74007274007631004e65787400417400506f736974696f6e004c6566740052696768740043656e74657200556e6b6e6f776e00416c69676e6d656e7400497300506172616d004e657874506172616d00496d706c69656400436f756e7400616c6c6f6300636f6c6c656374696f6e730043617061636974794f766572666c6f7700416c6c6f6345727200436f6c6c656374696f6e416c6c6f6345727200267538006274726565006e6f646500454d5054595f524f4f545f4e4f444500706172656e7400646174610065646765730070747200706f696e746572006e6f6e7a65726f005f5f30002a636f6e737420616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4c6561664e6f64653c28292c2028293e004e6f6e5a65726f3c2a636f6e737420616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4c6561664e6f64653c28292c2028293e3e005f6d61726b6572006d61726b6572005068616e746f6d446174613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4c6561664e6f64653c28292c2028293e3e00556e697175653c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4c6561664e6f64653c28292c2028293e3e00426f7865644e6f64653c28292c2028293e005f5f41525241595f53495a455f545950455f5f00496e7465726e616c4e6f64653c28292c2028293e002a636f6e737420616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a496e7465726e616c4e6f64653c28292c2028293e00706172656e745f696478006c656e006b6579730076616c73004c6561664e6f64653c28292c2028293e005f5a4e35616c6c6f633131636f6c6c656374696f6e73356274726565346e6f64653135454d5054595f524f4f545f4e4f4445313768356330366134623266393465643665394500626f72726f7700426f72726f776564004f776e656400436f77006c6962636f72652f6c69622e7273006e756d0041534349495f4c4f574552434153455f4d4150005f5a4e34636f7265336e756d313941534349495f4c4f574552434153455f4d415031376836333736323831313632393734396132450041534349495f5550504552434153455f4d4150005f5a4e34636f7265336e756d313941534349495f5550504552434153455f4d415031376835386637333734303165636661323061450041534349495f4348415241435445525f434c415353004300437700570044004c004c7800550055780050004173636969436861726163746572436c617373005f5a4e34636f7265336e756d323141534349495f4348415241435445525f434c415353313768323164633232626138646666663666614500456d70747900496e76616c69644469676974004f766572666c6f7700556e646572666c6f7700496e744572726f724b696e640026636f72653a3a6e756d3a3a496e744572726f724b696e64006974657200436f6e74696e756500427265616b004c6f6f70537461746500267533320064656332666c7400496e76616c696400466c6f61744572726f724b696e6400693136002669313600666c7432646563007374726174656779006772697375004341434845445f504f57313000753634005f5f31005f5f3200287536342c206931362c2069313629005f5a4e34636f7265336e756d37666c743264656338737472617465677935677269737531324341434845445f504f573130313768313437333033363863623331366632354500736c696365007600646174615f707472002a636f6e7374207538006c656e677468007573697a6500265b75385d0070726564007374720049734173636969576869746573706163650066696e697368656400626f6f6c0053706c69743c75382c20636f72653a3a7374723a3a49734173636969576869746573706163653e007072656469636174650049734e6f74456d7074790046696c7465723c636f72653a3a736c6963653a3a53706c69743c75382c20636f72653a3a7374723a3a49734173636969576869746573706163653e2c20636f72653a3a7374723a3a49734e6f74456d7074793e006600556e736166654279746573546f537472004d61703c636f72653a3a697465723a3a46696c7465723c636f72653a3a736c6963653a3a53706c69743c75382c20636f72653a3a7374723a3a49734173636969576869746573706163653e2c20636f72653a3a7374723a3a49734e6f74456d7074793e2c20636f72653a3a7374723a3a556e736166654279746573546f5374723e0026636f72653a3a697465723a3a4d61703c636f72653a3a697465723a3a46696c7465723c636f72653a3a736c6963653a3a53706c69743c75382c20636f72653a3a7374723a3a49734173636969576869746573706163653e2c20636f72653a3a7374723a3a49734e6f74456d7074793e2c20636f72653a3a7374723a3a556e736166654279746573546f5374723e00555446385f434841525f5749445448005f5a4e34636f7265337374723135555446385f434841525f57494454483137686466386530626461396564346537363745007061747465726e0054776f576179005374725365617263686572496d706c007461736b00706f6c6c0052656164790050656e64696e6700506f6c6c00663634002666363400267573697a65005a65726f004e756d00436f70790050617274006275696c6465727300627566002a6d757420753800265b7573697a653b20365d00266d7574205772697465006f6e5f6e65776c696e650050616441646170746572005068616e746f6d446174613c636f72653a3a686173683a3a7369703a3a5369703133526f756e64733e0026636f72653a3a6d61726b65723a3a5068616e746f6d446174613c636f72653a3a686173683a3a7369703a3a5369703133526f756e64733e00647261676f6e00504f573130005f5a4e34636f7265336e756d37666c743264656338737472617465677936647261676f6e35504f57313031376835373534333262373564643162343231450054574f504f573130005f5a4e34636f7265336e756d37666c743264656338737472617465677936647261676f6e3854574f504f573130313768646134623561353036633565613761664500504f573130544f3136005f5a4e34636f7265336e756d37666c743264656338737472617465677936647261676f6e39504f573130544f3136313768636537306530653638653662306234314500504f573130544f3332005f5a4e34636f7265336e756d37666c743264656338737472617465677936647261676f6e39504f573130544f3332313768353835633337343666363735613138664500504f573130544f3634005f5a4e34636f7265336e756d37666c743264656338737472617465677936647261676f6e39504f573130544f3634313768386539623562633132656230636266394500504f573130544f313238005f5a4e34636f7265336e756d37666c743264656338737472617465677936647261676f6e3130504f573130544f313238313768323865613130353662346332313562374500504f573130544f323536005f5a4e34636f7265336e756d37666c743264656338737472617465677936647261676f6e3130504f573130544f3235363137683364613366326463366137306531346145005255535424454e554d24444953520054687265650054776f004f6e6500436173654d617070696e67497465720026636f72653a3a636861723a3a436173654d617070696e6749746572004e6f6e5a65726f3c7573697a653e004e6f6e5a65726f5573697a650026636f72653a3a6e756d3a3a4e6f6e5a65726f5573697a6500636f6e7665727400456d707479537472696e6700546f6f4d616e79436861727300436861724572726f724b696e64007261775f766563007069656365730026737472002a636f6e7374202673747200265b267374725d005255535424454e434f44454424454e554d2430244e6f6e6500706f736974696f6e00666f726d61740066696c6c00616c69676e00666c61677300707265636973696f6e00776964746800466f726d61745370656300417267756d656e74002a636f6e737420636f72653a3a666d743a3a72743a3a76313a3a417267756d656e7400265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d004f7074696f6e3c265b636f72653a3a666d743a3a72743a3a76313a3a417267756d656e745d3e00617267730076616c7565005f70726976005f6f696269745f72656d6f766572005068616e746f6d446174613c2a6d757420466e3c28293e3e00566f69640026636f72653a3a666d743a3a566f696400666f726d6174746572004f7074696f6e3c7573697a653e0063757261726700656e64005068616e746f6d446174613c26636f72653a3a666d743a3a417267756d656e7456313e00497465723c636f72653a3a666d743a3a417267756d656e7456313e00466f726d617474657200266d757420636f72653a3a666d743a3a466f726d617474657200666e2826636f72653a3a666d743a3a566f69642c20266d757420636f72653a3a666d743a3a466f726d617474657229202d3e20636f72653a3a726573756c743a3a526573756c743c28292c20636f72653a3a666d743a3a4572726f723e00417267756d656e745631002a636f6e737420636f72653a3a666d743a3a417267756d656e74563100265b636f72653a3a666d743a3a417267756d656e7456315d00417267756d656e7473005f5a4e34636f726533666d7439417267756d656e74733138657374696d617465645f6361706163697479313768396635333036633630336136303564614500657374696d617465645f6361706163697479007b7b696d706c7d7d005f5a4e34636f72653370747233335f244c5424696d706c247532302424425024636f6e737424753230245424475424366f66667365743137686330383462313232653163356466393345006f66667365743c267374723e005f5a4e34636f72653370747233335f244c5424696d706c247532302424425024636f6e737424753230245424475424336164643137683232363737373039633835616539653245006164643c267374723e005f5a4e34636f726535736c69636532395f244c5424696d706c24753230242475356224542475356424244754243469746572313768393537666632313636303264636330324500697465723c267374723e005f5a4e39315f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683133356630303864376465623830313345006e6578743c267374723e005f5a4e39315f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f722447542434666f6c64313768643737336362363032613732376239644500666f6c643c267374722c7573697a652c636c6f737572653e005f5a4e38345f244c5424636f72652e2e697465722e2e4d6170244c54244924432424753230244624475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f722447542434666f6c64313768373938393865663930646430346331374500666f6c643c7573697a652c636f72653a3a736c6963653a3a497465723c267374723e2c636c6f737572652c7573697a652c666e287573697a652c207573697a6529202d3e207573697a653e00747261697473005f5a4e34395f244c54247573697a65247532302461732475323024636f72652e2e697465722e2e7472616974732e2e53756d244754243373756d31376862626133366265333132636138386631450073756d3c636f72653a3a697465723a3a4d61703c636f72653a3a736c6963653a3a497465723c267374723e2c20636c6f737572653e3e006974657261746f72004974657261746f72005f5a4e34636f72653469746572386974657261746f72384974657261746f723373756d31376830346434393336393433333638643933450073756d3c636f72653a3a697465723a3a4d61703c636f72653a3a736c6963653a3a497465723c267374723e2c20636c6f737572653e2c7573697a653e00497465723c267374723e005f5a4e34395f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424244754243134706f73745f696e635f7374617274313768343963663735353239323066653637624500706f73745f696e635f73746172743c267374723e005f5a4e34636f726533666d7439417267756d656e74733138657374696d617465645f636170616369747932385f24753762242475376224636c6f73757265247537642424753764243137686132653666643233333431313964323645007b7b636c6f737572657d7d00666f6c64005f5a4e38345f244c5424636f72652e2e697465722e2e4d6170244c54244924432424753230244624475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f722447542434666f6c6432385f24753762242475376224636c6f73757265247537642424753764243137683739333234363232613664313362316145007b7b636c6f737572657d7d3c7573697a652c636f72653a3a736c6963653a3a497465723c267374723e2c636c6f737572652c7573697a652c666e287573697a652c207573697a6529202d3e207573697a653e006f7073006172697468005f5a4e34375f244c54247573697a65247532302461732475323024636f72652e2e6f70732e2e61726974682e2e41646424475424336164643137683536353661613033336665346139333845006164640066756e6374696f6e00466e4d7574005f5a4e34636f7265336f70733866756e6374696f6e35466e4d75743863616c6c5f6d757431376835373138366435326461393266373939450063616c6c5f6d75743c666e287573697a652c207573697a6529202d3e207573697a652c287573697a652c207573697a65293e00636d7000696d706c73005f5a4e34636f726533636d7035696d706c7339315f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4571244c542424524624247532372462247532302442244754242475323024666f722475323024245246242475323724612475323024412447542432657131376862656432346337653833353430316564450065713c7374722c7374723e005f5a4e36385f244c54242475356224412475356424247532302461732475323024636f72652e2e736c6963652e2e536c6963655061727469616c4571244c542441244754242447542435657175616c313768616331386464623531643736306335614500657175616c3c75383e005f5a4e34636f726535736c69636538315f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4571244c54242475356224422475356424244754242475323024666f72247532302424753562244124753564242447542432657131376862646236653762643261653932333539450065713c75382c75383e005f5a4e34636f726533636d7035696d706c7339315f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4571244c542424524624247532372462247532302442244754242475323024666f722475323024245246242475323724612475323024412447542432657131376834393562366230333833623137383166450065713c5b75385d2c5b75385d3e005f5a4e34636f7265337374723674726169747335345f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c45712475323024666f722475323024737472244754243265713137686463383331373231333764646238616145006571005f5a4e34636f7265336e756d32335f244c5424696d706c24753230247573697a652447542431356f766572666c6f77696e675f6d756c3137683062653962643937363035343261353145006f766572666c6f77696e675f6d756c005f5a4e34636f7265336e756d32335f244c5424696d706c24753230247573697a65244754243131636865636b65645f6d756c313768623635393462373735623161303462384500636865636b65645f6d756c00526573756c743c28292c20616c6c6f633a3a636f6c6c656374696f6e733a3a436f6c6c656374696f6e416c6c6f634572723e005f5a4e34375f244c5424636f72652e2e726573756c742e2e526573756c74244c54245424432424753230244524475424244754243134756e777261705f6f725f656c7365313768383263613861326661343265323936344500756e777261705f6f725f656c73653c28292c616c6c6f633a3a636f6c6c656374696f6e733a3a436f6c6c656374696f6e416c6c6f634572722c636c6f737572653e004e6f6e5a65726f3c2a636f6e73742075383e005068616e746f6d446174613c75383e00556e697175653c75383e00636170006100476c6f62616c005261775665633c75382c20616c6c6f633a3a616c6c6f633a3a476c6f62616c3e005f5a4e34395f244c5424616c6c6f632e2e7261775f7665632e2e526177566563244c54245424432424753230244124475424244754243131616c6c6f636174655f696e313768656463626535383261653434616362304500616c6c6f636174655f696e3c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e005f5a4e34305f244c5424616c6c6f632e2e7261775f7665632e2e526177566563244c54245424475424244754243133776974685f6361706163697479313768323862313261326265636161663962394500776974685f63617061636974793c75383e00766563005665633c75383e005f5a4e33335f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424244754243133776974685f6361706163697479313768303235303462303164363037323764344500737472696e6700537472696e67005f5a4e35616c6c6f6336737472696e6736537472696e673133776974685f6361706163697479313768346463353437333232343039373364344500776974685f6361706163697479005f5a4e35616c6c6f6335616c6c6f6335616c6c6f633137683732393736626531656138393735626245005f5a4e35395f244c5424616c6c6f632e2e616c6c6f632e2e476c6f62616c247532302461732475323024636f72652e2e616c6c6f632e2e416c6c6f632447542435616c6c6f633137686638373532663566396466356537366645005f5a4e35616c6c6f6335616c6c6f63313868616e646c655f616c6c6f635f6572726f7231376831356139326366623563376262366237450068616e646c655f616c6c6f635f6572726f72005772697465005f5a4e34636f726533666d743557726974653977726974655f666d7431376861353736363635363132303761616338450077726974655f666d743c616c6c6f633a3a737472696e673a3a537472696e673e005f5a4e34375f244c5424636f72652e2e726573756c742e2e526573756c74244c5424542443242475323024452447542424475424366578706563743137683336343731633933663561633334303545006578706563743c28292c636f72653a3a666d743a3a4572726f723e005f5a4e34636f726533666d7439417267756d656e747331366e65775f76315f666f726d61747465643137683036383533333539666237366138333845006e65775f76315f666f726d6174746564006861636b005f5a4e35616c6c6f6335736c696365346861636b36746f5f766563313768353638356263633134363538306231334500746f5f7665633c75383e005f5a4e35616c6c6f6335736c69636532395f244c5424696d706c247532302424753562245424753564242447542436746f5f7665633137683362356132623863633663333835613845005f5a4e34636f726535736c69636532395f244c5424696d706c24753230242475356224542475356424244754243135636f70795f66726f6d5f736c696365313768303238653339623661316532623732614500636f70795f66726f6d5f736c6963653c75383e005f5a4e3133395f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424247532302461732475323024616c6c6f632e2e7665632e2e53706563457874656e64244c5424245246242475323724612475323024542443242475323024636f72652e2e736c6963652e2e49746572244c54242475323724612443242475323024542447542424475424244754243131737065635f657874656e64313768653238633930363435633335306336394500737065635f657874656e643c75383e005f5a4e33335f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424244754243137657874656e645f66726f6d5f736c696365313768633934333964656537656665626431374500657874656e645f66726f6d5f736c6963653c75383e006d6574686f6473005f5a4e34636f72653463686172376d6574686f647332325f244c5424696d706c24753230246368617224475424386c656e5f757466383137683736636236323636626631633061666645006c656e5f75746638005f5a4e35616c6c6f6336737472696e6736537472696e67347075736831376864363463373538353739633561363630450070757368005f5a4e35385f244c5424616c6c6f632e2e737472696e672e2e537472696e67247532302461732475323024636f72652e2e666d742e2e577269746524475424313077726974655f6368617231376835326234633266396332623562323462450077726974655f63686172005f5a4e33335f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424244754243470757368313768393337393030366565336661366233374500707573683c75383e005f5a4e34395f244c5424616c6c6f632e2e7261775f7665632e2e526177566563244c5424542443242475323024412447542424475424336361703137683530303564656539373333336564306645006361703c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e005f5a4e34636f7265336e756d32335f244c5424696d706c24753230247573697a652447542431356f766572666c6f77696e675f6164643137686663313236326430636661303463396245006f766572666c6f77696e675f616464005f5a4e34636f7265336e756d32335f244c5424696d706c24753230247573697a65244754243131636865636b65645f616464313768306638303535363630343165353239334500636865636b65645f616464005f5a4e34395f244c5424616c6c6f632e2e7261775f7665632e2e526177566563244c54245424432424753230244124475424244754243138616d6f7274697a65645f6e65775f73697a65313768343965373533363565303663613637654500616d6f7274697a65645f6e65775f73697a653c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e005f5a4e34395f244c5424616c6c6f632e2e7261775f7665632e2e526177566563244c54245424432424753230244124475424244754243136726573657276655f696e7465726e616c313768653265323564306635313430303336614500726573657276655f696e7465726e616c3c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e005f5a4e34395f244c5424616c6c6f632e2e7261775f7665632e2e526177566563244c54245424432424753230244124475424244754243772657365727665313768303164373130626366323063633561304500726573657276653c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e005f5a4e33335f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424244754243772657365727665313768396139356332313333363233363730394500726573657276653c75383e005f5a4e34636f726533636d7035696d706c7335375f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4f72642475323024666f7224753230247573697a65244754243267653137683739666337313765353161646532333845006765004f7264005f5a4e34636f726533636d70334f7264336d61783137683231333032363036663636303665613945006d61783c7573697a653e005f5a4e34636f726533636d70336d61783137683839623663363937636666626332663445005f5a4e35616c6c6f6335616c6c6f63377265616c6c6f633137683662663066306561386161366433323545007265616c6c6f63005f5a4e35395f244c5424616c6c6f632e2e616c6c6f632e2e476c6f62616c247532302461732475323024636f72652e2e616c6c6f632e2e416c6c6f6324475424377265616c6c6f633137683637336538316565386264623030393445005f5a4e34636f72653463686172376d6574686f647332325f244c5424696d706c247532302463686172244754243131656e636f64655f75746638313768663832633062343932323465306362324500656e636f64655f75746638005f5a4e34636f7265336e756d32335f244c5424696d706c24753230247573697a652447542431327772617070696e675f7375623137686531356437343331333133383131363945007772617070696e675f737562005f5a4e34395f244c5424616c6c6f632e2e7261775f7665632e2e526177566563244c5424542443242475323024412447542424475424337074723137683634643433323463336264356633316545007074723c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e005f5a4e37315f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424247532302461732475323024636f72652e2e6f70732e2e64657265662e2e44657265664d7574244754243964657265665f6d757431376862653135623565363366373031383461450064657265665f6d75743c75383e005f5a4e34636f72653370747233315f244c5424696d706c2475323024244250246d757424753230245424475424366f66667365743137686163363032356636356331656136336645006f66667365743c75383e005f5a4e34636f72653370747233315f244c5424696d706c2475323024244250246d757424753230245424475424336164643137683966653932656132353938383533653645006164643c75383e005f5a4e34636f72653370747235777269746531376833333038346537633038353164613230450077726974653c75383e005f5a4e33335f244c5424616c6c6f632e2e7665632e2e566563244c5424542447542424475424336c656e3137683465636364373632303966326333303345006c656e3c75383e005f5a4e33335f244c5424616c6c6f632e2e7665632e2e566563244c5424542447542424475424377365745f6c656e3137683932373132656561613031313265386245007365745f6c656e3c75383e005f5a4e39395f244c5424636f72652e2e6f70732e2e72616e67652e2e52616e6765244c54247573697a6524475424247532302461732475323024636f72652e2e736c6963652e2e536c696365496e646578244c54242475356224542475356424244754242447542431376765745f756e636865636b65645f6d75743137686564666363646666643932323733653245006765745f756e636865636b65645f6d75743c75383e005f5a4e3130335f244c5424636f72652e2e6f70732e2e72616e67652e2e52616e676546726f6d244c54247573697a6524475424247532302461732475323024636f72652e2e736c6963652e2e536c696365496e646578244c54242475356224542475356424244754242447542431376765745f756e636865636b65645f6d75743137683161346133653633633932313732646445005f5a4e34636f726535736c69636532395f244c5424696d706c247532302424753562245424753564242447542431376765745f756e636865636b65645f6d75743137683038386364313166303939356632363745006765745f756e636865636b65645f6d75743c75382c636f72653a3a6f70733a3a72616e67653a3a52616e676546726f6d3c7573697a653e3e0077726974655f666d74005f5a4e35616c6c6f6336737472696e6736537472696e6738707573685f737472313768313236303137383562623966353563324500707573685f737472005f5a4e35385f244c5424616c6c6f632e2e737472696e672e2e537472696e67247532302461732475323024636f72652e2e666d742e2e5772697465244754243977726974655f73747231376833616539633562386232393030646462450077726974655f737472005f5a4e34335f244c5424753332247532302461732475323024636f72652e2e666d742e2e6e756d2e2e496e742447542436746f5f753332313768306233323633353631383939653637614500746f5f753332005f5a4e34636f72653370747233335f244c5424696d706c247532302424425024636f6e737424753230245424475424366f66667365743137683833353336393834353137646564636245005f5a4e34636f72653370747233315f244c5424696d706c2475323024244250246d757424753230245424475424366f66667365743137686361656230363034663530346364383245005f5a4e34636f726533737472313972756e5f757466385f76616c69646174696f6e31376836326134326434653937613138346332450072756e5f757466385f76616c69646174696f6e005f5a4e34636f7265337074723132616c69676e5f6f6666736574313768653730336164343235303733636633324500616c69676e5f6f66667365743c75383e005f5a4e34636f72653370747233335f244c5424696d706c247532302424425024636f6e7374247532302454244754243132616c69676e5f6f66667365743137683932626136633565343365363632366245005f5a4e37385f244c5424636f72652e2e726573756c742e2e526573756c74244c54245424432424753230244524475424247532302461732475323024636f72652e2e6f70732e2e7472792e2e54727924475424313066726f6d5f6572726f7231376838643465326163353434323262656237450066726f6d5f6572726f723c267374722c636f72653a3a7374723a3a557466384572726f723e005f5a4e34636f72653373747232357472756e636174655f746f5f636861725f626f756e646172793137683061656666623036313962636366663445007472756e636174655f746f5f636861725f626f756e64617279005f5a4e36385f244c54247573697a65247532302461732475323024636f72652e2e736c6963652e2e536c696365496e646578244c542424753562245424753564242447542424475424336765743137683637373861373566346162316330646645006765743c75383e005f5a4e34636f726535736c69636532395f244c5424696d706c2475323024247535622454247535642424475424336765743137683335333438303137346465666137613945006765743c75382c7573697a653e005f5a4e34636f72653373747232315f244c5424696d706c247532302473747224475424313669735f636861725f626f756e6461727931376835643230303861346233303337623762450069735f636861725f626f756e64617279005f5a4e34636f72653370747233335f244c5424696d706c247532302424425024636f6e737424753230245424475424336164643137683633383337613637396137333032333245005f5a4e36385f244c54247573697a65247532302461732475323024636f72652e2e736c6963652e2e536c696365496e646578244c54242475356224542475356424244754242447542431336765745f756e636865636b65643137686432636137386631343230383964363345006765745f756e636865636b65643c75383e005f5a4e34636f726533737472367472616974733130355f244c5424696d706c2475323024636f72652e2e736c6963652e2e536c696365496e646578244c5424737472244754242475323024666f722475323024636f72652e2e6f70732e2e72616e67652e2e52616e676546726f6d244c54247573697a65244754242447542431336765745f756e636865636b65643137683437353363323138366266326532636645006765745f756e636865636b6564005f5a4e34636f726533737472367472616974733130355f244c5424696d706c2475323024636f72652e2e736c6963652e2e536c696365496e646578244c5424737472244754242475323024666f722475323024636f72652e2e6f70732e2e72616e67652e2e52616e676546726f6d244c54247573697a65244754242447542433676574313768663033306363633831373962633030664500676574005f5a4e34636f726533737472367472616974733130355f244c5424696d706c2475323024636f72652e2e736c6963652e2e536c696365496e646578244c5424737472244754242475323024666f722475323024636f72652e2e6f70732e2e72616e67652e2e52616e676546726f6d244c54247573697a65244754242447542435696e646578313768383262333261343331363031383365664500696e646578005f5a4e34636f726533737472367472616974733130355f244c5424696d706c2475323024636f72652e2e6f70732e2e696e6465782e2e496e646578244c5424636f72652e2e6f70732e2e72616e67652e2e52616e676546726f6d244c54247573697a6524475424244754242475323024666f7224753230247374722447542435696e6465783137683438303561653433303663663535373445005f5a4e34636f726535736c69636532395f244c5424696d706c24753230242475356224542475356424244754243469746572313768643039343966633833343833333364314500697465723c75383e005f5a4e34636f72653373747232315f244c5424696d706c2475323024737472244754243563686172733137686238333735306138626266303931623045006368617273005f5a4e39315f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683762643436386134626134333962313545006e6578743c75383e005f5a4e34636f72653373747231356e6578745f636f64655f706f696e743137683164383262613234633261303362306345006e6578745f636f64655f706f696e743c636f72653a3a736c6963653a3a497465723c75383e3e005f5a4e38315f244c5424636f72652e2e7374722e2e4368617273244c542424753237246124475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683037386533656565313861616134313745006e657874005068616e746f6d446174613c2675383e00497465723c75383e005f5a4e34395f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424244754243134706f73745f696e635f7374617274313768346666383662653665303730656362664500706f73745f696e635f73746172743c75383e005f5a4e34636f7265337374723131756e777261705f6f725f30313768623338383266356665303539633862384500756e777261705f6f725f30005f5a4e34636f7265337374723138757466385f6163635f636f6e745f62797465313768393330303431353330326661313336364500757466385f6163635f636f6e745f62797465004f7074696f6e3c636861723e005f5a4e33385f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c542454244754242447542436756e77726170313768313763386235353536386165323037614500756e777261703c636861723e005f5a4e34636f726533666d7439466f726d61747465723977726974655f666d7431376865313430386331396666303733643333450072616e6765005f5a4e34636f726533666d7439466f726d6174746572313564656275675f6c6f7765725f68657831376861303535666266663933363466646465450064656275675f6c6f7765725f686578005f5a4e34636f726533666d7439466f726d6174746572313564656275675f75707065725f68657831376835316530333961623230663563363136450064656275675f75707065725f686578005f5a4e34636f726533666d74336e756d35325f244c5424696d706c2475323024636f72652e2e666d742e2e446973706c61792475323024666f7224753230247533322447542433666d743137683130343663313633613833306264366445005f5a4e34636f726533666d74336e756d35355f244c5424696d706c2475323024636f72652e2e666d742e2e4c6f7765724865782475323024666f7224753230247573697a652447542433666d743137683861663966323335393563313132353245005f5a4e34375f244c54247573697a65247532302461732475323024636f72652e2e6f70732e2e61726974682e2e44697624475424336469763137686363666561353430323564663465396145006469760047656e657269635261646978005f5a4e34636f726533666d74336e756d313247656e65726963526164697837666d745f696e74313768353537643765303061313564393032314500666d745f696e743c636f72653a3a666d743a3a6e756d3a3a4c6f7765724865782c7573697a653e005f5a4e34355f244c54247573697a65247532302461732475323024636f72652e2e666d742e2e6e756d2e2e496e742447542435746f5f7538313768366435373262623639396233343231614500746f5f7538005f5a4e37335f244c5424636f72652e2e666d742e2e6e756d2e2e4c6f776572486578247532302461732475323024636f72652e2e666d742e2e6e756d2e2e47656e657269635261646978244754243564696769743137683237633531343036623863646264353545006469676974005f5a4e39395f244c5424636f72652e2e6f70732e2e72616e67652e2e52616e6765244c54247573697a6524475424247532302461732475323024636f72652e2e736c6963652e2e536c696365496e646578244c54242475356224542475356424244754242447542435696e646578313768643836636161333564363738663065374500696e6465783c75383e005f5a4e3130335f244c5424636f72652e2e6f70732e2e72616e67652e2e52616e676546726f6d244c54247573697a6524475424247532302461732475323024636f72652e2e736c6963652e2e536c696365496e646578244c54242475356224542475356424244754242447542435696e6465783137686131643864383236326463653337366645005f5a4e34636f726535736c69636537345f244c5424696d706c2475323024636f72652e2e6f70732e2e696e6465782e2e496e646578244c542449244754242475323024666f72247532302424753562245424753564242447542435696e646578313768653362636635613836346231346663664500696e6465783c75382c636f72653a3a6f70733a3a72616e67653a3a52616e676546726f6d3c7573697a653e3e005f5a4e34636f726535736c696365313466726f6d5f7261775f706172747331376864633133376539363033313963383435450066726f6d5f7261775f70617274733c75383e005f5a4e39395f244c5424636f72652e2e6f70732e2e72616e67652e2e52616e6765244c54247573697a6524475424247532302461732475323024636f72652e2e736c6963652e2e536c696365496e646578244c54242475356224542475356424244754242447542431336765745f756e636865636b65643137686332636562653065653938643966393445005f5a4e34636f726533666d74336e756d313247656e65726963526164697837666d745f696e74313768373730643135643137643330383761394500666d745f696e743c636f72653a3a666d743a3a6e756d3a3a55707065724865782c7573697a653e005f5a4e34636f726533666d74336e756d35355f244c5424696d706c2475323024636f72652e2e666d742e2e55707065724865782475323024666f7224753230247573697a652447542433666d743137683734646436623439623635393532393445005f5a4e37335f244c5424636f72652e2e666d742e2e6e756d2e2e5570706572486578247532302461732475323024636f72652e2e666d742e2e6e756d2e2e47656e657269635261646978244754243564696769743137683239323030636134616239333131303645005f5a4e34636f726533666d7439466f726d61747465723977726974655f7374723137686338616139333231636133326663353645005f5a4e34636f726533666d74386275696c64657273313664656275675f7374727563745f6e657731376866656566326430313563626533333365450064656275675f7374727563745f6e6577005f5a4e34636f726533666d7439466f726d6174746572313264656275675f73747275637431376836343330383530326232666333353964450064656275675f7374727563740063656c6c00756e69636f646500626f6f6c5f74726965005f5a4e34636f726537756e69636f646539626f6f6c5f747269653135747269655f72616e67655f6c656166313768366236356666626666623034343038614500747269655f72616e67655f6c656166007231007232007233002a636f6e73742075363400265b7536345d00723400723500723600426f6f6c54726965005f5a4e34636f72653370747233335f244c5424696d706c247532302424425024636f6e737424753230245424475424366f66667365743137686565396563383166333736666239643945006f66667365743c636f72653a3a666d743a3a417267756d656e7456313e005f5a4e34636f72653370747233335f244c5424696d706c247532302424425024636f6e737424753230245424475424336164643137683433313332616533656361383031373745006164643c636f72653a3a666d743a3a417267756d656e7456313e005f5a4e34636f726535736c69636532395f244c5424696d706c24753230242475356224542475356424244754243469746572313768613761613835356161356261626566644500697465723c636f72653a3a666d743a3a417267756d656e7456313e005f5a4e34636f72653370747233335f244c5424696d706c247532302424425024636f6e737424753230245424475424366f66667365743137686336343362336466646164383631326345005f5a4e34636f72653370747233335f244c5424696d706c247532302424425024636f6e737424753230245424475424336164643137683033363135663832626432656233373145005f5a4e34636f726535736c69636532395f244c5424696d706c247532302424753562245424753564242447542434697465723137686162326436626264613762623233353645005f5a4e34636f726535736c69636532395f244c5424696d706c24753230242475356224542475356424244754243469746572313768326335323132613166323665666138364500697465723c636f72653a3a666d743a3a72743a3a76313a3a417267756d656e743e005f5a4e39315f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683165356561636564316536373138323945006e6578743c636f72653a3a666d743a3a72743a3a76313a3a417267756d656e743e005f5a4e39315f244c5424636f72652e2e697465722e2e5a6970244c54244124432424753230244224475424247532302461732475323024636f72652e2e697465722e2e5a6970496d706c244c5424412443242475323024422447542424475424346e6578743137683366306536643835383538326536303445006e6578743c636f72653a3a736c6963653a3a497465723c636f72653a3a666d743a3a72743a3a76313a3a417267756d656e743e2c266d757420636f72653a3a736c6963653a3a497465723c267374723e3e005f5a4e38345f244c5424636f72652e2e697465722e2e5a6970244c54244124432424753230244224475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683235383030663038333363326566616345005f5a4e39315f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137686265356336653161356566396664393745005f5a4e37355f244c54242452462424753237246124753230246d7574247532302449247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683432326265333666396239623731656445006e6578743c636f72653a3a736c6963653a3a497465723c267374723e3e005f5a4e39315f244c5424636f72652e2e697465722e2e5a6970244c54244124432424753230244224475424247532302461732475323024636f72652e2e697465722e2e5a6970496d706c244c5424412443242475323024422447542424475424346e65787432385f24753762242475376224636c6f73757265247537642424753764243137683561323034333939353332646231376345007b7b636c6f737572657d7d3c636f72653a3a736c6963653a3a497465723c636f72653a3a666d743a3a72743a3a76313a3a417267756d656e743e2c266d757420636f72653a3a736c6963653a3a497465723c267374723e3e0026636f72653a3a666d743a3a72743a3a76313a3a417267756d656e74004f7074696f6e3c26636f72653a3a666d743a3a72743a3a76313a3a417267756d656e743e005f5a4e33385f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c542454244754242447542438616e645f7468656e313768393030373733306263393232346238614500616e645f7468656e3c26636f72653a3a666d743a3a72743a3a76313a3a417267756d656e742c2826636f72653a3a666d743a3a72743a3a76313a3a417267756d656e742c202626737472292c636c6f737572653e005f5a4e34636f726533666d7439466f726d61747465723372756e31376839636662663362386632613662333465450072756e005f5a4e34636f726533666d7439466f726d617474657238676574636f756e74313768376163663865373537336631343365384500676574636f756e74005f5a4e39315f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683038323431626465623237366439663645006e6578743c636f72653a3a666d743a3a417267756d656e7456313e005f5a4e34395f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424244754243134706f73745f696e635f7374617274313768363834663939613539313266613531654500706f73745f696e635f73746172743c636f72653a3a666d743a3a417267756d656e7456313e005f5a4e34636f726533666d743130417267756d656e7456313861735f7573697a6531376838373366656464636631623035333130450061735f7573697a65005f5a4e34636f726533666d7439466f726d617474657238676574636f756e7432385f24753762242475376224636c6f737572652475376424247537642431376830613338366332336530343630316663450026636f72653a3a666d743a3a417267756d656e745631004f7074696f6e3c26636f72653a3a666d743a3a417267756d656e7456313e005f5a4e33385f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c542454244754242447542438616e645f7468656e313768323361316337386562636634643961384500616e645f7468656e3c26636f72653a3a666d743a3a417267756d656e7456312c7573697a652c636c6f737572653e005f5a4e33385f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c542454244754242447542436756e77726170313768346263383037663865323838613864634500756e777261703c26636f72653a3a666d743a3a417267756d656e7456313e005f5a4e39315f244c5424636f72652e2e697465722e2e5a6970244c54244124432424753230244224475424247532302461732475323024636f72652e2e697465722e2e5a6970496d706c244c5424412443242475323024422447542424475424346e6578743137683262313932346564386432326662323545006e6578743c636f72653a3a736c6963653a3a497465723c636f72653a3a666d743a3a417267756d656e7456313e2c266d757420636f72653a3a736c6963653a3a497465723c267374723e3e005f5a4e38345f244c5424636f72652e2e697465722e2e5a6970244c54244124432424753230244224475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683465636338636263643565393732666345005f5a4e39315f244c5424636f72652e2e697465722e2e5a6970244c54244124432424753230244224475424247532302461732475323024636f72652e2e697465722e2e5a6970496d706c244c5424412443242475323024422447542424475424346e65787432385f24753762242475376224636c6f73757265247537642424753764243137683934636463373766366332643961333545007b7b636c6f737572657d7d3c636f72653a3a736c6963653a3a497465723c636f72653a3a666d743a3a417267756d656e7456313e2c266d757420636f72653a3a736c6963653a3a497465723c267374723e3e005f5a4e33385f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c542454244754242447542438616e645f7468656e313768356130613761383364626334643162644500616e645f7468656e3c26636f72653a3a666d743a3a417267756d656e7456312c2826636f72653a3a666d743a3a417267756d656e7456312c202626737472292c636c6f737572653e005068616e746f6d446174613c26267374723e005f5a4e34395f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424244754243134706f73745f696e635f73746172743137683561656264306435313337353964656145005f5a4e34636f726533666d7439466f726d6174746572397369676e5f706c75733137683365633836643639633534633538393045007369676e5f706c7573005f5a4e34636f726533666d7439466f726d617474657239616c7465726e617465313768396134383637366637633536343438384500616c7465726e617465005f5a4e38315f244c5424636f72652e2e7374722e2e4368617273244c542424753237246124475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f722447542435636f756e74313768366334633234363664636265653961654500636f756e74005f5a4e34636f7265337374723137757466385f69735f636f6e745f62797465313768623466643861383134316666373761364500757466385f69735f636f6e745f62797465005f5a4e34636f726533666d7439466f726d617474657231397369676e5f61776172655f7a65726f5f7061643137686238653232343464386436663565616545007369676e5f61776172655f7a65726f5f706164005f5a4e34636f726533666d7439466f726d61747465723132776974685f70616464696e67313768363963303533333838376537643263644500776974685f70616464696e673c636c6f737572653e005f5a4e34636f726533666d7439466f726d61747465723132776974685f70616464696e673137683236653765313133383631316532623045005f5a4e34636f726533636d7035696d706c7335375f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4f72642475323024666f7224753230247573697a6524475424326c743137683038333532396164313134323630656445006c74005f5a4e34636f726534697465723572616e676539335f244c5424696d706c2475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f722475323024666f722475323024636f72652e2e6f70732e2e72616e67652e2e52616e6765244c5424412447542424475424346e6578743137686665326362636364393166326634353545006e6578743c7573697a653e007061645f696e74656772616c005f5a4e34636f726533666d7439466f726d617474657231327061645f696e74656772616c32385f24753762242475376224636c6f73757265247537642424753764243137686532346532303531653964343634643445005f5a4e34636f726533666d7439466f726d617474657231327061645f696e74656772616c32385f24753762242475376224636c6f73757265247537642424753764243137683261613730333262336463316232656345005f5a4e33385f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c54245424475424244754243769735f736f6d6531376836626264336161343830626434386236450069735f736f6d653c7573697a653e005f5a4e33385f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c54245424475424244754243769735f6e6f6e6531376830643733656665313864346637636432450069735f6e6f6e653c7573697a653e005f5a4e38375f244c5424636f72652e2e7374722e2e43686172496e6469636573244c542424753237246124475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683236303734376239626230656132346445005f5a4e37355f244c54242452462424753237246124753230246d7574247532302449247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683665393365663235333163376562306545006e6578743c636f72653a3a7374723a3a43686172496e64696365733e005f5a4e34636f72653469746572386974657261746f72384974657261746f72336e74683137683939633338323063626661643261636345006e74683c636f72653a3a7374723a3a43686172496e64696365733e005f5a4e34636f72653373747232315f244c5424696d706c2475323024737472244754243132636861725f696e6469636573313768363466363362653237383234373039664500636861725f696e6469636573005f5a4e34636f726533737472367472616974733130335f244c5424696d706c2475323024636f72652e2e736c6963652e2e536c696365496e646578244c5424737472244754242475323024666f722475323024636f72652e2e6f70732e2e72616e67652e2e52616e6765546f244c54247573697a652447542424475424336765743137683162396332316137313234333938313545005f5a4e34636f72653373747232315f244c5424696d706c247532302473747224475424336765743137686331313930316331666338396530366145006765743c636f72653a3a6f70733a3a72616e67653a3a52616e6765546f3c7573697a653e3e004f7074696f6e3c267374723e005f5a4e33385f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c542454244754242447542439756e777261705f6f72313768343161383966386464616133653338314500756e777261705f6f723c267374723e005f5a4e34636f726533666d7439466f726d61747465723132776974685f70616464696e67313768633837346134303961346264613734634500706164005f5a4e34636f726533666d7439466f726d61747465723370616432385f24753762242475376224636c6f73757265247537642424753764243137683064323030666666326665306433356345005f5a4e37315f244c5424636f72652e2e666d742e2e466f726d6174746572244c542424753237246124475424247532302461732475323024636f72652e2e666d742e2e577269746524475424313077726974655f636861723137683662616663626232306665643362343345005f5a4e34636f72653463686172376d6574686f647332325f244c5424696d706c2475323024636861722447542431366573636170655f64656275675f6578743137686563353063326131613832643064393445006573636170655f64656275675f657874005f5a4e34636f72653463686172376d6574686f647332325f244c5424696d706c2475323024636861722447542431326573636170655f64656275673137686633616439376530626263343761363745006573636170655f6465627567007461626c657300646572697665645f70726f7065727479005f5a4e34636f726537756e69636f6465367461626c65733136646572697665645f70726f706572747931354772617068656d655f457874656e643137683532343766313366623062366638363745004772617068656d655f457874656e64005f5a4e34636f72653463686172376d6574686f647332325f244c5424696d706c24753230246368617224475424323069735f6772617068656d655f657874656e64656431376837383436306135323561623535306630450069735f6772617068656d655f657874656e646564005f5a4e34636f72653463686172376d6574686f647332325f244c5424696d706c2475323024636861722447542431346573636170655f756e69636f64653137683133646336306436343336326164663345006573636170655f756e69636f6465005f5a4e34636f7265336e756d32315f244c5424696d706c24753230247533322447542431336c656164696e675f7a65726f733137686562383338396563613535633130663245006c656164696e675f7a65726f73007072696e7461626c65005f5a4e34636f726537756e69636f6465397072696e7461626c65313269735f7072696e7461626c6531376866366265613563623231376462613365450069735f7072696e7461626c65005f5a4e34636f726537756e69636f6465397072696e7461626c6535636865636b313768636235356436616564303963316632664500636865636b005f5a4e34636f72653370747233335f244c5424696d706c247532302424425024636f6e737424753230245424475424366f66667365743137686233643635343232666661343363386645006f66667365743c2875382c207538293e002875382c20753829002a636f6e7374202875382c20753829005068616e746f6d446174613c262875382c207538293e00497465723c2875382c207538293e005f5a4e34395f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424244754243134706f73745f696e635f7374617274313768333832333632613039643036623230324500706f73745f696e635f73746172743c2875382c207538293e005f5a4e39315f244c5424636f72652e2e736c6963652e2e49746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683238653833396164316535316361313645006e6578743c2875382c207538293e005f5a4e34636f726535736c69636537345f244c5424696d706c2475323024636f72652e2e6f70732e2e696e6465782e2e496e646578244c542449244754242475323024666f72247532302424753562245424753564242447542435696e646578313768313531303263646564333066656532614500696e6465783c75382c636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e00636c6f6e65005f5a4e34636f726535636c6f6e6535696d706c7335315f244c5424696d706c2475323024636f72652e2e636c6f6e652e2e436c6f6e652475323024666f72247532302475382447542435636c6f6e65313768366366343530383966353364653365374500636c6f6e6564005f5a4e35335f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c542424524624247532372461247532302454244754242447542436636c6f6e656432385f24753762242475376224636c6f73757265247537642424753764243137686639636338376561356633626638653245007b7b636c6f737572657d7d3c75383e004f7074696f6e3c2675383e005f5a4e33385f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c5424542447542424475424336d61703137686562646365383634616665326335616345006d61703c2675382c75382c636c6f737572653e005f5a4e35335f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c542424524624247532372461247532302454244754242447542436636c6f6e6564313768656238323934656166643464393864614500636c6f6e65643c75383e005f5a4e37385f244c5424636f72652e2e697465722e2e436c6f6e6564244c54244924475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137686661623963656438346662346433343845006e6578743c636f72653a3a736c6963653a3a497465723c75383e2c75383e004f7074696f6e3c75383e005f5a4e33385f244c5424636f72652e2e6f7074696f6e2e2e4f7074696f6e244c542454244754242447542436756e77726170313768633664653034373832346334393264634500756e777261703c75383e005f5a4e37365f244c5424636f72652e2e636861722e2e45736361706544656661756c74247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137686163393763643735373030316461653145005f5a4e37345f244c5424636f72652e2e636861722e2e4573636170654465627567247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137683938613139626631626537633534646445005f5a4e37365f244c5424636f72652e2e636861722e2e457363617065556e69636f6465247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f7224475424346e6578743137686365313135666265646264333333663045005f5a4e34636f7265346368617237636f6e76657274313066726f6d5f646967697431376839616234373266333833633666643465450066726f6d5f6469676974005f5a4e34636f726533666d74386275696c64657273313564656275675f7475706c655f6e657731376831643031636261343738326363666637450064656275675f7475706c655f6e6577005f5a4e34636f726533666d7439466f726d6174746572313164656275675f7475706c6531376864663036383234333332303963626463450064656275675f7475706c65005f5a4e34325f244c5424737472247532302461732475323024636f72652e2e666d742e2e446973706c61792447542433666d7431376835643539396432636639303530383338450070616e69636b696e670070616e6963007061796c6f616400616e7900265b7573697a653b20345d0026416e79006d6573736167650026636f72653a3a666d743a3a417267756d656e7473004f7074696f6e3c26636f72653a3a666d743a3a417267756d656e74733e006c6f636174696f6e0066696c65006c696e6500636f6c004c6f636174696f6e0050616e6963496e666f005f5a4e34636f72653570616e69633950616e6963496e666f3230696e7465726e616c5f636f6e7374727563746f72313768333663333361326436623837643230634500696e7465726e616c5f636f6e7374727563746f72005f5a4e34636f726533666d7439417267756d656e7473366e65775f76313137686163376466303535633138323936376345006e65775f7631005f5a4e35616c6c6f63377261775f766563313763617061636974795f6f766572666c6f7731376834636334666238336564333166343538450063617061636974795f6f766572666c6f77005f5a4e35616c6c6f6333666d7436666f726d61743137686233376364346239306132383236353245005f5a4e34636f726536726573756c743133756e777261705f6661696c6564313768386530653236613763646135616538644500756e777261705f6661696c65643c636f72653a3a666d743a3a4572726f723e005f5a4e35616c6c6f6335736c69636536345f244c5424696d706c2475323024616c6c6f632e2e626f72726f772e2e546f4f776e65642475323024666f72247532302424753562245424753564242447542438746f5f6f776e6564313768303364623563383038366136313265654500746f5f6f776e65643c75383e005f5a4e39365f244c5424636f72652e2e666d742e2e57726974652e2e77726974655f666d742e2e41646170746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e666d742e2e577269746524475424313077726974655f6368617231376862383233383334363730613130353733450077726974655f636861723c616c6c6f633a3a737472696e673a3a537472696e673e005f5a4e39365f244c5424636f72652e2e666d742e2e57726974652e2e77726974655f666d742e2e41646170746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e666d742e2e5772697465244754243977726974655f666d743137683264363333666464613633326163303745005f5a4e39365f244c5424636f72652e2e666d742e2e57726974652e2e77726974655f666d742e2e41646170746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e666d742e2e5772697465244754243977726974655f73747231376839316538613262353436386638356366450077726974655f7374723c616c6c6f633a3a737472696e673a3a537472696e673e005f5a4e34636f726535736c6963653230736c6963655f696e6465785f6c656e5f6661696c313768656231373936303463633033316366304500736c6963655f696e6465785f6c656e5f6661696c005f5a4e34636f726535736c6963653232736c6963655f696e6465785f6f726465725f6661696c313768326566623861636230626565653235644500736c6963655f696e6465785f6f726465725f6661696c005f5a4e34636f7265337374723966726f6d5f7574663831376864313335353633353839656535646233450066726f6d5f75746638005f5a4e34636f7265337374723136736c6963655f6572726f725f6661696c313768353866626364393331356133353766324500736c6963655f6572726f725f6661696c005f5a4e37315f244c5424636f72652e2e6f70732e2e72616e67652e2e52616e6765244c542449647824475424247532302461732475323024636f72652e2e666d742e2e44656275672447542433666d74313768613763306465626437396366396362654500666d743c7573697a653e005f5a4e34636f726533666d74336e756d35325f244c5424696d706c2475323024636f72652e2e666d742e2e44656275672475323024666f7224753230247573697a652447542433666d743137686365643532303361333566616262373045005f5a4e36305f244c5424636f72652e2e63656c6c2e2e426f72726f774572726f72247532302461732475323024636f72652e2e666d742e2e44656275672447542433666d743137686163386536666532323039633838373945005f5a4e36335f244c5424636f72652e2e63656c6c2e2e426f72726f774d75744572726f72247532302461732475323024636f72652e2e666d742e2e44656275672447542433666d743137683634326365623264303330313431663445005f5a4e34636f726537756e69636f646539626f6f6c5f7472696538426f6f6c54726965366c6f6f6b75703137686161306133373039623734386163363845006c6f6f6b7570005f5a4e34636f726533666d743577726974653137683431623834643732663132323764666145007772697465005f5a4e34636f726533666d743130417267756d656e745631313073686f775f7573697a6531376836356636656537616361363663343461450073686f775f7573697a65005f5a4e34636f726533666d7439466f726d617474657231327061645f696e74656772616c3137686364663632656633343733643337313445005f5a4e34636f726533666d7439466f726d617474657231327061645f696e74656772616c32385f24753762242475376224636c6f73757265247537642424753764243137686334376533643035316438633735376545005f5a4e34636f726533666d7439466f726d6174746572337061643137683761663163653566643932653865623345005f5a4e34636f726533737472367472616974733130315f244c5424696d706c2475323024636f72652e2e736c6963652e2e536c696365496e646578244c5424737472244754242475323024666f722475323024636f72652e2e6f70732e2e72616e67652e2e52616e6765244c54247573697a65244754242447542435696e64657832385f24753762242475376224636c6f73757265247537642424753764243137683439323233336431376233643138316545005f5a4e34315f244c542463686172247532302461732475323024636f72652e2e666d742e2e44656275672447542433666d743137683963643666636530343630636639623445005f5a4e35335f244c5424636f72652e2e666d742e2e4572726f72247532302461732475323024636f72652e2e666d742e2e44656275672447542433666d743137683334643531663536303663643563393645005f5a4e35355f244c542424524624247532372461247532302454247532302461732475323024636f72652e2e666d742e2e446973706c61792447542433666d74313768626361643461666632306139353935374500666d743c7374723e005f5a4e34636f72653970616e69636b696e67313870616e69635f626f756e64735f636865636b31376839303163326633396266366534383237450070616e69635f626f756e64735f636865636b005f5a4e34636f72653970616e69636b696e673970616e69635f666d7431376861393833386661383139636334633361450070616e69635f666d74005f5a4e34636f726533707472313364726f705f696e5f706c61636531376830613565343633643561656463653233450064726f705f696e5f706c6163653c267533323e005f5a4e33365f244c542454247532302461732475323024636f72652e2e616e792e2e416e792447542431316765745f747970655f69643137686530666261383835323232653432613145006765745f747970655f69643c636f72653a3a70616e69633a3a7b7b696d706c7d7d3a3a696e7465726e616c5f636f6e7374727563746f723a3a4e6f5061796c6f61643e005f5a4e34636f72653970616e69636b696e673570616e69633137683238356537633565303138386565336645005f5a4e34636f7265366f7074696f6e31336578706563745f6661696c65643137683163356430373434306163353337383345006578706563745f6661696c656400636c616e67204c4c564d202872757374632076657273696f6e20312e33302e302d6e696768746c79202837303631623237373520323031382d30382d323829290072757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372632f6c69622e7273002f636865636b6f75742f73726300636f6d70696c65725f6275696c74696e73006d656d006d656d637079006d656d6d6f7665006d656d736574006d656d636d7000636c616e67204c4c564d202872757374632076657273696f6e20312e33302e302d6e696768746c79202837303631623237373520323031382d30382d323829290072757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372632f6c69622e7273002f636865636b6f75742f73726300636f7265006e756d007b7b696d706c7d7d005f5a4e34636f7265336e756d32315f244c5424696d706c24753230247533322447542431336c656164696e675f7a65726f733137686562383338396563613535633130663245006c656164696e675f7a65726f73005f5a4e34636f7265336e756d32315f244c5424696d706c24753230247533322447542431327772617070696e675f7375623137683864653130643737623831636433626145007772617070696e675f73756200636f6d70696c65725f6275696c74696e73005f5a4e3137636f6d70696c65725f6275696c74696e733561626f727431376839323933646139353161663065366666450061626f727400696e740075646976005f5f75646976736933005f5a4e35365f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e7424475424346869676831376864333062343665373635363564623964450068696768005f5a4e35365f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e7424475424336c6f773137683530353336623462333733656539663745006c6f77005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024753332244754243131636865636b65645f72656d313768306236326436336666376661613132394500636865636b65645f72656d005f5a4e35315f244c5424753332247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f72656d31376836343330663934623362353761623230450061626f7274696e675f72656d005f5a4e34636f7265336e756d36345f244c5424696d706c2475323024636f72652e2e636f6e766572742e2e46726f6d244c5424753332244754242475323024666f722475323024753634244754243466726f6d31376862356365353863623330326339613438450066726f6d005f5a4e34636f7265336e756d32315f244c5424696d706c247532302475333224475424313569735f706f7765725f6f665f74776f31376865626637323735613330376239623137450069735f706f7765725f6f665f74776f005f5a4e35365f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e7424475424313066726f6d5f706172747331376839343539303664633036666338643134450066726f6d5f7061727473005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024753332244754243131636865636b65645f646976313768353462643637666130386634383238304500636865636b65645f646976005f5a4e35315f244c5424753332247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f64697631376837383036376363376536623663656130450061626f7274696e675f646976005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024753332244754243134747261696c696e675f7a65726f73313768343161646462386261356230363237374500747261696c696e675f7a65726f73005f5a4e34636f7265336e756d32315f244c5424696d706c24753230247536342447542431327772617070696e675f7375623137686264643534323937356264623437386545005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7436756e77726170313768333038323532323437656138623832384500756e777261703c7533323e005f5a4e34636f7265336e756d32315f244c5424696d706c24753230247536342447542431336c656164696e675f7a65726f733137686362393633663962663961643364333745005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024753634244754243131636865636b65645f72656d3137686633353436333136313662613637383545005f5a4e35315f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f72656d3137686531396361643138323037653932373245005f5a4e34636f7265336e756d32315f244c5424696d706c247532302475363424475424313569735f706f7765725f6f665f74776f3137686261383535323430326463393635353445005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024753634244754243131636865636b65645f6469763137686637626530316633333537326465366645005f5a4e35315f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f6469763137683736383564343633666135623737306445005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024753634244754243134747261696c696e675f7a65726f733137683836663437303834306637643637623345005f5a4e34636f7265336e756d32325f244c5424696d706c2475323024753132382447542431327772617070696e675f7375623137683162303962363564663331333761386245005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7436756e77726170313768623633396431366135646236326534614500756e777261703c7536343e005f5f75646976746933005f5f756d6f64746933005f5f756d6f64736933005f5f756469766d6f64736934005f5f75646976646933005f5f756d6f64646933005f5f756469766d6f64646934005f5f756469766d6f64746934005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7434756469763133727573745f753132385f646976313768383830393934303533653464633032644500727573745f753132385f646976005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7434756469763133727573745f753132385f72656d313768653163373837636139363436636630364500727573745f753132385f72656d00636c616e67204c4c564d202872757374632076657273696f6e20312e33302e302d6e696768746c79202837303631623237373520323031382d30382d323829290072757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372632f6c69622e7273002f636865636b6f75742f73726300636f6d70696c65725f6275696c74696e7300696e74007b7b696d706c7d7d005f5a4e35365f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e7424475424336c6f773137683530353336623462333733656539663745006c6f77006d756c004d756c005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74336d756c334d756c336d756c3137686266373731636662663965626566306545006d756c3c7536343e00636f7265006f707300626974005f5a4e34335f244c5424753332247532302461732475323024636f72652e2e6f70732e2e6269742e2e5368722447542433736872313768326332386166383137356631666631384500736872006e756d005f5a4e34636f7265336e756d32315f244c5424696d706c24753230247533322447542431327772617070696e675f6d756c3137683630386666646537313336303934333045007772617070696e675f6d756c005f5a4e35315f244c5424753332247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f6d756c3137683034643162646664373234346534353645005f5a4e35365f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e7424475424346869676831376864333062343665373635363564623964450068696768006172697468005f5a4e35315f244c5424753332247532302461732475323024636f72652e2e6f70732e2e61726974682e2e41646441737369676e2447542431306164645f61737369676e3137683434663232643262396137633033316345006164645f61737369676e005f5a4e34365f244c5424753332247532302461732475323024636f72652e2e6f70732e2e6269742e2e426974416e642447542436626974616e64313768623962653332303661646261393735654500626974616e64005f5a4e34636f7265336e756d32315f244c5424696d706c24753230247533322447542431327772617070696e675f6164643137686237313064653239366266313663333745007772617070696e675f616464005f5a4e35315f244c5424753332247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f6164643137683035623664663832623662386238316545005f5a4e35365f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e7424475424313066726f6d5f706172747331376839343539303664633036666338643134450066726f6d5f7061727473005f5a4e34335f244c5424753332247532302461732475323024636f72652e2e6f70732e2e6269742e2e53686c244754243373686c31376834623634323130313636366231363364450073686c005f5a4e35325f244c5424753332247532302461732475323024636f72652e2e6f70732e2e6269742e2e426974416e6441737369676e244754243133626974616e645f61737369676e313768356138623933633034656366633732384500626974616e645f61737369676e004d756c6f005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74336d756c344d756c6f346d756c6f3137686439613030653538326132323533666645006d756c6f3c6933323e00636d7000696d706c73005f5a4e34636f726533636d7035696d706c7335345f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c45712475323024666f722475323024693332244754243265713137686536303837656166626463306466393445006571005f5a4e35345f244c5424693332247532302461732475323024636f72652e2e6f70732e2e6269742e2e536872244c54247533322447542424475424337368723137683837393334643739343937303433613645005f5a4e34365f244c5424693332247532302461732475323024636f72652e2e6f70732e2e6269742e2e426974586f722447542436626974786f72313768366536326439363537316638383066344500626974786f72005f5a4e34355f244c5424693332247532302461732475323024636f72652e2e6f70732e2e61726974682e2e5375622447542433737562313768306638386530326334353930306439394500737562005f5a4e34636f726533636d7035696d706c7335355f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4f72642475323024666f72247532302469333224475424326c743137686439373061353363633835313832373545006c74005f5a4e34636f726533636d7035696d706c7335355f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4f72642475323024666f722475323024693332244754243267743137683730333331656335623463663939626345006774005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024693332244754243131636865636b65645f646976313768316663303663636265383664363562644500636865636b65645f646976005f5a4e35315f244c5424693332247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f64697631376833326466333036623636636361343865450061626f7274696e675f646976005f5a4e3137636f6d70696c65725f6275696c74696e733561626f727431376839323933646139353161663065366666450061626f7274005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7436756e77726170313768323638323035313339323564346333624500756e777261703c6933323e005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74336d756c344d756c6f346d756c6f3137686530346131666662366434353065343445006d756c6f3c6936343e005f5a4e34636f726533636d7035696d706c7335345f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c45712475323024666f722475323024693634244754243265713137683066623762353335343434623663346545005f5a4e35345f244c5424693634247532302461732475323024636f72652e2e6f70732e2e6269742e2e536872244c54247533322447542424475424337368723137683230353935653537376632303836646145005f5a4e34365f244c5424693634247532302461732475323024636f72652e2e6f70732e2e6269742e2e426974586f722447542436626974786f723137683438613433396262623962356237353745005f5a4e34355f244c5424693634247532302461732475323024636f72652e2e6f70732e2e61726974682e2e53756224475424337375623137683034386636353033373766303130326645005f5a4e34636f726533636d7035696d706c7335355f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4f72642475323024666f72247532302469363424475424326c743137683764626438626637386635616439363045005f5a4e34636f726533636d7035696d706c7335355f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4f72642475323024666f722475323024693634244754243267743137683361623962333436333031346333383745005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024693634244754243131636865636b65645f6469763137686563376163376333616562303638633545005f5a4e35315f244c5424693634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f6469763137683162313063643262323663653433323945005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7436756e77726170313768366533373934623563653531396233394500756e777261703c6936343e005f5a4e34636f7265336e756d32325f244c5424696d706c2475323024693132382447542431327772617070696e675f6d756c3137683564306438363537343965626334366445005f5a4e35325f244c542469313238247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f6d756c3137686631656464363339333033306630626245005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74336d756c344d756c6f346d756c6f3137686161646664316232383036343265646545006d756c6f3c693132383e005f5a4e34636f726533636d7035696d706c7335355f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c45712475323024666f72247532302469313238244754243265713137686561383065363730396537396236303445005f5a4e35355f244c542469313238247532302461732475323024636f72652e2e6f70732e2e6269742e2e536872244c54247533322447542424475424337368723137683133646435373764626565366336366445005f5a4e34375f244c542469313238247532302461732475323024636f72652e2e6f70732e2e6269742e2e426974586f722447542436626974786f723137686532323261306237633735343234333645005f5a4e34365f244c542469313238247532302461732475323024636f72652e2e6f70732e2e61726974682e2e53756224475424337375623137683039393666316664343137613361323545005f5a4e34636f726533636d7035696d706c7335365f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4f72642475323024666f7224753230246931323824475424326c743137683533646263353835373531636232383145005f5a4e34636f726533636d7035696d706c7335365f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4f72642475323024666f72247532302469313238244754243267743137686339643137313839653537383435323645005f5a4e34636f7265336e756d32325f244c5424696d706c247532302469313238244754243131636865636b65645f6469763137683163633562376564626262373131643345005f5a4e35325f244c542469313238247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f6469763137686434323461323065623534396662303745005f5a4e34365f244c542469313238247532302461732475323024636f72652e2e6f70732e2e61726974682e2e4e656724475424336e65673137683438396361613830613561623534356245006e6567005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7436756e77726170313768393430376339626238666264383138334500756e777261703c693132383e005f5a4e35345f244c5424753634247532302461732475323024636f72652e2e6f70732e2e6269742e2e536872244c54247533322447542424475424337368723137683533653132633063323035633337316345005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74336d756c334d756c336d756c3137683562343264653761646462643639363145006d756c3c693132383e005f5f6d756c746933005f5a4e34636f7265336e756d32315f244c5424696d706c24753230247536342447542431327772617070696e675f6d756c3137683836373964636265666137336265316545005f5a4e35315f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f6d756c3137683037366566316536363736613161613545005f5a4e34636f7265336e756d32315f244c5424696d706c24753230246936342447542431327772617070696e675f6d756c3137683861613430323937663134663337643145005f5a4e35315f244c5424693634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f6d756c3137683862383737633463336165396635396645005f5a4e35315f244c5424693634247532302461732475323024636f72652e2e6f70732e2e61726974682e2e41646441737369676e2447542431306164645f61737369676e3137686333353032393364353466636262353345005f5a4e34365f244c5424753634247532302461732475323024636f72652e2e6f70732e2e6269742e2e426974416e642447542436626974616e643137686634303637393230373538383734313645005f5a4e35315f244c5424753634247532302461732475323024636f72652e2e6f70732e2e61726974682e2e41646441737369676e2447542431306164645f61737369676e3137686337393437626430343666646233303445005f5a4e34636f7265336e756d32315f244c5424696d706c24753230246936342447542431327772617070696e675f6164643137683139303930376135336231356530326545005f5a4e35315f244c5424693634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f6164643137683461356235316365316364346364623145005f5a4e35345f244c5424753634247532302461732475323024636f72652e2e6f70732e2e6269742e2e53686c244c542475333224475424244754243373686c3137683061323331623233376531656264616445005f5a4e35325f244c5424753634247532302461732475323024636f72652e2e6f70732e2e6269742e2e426974416e6441737369676e244754243133626974616e645f61737369676e3137683932663130653132633136613539323145005f5f6d756c6f746934005f5a4e34636f7265336e756d32325f244c5424696d706c247532302475313238244754243131636865636b65645f6469763137686530313632303763613861386463363245005f5a4e35325f244c542475313238247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f646976313768376664386666653733626139333037334500554d756c6f005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74336d756c35554d756c6f346d756c6f3137683636373262393835373139626562376645006d756c6f3c753132383e005f5a4e34636f7265336e756d32325f244c5424696d706c2475323024753132382447542431327772617070696e675f6d756c3137683361663438346261326263386433393345005f5a4e35325f244c542475313238247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f6d756c3137683233366435326330353630373238636645005f5a4e34636f726533636d7035696d706c7335365f244c5424696d706c2475323024636f72652e2e636d702e2e5061727469616c4f72642475323024666f72247532302475313238244754243267743137683536643036663865633937613562643545005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7436756e77726170313768636135313666633636616432366639624500756e777261703c753132383e005f5f6d756c646933005f5f6d756c6f736934005f5f6d756c6f646934005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74336d756c3133727573745f693132385f6d756c313768633763303735653135383237343638314500727573745f693132385f6d756c005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74336d756c3134727573745f693132385f6d756c6f313768636661643063333161326563626539614500727573745f693132385f6d756c6f005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74336d756c3134727573745f753132385f6d756c6f313768626135373434356637663334353262664500727573745f753132385f6d756c6f00636c616e67204c4c564d202872757374632076657273696f6e20312e33302e302d6e696768746c79202837303631623237373520323031382d30382d323829290072757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372632f6c69622e7273002f636865636b6f75742f73726300636f6d70696c65725f6275696c74696e7300696e74007368696674004173686c005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74357368696674344173686c346173686c3137683736623563616235633531316238353345006173686c3c7536343e007b7b696d706c7d7d005f5a4e35365f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e7424475424336c6f773137683530353336623462333733656539663745006c6f7700636f7265006f707300626974005f5a4e34335f244c5424753332247532302461732475323024636f72652e2e6f70732e2e6269742e2e5368722447542433736872313768326332386166383137356631666631384500736872005f5a4e35365f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e7424475424346869676831376864333062343665373635363564623964450068696768005f5a4e34335f244c5424753332247532302461732475323024636f72652e2e6f70732e2e6269742e2e53686c244754243373686c31376834623634323130313636366231363364450073686c005f5a4e34355f244c5424753332247532302461732475323024636f72652e2e6f70732e2e6269742e2e4269744f7224475424356269746f723137683433653166323163323834356139346445006269746f72005f5a4e35365f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e7424475424313066726f6d5f706172747331376839343539303664633036666338643134450066726f6d5f70617274730041736872005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7435736869667434417368723461736872313768333233386163396137663039663637624500617368723c6936343e005f5a4e35365f244c5424693634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e742447542434686967683137683932303537636166643636386232343645005f5a4e35345f244c5424693332247532302461732475323024636f72652e2e6f70732e2e6269742e2e536872244c54247533322447542424475424337368723137683837393334643739343937303433613645005f5a4e35365f244c5424693634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e7424475424313066726f6d5f70617274733137683662643938346637313939316132663445005f5a4e35365f244c5424693634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e4c61726765496e7424475424336c6f773137686464643434303632623635646235643045004c736872005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74357368696674344c736872346c7368723137686233343163646332616437343838383445006c7368723c7536343e005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74357368696674344173686c346173686c3137686162656635383232356438373836316245006173686c3c753132383e005f5f6173686c746933005f5a4e35345f244c5424753634247532302461732475323024636f72652e2e6f70732e2e6269742e2e536872244c54247533322447542424475424337368723137683533653132633063323035633337316345005f5a4e35345f244c5424753634247532302461732475323024636f72652e2e6f70732e2e6269742e2e53686c244c542475333224475424244754243373686c3137683061323331623233376531656264616445005f5a4e34355f244c5424753634247532302461732475323024636f72652e2e6f70732e2e6269742e2e4269744f7224475424356269746f723137686233633365636662373266633438616545005f5a4e3137636f6d70696c65725f6275696c74696e7333696e743573686966743133727573745f693132385f73686c313768373765373030333365383266343166384500727573745f693132385f73686c005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7435736869667434417368723461736872313768356463323934336262653064393861314500617368723c693132383e005f5f61736872746933005f5a4e35345f244c5424693634247532302461732475323024636f72652e2e6f70732e2e6269742e2e536872244c54247533322447542424475424337368723137683230353935653537376632303836646145005f5a4e3137636f6d70696c65725f6275696c74696e7333696e743573686966743133727573745f693132385f736872313768376464373734343537363663646534644500727573745f693132385f736872005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74357368696674344c736872346c7368723137683965333132616132343465363534636545006c7368723c753132383e005f5f6c736872746933005f5a4e3137636f6d70696c65725f6275696c74696e7333696e743573686966743133727573745f753132385f736872313768646662636465373964633934346530314500727573745f753132385f736872005f5f6173686c646933005f5f61736872646933005f5f6c736872646933005f5a4e3137636f6d70696c65725f6275696c74696e7333696e743573686966743134727573745f693132385f73686c6f313768386533663864303062653531633066394500727573745f693132385f73686c6f005f5a4e3137636f6d70696c65725f6275696c74696e7333696e743573686966743134727573745f693132385f7368726f313768626163363931373536393565303839634500727573745f693132385f7368726f005f5a4e3137636f6d70696c65725f6275696c74696e7333696e743573686966743134727573745f753132385f7368726f313768636237616263353536396233663562634500727573745f753132385f7368726f00636c616e67204c4c564d202872757374632076657273696f6e20312e33302e302d6e696768746c79202837303631623237373520323031382d30382d323829290072757374632f636f6d70696c65725f6275696c74696e735f7368696d2f2e2e2f2e2e2f6c6962636f6d70696c65725f6275696c74696e732f7372632f6c69622e7273002f636865636b6f75742f73726300636f7265006f707300626974007b7b696d706c7d7d005f5a4e35345f244c5424693332247532302461732475323024636f72652e2e6f70732e2e6269742e2e536872244c542475333224475424244754243373687231376838373933346437393439373034336136450073687200636f6d70696c65725f6275696c74696e7300696e74007364697600446976005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74347364697633446976336469763137683961636433623735376433643339356345006469763c6933323e005f5a4e34365f244c5424693332247532302461732475323024636f72652e2e6f70732e2e6269742e2e426974586f722447542436626974786f72313768366536326439363537316638383066344500626974786f72006e756d005f5a4e34636f7265336e756d32315f244c5424696d706c24753230246933322447542431327772617070696e675f7375623137683461653535396130646532623962376645007772617070696e675f737562005f5a4e35315f244c5424693332247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f7375623137683437386365373338306165396139353945005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024753332244754243131636865636b65645f646976313768353462643637666130386634383238304500636865636b65645f646976005f5a4e35315f244c5424753332247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f64697631376837383036376363376536623663656130450061626f7274696e675f646976006172697468005f5a4e34355f244c5424693332247532302461732475323024636f72652e2e6f70732e2e61726974682e2e5375622447542433737562313768306638386530326334353930306439394500737562005f5a4e3137636f6d70696c65725f6275696c74696e733561626f727431376839323933646139353161663065366666450061626f7274005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7436756e77726170313768333038323532323437656138623832384500756e777261703c7533323e005f5a4e35345f244c5424693634247532302461732475323024636f72652e2e6f70732e2e6269742e2e536872244c54247533322447542424475424337368723137683230353935653537376632303836646145005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74347364697633446976336469763137686630393564336138373964373135353945006469763c6936343e005f5a4e34365f244c5424693634247532302461732475323024636f72652e2e6f70732e2e6269742e2e426974586f722447542436626974786f723137683438613433396262623962356237353745005f5a4e34636f7265336e756d32315f244c5424696d706c24753230246936342447542431327772617070696e675f7375623137686530656337323666613534333335366545005f5a4e35315f244c5424693634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f7375623137683532346238383063323166626330633145005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024753634244754243131636865636b65645f6469763137686637626530316633333537326465366645005f5a4e35315f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f6469763137683736383564343633666135623737306445005f5a4e34355f244c5424693634247532302461732475323024636f72652e2e6f70732e2e61726974682e2e53756224475424337375623137683034386636353033373766303130326645005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7436756e77726170313768623633396431366135646236326534614500756e777261703c7536343e005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024753332244754243131636865636b65645f72656d313768306236326436336666376661613132394500636865636b65645f72656d005f5a4e35315f244c5424753332247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f72656d31376836343330663934623362353761623230450061626f7274696e675f72656d004d6f64005f5a4e3137636f6d70696c65725f6275696c74696e7333696e743473646976334d6f64346d6f645f3137686438383932353665623135343032313345006d6f645f3c6933323e005f5a4e34636f7265336e756d32315f244c5424696d706c2475323024753634244754243131636865636b65645f72656d3137686633353436333136313662613637383545005f5a4e35315f244c5424753634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f72656d3137686531396361643138323037653932373245005f5a4e3137636f6d70696c65725f6275696c74696e7333696e743473646976334d6f64346d6f645f3137686330663535356339613866366465663845006d6f645f3c6936343e005f5f646976736933005f5f6469766d6f64736934005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74347364697631315f5f6469766d6f6473693432385f24753762242475376224636c6f73757265247537642424753764243137683231663333666335666164643664616645007b7b636c6f737572657d7d004469766d6f64005f5a4e3137636f6d70696c65725f6275696c74696e7333696e743473646976364469766d6f64366469766d6f643137686237666436386163633462353261656445006469766d6f643c6933322c636c6f737572653e005f5a4e34636f7265336e756d32315f244c5424696d706c24753230246933322447542431327772617070696e675f6d756c3137683263386662643932653034313266366145007772617070696e675f6d756c005f5a4e35315f244c5424693332247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f6d756c3137686233336633376432653865343632316145005f5f646976646933005f5f6469766d6f64646934005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74347364697631315f5f6469766d6f6464693432385f24753762242475376224636c6f73757265247537642424753764243137686166306236376632393761313435653645005f5a4e3137636f6d70696c65725f6275696c74696e7333696e743473646976364469766d6f64366469766d6f643137686337376132626564666538346632366445006469766d6f643c6936342c636c6f737572653e005f5a4e34636f7265336e756d32315f244c5424696d706c24753230246936342447542431327772617070696e675f6d756c3137683861613430323937663134663337643145005f5a4e35315f244c5424693634247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f6d756c3137683862383737633463336165396635396645005f5a4e35355f244c542469313238247532302461732475323024636f72652e2e6f70732e2e6269742e2e536872244c54247533322447542424475424337368723137683133646435373764626565366336366445005f5a4e3137636f6d70696c65725f6275696c74696e7333696e74347364697633446976336469763137683561653030363531353635613133623545006469763c693132383e005f5f646976746933005f5a4e34375f244c542469313238247532302461732475323024636f72652e2e6f70732e2e6269742e2e426974586f722447542436626974786f723137686532323261306237633735343234333645005f5a4e34636f7265336e756d32325f244c5424696d706c2475323024693132382447542431327772617070696e675f7375623137686438623764653832626236373165383145005f5a4e35325f244c542469313238247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e742447542431327772617070696e675f7375623137683462616437316331623266313832386645005f5a4e34636f7265336e756d32325f244c5424696d706c247532302475313238244754243131636865636b65645f6469763137686530313632303763613861386463363245005f5a4e35325f244c542475313238247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f6469763137683766643866666537336261393330373345005f5a4e34365f244c542469313238247532302461732475323024636f72652e2e6f70732e2e61726974682e2e53756224475424337375623137683039393666316664343137613361323545005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7436756e77726170313768636135313666633636616432366639624500756e777261703c753132383e005f5a4e34636f7265336e756d32325f244c5424696d706c247532302475313238244754243131636865636b65645f72656d3137686535353137613162646334623835613345005f5a4e35325f244c542475313238247532302461732475323024636f6d70696c65725f6275696c74696e732e2e696e742e2e496e7424475424313261626f7274696e675f72656d3137686433663139646561356236653735376345005f5a4e3137636f6d70696c65725f6275696c74696e7333696e743473646976334d6f64346d6f645f3137686665393661333130663266663138326345006d6f645f3c693132383e005f5f6d6f64746933005f5f6d6f64736933005f5f6d6f64646933005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7434736469763133727573745f693132385f646976313768386338393238313533306338653839394500727573745f693132385f646976005f5a4e3137636f6d70696c65725f6275696c74696e7333696e7434736469763133727573745f693132385f72656d313768373833323333643465613339313036394500727573745f693132385f72656d00009b580f2e64656275675f7075626e616d657377000000020000000000d401000008010000726573756c74003c0100006578706563743c28292c636f72653a3a666d743a3a4572726f723e00500100007274004b010000666d74005501000076310073000000636f726500780000006f7074696f6e0066000000767461626c6500ae000000636861720000000000820100000200d4010000be010000ad000000636d70001501000063617061636974795f6f766572666c6f7700910100007b7b696d706c7d7d00a00000006d61726b657200b2000000696d706c7300cb0000004f726400100100007261775f76656300960100007265616c6c6f630026000000636f726500a2010000616c6c6f6300870000006e6f6e7a65726f00bc00000067650047000000636865636b65645f61646400300000006e756d00de0000006d61783c7573697a653e00540000007772617070696e675f7375620051010000616d6f7274697a65645f6e65775f73697a653c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e0063000000707472006b0100006361703c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e002b0000006f7074696f6e003a0000006f766572666c6f77696e675f616464005e010000726573657276655f696e7465726e616c3c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e00f2000000636f6c6c656374696f6e7300000000004e000000020092030000610000004900000072740044000000666d74004e0000007631003f000000636f726500550000006f7074696f6e001e000000767461626c65005a000000726573756c740000000000910400000200f3030000c8090000e60300006164643c267374723e001b08000073756d3c636f72653a3a697465723a3a4d61703c636f72653a3a736c6963653a3a497465723c267374723e2c20636c6f737572653e3e007f080000696d706c7300f0070000666f6c643c7573697a652c636f72653a3a736c6963653a3a497465723c267374723e2c636c6f737572652c7573697a652c666e287573697a652c207573697a6529202d3e207573697a653e007c010000776974685f6361706163697479002f0800004974657261746f720066080000466e4d757400480700005772697465008e070000697465723c267374723e00440800006f707300c207000065713c75382c75383e003a000000454d5054595f524f4f545f4e4f444500490800006172697468006e0400006f7074696f6e00a608000073747200ef040000756e777261705f6f725f656c73653c28292c616c6c6f633a3a636f6c6c656374696f6e733a3a436f6c6c656374696f6e416c6c6f634572722c636c6f737572653e00f30300006f66667365743c267374723e007a080000636d7000d7070000706f73745f696e635f73746172743c267374723e0003050000727400350000006e6f646500fd070000666f6c64002a0800006974657261746f7200200400006e6f6e7a65726f004d07000077726974655f666d743c616c6c6f633a3a737472696e673a3a537472696e673e00020800007b7b636c6f737572657d7d3c7573697a652c636f72653a3a736c6963653a3a497465723c267374723e2c636c6f737572652c7573697a652c666e287573697a652c207573697a6529202d3e207573697a653e005b070000736c6963650030000000627472656500e60700006974657200dc080000636865636b65645f6d756c00ab0800007472616974730065010000737472696e6700ef000000616c6c6f636174655f696e3c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e00e3040000726573756c74006b08000063616c6c5f6d75743c666e287573697a652c207573697a6529202d3e207573697a652c287573697a652c207573697a65293e004c0400006d61726b657200210100007b7b696d706c7d7d003408000073756d3c636f72653a3a697465723a3a4d61703c636f72653a3a736c6963653a3a497465723c267374723e2c20636c6f737572653e2c7573697a653e006108000066756e6374696f6e009608000065713c5b75385d2c5b75385d3e00c20000007261775f76656300ac030000636f726500390700007b7b636c6f737572657d7d008908000065713c7374722c7374723e00b5070000657175616c3c75383e00b1030000707472009b0700006e6578743c267374723e00cf0800006f766572666c6f77696e675f6d756c003401000076656300a8070000666f6c643c267374722c7573697a652c636c6f737572653e008b010000666d740008050000763100530800006164640090010000666f726d61740026010000616c6c6f63002b000000636f6c6c656374696f6e730034070000657374696d617465645f636170616369747900c50800006e756d0056010000776974685f63617061636974793c75383e00b508000065710000000000430000000200bb0d0000400000002d00000072740028000000666d7400320000007631001e000000636f726500230000006f7074696f6e0039000000726573756c740000000000720000000200fb0d0000590000003e000000736c69636500430000007b7b696d706c7d7d0048000000636f70795f66726f6d5f736c6963653c75383e002800000072740023000000666d74002d0000007631001e000000636f726500390000006f7074696f6e0034000000726573756c740000000000230000000200540e0000430000001e000000616c6c6f630023000000626f72726f770000000000910000000200970e0000fb0300000c030000736c69636500f80200006d61726b657200940100006e65775f76315f666f726d617474656400300000007274002b000000666d74003500000076310026000000636f726500830200006f7074696f6e0062020000756e777261705f6661696c65643c636f72653a3a666d743a3a4572726f723e005d020000726573756c74000000000022000000020092120000430000001e000000636f726500230000006f7074696f6e0000000000ef0200000200d5120000d40700004a0000007b7b696d706c7d7d00530600006d61726b657200dd06000077726974655f73747200b20500006c656e5f7574663800350700006c656e3c75383e00710700007261775f766563000e070000707573683c75383e0026000000636f726500d006000077726974655f6368617200400000005772697465004f00000077726974655f636861723c616c6c6f633a3a737472696e673a3a537472696e673e001e0600006164643c75383e004500000077726974655f666d74002c06000077726974653c75383e00a80500006d6574686f647300cf050000707472009e0500006f7074696f6e00aa070000726573657276653c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e00ec06000076656300b00600007075736800a305000063686172006207000064657265665f6d75743c75383e001b070000726573657276653c75383e00af03000077726974655f7374723c616c6c6f633a3a737472696e673a3a537472696e673e00770600006765745f756e636865636b65645f6d75743c75383e003500000072740030000000666d74003a000000763100840600006765745f756e636865636b65645f6d75743c75382c636f72653a3a6f70733a3a72616e67653a3a52616e676546726f6d3c7573697a653e3e00c5070000616c6c6f63003a0600006e6f6e7a65726f009003000077726974655f666d743c616c6c6f633a3a737472696e673a3a537472696e673e00110600006f66667365743c75383e0060060000736c6963650028070000657874656e645f66726f6d5f736c6963653c75383e00420700007365745f6c656e3c75383e00bf050000656e636f64655f75746638009e0700006361703c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e0099060000737472696e6700b70700007074723c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e0055070000737065635f657874656e643c75383e00bd060000707573685f737472002b000000726573756c7400000000007a0000000200a91a00000c0100003b0000006e756d00e90000007b7b696d706c7d7d00e40000007074720030000000727400cb000000666d74003500000076310026000000636f726500df0000006f7074696f6e0045000000746f5f75333200fb0000006f66667365743c75383e00da000000726573756c740000000000a00000000200b51b00002c010000230000006e756d00c4000000727400bf000000666d7400c90000007631001e000000636f7265002800000041534349495f4c4f574552434153455f4d4150004800000041534349495f4348415241435445525f434c41535300d50000006f7074696f6e003800000041534349495f5550504552434153455f4d4150001e010000767461626c6500d0000000726573756c7400000000004c0000000200e11c00005e0000002300000069746572004600000072740041000000666d74004b0000007631001e000000636f726500570000006f7074696f6e0052000000726573756c7400000000001502000002003f1d000016030000d90200007b7b696d706c7d7d00a20200006d61726b6572009700000064656332666c7400bb020000696d706c73006b010000756e69636f6465008d000000636f726500db0000006d61703c2675382c75382c636c6f737572653e00de0200006e6578743c636f72653a3a736c6963653a3a497465723c75383e2c75383e000f0200006e6578743c2875382c207538293e00c5020000636c6f6e6500b30100006164643c75383e00c0000000636c6f6e6564008f01000070747200990100006f66667365743c2875382c207538293e00b60000006f7074696f6e007501000069735f7072696e7461626c6500fc010000706f73745f696e635f73746172743c2875382c207538293e0081010000636865636b001c020000696e6465783c75383e00700100007072696e7461626c650080000000767461626c65000d010000756e777261703c75383e0029020000696e6465783c75382c636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e00500200006e6578743c75383e00c00100006f66667365743c75383e00360200006765745f756e636865636b65643c75383e00920000006e756d00cf010000736c6963650093020000706f73745f696e635f73746172743c75383e00c50000007b7b636c6f737572657d7d3c75383e00d40200006974657200e8000000636c6f6e65643c75383e004d010000726573756c740000000000ac0000000200552000006b0400003a030000736c6963650068030000736c6963655f696e6465785f6c656e5f6661696c00260300006d61726b657200580200006e65775f76315f666f726d617474656400f4000000727400ef000000666d7400f900000076310075000000636f7265007a0000006f7074696f6e0089030000736c6963655f696e6465785f6f726465725f6661696c0068000000767461626c650021030000726573756c7400000000005e0000000200c0240000af000000230000006e756d002d00000073747261746567790028000000666c7432646563001e000000636f726500320000006772697375004b0000006f7074696f6e00370000004341434845445f504f5731300000000000a602000002006f250000430a00001f0200006e65787400760800007b7b696d706c7d7d007d010000555446385f434841525f574944544800ce0000006765743c75382c7573697a653e00510800006d61726b6572007b0800006c656e5f7574663800c10000006765743c75383e0047000000636f726500370200006765745f756e636865636b656400420800006164643c75383e001202000063686172730087020000757466385f6163635f636f6e745f6279746500710800006d6574686f6473002f0700006e65775f76315f666f726d617474656400110800007074720028080000616c69676e5f6f66667365743c75383e0063010000737472001e0500006f7074696f6e00e8000000697465723c75383e00a001000066726f6d5f757466380077090000767461626c6500a4050000756e777261703c636861723e0044020000676574006c08000063686172009301000072756e5f757466385f76616c69646174696f6e00cb050000727400c6050000666d7400d0050000763100f30100007472756e636174655f746f5f636861725f626f756e6461727900f50000006e6578743c75383e007a020000756e777261705f6f725f3000350800006f66667365743c75383e008e000000736c69636500db0000006765745f756e636865636b65643c75383e0054010000706f73745f696e635f73746172743c75383e004c000000697465720094020000736c6963655f6572726f725f6661696c002d020000747261697473005e020000696e646578006d0200006e6578745f636f64655f706f696e743c636f72653a3a736c6963653a3a497465723c75383e3e000502000069735f636861725f626f756e64617279000208000066726f6d5f6572726f723c267374722c636f72653a3a7374723a3a557466384572726f723e00f8070000726573756c740000000000730200000200b22f0000bd070000d005000063656c6c006e0500006d61726b657200d50500007b7b696d706c7d7d00e701000077726974655f737472006d060000626f6f6c5f747269650068060000756e69636f64650028010000636f7265008705000072616e676500c001000077726974655f666d7400820500006f707300d40400007461736b00cd01000064656275675f6c6f7765725f686578005f040000666d745f696e743c636f72653a3a666d743a3a6e756d3a3a55707065724865782c7573697a653e0096020000646967697400b60500006172697468002d01000073747200850400006f7074696f6e0045050000696e6465783c75382c636f72653a3a6f70733a3a72616e67653a3a52616e676546726f6d3c7573697a653e3e00cd0600006c6f6f6b757000320100007061747465726e001b010000767461626c650038050000696e6465783c75383e00c0050000646976005601000072740020060000666d74005b0100007631007204000064656275675f7374727563745f6e657700f401000064656275675f737472756374006005000066726f6d5f7261775f70617274733c75383e0072020000746f5f7538005c0200006e756d00f8040000736c6963650053040000666d745f696e743c636f72653a3a666d743a3a6e756d3a3a4c6f7765724865782c7573697a653e00520500006765745f756e636865636b65643c75383e004e04000047656e65726963526164697800da01000064656275675f75707065725f68657800d9040000706f6c6c0072060000747269655f72616e67655f6c656166006d0400006275696c646572730091050000666d743c7573697a653e0080040000726573756c7400000000001900000002006f370000bc000000ae000000767461626c6500000000004c00000002002b380000940000005e0000006e756d0063000000666c74326465630059000000636f726500880000006f7074696f6e004c000000767461626c65008d000000726573756c740000000000760800000200bf380000621700003f08000061735f7573697a65006a120000666c743264656300e7150000696d706c73001d1600006573636170655f64656275675f65787400841400007b7b636c6f737572657d7d3c636f72653a3a736c6963653a3a497465723c636f72653a3a666d743a3a417267756d656e7456313e2c266d757420636f72653a3a736c6963653a3a497465723c267374723e3e0001130000697465723c636f72653a3a666d743a3a417267756d656e7456313e00061600006d6574686f64730096000000727400741200006c656164696e675f7a65726f7300c6130000706f73745f696e635f73746172743c636f72653a3a666d743a3a417267756d656e7456313e00f01400006e6578743c7573697a653e006f0e0000777269746500a111000069735f6e6f6e653c7573697a653e00ae15000074726169747300421600006573636170655f756e69636f646500421300006e6578743c636f72653a3a666d743a3a417267756d656e7456313e005f15000069735f636861725f626f756e64617279006f1600006e657874009f1400006e6578743c636f72653a3a736c6963653a3a497465723c636f72653a3a666d743a3a417267756d656e7456313e2c266d757420636f72653a3a736c6963653a3a497465723c267374723e3e00c41400006e6578743c636f72653a3a7374723a3a43686172496e64696365733e00501600007b7b696d706c7d7d00ff1400006d61726b6572000708000077726974655f7374720060120000726573756c740090160000756e69636f6465002b150000636f756e74008c0200007061645f696e74656772616c00d71400006e74683c636f72653a3a7374723a3a43686172496e64696365733e00e81200006164643c75383e00cb030000706164003e120000756e777261705f6f723c267374723e004f1300006e6578743c267374723e0058020000616c7465726e61746500f11500006c74007c160000636f6e76657274008116000066726f6d5f646967697400fc0d0000666d74009b000000763100281300006e6578743c636f72653a3a666d743a3a72743a3a76313a3a417267756d656e743e0094150000756e777261705f6f725f3000651200006e756d00901300006765745f756e636865636b65643c75383e003102000072756e00871500006e6578745f636f64655f706f696e743c636f72653a3a736c6963653a3a497465723c75383e3e009511000069735f736f6d653c7573697a653e00480000006275696c6465727300c5150000696e6465780052150000636861725f696e646963657300b41200006164643c267374723e008d1200006f66667365743c636f72653a3a666d743a3a417267756d656e7456313e00b71400006e6578743c636f72653a3a736c6963653a3a497465723c267374723e3e007a150000757466385f69735f636f6e745f6279746500d21400004974657261746f72000e130000697465723c267374723e001408000064656275675f7475706c6500761300006765743c75383e004c08000073686f775f7573697a65009a160000646572697665645f70726f706572747900461100006f7074696f6e00211500007374720026000000767461626c65005d110000616e645f7468656e3c26636f72653a3a666d743a3a72743a3a76313a3a417267756d656e742c2826636f72653a3a666d743a3a72743a3a76313a3a417267756d656e742c202626737472292c636c6f737572653e00c11200006f66667365743c267374723e00e2150000636d7000b8150000676574009a1200006164643c636f72653a3a666d743a3a417267756d656e7456313e00691300006e6578743c75383e00f1110000616e645f7468656e3c26636f72653a3a666d743a3a417267756d656e7456312c7573697a652c636c6f737572653e00ad1400006974657261746f7200fc130000706f73745f696e635f73746172743c267374723e00651400006e6578743c636f72653a3a736c6963653a3a497465723c636f72653a3a666d743a3a72743a3a76313a3a417267756d656e743e2c266d757420636f72653a3a736c6963653a3a497465723c267374723e3e00f7120000736c696365003f140000706f73745f696e635f73746172743c75383e004e140000697465720010160000656e636f64655f75746638003516000069735f6772617068656d655f657874656e646564000b120000616e645f7468656e3c26636f72653a3a666d743a3a417267756d656e7456312c2826636f72653a3a666d743a3a417267756d656e7456312c202626737472292c636c6f737572653e00831300006765743c75382c7573697a653e006909000077726974655f63686172003e000000636f726500be030000776974685f70616464696e673c636c6f737572653e00ca1500007b7b636c6f737572657d7d00e614000072616e6765009f1600004772617068656d655f457874656e6400650200007369676e5f61776172655f7a65726f5f706164004b0200007369676e5f706c75730083120000707472006c1500006765743c636f72653a3a6f70733a3a72616e67653a3a52616e6765546f3c7573697a653e3e00a1150000757466385f6163635f636f6e745f6279746500951600007461626c657300011600006368617200fe080000676574636f756e7400db1200006f66667365743c75383e00291600006573636170655f6465627567006b00000064656275675f7475706c655f6e6577004d0e0000666d743c7374723e00771400007b7b636c6f737572657d7d3c636f72653a3a736c6963653a3a497465723c636f72653a3a666d743a3a72743a3a76313a3a417267756d656e743e2c266d757420636f72653a3a736c6963653a3a497465723c267374723e3e001b130000697465723c636f72653a3a666d743a3a72743a3a76313a3a417267756d656e743e00fe110000756e777261703c26636f72653a3a666d743a3a417267756d656e7456313e0000000000590000000200215000000a010000440000006d61726b657200600000007274005b000000666d7400650000007631003f000000636f726500510000006f7074696f6e00fc000000767461626c650056000000726573756c740000000000c100000002002b5100005802000055000000504f573130544f31360028000000666c74326465630073000000504f573130544f3634004a020000767461626c65001e000000636f726500230000006e756d004600000054574f504f573130002d00000073747261746567790082000000504f573130544f3132380037000000504f5731300091000000504f573130544f32353600860100006f7074696f6e0032000000647261676f6e00a4000000636861720064000000504f573130544f333200000000004c000000020083530000450000002300000069746572002d00000072740028000000666d7400320000007631001e000000636f7265003e0000006f7074696f6e0039000000726573756c740000000000770000000200c85300001f010000440000006e756d007b000000636f6e76657274009f000000726573756c7400a9000000727400a4000000666d7400ae0000007631003f000000636f7265009a0000006f7074696f6e005d0000006e6f6e7a65726f0011010000767461626c650076000000636861720000000000710100000200e75400003d060000f70300006d61726b657200ca040000696e7465726e616c5f636f6e7374727563746f7200240500007b7b696d706c7d7d00f7000000727400f2000000666d7400fc000000763100ed000000636f7265004305000064726f705f696e5f706c6163653c267533323e007d04000070616e696300d00300006578706563745f6661696c65640001050000616e79000b040000736c69636500680200006e65775f7631003f04000070616e69635f626f756e64735f636865636b003a04000070616e69636b696e6700f203000069746572005b0200006e65775f76315f666f726d6174746564003e05000070747200360300006f7074696f6e005e04000070616e69635f666d7400290500006765745f747970655f69643c636f72653a3a70616e69633a3a7b7b696d706c7d7d3a3a696e7465726e616c5f636f6e7374727563746f723a3a4e6f5061796c6f61643e00e0000000767461626c650031030000726573756c7400000000002f0000000200245b00003700000023000000616c6c6f63002800000068616e646c655f616c6c6f635f6572726f7200000000005201000002005b5b000044020000830000006d61726b657200450100007b7b696d706c7d7d0082010000746f5f6f776e65643c75383e00960000007261775f7665630075010000746f5f7665633c75383e0026000000636f726500fa000000616c6c6f63006a0000006e6f6e7a65726f002a010000776974685f63617061636974793c75383e0059010000736c6963650037010000657874656e645f66726f6d5f736c6963653c75383e00460000007074720037000000756e777261705f6f725f656c73653c28292c616c6c6f633a3a636f6c6c656374696f6e733a3a436f6c6c656374696f6e416c6c6f634572722c636c6f737572653e005e0100006861636b004a010000737065635f657874656e643c75383e00c3000000616c6c6f636174655f696e3c75382c616c6c6f633a3a616c6c6f633a3a476c6f62616c3e0008010000766563002b000000726573756c7400000000005900000002009f5d00007f000000690000006d656d636d700026000000636f6d70696c65725f6275696c74696e7300430000006d656d6d6f766500300000006d656d63707900560000006d656d736574002b0000006d656d0000000000dd01000002001e5e00007a0700000a0700006869676800050700007b7b696d706c7d7d00620100005f5f7564697673693300aa0600005f5f756469767469330026000000636f726500ff000000696e7400de0000007772617070696e675f737562005f070000756e777261703c7533323e00570200005f5f756d6f64646933005c00000066726f6d006b070000756e777261703c7536343e00840200005f5f756469766d6f6464693400f300000061626f7274002e07000066726f6d5f706172747300b6060000727573745f753132385f64697600e3060000727573745f753132385f72656d006e0100005f5f756d6f6473693300d70600005f5f756d6f6474693300ee000000636f6d70696c65725f6275696c74696e73009d0000006c656164696e675f7a65726f7300d90100005f5f756469766d6f64736934000d0500005f5f756469766d6f6474693400c4000000636865636b65645f64697600aa000000636865636b65645f72656d00d1000000747261696c696e675f7a65726f73002b0000006e756d00160700006c6f7700b700000069735f706f7765725f6f665f74776f00440200005f5f75646976646933000401000075646976004607000061626f7274696e675f72656d005207000061626f7274696e675f6469760000000000850200000200986500005e0c0000cd0b0000696d706c7300ac0a000073686c00390900006d756c6f3c753132383e00670300005f5f6d756c6f73693400f40000006d756c3c693132383e00930a000073687200e30000004d756c00b90000007772617070696e675f61646400030a00006f70730034090000554d756c6f0024080000727573745f693132385f6d756c6f00c80a000061726974680046090000727573745f753132385f6d756c6f00d8090000756e777261703c693132383e006500000066726f6d5f706172747300c80b0000636d700026000000636f6d70696c65725f6275696c74696e7300420300006d756c6f3c6933323e00e80000006d756c3c7536343e00e4090000756e777261703c753132383e00f70a0000737562004e0300006d756c6f3c6936343e00010100005f5f6d756c64693300de0000006d756c00350000006c6f7700a00a0000626974616e6400860a0000626974786f72004c0c0000677400400400005f5f6d756c6f646934003d0300004d756c6f00060600005f5f6d756c746933004d0000006869676800d20b00007b7b696d706c7d7d00c0090000756e777261703c6933323e00fe090000636f726500cc090000756e777261703c6936343e002b000000696e7400180800005f5f6d756c6f746934001d0b00006164645f61737369676e00d10000007772617070696e675f6d756c00f109000061626f727400030b00006e65670012060000727573745f693132385f6d756c00080a000062697400320c00006c7400ac0b0000636865636b65645f646976002d0b00006e756d00b90a0000626974616e645f61737369676e00250c0000657100c500000061626f7274696e675f646976005a0300006d756c6f3c693132383e0000000000cb0100000200f6710000c80600002206000068696768003a0000006173686c3c7536343e00580600007b7b696d706c7d7d00530000005f5f6173686c646933009d06000073686c0049060000636f7265005f050000727573745f753132385f736872002b000000696e74001f0100005f5f6173687264693300b60600007368720043040000727573745f693132385f7368726f0022030000727573745f693132385f73686c6f004e0600006f707300d90100006c7368723c7536343e009c0200005f5f6173686c74693300f20100005f5f6c736872646933006c050000727573745f753132385f7368726f00d40100004c73687200a60300005f5f61736872746933002e06000066726f6d5f706172747300300000007368696674005306000062697400aa0600006269746f7200e50100006c7368723c753132383e0026000000636f6d70696c65725f6275696c74696e7300de0400005f5f6c73687274693300350000004173686c0012010000617368723c693132383e000101000041736872003a0600006c6f7700460000006173686c3c753132383e0015030000727573745f693132385f73686c0006010000617368723c6936343e0036040000727573745f693132385f7368720000000000670200000200be780000ec090000600300004d6f6400460600005f5f646976646933008f0000007b7b696d706c7d7d006601000044697600ec0400004469766d6f6400640600005f5f6469766d6f6464693400650300006d6f645f3c6933323e0026000000636f7265005c010000696e7400710300006d6f645f3c6936343e006e00000073687200570600007b7b636c6f737572657d7d00ce0400005f5f64697673693300940900007772617070696e675f737562002b0000006f707300ac070000727573745f693132385f64697600b9090000756e777261703c7533323e00f10400006469766d6f643c6933322c636c6f737572653e00c5090000756e777261703c7536343e000a0500005f5f6469766d6f64736934008a000000617269746800de09000061626f727400fd0400006469766d6f643c6936342c636c6f737572653e00880900007772617070696e675f6d756c00830100006469763c693132383e007d0300006d6f645f3c693132383e003000000062697400a00700005f5f646976746933002c0400005f5f6d6f646469330093080000727573745f693132385f72656d0057010000636f6d70696c65725f6275696c74696e7300d1090000756e777261703c753132383e003a010000636865636b65645f6469760047010000636865636b65645f72656d006b0100006469763c6933323e00ac00000073756200870800005f5f6d6f6474693300bb0000006e756d00770100006469763c6936343e008a0300005f5f6d6f64736933006101000073646976007b000000626974786f7200a009000061626f7274696e675f64697600ac09000061626f7274696e675f72656d000000000000dfee01046e616d6501d6ee01db02000a6578745f6d616c6c6f6301086578745f66726565020c6578745f74776f785f313238030f6578745f7365745f73746f7261676504146578745f6765745f73746f726167655f696e746f05236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74060e6578745f7072696e745f75746638070d6578745f7072696e745f6e756d08166578745f73616e64626f785f6d656d6f72795f67657409166578745f73616e64626f785f6d656d6f72795f7365740a116578745f636c6561725f73746f726167650b126578745f656432353531395f7665726966790c166578745f73616e64626f785f6d656d6f72795f6e65770d1b6578745f73616e64626f785f6d656d6f72795f74656172646f776e0e176578745f73616e64626f785f696e7374616e74696174650f126578745f73616e64626f785f696e766f6b65101d6578745f73616e64626f785f696e7374616e63655f74656172646f776e110e6578745f626c616b65325f323536120d6578745f7072696e745f68657813106578745f73746f726167655f726f6f7414126578745f6578697374735f73746f7261676515106578745f636c6561725f70726566697816186578745f73746f726167655f6368616e6765735f726f6f741791015f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424247532302461732475323024616c6c6f632e2e7665632e2e53706563457874656e64244c5424542443242475323024616c6c6f632e2e7665632e2e496e746f49746572244c5424542447542424475424244754243a3a737065635f657874656e643a3a68663263613337353363643065616262301834616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68346363346662383365643331663435381908727573745f6f6f6d1a3d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68616232656432316533376234633363391b397061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a68323639346138373630386530363737361c3d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68656461613337623133303232333630611d347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a68326265306639363933386337363031321e347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a68353737623839313064393432316663301f397061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573685f627974653a3a6835316238353735626138303636326461205a5f244c54242475356224753824753564242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e456e636f6465244754243a3a656e636f64655f746f3a3a683262303638313361623061383462656421347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a686538626362356664633331323566323322347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a683632333231653962613832303133363223347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a686465333766643430303465613237303824347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a686331386236653134646630666664363825347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a686333623038646531643734633730626426347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a686338343637386231653834316364376127347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a686662323838356439663831303632373028595f244c542424753562245424753564242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e456e636f6465244754243a3a656e636f64655f746f3a3a686433303563346166666637656363353029475f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424244754243a3a657874656e645f66726f6d5f736c6963653a3a68613265363134316637613461376530302a3c5f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424244754243a3a726573697a653a3a68653061313933373434666662663739622b2b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a68313838356135363430366138386162632c2b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a68653966313039373531646336336339622d595f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424247532302461732475323024636f72652e2e636c6f6e652e2e436c6f6e65244754243a3a636c6f6e653a3a68316137373134313961376566386637312e6f5f244c5424616c6c6f632e2e7261775f7665632e2e526177566563244c54245424432424753230244124475424244754243a3a616c6c6f636174655f696e3a3a5f24753762242475376224636c6f73757265247537642424753764243a3a68303264653233626164376664616134362f605f244c5424616c6c6f632e2e7665632e2e496e746f49746572244c54245424475424247532302461732475323024636f72652e2e6f70732e2e64726f702e2e44726f70244754243a3a64726f703a3a683737386133393964623639353536373630605f244c5424616c6c6f632e2e7665632e2e496e746f49746572244c54245424475424247532302461732475323024636f72652e2e6f70732e2e64726f702e2e44726f70244754243a3a64726f703a3a686138623665376165613039323439393831605f244c5424616c6c6f632e2e7665632e2e496e746f49746572244c54245424475424247532302461732475323024636f72652e2e6f70732e2e64726f702e2e44726f70244754243a3a64726f703a3a686431356331393439666461613038366132635f244c5424616c6c6f632e2e7665632e2e566563244c542454244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a683135383163643238623737356561303833725f244c54247061726974795f636f6465632e2e636f6465632e2e436f6d70616374244c5424753332244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a686238363362343363383035343635376134635f244c5424616c6c6f632e2e7665632e2e566563244c542454244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a683233623332646537303038363165326335725f244c54247061726974795f636f6465632e2e636f6465632e2e436f6d70616374244c5424753332244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a686265353437363166613561336134663536635f244c5424616c6c6f632e2e7665632e2e566563244c542454244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a686135663931363032303139336439666337e3015f244c54246e6f64655f72756e74696d652e2e4c6f67247532302461732475323024636f72652e2e636f6e766572742e2e46726f6d244c542473725f7072696d6974697665732e2e67656e657269632e2e6469676573742e2e4469676573744974656d244c54247375627374726174655f7072696d6974697665732e2e686173682e2e4832353624432424753230247375627374726174655f7072696d6974697665732e2e617574686f726974795f69642e2e417574686f7269747949642447542424475424244754243a3a66726f6d3a3a683763663265336135336634656639363438635f244c5424616c6c6f632e2e7665632e2e566563244c542454244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a683464366261343362353132306631373639635f244c5424616c6c6f632e2e7665632e2e566563244c542454244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a68383462643761386534336362363662383a635f244c5424616c6c6f632e2e7665632e2e566563244c542454244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a68386439666635323534336537303437623b635f244c5424616c6c6f632e2e7665632e2e566563244c542454244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a68613435356436623836643163303639303c635f244c5424616c6c6f632e2e7665632e2e566563244c542454244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a68633138663639363264343437373432353d755f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424247532302461732475323024616c6c6f632e2e7665632e2e53706563457874656e64244c54245424432424753230244924475424244754243a3a737065635f657874656e643a3a68343765653062656633653263393763643e735f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424247532302461732475323024616c6c6f632e2e7665632e2e53706563457874656e64244c54245424432424753230244924475424244754243a3a66726f6d5f697465723a3a68326463353961613232353533323536373f735f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424247532302461732475323024616c6c6f632e2e7665632e2e53706563457874656e64244c54245424432424753230244924475424244754243a3a66726f6d5f697465723a3a6838633635623036663437396532646530402e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a683163356430373434306163353337383341735f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424247532302461732475323024616c6c6f632e2e7665632e2e53706563457874656e64244c54245424432424753230244924475424244754243a3a66726f6d5f697465723a3a6866643761653163656137393336323032426f5f244c5424636f72652e2e697465722e2e436861696e244c54244124432424753230244224475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f72244754243a3a6e6578743a3a683235316537316135353336383030636343735f244c5424636f72652e2e697465722e2e54616b655768696c65244c54244924432424753230245024475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f72244754243a3a6e6578743a3a6838393633646339383565363632353264447b5f244c542473726d6c5f737570706f72742e2e73746f726167652e2e52756e74696d6553746f7261676524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e67656e657261746f722e2e53746f72616765244754243a3a6765743a3a6835373634316436346162623964393964453c707761736d5f7574696c733a3a737461636b5f6865696768743a3a696e6a6563745f6c696d697465723a3a683731633464636136366238353439653146467061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a436f646553656374696f6e3a3a626f646965733a3a6837616463323032316237393263353261476b616c6c6f633a3a736c6963653a3a5f244c5424696d706c2475323024616c6c6f632e2e626f72726f772e2e546f4f776e65642475323024666f7224753230242475356224542475356424244754243a3a746f5f6f776e65643a3a6830336462356338303836613631326565484b707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a706f705f76616c7565733a3a6864653634326662386239653532366463493f707761736d5f7574696c733a3a737461636b5f6865696768743a3a7265736f6c76655f66756e635f747970653a3a68653865393531643766353830343833334a36636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a68393031633266333962663665343832374b4f5f244c542424524624247532372461247532302454247532302461732475323024636f72652e2e666d742e2e446973706c6179244754243a3a666d743a3a68363634633733313233633734366161354c25616c6c6f633a3a666d743a3a666f726d61743a3a68623337636434623930613238323635324d29636f72653a3a70616e69636b696e673a3a70616e69633a3a68323835653763356530313838656533664e675f244c5424636f72652e2e697465722e2e436c6f6e6564244c54244924475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f72244754243a3a6e6578743a3a68626465366666326133616135366464664f755f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424247532302461732475323024616c6c6f632e2e7665632e2e53706563457874656e64244c54245424432424753230244924475424244754243a3a737065635f657874656e643a3a6831653932663237373732313265373365503c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a66726f6d5f6d6f64756c653a3a6834363836663731643638396239376334515f5f244c54247061726974795f7761736d2e2e6275696c6465722e2e6d6f64756c652e2e4d6f64756c654275696c646572244c54244624475424244754243a3a707573685f66756e6374696f6e3a3a686238623537663034393532313331303752c2017061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a5f244c5424696d706c2475323024636f72652e2e636f6e766572742e2e46726f6d244c54247061726974795f7761736d2e2e6275696c6465722e2e6d6f64756c652e2e4d6f64756c6553636166666f6c64244754242475323024666f7224753230247061726974795f7761736d2e2e656c656d656e74732e2e6d6f64756c652e2e4d6f64756c65244754243a3a66726f6d3a3a6862376363613836306364363638363734537d5f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e42547265654d6170244c54244b24432424753230245624475424247532302461732475323024636f72652e2e6f70732e2e64726f702e2e44726f70244754243a3a64726f703a3a6865643234616338393039363732323838545c636f72653a3a666d743a3a6e756d3a3a5f244c5424696d706c2475323024636f72652e2e666d742e2e446973706c61792475323024666f722475323024753332244754243a3a666d743a3a6831303436633136336138333062643664555b5f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424247532302461732475323024636f72652e2e6f70732e2e64726f702e2e44726f70244754243a3a64726f703a3a68613131653564316438653366313062655637707761736d5f7574696c733a3a6761733a3a696e6a6563745f6761735f636f756e7465723a3a6865323432343261313434666338663733577e5f244c54247061726974795f7761736d2e2e6275696c6465722e2e6d6f64756c652e2e4d6f64756c654275696c646572244c54244624475424244754243a3a7265736f6c76655f747970655f7265663a3a683937653363386330653762393137356520282e6c6c766d2e3539343036333735333531353130353930343729583a707761736d5f7574696c733a3a72756c65733a3a496e737472756374696f6e547970653a3a6f703a3a68373263306432383031623864303931395991015f244c5424616c6c6f632e2e7665632e2e566563244c54245424475424247532302461732475323024616c6c6f632e2e7665632e2e53706563457874656e64244c5424542443242475323024616c6c6f632e2e7665632e2e496e746f49746572244c5424542447542424475424244754243a3a737065635f657874656e643a3a68336463613833303862336564396138625a5e5f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e42547265654d6170244c54244b24432424753230245624475424244754243a3a696e736572743a3a68343235326437336532383732623636395b35636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a68636466363265663334373364333731345c535f244c54247061726974795f7761736d2e2e696f2e2e4572726f72247532302461732475323024636f72652e2e666d742e2e4465627567244754243a3a666d743a3a68356462346363363635303338626230345d497061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a4d656d6f727953656374696f6e3a3a656e74726965733a3a68363164333565386635346465316632335e2f73726d6c5f73797374656d3a3a4576656e743a3a6d657461646174613a3a68666230343135383238333464343134665f7b5f244c542473725f7072696d6974697665732e2e7472616974732e2e426c616b6554776f32353624753230246173247532302473725f7072696d6974697665732e2e7472616974732e2e48617368244754243a3a656e756d6572617465645f747269655f726f6f743a3a68643732346563643931326334613632666011727573745f626567696e5f756e77696e646123636f72653a3a666d743a3a77726974653a3a6834316238346437326631323237646661622e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a6838653065323661376364613561653864634d5f244c5424636f72652e2e666d742e2e4572726f72247532302461732475323024636f72652e2e666d742e2e4465627567244754243a3a666d743a3a6833346435316635363036636435633936644f5f244c542424524624247532372461247532302454247532302461732475323024636f72652e2e666d742e2e446973706c6179244754243a3a666d743a3a6862636164346166663230613935393537652d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a6861393833386661383139636334633361667f5f244c5424636f72652e2e666d742e2e57726974652e2e77726974655f666d742e2e41646170746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e666d742e2e5772697465244754243a3a77726974655f636861723a3a6862383233383334363730613130353733677e5f244c5424636f72652e2e666d742e2e57726974652e2e77726974655f666d742e2e41646170746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e666d742e2e5772697465244754243a3a77726974655f666d743a3a6832643633336664646136333261633037687e5f244c5424636f72652e2e666d742e2e57726974652e2e77726974655f666d742e2e41646170746572244c542424753237246124432424753230245424475424247532302461732475323024636f72652e2e666d742e2e5772697465244754243a3a77726974655f7374723a3a6839316538613262353436386638356366695e636f72653a3a666d743a3a6e756d3a3a5f244c5424696d706c2475323024636f72652e2e666d742e2e446973706c61792475323024666f7224753230247573697a65244754243a3a666d743a3a68323430323663666431643937623066636a34636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68656231373936303463633033316366306b36636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a68326566623861636230626565653235646c27636f72653a3a7374723a3a66726f6d5f757466383a3a68643133353536333538396565356462336d2e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a68353866626364393331356133353766326e415f244c542463686172247532302461732475323024636f72652e2e666d742e2e4465627567244754243a3a666d743a3a68396364366663653034363063663962346f5f5f244c5424636f72652e2e6f70732e2e72616e67652e2e52616e6765244c542449647824475424247532302461732475323024636f72652e2e666d742e2e4465627567244754243a3a666d743a3a68613763306465626437396366396362657063636f72653a3a666d743a3a6e756d3a3a5f244c5424696d706c2475323024636f72652e2e666d742e2e44656275672475323024666f7224753230247573697a65244754243a3a666d743a3a686365643532303361333566616262373020282e3731362971545f244c5424636f72652e2e63656c6c2e2e426f72726f774572726f72247532302461732475323024636f72652e2e666d742e2e4465627567244754243a3a666d743a3a686163386536666532323039633838373972575f244c5424636f72652e2e63656c6c2e2e426f72726f774d75744572726f72247532302461732475323024636f72652e2e666d742e2e4465627567244754243a3a666d743a3a6836343263656232643033303134316634733d636f72653a3a756e69636f64653a3a626f6f6c5f747269653a3a426f6f6c547269653a3a6c6f6f6b75703a3a6861613061333730396237343861633638744f636f72653a3a666d743a3a417267756d656e7456313a3a73686f775f7573697a653a3a683635663665653761636136366334346120282e6c6c766d2e363631333237393937363437333239373037297553636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a5f24753762242475376224636c6f73757265247537642424753764243a3a6863343765336430353164386337353765762c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a683761663163653566643932653865623377b001636f72653a3a7374723a3a7472616974733a3a5f244c5424696d706c2475323024636f72652e2e736c6963652e2e536c696365496e646578244c5424737472244754242475323024666f722475323024636f72652e2e6f70732e2e72616e67652e2e52616e6765244c54247573697a6524475424244754243a3a696e6465783a3a5f24753762242475376224636c6f73757265247537642424753764243a3a68343932323333643137623364313831657832636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a683061356534363364356165646365323320282e3933362979445f244c542454247532302461732475323024636f72652e2e616e792e2e416e79244754243a3a6765745f747970655f69643a3a68653066626138383532323265343261317ab9025f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e48616e646c65244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e4e6f6465526566244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4d7574244c54242475323724612447542424432424753230244b2443242475323024562443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4c656166244754242443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4564676524475424244754243a3a696e736572743a3a68616138326636303338363265366363307bb9025f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e48616e646c65244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e4e6f6465526566244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4d7574244c54242475323724612447542424432424753230244b2443242475323024562443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4c656166244754242443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4564676524475424244754243a3a696e736572743a3a68643338366339383835646133653761377cc1025f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e48616e646c65244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e4e6f6465526566244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4d7574244c54242475323724612447542424432424753230244b2443242475323024562443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e496e7465726e616c244754242443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4564676524475424244754243a3a696e736572745f6669743a3a68323563363162643939326662643962307dbd025f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e48616e646c65244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e4e6f6465526566244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4d7574244c54242475323724612447542424432424753230244b2443242475323024562443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e496e7465726e616c244754242443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4564676524475424244754243a3a696e736572743a3a68393666343166646634383765623564397ec1025f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e48616e646c65244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e4e6f6465526566244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4d7574244c54242475323724612447542424432424753230244b2443242475323024562443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e496e7465726e616c244754242443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4564676524475424244754243a3a696e736572745f6669743a3a68633366343362663764353331366236397fbd025f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e48616e646c65244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e4e6f6465526566244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4d7574244c54242475323724612447542424432424753230244b2443242475323024562443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e496e7465726e616c244754242443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4564676524475424244754243a3a696e736572743a3a68643964353762326439373438393239338001c1025f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e48616e646c65244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e4e6f6465526566244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4d7574244c54242475323724612447542424432424753230244b2443242475323024562443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e496e7465726e616c244754242443242475323024616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6e6f64652e2e6d61726b65722e2e4564676524475424244754243a3a696e736572745f6669743a3a68623061353832343561386666373930348101775f244c54247061726974795f7761736d2e2e656c656d656e74732e2e6f70732e2e496e6974457870722475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e53657269616c697a65244754243a3a73657269616c697a653a3a686239656163343138643136376139376282017a5f244c54247061726974795f7761736d2e2e656c656d656e74732e2e6f70732e2e496e737472756374696f6e2475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e53657269616c697a65244754243a3a73657269616c697a653a3a686231626331363534646661303364396683017b5f244c54247061726974795f7761736d2e2e656c656d656e74732e2e6f70732e2e496e6974457870722475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e446573657269616c697a65244754243a3a646573657269616c697a653a3a686664633232356334623233386338313884017e5f244c54247061726974795f7761736d2e2e656c656d656e74732e2e6f70732e2e496e737472756374696f6e2475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e446573657269616c697a65244754243a3a646573657269616c697a653a3a6837613165666664366130373630356236850183015f244c54247061726974795f7761736d2e2e656c656d656e74732e2e7072696d6974697665732e2e56617255696e7433322475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e446573657269616c697a65244754243a3a646573657269616c697a653a3a686466646161653634313331396663346386018e015f244c54247061726974795f7761736d2e2e656c656d656e74732e2e7072696d6974697665732e2e436f756e7465644c697374244c542454244754242475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e446573657269616c697a65244754243a3a646573657269616c697a653a3a683534343262653434343463396633626287017b5f244c54247061726974795f7761736d2e2e656c656d656e74732e2e6f70732e2e496e737472756374696f6e732475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e53657269616c697a65244754243a3a73657269616c697a653a3a6836303662626130393563653239356631880195017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a5f244c5424696d706c24753230247061726974795f7761736d2e2e656c656d656e74732e2e53657269616c697a652475323024666f722475323024616c6c6f632e2e737472696e672e2e537472696e67244754243a3a73657269616c697a653a3a6864373133343937366430343365656662890195017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a5f244c5424696d706c24753230247061726974795f7761736d2e2e656c656d656e74732e2e53657269616c697a652475323024666f722475323024616c6c6f632e2e737472696e672e2e537472696e67244754243a3a73657269616c697a653a3a68646538646538346438353534396238358a0199017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a5f244c5424696d706c24753230247061726974795f7761736d2e2e656c656d656e74732e2e446573657269616c697a652475323024666f722475323024616c6c6f632e2e737472696e672e2e537472696e67244754243a3a646573657269616c697a653a3a68333239326637613833666532396331658b013c73726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6761733a3a68323330626332633134383865366432388c014873726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f7365745f73746f726167653a3a68376563303365646435343032393234378d015d5f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e42547265654d6170244c54244b24432424753230245624475424244754243a3a656e7472793a3a68383335353436323566346638396330328e018d015f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e42547265654d6170244c54244b24432424753230245624475424247532302461732475323024636f72652e2e697465722e2e7472616974732e2e496e746f4974657261746f72244754243a3a696e746f5f697465723a3a68346138363338313030396366623233318f017d5f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e496e746f49746572244c54244b24432424753230245624475424247532302461732475323024636f72652e2e6f70732e2e64726f702e2e44726f70244754243a3a64726f703a3a686130366661396662336663366466626590016f5f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e566163616e74456e747279244c542424753237246124432424753230244b24432424753230245624475424244754243a3a696e736572743a3a686235323337343935613238383836633891015e5f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e42547265654d6170244c54244b24432424753230245624475424244754243a3a696e736572743a3a683765666539323238363734353231663492012e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a686432336363336535376130653436616493014873726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f6765745f73746f726167653a3a68613561616636366532346535326361349401a4015f244c542473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4f7665726c61794163636f756e744462244c54242475323724612443242475323024542447542424753230246173247532302473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4163636f756e744462244c54245424475424244754243a3a6765745f73746f726167653a3a683865386331363531373837333162663195014173726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f63616c6c3a3a683535643338623263363434373335383896015e5f244c542473726d6c5f636f6e74726163742e2e657865632e2e457865637574696f6e436f6e74657874244c542424753237246124432424753230245424475424244754243a3a63616c6c3a3a683830353331653461393866613830636197014373726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f6372656174653a3a68363430383465366666303831333131359801605f244c542473726d6c5f636f6e74726163742e2e657865632e2e457865637574696f6e436f6e74657874244c542424753237246124432424753230245424475424244754243a3a6372656174653a3a683438353437333562633034643037616499014373726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f72657475726e3a3a68303638396361643830396331366661349a014773726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f696e7075745f73697a653a3a68323766656562383435363364343932639b014773726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f696e7075745f636f70793a3a68643531653638666635376636646131349c014973726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f736372617463685f73697a653a3a68653032393030306136616165326335619d014973726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f736372617463685f636f70793a3a68343634336535633030643562336233349e01645f244c542473726d6c5f64656d6f63726163792e2e4d6f64756c65244c54245424475424244754243a3a656e645f626c6f636b3a3a5f24753762242475376224636c6f73757265247537642424753764243a3a68326164343031356266386463376332619f014e5f244c542473726d6c5f64656d6f63726163792e2e4d6f64756c65244c54245424475424244754243a3a696e6a6563745f7265666572656e64756d3a3a6861353434633337303538393134393761a001605f244c54246e6f64655f72756e74696d652e2e43616c6c2475323024617324753230247061726974795f636f6465632e2e636f6465632e2e456e636f6465244754243a3a656e636f64655f746f3a3a6831366432656335363063653462316362a101475f244c542473726d6c5f73797374656d2e2e4d6f64756c65244c54245424475424244754243a3a6465706f7369745f6576656e743a3a6833346639633537346133316662383734a2014d5f244c542473726d6c5f64656d6f63726163792e2e4d6f64756c65244c54245424475424244754243a3a636c6561725f7265666572656e64756d3a3a6831356631356631626438623066373534a30191017061726974795f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a5f244c5424696d706c24753230247061726974795f636f6465632e2e636f6465632e2e456e636f64652475323024666f722475323024244c50244a24432424753230244b24525024244754243a3a656e636f64655f746f3a3a6830653332303136633338623439393736a401d0015f244c542473725f7072696d6974697665732e2e67656e657269632e2e756e636865636b65645f6d6f7274616c5f65787472696e7369632e2e556e636865636b65644d6f7274616c45787472696e736963244c5424416464726573732443242475323024496e646578244324247532302443616c6c24432424753230245369676e6174757265244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a6837306561333637373061646466666532a5018f015f244c542473726d6c5f62616c616e6365732e2e616464726573732e2e41646472657373244c54244163636f756e74496424432424753230244163636f756e74496e646578244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a6861626464303937326362636138333739a6015d5f244c54246e6f64655f72756e74696d652e2e43616c6c2475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a6837393565363339353966393962653562a701e3015f244c542473725f7072696d6974697665732e2e67656e657269632e2e756e636865636b65645f6d6f7274616c5f65787472696e7369632e2e556e636865636b65644d6f7274616c45787472696e736963244c5424416464726573732443242475323024496e646578244324247532302443616c6c24432424753230245369676e61747572652447542424753230246173247532302473725f7072696d6974697665732e2e7472616974732e2e436865636b61626c65244c5424436f6e7465787424475424244754243a3a636865636b3a3a6837326166613033616537373038373263a801485f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a6c6f6f6b75705f696e6465783a3a6862613633626439373564363038346531a901445f244c542473726d6c5f636f6e74726163742e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6838366638653166346563373934653039aa014b5f244c542473726d6c5f64656d6f63726163792e2e4d6f64756c65244c54245424475424244754243a3a73746f72655f6d657461646174613a3a6831613730346663623831323263613432ab01565f244c542473726d6c5f64656d6f63726163792e2e4d6f64756c65244c54245424475424244754243a3a696e7465726e616c5f73746172745f7265666572656e64756d3a3a6832303664393961616664393730353562ac01465f244c542473726d6c5f73797374656d2e2e4d6f64756c65244c54245424475424244754243a3a626c6f636b5f6e756d6265723a3a6863303963333039326562313438393037ad01455f244c542473726d6c5f64656d6f63726163792e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6861386133396564356161663463396534ae015d5f244c542473726d6c5f636f6e74726163742e2e5261774576656e74244c542442616c616e636524432424753230244163636f756e74496424475424244754243a3a6d657461646174613a3a6861396164333961363633323161363264af015e5f244c542473726d6c5f64656d6f63726163792e2e5261774576656e74244c542442616c616e636524432424753230244163636f756e74496424475424244754243a3a6d657461646174613a3a6835626335333439653538636439636265b0015e5f244c542473726d6c5f64656d6f63726163792e2e43616c6c244c54245424475424247532302461732475323024636f72652e2e636c6f6e652e2e436c6f6e65244754243a3a636c6f6e653a3a6838343434643232623362313965393630b101535f244c54246e6f64655f72756e74696d652e2e43616c6c247532302461732475323024636f72652e2e636c6f6e652e2e436c6f6e65244754243a3a636c6f6e653a3a6834313536353930666236336536316436b201635f244c542473726d6c5f636f756e63696c2e2e73656174732e2e43616c6c244c54245424475424247532302461732475323024636f72652e2e636c6f6e652e2e436c6f6e65244754243a3a636c6f6e653a3a6861643536333731346137666330653939b301645f244c542473726d6c5f636f756e63696c2e2e766f74696e672e2e43616c6c244c54245424475424247532302461732475323024636f72652e2e636c6f6e652e2e436c6f6e65244754243a3a636c6f6e653a3a6864373436313135633836303237303365b4015e5f244c542473726d6c5f636f6e73656e7375732e2e43616c6c244c54245424475424247532302461732475323024636f72652e2e636c6f6e652e2e436c6f6e65244754243a3a636c6f6e653a3a6861376466313437313133383039336333b5015b5f244c54246e6f64655f72756e74696d652e2e43616c6c247532302461732475323024636f72652e2e636c6f6e652e2e436c6f6e65244754243a3a636c6f6e653a3a683431353635393066623633653631643620282e3134303929b601615f244c54245524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e53746f726167654d6170244c54244b24432424753230245624475424244754243a3a6765743a3a6838323737333832633430343565346566b701645f244c54245524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e53746f726167654d6170244c54244b24432424753230245624475424244754243a3a696e736572743a3a6839666636333139666264313761313637b8014b73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653a3a74616b655f6f725f70616e69633a3a6866613437373466626462343161396232b9014c73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653a3a6765745f6f725f64656661756c743a3a6830613033653464336263616631363035ba014c73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653a3a6765745f6f725f64656661756c743a3a6832383431626234313630333664333532bb015d5f244c54246e6f64655f72756e74696d652e2e43616c6c2475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a6864633935633338386230623562363563bc0133636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a686539663130393735316463363363396220282e3237323629bd014c73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653a3a6765745f6f725f64656661756c743a3a6839323532653630633830306130366165be014d73726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653a3a74616b655f6f725f64656661756c743a3a6863343034333537653332303432323766bf014573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653a3a726571756972653a3a6861393564346239306536386162656138c0014573726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653a3a726571756972653a3a6863306365306638303263616463663337c101495f244c542473726d6c5f73657373696f6e2e2e4d6f64756c65244c54245424475424244754243a3a73746f72655f6d657461646174613a3a6863643837323766366339616262653536c201435f244c542473726d6c5f73657373696f6e2e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6863666431643338336663646139663032c301525f244c542473726d6c5f636f756e63696c2e2e6d6f74696f6e732e2e4d6f64756c65244c54245424475424244754243a3a73746f72655f6d657461646174613a3a6864386262633734306332333935376639c4014c5f244c542473726d6c5f636f756e63696c2e2e6d6f74696f6e732e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6835626433323762306164313132646333c5014f5f244c542473726d6c5f73657373696f6e2e2e5261774576656e74244c5424426c6f636b4e756d62657224475424244754243a3a6d657461646174613a3a6834646233313332653462343932353930c601625f244c542473726d6c5f636f756e63696c2e2e6d6f74696f6e732e2e5261774576656e74244c54244861736824432424753230244163636f756e74496424475424244754243a3a6d657461646174613a3a6862306236376466356236393065383132c7017b5f244c542473726d6c5f737570706f72742e2e73746f726167652e2e52756e74696d6553746f7261676524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e67656e657261746f722e2e53746f72616765244754243a3a6765743a3a6838396233663364616462393163663861c8017b5f244c542473726d6c5f737570706f72742e2e73746f726167652e2e52756e74696d6553746f7261676524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e67656e657261746f722e2e53746f72616765244754243a3a6765743a3a6862653838646261666137323263613965c9017b5f244c542473726d6c5f737570706f72742e2e73746f726167652e2e52756e74696d6553746f7261676524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e67656e657261746f722e2e53746f72616765244754243a3a7075743a3a6831303337373035653964376263666561ca017b5f244c542473726d6c5f737570706f72742e2e73746f726167652e2e52756e74696d6553746f7261676524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e67656e657261746f722e2e53746f72616765244754243a3a7075743a3a6836633463356636656235386636653935cb017b5f244c542473726d6c5f737570706f72742e2e73746f726167652e2e52756e74696d6553746f7261676524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e67656e657261746f722e2e53746f72616765244754243a3a7075743a3a6864313434626162666361343833613735cc017b5f244c542473726d6c5f737570706f72742e2e73746f726167652e2e52756e74696d6553746f7261676524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e67656e657261746f722e2e53746f72616765244754243a3a7075743a3a6865636133366166326262326665626539cd017b5f244c542473726d6c5f737570706f72742e2e73746f726167652e2e52756e74696d6553746f7261676524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e67656e657261746f722e2e53746f72616765244754243a3a7075743a3a6866303537306663383235613632366632ce018b015f244c54247061726974795f7761736d2e2e656c656d656e74732e2e696d706f72745f656e7472792e2e526573697a61626c654c696d6974732475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e446573657269616c697a65244754243a3a646573657269616c697a653a3a6866653433663034323565643139633838cf014173725f7072696d6974697665733a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6863366133343538396535373730653065d00192015f244c542473726d6c5f62616c616e6365732e2e616464726573732e2e41646472657373244c54244163636f756e74496424432424753230244163636f756e74496e646578244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e456e636f6465244754243a3a656e636f64655f746f3a3a6838346463343564336362656564613064d1012d73726d6c5f636f6e74726163743a3a766d3a3a657865637574653a3a6862353761333136313736663330323064d2015e5f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e42547265654d6170244c54244b24432424753230245624475424244754243a3a696e736572743a3a6863623139343438366436366230656631d3017e5f244c54247061726974795f7761736d2e2e656c656d656e74732e2e73656374696f6e2e2e53656374696f6e2475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e446573657269616c697a65244754243a3a646573657269616c697a653a3a6834656132363265363339366639636166d4017d5f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e42547265654d6170244c54244b24432424753230245624475424247532302461732475323024636f72652e2e6f70732e2e64726f702e2e44726f70244754243a3a64726f703a3a6866633163343630653063326563626366d5017a5f244c54247061726974795f7761736d2e2e656c656d656e74732e2e73656374696f6e2e2e53656374696f6e2475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e53657269616c697a65244754243a3a73657269616c697a653a3a6833333938333465313261336533653033d60190015f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e49746572244c542424753237246124432424753230244b24432424753230245624475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f72244754243a3a6e6578743a3a6865353266343132393066343262326239d701367061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6864326337386235313630313831663433d8013273725f73616e64626f783a3a696d703a3a64697370617463685f7468756e6b3a3a6834323161613063616638386534343831d901ba017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f4445434f44455f464f525f547970656456616c75653a3a5f244c5424696d706c24753230247061726974795f636f6465632e2e636f6465632e2e4465636f64652475323024666f7224753230247375627374726174655f7072696d6974697665732e2e73616e64626f782e2e547970656456616c7565244754243a3a6465636f64653a3a6839343539393133306135636331316330da017d5f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e42547265654d6170244c54244b24432424753230245624475424247532302461732475323024636f72652e2e6f70732e2e64726f702e2e44726f70244754243a3a64726f703a3a6865333130303237323330613833373433db0186015f244c54247061726974795f7761736d2e2e656c656d656e74732e2e696e6465785f6d61702e2e496e6465784d6170244c542454244754242475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e53657269616c697a65244754243a3a73657269616c697a653a3a6863373961376364363839623564306362dc0180015f244c54247061726974795f7761736d2e2e656c656d656e74732e2e73656374696f6e2e2e437573746f6d53656374696f6e2475323024617324753230247061726974795f7761736d2e2e656c656d656e74732e2e53657269616c697a65244754243a3a73657269616c697a653a3a6866376436633234656533343666343433dd01457061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e5265616465723a3a6e65773a3a6834336436393462643165396236636330de01367061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6835336461303364353863623861613537df01397061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6832626264613338366336386537393133e001397061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6833646334356261663530353737303936e101397061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6836636238326533656137383964626234e201bd017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f454e434f44455f464f525f547970656456616c75653a3a5f244c5424696d706c24753230247061726974795f636f6465632e2e636f6465632e2e456e636f64652475323024666f7224753230247375627374726174655f7072696d6974697665732e2e73616e64626f782e2e547970656456616c7565244754243a3a656e636f64655f746f3a3a6835663166323062373566626135356466e301595f244c542424753562245424753564242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e456e636f6465244754243a3a656e636f64655f746f3a3a6838316134633966346261646462323961e401595f244c542424753562245424753564242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e456e636f6465244754243a3a656e636f64655f746f3a3a6865346534373936393436323033363937e5018c015f244c542473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4469726563744163636f756e74446224753230246173247532302473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4163636f756e744462244c54245424475424244754243a3a6765745f62616c616e63653a3a6837313166333837343936643264313538e601485f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a667265655f62616c616e63653a3a6831356436363662396266306663623439e7018c015f244c542473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4469726563744163636f756e74446224753230246173247532302473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4163636f756e744462244c54245424475424244754243a3a6765745f73746f726167653a3a6864663435383932613261323830376662e8013673726d6c5f636f6e74726163743a3a646f75626c655f6d61703a3a66756c6c5f6b65793a3a6866306266373061633430343263343665e90187015f244c542473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4469726563744163636f756e74446224753230246173247532302473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4163636f756e744462244c54245424475424244754243a3a636f6d6d69743a3a6864666131356261613563633632343738ea018d015f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e42547265654d6170244c54244b24432424753230245624475424247532302461732475323024636f72652e2e697465722e2e7472616974732e2e496e746f4974657261746f72244754243a3a696e746f5f697465723a3a6862323062363235623639613565366138eb0186015f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e496e746f49746572244c54244b24432424753230245624475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f72244754243a3a6e6578743a3a6864313935613336663535623165633961ec01555f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a7365745f667265655f62616c616e63655f6372656174696e673a3a6832393866643036323035383564656566ed0186015f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e496e746f49746572244c54244b24432424753230245624475424247532302461732475323024636f72652e2e697465722e2e6974657261746f722e2e4974657261746f72244754243a3a6e6578743a3a6833646166613766316636383236383337ee017d5f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e496e746f49746572244c54244b24432424753230245624475424247532302461732475323024636f72652e2e6f70732e2e64726f702e2e44726f70244754243a3a64726f703a3a6861393431373566653834346639643230ef0189015f244c542473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4469726563744163636f756e74446224753230246173247532302473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4163636f756e744462244c54245424475424244754243a3a6765745f636f64653a3a6861353330313565376638356466653430f00191017061726974795f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a5f244c5424696d706c24753230247061726974795f636f6465632e2e636f6465632e2e456e636f64652475323024666f722475323024244c50244a24432424753230244b24525024244754243a3a656e636f64655f746f3a3a6865323866616532643838643235313036f101367061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6834646638396534623066333237313961f2014273726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765745f6f725f64656661756c743a3a6839363664396536323363626262663539f3013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833616139376335656361616235646563f4013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6865396237653537633665316637306336f5019d015f244c542473725f7072696d6974697665732e2e67656e657269632e2e6865616465722e2e486561646572244c54244e756d62657224432424753230244861736824432424753230244469676573744974656d244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a6863303136343464326163363661656665f601a4015f244c542473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4f7665726c61794163636f756e744462244c54242475323724612443242475323024542447542424753230246173247532302473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4163636f756e744462244c54245424475424244754243a3a6765745f62616c616e63653a3a6866666431363266333135363037376161f7015b5f244c5424616c6c6f632e2e636f6c6c656374696f6e732e2e62747265652e2e6d61702e2e42547265654d6170244c54244b24432424753230245624475424244754243a3a6765743a3a6863373766336561353462393064343164f8012e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a6838393162383063653736656639323831f9019f015f244c542473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4f7665726c61794163636f756e744462244c54242475323724612443242475323024542447542424753230246173247532302473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4163636f756e744462244c54245424475424244754243a3a636f6d6d69743a3a6861656164396434626461326336396531fa01a1015f244c542473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4f7665726c61794163636f756e744462244c54242475323724612443242475323024542447542424753230246173247532302473726d6c5f636f6e74726163742e2e6163636f756e745f64622e2e4163636f756e744462244c54245424475424244754243a3a6765745f636f64653a3a6838333039343335363462323066343366fb014b5f244c542473726d6c5f74696d657374616d702e2e4d6f64756c65244c54245424475424244754243a3a73746f72655f6d657461646174613a3a6838376261316130363239326134366263fc01455f244c542473726d6c5f74696d657374616d702e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6830326263333934373837316437633564fd014d5f244c542424524624247532372461247532302454247532302461732475323024636f72652e2e666d742e2e4465627567244754243a3a666d743a3a6863336563653938316363353764383861fe010776657273696f6eff01086d6574616461746180020b617574686f726974696573810210696e697469616c6973655f626c6f636b8202445f244c542473726d6c5f73797374656d2e2e4d6f64756c65244c54245424475424244754243a3a696e697469616c6973653a3a683631356638373937643464393630613383020f6170706c795f65787472696e7369638402a4015f244c542473726d6c5f6578656375746976652e2e457865637574697665244c542453797374656d2443242475323024426c6f636b2443242475323024436f6e7465787424432424753230245061796d656e74244324247532302446696e616c69736174696f6e24475424244754243a3a6170706c795f65787472696e7369635f6e6f5f6e6f74655f776974685f6c656e3a3a686565643435646237613563656236323785020d657865637574655f626c6f636b8602525f244c542473726d6c5f73797374656d2e2e4d6f64756c65244c54245424475424244754243a3a6e6f74655f66696e69736865645f65787472696e736963733a3a68616665303432343531633333633738648702c7015f244c5424244c50245024432424753230245124432424753230245224432424753230245324432424753230245424432424753230245524432424753230245624432424753230245724432424753230245824432424753230245924432424753230245a2452502424753230246173247532302473725f7072696d6974697665732e2e7472616974732e2e4f6e46696e616c697365244c54244e756d62657224475424244754243a3a6f6e5f66696e616c6973653a3a68636532633330353731356261666133648802425f244c542473726d6c5f73797374656d2e2e4d6f64756c65244c54245424475424244754243a3a66696e616c6973653a3a686362316633313031316332343037343089020e66696e616c6973655f626c6f636b8a0213696e686572656e745f65787472696e736963738b020f76616c696461746f725f636f756e748c020a76616c696461746f72738d020974696d657374616d708e020b72616e646f6d5f736565648f020d6163636f756e745f6e6f6e63659002475f244c542473726d6c5f73797374656d2e2e4d6f64756c65244c54245424475424244754243a3a6163636f756e745f6e6f6e63653a3a683161363432376365653261393731316291020e6c6f6f6b75705f6164647265737392021476616c69646174655f7472616e73616374696f6e9302b0015f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c5424542447542424753230246173247532302473725f7072696d6974697665732e2e7472616974732e2e4d616b655061796d656e74244c5424244c54245424753230246173247532302473726d6c5f73797374656d2e2e5472616974244754242e2e4163636f756e74496424475424244754243a3a6d616b655f7061796d656e743a3a68363863636266383339663330393531379402af015f244c542473726d6c5f7374616b696e672e2e4d6f64756c65244c5424542447542424753230246173247532302473726d6c5f73657373696f6e2e2e4f6e53657373696f6e4368616e6765244c5424244c54245424753230246173247532302473726d6c5f74696d657374616d702e2e5472616974244754242e2e4d6f6d656e7424475424244754243a3a6f6e5f73657373696f6e5f6368616e67653a3a68363539366231306238633663393139369502495f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a746f74616c5f62616c616e63653a3a68616631366234353933376163636639389602425f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a7265776172643a3a683264643231396637303639336662383297024a5f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a746f74616c5f69737375616e63653a3a683935613162333065313138613431333998022d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a68393534636334313061386638316637639902565f244c542473726d6c5f636f6e73656e7375732e2e4d6f64756c65244c54245424475424244754243a3a736176655f6f726967696e616c5f617574686f7269746965733a3a68396433336632306431633134663432669a0234636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a68626262313631653532333639376633639b022e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a68356338633932396434653763656234639c023c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a68623234303032353665616139333864329d02b8015f244c542473726d6c5f7374616b696e672e2e4d6f64756c65244c5424542447542424753230246173247532302473726d6c5f62616c616e6365732e2e456e737572654163636f756e744c6971756964244c5424244c54245424753230246173247532302473726d6c5f73797374656d2e2e5472616974244754242e2e4163636f756e74496424475424244754243a3a656e737572655f6163636f756e745f6c69717569643a3a68313738353938313530633437383838629e02495f244c542473726d6c5f7374616b696e672e2e4d6f64756c65244c54245424475424244754243a3a73746f72655f6d657461646174613a3a68383333663531666634643933363661629f02435f244c542473726d6c5f7374616b696e672e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6863393436336161666535623031636462a0025c5f244c542473726d6c5f7374616b696e672e2e5261774576656e74244c542442616c616e636524432424753230244163636f756e74496424475424244754243a3a6d657461646174613a3a6830326430323832383531313531316530a102715f244c542473726d6c5f7374616b696e672e2e43616c6c244c5424542447542424753230246173247532302473726d6c5f737570706f72742e2e64697370617463682e2e446973706174636861626c65244754243a3a64697370617463683a3a6832626337303936333462313436333937a202645f244c54245524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e53746f726167654d6170244c54244b24432424753230245624475424244754243a3a696e736572743a3a6834306262386638313765346163336431a302485f244c542473726d6c5f7374616b696e672e2e4d6f64756c65244c54245424475424244754243a3a6170706c795f756e7374616b653a3a6862303765636263396134343438616163a4023073726d6c5f636f6e74726163743a3a657865633a3a7472616e736665723a3a6830623430386333373766316261616137a5024f5f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a6578697374656e7469616c5f6465706f7369743a3a6831353833383437363639396663333030a6022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6864656266313136356634326463333966a702655f244c5424616c6c6f632e2e626f7865642e2e426f78244c542454244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a6863656163396464663465663435393937a8028f015f244c542473726d6c5f62616c616e6365732e2e616464726573732e2e41646472657373244c54244163636f756e74496424432424753230244163636f756e74496e646578244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a6833613563323464633533366431306230a9022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6863323162623864623862633337623861aa02655f244c5424616c6c6f632e2e626f7865642e2e426f78244c542454244754242475323024617324753230247061726974795f636f6465632e2e636f6465632e2e4465636f6465244754243a3a6465636f64653a3a6833316533386231333335383665346563ab02685f244c54246e6f64655f72756e74696d652e2e43616c6c24753230246173247532302473726d6c5f737570706f72742e2e64697370617463682e2e446973706174636861626c65244754243a3a64697370617463683a3a6866646530626631343530323838373230ac02785f244c542473726d6c5f636f756e63696c2e2e73656174732e2e43616c6c244c5424542447542424753230246173247532302473726d6c5f737570706f72742e2e64697370617463682e2e446973706174636861626c65244754243a3a64697370617463683a3a6838343131613239666330613630323936ad02795f244c542473726d6c5f636f756e63696c2e2e766f74696e672e2e43616c6c244c5424542447542424753230246173247532302473726d6c5f737570706f72742e2e64697370617463682e2e446973706174636861626c65244754243a3a64697370617463683a3a6865386665376130353562366231363831ae022e73726d6c5f636f6e74726163743a3a6761733a3a6275795f6761733a3a6865356465393236323936666336653466af02505f244c542473726d6c5f636f756e63696c2e2e766f74696e672e2e4d6f64756c65244c54245424475424244754243a3a69735f636f756e63696c6c6f723a3a6835343361333734626566646233316631b002435f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a726573657276653a3a6837306166353662666364383938393936b1023873726d6c5f636f6e74726163743a3a6761733a3a726566756e645f756e757365645f6761733a3a6832633761393733373764653834663031b202415f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a736c6173683a3a6835366363343231653763663661373762b3022e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a6864393733613264306564333630393937b4024c5f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a7365745f667265655f62616c616e63653a3a6831366231396564316130613432396265b502505f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a7365745f72657365727665645f62616c616e63653a3a6862363530633865356161386639383133b6024a5f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a736c6173685f72657365727665643a3a6835626238663462303066323537316636b702b6015f244c542473726d6c5f636f756e63696c2e2e73656174732e2e4d6f64756c65244c5424542447542424753230246173247532302473725f7072696d6974697665732e2e7472616974732e2e4f6e46696e616c697365244c5424244c54245424753230246173247532302473726d6c5f73797374656d2e2e5472616974244754242e2e426c6f636b4e756d62657224475424244754243a3a6f6e5f66696e616c6973653a3a6830333031323464393433343438323336b802455f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a756e726573657276653a3a6863373364626464633164616139376137b902505f244c542473726d6c5f636f756e63696c2e2e73656174732e2e4d6f64756c65244c54245424475424244754243a3a73746f72655f6d657461646174613a3a6830346134313539373865666465636261ba024a5f244c542473726d6c5f636f756e63696c2e2e73656174732e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6865383663366565323866383266623435bb02545f244c542473726d6c5f636f756e63696c2e2e73656174732e2e5261774576656e74244c54244163636f756e74496424475424244754243a3a6d657461646174613a3a6833636564613263336662306636656161bc024e5f244c542473726d6c5f636f756e63696c2e2e73656174732e2e4d6f64756c65244c54245424475424244754243a3a72656d6f76655f766f7465723a3a6830323365666664386565353430373539bd02a10173726d6c5f73797374656d3a3a5f494d504c5f4445434f44455f464f525f4576656e745265636f72643a3a5f244c5424696d706c24753230247061726974795f636f6465632e2e636f6465632e2e4465636f64652475323024666f72247532302473726d6c5f73797374656d2e2e4576656e745265636f7264244c54244524475424244754243a3a6465636f64653a3a6833633035383631323431303564626465be02485f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a726561705f6163636f756e743a3a6837653362306663386236383862646132bf02455f244c542473726d6c5f74726561737572792e2e4d6f64756c65244c54245424475424244754243a3a70726f706f73616c733a3a6862616333333136333830343335356364c002485f244c542473726d6c5f73797374656d2e2e4d6f64756c65244c54245424475424244754243a3a73746f72655f6d657461646174613a3a6836346261613264633136653138333966c102425f244c542473726d6c5f73797374656d2e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6833363130386335633036616564363430c2024a5f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a73746f72655f6d657461646174613a3a6864366237646534623136643963353032c302645f244c54245524753230246173247532302473726d6c5f737570706f72742e2e73746f726167652e2e53746f726167654d6170244c54244b24432424753230245624475424244754243a3a696e736572743a3a6864656631383734373561666639666132c402445f244c542473726d6c5f62616c616e6365732e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6864306262363161623231303839366130c5024b5f244c542473726d6c5f636f6e73656e7375732e2e4d6f64756c65244c54245424475424244754243a3a73746f72655f6d657461646174613a3a6837633936633262363533323037346464c602455f244c542473726d6c5f636f6e73656e7375732e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6838623265323930613562336466336661c702715f244c542473726d6c5f62616c616e6365732e2e5261774576656e74244c54244163636f756e74496424432424753230244163636f756e74496e646578244324247532302442616c616e636524475424244754243a3a6d657461646174613a3a6865396139396637653636613764333532c8024a5f244c542473726d6c5f74726561737572792e2e4d6f64756c65244c54245424475424244754243a3a73746f72655f6d657461646174613a3a6832616335633230386131633732663130c902445f244c542473726d6c5f74726561737572792e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6834383666386466666332636565396234ca025d5f244c542473726d6c5f74726561737572792e2e5261774576656e74244c542442616c616e636524432424753230244163636f756e74496424475424244754243a3a6d657461646174613a3a6838323965393333353337656432393161cb02515f244c542473726d6c5f636f756e63696c2e2e766f74696e672e2e4d6f64756c65244c54245424475424244754243a3a73746f72655f6d657461646174613a3a6866356565636136643462363937643161cc024b5f244c542473726d6c5f636f756e63696c2e2e766f74696e672e2e4d6f64756c65244c54245424475424244754243a3a6d657461646174613a3a6864336435343665376231663363636461cd02505f244c542473726d6c5f636f756e63696c2e2e766f74696e672e2e5261774576656e74244c54244861736824475424244754243a3a6d657461646174613a3a6836333634623762666266333838333764ce02066d656d637079cf02076d656d6d6f7665d002066d656d736574d102066d656d636d70d202095f5f75646976746933d3020c5f5f756469766d6f64746934d402095f5f756d6f64746933d502085f5f6d756c746933d6023d636f6d70696c65725f6275696c74696e733a3a696e743a3a6d756c3a3a727573745f693132385f6d756c3a3a6863376330373565313538323734363831d7023f636f6d70696c65725f6275696c74696e733a3a696e743a3a73686966743a3a727573745f693132385f73686c3a3a6837376537303033336538326634316638d8023f636f6d70696c65725f6275696c74696e733a3a696e743a3a73686966743a3a727573745f753132385f7368723a3a6864666263646537396463393434653031d902095f5f6c736872746933da02095f5f6173686c746933", - "0x4664fb5d4e16f894df23cadb3faaa9a6": "0x04000000", - "0xfb4fdd0ab2d85118e220e2e7473cd3b5": "0x0000a0dec5adc9353600000000000000", - "0x3a617574683a6c656e": "0x04000000", - "0xa36baa0f89eff09b2facf282f27a11ba": "0x50c30000", - "0x52b963fbdb3d6e1b03808fc20071f07f": "0x0062070000000000", - "0x8366297e853b97a38cca0f62019a717b": "0x00000000000000000000000000000000", - "0x59b17352bea17cb7dec6dde697de7db4": "0x3c00000000000000", - "0xfc2dc4b8bb0b9ca8f01a73a726f7c7f5": "0x000e010000000000", - "0x24b2518f9a9ee24ab0b62346d83d90b0": "0x11080000", - "0xf718f07ec955fb94f1b3069713461089": "0x0010a5d4e80000000000000000000000", - "0x34de7fc8c73e4252b9e09a9e3bf602f8": "0x3c00000000000000", - "0x637414312dac3b280120bf15b4f66cee": "0x00000000", - "0x3a617574683a02000000": "0x063d7787ebca768b7445dfebe7d62cbb1625ff4dba288ea34488da266dd6dca5", - "0xdade128e67a5ed110063f56a01ab6bbf": "0x0000000000000000", - "0x579ab55d37b1220812be3c3df29d4858": "0x0000000000000000", - "0xa902f1f0ef97177b8df9f9fd413768e7": "0x00000000", - "0x0b21b3456b23e90d061941ab416f5ea2": "0x00000000000000000000000000000000", - "0xb8f48a8c01f629d6dc877f64892bed49": "0x0000000000000000", - "0x90e2849b965314409e8bc00011f3004f": "0x04000000", - "0x99e2aba8a2b7c8ccba2d740fb86adb0c": "0x00", - "0x24586f4898a5a637b755b658ec163d00": "0x00407a10f35a00000000000000000000", - "0xa361c08e2d7768113505020abde19e30": "0x00000000", - "0x0e0cdac0d4de97c54f3ae216b003fa81": "0x8043000000000000", - "0x799192c17c5cc562d709af11ace92e6a": "0x00040000", - "0x9651d20f401bfac47731a01d6eba33b4": "0x00000000", - "0x3b7d32346a3315a351084927a27d06a7": "0x0010a5d4e80000000000000000000000", - "0x125dc846383907f5846f72ce53ca0e4b": "0x00ca9a3b000000000000000000000000", - "0x2dce29f1a768624dc5343063cb77f77d": "0x07000000", - "0xdee5bbb035d9ebc2c9338b5aedf744d7": "0x8043000000000000", - "0x6e45a8645fa8f905c49fecfef3d06c67": "0x0100000000000000", - "0x53d1471b684c8a776c80353e5981c960": "0x00407a10f35a00000000000000000000", - "0xe026dd082e3158e72eb7c985fc8bac4f": "0x8043000000000000", - "0x62f532424b7b1c52f522857315040f27": "0x00407a10f35a00000000000000000000", - "0xdfaac108e0d4bc78fc9419a7fcfa84dc": "0x1082c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf54de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7063d7787ebca768b7445dfebe7d62cbb1625ff4dba288ea34488da266dd6dca58101764f45778d4980dadaceee6e8af2517d3ab91ac9bec9cd1714fa5994081c", - "0xb7b6ec0f25eb1ed8b91d05f697d7a874": "0x0c00000000000000", - "0x500603c2af44c475f017a2bbd8d08cbf": "0x04f295940fa750df68a686fcf4abd4111c8a9c5a5a5a83c4c8639c451a94a7adfd", - "0x934302c5ec4cb4f73a395e2184ab0aa6": "0x00e40b54020000000000000000000000", - "0x0e4944cfd98d6f4cc374d16f5a4e3f9c": "0x0000000000000000", - "0xb553f17a95cb65012a4326bbaae97035": "0x0010a5d4e80000000000000000000000", - "0x52c9048efbfc40fd1e312b7bed451dee": "0x06000000", - "0xf4039aa8ae697861be900c58239e96f7": "0x0010a5d4e80000000000000000000000", - "0x90d5871cf3f4d0a3642cf2043a7d8eda": "0x0010a5d4e80000000000000000000000", - "0xcf9a75deea0508104cd993c82daf57d3": "0x8096980000000000", - "0xfe7030fd433199728c516e4392091aa5": "0x0080c6a47e8d03000000000000000000", - "0x2b89d3b6f46fc8a3aee48c9cb06d7670": "0x0010a5d4e80000000000000000000000", - "0xdd9b01f8462dc19488279cb351a6d861": "0x20a10700", - "0xd9c94b41dc87728ebf0a966d2e9ad9c0": "0x3c00000000000000", - "0x3a617574683a01000000": "0x4de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7", - "0xfbb77d814ac81cfe0ef7030e8bd686f0": "0xe803000000000000", - "0x4a8b1a5c7681353a6a320553abbbca49": "0x8043000000000000", - "0x78f4ad73d6b7279f8d06f359e363c829": "0x0000a0dec5adc9353600000000000000", - "0xf14d23a9d4492a1efc9194e257b3c3d9": "0x00000000" - } - } -} diff --git a/node/cli/res/charred-cherry.json b/node/cli/res/charred-cherry.json new file mode 100644 index 0000000000000000000000000000000000000000..11f64f098d42eaba2ba63ca311d02caf7388d863 --- /dev/null +++ b/node/cli/res/charred-cherry.json @@ -0,0 +1,92 @@ +{ + "name": "Charred Cherry", + "id": "charred-cherry", + "properties": { + "tokenDecimals": 15, + "tokenSymbol": "CHR" + }, + "telemetryUrl": "wss://telemetry.polkadot.io/submit/", + "protocolId": null, + "bootNodes": [ + "/ip4/104.211.54.233/tcp/30333/p2p/QmWxNqJeKEBWjJXeX8s882ZdphuVPgUV43THfGAJn7UBWB", + "/ip4/104.211.48.51/tcp/30333/p2p/QmXd7MQAuXkQK1r3ejSbaXKgjXmT2FvbJ3yNfLZpsQ2t8S", + "/ip4/104.211.48.247/tcp/30333/p2p/QmV2zjgFRfxbgYZQC9qFr4aHsQt7tDBJRAdgqqxqTq1Kta", + "/ip4/40.114.120.164/tcp/30333/p2p/QmQbPCeurXuKhzCw6Ar6ovizNKATMTnkkqFJKgZzbF2MJs" + ], + "genesis": { + "raw": { + "0xfbb77d814ac81cfe0ef7030e8bd686f0": "0xe803000000000000", + "0xa902f1f0ef97177b8df9f9fd413768e7": "0x00000000", + "0x27b3872d47181b4a2dc15f0da43e7026": "0xe803000000000000", + "0x5278a9149ec1adfa8090a8ad336c881e": "0x0300000000000000", + "0x52b963fbdb3d6e1b03808fc20071f07f": "0x0027060000000000", + "0xfc2dc4b8bb0b9ca8f01a73a726f7c7f5": "0x00e1000000000000", + "0x3a617574683a03000000": "0x8101764f45778d4980dadaceee6e8af2517d3ab91ac9bec9cd1714fa5994081c", + "0x93940e78496482b15b64783020bbdfa0": "0x6400000000000000", + "0xb8f48a8c01f629d6dc877f64892bed49": "0x0000000000000000", + "0xcf9a75deea0508104cd993c82daf57d3": "0x8096980000000000", + "0xd9c94b41dc87728ebf0a966d2e9ad9c0": "0x3200000000000000", + "0x0e0cdac0d4de97c54f3ae216b003fa81": "0x5802000000000000", + "0x3a6772616e6470613a617574683a01000000": "0x4de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e70100000000000000", + "0x3b7d32346a3315a351084927a27d06a7": "0x0010a5d4e80000000000000000000000", + "0x34de7fc8c73e4252b9e09a9e3bf602f8": "0x6400000000000000", + "0x24586f4898a5a637b755b658ec163d00": "0x00407a10f35a00000000000000000000", + "0x8366297e853b97a38cca0f62019a717b": "0x00000000000000000000000000000000", + "0x3a6772616e6470613a617574683a02000000": "0x063d7787ebca768b7445dfebe7d62cbb1625ff4dba288ea34488da266dd6dca50100000000000000", + "0x3a636f6465": "0x0061736d0100000001f5012260037f7f7f017f60017f0060027f7f017f60057f7f7f7f7f0060037f7f7f0060047f7f7f7f0060017f017f60057f7f7f7f7f017f60027f7f0060017e0060047f7f7f7f017f60067f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60047f7f7e7f017f60000060027e7f0060017f017e60027e7f017f60027f7e0060037e7e7f0060057f7e7e7e7e0060037f7e7e0060037f7f7e0060047f7f7e7e0060027f7f017e60037e7f7f00600a7f7f7f7f7e7e7f7f7f7f00600a7f7f7f7e7e7f7f7f7f7f0060057f7e7f7f7e0060037f7e7e017f60087f7f7f7f7f7e7e7f0060047f7f7f7f017e60047f7e7e7f0060067f7e7e7e7e7f0002cc041703656e760a6578745f6d616c6c6f63000603656e76086578745f66726565000103656e760c6578745f74776f785f313238000403656e760f6578745f7365745f73746f72616765000503656e76146578745f6765745f73746f726167655f696e746f000703656e76236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74000503656e760e6578745f7072696e745f75746638000803656e760d6578745f7072696e745f6e756d000903656e76116578745f636c6561725f73746f72616765000803656e760d6578745f7072696e745f686578000803656e76106578745f73746f726167655f726f6f74000103656e76166578745f73616e64626f785f6d656d6f72795f676574000a03656e76166578745f73616e64626f785f6d656d6f72795f736574000a03656e760e6578745f626c616b65325f323536000403656e76126578745f6578697374735f73746f72616765000203656e76126578745f656432353531395f766572696679000a03656e76166578745f73616e64626f785f6d656d6f72795f6e6577000203656e761b6578745f73616e64626f785f6d656d6f72795f74656172646f776e000103656e76176578745f73616e64626f785f696e7374616e7469617465000b03656e76126578745f73616e64626f785f696e766f6b65000c03656e761d6578745f73616e64626f785f696e7374616e63655f74656172646f776e000103656e76106578745f636c6561725f707265666978000803656e76186578745f73746f726167655f6368616e6765735f726f6f74000d03ec02ea02080e080808080808080808080f08040408010101080e08040801010101080808080808080808080808080408080404040804080408020804010808040808080804020104020604040408020104040808080808080401000e02020801000202080b1002081100050202060202020201040212080101010404010108080808080808080813020f0201010108080808080808140815160108170808040802010101010108020201010101010f150502010401080808080108010801080108010105080802080802010204050502181818191208040e090118181801181818180818080210010818081801180505050e0503051a051b050505050505081c08120801080106010108080101010101040401040204040808080804080101010404040404040408080808040304081d0408040e080408080804040806040417151708080808080101010101080115091e0c1f0101010108080101010408010101080101000000001414142020210405017001535305030100110619037f01418080c0000b7f0041d0b0c3000b7f0041d0b0c3000b07d70312066d656d6f72790200195f5f696e6469726563745f66756e6374696f6e5f7461626c6501000b5f5f686561705f6261736503010a5f5f646174615f656e6403020c436f72655f76657273696f6e00e30110436f72655f617574686f72697469657300e40112436f72655f657865637574655f626c6f636b00e50115436f72655f696e697469616c6973655f626c6f636b00ed01114d657461646174615f6d6574616461746100ee011c426c6f636b4275696c6465725f6170706c795f65787472696e73696300ef011b426c6f636b4275696c6465725f66696e616c6973655f626c6f636b00f10120426c6f636b4275696c6465725f696e686572656e745f65787472696e7369637300f2011c426c6f636b4275696c6465725f636865636b5f696e686572656e747300f30118426c6f636b4275696c6465725f72616e646f6d5f7365656400f4012b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e00f601214772616e6470614170695f6772616e6470615f70656e64696e675f6368616e676500fc011e4772616e6470614170695f6772616e6470615f617574686f72697469657300fe0115417572614170695f736c6f745f6475726174696f6e008002099d01010041010b52704c5882016f7e7f810187019b019d01bb01ba018401618301810282028502870289028b028c028d028e028f029002e502727374759f0178bf02c302be02c10262f602dd01bf019b02ee02de029001b202c0018f01be01e702f202db02da02e902e802f502f302d501d401b601ac019a029802ed02ec02dd02dc028c018b01b102b002b801b7018a01bd01bc01e6028602c802c502c7020a8c8a23ea02e50203087f017e017f024002400240024002400240200041046a2802002202200041086a28020022036b2001410c6a2802002204200141086a28020022056b220641d8006d22074f0d00200320076a22082003490d0420024101742203200820082003491b2209ad42d8007e220a422088a70d04200aa722034100480d042002450d012000280200210b200310002208450d052008200b2003200241d8006c2202200220034b1b10f8021a200b10010c020b200028020021080c020b200310002208450d030b20002008360200200041046a2009360200200041086a28020021030b2008200341d8006c6a2005200610f8021a200141086a22022004360200200041086a2200200028020020076a36020041002100024003402000450d012002200441d8006a2203360200200041a87f6a210020042d000021082003210420084102470d000b0b02402001280204450d00200128020010010b0f0b1018000b200341081019000b0a0041b890c200104f000b0d0041ad8ec0004122100600000ba00601087f230041206b2202240020024100360218200242013703102000280200210320002802082200200241106a101b024002400240024002402000450d00200041d8006c2104200241186a2105034020052802002100200228021421060240024002400240024002400240024002402003280200410d470d0020062000470d01200041016a22062000490d0b20004101742207200620062007491b22074100480d0b2000450d0320022802102108200710002206450d0c2006200820072000200020074b1b10f8021a200810010c040b20062000470d01200041016a22062000490d0a20004101742207200620062007491b22074100480d0a2000450d0520022802102108200710002206450d0c2006200820072000200020074b1b10f8021a200810010c060b200228021021060c030b200228021021060c050b200710002206450d080b2002200736021420022006360210200528020021000b2005200041016a360200200620006a41003a0000200341d8006a2103200441a87f6a22040d030c040b200710002206450d060b2002200736021420022006360210200528020021000b2005200041016a360200200620006a41013a00002003200241106a101c200341d0006a2802002108024002400240024020022802142207200528020022006b41044f0d00200041046a22062000490d0620074101742200200620062000491b22004100480d062007450d0120022802102109200010002206450d092006200920002007200720004b1b10f8021a200910010c020b200228021021060c020b200010002206450d070b2002200036021420022006360210200528020021000b2005200041046a360200200620006a2008360000200341d8006a2103200441a87f6a22040d000b0b200241106a41086a2200280200210520022802142104200228021021032001280204210620012802002107200042003703002002420037031020072006200241106a1002200241086a2000290300370300200220022903103703002002411020032005100302402004450d00200310010b200241206a24000f0b1018000b200741011019000b200741011019000b200041011019000b960501047f02402000413f4b0d002001200041027410240f0b0240024002400240024002400240024002400240024002400240024002400240024002402000418080014f0d00200141046a2802002202200141086a28020022036b41024f0d01200341026a22042003490d0e20024101742203200420042003491b22034100480d0e2002450d0520012802002105200310002204450d0f2004200520032002200220034b1b10f8021a200510010c060b20004180808080044f0d01200141046a2802002202200141086a28020022036b41044f0d02200341046a22042003490d0d20024101742203200420042003491b22034100480d0d2002450d0720012802002105200310002204450d0f2004200520032002200220034b1b10f8021a200510010c080b200128020021040c050b200141031024200141046a2802002202200141086a28020022036b41044f0d01200341046a22042003490d0b20024101742203200420042003491b22034100480d0b2002450d0820012802002105200310002204450d0e2004200520032002200220034b1b10f8021a200510010c090b200128020021040c060b200128020021040c080b200310002204450d090b20012004360200200141046a2003360200200141086a28020021030b200141086a200341026a360200200420036a20004102744101723b00000f0b200310002204450d070b20012004360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200420036a20004102744102723600000f0b200310002204450d050b20012004360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200420036a20003600000f0b1018000b200341011019000b200341011019000b200341011019000bf42302057f017e02400240024020002802002202450d004101210320024101470d020c010b2001410010240240200041086a220229030022074202520d00200141001024200041106a2903002001109c01200229030021070b024002402007a722024101460d002002450d0141012103200028020022024101460d020c030b41a881c300104f000b41a881c300104f000b200120031024200041086a200110c402200028020021020b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020024102470d002001410210240240024002400240200041086a220328020022024102460d0020024103460d010c020b2001410010242000410c6a200110a401200041306a290300200041386a2903002001109a01200328020022024103470d010b2001410110242000410c6a200110a401200041306a290300200041386a2903002001109a01200041c0006a290300200041c8006a2903002001109a01200041086a28020022024101470d010c030b20024101460d020b2002450d08200028020021020b20024103470d06200141031024200041086a22032d000022024102470d05200141001024200141046a2802002204200141086a28020022026b41204f0d01200241206a22052002490d2420044101742202200520052002491b22024100480d242004450d0220012802002106200210002205450d0e2005200620022004200420024b1b10f8021a200610010c030b41c4aec300104f000b200128020021050c020b200210002205450d0b0b20012005360200200141046a2002360200200141086a28020021020b200141086a200241206a360200200520026a220241186a200341196a290000370000200241106a200341116a290000370000200241086a200341096a2900003700002002200329000137000020032d000021020b0240200241ff01714103470d00200141011024200041106a2903002001109c01200041086a2d000021020b0240200241ff01714104470d002001410210240240024002400240200141046a280200200141086a2802002202470d00200241016a22052002490d2320024101742204200520052004491b22044100480d232002450d0120012802002106200410002205450d0e2005200620042002200220044b1b10f8021a200610010c020b200128020021050c020b200410002205450d0c0b20012005360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200520026a200341016a2d00003a000020032d000021020b200241ff017122024101460d022002450d03200028020021020b024020024104470d0020014104102402400240200041086a22032d00002202410f714103460d0020024102470d012001410010240c010b2001410110242000410c6a2802002001101b20032d000021020b0240200241ff01714104470d002001410210242000410c6a200110a401200041086a2d000021020b0240200241ff01714105470d002001410310242000410c6a2802002001101b200041086a2d000021020b0240200241ff01714106470d002001410410242000410c6a2802002001101b200041206a2802002001101b200041106a290300200041186a2903002001109a01200041086a2d000021020b0240200241ff01714107470d00200141051024200041106a2903002001109c01200041086a2d000021020b0240200241ff01714108470d00200141061024200041106a2903002001109c01200041086a2d000021020b0240200241ff01714109470d002001410710242000410c6a2802002001101b200041086a2d000021020b0240200241ff0171410a470d002001410810240240024002400240200141046a280200200141086a2802002202470d00200241016a22032002490d2320024101742205200320032005491b22054100480d232002450d0120012802002104200510002203450d0f2003200420052002200220054b1b10f8021a200410010c020b200128020021030c020b200510002203450d0d0b20012003360200200141046a2005360200200141086a28020021020b200141086a200241016a360200200320026a200041096a2d00003a0000200041086a2d000021020b0240200241ff0171410b470d002001410910242000410c6a2802002001101b200041086a2d000021020b2002410f7122024101460d042002450d05200028020021020b024020024105470d002001410510240240200041086a22032d000022024102470d002001410010242000410c6a2802002001101c200041106a290300200041186a2903002001109a0120032d000021020b0240200241ff01714103470d002001410110242000410c6a2802002001101b200041086a2d000021020b0240200241ff01714104470d002001410210242000410c6a2802002001101b0240024002400240200141046a280200200141086a2802002202470d00200241016a22032002490d2320024101742205200320032005491b22054100480d232002450d0120012802002104200510002203450d102003200420052002200220054b1b10f8021a200410010c020b200128020021030c020b200510002203450d0e0b20012003360200200141046a2005360200200141086a28020021020b200141086a200241016a360200200320026a200041096a2d00003a0000200041086a2d000021020b0240200241ff01714105470d002001410310242000410c6a2802002001101c024002400240200041096a2d000022024101460d0020024102470d012001410210240c020b2001410110240c010b2001410010240b200041106a29030020011023200041086a2d000021020b0240200241ff01714106470d002001410410242000410c6a2802002001101b200041086a2d000021020b0240200241ff01714107470d00200141051024200041106a290300200110232000410c6a2802002001108901200041086a2d000021020b200241077122024101460d062002450d07200028020021020b20024106470d1c20014106102402400240200041086a220328020022024102460d0020024103460d010c0d0b2001410010242000410c6a280200200041146a2802002001108d01200041186a2802002001101b200328020022024103470d0c0b2001410110242000410c6a2802002001101b200041106a200110a401200041346a2802002001101b200041386a2802002001101b200041086a28020022024104470d0c0c0d0b41c4aec300104f000b41acd5c200104f000b41acd5c200104f000b41a8ccc200104f000b41a8ccc200104f000b41a8e6c200104f000b41a8e6c200104f000b200241011019000b200441011019000b200541011019000b200541011019000b20024104460d010b20024105460d010c020b2001410210242000410c6a2802002001101b200041086a28020022024105470d010b2001410310242000410c6a2802002001101b200041086a28020022024106470d010c020b20024106460d010b20024107460d010c020b2001410410242000410c6a200110a401200041386a290300200041c0006a2903002001109a01200041306a2802002001101b200041086a28020022024107470d010b2001410510242000410c6a2802002001101b41082103200041086a28020022024108470d010c020b4108210320024108460d010b20024109460d010c020b2001410610242000410c6a200110a401200020036a28020022024109470d010b200141071024200041106a2903002001109c01200041086a2802002202410a470d010c020b2002410a460d010b20024101460d010c020b200141081024200041106a2903002001109c01200041086a28020022024101470d010b41d09fc300104f000b2002450d02200028020021020b024020024107470d002001410710240240200041086a22032d000022024102470d002001410010242000410c6a2802002001101c20032d000021020b0240200241ff01714103470d00200141011024200341016a2001101e0240024002400240200141046a280200200141086a2802002202470d00200241016a22052002490d0620024101742204200520052004491b22044100480d062002450d0120012802002106200410002205450d0d2005200620042002200220044b1b10f8021a200610010c020b200128020021050c020b200410002205450d0b0b20012005360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200520026a200341216a2d00003a000020032d000021020b0240200241ff01714104470d00200141021024200341016a2001101e20032d000021020b0240200241ff01714105470d00200141031024200041106a2903002001109c01200041086a2d000021020b0240200241ff01714106470d00200141041024200041106a2903002001109c01200041086a2d000021020b200241ff017122024101460d032002450d04200028020021020b024020024108470d00200141081024024020002d000422024102470d00200141001024200041086a2802002001101b2000410c6a2802002001101c20002d000421020b0240200241ff01714103470d00200141011024200041046a220341016a2001101e200041286a2802002001101b0240024002400240200141046a280200200141086a2802002202470d00200241016a22052002490d0620024101742204200520052004491b22044100480d062002450d0120012802002106200410002205450d0e2005200620042002200220044b1b10f8021a200610010c020b200128020021050c020b200410002205450d0c0b20012005360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200520026a200341216a2d00003a000020032d000021020b200241037122024101460d052002450d06200028020021020b024020024109470d0020014109102402400240200028020422024102460d002002450d0920024101470d014180e8c200104f000b200141001024200041086a280200200041106a2802002001108e010b200028020021020b2002410a470d122001410a102402400240200041086a220328020022024102460d0020024103460d010c0b0b200141001024200041306a290300200041386a2903002001109a012000410c6a200110a401200328020022024103470d0a0b200141011024200041106a290300200041186a2903002001109a01200041086a28020022024104470d0a0c0b0b1018000b41d09fc300104f000b41c081c300104f000b41c081c300104f000b418cabc200104f000b418cabc200104f000b4180e8c200104f000b200441011019000b200441011019000b20024104460d010b20024105460d010c020b2001410210242000410c6a2802002001108901200041186a290300200041206a2903002001109a01200041286a2903002001109c01200041106a2802002001108901200041086a28020022024105470d010b2001410310242000410c6a2802002001101b200041086a28020022024106470d010c020b20024106460d010b20024101460d010c020b2001410410242000410c6a2802002001101b200041086a28020022024101470d010b41c0ccc200104f000b2002450d01200028020021020b02402002410b470d002001410b10240240200041086a22032d000022024102470d00200141001024200341016a2001101e200041386a290300200041c0006a2903002001109a01200041c8006a2903002001109c012000412c6a280200200041346a2802002001108e0120032d000021020b0240200241ff01714103470d00200141011024200041286a290300200041306a2903002001109a01200041386a2903002001109c012000410c6a280200200041146a2802002001108e01200041186a280200200041206a2802002001108e01200041086a2d000021020b200241037122024101460d022002450d03200028020021020b02402002410c470d002001410c1024024020002d000422024102470d00200141001024200041086a280200200041106a2802002001108e010f0b024020024103470d00200141011024200041046a220041016a2001101e20002d000021020b200241037122014101460d042001450d050b0f0b41c0ccc200104f000b4188a8c200104f000b4188a8c200104f000b41d8ccc200104f000b41d8ccc200104f000bb00301087f230041206b2202240020024100360218200242013703102000280200210320002802082200200241106a101b0240024002402000450d00200041f8006c2104200241186a21050340200341d0006a2802002106024002400240024020022802142207200528020022006b41044f0d00200041046a22082000490d0620074101742200200820082000491b22004100480d062007450d0120022802102109200010002208450d072008200920002007200720004b1b10f8021a200910010c020b200228021021080c020b200010002208450d050b2002200036021420022008360210200528020021000b2005200041046a360200200820006a20063600002003200241106a101c200341d4006a200241106a101e200341f8006a2103200441887f6a22040d000b0b200241106a41086a2203280200210820022802142107200228021021002001280204210520012802002104200342003703002002420037031020042005200241106a1002200241086a2003290300370300200220022903103703002002411020002008100302402007450d00200010010b200241206a24000f0b1018000b200041011019000b830201047f024002400240024002400240200141046a2802002202200141086a28020022036b41204f0d00200341206a22042003490d0420024101742203200420042003491b22034100480d042002450d0120012802002105200310002204450d052004200520032002200220034b1b10f8021a200510010c020b200128020021040c020b200310002204450d030b20012004360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200420036a220141186a200041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200120002900003700000f0b1018000b200341011019000bb602010a7f230041106b2202240020012802002103200128020822012000101b0240024002402001450d00200141286c2104200041046a2105034020022003102020022802002106024002400240024020052802002207200041086a220828020022016b200241086a28020022094f0d00200120096a220a2001490d0620074101742201200a200a2001491b22014100480d062007450d012000280200210b20011000220a450d07200a200b20012007200720014b1b10f8021a200b10010c020b2000280200210a0c020b20011000220a450d050b2000200a36020020052001360200200828020021010b2008200120096a360200200a20016a2006200910f8021a02402002280204450d00200610010b200341286a2103200441586a22040d000b0b200241106a24000f0b1018000b200141011019000be20302037f017e230041e0006b22022400024002400240024020012d000022034101460d0020030d0241012103200141016a21010c010b2001410c6a2802002104200141046a2802002101410021030b200241086a200436020020022001360204200220033602002000200210ca020c010b2002410036020820024201370300024002400240410110002204450d00200441023a0000200242818080801037020420022004360200410210002203450d01200320042d00003a000020041001200341003a0001200242828080802037020420022003360200200141086a2903002105410a10002204450d02200420032f00003b000020031001200420053700022002428a808080a001370204200220043602002002200141106a1022200241d0006a41086a2201200241086a280200360200200220022903003703502002410c6a2001280200360200200241033a00002002200229035037020420024103360250200220024104723602542000200241d0006a10ca0220022d00002201417f6a4102490d03024020010d00200241086a280200450d0420022802041001200241e0006a24000f0b200241086a280200450d0320022802041001200241e0006a24000f0b410141011019000b410241011019000b410a41011019000b200241e0006a24000bce0101047f024002400240024002400240200041046a2802002202200041086a28020022036b41024f0d00200341026a22042003490d0420024101742203200420042003491b22034100480d042002450d0120002802002105200310002204450d052004200520032002200220034b1b10f8021a200510010c020b200028020021040c020b200310002204450d030b20002004360200200041046a2003360200200041086a28020021030b200041086a200341026a360200200420036a20013b00000f0b1018000b200341011019000bc10201077f20012802002102200128020822012000101b0240024002402001450d002002200141286c6a2103200041086a2104200041046a21050340024002400240024020052802002206200428020022016b41204f0d00200141206a22072001490d0620064101742201200720072001491b22014100480d062006450d0120002802002108200110002207450d072007200820012006200620014b1b10f8021a200810010c020b200028020021070c020b200110002207450d050b2000200736020020052001360200200428020021010b2004200141206a360200200720016a220141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a29000037000020012002290000370000200241206a290300200010232003200241286a2202470d000b0b0f0b1018000b200141011019000bce0101047f024002400240024002400240200141046a2802002202200141086a28020022036b41084f0d00200341086a22042003490d0420024101742203200420042003491b22034100480d042002450d0120012802002105200310002204450d052004200520032002200220034b1b10f8021a200510010c020b200128020021040c020b200310002204450d030b20012004360200200141046a2003360200200141086a28020021030b200141086a200341086a360200200420036a20003700000f0b1018000b200341011019000bc90101047f024002400240024002400240200041046a280200200041086a2802002202470d00200241016a22032002490d0420024101742204200320032004491b22044100480d042002450d0120002802002105200410002203450d052003200520042002200220044b1b10f8021a200510010c020b200028020021030c020b200410002203450d030b20002003360200200041046a2004360200200041086a28020021020b200041086a200241016a360200200320026a20013a00000f0b1018000b200441011019000bd10101047f024002400240024002400240200041046a2802002203200041086a28020022046b20024f0d00200420026a22052004490d0420034101742204200520052004491b22044100480d042003450d0120002802002106200410002205450d052005200620042003200320044b1b10f8021a200610010c020b200028020021050c020b200410002205450d030b20002005360200200041046a2004360200200041086a28020021040b200041086a200420026a360200200520046a2001200210f8021a0f0b1018000b200441011019000bf10103047f017e017f024002400240024002400240200041046a2802002203200041086a28020022046b20024f0d00200420026a22052004490d0420034101742204200520052004491b2206ad4204862207422088a70d042007a722044100480d042003450d0120002802002108200410002205450d0520052008200420034104742203200320044b1b10f8021a200810010c020b200028020021050c020b200410002205450d030b20002005360200200041046a2006360200200041086a28020021040b200041086a200420026a360200200520044104746a2001200241047410f8021a0f0b1018000b200441081019000bf40201067f02400240024002400240024002400240024002400240200041086a280200220220014f0d00200041046a280200220320026b200120026b22044f0d01200220046a22012002490d0620034101742202200120012002491b22014100480d062003450d0320002802002105200110002202450d072002200520012003200320014b1b10f8021a200510010c040b200220014d0d012002210303402003417f6a2103200141016a22012002490d000c0a0b0b2000280200200222036a21054102210620044102490d030c060b200041086a20023602000f0b200110002202450d030b20002002360200200041046a20013602002002200041086a28020022036a210541022106200441024f0d030b2004450d040c030b1018000b200141011019000b410021010340200520016a41003a0000200120066a2102200141016a2207210120022004490d000b200320076a2103200520076a21050b200541003a0000200341016a21030b200041086a20033602000b840301017f0240024002400240024002400240024002400240024020002802002201410b4b0d0020010e0c0a010a0a0a02030405060a070a0b20002d00044102470d092000410c6a280200450d09200041086a28020010010f0b200041086a10290f0b200041086a2d000022014105460d0520014102470d072000410c6a22002802001028200028020010010f0b200041086a2802004102470d06200041106a280200450d062000410c6a28020010010f0b200041086a2d00004102470d052000410c6a22002802001028200028020010010f0b20002d00044102470d042000410c6a22002802001028200028020010010f0b20002802044102490d032000410c6a280200450d03200041086a28020010010f0b200041086a2d000022014102490d0220014102470d01200041306a280200450d022000412c6a28020010010f0b2000410c6a22002802001028200028020010010f0b0240200041106a280200450d002000410c6a28020010010b2000411c6a280200450d00200041186a28020010010f0b0bd80101027f024002400240024002402000280200220141064b0d0020010e0704040104020403040b02402000410c6a2802002202450d0020002802042101200241186c210203400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141186a2101200241686a22020d000b0b200041086a280200450d03200041046a28020010010f0b200041086a280200450d02200028020410010f0b200041086a280200450d01200028020410010f0b200041086a280200450d00200028020410010f0b0bf60d01067f0240024002400240024002400240024002400240024002400240024020002d00002201410d4b0d00024020010e0e0002030405060708090e0a0b0c0d000b200041086a280200450d0d200041046a28020010010f0b0240200041086a280200450d00200041046a28020010010b0240200041146a2802002201450d00200041186a280200450d00200110010b200041246a280200450d0c200041206a28020010010f0b0240200041086a280200450d00200041046a28020010010b200041146a280200450d0b200041106a28020010010f0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d00200128020010010b200141106a2101200241706a22020d000b0b200041086a280200450d0a200041046a28020010010f0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101200241586a22020d000b0b200041086a280200450d09200041046a28020010010f0b200041086a280200450d08200041046a28020010010f0b200041086a280200450d07200041046a28020010010f0b200041086a280200450d06200041046a28020010010f0b02402000410c6a2802002201450d00200041046a280200220320014104746a21040340024020032802082202450d0020032802002101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200241706a22020d000b0b200341106a21010240200341046a280200450d00200328020010010b2001210320012004470d000b0b200041086a280200450d05200041046a28020010010f0b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d00200128020010010b200141146a21012002416c6a22020d000b0b200041086a280200450d04200041046a28020010010f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200241706a22020d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b2001210320012004470d000b0b200041086a280200450d03200041046a28020010010f0b02402000410c6a2802002201450d00200041046a2802002203200141186c6a210403400240200341046a280200450d00200328020010010b0240200341146a2802002202450d00200328020c2101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200241706a22020d000b0b200341186a21010240200341106a280200450d002003410c6a28020010010b2001210320012004470d000b0b200041086a280200450d02200041046a28020010010f0b02402000410c6a2802002201450d00200041046a28020022032001411c6c6a2104034002402003410c6a2802002202450d0020032802042101200241047421020340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200241706a22020d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b2001210320012004470d000b0b200041086a280200450d01200041046a28020010010f0b024002400240200041046a2d000022014102460d0020014101460d0120010d022000410c6a280200450d03200041086a28020010010f0b0240200041146a2802002201450d002000410c6a280200220520014104746a210603402005220441106a2105024020042802042201450d0002402004410c6a2802002202450d002002410c6c21020340024020012802002203450d00200141046a280200450d00200310010b2001410c6a2101200241746a22020d000b0b200441086a280200450d00200441046a28020010010b20052006470d000b0b200041106a280200450d022000410c6a28020010010c020b0240200041146a2802002202450d002000410c6a28020021012002410c6c21020340024020012802002203450d00200141046a280200450d00200310010b2001410c6a2101200241746a22020d000b0b200041106a280200450d012000410c6a28020010010f0b2000410c6a280200450d00200041086a28020010010f0b0b5c01027f024020012802082202417f4c0d0020012802002101024002402002450d002002100022030d01200241011019000b410121030b20032001200210f80221012000200236020820002002360204200020013602000f0b102c000b05001018000b8a0303027f017e067f230041106b2202240002400240024020012802082203ad2204421e88a70d002004420286a72205417f4c0d0020012802002101024002402005450d002005100022060d01200541041019000b410421060b200241086a2001200120034102746a102e024002400240024002402003200228020c2207200228020822016b41027622054f0d0020034101742208200520052008491b2209ad4202862204422088a70d062004a722054100480d062003450d0120051000220a450d07200a2006200520034102742203200320054b1b10f8021a200610014100210620012007470d020c030b200321092006210a4100210620012007470d010c020b20051000220a450d054100210620012007460d010b200a210303402001280200220528020041016a220841014d0d022005200836020020032005360200200641016a2106200341046a21032007200141046a2201470d000b0b20002006360208200020093602042000200a360200200241106a24000f0b00000b102c000b1018000b200541041019000b100020002002360204200020013602000b7103017f017e027f024020012802082202ad42287e2203422088a70d002003a72204417f4c0d0020012802002101024002402004450d002004100022050d01200441081019000b410821050b20052001200410f80221042000200236020820002002360204200020043602000f0b102c000be00101077f024020002802082201200028020c460d000340200041086a22022001411c6a36020020012802042203450d01200141146a2802002104200141086a28020021052001280210210602402001410c6a2802002201450d0020014104742107200321010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200741706a22070d000b0b02402005450d00200310010b02402004450d00200610010b200228020022012000410c6a280200470d000b0b02402000280204450d00200028020010010b0be10101077f024020002802082201200028020c460d00200041086a21022000410c6a210303402002200141186a36020020012802002204450d01200141146a2802002105200141106a2802002106200128020c210702402001280204450d00200410010b02402005450d0020054104742105200721010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b02402006450d00200710010b200228020022012003280200470d000b0b02402000280204450d00200028020010010b0bc60101067f024020002802082201200028020c2202460d00200041086a210303402003200141106a2204360200024020012802042205450d002001280208210602402001410c6a2802002201450d002001410c6c2104200521010340024020012802002202450d00200141046a280200450d00200210010b2001410c6a2101200441746a22040d000b0b02402006450d00200510010b2000410c6a2802002102200328020021040b2004210120042002470d000b0b02402000280204450d00200028020010010b0bcd0101067f024020002802082201200028020c460d00200041086a21022000410c6a210303402002200141106a3602002001410d6a2d00004102460d012001280204210420012802002105024020012802082201450d0020014104742106200521010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200641706a22060d000b0b02402004450d00200510010b200228020022012003280200470d000b0b02402000280204450d00200028020010010b0bba0705027f017e0c7f027e037f230041f0006b22022400200241086a2001103502400240024002400240024002400240024002402002280208450d00200228020c2203ad2204421b88a70d032004420586a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241f0006a24000f0b4101210620030d030b410021054100210c0c030b102c000b200541011019000b200241d0006a41186a2107200241d0006a41106a2108200141046a21094100210a4100210b410021052003210c03402007420037030020084200370300200241d0006a41086a220d420037030020024200370350200141086a220e410020012802002009280200200241d0006a4120200e2802001004220f200f417f461b220f4120200f4120491b200e2802006a360200200f411f4d0d02200241306a41186a220e2007290300370300200241306a41106a220f2008290300370300200241306a41086a2210200d290300370300200220022903503703302007200e29030022043703002008200f2903002211370300200d20102903002212370300200241106a41086a22132012370300200241106a41106a22142011370300200241106a41186a2215200437030020022002290330220437031020022004370350200720152903002204370300200820142903002211370300200d2013290300221237030020102012370300200f2011370300200e20043703002002200229031022043703302002200437035002402005200c470d00200b200541016a220d200d200b491b220cad4205862204422088a70d042004a7220d4100480d0402402005450d00200d10002213450d0620132006200d200a200a200d4b1b10f802210d20061001200d21060c010b200d10002206450d050b2006200a6a220d2002290330370000200d41186a200e290300370000200d41106a200f290300370000200d41086a2010290300370000200a41206a210a200b41026a210b200541016a22052003490d000b0b2000200c36020420002006360200200041086a2005360200200241f0006a24000f0b200241d0006a41186a2205200241306a41186a290000370300200241d0006a41106a2207200241306a41106a290000370300200241d0006a41086a2208200241306a41086a290000370300200220022900303703502005200241106a41186a2900003703002007200241106a41106a2900003703002008200241106a41086a29000037030020022002290010370350200041003602000240200c450d00200610010b200241f0006a24000f0b1018000b200d41011019000bcc0301057f230041106b2202240041002103200241003a000f200128020020012802042002410f6a410120012802081004210420012001280208200441016a220441014b6a220536020802400240024020044102490d0002400240024020022d000f22064103712204450d0020044101460d0120044102470d0220024100360208200220063a000841012103200141086a220441002001280200200141046a280200200241086a41017241032005100422012001417f461b22014103200141034922011b20042802006a36020020010d04200228020841027621040c050b20064102762104410121030c040b41002103200241003b0106200220063a00062001280200200141046a280200200241066a4101724101200510042104200141086a22012001280200200441016a220141014b6a36020020014102490d0120022f01064102762104410121030c030b200641044f0d02200141046a28020021044100210320024100360200200141086a2206410020012802002004200241042005100422012001417f461b22014104200141044922011b20062802006a36020020010d0020022802002104410121030c020b0c010b410021030b2000200436020420002003360200200241106a24000bae0605027f017e0c7f027e017f230041f0006b22022400200241086a2001103502400240024002400240024002400240024002402002280208450d00200228020c2203ad2204421b88a70d032004420586a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241f0006a24000f0b4101210620030d030b410021054100210c0c030b102c000b200541011019000b200241d0006a41186a2107200241d0006a41106a2108200141046a21094100210a4100210b410021052003210c03402007420037030020084200370300200241d0006a41086a220d420037030020024200370350200141086a220e410020012802002009280200200241d0006a4120200e2802001004220f200f417f461b220f4120200f4120491b200e2802006a360200200f411f4d0d02200241306a41186a220e2007290300370300200241306a41106a220f2008290300370300200241306a41086a2210200d290300370300200220022903503703302007200e29030022043703002008200f2903002211370300200d20102903002212370300200241106a41086a220f2012370300200241106a41106a220d2011370300200241106a41186a221020043703002002200229033022043703102002200437035002402005200c470d00200b200541016a220e200e200b491b220cad4205862204422088a70d042004a7220e4100480d0402402005450d00200e10002213450d0620132006200e200a200a200e4b1b10f802210e20061001200e21060c010b200e10002206450d050b2006200a6a220e2002290310370000200e41186a2010290300370000200e41106a200d290300370000200e41086a200f290300370000200a41206a210a200b41026a210b200541016a22052003490d000b0b2000200c36020420002006360200200041086a2005360200200241f0006a24000f0b200241d0006a41186a200241306a41186a290000370300200241d0006a41106a200241306a41106a290000370300200241d0006a41086a200241306a41086a29000037030020022002290030370350200041003602000240200c450d00200610010b200241f0006a24000f0b1018000b200e41011019000bf50803027f017e107f230041e0026b22022400200241086a200110350240024002400240024002400240024002400240024002402002280208450d00200228020c2203ad42f8007e2204422088a70d032004a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241e0026a24000f0b4108210620030d030b4100210c4100210d0c030b102c000b200541081019000b200241a0016a4104722107200141086a2108200241c0026a41186a2109200241c0026a41106a210a4100210b410021054100210c2003210d0340200141046a220e280200210f20082802002110200241003602f001200841002001280200200f200241f0016a410420101004220f200f417f461b220f4104200f4104491b20082802006a360200200f41034d0d0320022802f0012111200241f0016a2001103820022802f001410d460d03200241a0016a200241f0016a41d00010f8021a20094200370300200a4200370300200241c0026a41086a220f4200370300200242003703c002200841002001280200200e280200200241c0026a41202008280200100422102010417f461b2210412020104120491b20082802006a3602002010411f4d0d02200241306a41186a220e2009290300370300200241306a41106a2212200a290300370300200241306a41086a2213200f290300370300200220022903c00237033020022802a0012110200241d4006a200741cc0010f8021a200241f0016a200241d4006a41cc0010f8021a2009200e290300370300200a2012290300370300200f2013290300370300200220022903303703c0022010410d460d04200241a0016a200241f0016a41cc0010f8021a200241106a41186a220e2009290300370300200241106a41106a2212200a290300370300200241106a41086a2213200f290300370300200220022903c0023703100240200c200d470d00200b200c41016a220f200f200b491b220dad42f8007e2204422088a70d062004a7220f4100480d060240200c450d00200f10002214450d0820142006200f20052005200f4b1b10f802210f20061001200f21060c010b200f10002206450d070b200620056a220f2010360200200f41046a200241a0016a41cc0010f8021a200f41d0006a2011360200200f41ec006a200e290300370200200f41e4006a2012290300370200200f41dc006a2013290300370200200f41d4006a2002290310370200200b41026a210b200541f8006a2105200c41016a220c2003490d000b0b2000200d36020420002006360200200041086a200c360200200241e0026a24000f0b200241a0016a10280b200241f0016a200241d4006a41cc0010f8021a200241c0026a41186a200241306a41186a290300370300200241c0026a41106a200241306a41106a290300370300200241c0026a41086a200241306a41086a290300370300200220022903303703c0020b200041003602000240200c450d002006210f0340200f1028200f41f8006a210f200541887f6a22050d000b0b0240200d450d00200610010b200241e0026a24000f0b1018000b200f41081019000ba55b05037f037e057f047e077f230041b0076b22022400200241003a0090062001280200200128020420024190066a410120012802081004210320012001280208200341016a220341014b6a22043602080240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020034102490d0020022d0090062203410c4b0d0a024020030e0d00090607030a0c080e050d0204000b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a36020020034102490d9a0120022d009006450d0f0c9a010b2000410d360200200241b0076a24000f0b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d7f20022d0090062203450d0e20034101470d7f20024198056a2001109801200228029805450d7f200241a8056a290300210520022903a005210620024188056a2001109901200228028805450d7f200229039005210720024180056a20011035200228028005450d7f2002280284052203417f4c0d81012003450d6d200310002204450d8f0120044100200310f7021a0c6e0b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a22083602004102210420034102490d5320022d009006220941094b0d53024020090e0a53004a4c484f504d5249530b20024198016a20011035200228029801450d53200228029c012203410876210a410321040c4d0b200241003a009006410421032001280200200141046a28020020024190066a4101200410042104200141086a22082008280200200441016a220441014b6a220836020020044102490d1820022d0090062204450d0d20044101470d18200241a8066a4200370300200241a0066a420037030020024190066a41086a4200370300200242003703900641042103200141086a220441002001280200200141046a28020020024190066a41202008100422012001417f461b22014120200141204922011b20042802006a36020020010d17200220022f0091063b01be0520022d009006210820022800930621042002290097062107200229009f06210520022800a706210b20022800ab06210920022d00af06210c200220022f01be0522013b019006200220013b01bc05200220013b01ba05410321030c93010b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a36020020034102490d940120022d009006450d090c94010b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a36020020034102490d0e20022d0090062203450d0c20034101470d0e20024190066a200110a30120022d00900622034102460d0e20022d009306210420022f00910621092002419c066a2902002107200241ac066a2902002105200241a8066a2802002108200241a4066a280200210b2002290294062106200241f0006a20011098012002280270450d0e200241f0006a41106a290300210d2002290378210e200241d8006a20011098012002280258450d0e20092004411074722101200241e8006a290300210f41032104200229036021100c0d0b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d3420022d0090062203450d1120034101460d1020034102470d34200241003a009006410421032001280200200141046a28020020024190066a4101200410042104200141086a22012001280200200441016a220141014b6a36020020014102490d3420022d00900621010c120b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d1b20022d009006220341044b0d1b024020030e05001d171916000b20024190066a200110382002280290062101200241e0066a20024190066a41047241cc0010f8021a2001410d460d1b200241c0056a200241e0066a41cc0010f8021a41d00010002204450d830120042001360200200441046a200241c0056a41cc0010f8021a410221030c1a0b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d7320022d009006220841054b0d734103210b024020080e0600662829262c000b200241106a200110352002280210450d7320022802142204417f4c0d7a2004450d61200410002203450d850120034100200410f7021a0c620b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d4e20022d009006220341054b0d4e024020030e06002c292a262d000b20024190066a200110382002280290062104200241e0066a20024190066a41047241cc0010f8021a2004410d460d4e200241c0056a200241e0066a41cc0010f8021a41d00010002203450d820120032004360200200341046a200241c0056a41cc0010f8021a20024180026a2001109801200229038002a7450d4d20024190026a29030021052002290388022107410221040c2d0b2000410d360200200241b0076a24000f0b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a36020020034102490d6620022d009006220341084b0d66024020030e090037343533383a363b000b20024190066a2001103d2002280290062203450d662002290294062107200241b0026a2001103520022802b002450d6520022802b40221012007420888210d2003410876210c2007a72104410221110c3c0b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d2020022d009006220341044b0d20024020030e05001e1c1d13000b200241e0036a200110980120022802e003450d20200241f0036a290300210720022903e803210520024190066a200110a3014102210420022d00900622034102460d20200241ac066a2902002106200241a4066a290200210d20022f009106210120022d0093062108200229029406210e20022002419c066a2902003703e8062002200e3703e0062002200d3703f006200120084110747221010c1f0b200241003a0090062001280200200141046a28020020024190066a4101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d0820022d0090062203450d0720034101470d08200241a8066a4200370300200241a0066a420037030020024190066a41086a4200370300200242003703900641042103200141086a220841002001280200200141046a28020020024190066a41202004100422042004417f461b22044120200441204922041b20082802006a36020020040d17200220022f0091063b01e00620022d009006210c2002280093062104200229009f06210720022800a706211120022800ab06211220022d00af0621132002290097062105200220022f01e00622083b019006200220083b01bc05200241d0036a2001103520022802d003450d1820022802d4032108200241003a009006410421032001280200200141046a28020020024190066a4101200141086a22012802001004210b20012001280200200b41016a220b41014b6a360200200b4102490d182005422088a7210b2005a7210120022d0090062109200220022f01bc053b01be05410321030c190b200241d8036a2001103520022802d803450d8a0120022802dc032203417f4c0d742003450d4a200310002204450d7920044100200310f7021a0c4b0b200220011099012002290300a7450d8a012002290308210720004100360200200041106a2007370300200041086a4202370300200241b0076a24000f0b200241a8066a420037030020024190066a41106a420037030020024190066a41086a4200370300200242003703900641042108200141086a220341002001280200200141046a28020020024190066a41202004100422042004417f461b22044120200441204922041b20032802006a36020020040d09200220022f0091063b01e00620022d009006210b2002280093062104200229009706210f200229009f06211020022800a706210920022800ab06210c20022d00af062111200220022f01e00622033b019006200220033b01bc05200241e0046a200110980120022802e004450d64200241e0046a41106a290300210d20022903e8042107200241d0046a200110990120022802d004450d6420022903d804210e200241c8046a2001103520022802c804450d6420022802cc042203417f4c0d722003450d62200310002212450d810120124100200310f7021a0c630b200241b0056a2001103520022802b005450d2720022802b4052208417f4c0d712008450d4c200810002211450d7720114100200810f7021a0c4d0b20024190066a200110a3014102210420022d00900622034102460d0120022d009306210920022f009106210c2002419c066a2902002107200241ac066a2902002105200241a8066a2802002108200241a4066a280200210b2002290294062106200241c0006a20011098012002280240450d01200c2009411074722101200241c0006a41106a290300210d2002290348210e0b200020013b000d200041023602002000410f6a20014110763a0000200041c8006a200f370200200041c0006a2010370200200041386a200d370200200041306a200e370200200041186a2007370000200041106a2006370000200041286a2005370000200041246a2008360000200041206a200b3600002000410c6a20033a0000200041086a2004360200200241b0076a24000f0b2000410d360200200241b0076a24000f0b200241c8036a2001103520022802c803450d0020022802cc03210420024190066a200110382002280290062103200241e0066a20024190066a41047241cc0010f8021a2003410d470d260b200220022f01be053b0190060c81010b20024188016a2001109901200229038801a7450d232002290390012207422088a721092007a7210c410321030c010b200241a8066a4200370300200241a0066a420037030020024190066a41086a42003703002002420037039006200141086a220341002001280200200141046a28020020024190066a41202004100422012001417f461b22014120200141204922011b20032802006a36020020010d21200220022f0091063b01e00620022d00900621012002280093062111200229009f06210720022800a706210b20022800ab06210420022d00af0621082002290097062105200220022f01e00622033b019006200220033b01bc05200220033b01be05200220022f01be0522033b01c005200220033b01ba052005422088a721092005a7210c410221030b200220022f01ba0522123b019006200220123b01b805200020013a0009200041086a20033a000020004103360200200041286a20083a0000200041246a2004360200200041206a200b360200200041186a2007370200200041146a2009360200200041106a200c3602002000410c6a2011360200200020022f01b8053b000a200241b0076a24000f0b200220022f01e0063b0190060c660b200220022f01be053b0190060b0c790b200241b8036a200110990120022903b803a7450d0520022903c0032207422088a721012007a72108410621030c030b200241a8066a4200370300200241a0066a420037030020024190066a41086a4200370300200242003703900641042103200141086a220841002001280200200141046a28020020024190066a41202004100422012001417f461b22014120200141204922011b20082802006a36020020010d3c200220022f0091063b01e00620022d009006210b2002280093062104200229009f06210720022800a706210920022800ab06210c20022d00af0621112002290097062105200220022f01e00622013b019006200220013b01bc05200220013b01be052005422088a721012005a721080c420b200241c0046a2001103520022802c004450d0d20022802c40422034108762101410621040c0b0b200241a8036a200110990120022903a803a7450d0220022903b0032207422088a721012007a72108410521030b0b200220022f01be053b0190060c400b200220022f01be053b0190060c710b200241a8066a4200370300200241a0066a420037030020024190066a41086a42003703002002420037039006200141086a220341002001280200200141046a220828020020024190066a41202004100422042004417f461b22044120200441204922041b20032802006a221236020020040d37200220022f0091063b01e00620022d009006210b20022800930621042002290097062105200229009f06210720022800a706210920022800ab06210c20022d00af062111200220022f01e00622133b019006200220133b01c005200241003a0090062001280200200828020020024190066a410120121004210120032003280200200141016a41014b22016a3602002001450d3b20022d0090062112200220022f01c0053b01be052005422088a721012005a72108410321030c3d0b200220022f01e0063b0190060b0b200220022f01be053b01900620034104460d700c150b200141046a28020021032002410036029006200141086a220841002001280200200320024190066a41042004100422032003417f461b22034104200341044922031b20082802006a36020020030d042002280290062103200241a0046a200110980120022802a004450d04200241b0046a290300210720022903a804210520024190046a2001109901200228029004450d04200229039804210641042104200141046a280200210b200141086a220828020021092002410036029006200841002001280200200b20024190066a41042009100422012001417f461b22014104200141044922011b20082802006a36020020010d042002280290062101200241f0066a2007370300200220053703e806200220013602e006200341087621010c030b200241b8046a2001103520022802b804450d0320022802bc0422034108762101410521040c010b200241f8036a200110980120022903f803a7450d0220024188046a290300210720022002290380043703e006200220073703e806410321040b0b20024190066a41106a200241e0066a41106a290300220d37030020024190066a41086a200241e0066a41086a290300220e370300200241c0056a41086a2208200e370300200241c0056a41106a220b200d370300200220022903e006220d3703c0052002200d37039006200041386a2007370200200041306a20053702002000410c6a2001410874200341ff017172360200200041086a20043602002000410a360200200041286a2006370200200041106a20022903c005370200200041186a2008290300370200200041206a200b290300370200200241b0076a24000f0b20024190066a41106a200241e0066a41106a29030037030020024190066a41086a200241e0066a41086a290300370300200220022903e006370390062000410d360200200241b0076a24000f0b200241206a200110352002280220450d4d20022802242204417f4c0d542004450d37200410002203450d6020034100200410f7021a0c380b200241a8026a2001103520022802a802450d284106210420022802ac0221030c070b200241186a200110352002280218450d4b200228021c2204417f4c0d522004450d37200410002203450d5f20034100200410f7021a0c380b2002420037039006200141086a220341002001280200200141046a28020020024190066a41082004100422012001417f461b22014108200141084922011b20032802006a36020020010d4a20022903900621074105210b0c3c0b200241a0026a2001103520022802a002450d2520022802a4022103200241003a009006410421042001280200200141046a28020020024190066a4101200141086a22012802001004210820012001280200200841016a41014b22086a3602002008450d2520022d00900621080c050b20024190066a200110382002280290062104200241e0066a20024190066a41047241cc0010f8021a2004410d460d24200241c0056a200241e0066a41cc0010f8021a41d00010002203450d5920032004360200200341046a200241c0056a41cc0010f8021a200241003a0090062001280200200141046a28020020024190066a4101200141086a22042802001004210820042004280200200841016a220841014b6a220b36020020084102490d2320022d009006220841034f0d23420021052002420037039006200141086a220441002001280200200141046a28020020024190066a4108200b100422012001417f461b22014108200141084922011b20042802006a36020020010d232002290390062107410521040c040b200241386a200110352002280238450d47200228023c2213ad220742187e2205422088a70d4e2005a72204417f4c0d4e2004450d372004100022030d38200441041019000b20024198026a20011035200228029802450d2241032104200228029c0221030c010b2002420037039006200141086a220341002001280200200141046a220828020020024190066a41082004100422042004417f461b22044108200441084922041b20032802006a220b36020020040d212002290390062107200828020021042002410036029006200341002001280200200420024190066a4104200b100422012001417f461b2201410420014104491b20032802006a360200200141034d0d21200228029006210342002105410721040b0b200220022f01be0522013b019006200220013b01bc05200041186a2005370200200041106a2007370200200020083a0009200041086a20043a0000200041053602002000410c6a2003360200200020022f01bc053b000a200241b0076a24000f0b410021040c2b0b200220022f01e0063b019006200220022f01be053b01c0050b200220022f01ba053b0190062000410d360200200241b0076a24000f0b200241c0056a200241e0066a41cc0010f8021a41d00010002201450d4d20012003360200200141046a200241c0056a41cc0010f8021a200220022f01be053b019006410221030b200220022f0190063b01ba052000200c3a0005200020033a000420004108360200200041286a2008360200200020093a0025200041246a20133a0000200041206a20123602002000411c6a2011360200200041146a2007370200200041106a200b3602002000410c6a2001360200200041086a2004360200200020022f01ba053b0006200241b0076a24000f0b20024190066a200110a30120022d00900622034102460d3320022d009306210420022f00910621092002419c066a290200210d200241ac066a2902002107200241a8066a2802002108200241a4066a280200210b200229029406210e200241e8026a200110980120022802e802450d33200241e8026a41106a290300210620022903f0022105200241e0026a2001103520022802e002450d332009200441107472210c200d422088a72113200da7210120022802e4022112200e420888210d200ea72104410621110c0a0b200241d0026a2001103520022802d002450d3220022802d4022203410876210c410421110c040b200241d8026a2001103520022802d802450d3120022802dc022203410876210c410521110c030b20024188036a2001109901200229038803a7450d302002290390032207420888210d2007a72104410921110c050b200241c8026a2001103520022802c802450d2f20022802cc02210320024190066a200110a30120022d00900622044102460d2f2002419c066a2902002107200241ac066a2902002105200241a4066a2802002108200220022902940622063700e306200241eb066a2007370000200220022d0093063a00e206200220022f0091063b01e0062002200241a8066a2802003602c005200220053702c405200241c0026a2001103520022802c002450d2f20022802c4022109200241b8026a2001103520022802b802450d2f2005422088a721122006422088a721012007422088a7210b2007a721132003410876210c20023502e00620023301e40620023100e6064210868442208684210d20022903c005210720022802bc02ad210542002106410321110c060b20024180036a20011035200228028003450d2e2002280284032203410876210c410721110b0c030b20024190066a200110a30120022d00900622034102460d2c2002290294062205420888210d20022f00910620022d00930641107472210c2002419c066a2902002206422088a72113200241a4066a280200210b200241a8066a2802002108200241ac066a29020021072005a721042006a72101410821110c030b20024198036a2001109901200229039803a7450d2b20022903a0032207420888210d2007a72104410a21110b0b0b20004106360200200041c0006a2006370200200041386a2005370200200041346a2009360200200041306a2012360200200041286a2007370200200041246a2008360200200041206a200b3602002000411c6a2013360200200041186a2001360200200041086a20113602002000410c6a200c410874200341ff017172360200200041106a200d4208862004ad42ff018384370200200241b0076a24000f0b200241c8016a2001103520022802c801450d0b20022802cc012103200241c0016a2001103520022802c001450d0b20022802c401210b200241a8016a200110980120022903a801a7450d0b200241b8016a29030021072003410876210a20022903b0012205a72114410621040c020b200241f8016a2001103520022802f801450d0a20022802fc012203410876210a410b21040c040b20024190066a200110a30120022d00900622034102460d092002419c066a290200210720022f00910620022d00930641107472210a200241ac066a2902002205422088a721132005421088a721122005420888a72115200241a4066a280200210b200241a8066a280200210c2005a721112002290294062205a72114410421040b2005422088a721160c070b200241a0016a2001103520022802a001450d0720022802a4012203410876210a410521040c010b200241f0016a2001103520022802f001450d0620022802f4012203410876210a410921040b0c040b200241d0016a200110990120022903d001a7450d0420022903d8012207422088a721162007a72114410721040c010b200241e0016a200110990120022903e001a7450d0320022903e8012207422088a721162007a72114410821040b0c010b200241003a0090062001280200200141046a28020020024190066a4101200810042103200141086a22012001280200200341016a220141014b6a36020020014102490d0120022d0090062117410a21040b200220022f01e00622013b019006200220013b01c005200020173a0009200041086a20043a0000200041043602002000412c6a2013360200200020123b012a200020153a0029200041286a20113a0000200041246a200c360200200041206a200b360200200041186a2007370200200041146a2016360200200041106a20143602002000410c6a200a410874200341ff017172360200200020022f01c0053b000a200241b0076a24000f0b200220022f01e0063b0190062000410d360200200241b0076a24000f0b200310a001200310010b200220022f01be053b0190062000410d360200200241b0076a24000f0b410121040b200141086a2208200341002001280200200141046a280200200420032008280200100422012001417f461b2201200120034b1b20082802006a3602000240200320014d0d00200410010c3f0b2004450d3e20004289808080203703002000410c6a2003ad2207422086200784370200200041086a2004360200200241b0076a24000f0b200220022f01e0063b0190060c010b200220022f01e0063b0190060b410721030c040b410121110b41002104200141086a220b200841002001280200200141046a28020020112008200b280200100422012001417f461b2201200120084b1b200b2802006a3602002008ad220742208620078421070240200820014d0d00201110010c060b2011450d0441022103201121040c360b410721030b0b200220022f01be053b01900620034107460d320b200220022f0190063b01ba052000200b3a0009200041086a20033a000020004107360200200020123a0029200041286a20113a0000200041246a200c360200200041206a2009360200200041186a2007370200200041146a2001360200200041106a20083602002000410c6a2004360200200020022f01ba053b000a200241b0076a24000f0b201121040b0c300b410121030b200141086a2208200441002001280200200141046a280200200320042008280200100422012001417f461b2201200120044b1b20082802006a360200200420014b0d132003450d142004ad220742208620078421074106210b0c060b410121030b4104210b200141086a2208200441002001280200200141046a280200200320042008280200100422012001417f461b2201200120044b1b20082802006a360200200420014b0d112003450d122004ad220742208620078421070c040b410121030b200141086a2208200441002001280200200141046a280200200320042008280200100422012001417f461b2201200120044b1b20082802006a360200200420014b0d0f2003450d102004ad220742208620078421074102210b0c020b410421030b02402013450d00200141086a2108200141046a2111410021120340200241306a200110352002280230450d0e20022802342204417f4c0d17024002402004450d0020041000220b450d1b200b4100200410f7021a0c010b4101210b0b20082004410020012802002011280200200b20042008280200100422092009417f461b2209200920044b1b20082802006a360200200420094b0d0d200b450d0e2004ad22054220862005842105200241286a200110352002280228450d0c200228022c2204417f4c0d17024002402004450d00200410002209450d1c20094100200410f7021a0c010b410121090b200820044100200128020020112802002009200420082802001004220c200c417f461b220c200c20044b1b20082802006a3602002004200c4b0d0b2009450d0c02402007422088a7220c2007a7470d00200c41016a2215200c490d19200c410174220a20152015200a491bad220642187e220d422088a70d19200da722154100480d1902400240200c450d0020151000220a450d1e200a20032015200c41186c220c200c20154b1b10f802210c20031001200c21030c010b201510002203450d1d0b20074280808080708320068421070b20032007422088a741186c6a220c200936020c200c2005370204200c200b360200200c41106a2004ad220542208620058437020020074280808080107c2107201241016a22122013490d000b0b2003450d0e4107210b0b20004101360200200041106a20073702002000410c6a2003360200200041086a200b360200200241b0076a24000f0b410121040b200141086a2208200341002001280200200141046a2802002004200320082802001004220b200b417f461b220b200b20034b1b20082802006a3602002003200b4b0d0f2004450d102003ad220d422086200d84210f200241f8046a2001103520022802f804450d0e20022802fc042203417f4c0d122003450d0c200310002208450d2220084100200310f7021a0c0d0b2007a7450d00200310010b2000410d360200200241b0076a24000f0b410121120b41042108200141086a2213200341002001280200200141046a280200201220032013280200100422012001417f461b2201200120034b1b20132802006a3602000240200320014d0d00201210010c010b2012450d00200220022f01bc053b01c0052003ad2205422086200584220542088842088620054238862012ad4218868422064238888421052011ad42ff01832006420886842106410221080c010b0b200220022f01c0053b01900620084104460d0b0c1d0b200910010b2005a7450d010b200b10010b02402007422088a72201450d00200141186c21042003210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141186a2101200441686a22040d000b0b2007a7450d010b200310010b2000410d360200200241b0076a24000f0b410121080b200141086a220b200341002001280200200141046a28020020082003200b280200100422012001417f461b2201200120034b1b200b2802006a3602000240200320014d0d00200810010c010b2008450d00200220022f01c0053b0190062003ad220d422086200d84220d4220862008ad842110200d422088a72109410321080c150b200fa7450d010b200410010b200220022f01c0053b0190060b2000410d360200200241b0076a24000f0b102c000b1018000b200441011019000b200441011019000b201541041019000b200341011019000b200841011019000b41d00041081019000b41d00041081019000b41d00041081019000b41d00041081019000b200441011019000b200441011019000b200441011019000b200341011019000b200341011019000b200341011019000b200220022f0190063b01be05200041c0006a200d370000200041386a2007370000200041306a2005370000200041286a20063700002000200b3a0009200041086a20083a00002000410b360200200041c8006a200e370000200041246a200c360000200041206a2009360000200041186a2010370000200041106a200f3700002000410c6a2004360000200020022f01be053b000a200241b0076a24000f0b2000410d360200200241b0076a24000f0b0b20024190066a41026a2201200241e0066a41026a2d00003a0000200220022f01ba053b01be05200220022f00e0063b019006024020034104470d002000410d360200200241b0076a24000f0b200241c0056a41026a221120012d00003a0000200220022f01be053b01b805200220022f0190063b01c005200020083a0005200020033a00042000410c360200200041246a200c3a0000200041206a20093600002000411c6a200b360000200041146a20053700002000410c6a2007370000200041086a2004360000200020022f01b8053b0006200020022f01c0053b0025200041276a20112d00003a0000200241b0076a24000f0b2000410d360200200241b0076a24000f0b2000410d360200200241b0076a24000f0b2000410d360200200241b0076a24000bb50705027f017e0c7f027e037f230041f0006b22022400200241086a2001103a02400240024002400240024002400240024002402002280208450d00200228020c2203ad2204421b88a70d032004420586a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241f0006a24000f0b4101210620030d030b410021054100210d0c030b102c000b200541011019000b200241d0006a41186a2107200241d0006a41106a2108200241d0006a41086a2109200141046a210a4100210b4100210c410021052003210d034020074200370300200842003703002009420037030020024200370350200241d0006a2001280200220e200a280200220f4120200f4120491b221010f8021a200a200f20106b3602002001200e20106a360200200f411f4d0d02200241306a41186a220f2007290300370300200241306a41106a22102008290300370300200241306a41086a220e2009290300370300200220022903503703302007200f29030022043703002008201029030022113703002009200e2903002212370300200241106a41086a22132012370300200241106a41106a22142011370300200241106a41186a2215200437030020022002290330220437031020022004370350200720152903002204370300200820142903002211370300200920132903002212370300200e201237030020102011370300200f20043703002002200229031022043703302002200437035002402005200d470d00200c200541016a22132013200c491b220dad4205862204422088a70d042004a722134100480d0402402005450d00201310002214450d06201420062013200b200b20134b1b10f802211320061001201321060c010b201310002206450d050b2006200b6a22132002290330370000201341186a200f290300370000201341106a2010290300370000201341086a200e290300370000200b41206a210b200c41026a210c200541016a22052003490d000b0b2000200d36020420002006360200200041086a2005360200200241f0006a24000f0b200241d0006a41186a2205200241306a41186a290000370300200241d0006a41106a220f200241306a41106a290000370300200241d0006a41086a2207200241306a41086a290000370300200220022900303703502005200241106a41186a290000370300200f200241106a41106a2900003703002007200241106a41086a29000037030020022002290010370350200041003602000240200d450d00200610010b200241f0006a24000f0b1018000b201341011019000bcb0301077f230041106b22022400200241003a0003200241036a2001280200220320012802042204410047220510f8021a0240024020042005490d00200141046a200420056b22063602002001200320056a22053602000240024002402004450d000240024020022d000322034103712204450d00024020044101460d0020044102470d0241002104200241003a000e200241003b010c2002410c6a200520064103200641034922071b220810f8021a200141046a200620086b3602002001200520086a36020020070d0520022f010c20022d000e411074724108742003724102762101410121040c050b200241003a000b2002410b6a20052006410047220410f8021a20062004490d06200141046a200620046b3602002001200520046a3602002006450d0220022d000b4108742003724102762101410121040c040b20034102762101410121040c030b200341044f0d004100210420024100360204200241046a200520064104200641044922081b220310f8021a200141046a200620036b3602002001200520036a36020020080d0120022802042101410121040c020b410021040b0b2000200136020420002004360200200241106a24000f0b20052004107a000b20042006107a000bdb0303027f017e097f230041106b2202240020022001103502400240024002400240024002400240024002402002280200450d0020022802042203ad2204421e88a70d032004420286a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241106a24000f0b4104210620030d030b410021054100210a0c030b102c000b200541041019000b200141086a21074100210841002109410021052003210a0340200141046a280200210b2007280200210c2002410036020c200741002001280200200b2002410c6a4104200c1004220b200b417f461b220b4104200b410449220b1b20072802006a360200200b0d02200228020c210b02402005200a470d002009200541016a220c200c2009491b220aad4202862204422088a70d042004a7220c4100480d0402402005450d00200c1000220d450d06200d2006200c20082008200c4b1b10f802210c20061001200c21060c010b200c10002206450d050b200620086a200b360200200841046a2108200941026a2109200541016a22052003490d000b0b2000200a36020420002006360200200041086a2005360200200241106a24000f0b200041003602000240200a450d00200610010b200241106a24000f0b1018000b200c41041019000bf50705027f017e0e7f027e017f23004190016b22022400200241086a20011035024002400240024002400240024002400240024002402002280208450d00200228020c2203ad42287e2204422088a70d032004a72205417f4c0d032005450d01200510002206450d042003450d020c050b2000410036020020024190016a24000f0b4108210620030d030b4100210c4100210d0c030b102c000b200541081019000b200241f0006a41186a2107200241f0006a41106a2108200141046a21094100210a4100210b4100210c2003210d03402007420037030020084200370300200241f0006a41086a220e420037030020024200370370200141086a2205410020012802002009280200200241f0006a412020052802001004220f200f417f461b220f4120200f4120491b20052802006a2210360200200f411f4d0d02200241d0006a41186a220f2007290300370300200241d0006a41106a22112008290300370300200241d0006a41086a2212200e290300370300200220022903703703502007200f2903002204370300200820112903002213370300200e20122903002214370300200241306a41086a22112014370300200241306a41106a22122013370300200241306a41186a2215200437030020022002290350220437033020022004370370200242003703702005410020012802002009280200200241f0006a410820101004220f200f417f461b220f4108200f4108491b20052802006a360200200f41074d0d0320022903702104200241106a41186a22052015290300370300200241106a41106a220f2012290300370300200241106a41086a2210201129030037030020022002290330370310200720052903003703002008200f290300370300200e2010290300370300200220022903103703700240200c200d470d00200a200c41016a22052005200a491b220dad42287e2213422088a70d052013a722054100480d050240200c450d0020051000220f450d07200f20062005200b200b20054b1b10f802210520061001200521060c010b200510002206450d060b2006200b6a22052002290370370300200541186a2007290300370300200541106a2008290300370300200541086a200e290300370300200541206a2004370300200a41026a210a200b41286a210b200c41016a220c2003490d000b0b2000200d36020420002006360200200041086a200c36020020024190016a24000f0b200241f0006a41186a200241d0006a41186a290000370300200241f0006a41106a200241d0006a41106a290000370300200241f0006a41086a200241d0006a41086a290000370300200220022900503703700b200041003602000240200d450d00200610010b20024190016a24000f0b1018000b200541081019000b9203010a7f230041106b22022400200220011035024002400240024002400240024002402002280200450d0020022802042203417f4c0d062003450d01200310002204450d07200141046a2105200141086a2106410021074100210820032109034020082108200241003a000f200128020020052802002002410f6a410120062802001004210a20062006280200200a41016a220a41014b6a360200200a4102490d0420022d000f210a024020082009470d002007200841016a220920092007491b22094100480d0602402008450d0020091000220b450d08200b200420092008200820094b1b10f802210b20041001200b21040c010b200910002204450d070b200420086a200a3a0000200741026a2107200841016a22082003490d000c030b0b20004100360200200241106a24000f0b4101210441002108410021090b2000200936020420002004360200200041086a2008360200200241106a24000f0b2000410036020002402009450d00200410010b200241106a24000f0b1018000b200941011019000b102c000b200341011019000b8d0606027f017e0b7f017e027f017e230041d0006b22022400200241086a200110350240024002400240024002400240024002402002280208450d00200228020c2203ad42307e2204422088a70d032004a72205417f4c0d032005450d01200510002206450d042003450d020c050b20004100360200200241d0006a24000f0b4108210620030d030b4100210c4100210d0c030b102c000b200541081019000b200141046a2107200141086a2108200241306a41186a21094100210a4100210b4100210c2003210d0240034020024200370338200242003703302008410020012802002007280200200241306a41102008280200100422052005417f461b2205411020054110491b20082802006a220e3602002005410f4d0d01200241306a41086a220f29030021042002290330211020094200370300200241306a41106a22114200370300200f4200370300200242003703302008410020012802002007280200200241306a4120200e100422052005417f461b2205412020054120491b20082802006a3602002005411f4d0d01200241106a41186a22052009290300370300200241106a41106a220e2011290300370300200241106a41086a2212200f29030037030020022002290330370310200920052903003703002011200e290300370300200f2012290300370300200220022903103703300240200c200d470d00200a200c41016a22052005200a491b220dad42307e2213422088a70d042013a722054100480d040240200c450d0020051000220e450d06200e20062005200b200b20054b1b10f802210520061001200521060c010b200510002206450d050b2006200b6a2205200437030820052010370300200541286a2009290300370300200541206a2011290300370300200541186a200f290300370300200541106a2002290330370300200a41026a210a200b41306a210b200c41016a220c2003490d000c020b0b200041003602000240200d450d00200610010b200241d0006a24000f0b2000200d36020420002006360200200041086a200c360200200241d0006a24000f0b1018000b200541081019000bc70201057f0240024002400240024002400240200041046a2802002202200028020822036b20012802042204200128020022056b22064f0d00200320066a22052003490d0420024101742203200520052003491b22034100480d042002450d0120002802002105200310002206450d052006200520032002200220034b1b10f8021a200510010c020b2000280200210620052004470d020c050b200310002206450d030b20002006360200200041046a2003360200200041086a280200210320012802002205200141046a280200460d030b2001200541016a36020020052d00002105200141046a210202400340200620036a20053a0000200128020022052002280200460d01200341016a21032001200541016a36020020052d000021050c000b0b200041086a200341016a3602000f0b1018000b200341011019000b200041086a20033602000bc20307017f017e047f017e037f027e027f230041c0006b2202240020012902002103410021040240024002400240024002400240200128020c2205200128020822066b2201450d0020014105752207ad42287e2208422088a70d022008a722094100480d0220091000220a450d0320062005470d010c040b4108210a4100210720062005460d030b200141606a410576210b200a21010340200641186a2900002108200641106a290000210c2006290000210d200241206a41086a2204200641086a290000370300200241206a41106a2209200c370300200241206a41186a220e2008370300200241086a220f2004290300370300200241106a22042009290300370300200241186a2209200e2903003703002002200d37032020022002290320370300200141186a2009290300370000200141106a2004290300370000200141086a200f29030037000020012002290300370000200141206a4201370300200141286a21012005200641206a2206470d000b200b41016a210420034280808080105a0d030c040b1018000b200941081019000b2003428080808010540d010b2003a710010b20002004360208200020073602042000200a360200200241c0006a24000ba90705037f017e0b7f027e037f230041e0006b22032400410021040240024002400240024002400240024020022001200220014b1b20016b2205450d002005ad42287e2206422088a70d062006a722074100480d06200710002208450d07200220014b0d010c020b4108210841002105200220014d0d010b200341c0006a41186a2109200341c0006a41106a210a200821042001210b03402003200b360200410e10002207450d042003420e37024420032007360240200341c0006a41d79bc100410e1025200341206a41086a220d200341c0006a41086a220728020036020020032003290340370320200341206a2003410410252003280224210c0240024002402003280220220e200d280200220f4188f0c100410041001004417f470d004200210620094200370300200a42003703002007420037030020034200370340200b41016a210b200c0d010c020b20094200370300200a42003703002007420037030020034200370340200e200f200341c0006a4120410010042210417f460d042010411f4d0d04200341206a41186a22102009290300370300200341206a41106a2211200a290300370300200d200729030037030020032003290340370320200920102903002206370300200a201129030022123703002007200d2903002213370300200341086a22142013370300200341106a22152012370300200341186a221620063703002003200329032022063703002003200637034020034200370340200e200f200341c0006a41084120100441016a41084d0d052003290340210620092016290300370300200a20152903003703002007201429030037030020032003290300370340201020092903003703002011200a290300370300200d20072903003703002003200329034037032020092010290300370300200a20112903003703002007200d29030037030020032003290320370340200b41016a210b200c450d010b200e10010b20042003290340370300200441186a2009290300370300200441106a200a290300370300200441086a2007290300370300200441206a2006370300200441286a21042002200b470d000b200220016b21040b200020043602082000200536020420002008360200200341e0006a24000f0b200341c0006a41186a200341206a41186a290000370300200341c0006a41106a200341206a41106a290000370300200341c0006a41086a200341206a41086a290000370300200320032900203703400b41eac4c10041331042000b410e41011019000b1018000b200741081019000b7201017f230041306b220224002002200136020c20022000360208200241246a41013602002002411c6a41013602002002410136022c200241e0c3c10036021820024101360214200241f89fc2003602102002200241086a3602282002200241286a360220200241106a4180a0c2001071000bed0104017e047f017e027f20012902002102410021030240024002400240024002400240200128020c2204200128020822016b2205450d0020054102752206ad4202862207422088a70d022007a722084100480d02200810002209450d0320012004470d010c040b410421094100210620012004460d030b2005417c6a410276210520092103034020032001280200360200200341046a21032004200141046a2201470d000b200541016a210320024280808080105a0d030c040b1018000b200841041019000b2002428080808010540d010b2002a710010b2000200336020820002006360204200020093602000bfc0102057f047e200220016b220341286e210441082105410021064100210702400240024020034128490d002004ad42287e2208422088a70d012008a722034100480d01200310002205450d02200421070b024020012002460d0041002106200521030340200141086a2903002108200141106a2903002109200141186a290300210a2001290300210b200341206a200141206a290300370300200341186a200a370300200341106a2009370300200341086a20083703002003200b370300200341286a2103200641016a21062002200141286a2201470d000b0b2000200636020820002007360204200020053602000f0b1018000b200341081019000bb20101057f200220016b2203410c6e21044104210541002106410021070240024002402003410c490d00200441037422034100480d01200310002205450d02200421070b024020012002460d004100210620052103034020012802002104200341046a200141086a28020036020020032004360200200341086a2103200641016a21062001410c6a22012002470d000b0b2000200636020820002007360204200020053602000f0b1018000b200341041019000bee0605037f017e0b7f027e027f230041e0006b2203240041002104024002400240024002400240024020022001200220014b1b20016b2205450d002005ad4205862206422088a70d052006a722074100480d05200710002208450d06200220014b0d010c020b4101210841002105200220014d0d010b200341206a41186a2109200341206a41106a210a200821042001210b03402003200b360200410610002207450d032003420637024420032007360240200341c0006a41bab6c10041061025200341206a41086a2207200341c0006a41086a220d28020036020020032003290340370320200341206a2003410410252003280224210c0240024002402003280220220e2007280200220f4188f0c100410041001004417f470d0020094200370300200a42003703002007420037030020034200370320200b41016a210b200c0d010c020b200341c0006a41186a22104200370300200341c0006a41106a22114200370300200d420037030020034200370340200e200f200341c0006a412041001004220f417f460d04200f411f4d0d0420092010290300370300200a20112903003703002007200d290300370300200320032903403703202010200929030022063703002011200a2903002212370300200d20072903002213370300200341086a220f2013370300200341106a22142012370300200341186a22152006370300200320032903202206370300200320063703402010201529030037030020112014290300370300200d200f29030037030020032003290300370340201520102903002206370300201420112903002212370300200f200d290300221337030020072013370300200a20123703002009200637030020032003290340220637030020032006370320200b41016a210b200c450d010b200e10010b20042003290320370000200441186a2009290300370000200441106a200a290300370000200441086a2007290300370000200441206a21042002200b470d000b200220016b21040b200020043602082000200536020420002008360200200341e0006a24000f0b200341c0006a41186a200341206a41186a290000370300200341c0006a41106a200341206a41106a290000370300200341c0006a41086a200341206a41086a2900003703002003200329002037034041eac4c10041331042000b410641011019000b1018000b200741011019000bf10903027f047e037f230041d0006b2102024002400240024002400240024002400240024020012d002022034101460d0020034102470d0120012802142203200141186a280200460d02200141146a200341206a360200200241286a41186a200341186a2900002204370300200241286a41106a200341106a2900002205370300200241286a41086a200341086a2900002206370300200020032900002207370308200041106a2006370300200041186a2005370300200041206a2004370300200041286a2001411c6a28020029030037030020022007370328200042013703000f0b20012802102208450d02200141106a4100360200024020012802082203200128020c2209460d002008417f73210a0340200141086a200341286a2208360200200241286a41206a200341206a290300370300200241286a41186a200341186a290300370300200241286a41106a200341106a290300370300200241286a41086a200341086a29030037030020022003290300370328200a41016a220a450d072008210320092008470d000b0b200042003703000f0b20012802102208450d02200141106a410036020020012802082203200128020c2209460d032008417f73210a0340200141086a200341286a2208360200200241286a41206a200341206a290300370300200241286a41186a200341186a290300370300200241286a41106a200341106a290300370300200241286a41086a200341086a29030037030020022003290300370328200a41016a220a450d062008210320092008470d000c040b0b200042003703000f0b20012802082202200128020c460d05200141086a200241286a360200200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a29030037030020002002290300370308200042013703000f0b20012802082203200128020c460d00200141086a200341286a360200200241206a200341206a290300370300200241186a200341186a290300370300200241106a200341106a290300370300200241086a200341086a290300370300200220032903003703000c030b200141206a41023a0000024020012802142203200141186a280200460d00200141146a200341206a360200200241286a41186a200341186a2900002204370300200241286a41106a200341106a2900002205370300200241286a41086a200341086a2900002206370300200020032900002207370308200041106a2006370300200041186a2005370300200041206a2004370300200041286a2001411c6a28020029030037030020022007370328200042013703000f0b200042003703000f0b2000200229032837030820004201370300200041286a200241286a41206a290300370300200041206a200241286a41186a290300370300200041186a200241286a41106a290300370300200041106a200241306a2903003703000f0b200241206a200241286a41206a290300370300200241186a200241286a41186a290300370300200241106a200241286a41106a290300370300200241086a200241286a41086a290300370300200220022903283703000b2000200229030037030820004201370300200041106a200241086a290300370300200041186a200241106a290300370300200041206a200241186a290300370300200041286a200241206a2903003703000f0b200042003703000b978501050a7f017e447f037e017f230022032104200341e0096b41607122032400024002400240024002400240024002400240024002400240024002400240024002400240411010002205450d00200541063a0000412010002206450d01200641063a001020064100360204200620032f00a0063b00012006412d3a0000200641036a200341a2066a2d00003a0000024020052d00004109470d00200528020841ffffffff0371450d00200528020410010b20051001200141086a2107200141106a2802002208412c6c21052001280208220941586a210a02400240024002400240024002400240024003402005450d01200541546a2105200a41286a210b200a412c6a220c210a200b2d00004107470d000b200320032f0190053b01a006200c41046a280200200c41086a2802002205470d01200541016a220a2005490d182005410174220b200a200a200b491b2208ad420486220d422088a70d18200da7220b4100480d182005450d05200c2802002109200b1000220a450d0f200a2009200b200541047422052005200b4b1b10f8021a200910010c060b41101000220a450d0c200a4180023b010c200a428280808020370204200a2006360200200a20032f0190053b010e2001410c6a2802002008470d03200841016a22052008490d172008410174220b20052005200b491b220bad422c7e220d422088a70d17200da722054100480d172008450d0120051000220c450d0d200c200920052008412c6c2206200620054b1b10f802210520091001200521090c020b200c280200210a0c050b200510002209450d0b0b2001410c6a200b360200200141086a20093602000b200141106a200841016a220e36020020092008412c6c6a220520032f00b0033b0001200541073a000020054281808080103700082005200a360004200520032902a006370210200541036a200341b2036a2d00003a0000200541186a200341a8066a290200370200200541206a200341a0066a41106a290200370200200541286a200341a0066a41186a2802003602004100210f0c030b200b1000220a450d090b200c200a360200200c41046a2008360200200c41086a28020021050b200a20054104746a22054180023b010c200542828080802037020420052006360200200520032f01a0063b010e200c41086a2205200528020041016a360200200341306a200c10492003280234417f6a210f200141106a280200210e200141086a28020021090b200e412c6c2105200941586a210a02400340410021082005450d01200541546a2105200a41286a210b200a412c6a220c210a200b2d00004103470d000b200c41086a2802002205450d00200541286c210a200c28020041186a2105410021080340200820052d0000456a2108200541286a2105200a41586a220a0d000b0b200e412c6c2105200941586a210a024003404100210b2005450d01200541546a2105200a41286a210c200a412c6a2206210a200c2d00004103470d000b200641086a2802002205450d00200541286c210a200628020041186a21054100210b0340200b20052d0000456a210b200541286a2105200a41586a220a0d000b0b200e412c6c2105200941606a210a0240024003402005450d01200541546a2105200a41206a210c200a412c6a2206210a200c2d00004104470d000b200628020021050c010b410021050b2005200b6a2210ad220d421e88a70d0e200d420286a72205417f4c0d0e02400240024002400240024002402005450d00200510002211450d0920114100200510f7021a20100d010c020b410421112010450d010b201120104102746a211241002113200141106a2114200141086a2115201121160340024020132008490d0020142802002217412c6c220b21052015280200221841586a220c210a02400340410021062005450d01200541546a2105200a41286a2109200a412c6a220e210a20092d00004103470d000b200e41086a2802002205450d00200541286c210a200e28020041186a2105410021060340200620052d0000456a2106200541286a2105200a41586a220a0d000b0b201320066b220620134b0d040340200b450d04200b41546a210b200c41286a2105200c412c6a220a210c20052d0000410b470d000b200a41086a28020020064d0d05200a280200200641186c6a280208210a200341a0066a20062001104a20032802a406210520032802a0064101460d0620162005200a6a3602000b201341016a2113201641046a22162012470d000b0b200141086a2802002118412c2119200141106a2802002217450d110c100b412c10002205450d06200541286a41002800e38140360000200541206a41002900db8140370000200541186a41002900d38140370000200541106a41002900cb8140370000200541086a41002900c38140370000200541002900bb81403700000c0c0b412c10002205450d09200541286a41002800b78140360000200541206a41002900af8140370000200541186a41002900a78140370000200541106a410029009f8140370000200541086a410029009781403700002005410029008f81403700000c0b0b411e10002205450d09200541166a41002900fd8140370000200541106a41002900f78140370000200541086a41002900ef8140370000200541002900e78140370000429e808080e003210d0c0b0b200341a8066a290300210d2011100120050d0b41002111412c211920170d0c0c0d0b411041081019000b412041081019000b200541041019000b412c41011019000b411041041019000b200541041019000b200b41041019000b412c41011019000b411e41011019000b42ac808080c005210d0b201110010b2000200536020420004101360200200041086a200d3702000c040b2018201720196c6a211a200341b0036a41146a210920034190086a211b200341a0066a410172211c20034184086a211d20034180086a211e200341f0076a211f200341e4076a2120200341e0076a2121200341d4076a2122200341d0076a2123200341c4076a2124200341c0076a2125200341b0076a2126200341a0076a212720034190076a212820034180076a2129200341f4066a212a200341f0066a212b200341e4066a212c200341e0066a212d200341d4066a212e200341d0066a212f200341a0066a41206a2130200341a0066a41106a2131200341b0036a41086a210b200341c8066a2132200341c4066a2133200341d8066a2134200341e8066a2135200341f8066a213620034188076a213720034184076a213820034198076a213920034194076a213a200341a8076a213b200341a4076a213c200341b8076a213d200341b4076a213e200341c8076a213f200341d8076a2140200341e8076a2141200341f8076a2142200341f4076a214320034188086a21440340024020182d0000410b470d00201828020c2205450d0020182802042245200541186c6a214603400240204541146a22082802002205450d002045410c6a21124100210603400240024002400240024002400240024002400240200620054f0d00024002400240024002402012280200200641047422146a22052d0000410b470d002003200541046a22053602a0022011450d062010200528020022054d0d04201120054102746a280200220a450d00201d200f360200201e41133a0000201f41d7003a00002020200a3602002021412d3a00002022200f360200202341123a0000202420053602002025410b3a0000202641063a0000202741003a000020284184083b0100202941373a0000202a2002360200202b412d3a0000202c200f360200202d41123a0000202e200f360200202f41133a0000203041d6003a0000200341a0066a41146a2247200a3602002031412d3a0000201c20032f00b0033b0000201c41026a200341b0036a41026a2d00003a0000200341123a00a0062003200f3602a40620082802002215200641016a2217490d072008200636020020122802002105200341b0036a41186a2216201b360200200341b0036a41106a22482012360200200b200520146a221341106a220e360200200320173602b003200341b0036a410c6a224920052017410474224a6a224b3602002009200341a0066a3602002003201520176b224c3602b403200e2105024020132d0000220c41ac01460d00410021050340201320056a210a0240200c41ff01714109470d00200a41086a28020041ffffffff0371450d00200a41046a28020010010b2005450d03200b200a41206a360200200541106a2105200a41106a2d0000220c41ac01470d000b201320056a41106a21050b2005204b470d020c030b410121050c0c0b200a41106a2205204b460d010b0340200b2005220a41106a220536020002400240200a2d0000220c4109460d00200c41ac01470d010c030b200a41086a28020041ffffffff0371450d00200a41046a28020010010b200e2005470d000b0b02400240204c450d00201720452802142205470d01201b2214200341a0066a220a6b41047622050d080c070b20122009104b200b28020022052049280200220e470d090c080b2014200541047422056b210c201228020020056a2105200341a0066a220a201b460d044100214d0c0a0b200341a0066a41146a4101360200200341a0066a410c6a4101360200200341a0066a41086a41e0c3c1003602002003410236029405203120034190056a360200200341013602a406200341908ec2003602a0062003200341a0026a36029005200341b0036a200341a0066a104d20032802b0032205450d0b20032902b403210d2000200536020420004101360200200041086a200d3702002011450d122010450d12201110010c120b41808ec20020062005104e000b41c380c00041cc001042000b41d08ec200104f000b4104214d0c050b410f214d0c040b4106214d0c030b4121214d0c020b411e214d0c010b4135214d0b034002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240204d0e6a020506030407080f12131517181416191a212425262728292a2b2e2f30313233363738393a3b3e4144474a4d505356595c5f626568696667636460615d5e5a5b5758545551524e4f4b4c4849454642433f403c3d34352c2d01001b1c1d1e1f202322090a0b0c0d0e1110100b200e2205200e470d85010c84010b200a41106a2205200e470d82010c81010b2009200a41106a3602000c6c0b200541106a2105200c41706a210c2009280200220a2016280200470d6a4104214d0cb2010b4100210a4101214d0cb1010b20034190056a200a105020032d00900541ac01460d6a4102214d0cb0010b2005200329039005370300200541086a20034190056a41086a2903003703002008200828020041016a360200200c0d6a4105214d0caf010b201628020022142009280200220a6b4104762205450d6a4106214d0cae010b2048280200220e41046a224b280200221320156b20054f0d6a41e200214d0cad010b201520056a220c2015490db40141e300214d0cac010b20134101742215200c200c2015491b224ead420486220d422088a70db30141e400214d0cab010b200da722154100480db20141e500214d0caa010b2013450da70141e600214d0ca9010b200e280200214f20151000220c450d5c41e700214d0ca8010b200c204f201520134104742213201320154b1b10f8021a204f10010ca6010b200e280200210c0c640b20151000220c450d5941e800214d0ca5010b200e200c360200204b204e3602004108214d0ca4010b200c201720056a22134104746a200c204a6a204c41047410f9021a200320133602b0032013200e280208220c460d624109214d0ca3010b200620056a410474200c41047422056b210c200e28020020056a2105200a2014470d630c620b200541106a2105200c41706a210c2009280200220a2016280200460d57410a214d0ca1010b2009200a41106a3602000c570b4100210a410b214d0c9f010b20034190056a200a105020032d00900541ac01460d60410c214d0c9e010b2005200329039005370300200541086a20034190056a41086a290300370300200e41086a220a200a28020041016a360200200c0d60410f214d0c9d010b20034190056a41086a22054100360200200342083703900520034190056a2009104b20032802900522152005280200220a41047422136a210e200328029405214b20152105200a450d604110214d0c9c010b2048280200221441046a224a280200221620032802b403221720032802b003220a6a22056b2013410475220c4f0d6041da00214d0c9b010b2005200c6a224c2005490da20141db00214d0c9a010b20164101742205204c204c2005491b224ead420486220d422088a70da10141dc00214d0c99010b200da7224c4100480da00141dd00214d0c98010b2016450d930141de00214d0c97010b2014280200214f204c10002205450d4b41df00214d0c96010b2005204f204c201641047422162016204c4b1b10f8021a204f10010c92010b201428020021050c5a0b204c10002205450d4841e000214d0c93010b20142005360200204a204e3602004112214d0c92010b2005200a200c6a220c41047422166a2005200a4104746a201741047410f9021a2003200c3602b00320152105200c2014280208220a460d584113214d0c91010b2014280200220520166a214c2005200a4104746a210c2015210a4114214d0c90010b2013450d584115214d0c8f010b20034190056a41026a2205200a41036a2d00003a00002003200a2f00013b019005200a2d0000221641ac01460d584116214d0c8e010b200a41046a290200210d200a410c6a2802002117200c20163a0000200c410c6a2017360200200c41046a200d37020020032f0190052116200c41036a20052d00003a0000200c41016a20163b0000201441086a2205200528020041016a360200201341706a2113200a41106a2205210a200c41106a220c204c470d554117214d0c8d010b2005200e460d584118214d0c8c010b20052d0000220a4109460d5c4119214d0c8b010b200a41ac01470d5d0c5c0b200541086a28020041ffffffff0371450d5d41d700214d0c89010b200541046a2802001001411a214d0c88010b200541106a2205200e470d52411b214d0c87010b204b450d5b411c214d0c86010b20151001411d214d0c85010b200b28020022052049280200220e460d5b411e214d0c84010b200b2005220a41106a2205360200200a2d0000220c4109460d5b411f214d0c83010b200c41ac01470d5c0c5b0b200a41086a28020041ffffffff0371450d5c41d500214d0c81010b200a41046a28020010014120214d0c80010b200e2005470d554121214d0c7f0b20032802b4032205450d5a4122214d0c7e0b20032802b003220e2048280200221341086a220c280200220a460d5a4123214d0c7d0b20132802002213200a4104746a2013200e4104746a200541047410f9021a4124214d0c7c0b200c2005200a6a3602004125214d0c7b0b20032d00a0064109470d5841d200214d0c7a0b200341a0066a41086a28020041ffffffff0371450d5841d300214d0c790b20032802a40610014126214d0c780b20312d00004109470d5741d000214d0c770b200341a0066a41186a28020041ffffffff0371450d5741d100214d0c760b204728020010014127214d0c750b20302d00004109470d5641ce00214d0c740b203228020041ffffffff0371450d5641cf00214d0c730b203328020010014128214d0c720b202f2d00004109470d5541cc00214d0c710b203428020041ffffffff0371450d5541cd00214d0c700b202e28020010014129214d0c6f0b202d2d00004109470d5441ca00214d0c6e0b203528020041ffffffff0371450d5441cb00214d0c6d0b202c2802001001412a214d0c6c0b202b2d00004109470d5341c800214d0c6b0b203628020041ffffffff0371450d5341c900214d0c6a0b202a2802001001412b214d0c690b20292d00004109470d5241c600214d0c680b203728020041ffffffff0371450d5241c700214d0c670b20382802001001412c214d0c660b20282d00004109470d5141c400214d0c650b203928020041ffffffff0371450d5141c500214d0c640b203a2802001001412d214d0c630b20272d00004109470d5041c200214d0c620b203b28020041ffffffff0371450d5041c300214d0c610b203c2802001001412e214d0c600b20262d00004109470d4f41c000214d0c5f0b203d28020041ffffffff0371450d4f41c100214d0c5e0b203e2802001001412f214d0c5d0b20252d00004109470d4e413e214d0c5c0b203f28020041ffffffff0371450d4e413f214d0c5b0b202428020010014130214d0c5a0b20232d00004109470d4d413c214d0c590b204028020041ffffffff0371450d4d413d214d0c580b202228020010014131214d0c570b20212d00004109470d4c413a214d0c560b204128020041ffffffff0371450d4c413b214d0c550b202028020010014132214d0c540b201f2d00004109470d4b4138214d0c530b204228020041ffffffff0371450d4b4139214d0c520b204328020010014133214d0c510b201e2d00004109470d4a4136214d0c500b204428020041ffffffff0371450d4a4137214d0c4f0b201d28020010014134214d0c4e0b410f21054135214d0c4d0b200520066a220620082802002205490d4d0c4e0b201541081019000b204c41081019000b410e214d0c490b410b214d0c480b4100214d0c470b4101214d0c460b411d214d0c450b4103214d0c440b410f214d0c430b4107214d0c420b4108214d0c410b410f214d0c400b410e214d0c3f0b410a214d0c3e0b411d214d0c3d0b410d214d0c3c0b4117214d0c3b0b4111214d0c3a0b4112214d0c390b4117214d0c380b4114214d0c370b41d900214d0c360b41d800214d0c350b4118214d0c340b411b214d0c330b411b214d0c320b4118214d0c310b411b214d0c300b4118214d0c2f0b41d600214d0c2e0b411b214d0c2d0b411a214d0c2c0b411a214d0c2b0b411d214d0c2a0b411e214d0c290b4121214d0c280b41d400214d0c270b4121214d0c260b4120214d0c250b4120214d0c240b4125214d0c230b4124214d0c220b4126214d0c210b4126214d0c200b4127214d0c1f0b4127214d0c1e0b4128214d0c1d0b4128214d0c1c0b4129214d0c1b0b4129214d0c1a0b412a214d0c190b412a214d0c180b412b214d0c170b412b214d0c160b412c214d0c150b412c214d0c140b412d214d0c130b412d214d0c120b412e214d0c110b412e214d0c100b412f214d0c0f0b412f214d0c0e0b4130214d0c0d0b4130214d0c0c0b4131214d0c0b0b4131214d0c0a0b4132214d0c090b4132214d0c080b4133214d0c070b4133214d0c060b4134214d0c050b4134214d0c040b41e100214d0c030b41e000214d0c020b41e900214d0c010b41e800214d0c000b0b0b204541186a22452046470d000b0b201820196a2218201a470d000b0b200341386a41106a2205200141106a280200360200200341386a41086a222d200141086a290200370300200320012902003703382005280200222520196c2105202d280200222341586a210a0240024003402005450d01200541546a2105200a41286a210b200a20196a220c210a200b2d00004108470d000b200341286a200c104920032802282105200328022c210a0c010b410021050b200a410020051b21082025412c6c210a202341586a210b20054188f0c10020051b2105024002400340200a450d01200a41546a210a200b41286a210c200b412c6a2206210b200c2d0000410a470d000b200341206a200610492003280220210a2003280224210b0c010b4100210a0b2003420037028405200341e8bdc00036028005200a4188f0c100200a1b2214200b4100200a1b411c6c6a212b2005200841146c6a210b200341a0066a410c6a2130200341a0066a41086a211c410021272005210a4100211e410021154100210e4100215041042148410421294104215141042117034002400240024002400240024002400240024002400240024002400240024002400240024002400240201541ff0171220c4102460d000240200c4101470d000340200b200a460d09200a410c6a210c200a41146a2205210a200c2802000d000b410121152005210a20032005417c6a280200220c36025c20110d070c0f0b0340200b2005460d022005410c6a210c200541146a220a2105200c2802000d000b41002115200a21052003200a417c6a280200220c36025c20110d060c0e0b2031210c201e4101470d01200c201f460d010c040b2031210c20274101470d01200c201f460d010c020b03402014202b460d05200341186a201410512003280218220c450d052014411c6a211441012127200c200c200328021c4102746a221f470d030c000b0b03402014202b460d04200341106a201410512003280210220c450d042014411c6a2114200c200c20032802144102746a221f460d000b0b200c450d02200c41046a21314102211541012127200b2105200b210a4101211e2003200c280200220c36025c20110d010c090b200c450d01200c41046a2131410221154101211e2003200c280200220c36025c2011450d080b2010200c4d0d092011200c4102746a2802002206450d0d02402050200e470d00200e41016a2208200e490d10200e4101742209200820082009491b2250ad420286220d422088a70d10200da722084100480d1002400240200e450d00200810002248450d04204820292008200e4102742209200920084b1b10f8021a202910010c010b200810002248450d030b2048212920482151204821170b2017200e4102746a200c360200200341a0066a200328025c2213200341386a1052201c280200212820032802a406211220032802a00622264101460d082012280208220c417f4c0d0e2012280200210920122d000c211602400240200c450d00200c100022080d010c080b410121080b20082009200c10f80221082012410d6a2d000021092003200636029c012003200328025c360298012003410036029001200320093a008d01200320163a008c012003200c360288012003200c36028401200320083602800102400240200328028005220c41e8bdc000460d00200328028405214c0c010b4194031000220c450d064100214c200c41003b0106200c4100360200200c41086a200341a0066a418c0310f8021a20034100360284052003200c360280050b200e41016a210e024002400340200c41086a2109200c2f010622214102742108417f210602400240024003402008450d01200641016a21064100417f41012009280200221620134b1b20162013461b2216450d052008417c6a2108200941046a210920164101460d000b204c0d010c020b20212106204c450d010b204c417f6a214c200c20064102746a4194036a280200210c0c010b0b20034180056a41086a2208200828020041016a360200200329039801210d200329039001215220032903880121532003290380012154200c2f01062208410b4f0d01200c41086a2209200641016a22164102746a200920064102746a2209200820066b41027410f9021a20092013360200200c41346a220820164105746a200820064105746a2208200c41066a220c2f010020066b41057410f9021a200841186a200d370200200820523702102008205337020820082054370200200c200c2f010041016a3b01000c0d0b200c20064105746a220c41cc006a220629000021522006200329039801370000200c41c4006a2206290000210d2006200329039001370000200c413c6a220629000021532006200329038801370000200c41346a220c2900002154200c20032903800137000020032054370360200320523703782003200d370370200320533703680240200da74102460d002003280264450d00200328026010010b2026450d0e0c0d0b4194031000221b450d04201b41003b0106201b4100360200201b41086a200341a0066a418c0310f8022109200341a0066a41186a2221200c418c026a290200370300200341a0066a41106a222f200c4184026a290200370300201c200c41fc016a2902003703002003200c2902f4013703a006200c280220212e2009200c41246a200c41066a22162f010041796a220841027410f8022109201b41346a200c4194026a200841057410f802214c201641063b0100201b20083b0106200341b0036a41186a22472021290300370300200341b0036a41106a224a202f290300370300200341b0036a41086a2232201c290300370300200320032903a0063703b00302400240200641064b0d00200c41086a2208200641016a22094102746a200820064102746a2216200c41066a22082f010020066b41027410f9021a20162013360200200c41346a221320094105746a201320064105746a220920082f010020066b41057410f9021a200941186a200d3702002009205237021020092053370208200920543702000c010b20092006417a6a22494102746a2009200641796a22164102746a2206200841ffff037120166b41027410f9021a20062013360200204c20494105746a204c20164105746a2206201b41066a22082f010020166b41057410f9021a200641186a200d3702002006205237021020062053370208200620543702000b200820082f010041016a3b010020034190056a41186a221d204729030037030020034190056a41106a2220204a29030037030020034190056a41086a22222032290300370300200320032903b00337039005200341a0026a41186a2224201d290300370300200341a0026a41106a222a2020290300370300200341a0026a41086a222c202229030037030020032003290390053703a00202400240200c2802002216450d00200c2f010421490340201d20242903003703002020202a2903003703002022202c290300370300200320032903a00237039005204941ffff0371211320162f0106220c410a4d0d0241c40310002209450d06200941003b010620094100360200200941086a200341a0066a41bc0310f80221062016280220213420212016418c026a290200370300202f20164184026a290200370300201c201641fc016a290200370300200320162902f4013703a0062006201641246a201641066a224b2f0100220841796a220c41027410f8022135200941346a20164194026a200c41057410f802213620094194036a201641b0036a2008417a6a224c41027410f8022145204b41063b01002009200c3b01060240204c450d004100210c20452106034020062802002208200c3b010420082009360200200641046a2106204c200c41016a220c470d000b0b20472021290300370300204a202f2903003703002032201c290300370300200320032903a0063703b00320212047290300370300202f204a290300370300201c2032290300370300200320032903b0033703a00602400240204941ffff0371220641064b0d00201641086a220c201341016a224c41027422086a200c201341027422496a220c204b2f0100224520136b223541027410f9021a200c202e360200201641346a220c204c4105746a200c20134105746a220c203541057410f9021a200c41186a201d290300370200200c41106a2020290300370200200c41086a2022290300370200200c200329039005370200204b204541016a220c3b010020164194036a224b20496a41086a204b20086a224b200c41ffff03712208204c6b41027410f9021a204b201b360200200620084f0d01201620496a4198036a210c0340200c2802002206201341016a22133b010420062016360200200c41046a210c20082013470d000c020b0b20352013417a6a220841027422496a2035201341796a220c4102746a2206200941066a224c2f0100200c6b41027410f9021a2006202e360200203620084105746a2036200c4105746a2206204c2f0100200c6b41057410f9021a200641186a201d290300370200200641106a2020290300370200200641086a20222903003702002006200329039005370200204c204c2f010041016a22063b010020452013410274224b6a416c6a204520496a224c200641ffff0371221320086b41027410f9021a204c201b360200200820134b0d002009204b6a41fc026a2106034020062802002208200c41016a220c3b010420082009360200200641046a21062013200c470d000b0b20242021290300370300202a202f290300370300202c201c290300370300200320032903a0063703a00202402016280200220c450d0020162f01042149200c21162034212e2009211b0c010b0b2009211b2034212e0b41c4031000220c450d03200c41003b0106200c4100360200200c41086a200341a0066a41bc0310f8022109200c200328028005220636029403200320032802840541016a36028405200641003b01042003200c360280052006200c360200200c200c2f010622084105746a220641cc006a2024290300370200200641c4006a202a2903003702002006413c6a202c290300370200200641346a20032903a002370200200920084102746a202e360200200c4194036a200841016a22064102746a201b360200200c20063b0106201b20063b0104201b200c3602002003410236027020260d0d0c0e0b201641086a2206201341016a220841027422096a20062013410274224c6a2206200c20136b222141027410f9021a2006202e360200201641346a220620084105746a200620134105746a2206202141057410f9021a200641186a201d290300370200200641106a2020290300370200200641086a20222903003702002006200329039005370200201641066a200c41016a220c3b010020164194036a2206204c6a41086a200620096a2206200c41ffff0371220920086b41027410f9021a2006201b360200201320094f0d0b20162008417f6a220c4102746a4198036a2106034020062802002208200c41016a220c3b010420082016360200200641046a21062009200c470d000c0c0b0b200341d0006a41086a20034180056a41086a28020036020020032003290380053703502025412c6c2105202341586a210a024003404100210b2005450d01200541546a2105200a41286a210c200a412c6a2206210a200c2d00004103470d000b200641086a2802002205450d00200541286c210a200628020041186a21054100210b0340200b20052d0000456a210b200541286a2105200a41586a220a0d000b0b2025412c6c2105202341606a210a0240024003402005450d01200541546a2105200a41206a210c200a412c6a2206210a200c2d00004104470d000b200628020021050c010b410021050b200341a0066a41106a2231200341386a41106a280200360200200341a0066a41086a2233200341386a41086a290300370300200320032903383703a00620034180016a200341a0066a1053024002400240024002400240024002400240200e450d002017200e4102746a21372005200b6a2114200341e9046a211c200341b0036a4194016a2115200341ec046a214c20034190086a211320034184086a212c20034180086a211e200341f0076a211f200341a0066a41c4016a212e200341a0066a41c0016a2121200341a0066a41b4016a2147200341a0066a41b0016a2123200341a0066a41a4016a214a200341a0066a41a0016a2125200341a0066a4190016a2126200341a0076a212720034190076a212820034180076a2129200341f4066a2132200341f0066a212b200341e4066a2134200341e0066a212d200341d0066a212f200341a0066a41206a2130200341a0066a41146a2135200341b7036a2139200341b0036a41b8016a2149200341dc046a214b200341b0036a41a8016a213b200341b0036a41c8016a213d20034190056a410c6a213f200341cc026a2140200341a0026a41286a2141200341a0026a41246a2142200341bc026a2144200341b8066a2138200341d8066a213a200341e8066a213c200341f8066a213e20034188076a214320034184076a211920034198076a214e20034194076a211a200341a8076a214f200341a4076a2107200341b8076a2146200341f8076a2118200341f4076a215520034188086a210103402017220541046a21172005280200210c200341d0006a210520032802542109024002400240024002400240024003402005280200220641086a210b20062f0106220e410274210a417f21050240024002400340200a450d01200541016a21054100417f4101200b2802002208200c4b1b2008200c461b2208450d03200a417c6a210a200b41046a210b20084101460d000b20090d010c040b200e21052009450d030b2009417f6a2109200620054102746a4194036a21050c010b0b200641346a20054105746a2216450d002016280218210a201628021c2105202c200f360200201e41133a0000201f41d7003a0000202e20053602002021412d3a00002047200f360200202341123a0000204a200a3602002025410b3a0000202641063a0000202741003a000020284184083b0100202941373a000020322002360200202b412d3a00002034200f360200202d41123a0000200341a0066a41346a2236200f360200202f41133a0000203041d6003a0000203520053602002031412d3a00002003200f3602a406200341123a00a0062016280208220641106a220aad220d421c88a70d1e200d420486a72205417f4c0d1e201641086a2148024002402005450d0020051000220e450d0320482802002206450d010c040b4108210e20060d030b4100210b200a41006b410f490d030c040b41b88ac0004180011042000b200541081019000b4100210c41002105034002402005200a470d00200a41016a220b200a490d1e200a4101742208200b200b2008491b2208ad420486220d422088a70d1e200da7220b4100480d1e02400240200a450d00200b10002209450d0a2009200e200b200a410474220a200a200b4b1b10f802210a200e1001200a210e0c010b200b1000220e450d090b2008210a0b200e200c6a220b410f3a0000200b41046a2005360200200b41036a20034190056a41026a2d00003a0000200b41016a20032f0190053b0000200c41106a210c200541016a220b21052006200b470d000b200a200b6b410f4f0d010b200b410f6a2205200b490d1b200a410174220c20052005200c491b2212ad420486220d422088a70d1b200da722054100480d1b200a450d0120051000220c450d0b200c200e2005200a410474220a200a20054b1b10f8022105200e10012005210e0c020b200a21120c010b20051000220e450d090b200e200b4104746a2105200341a0066a210a0340200b21080240024002400240200a2d00002206417e6a2209412e4b0d0002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020090e2f291c202d2d121d162d1b082d2d0b0a1a2417091319211f0f0e2526031807060d2214230211041e050100152827100c290b200a2d0001210c412b21060c2c0b200a41046a280200210b200a350208210d412a21060c2a0b200a41046a280200210b200a350208210d412521060c290b200a41046a280200210b200a350208210d411d21060c280b200a41046a280200210b200a350208210d412721060c270b200a41046a280200210b200a350208210d412921060c260b200a41046a280200210b200a350208210d412021060c250b200a41046a280200210b200a350208210d411f21060c240b200a41046a280200210b200a2d0001210c410c21060c240b200a41046a280200210b200a350208210d411421060c220b200a41046a280200210b411021060c210b200a41046a280200210b410f21060c200b200a290308210d413021060c1e0b200a41046a280200210b200a350208210d412121060c1e0b200a41046a280200210b200a350208210d411a21060c1d0b200a41046a280200210b200a350208210d411921060c1c0b200a41046a280200210b412f21060c1b0b200a41046a280200210b200a350208210d412621060c1a0b200a41046a280200210b410721060c190b200a41046a280200210b200a350208210d411521060c180b200a41046a280200210b200a350208210d412321060c170b200a2d0001210c412c21060c170b200a2802082206ad220d421e88a70d2f200d420286a7220c417f4c0d2f4104210b0240200c450d00200c1000220b450d1c0b02402006450d00200a41046a280200210c20064102742109200b210603402006200c280200360200200641046a2106200c41046a210c2009417c6a22090d000b0b200a410c6a350200422086200d84210d410921060c150b200a41046a280200210b411321060c140b200a41046a280200210b200a350208210d411e21060c130b200a41046a280200210b200a350208210d411621060c120b200a41046a280200210b411121060c110b200a41046a280200210b410b21060c100b200a2d0001210c410321060c100b200a41046a280200210b410821060c0e0b200a41046a280200210b200a350208210d412821060c0d0b200a41046a280200210b200a350208210d411821060c0c0b200a2d0001210c410421060c0c0b200a41046a280200210b200a350208210d411721060c0a0b200a41046a280200210b200a350208210d412221060c090b200a41046a280200210b200a350208210d412421060c080b200a41046a280200210b411221060c070b200a41046a280200210b200a350208210d411b21060c060b200a41046a280200210b200a350208210d411c21060c050b200a290308210d412e21060c030b200a41046a280200210b412d21060c030b200a2d0001210c410221060c030b0b0b0b2005200c3a0001200520063a0000200541086a200d370300200541046a200b360200200841016a210b200541106a2105200a41106a220a2013470d000b0240024002402012200b470d00201241016a22052012490d1b2012410174220a20052005200a491b220cad420486220d422088a70d1b200da722054100480d1b2012450d0120051000220a450d0c200a200e20052012410474220b200b20054b1b10f8022105200e10012005210e0c020b2012210c200b21120c010b20051000220e450d0a0b200e20124104746a220541063a0000200541086a2039290000370000200520032900b00337000120034190056a20034180016a418c0110f8021a411010002205450d05200541063a000020034180056a41086a220a200341a0026a41086a2206280200360200200341fc046a41026a220b200341dc006a41026a2d00003a0000200320032902a00237038005200320032f005c3b01fc04200341b0036a20034190056a418c0110f8021a204941003a0000200341b0036a41b0016a2209428180808010370300204b2005360200203b4100360200200341b0036a41a0016a22124204370300203d41e0083b0100200341b0036a41c4016a221b4100360200204c4201370200200341b0036a418c016a224542003702002015200329038005370200201541086a200a280200360200201c20032f01fc043b0000201c41026a200b2d00003a000020482802002205417f4c0d172016280200210a024002402005450d0020051000220b0d010c090b4101210b0b203f200b200a200510f802220a20056a36020020034190056a41086a200a36020020032005360294052003200a36029005204c20034190056a105420034190056a200341b0036a418c0110f8021a200341b0036a41c0016a2802002148204c280200211d20492802002120200341b0036a41b4016a280200210a20092802002109204b280200210b200341b0036a41a4016a28020021222012280200212420152802002112200341b0036a4190016a280200212a20452802002105201b290200210d201631000d2152200341a0026a20034190056a418c0110f8021a200341b0036a200341a0026a418c0110f8021a02402005450d002012450d00202a10010b20034190056a200341b0036a418c0110f8021a411010002205450d06200541063a000020051001200341a0026a20034190056a418c0110f8021a200341b0036a200341a0026a418c0110f8021a02402022450d00202410010b200d42ffffffffff9f4083210d205242288621520240200a450d00200a410474210a200b21050340024020052d00004109470d00200541086a28020041ffffffff0371450d00200541046a28020010010b200541106a2105200a41706a220a0d000b0b200841026a2105200d205284210d02402009450d00200b10010b20034190056a200341b0036a418c0110f8021a200341b0036a20034190056a418c0110f8021a20402020360200204120053602002042200c360200200341a0026a41206a200e36020020444100360200200341a0026a41146a4204370200200341a0026a410c6a200d370200200620483602002003201d3602a402200341013602a002200341b0036a200341a0026a105520034180016a200341b0036a418c0110f8021a2016410136021020162014360214024020032d00a0064109470d00203328020041ffffffff0371450d0020032802a40610010b024020312d00004109470d00203828020041ffffffff0371450d00203528020010010b024020302d00004109470d00200341a0066a41286a28020041ffffffff0371450d00200341a0066a41246a28020010010b0240202f2d00004109470d00203a28020041ffffffff0371450d00203628020010010b0240202d2d00004109470d00203c28020041ffffffff0371450d00203428020010010b0240202b2d00004109470d00203e28020041ffffffff0371450d00203228020010010b024020292d00004109470d00204328020041ffffffff0371450d00201928020010010b024020282d00004109470d00204e28020041ffffffff0371450d00201a28020010010b024020272d00004109470d00204f28020041ffffffff0371450d00200728020010010b024020262d00004109470d00204628020041ffffffff0371450d00200341a0066a4194016a28020010010b024020252d00004109470d00200341a0066a41a8016a28020041ffffffff0371450d00204a28020010010b024020232d00004109470d00200341a0066a41b8016a28020041ffffffff0371450d00204728020010010b024020212d00004109470d00200341a0066a41c8016a28020041ffffffff0371450d00202e28020010010b0240201f2d00004109470d00201828020041ffffffff0371450d00205528020010010b0240201e2d00004109470d00200128020041ffffffff0371450d00202c28020010010b201441016a211420172037470d000b0b02402050450d00205110010b200341a0066a20034180016a418c0110f8021a200341b0036a200341a0066a105602400240200341b0036a41106a2802002205450d0020032802b80322142005412c6c6a211503400240024020142d00002205410a460d0020054108470d01201428020c2205450d012014280204220a200541146c6a211303400240200a28020c0d00200a2802102106200341d0006a21052003280254210e03402005280200220841086a210c20082f01062216410274210b417f21050240024002400340200b450d01200541016a21054100417f4101200c280200220920064b1b20092006461b2209450d03200b417c6a210b200c41046a210c20094101460d000b200e0d010c040b20162105200e450d030b200e417f6a210e200820054102746a4194036a21050c010b0b200841346a20054105746a2205450d002005280210450d09200a41106a20052802143602000b200a41146a220a2013470d000c020b0b201428020c2205450d002014280204220f2005411c6c6a211703400240200f2802182205450d00200f280210220e20054102746a21120340200e221341046a210e2013280200210c200341d0006a210520032802542109024003402005280200220641086a210b20062f01062216410274210a417f21050240024002400340200a450d01200541016a21054100417f4101200b2802002208200c4b1b2008200c461b2208450d03200a417c6a210a200b41046a210b20084101460d000b20090d010c040b201621052009450d030b2009417f6a2109200620054102746a4194036a21050c010b0b200641346a20054105746a2205450d002005280210450d07201320052802143602000b200e2012470d000b0b200f411c6a220f2017470d000b0b2014412c6a22142015470d000b0b200341bc036a290200210d20032802b003210520032902b40321522003280250200328025420032802581057200041106a200d370200200041086a205237020020002005360204200041003602002011450d192010450d1920111001200424000f0b41b88bc00041351042000b200b41081019000b200c41041019000b41b88bc00041351042000b411041081019000b411041081019000b200541011019000b200541081019000b200541081019000b200841041019000b41c40341041019000b41c40341041019000b41940341041019000b41940341041019000b200c41011019000b41c380c00041cc001042000b203028020021050c010b200341b4066a4101360200200341ac066a4101360200200341a8066a41e0c3c1003602002003410336029405200341b0066a20034190056a360200200341023602a406200341a08fc2003602a0062003200341dc006a36029005200341b0036a200341a0066a104d20032902b403220d422088a7210520032802b0032112200da721280b20032802800520032802840520034188056a280200105702402050450d00204810010b202d10590240200341c4006a280200450d00202310010b2000201236020420004101360200200041086a2005ad4220862028ad843702002011450d062010450d0620111001200424000f0b200341023602702026450d010b2028450d00201210010c000b0b102c000b1018000b200710592001410c6a280200450d00200728020010010b200424000b160020002001280208360204200020012802003602000be539030f7f017e017f230041c0006b220324002002280208220441586a2105200241106a2802002206412c6c210702400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024003402007450d01200741546a2107200541286a21082005412c6a2209210520082d00004104470d000b2006412c6c2107200441586a210503402007450d02200741546a2107200541286a21082005412c6a220a210520082d0000410b470d000b2006412c6c2107200441586a210503402007450d03200741546a2107200541286a21082005412c6a2204210520082d00004102470d000b200341106a20091049200328021420014d0d03200328021020014102746a2207450d03200341086a20041049200328020c200728020022074d0d04200328020820074104746a2207450d04200a41086a28020020014d0d05200a2802002109200341186a41086a420037030020034280808080c00037031820072d000d2108200341306a41026a220a2003412d6a41026a2d00003a0000200320032f002d3b0130411010002207450d3f200341206a220b4101360200200341186a410c6a220528020021062003200736021c200720064104746a220741003a000c2007410036020820072008410447220c3602042007200c360200200720032f01303b000d2007410f6a200a2d00003a00002005200528020041016a3602004100210802402009200141186c6a22072802142205450d002007410c6a2106200741146a210a200341306a410472210d4100210841002107034002402003280218220920084d0d00200341306a200341186a4100105e20032802304101460d0920082003280218220920032802342d000c1b2108200a28020021050b200720054f0d3e02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402006280200220120074104746a2d0000220541ab014b0d00024020050eac01141e0707071e13120c181915110e0d0b17160f1004040404040404040404040404040505050505050505050a1a06060606080000000000000000000008000000000000000000000000000000000000000000000303030101010101010101010101010101010303030101010101010101010101010101010303030303030301010101010101030303030303030101010101010102020202020202020202020202020202020202020202020202140b200341306a200341186a4102105f20032802300d2a2003280218220541016a22092005490d2b20032009360218200741016a2207200a2802002205490d1f0c200b200341306a200341186a4102105f20032802300d272003280218220541016a22092005490d2820032009360218200741016a2207200a2802002205490d1e0c1f0b200341306a200341186a4101105f20032802300d2a2003280218220541016a22092005490d2b20032009360218200741016a2207200a2802002205490d1d0c1e0b200341306a200341186a4101105f20032802300d2b2003280218220541016a22092005490d2c20032009360218200741016a2207200a2802002205490d1c0c1d0b200341306a200341186a4101105f20032802300d2c2003280218220541016a22092005490d2d20032009360218200741016a2207200a2802002205490d1b0c1c0b200341306a200341186a4102105f2003280230450d180c2f0b200941016a22052009490d2f20032005360218200741016a2207200a2802002205490d190c1a0b200120074104746a2d0001210e200341306a41026a2003412d6a41026a2d00003a0000200320032f002d3b0130200341246a2802002201200341206a280200470d01200141016a220f2001490d5b20014101742210200f200f2010491b2211ad4204862212422088a70d5b2012a722104100480d5b2001450d13200328021c211320101000220f450d5c200f2013201020014104742201200120104b1b10f8021a201310010c140b200341306a200341186a4101105f20032802300d2e2003280218220541016a22092005490d3020032009360218200741016a2207200a2802002205490d170c180b200328021c210f0c130b200941016a22052009490d3d20032005360218200741016a2207200a2802002205490d150c160b200941016a22052009490d3720032005360218200741016a2207200a2802002205490d140c150b200341306a200341186a200120074104746a41046a280200105e20032802304101460d2f200341306a200341186a20032802342802042205105f20032802300d41200341306a200341186a4101105f20032802300d4a2003280218220920056a22052009490d4b20032005360218200741016a2207200a2802002205490d130c140b200341306a200341186a4102105f20032802300d34200341306a200341186a4101105f20032802300d3e2003280218220541016a22092005490d4820032009360218200741016a2207200a2802002205490d120c130b200341306a200341186a4101105f2003280230450d0f0c300b200941016a22052009490d3720032005360218200741016a2207200a2802002205490d100c110b200341306a200341186a4101105f2003280230450d0d0c2f0b2003200410492003280204200120074104746a41046a28020022054d0d2b2003280200220920054104746a2201450d2b200341306a200341186a200920054104746a280208105f20032802300d3b2003280218220520012d000d4104476a22092005490d4320032009360218200741016a2207200a2802002205490d0e0c0f0b200341306a200341186a200120074104746a41046a280200105e20032802304101460d32200341306a200341186a2003280234280204105f20032802300d38200341246a2802002205417f6a220920054f0d41200920054b0d41200328021c20094104746a41013a000c200741016a2207200a2802002205490d0d0c0e0b200341246a22052802002209450d2420052009417f6a2209360200200328021c20094104746a22052d000c4102460d2420052802002109200320052802082205360218200520096a22092005490d3f20032009360218200741016a2207200a2802002205490d0c0c0d0b200341246a2802002205417f6a220920054f0d31200920054b0d31200328021c20094104746a41013a000c200741016a2207200a2802002205490d0b0c0c0b200341306a200120074104746a41046a2802002002105220032802304101460d25200341306a200341186a20032802342205280208105f20032802300d392003280218220920052d000d4104476a22052009490d3c20032005360218200741016a2207200a2802002205490d0a0c0b0b200341306a200341186a4101105f20032802300d2d2003280218220541016a22092005490d3920032009360218200741016a2207200a2802002205490d090c0a0b200341306a200341186a4101105f2003280230450d060c290b200341306a200341186a200120074104746a2209410c6a280200105e20032802304101460d2120032802342802042101200941086a2802004102742105200941046a280200210903402005450d07200341306a200341186a2009280200105e20032802304101460d1b2005417c6a2105200941046a210920032802342802042001460d000c1c0b0b200341306a200341186a200c105f20032802300d24200341246a2802002205417f6a220920054f0d30200920054b0d30200328021c20094104746a41013a000c200741016a2207200a2802002205490d060c070b200341306a200341186a4101105f20032802300d2e2003280218220541016a22092005490d3620032009360218200741016a2207200a2802002205490d050c060b20101000220f450d480b200341206a20113602002003200f36021c200341246a28020021010b200f20014104746a220141003a000c2001200936020820012005410347200e41044722057136020420012005360200200120032f01303b000d2001410f6a200341326a2d00003a0000200341246a2205200528020041016a3602000b200741016a2207200a2802002205490d010c020b200341306a200341186a2001105f20032802300d39200341246a2802002205417f6a220920054f0d3a200920054b0d3a200328021c20094104746a41013a000c200741016a2207200a2802002205490d000b0b2000410036020020002008360204200b280200450d5c200328021c1001200341c0006a24000f0b411310002207450d38200741126a41002d00c986403a0000200741106a41002f00c786403b0000200741086a41002900bf8640370000200741002900b78640370000200041086a4293808080b0023702002000200736020420004101360200200341c0006a24000f0b410f10002207450d38200741076a41002900d18640370000200741002900ca8640370000200041086a428f808080f0013702002000200736020420004101360200200341c0006a24000f0b410f10002207450d38200741076a41002900e08640370000200741002900d98640370000200041086a428f808080f0013702002000200736020420004101360200200341c0006a24000f0b412510002207450d392007411d6a41002900858740370000200741186a41002900808740370000200741106a41002900f88640370000200741086a41002900f08640370000200741002900e88640370000200041086a42a5808080d0043702002000200736020420004101360200200341c0006a24000f0b412510002207450d392007411d6a41002900858740370000200741186a41002900808740370000200741106a41002900f88640370000200741086a41002900f08640370000200741002900e88640370000200041086a42a5808080d0043702002000200736020420004101360200200341c0006a24000f0b412710002207450d3a2007411f6a41002900ac8740370000200741186a41002900a58740370000200741106a410029009d8740370000200741086a410029009587403700002007410029008d8740370000200041086a42a7808080f0043702002000200736020420004101360200200341c0006a24000f0b200041013602002000200d2902003702042000410c6a200d41086a280200360200200341206a280200450d550c540b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d530c540b410e10002207450d3a200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d520c530b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d510c520b410e10002207450d39200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d500c510b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d4f0c500b410e10002207450d38200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d4e0c4f0b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d4d0c4e0b410e10002207450d37200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d4c0c4d0b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d4b0c4c0b410e10002207450d36200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d4a0c4b0b200041013602002000200d2902003702042000410c6a200d41086a280200360200200341206a2802000d490c4a0b412710002207450d352007411f6a41002900f88740370000200741186a41002900f18740370000200741106a41002900e98740370000200741086a41002900e18740370000200741002900d98740370000200041086a42a7808080f0043702002000200736020420004101360200200341206a2802000d480c490b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d470c480b410e10002207450d34200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d460c470b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d450c460b411710002207450d332007410f6a41002900c38740370000200741086a41002900bc8740370000200741002900b48740370000200041086a4297808080f0023702002000200736020420004101360200200341206a2802000d440c450b410e10002207450d33200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d430c440b200041013602002000200d2902003702042000410c6a200d41086a280200360200200341206a2802000d420c430b200041013602002000200d2902003702042000410c6a200d41086a280200360200200341206a2802000d410c420b200041013602002000200d2902003702042000410c6a200d41086a280200360200200341206a2802000d400c410b410e10002207450d30200741066a41002900868840370000200741002900808840370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d3f0c400b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d3e0c3f0b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d3d0c3e0b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d3c0c3d0b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d3b0c3c0b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d3a0c3b0b410e10002207450d2b200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d390c3a0b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d380c390b200041013602002000200d2902003702042000410c6a200d41086a280200360200200341206a2802000d370c380b411710002207450d292007410f6a41002900c38740370000200741086a41002900bc8740370000200741002900b48740370000200041086a4297808080f0023702002000200736020420004101360200200341206a2802000d360c370b410e10002207450d29200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d350c360b410e10002207450d29200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d340c350b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d330c340b411710002207450d282007410f6a41002900c38740370000200741086a41002900bc8740370000200741002900b48740370000200041086a4297808080f0023702002000200736020420004101360200200341206a2802000d320c330b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d310c320b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d300c310b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d2f0c300b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d2e0c2f0b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d2d0c2e0b410e10002207450d23200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d2c0c2d0b410e10002207450d23200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d2b0c2c0b410e10002207450d23200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d2a0c2b0b410e10002207450d23200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d290c2a0b411710002207450d232007410f6a41002900c38740370000200741086a41002900bc8740370000200741002900b48740370000200041086a4297808080f0023702002000200736020420004101360200200341206a2802000d280c290b410e10002207450d23200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d270c280b410e10002207450d23200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d260c270b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d250c260b410e10002207450d22200741066a41002900d18740370000200741002900cb8740370000200041086a428e808080e0013702002000200736020420004101360200200341206a2802000d240c250b20002003290330370204200041013602002000410c6a200341386a280200360200200341206a2802000d230c240b411710002207450d212007410f6a41002900c38740370000200741086a41002900bc8740370000200741002900b48740370000200041086a4297808080f0023702002000200736020420004101360200200341206a2802000d220c230b411341011019000b410f41011019000b410f41011019000b41808fc20020072005104e000b412541011019000b412541011019000b411041041019000b412741011019000b1018000b201041041019000b410e41011019000b410e41011019000b410e41011019000b410e41011019000b410e41011019000b412741011019000b410e41011019000b411741011019000b410e41011019000b410e41011019000b410e41011019000b411741011019000b410e41011019000b410e41011019000b411741011019000b410e41011019000b410e41011019000b410e41011019000b410e41011019000b411741011019000b410e41011019000b410e41011019000b410e41011019000b411741011019000b200328021c10010b200341c0006a24000ba80302067f017e230041106b2202240002400240024002400240024002400240200041046a2802002203200028020822046b20012802042205200128020022066b41047622074f0d00200420076a22062004490d0420034101742204200620062004491b2204ad4204862208422088a70d042008a722064100480d042003450d0120002802002105200610002207450d0520072005200620034104742203200320064b1b10f8021a200510010c020b2000280200210720062005460d020c050b200610002207450d030b20002007360200200041046a2004360200200041086a280200210420012802002206200141046a280200470d030b410021060c030b1018000b200641081019000b2001200641106a3602000b200220061050024020022d000041ac01460d00200720044104746a2106034020062002290300370300200641086a200241086a2903003703000240024020012802002203200141046a280200460d002001200341106a3602000c010b410021030b200441016a2104200641106a210620022003105020022d000041ac01470d000b0b200041086a2004360200200241106a24000b0b002000280200200110580bfe0201067f230041306b22022400200128020021030240024002400240024002400240200128020422044103742205450d00200341046a2106410021070340200628020020076a2107200641086a2106200541786a22050d000b200141146a280200450d010c020b41002107200141146a2802000d010b200721060c010b2004450d02024002402007410f4b0d002003280204450d010b200720076a220620074f0d010b4101210541002106200241086a21070c010b2006417f4c0d02200241086a210702402006450d002006100022050d01200641011019000b41012105410021060b200241003602102002200636020c200220053602082002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a290200370300200220012902003703180240200241146a41e090c200200241186a106d0d0020002007290200370200200041086a200741086a280200360200200241306a24000f0b106e000b41d090c20041004100104e000b102c000b860101017f230041306b220324002003200236020420032001360200200341206a410c6a41033602002003411c6a4102360200200341086a410c6a4102360200200341033602242003418489c2003602102003410236020c200341f890c200360208200320033602282003200341046a3602202003200341206a360218200341086a20001071000b6802017f037e230041306b22012400200029020821022000290210210320002902002104200141146a41003602002001200437031820014188f0c100360210200142013702042001200141186a36020020012003370328200120023703202001200141206a1071000bc80903037f017e017f0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d0020012d00002202417e6a2203412e4b0d01024020030e2f001f233030152019301e0b30300e0d1d271a0c161c242212112829061b0a091025172605140721080403182b2a130f000b20012d00012104410221020c2f0b200041ac013a00000f0b0c2b0b20012d00012104412b21020c2c0b200141046a280200210620013502082105412a21020c2a0b200141046a280200210620013502082105412521020c290b200141046a280200210620013502082105411d21020c280b200141046a280200210620013502082105412721020c270b200141046a280200210620013502082105412921020c260b200141046a280200210620013502082105412021020c250b200141046a280200210620013502082105411f21020c240b200141046a280200210620012d00012104410c21020c240b200141046a280200210620013502082105411421020c220b200141046a2802002106411021020c210b200141046a2802002106410f21020c200b20012903082105413021020c1e0b200141046a280200210620013502082105412121020c1e0b200141046a280200210620013502082105411a21020c1d0b200141046a280200210620013502082105411921020c1c0b200141046a2802002106412f21020c1b0b200141046a280200210620013502082105412621020c1a0b200141046a2802002106410721020c190b200141046a280200210620013502082105411521020c180b200141046a280200210620013502082105412321020c170b20012d00012104412c21020c170b20012802082204ad2205421e88a70d122005420286a72202417f4c0d124104210602402002450d00200210002206450d140b02402004450d00200141046a28020021022004410274210320062104034020042002280200360200200441046a2104200241046a21022003417c6a22030d000b0b2001410c6a3502004220862005842105410921020c150b200141046a2802002106411321020c140b200141046a280200210620013502082105411e21020c130b200141046a280200210620013502082105411621020c120b200141046a2802002106411121020c110b200141046a2802002106410b21020c100b20012d00012104410321020c100b200141046a2802002106410821020c0e0b200141046a280200210620013502082105412821020c0d0b200141046a280200210620013502082105411821020c0c0b20012d00012104410421020c0c0b200141046a280200210620013502082105411721020c0a0b200141046a280200210620013502082105412221020c090b200141046a280200210620013502082105412421020c080b200141046a2802002106411221020c070b200141046a280200210620013502082105411b21020c060b200141046a280200210620013502082105411c21020c050b20012903082105412e21020c030b200141046a2802002106412d21020c030b102c000b200241041019000b0b0b200020043a0001200020023a0000200041086a2005370300200041046a20063602000b19002000200141186a280200360204200020012802103602000bf507020b7f017e230041e0006b22032400200320013602202002280208220441586a2105200241106a2802002206412c6c21020240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004102470d000b200341186a2008104920032802182107200328021c21020c010b410021070b2002410020071b21092006412c6c2102200441586a210520074188f0c10020071b210a0240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004104470d000b200341106a200810492003280210210b2003280214210c0c010b4100210b0b2006412c6c2102200441586a2105200b4188f0c100200b1b210d02400240024002400240024002400240024003402002450d01200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b200841086a2802002202450d00200241286c2107200828020041186a2102410021050340200520022d0000456a2105200241286a2102200741586a22070d000b200520014d0d012006412c6c2102200441586a210503402002450d06200241546a2102200541286a21072005412c6a2208210520072d00004103470d000b200341086a20081049200328020c220b41286c210520032802082204210703402005450d05200541586a2105200741186a2108200741286a2202210720082d00000d000b2001450d022004200b41286c6a210803402001417f6a2101034020082002460d06200241186a2105200241286a2207210220052d00000d000b2007210220010d000b200741586a21020c030b410021050b0240200c4100200b1b200120056b22024d0d00200d20024102746a2202450d00200320022802002202360224200920024d0d060c050b200341cc006a4101360200200341c4006a41013602002003410336022c200341e0c3c1003602402003410236023c200341988ec2003602382003200341206a3602282003200341286a360248200341d0006a200341386a104d2003290254210e200328025021020c060b200241586a21020b20032002411c6a2802002202360224200920024b0d020c030b41d983c00041dd001042000b419783c00041c2001042000b200a20024104746a2202450d002000410036020020002002360204200341e0006a24000f0b200341d0006a410c6a4103360200200341cc006a4102360200200341386a410c6a4102360200200341033602542003418489c2003602402003410336023c200341a88ec2003602382003200341206a3602582003200341246a3602502003200341d0006a360248200341286a200341386a104d200329022c210e200328022821020b2000200236020420004101360200200041086a200e370200200341e0006a24000bee2801377f23004190016b2202240020024184016a4200370200200241fc006a4280808080c000370200200241ec006a4200370200200241e4006a4280808080c000370200200241d0006a4200370300200241c0006a4200370300200241386a4280808080c000370300200241286a4200370300200241206a4280808080c000370300200241106a4200370300200242043702742002420437025c20024204370348200242043703302002420437031820024280808080c000370308200242043703002001410c6a280200210320012802082104024002400240200141106a2802002205450d00410021064100210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f41002101024002400340201121102001211220042005417f6a2205412c6c6a2201280024211320012800202114200128001821152001280014211620012800102117200128000c2118200128000821192001280004211a4101211b024002400240024002400240024002400240024020012d0000221c417e6a221d410d4b0d004101211e4101211f4101212041012121410121224101212341012101201a21110240024002400240024002400240024002400240201d0e0e00020304050106130708090f0f16000b0240200f450d0002402024450d0020244104742111200f210103400240200141046a280200450d00200128020010010b200141106a2101201141706a22110d000b0b2025450d00200f10010b4101211e4100211b2018212420192125201a210f0c0a0b0240200a450d0002402026450d00200a20264104746a2122200a211d03400240201d2802082211450d00201d2802002101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b201d41106a21010240201d41046a280200450d00201d28020010010b2001211d20012022470d000b0b2027450d00200a10010b4100211f4101211b2018212620192127201a210a4101211e0c0a0b0240200e450d0002402028450d00202841286c2111200e210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101201141586a22110d000b0b2029450d00200e10010b4100211e4101211b2018212820192129201a210e0c080b0240202a450d00200d450d00200d10010b2012210120102111201a210d2019212a2018212b20050d100c110b0240202c450d00200c450d00200c10010b2012210120102111201a210c2019212c2018212d20050d0f0c100b0240202e450d00200b450d00200b10010b2012210120102111201a210b2019212e2018212f20050d0e0c0f0b02402009450d0002402030450d00203041146c21112009210103400240200141046a280200450d00200128020010010b200141146a21012011416c6a22110d000b0b2031450d00200910010b410021204101211b2018213020192131201a21094101211e4101211f0c060b02402008450d0002402032450d0020082032411c6c6a21222008211d03400240201d410c6a2802002211450d00201d2802042101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b0240201d41086a280200450d00201d41046a28020010010b201d411c6a21010240201d41146a280200450d00201d28021010010b2001211d20012022470d000b0b2033450d00200810010b410021214101211b2018213220192133201a21084101211e4101211f410121200c060b02402007450d0002402034450d002007203441186c6a21222007211d03400240201d41046a280200450d00201d28020010010b0240201d41146a2802002211450d00201d28020c2101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b201d41186a21010240201d41106a280200450d00201d410c6a28020010010b2001211d20012022470d000b0b2035450d00200710010b410021224101211b2018213420192135201a21074101211e4101211f410121204101212141012123201c410d4d0d070c080b02402006450d0002402036450d0020062036411c6c6a21222006211d03400240201d410c6a2802002211450d00201d2802042101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b0240201d41086a280200450d00201d41046a28020010010b201d411c6a21010240201d41146a280200450d00201d28021010010b2001211d20012022470d000b0b2037450d00200610010b410021234101211b2018213620192137201a21064101211e4101211f410121204101212141012122201c410d4d0d060c070b4101211e0b4101211f0b410121200b410121210b41012122410121230b201c410d4b0d010b20122101201021110240024002400240024002400240024002400240201c0e0e0900010209090903040c05060708090b02402019450d00201a10010b2016450d0a201710010c0a0b201b450d092018450d0720184104742111201a210103400240200141046a280200450d00200128020010010b200141106a2101201141706a22110d000c080b0b201e450d082018450d06201841286c2111201a210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101201141586a22110d000c070b0b201f450d072018450d05201a20184104746a211c201a211d03400240201d2802082211450d00201d2802002101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b201d41106a21010240201d41046a280200450d00201d28020010010b2001211d2001201c470d000c060b0b2020450d062018450d04201841146c2111201a210103400240200141046a280200450d00200128020010010b200141146a21012011416c6a22110d000c050b0b2021450d052018450d03201a2018411c6c6a211c201a211d03400240201d410c6a2802002211450d00201d2802042101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b0240201d41086a280200450d00201d41046a28020010010b201d411c6a21010240201d41146a280200450d00201d28021010010b2001211d2001201c470d000c040b0b2022450d042018450d02201a201841186c6a211c201a211d03400240201d41046a280200450d00201d28020010010b0240201d41146a2802002211450d00201d28020c2101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b201d41186a21010240201d41106a280200450d00201d410c6a28020010010b2001211d2001201c470d000c030b0b2023450d032018450d01201a2018411c6c6a211c201a211d03400240201d410c6a2802002211450d00201d2802042101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b0240201d41086a280200450d00201d41046a28020010010b201d411c6a21010240201d41146a280200450d00201d28021010010b2001211d2001201c470d000c020b0b024002400240201a41ff017122014102460d0020014101460d012018450d05201910010c050b2016450d01201820164104746a21192018211c0340201c221a41106a211c0240201a2802042201450d000240201a410c6a2802002211450d002011410c6c2111034002402001280200221d450d00200141046a280200450d00201d10010b2001410c6a2101201141746a22110d000b0b201a41086a280200450d00201a41046a28020010010b201c2019470d000c020b0b2016450d002016410c6c211120182101034002402001280200221d450d00200141046a280200450d00201d10010b2001410c6a2101201141746a22110d000b0b2017450d02201810010c020b2019450d01201a10010c010b02402019450d00201a10010b02402016450d002015450d00201610010b2013450d00201410010b20122101201021110b20050d000b0b4100210520112110200121120b2034410020071b21182035410020071b21222032410020081b21382033410020081b21332030410020091b21232031410020091b212120264100200a1b213520274100200a1b2127202f4100200b1b2120202e4100200b1b211b202d4100200c1b2130202c4100200c1b2132202b4100200d1b2116202a4100200d1b211720284100200e1b213420294100200e1b212620244100200f1b211520254100200f1b21142007410420071b21192008410420081b21282009410420091b211f200a4104200a1b2109200b4104200b1b211e200c4104200c1b2108200d4104200d1b2113200e4104200e1b2107200f4104200f1b210a20060d020c010b41042119410021184100212241002123410021214104211f410021204100211b4104211e41002116410021174104211341002115410021144104210a41002105410021124104210741002126410021344104210841002132410021304104210941002127410021354104212841002133410021380b4104210641002137410021360b2002280200211d0240200241086a2802002201450d0020014104742111201d210103400240200141046a280200450d00200128020010010b200141106a2101201141706a22110d000b0b02402002280204450d00201d10010b2002410c6a280200211d0240200241146a2802002201450d00200141286c2111201d210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101201141586a22110d000b0b0240200241106a280200450d00201d10010b02402002411c6a280200450d00200241186a28020010010b0240200241286a280200450d00200241246a28020010010b0240200241346a280200450d00200241306a28020010010b2002413c6a280200211c0240200241c4006a2802002201450d00201c20014104746a211a201c211d03400240201d2802082211450d00201d2802002101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b201d41106a21010240201d41046a280200450d00201d28020010010b2001211d2001201a470d000b0b0240200241c0006a280200450d00201c10010b200241c8006a280200211d0240200241d0006a2802002201450d00200141146c2111201d210103400240200141046a280200450d00200128020010010b200141146a21012011416c6a22110d000b0b0240200241cc006a280200450d00201d10010b200241dc006a280200211c0240200241e4006a2802002201450d00201c2001411c6c6a211a201c211d03400240201d410c6a2802002211450d00201d2802042101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b0240201d41086a280200450d00201d41046a28020010010b201d411c6a21010240201d41146a280200450d00201d28021010010b2001211d2001201a470d000b0b0240200241e0006a280200450d00201c10010b200241e8006a280200211c0240200241f0006a2802002201450d00201c200141186c6a211a201c211d03400240201d41046a280200450d00201d28020010010b0240201d41146a2802002211450d00201d28020c2101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b201d41186a21010240201d41106a280200450d00201d410c6a28020010010b2001211d2001201a470d000b0b0240200241ec006a280200450d00201c10010b200241f4006a280200211c0240200241fc006a2802002201450d00201c2001411c6c6a211a201c211d03400240201d410c6a2802002211450d00201d2802042101201141047421110340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101201141706a22110d000b0b0240201d41086a280200450d00201d41046a28020010010b201d411c6a21010240201d41146a280200450d00201d28021010010b2001211d2001201a470d000b0b20024180016a21010240200241f8006a280200450d00201c10010b20011059024020024184016a2201280200450d0020024180016a28020010010b20024188016a20053602002001200336020020024180016a2004360200200241fc006a2036360200200241f8006a2037360200200241f4006a2006360200200241f0006a2018360200200241ec006a2022360200200241e8006a2019360200200241e4006a2038360200200241e0006a2033360200200241dc006a2028360200200241d8006a2010360200200241d4006a2012360200200241d0006a2023360200200241cc006a2021360200200241c8006a201f360200200241c4006a2035360200200241c0006a20273602002002413c6a2009360200200241386a2020360200200241346a201b360200200241306a201e3602002002412c6a2030360200200241286a2032360200200241246a2008360200200241206a20163602002002411c6a2017360200200241186a2013360200200241146a2034360200200241106a20263602002002410c6a2007360200200241086a2015360200200220143602042002200a36020020002002418c0110f8021a20024190016a24000bbd0201077f024002400240024002400240200041046a2802002202200041086a28020022036b2001410c6a2802002204200141086a28020022056b22064f0d00200320066a22072003490d0420024101742203200720072003491b22034100480d042002450d0120002802002108200310002207450d052007200820032002200220034b1b10f8021a200810010c020b200028020021070c020b200310002207450d030b20002007360200200041046a2003360200200041086a28020021030b200720036a2005200610f8021a200141086a22072004360200200041086a2200200028020020066a36020041002100024003402000450d012007200441016a22033602002000417f6a210020042d000021062003210420064104470d000b0b02402001280204450d00200128020010010b0f0b1018000b200341011019000bd00503067f017e017f230041306b22022400200241106a200141246a290200370300200241086a2001411c6a29020037030020022001290214370300200241186a41106a200141106a280200360200200241186a41086a200141086a290200370300200220012902003703182000200241186a105b210302400240024002400240024002402000411c6a280200200041206a2802002204470d00200441016a22052004490d0420044101742206200520052006491b2207ad4202862208422088a70d042008a722064100480d042004450d01200041186a2802002109200610002205450d0520052009200620044102742204200420064b1b10f8021a200910010c020b200041186a28020021050c020b200610002205450d030b2000411c6a2007360200200041186a2005360200200041206a28020021040b200520044102746a2003360200200041206a2204200428020041016a360200200241186a41106a200241106a290300370300200241186a41086a200241086a290300370300200220022903003703180240024002400240200041ec006a280200200041f0006a2802002204470d00200441016a22052004490d0420044101742203200520052003491b2206ad42187e2208422088a70d042008a722034100480d042004450d01200041e8006a2802002107200310002205450d06200520072003200441186c2204200420034b1b10f8021a200710010c020b200041e8006a28020021050c020b200310002205450d040b200041ec006a2006360200200041e8006a2005360200200041f0006a28020021040b2005200441186c6a22042002290318370200200441106a200241186a41106a290300370200200441086a200241186a41086a290300370200200041f0006a22042004280200220441016a360200024020012d002c450d0020004101360254200041d8006a20043602000b200241306a24000f0b1018000b200641041019000b200341041019000b9925032e7f017e017f230041306b2202240020012802042103200128020021044101210502400240024002400240024002400240024002400240024002400240024002400240024020012802082206450d00412c10002207450d02200720022f002d3b0001200741023a00002007200636000c200720033600082007200436000420072002290208370210200741036a2002412d6a41026a2d00003a0000200741186a200241106a290200370200200741206a200241186a290200370200200741286a200241086a41186a28020036020041002108410121090c010b4104210741002109410121080b200141106a280200210a200128020c210b0240024002400240200141146a280200220c450d002009410174220d200941016a220e200e200d491b220e412c6c210f2009450d01200f1000220d450d05200d2007200f2009412c6c22102010200f4b1b10f8021a200710010c020b2009210e2007210d0c020b200f1000220d450d030b200d2009412c6c6a220720022f002d3b0001200741033a00002007200c36000c2007200a3600082007200b36000420072002290208370210200741036a2002412f6a2d00003a0000200741186a200241106a290200370200200741206a200241186a290200370200200741286a200241086a41186a280200360200200941016a210941002105200d21070b2001411c6a28020021112001280218211241002113024002400240024002400240200141206a2802002210450d00200e2009470d0141000d1041000d10200e4101742207200e41016a220f200f2007491b220fad422c7ea722074100480d10200e450d02200710002214450d082014200d2007200e412c6c220e200e20074b1b10f8022107200d10012007210d0c030b200e210f410021150c040b200e210f0c020b20071000220d450d050b200d21070b20072009412c6c6a220e41043a0000200e201036000c200e2011360008200e2012360004200e41036a2002412f6a2d00003a0000200e20022f002d3b0001200e41286a200241086a41186a280200360200200e41206a200241186a290200370200200e41186a200241106a290200370200200e200229020837021041012115200941016a21090b200141286a2802002116200128022421170240024002400240024002402001412c6a2802002214450d00200f2009470d0141000d1041000d10200f4101742207200f41016a220e200e2007491b2210ad422c7ea722074100480d10200f450d0220071000220e450d09200e200d2007200f412c6c220f200f20074b1b10f8022107200d10012007210d0c030b200f21100c040b200f21100c020b20071000220d450d060b200d21070b20072009412c6c6a220e41053a0000200e201436000c200e2016360008200e2017360004200e41036a2002412f6a2d00003a0000200e20022f002d3b0001200e41286a200241086a41186a280200360200200e41206a200241186a290200370200200e41186a200241106a290200370200200e200229020837021041012113200941016a21090b200141346a280200211820012802302119024002400240024002400240200141386a2802002214450d0020102009470d0141000d1041000d1020104101742207201041016a220e200e2007491b220fad422c7ea722074100480d102010450d0220071000220e450d0a200e200d20072010412c6c2210201020074b1b10f8022107200d10012007210d0c030b4100211a2010210f0c040b2010210f0c020b20071000220d450d070b200d21070b20072009412c6c6a220e41063a0000200e201436000c200e2018360008200e2019360004200e41036a2002412f6a2d00003a0000200e20022f002d3b0001200e41286a200241086a41186a280200360200200e41206a200241186a290200370200200e41186a200241106a290200370200200e20022902083702104101211a200941016a21090b200141c0006a280200211b200128023c211c4101211d024002400240024002400240200141c4006a280200221e450d00200f2009470d0141000d1041000d10200f4101742207200f41016a220e200e2007491b2210ad422c7ea722074100480d10200f450d0220071000220e450d0b200e200d2007200f412c6c220f200f20074b1b10f8022107200d10012007210d0c030b200f21104101211f0c040b200f21100c020b20071000220d450d080b200d21070b20072009412c6c6a220e41073a0000200e201e36000c200e201b360008200e201c360004200e41036a2002412f6a2d00003a0000200e20022f002d3b0001200e41286a200241086a41186a280200360200200e41206a200241186a290200370200200e41186a200241106a290200370200200e2002290208370210200941016a21094100211f0b200141cc006a280200212020012802482121024002400240024002400240200141d0006a2802002222450d0020102009470d0141000d1041000d1020104101742207201041016a220e200e2007491b2214ad422c7ea722074100480d102010450d0220071000220e450d0c200e200d20072010412c6c220f200f20074b1b10f8022107200d10012007210d0c030b201021144101212320012802544101460d040c0d0b201021140c020b20071000220d450d090b200d21070b20072009412c6c6a220e41083a0000200e202236000c200e2020360008200e2021360004200e41036a2002412f6a2d00003a0000200e20022f002d3b0001200e41286a200241086a41186a280200360200200e41206a200241186a290200370200200e41186a200241086a41086a290200370200200e2002290208370210200941016a21094100211d4101212320012802544101470d090b200141d8006a2802002110024002400240024020142009470d0041000d0e41000d0e20144101742207201441016a220e200e2007491b220fad422c7ea722074100480d0e2014450d0120071000220e450d0b200e200d20072014412c6c2214201420074b1b10f8022107200d10012007210d0c020b2014210f0c020b20071000220d450d090b200d21070b20072009412c6c6a220e41093a0000200e2010360204200e41036a2002412f6a2d00003a0000200e20022f002d3b0001200e41286a200241086a41206a280200360200200e41206a200241086a41186a290200370200200e41186a200241086a41106a290200370200200e41106a200241106a290200370200200e2002290208370208200941016a21090c090b412c41041019000b200f41041019000b200741041019000b200741041019000b200741041019000b200741041019000b200741041019000b200741041019000b2014210f0b200141e0006a2802002124200128025c2125024002400240024002400240200141e4006a2802002226450d00200f2009470d0141000d0641000d06200f4101742207200f41016a220e200e2007491b2210ad422c7ea722074100480d06200f450d0220071000220e450d09200e200d2007200f412c6c220f200f20074b1b10f8022107200d10012007210d0c030b200f21100c040b200f21100c020b20071000220d450d060b200d21070b20072009412c6c6a220e410a3a0000200e202636000c200e2024360008200e2025360004200e41036a2002412f6a2d00003a0000200e20022f002d3b0001200e41286a200241086a41186a280200360200200e41206a200241186a290200370200200e41186a200241106a290200370200200e2002290208370210200941016a2109410021230b200141ec006a28020021272001280268212841012129024002400240024002400240200141f0006a280200222a450d0020102009470d0141000d0641000d0620104101742207201041016a220e200e2007491b2214ad422c7ea722074100480d062010450d0220071000220e450d0a200e200d20072010412c6c220f200f20074b1b10f8022107200d10012007210d0c030b201021144101212b0c040b201021140c020b20071000220d450d070b200d21070b20072009412c6c6a220e410b3a0000200e202a36000c200e2027360008200e2028360004200e41036a2002412f6a2d00003a0000200e20022f002d3b0001200e41286a200241086a41186a280200360200200e41206a200241186a290200370200200e41186a200241106a290200370200200e2002290208370210200941016a21094100212b0b200141f8006a280200212c20012802742110024002400240024002400240200141fc006a280200222d450d0020142009470d0141000d0641000d0620144101742207201441016a220e200e2007491b220fad422c7ea722074100480d062014450d0220071000220e450d0b200e200d20072014412c6c2214201420074b1b10f8022107200d10012007210d0c030b2014210f0c040b2014210f0c020b20071000220d450d080b200d21070b20072009412c6c6a220e410c3a0000200e202d36000c200e202c360008200e2010360004200e41036a2002412f6a2d00003a0000200e20022f002d3b0001200e41286a200241086a41186a280200360200200e41206a200241186a290200370200200e41186a200241106a290200370200200e2002290208370210200941016a2109410021290b20014184016a2802002114200128028001210e024002400240200f20096b20014188016a280200412c6c222e412c6d22014f0d00200920016a22012009490d03200f4101742207200120012007491b222fad422c7e2230422088a70d032030a722314100480d03200f450d01203110002207450d052007200d2031200f412c6c220f200f20314b1b10f8021a200d10010c020b200920016a2101200f212f0c010b203110002207450d030b20072009412c6c6a200e202e10f8021a02402014450d00200e10010b41c00510002209450d012000200736020820004280c2cdeb16370200200241086a410c6a4210370200200041106a20013602002000410c6a202f3602002002200936021020024280c2cdeb16370308200241106a10592009100102402029450d000240202d450d002010202d411c6c6a210d20102107034002402007410c6a2802002209450d0020072802042101200941047421090340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200941706a22090d000b0b0240200741086a280200450d00200741046a28020010010b2007411c6a21010240200741146a280200450d00200728021010010b200121072001200d470d000b0b202c450d00201010010b0240202b450d000240202a450d002028202a41186c6a210d2028210703400240200741046a280200450d00200728020010010b0240200741146a2802002209450d00200728020c2101200941047421090340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200941706a22090d000b0b200741186a21010240200741106a280200450d002007410c6a28020010010b200121072001200d470d000b0b2027450d00202810010b02402023450d0002402026450d0020252026411c6c6a210d20252107034002402007410c6a2802002209450d0020072802042101200941047421090340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200941706a22090d000b0b0240200741086a280200450d00200741046a28020010010b2007411c6a21010240200741146a280200450d00200728021010010b200121072001200d470d000b0b2024450d00202510010b0240201d450d0002402022450d00202241146c21092021210103400240200141046a280200450d00200128020010010b200141146a21012009416c6a22090d000b0b2020450d00202110010b0240201f450d000240201e450d00201c201e4104746a210d201c21070340024020072802082209450d0020072802002101200941047421090340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200941706a22090d000b0b200741106a21010240200741046a280200450d00200728020010010b200121072001200d470d000b0b201b450d00201c10010b02402018410047201a41017371450d00201910010b02402016410047201341017371450d00201710010b02402011410047201541017371450d00201210010b02402005450d000240200c450d00200c41286c2109200b210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101200941586a22090d000b0b200a450d00200b10010b02402008450d0002402006450d00200641047421092004210103400240200141046a280200450d00200128020010010b200141106a2101200941706a22090d000b0b2003450d00200410010b200241306a24000f0b1018000b41c00541041019000b203141041019000b200741041019000b200741041019000b200741041019000bb90504057f017e017f017e230041106b2203240002402001450d0020012104034020002802940321002004417f6a22040d000b0b02402001450d0003402001417f6a22010d000b0b4100210502402002450d0041002101034002400240200120002f01064f0d00200020014105746a220641386a2802002104200641346a2802002107200141016a2101200641c4006a2802004102460d030c010b0240024020002802002204450d0020003301044220862005ad84210841012106200421010c010b2005ad210841002106410021010b200010012008a72105024002402008422088a7220720042f01064f0d00200121040c010b03400240024020012802002200450d00200641016a210620013301044220862005ad842108200021040c010b2005ad2108410021040b200110012008a72105200421012008422088a7220720002f01064f0d000b0b200420074102746a4198036a2802002100200420074105746a220141c4006a2802002109200141386a2802002104200141346a2802002107024020064101460d00410120066b210103402000280294032100200141016a22010d000b0b4100210120094102460d020b2002417f6a210202402004450d00200710010b20020d000b0b02400240200041e8bdc000460d000240024020002802002201450d00200033010421082003200136020420034101360200200320084220862005ad84220837030841022104200010012001450d020c010b2005ad21084100210141012104200010014100450d010b024020012802002200450d002001330104210a20032000360204200320043602002003200a422086200842ffffffff0f8384370308200110012000450d010c020b410021002001100141000d010b200341106a24000f0b024020002802002201450d000340200010012001210020012802002204210120040d000b0b20001001200341106a24000bdf0201067f230041306b2202240041272103024002400240024002400240200028020022004190ce00490d00412721030340200241096a20036a2204417c6a200020004190ce006e220541f0b17f6c6a220641e4006e2207410174419892c0006a2f00003b00002004417e6a20062007419c7f6c6a410174419892c0006a2f00003b00002003417c6a2103200041ffc1d72f4b21042005210020040d000b41e4002104200541e400480d010c020b41e40021042000220541e4004e0d010b2005220041094a0d010c020b200241096a2003417e6a22036a200541ffff037120046e2200419c7f6c20056a41ffff0371410174419892c0006a2f00003b0000200041094c0d010b200241096a2003417e6a22036a22052000410174419892c0006a2f00003b00000c010b200241096a2003417f6a22036a2205200041306a3a00000b200141014188f0c10041002005412720036b10772100200241306a240020000bac0f01097f024020002802082201450d00200028020022022001412c6c6a2103034020022204412c6a21020240024002400240024002400240024002400240024002400240024020042d00002200410d4b0d00024020000e0e0002030405060708090e0a0b0c0d000b200441086a280200450d0d200441046a280200100120022003470d0e0c0f0b0240200441086a280200450d00200441046a28020010010b0240200441146a2802002200450d00200441186a280200450d00200010010b200441246a280200450d0c200441206a280200100120022003470d0d0c0e0b0240200441086a280200450d00200441046a28020010010b200441146a280200450d0b200441106a280200100120022003470d0c0c0d0b200441046a210502402004410c6a2802002201450d00200528020021002001410474210103400240200041046a280200450d00200028020010010b200041106a2100200141706a22010d000b0b200441086a280200450d0a2005280200100120022003470d0b0c0c0b200441046a210502402004410c6a2802002201450d0020052802002100200141286c210103400240200041046a280200450d00200028020010010b0240200041106a280200450d002000410c6a28020010010b200041286a2100200141586a22010d000b0b200441086a280200450d092005280200100120022003470d0a0c0b0b200441086a280200450d08200441046a280200100120022003470d090c0a0b200441086a280200450d07200441046a280200100120022003470d080c090b200441086a280200450d06200441046a280200100120022003470d070c080b200441046a210602402004410c6a2802002200450d002006280200220520004104746a21070340024020052802082201450d0020052802002100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010010b200041106a2100200141706a22010d000b0b200541106a21000240200541046a280200450d00200528020010010b2000210520002007470d000b0b200441086a280200450d052006280200100120022003470d060c070b200441046a210502402004410c6a2802002201450d0020052802002100200141146c210103400240200041046a280200450d00200028020010010b200041146a21002001416c6a22010d000b0b200441086a280200450d042005280200100120022003470d050c060b200441046a210602402004410c6a2802002200450d00200628020022052000411c6c6a2107034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010010b200041106a2100200141706a22010d000b0b0240200541086a280200450d00200541046a28020010010b2005411c6a21000240200541146a280200450d00200528021010010b2000210520002007470d000b0b200441086a280200450d032006280200100120022003470d040c050b200441046a210602402004410c6a2802002200450d0020062802002205200041186c6a210703400240200541046a280200450d00200528020010010b0240200541146a2802002201450d00200528020c2100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010010b200041106a2100200141706a22010d000b0b200541186a21000240200541106a280200450d002005410c6a28020010010b2000210520002007470d000b0b200441086a280200450d022006280200100120022003470d030c040b200441046a210602402004410c6a2802002200450d00200628020022052000411c6c6a2107034002402005410c6a2802002201450d0020052802042100200141047421010340024020002d00004109470d00200041086a28020041ffffffff0371450d00200041046a28020010010b200041106a2100200141706a22010d000b0b0240200541086a280200450d00200541046a28020010010b2005411c6a21000240200541146a280200450d00200528021010010b2000210520002007470d000b0b200441086a280200450d012006280200100120022003470d020c030b024002400240200441046a2d000022004102460d0020004101460d0120000d022004410c6a280200450d03200441086a280200100120022003470d040c050b2004410c6a21080240200441146a2802002200450d002008280200220620004104746a210903402006220741106a2106024020072802042200450d0002402007410c6a2802002201450d002001410c6c21010340024020002802002205450d00200041046a280200450d00200510010b2000410c6a2100200141746a22010d000b0b200741086a280200450d00200741046a28020010010b20062009470d000b0b200441106a280200450d022008280200100120022003470d030c040b2004410c6a21070240200441146a2802002201450d00200728020021002001410c6c21010340024020002802002205450d00200041046a280200450d00200510010b2000410c6a2100200141746a22010d000b0b200441106a280200450d012007280200100120022003470d020c030b2004410c6a280200450d00200441086a28020010010b20022003470d000b0b0bfe1f03087f017e177f230041e0036b22032400200341d0026a41106a2204200141106a280200360200200341d0026a41086a2205200141086a290200370300200320012902003703d0022003200341d0026a1053024002400240024002400240024002400240410110002201450d00200141003a0000200320032f01d0023b01c001200441e0083b01002005428180808010370300200320013602d402200341013602d002200320032f01c0013b01e2022003200341d0026a105b2106410310002204450d01200441026a41002d0098b9413a0000200441002f0096b9413b0000410310002205450d02200541026a41002d008680413a0000200541002f008480413b0000200341c0016a41026a2207200341d0026a41026a22082d00003a0000200320032f00d0023b01c001200341146a2209280200210a200341106a2802002101200820072d00003a0000200320032f01c0013b01d002024002400240024002400240024002400240200a2001470d00200141016a220a2001490d0120014101742207200a200a2007491b2208ad42287e220b422088a70d01200ba7220a4100480d01024002402001450d002003410c6a280200210c200a10002207450d0e2007200c200a200141286c22012001200a4b1b10f8021a200c10010c010b200a10002207450d0d0b200341106a20083602002003410c6a2007360200200341146a280200210a0b2003410c6a280200200a41286c6a220141003a00182001200536020c200142838080803037020420012004360200200141106a4283808080303702002001411b6a200341d2026a2d00003a0000200141196a20032f01d0023b00002001411c6a20063602002009200928020041016a360200200341d0026a2003418c0110f8021a20034190016a200341d0026a105620034190016a41106a2802002208412c6c2101200328029801220741586a210402400340410021052001450d01200141546a2101200441286a210a2004412c6a22092104200a2d00004103470d000b200941086a2802002201450d00200141286c2104200928020041186a2101410021050340200520012d0000456a2105200141286a2101200441586a22040d000b0b2008412c6c2101200741586a21042005417f6a210a02400340410021052001450d01200141546a2101200441286a21092004412c6a2206210420092d00004103470d000b200641086a2802002201450d00200141286c2104200628020041186a2101410021050340200520012d0000456a2105200141286a2101200441586a22040d000b0b2008412c6c2101200741606a210402400240024003402001450d01200141546a2101200441206a21092004412c6a2206210420092d00004104470d000b2006280200210120080d010c020b410021012008450d010b200120056a210d20072008412c6c6a210e200241046a210f200241106a211041002111410021080240034002400240024020072d00002201410b460d0002402001410a460d0020014108470d02200728020c2201450d02200141146c2104200728020441106a2101034002402001417c6a2802000d0020012802002205200a490d002001200541016a3602000b200141146a21012004416c6a22040d000c030b0b200728020c2201450d01200728020422092001411c6c6a2106034020092201411c6a2109024020012802182204450d0020012802102101200441027421040340024020012802002205200a490d002001200541016a3602000b200141046a21012004417c6a22040d000b0b20092006470d000c020b0b200728020c2201450d0020072802042212200141186c6a2113034020082114024020122802144104742204450d00201228020c21010340024020012d0000410b470d00200141046a22052802002209200a490d002005200941016a3602000b200141106a2101200441706a22040d000b0b410810002215450d082015428080808010370200410410002216450d092012410c6a210520164100360200024002400240201241146a22172802002218450d0041002104410121082015210141012106201621192016211a4101211b4101210941002018220c4f0d0a02400340200441016a211d02400240024002400240024002400240024002400240024002400240024002400240200528020020044104746a2d00002204417e6a41034f0d002004105c211e200241086a280200211f200f210403402004280200221c41086a2120201c2f0106210c4100210402400340200c2004460d014100417f4101202020046a2d00002221201e41ff017122224b1b20212022461b2221450d04200441016a210420214101460d000b2004417f6a210c0b0240201f450d00201f417f6a211f201c200c4102746a41ec006a21040c010b0b2002210c2009417f6a22042009490d020c180b20044105460d0220044106470d032009450d172009417f6a21090c0b0b02400240201c20044103746a41146a2204450d002004280200221c4101460d182002210c201c4102470d01200441046a210c2009417f6a22042009490d020c180b2002210c0b2009417f6a220420094f0d160b200420094b0d152006201620044102746a28020022044d0d15200120044103746a221c2802042204200c2802006a220c2004490d15201c41046a200c360200024020082006470d00200841016a22012008490d1a20084101742204200120012004491b220cad420386220b422088a70d1a200ba722044100480d1a2008450d04200410002201450d1e20012015200420084103742208200820044b1b10f8021a201510010c050b2008210c0c050b2009450d1420082006470d01200841016a22042008490d182008410174220c20042004200c491b220cad420386220b422088a70d18200ba722044100480d182008450d09200410002215450d1e20152001200420084103742208200820044b1b10f8021a200110010c0a0b2004105c211e200241086a280200211f200f2104024003402004280200221c41086a2120201c2f0106210c4100210402400340200c2004460d014100417f4101202020046a2d00002221201e41ff017122224b1b20212022461b2221450d03200441016a210420214101460d000b2004417f6a210c0b0240201f450d00201f417f6a211f201c200c4102746a41ec006a21040c010b0b2002210c2009417f6a22042009490d070c140b201c20044103746a41146a2204450d042004280200221c4101460d132002210c201c4102470d05200441046a210c2009417f6a22042009490d060c130b2008210c0c090b200410002201450d190b200121150b200120064103746a220441013602042004201d3602000240024002400240201b2009470d00201b41016a2204201b490d17201b4101742208200420042008491b221cad420286220b422088a70d17200ba722044100480d17201b450d01200410002216450d1c2016201a2004201b4102742208200820044b1b10f8021a201a10010c020b201b211c0c020b200410002216450d1a0b201621192016211a0b200641016a2104201620094102746a2006360200200941016a2109201d2018490d070c090b2002210c0b2009417f6a220420094f0d0d0b200420094b0d0c2006201620044102746a28020022044d0d0c200120044103746a221c2802042204200c2802006a220c2004490d0c201c41046a200c3602000b2008210c20062104201b211c201d2018490d030c050b200410002215450d140b201521010b200120064103746a220441013602042004201d3602000240024002400240201b2009417f6a2208470d00201b4101742204200920092004491b221cad420286220b422088a70d10200ba722044100480d10201b450d01200410002216450d17201620192004201b410274221b201b20044b1b10f8021a201910010c020b201b211c0c020b200410002216450d150b201621192016211a0b200641016a2104201620084102746a2006360200201d20184f0d020b200c210820042106201c211b201d22042017280200220c4f0d0c0c000b0b2004450d02200120044103746a21060c010b201541086a21064101211c4101210c201521010b4101210403402001290200210b2003412d3a00d0022003200b4220883e02d40220052004200ba76a2209417f6a200341d0026a105d2003410b3a00d0022003200a3602d40220052009200341d0026a105d200441026a21042006200141086a2201470d000b0b0240200c450d00201510010b0240201c450d00201610010b201241186a211202402010280200450d0020172802002204450d002005280200210120044104742104410021050340024020012d0000412c470d002001410b3a0000200141046a200d360200200541016a21050b200141106a2101200441706a22040d000b410121082005450d0020122013470d010c020b2014210820122013470d000b0b2007412c6a2207200e470d010c020b02402008450d00201510010b410121110240201b450d00201610010b201421082007412c6a2207200e470d000b0b02402011410171450d00200020032903900137020420004101360200200041146a200341a0016a2802003602002000410c6a20034198016a290300370200200341e0036a24000f0b2008410171450d00200341d0026a41106a20034190016a41106a280200360200200341d0026a41086a20034190016a41086a29030037030020032003290390013703d002200341c0016a200341d0026a1053411010002204450d0d200441063a0000410110002201450d0e200141003a0000410110002209450d0f200920012d00003a000020011001411010002205450d10200541063a000041f00010002201450d11200141063a00602001412c3b01502001200a3602442001410b3a0040200141d8003a00302001412d3a0020200141003602142001410f3a0010200141003602042001410f3a00002001200241106a280200360224024020052d00004109470d00200528020841ffffffff0371450d00200528020410010b20051001024020042d00004109470d00200428020841ffffffff0371450d00200428020410010b20041001200341f4026a4287808080f000370200200341f0026a2001360200200341ec026a4100360200200341d0026a410c6a4281808080800c370200200341d0026a41086a4101360200200341003602fc02200342043702e402200320093602d402200341013602d002200341c0016a200341d0026a1055200341d0026a200341c0016a418c0110f8021a200341a8016a200341d0026a105620004100360200200041146a200341b8016a2802003602002000410c6a200341a8016a41086a290300370200200020032903a801370204200341e0036a24000f0b200020032903900137020420004100360200200041146a200341a0016a2802003602002000410c6a20034198016a290300370200200341e0036a24000f0b1018000b41c08ec2002004200c104e000b410841041019000b410441041019000b200441041019000b200441041019000b200441041019000b200441041019000b410141011019000b410341011019000b410341011019000b200a41041019000b411041081019000b410141011019000b410141011019000b411041081019000b41f00041081019000bd60a020f7f017e230041106b220224000240024002400240024002400240024002400240024020012802004101470d00200141106a2d000021032001410c6a2802002104200141086a280200210520012f0112210620012d0011210720012802042101200241086a2000104920022802082208200228020c22094104746a210a4100210b024020094104490d00200341ff0171210c0340024020082d000c200c470d0020082802082004470d002008280200210d4100210902400340200920044f0d01200120096a210e200d20096a210f200941016a2109200f2d0000200e2d0000460d000c020b0b200741ff017122094104472008410d6a2d0000220e410446220f460d00200e2009460d0920094104460d09200f0d090b02402008411c6a2d0000200c470d00200841186a2802002004470d00200841106a280200210d4100210902400340200920044f0d01200120096a210e200d20096a210f200941016a2109200f2d0000200e2d0000460d000c020b0b200741ff017122094104472008411d6a2d0000220e410446220f460d00200e2009460d0620094104460d06200f0d060b02402008412c6a2d0000200c470d00200841286a2802002004470d00200841206a280200210d4100210902400340200920044f0d01200120096a210e200d20096a210f200941016a2109200f2d0000200e2d0000460d000c020b0b200741ff017122094104472008412d6a2d0000220e410446220f460d00200e2009460d0720094104460d07200f0d070b02402008413c6a2d0000200c470d00200841386a2802002004470d00200841306a280200210d4100210902400340200920044f0d01200120096a210e200d20096a210f200941016a2109200f2d0000200e2d0000460d000c020b0b200741ff017122094104472008413d6a2d0000220e410446220f460d00200e2009460d0820094104460d08200f0d080b200b41046a210b200a200841c0006a22086b413f4b0d000b0b2008200a460d02200741ff017122104104470d01200341ff0171210c0340024020082d000c200c470d0020082802082004470d002008280200210d4100210902400340200920044f0d01200120096a210e200d20096a210f200941016a2109200f2d0000200e2d0000460d000c020b0b2008410d6a2d00004104460d080b200b41016a210b200841106a2208200a470d000c030b0b20012802042104200241106a240020040f0b200341ff0171210c0340024020082d000c200c470d0020082802082004470d002008280200210d4100210902400340200920044f0d01200120096a210e200d20096a210f200941016a2109200f2d0000200e2d0000460d000c020b0b2008410d6a2d000022092010470d0020094104470d060b200b41016a210b200841106a2208200a470d000b0b0240024002400240200041046a28020020002802082209470d00200941016a22082009490d092009410174220e20082008200e491b220fad4204862211422088a70d092011a7220e4100480d092009450d012000280200210b200e10002208450d0a2008200b200e200941047422092009200e4b1b10f8021a200b10010c020b200028020021080c020b200e10002208450d080b20002008360200200041046a200f360200200041086a28020021090b200820094104746a220920063b010e200920073a000d200920033a000c200920043602082009200536020420092001360200200041086a2204200428020041016a3602002002200010492002280204417f6a210b0c070b200b410172210b20050d030c060b200b410272210b20050d020c050b200b410372210b0b2005450d030b20011001200241106a2400200b0f0b1018000b200e41041019000b200241106a2400200b0bb505000240024002400240024002400240024002400240200041ff0171417f6a220041aa014b0d00024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000eab014a00000000000000000000000000010101010103030404050506060707080809094b0a0a0b0b0c0c0d0d4c4d0e0e0f0f10101111121213131414151516161717181819191a1a1b1b1c1c1d1d1e1e1f1f20204e212122224f2323242450252526262727282829292a2a512b2b2c2c2d2d2e2e2f2f30303131323233333434353536363737383839393a3a3b3b3c3c3d3d3e3e523f3f404041414242434344444545464647474848020202024a0b410a0f0b41080f0b41100f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41040f0b41050f0b41050f0b41050f0b41050f0b41060f0b41070f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410b0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b410c0f0b41000f0b41010f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b41000f0b41010f0b41030f0b41030f0b41000f0b41000f0b41000f0b41000f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410d0f0b410f0f0b410f0f0b410e0f0b410f0f0b410f0f0b410f0f0b410f0f0b410f0f0b410f0f0b410f0f0b41110f0b41120f0b41050f0b41130f0b41140f0b41000f0b41020f0b41000f0b41020f0b410e0b9a0203047f017e037f02400240200041086a28020022032001490d00024002400240024002402003200041046a280200470d00200341016a22042003490d0420034101742205200420042005491b2206ad4204862207422088a70d042007a722084100480d042003450d0120002802002109200810002205450d062005200920082003410474220a200a20084b1b10f8021a200910010c020b200341016a2104200028020021050c020b200810002205450d040b20002005360200200041046a20063602000b200520014104746a220541106a2005200320016b41047410f9021a200541086a200241086a29030037030020052002290300370300200041086a20043602000f0b1018000b41e88ec200104f000b200841081019000baf0201027f02400240024002402001410c6a2802002203417f6a220420034d0d00411610002201450d01200020013602042001410e6a41002900c08940370000200141086a41002900ba8940370000200141002900b28940370000200041086a4296808080e002370200200041013602000f0b0240200420026b220220044d0d00411b10002201450d02200020013602042001411a6a41002d00e289403a0000200141186a41002f00e089403b0000200141106a41002900d88940370000200141086a41002900d08940370000200141002900c88940370000200041086a429b808080b003370200200041013602000f0b200320024d0d022000200141046a28020020024104746a360204200041003602000f0b411641011019000b411b41011019000b41908fc20020022003104e000bf50201037f230041106b22032400024002402002450d00200320014100105e20032802004101470d01200020034104722202290200370200200041086a200241086a280200360200200341106a24000f0b20004100360200200341106a24000f0b02400240024002402001280200220420032802042205280208470d0020052d000c450d0120004100360200200341106a24000f0b0240200420026b220220044d0d00410f10002202450d022000428f808080f00137020420002002360200200241076a41002900aa8940370000200241002900a38940370000200341106a24000f0b2000410036020020012002360200200341106a24000f0b412510002202450d01200042a5808080d004370204200020023602002002411d6a410029009b8940370000200241186a41002900968940370000200241106a410029008e8940370000200241086a41002900868940370000200241002900fe8840370000200341106a24000f0b410f41011019000b412541011019000bcf0f03097f027e077f230041b0016b2202240002400240024002400240024002402000280200220341e8bdc000460d00200028020421040c010b41ec0010002203450d0141002104200341003b010620034100360200200341086a200241186a41e40010f8021a20004100360204200020033602000b200141ff01712105024002400340200341086a210720032f01062106410021080240034020062008460d014100417f4101200720086a2d0000220920054b1b20092005461b2209450d03200841016a210820094101460d000b2008417f6a21060b02402004450d002004417f6a2104200320064102746a41ec006a28020021030c010b0b2000200028020841016a3602082002200636021420022000360210200241003602082002200336020c20032f01062208410b4f0d01200341086a2205200641016a22096a200520066a2205200820066b10f9021a200520013a0000200341146a220820094103746a200820064103746a2205200341066a22082f010020066b41037410f9021a20054101360200200820082f010041016a3b0100200241b0016a24000f0b20022004360218200220003602202002200041086a360228200220083602242002200336021c200320084103746a41146a42013702000c050b41ec0010002205450d02200541003b010620054100360200200541086a200241186a41e40010f80221092003410e6a2d0000210a2003290244210b20092003410f6a200341066a22042f010041796a220810f8022109200541146a200341cc006a200841037410f8022107200441063b0100200520083b0106200b422088210c02400240200641064b0d00200341086a2208200641016a22096a200820066a2204200341066a22082f010020066b10f9021a200420013a0000200341146a220420094103746a200420064103746a220920082f010020066b41037410f9021a200941013602000c010b20092006417a6a22046a2009200641796a22066a2209200841ffff037120066b10f9021a200920013a0000200720044103746a200720064103746a2209200541066a22082f010020066b41037410f9021a200941013602000b200ca7210d200ba7210e200820082f010041016a3b01000240024020032802002208450d0003402005210f200a211020032f01042109200822072f01062208410a4d0d02419c0110002205450d04200541003b010620054100360200200541086a200241186a41940110f80221032007410e6a2d0000210a2007290244210b20032007410f6a200741066a22012f0100220641796a220810f8022111200541146a200741cc006a200841037410f8022112200541ec006a20074188016a2006417a6a220441027410f8022113200141063b0100200520083b010602402004450d00410021082013210303402003280200220620083b010420062005360200200341046a21032004200841016a2208470d000b0b200b422088210c02400240200941064b0d00200741086a2203200941016a22086a200320096a220320012f0100220620096b220410f9021a200320103a0000200741146a220320084103746a200320094103746a2203200441037410f9021a2003200e3602002003200d3602042001200641016a22033b0100200741ec006a2206200941027422016a41086a200620084102746a2204200341ffff0371220620086b41027410f9021a2004200f360200200920064f0d01200720016a41f0006a2108034020082802002203200941016a22093b010420032007360200200841046a210820062009470d000c020b0b20112009417a6a22036a2011200941796a22086a2204200541066a22062f010020086b10f9021a200420103a0000201220034103746a201220084103746a220420062f010020086b41037410f9021a2004200e3602002004200d360204200620062f010041016a22043b01002013200941027422016a416c6a201320034102746a2206200441ffff0371220920036b41027410f9021a2006200f360200200320094b0d00200520016a41d4006a2103034020032802002206200841016a22083b010420062005360200200341046a210320092008470d000b0b200ca7210d200ba7210e20072103200728020022080d000b0b419c0110002208450d04200841003b010620084100360200200841086a200241186a41940110f802210620082000280200220336026c200020083602002000200028020441016a360204200341003b010420032008360200200820082f010622034103746a220941186a200d360200200941146a200e360200200620036a200a3a0000200841ec006a200341016a22034102746a2005360200200820033b0106200520033b010420052008360200200241b0016a24000f0b200741086a2206200941016a22036a200620096a2206200820096b220510f9021a200620103a0000200741146a220620034103746a200620094103746a2206200541037410f9021a2006200e3602002006200d360204200741066a200841016a22083b0100200741ec006a220620094102746a41086a200620034102746a2206200841ffff0371220520036b41027410f9021a2006200f360200200920054f0d0420072003417f6a22084102746a41f0006a2103034020032802002206200841016a22083b010420062007360200200341046a210320052008470d000c050b0b41ec0041041019000b419c0141041019000b41ec0041041019000b419c0141041019000b200241b0016a24000b6b000240024020002d000022004101460d0020004102470d01200128021841a48cc000410b2001411c6a28020028020c1100000f0b200128021841978cc000410d2001411c6a28020028020c1100000f0b2001280218418b8cc000410c2001411c6a28020028020c1100000b130020004102360204200041b88fc2003602000bda0801047f0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001413f4b0d00200241046a280200200241086a2802002203470d01200341016a22042003490d1520034101742205200420042005491b22054100480d152003450d0520022802002106200510002204450d162004200620052003200320054b1b10f8021a200610010c060b2001418080014f0d01200241046a2802002205200241086a28020022036b41024f0d02200341026a22042003490d1420054101742203200420042003491b22034100480d142005450d0920022802002106200310002204450d162004200620032005200520034b1b10f8021a200610010c0a0b200228020021040c050b20014180808080044f0d01200241046a2802002205200241086a28020022036b41044f0d05200341046a22042003490d1220054101742203200420042003491b22034100480d122005450d0a20022802002106200310002204450d152004200620032005200520034b1b10f8021a200610010c0b0b200228020021040c080b200241046a280200200241086a2802002203470d04200341016a22042003490d1020034101742205200420042005491b22054100480d102003450d0b20022802002106200510002204450d142004200620052003200320054b1b10f8021a200610010c0c0b200510002204450d100b20022004360200200241046a2005360200200241086a28020021030b200241086a200341016a360200200420036a20014102743a0000200141037422010d0b0c0c0b200228020021040c060b200228020021040c080b200310002204450d0c0b20022004360200200241046a2003360200200241086a28020021030b200241086a200341026a360200200420036a20014102744101723b0000200141037422010d060c070b200310002204450d0a0b20022004360200200241046a2003360200200241086a28020021030b200241086a200341046a360200200420036a2001410274410272360000200141037422010d030c040b200510002204450d080b20022004360200200241046a2005360200200241086a28020021030b200241086a2206200341016a360200200420036a41033a00000240024002400240200241046a2802002205200628020022036b41044f0d00200341046a22042003490d0620054101742203200420042003491b22034100480d062005450d0120022802002106200310002204450d0b2004200620032005200520034b1b10f8021a200610010c020b200228020021040c020b200310002204450d090b20022004360200200241046a2003360200200241086a28020021030b200241086a200341046a360200200420036a200136000020014103742201450d010b200020016a210103402000280200200041046a28020020021064200041086a22002001470d000b0b0f0b1018000b200541011019000b200341011019000b200341011019000b200541011019000b200341011019000bc40901067f0240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001413f4b0d00200241046a2203280200200241086a22042802002205470d01200541016a22062005490d1420054101742207200620062007491b22074100480d142005450d0520022802002108200710002206450d162006200820072005200520074b1b10f8021a200810010c060b2001418080014f0d01200241046a22032802002207200241086a220428020022056b41024f0d02200541026a22062005490d1320074101742205200620062005491b22054100480d132007450d0920022802002108200510002206450d162006200820052007200720054b1b10f8021a200810010c0a0b200228020021060c050b20014180808080044f0d01200241046a22032802002207200241086a220428020022056b41044f0d05200541046a22062005490d1120074101742205200620062005491b22054100480d112007450d0a20022802002108200510002206450d152006200820052007200720054b1b10f8021a200810010c0b0b200228020021060c080b200241046a2203280200200241086a22042802002205470d04200541016a22062005490d0f20054101742207200620062007491b22074100480d0f2005450d0b20022802002108200710002206450d142006200820072005200520074b1b10f8021a200810010c0c0b200710002206450d100b20022006360200200241046a2007360200200241086a28020021050b2004200541016a360200200620056a20014102743a00000c0b0b200228020021060c060b200228020021060c080b200510002206450d0c0b20022006360200200241046a2005360200200241086a28020021050b2004200541026a360200200620056a20014102744101723b00000c060b200510002206450d0a0b20022006360200200241046a2005360200200241086a28020021050b2004200541046a360200200620056a20014102744102723600000c030b200710002206450d080b20022006360200200241046a2007360200200241086a28020021050b2004200541016a360200200620056a41033a0000024002400240024020032802002207200428020022056b41044f0d00200541046a22062005490d0520074101742205200620062005491b22054100480d052007450d0120022802002108200510002206450d0b2006200820052007200720054b1b10f8021a200810010c020b200228020021060c020b200510002206450d090b20022006360200200241046a2005360200200241086a28020021050b2004200541046a360200200620056a20013600000b024002400240024020032802002206200428020022056b20014f0d00200520016a22032005490d0420064101742205200320032005491b22054100480d042006450d0120022802002107200510002203450d052003200720052006200620054b1b10f8021a200710010c020b200228020021030c020b200510002203450d030b20022003360200200241046a2005360200200241086a28020021050b2004200520016a360200200320056a2000200110f8021a0f0b1018000b200541011019000b200741011019000b200541011019000b200541011019000b200741011019000b200541011019000b850801047f02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402000413f4b0d00200141046a280200200141086a2802002202470d01200241016a22032002490d1320024101742204200320032004491b22044100480d132002450d0520012802002105200410002203450d142003200520042002200220044b1b10f8021a200510010c060b2000418080014f0d01200141046a2802002204200141086a28020022026b41024f0d02200241026a22032002490d1220044101742202200320032002491b22024100480d122004450d0920012802002105200210002203450d142003200520022004200420024b1b10f8021a200510010c0a0b200128020021030c050b20004180808080044f0d01200141046a2802002204200141086a28020022026b41044f0d05200241046a22032002490d1020044101742202200320032002491b22024100480d102004450d0a20012802002105200210002203450d132003200520022004200420024b1b10f8021a200510010c0b0b200128020021030c080b200141046a280200200141086a2802002202470d04200241016a22032002490d0e20024101742204200320032004491b22044100480d0e2002450d0b20012802002105200410002203450d122003200520042002200220044b1b10f8021a200510010c0c0b200410002203450d0e0b20012003360200200141046a2004360200200141086a28020021020b200141086a200241016a360200200320026a20004102743a00000f0b200128020021030c060b200128020021030c080b200210002203450d0a0b20012003360200200141046a2002360200200141086a28020021020b200141086a200241026a360200200320026a20004102744101723b00000f0b200210002203450d080b20012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20004102744102723600000f0b200410002203450d060b20012003360200200141046a2004360200200141086a28020021020b200141086a2205200241016a360200200320026a41033a00000240024002400240200141046a2802002204200528020022026b41044f0d00200241046a22032002490d0420044101742202200320032002491b22024100480d042004450d0120012802002105200210002203450d092003200520022004200420024b1b10f8021a200510010c020b200128020021030c020b200210002203450d070b20012003360200200141046a2002360200200141086a28020021020b200141086a200241046a360200200320026a20003600000f0b1018000b200441011019000b200241011019000b200241011019000b200441011019000b200241011019000bcf0101027f200028020421020240024020002802004101470d002000410c6a2802002200200110652000450d01200041186c2103200241146a21000340200041706a280200200041746a280200200110642000417c6a280200200028020020011064200041186a2100200341686a22030d000c020b0b200041086a2802002200200110652000450d00200041186c2103200241146a21000340200041706a280200200041746a280200200110642000417c6a280200200028020020011064200041186a2100200341686a22030d000b0b0bb60201037f230041306b22022400024020002802004101470d00200041086a2802002000410c6a28020020011064200041146a280200200041186a280200200110642000411c6a20011068200241306a24000f0b200241086a2000280204110100200228020c200241106a28020020011064200241186a2802002002411c6a28020020011064200241206a22002001106802402000280200450d00200241086a411c6a28020021030240200241086a41246a2802002200450d00200041306c21044100210103400240200320016a2200410c6a280200450d00200041146a280200450d00200041106a28020010010b02402000411c6a280200450d00200041246a280200450d00200041206a28020010010b2004200141306a2201470d000b0b200241286a280200450d00200310010b200241306a24000be205010a7f200028020421020240024002400240024020002802004101470d002000410c6a2802002200200110652000450d01200041306c2103200141086a2104200141046a2105410021060340200220066a2200412c6a2f01002107024002400240024020052802002208200428020022096b41024f0d00200941026a220a2009490d0720084101742209200a200a2009491b22094100480d072008450d012001280200210b20091000220a450d08200a200b20092008200820094b1b10f8021a200b10010c020b2001280200210a0c020b20091000220a450d060b2001200a36020020052009360200200428020021090b2004200941026a360200200a20096a20073b0000200041046a280200200041086a280200200110642000410c6a20011066200041206a280200210902402000411c6a2802004101470d002009200041286a280200200110632003200641306a2206470d010c030b2009200041246a280200200110632003200641306a2206470d000c020b0b200041086a2802002200200110652000450d00200041306c2103200141086a2104200141046a2105410021060340200220066a2200412c6a2f01002107024002400240024020052802002208200428020022096b41024f0d00200941026a220a2009490d0620084101742209200a200a2009491b22094100480d062008450d012001280200210b20091000220a450d08200a200b20092008200820094b1b10f8021a200b10010c020b2001280200210a0c020b20091000220a450d060b2001200a36020020052009360200200428020021090b2004200941026a360200200a20096a20073b0000200041046a280200200041086a280200200110642000410c6a20011066200041206a280200210902402000411c6a2802004101470d002009200041286a280200200110632003200641306a2206470d010c020b2009200041246a280200200110632003200641306a2206470d000b0b0f0b1018000b200941011019000b200941011019000bdf0101027f230041206b22022400024020002802004101470d00200041086a2802002000410c6a28020020011064200041106a2001106a200241206a24000f0b200220002802041101002002280204200241086a280200200110642002410c6a2001106a0240200228020c450d00200241106a28020021030240200241186a2802002200450d002000413c6c2101200341306a210003400240200041786a280200450d002000280200450d002000417c6a28020010010b2000413c6a2100200141446a22010d000b0b200241146a280200450d00200310010b200241206a24000b880f01097f200028020421020240024002400240024002400240024002400240024020002802004101470d002000410c6a2802002200200110652000450d012000413c6c2103410021040340200220046a220041046a280200200041086a28020020011064200141046a22052802002106200141086a220728020021080240024002400240024002400240024002400240200041386a2d00004101470d0020062008470d01200841016a22062008490d0d20084101742209200620062009491b22094100480d0d2008450d032001280200210a200910002206450d0e2006200a20092008200820094b1b10f8021a200a10010c040b20062008470d01200841016a22062008490d0c20084101742209200620062009491b22094100480d0c2008450d052001280200210a200910002206450d0e2006200a20092008200820094b1b10f8021a200a10010c060b200128020021060c030b200128020021060c050b200910002206450d0a0b2001200636020020052009360200200728020021080b2007200841016a360200200620086a41013a00000c030b200910002206450d080b2001200636020020052009360200200728020021080b2007200841016a360200200620086a41003a00000b200528020021062007280200210802400240024002400240024002400240024002402000410c6a2802004101470d0020062008470d01200841016a22062008490d0d20084101742209200620062009491b22094100480d0d2008450d032001280200210a200910002206450d102006200a20092008200820094b1b10f8021a200a10010c040b20062008470d01200841016a22062008490d0c20084101742209200620062009491b22094100480d0c2008450d052001280200210a200910002206450d102006200a20092008200820094b1b10f8021a200a10010c060b200128020021060c030b200128020021060c050b200910002206450d0c0b2001200636020020052009360200200728020021080b2007200841016a360200200620086a41013a0000200041146a280200200041186a28020020011064200041206a280200200041246a280200200110640c030b200910002206450d0a0b2001200636020020052009360200200728020021080b2007200841016a360200200620086a41003a0000200041146a280200200041186a280200200110640b2000412c6a28020021080240200041286a2802004101470d002008200041346a2802002001106320032004413c6a2204470d010c030b2008200041306a2802002001106320032004413c6a2204470d000c020b0b200041086a2802002200200110652000450d002000413c6c2103410021040340200220046a220041046a280200200041086a28020020011064200141046a22052802002106200141086a220728020021080240024002400240024002400240024002400240200041386a2d00004101470d0020062008470d01200841016a22062008490d0c20084101742209200620062009491b22094100480d0c2008450d032001280200210a200910002206450d112006200a20092008200820094b1b10f8021a200a10010c040b20062008470d01200841016a22062008490d0b20084101742209200620062009491b22094100480d0b2008450d052001280200210a200910002206450d112006200a20092008200820094b1b10f8021a200a10010c060b200128020021060c030b200128020021060c050b200910002206450d0d0b2001200636020020052009360200200728020021080b2007200841016a360200200620086a41013a00000c030b200910002206450d0b0b2001200636020020052009360200200728020021080b2007200841016a360200200620086a41003a00000b200528020021062007280200210802400240024002400240024002400240024002402000410c6a2802004101470d0020062008470d01200841016a22062008490d0c20084101742209200620062009491b22094100480d0c2008450d032001280200210a200910002206450d132006200a20092008200820094b1b10f8021a200a10010c040b20062008470d01200841016a22062008490d0b20084101742209200620062009491b22094100480d0b2008450d052001280200210a200910002206450d132006200a20092008200820094b1b10f8021a200a10010c060b200128020021060c030b200128020021060c050b200910002206450d0f0b2001200636020020052009360200200728020021080b2007200841016a360200200620086a41013a0000200041146a280200200041186a28020020011064200041206a280200200041246a280200200110640c030b200910002206450d0d0b2001200636020020052009360200200728020021080b2007200841016a360200200620086a41003a0000200041146a280200200041186a280200200110640b2000412c6a28020021080240200041286a2802004101470d002008200041346a2802002001106320032004413c6a2204470d010c020b2008200041306a2802002001106320032004413c6a2204470d000b0b0f0b1018000b200941011019000b200941011019000b200941011019000b200941011019000b200941011019000b200941011019000b200941011019000b200941011019000be103010c7f230041206b22032400024002402002450d0020024102742204100022050d01200441041019000b410421050b0240024002400240200120024103746a22062001460d0020024103742107200141046a210420052108034020082004280200360200200441086a2104200841046a2108200741786a22070d000b200641786a20016b41037641016a21094101210a410021084100210703402001280200210b02400240024002402008200722046b200141046a280200220c4f0d002004200c6a22072004490d072008410174220d20072007200d491b220d4100480d072008450d01200d1000220e450d08200e200a200d20082008200d4b1b10f8022108200a10012008210a0c020b200c20046a21070c020b200d1000220a450d060b200d21080b200a20046a200b200c10f8021a200141086a22012006470d000c020b0b4101210a41002109410021080b200341186a22014200370300200341106a22044200370300200341086a2207420037030020034200370300200a2005200920031005200041186a2001290300370000200041106a2004290300370000200041086a20072903003700002000200329030037000002402008450d00200a10010b02402002450d00200510010b200341206a24000f0b1018000b200d41011019000b2700200028020c200041106a2802001006200041146a3502001007200041186a350200100700000ba50801117f230041c0006b22032400200341086a411c6a22042001360200200341346a2205200241146a2802002201360200200341033a0038200341086a41246a220620022802102207200141037422086a360200200342808080808004370308200320003602204100210120034100360218200341003602102003200736023020032007360228200228020441037421092002280200210a02400240024002400240024002400240024020022802082200450d002000411c6a21072002410c6a28020041246c2102200341206a210b200341386a210c200341306a210d200341086a41086a210e200341086a41146a210f200341186a2110200341286a211103402002450d0220092001460d05200b280200200a20016a2208280200200841046a280200200428020028020c1100000d04200c20002d00203a00002003200028020836020c2003200028020c360208410021080240024002400240200028021822124101460d00024020124103460d0020124102470d02201128020022132006280200460d002011201341086a36020020132802044104470d04201328020028020021120c030b0c030b20072802002213200528020022124f0d0b200d28020020134103746a22132802044104470d02201328020028020021120c010b200728020021120b410121080b200341086a410c6a2012360200200e2008360200410021080240024002400240200028021022124101460d00024020124103460d0020124102470d02201128020022132006280200460d002011201341086a36020020132802044104470d04201328020028020021120c030b0c030b200741786a2802002213200528020022124f0d0c200d28020020134103746a22132802044104470d02201328020028020021120c010b200741786a28020021120b410121080b200f2012360200201020083602000240024020002802004101470d00200741686a2802002208200528020022124f0d08200d28020020084103746a21080c010b201128020022082006280200460d082011200841086a3602000b200041246a21002002415c6a2102200741246a2107200141086a21012008280200200341086a200841046a280200110200450d000c040b0b200341206a211120092101200a210003402008450d022001450d0420112802002000280200200041046a280200200428020028020c1100000d03200841786a2108200141786a2101200041086a21002007280200210220072802042112200741086a21072002200341086a2012110200450d000c030b0b200a20016a21000b2000200a20096a460d01200341206a28020020002802002000280204200341246a28020028020c110000450d010b200341c0006a240041010f0b200341c0006a240041000f0b41a093c20020082012104e000b41b092c200104f000b419093c20020132012104e000b419093c20020132012104e000b900101017f230041c0006b220024002000413336020c200041e08ec000360208200041286a410c6a4105360200200041246a4102360200200041106a410c6a41023602002000410136022c2000418489c20036021820004102360214200041a4aec3003602102000200041386a3602302000200041086a3602282000200041286a360220200041106a41b4aec3001071000b1c00200128021841c1afc00041052001411c6a28020028020c1100000b1000200120002802002000280204107c0b4a02017f017e230041206b2202240020012902002103200241146a20012902083702002002200337020c200220003602082002418891c20036020420024188f0c1003602002002106c000b02000bd20101047f024002400240024002400240200028020022002802042203200028020822046b20024f0d00200420026a22052004490d0420034101742204200520052004491b22044100480d042003450d0120002802002106200410002205450d052005200620042003200320044b1b10f8021a200610010c020b200028020021050c020b200410002205450d030b20002005360200200041046a2004360200200041086a28020021040b200041086a200420026a360200200520046a2001200210f8021a41000f0b1018000b200441011019000be90401057f230041106b22022400200028020021000240024002400240024002400240024002400240024020014180014f0d00200028020822032000280204470d03200341016a22042003490d0820034101742205200420042005491b22044100480d082003450d0120002802002106200410002205450d092005200620042003200320044b1b10f8021a200610010c020b2002410036020c0240024020014180104f0d0020022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b0240200141ffff034b0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b024020002802042205200028020822036b20014f0d00200320016a22042003490d0820054101742203200420042003491b22034100480d082005450d0420002802002106200310002204450d0a2004200620032005200520034b1b10f8021a200610010c050b200028020021040c050b200410002205450d070b20002005360200200041046a2004360200200041086a28020021030b200028020020036a20013a0000200041086a2200200028020041016a3602000c030b200310002204450d050b20002004360200200041046a2003360200200041086a28020021030b200041086a200320016a360200200420036a2002410c6a200110f8021a0b200241106a240041000f0b1018000b200441011019000b200341011019000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41e090c200200241086a106d2101200241206a240020010b890101017f230041306b220224002002200136020420022000360200200241206a410c6a41033602002002411c6a4102360200200241086a410c6a4102360200200241033602242002418489c2003602102002410236020c2002419891c2003602082002200241046a360228200220023602202002200241206a360218200241086a41a891c2001071000b9a0a01047f230041206b2206240020062003360204200620023602002006418080c4003602080240024002402001450d00200028020022074101710d01200521080c020b2006412d360208200541016a2108200028020021070c010b2006412b360208200541016a21080b41002101200641003a000f02402007410471450d00200641013a000f02402003450d0041002101200321090340200120022d000041c00171418001466a2101200241016a21022009417f6a22090d000b0b200820036a20016b21080b200028020821022006200636021820062006410f6a3602142006200641086a3602100240024002400240024002400240024002400240024002400240024002400240024020024101470d002000410c6a280200220220084d0d0120074108710d02200220086b2109410120002d0030220220024103461b4103712202450d0420024102460d03410021030c050b200641106a200010790d0e2000280218200420052000411c6a28020028020c1100002102200641206a240020020f0b200641106a200010790d0d2000280218200420052000411c6a28020028020c1100002102200641206a240020020f0b200041013a003020004130360204200641106a200010790d0c200220086b21094101200041306a2d0000220220024103461b4103712202450d0420024102460d03410021030c050b200941016a4101762103200941017621090c010b20092103410021090b2006410036021c02402000280204220241ff004b0d00200620023a001c410121010c050b0240200241ff0f4b0d0020062002413f71418001723a001d20062002410676411f7141c001723a001c410221010c050b200241ffff034b0d0320062002413f71418001723a001e20062002410676413f71418001723a001d20062002410c76410f7141e001723a001c410321010c040b200941016a4101762103200941017621090c010b20092103410021090b2006410036021c0240200041046a280200220241ff004b0d00200620023a001c410121010c060b200241ff0f4b0d0220062002413f71418001723a001d20062002410676411f7141c001723a001c410221010c050b20062002413f71418001723a001f2006200241127641f001723a001c20062002410676413f71418001723a001e20062002410c76413f71418001723a001d410421010b417f210202400340200241016a220220094f0d01200041186a2802002006411c6a20012000411c6a28020028020c110000450d000c060b0b200641106a200010790d04200041186a2209280200200420052000411c6a220028020028020c1100000d04417f21020340200241016a220220034f0d0220092802002006411c6a2001200028020028020c110000450d000c050b0b200241ffff034b0d0120062002413f71418001723a001e20062002410676413f71418001723a001d20062002410c76410f7141e001723a001c410321010c020b200641206a240041000f0b20062002413f71418001723a001f2006200241127641f001723a001c20062002410676413f71418001723a001e20062002410c76413f71418001723a001d410421010b417f210202400340200241016a220220094f0d01200041186a2802002006411c6a20012000411c6a28020028020c110000450d000c020b0b200041186a2209280200200420052000411c6a220028020028020c1100000d00417f21020340200241016a220220034f0d0220092802002006411c6a2001200028020028020c110000450d000b0b200641206a240041010f0b200641206a240041000b0d0042b4d39cd2fdebc6cdde000be80201057f230041106b2202240002400240024020002802002802002203418080c400460d002001411c6a2802002104200128021821052002410036020c02400240200341ff004b0d00200220033a000c410121060c010b0240200341ff0f4b0d0020022003413f71418001723a000d20022003410676411f7141c001723a000c410221060c010b0240200341ffff034b0d0020022003413f71418001723a000e20022003410676413f71418001723a000d20022003410c76410f7141e001723a000c410321060c010b20022003413f71418001723a000f2002200341127641f001723a000c20022003410676413f71418001723a000e20022003410c76413f71418001723a000d410421060b4101210320052002410c6a2006200428020c1100000d010b20002802042d0000450d0120012802182000280208220028020020002802042001411c6a28020028020c11000021030b200241106a240020030f0b200241106a240041000b890101017f230041306b220224002002200136020420022000360200200241206a410c6a41033602002002411c6a4102360200200241086a410c6a4102360200200241033602242002418489c2003602102002410236020c200241b891c2003602082002200241046a360228200220023602202002200241206a360218200241086a41c891c2001071000bda0203037f017e027f230041306b220224004127210302400240024020004290ce00540d00412721030340200241096a20036a2204417c6a200020004290ce0080220542f0b17f7e7ca7220641e4006e2207410174419892c0006a2f00003b00002004417e6a2007419c7f6c20066a410174419892c0006a2f00003b00002003417c6a2103200042ffc1d72f5621042005210020040d000b41e40021062005a7220441e400480d020c010b41e400210620002205a7220441e400480d010b200241096a2003417e6a22036a2005a7220741ffff037120066e2204419c7f6c20076a41ffff0371410174419892c0006a2f00003b00000b02400240200441094a0d00200241096a2003417f6a22036a2206200441306a3a00000c010b200241096a2003417e6a22036a22062004410174419892c0006a2f00003b00000b200141014188f0c10041002006412720036b10772103200241306a240020030bfb09010c7f230041106b2203240020002802102104024002400240024002400240024002400240200028020822054101470d0020040d010c020b2004450d070b02402002450d00200120026a2106200041146a280200417f732107410021082001210420012109024002400340200441016a210a0240024020042c0000220b4100480d00200b41ff0171210b200a2104200741016a22070d010c030b024002400240200a2006460d00200a2d0000413f71210c200441026a2204210a200b411f71210d200b41ff0171220b41e001490d010c020b4100210c20062104200b411f71210d200b41ff0171220b41e0014f0d010b200c200d41067472210b200a2104200741016a22070d010c030b02400240024020042006460d00200441016a220a210e20042d0000413f71200c41067472210c200b41f001490d010c020b2006210e4100200c41067472210c200b41f0014f0d010b200c200d410c7472210b200a2104200741016a22070d010c030b02400240200e2006460d00200e41016a2104200e2d0000413f71210b0c010b4100210b200a21040b200c410674200d411274418080f0007172200b72220b418080c400460d03200741016a2207450d020b200820096b20046a21082004210920062004470d000c020b0b200b418080c400460d00024002402008450d0020082002460d0041002104200820024f0d01200120086a2c00004140480d010b200121040b2008200220041b21022004200120041b21010b2005450d020c010b410021022005450d010b4100210a02402002450d002002210b200121040340200a20042d000041c00171418001466a210a200441016a2104200b417f6a220b0d000b0b2002200a6b2000410c6a28020022074f0d014100210a02402002450d004100210a2002210b200121040340200a20042d000041c00171418001466a210a200441016a2104200b417f6a220b0d000b0b200a20026b20076a210b410020002d0030220420044103461b4103712204450d0220044102460d03410021070c040b2000280218200120022000411c6a28020028020c1100002104200341106a240020040f0b2000280218200120022000411c6a28020028020c1100002104200341106a240020040f0b200b21074100210b0c010b200b41016a4101762107200b410176210b0b2003410036020c024002402000280204220441ff004b0d00200320043a000c4101210a0c010b0240200441ff0f4b0d0020032004413f71418001723a000d20032004410676411f7141c001723a000c4102210a0c010b0240200441ffff034b0d0020032004413f71418001723a000e20032004410676413f71418001723a000d20032004410c76410f7141e001723a000c4103210a0c010b20032004413f71418001723a000f2003200441127641f001723a000c20032004410676413f71418001723a000e20032004410c76413f71418001723a000d4104210a0b417f21040240024002400340200441016a2204200b4f0d01200041186a2802002003410c6a200a2000411c6a28020028020c110000450d000c020b0b200041186a220b280200200120022000411c6a220028020028020c110000450d010b200341106a240041010f0b417f210402400340200441016a220420074f0d01200b2802002003410c6a200a200028020028020c110000450d000b200341106a240041010f0b200341106a240041000f0b2000280218200120022000411c6a28020028020c1100002104200341106a240020040bd00901067f230041f0006b220424002004200336020c20042002360208410121052001210602402001418102490d00410020016b21074180022108024003400240200820014f0d00200020086a2c000041bf7f4a0d020b2008417f6a21064100210520084101460d02200720086a21092006210820094101470d000c020b0b41002105200821060b200420063602142004200036021020044100410520051b36021c20044188f0c10041ae94c00020051b360218024002400240024002400240024002400240200220014b22080d00200320014b0d00200220034b0d02024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200420023602202002450d0120022001460d01200141016a2109024003400240200220014f0d00200020026a22062c000041bf7f4a0d020b2002417f6a2108024020024101460d0020092002462106200821022006450d010b0b200020086a2206200020016a2202470d040c050b200221082006200020016a2202460d040c030b20042002200320081b360228200441c8006a41146a4101360200200441c8006a410c6a4101360200200441306a41146a4103360200200441306a410c6a41033602002004410336024c200441b0b3c10036023820044103360234200441d891c2003602302004200441186a3602582004200441106a3602502004200441286a3602482004200441c8006a360240200441306a41f091c2001071000b2000200222086a2206200020016a2202470d010c020b200441e4006a4101360200200441c8006a41146a4101360200200441c8006a410c6a4103360200200441306a41146a4104360200200441306a410c6a41043602002004410336024c200441b494c000360238200441043602342004418092c2003602302004200441186a3602602004200441106a36025820042004410c6a3602502004200441086a3602482004200441c8006a360240200441306a41a092c2001071000b4101210141002109024020062c000022064100480d002004200641ff0171360224200441286a21020c050b200221010240200020086a220041016a2002460d00200041026a2101200041016a2d0000413f7121090b2006411f712100200641ff017141e001490d014100210520022107024020012002460d00200141016a210720012d0000413f7121050b20052009410674722101200641ff017141f001490d0241002106024020072002460d0020072d0000413f7121060b20014106742000411274418080f00071722006722206418080c400470d030b41b092c200104f000b200920004106747221060c010b20012000410c747221060b2004200636022441012101200441286a21022006418001490d00410221012006418010490d0041034104200641808004491b21010b200420083602282004200120086a36022c200441ec006a4101360200200441e4006a4101360200200441c8006a41146a4106360200200441c8006a410c6a4107360200200441306a41146a4105360200200441306a410c6a4105360200200420023602582004410336024c200441c495c00036023820044105360234200441c892c2003602302004200441186a3602682004200441106a3602602004200441246a3602502004200441206a3602482004200441c8006a360240200441306a41f092c2001071000b950101017f230041306b22022400200241086a410c6a41083602002002410836020c200220003602082002200041046a3602102001411c6a2802002100200128021821012002412c6a4102360200200241186a410c6a41023602002002418489c2003602202002410236021c2002418093c2003602182002200241086a36022820012000200241186a106d2101200241306a240020010bad0b03037f017e047f410121020240200128021841272001411c6a2802002802101102000d00410221020240024002400240024002400240024002400240024002400240024002402000280200220341776a2200411e4b0d0041f4002104024020000e1f0f0002020302020202020202020202020202020202020202020d020202020d0f0b41ee0021040c030b200341dc00460d0b0b2003108001450d02200341017267410276410773ad4280808080d0008421050c030b41f20021040b0c0a0b0240024002400240200341ffff034b0d0020034180fe037141087621064198a4c000210041002107200341ff0171210402400340200041026a2108200720002d000122026a21090240024020002d000022002006470d0020092007490d09200941b0024f0d0a200741e8a4c0006a210003402002450d022002417f6a210220002d00002107200041016a210020072004470d000c080b0b200020064b0d022009210720082100200841e8a4c000470d010c020b2009210720082100200841e8a4c000470d000b0b200341ffff037121074197a7c0002102410121000340200241016a21040240024020022d000022094118744118752208417f4c0d0020042102200720096b220741004e0d010c040b200441d3a9c000460d0b200241016a2104200241026a21022007200841ff007141087420042d0000726b22074100480d030b20004101732100200241d3a9c000470d000c020b0b200341ffff074b0d0120034180fe0371410876210641d3a9c000210041002107200341ff0171210402400340200041026a2108200720002d000122026a21090240024020002d000022002006470d0020092007490d0a2009419f014f0d0b20074195aac0006a210003402002450d022002417f6a210220002d00002107200041016a210020072004470d000c070b0b200020064b0d02200921072008210020084195aac000470d010c020b200921072008210020084195aac000470d000b0b200341ffff0371210741b3abc0002102410121000340200241016a21040240024020022d000022094118744118752208417f4c0d0020042102200720096b220741004e0d010c030b200441b0aec000460d0b200241016a2104200241026a21022007200841ff007141087420042d0000726b22074100480d020b20004101732100200241b0aec000470d000b0b410121022000410171450d010c090b20034190fc476a4190fc0b490d00200341e28b746a41e28d2c490d002003419fa8746a419f18490d00200341dee2746a410e490d00200341feffff0071419ef00a460d00200341a9b2756a4129490d00200341cb91756a410a4d0d00410121020c080b200341017267410276410773ad4280808080d0008421050b410321020c070b20072009107a000b200941af021076000b20072009107a000b2009419e011076000b41b092c200104f000b41b092c200104f000b0b200321040b200141186a21072001411c6a21030340024002400240024002400240024020024101460d00024020024102460d0020024103470d062005422088a741ff0171417f6a220241044b0d06024020020e050006040503000b200542ffffffff8f6083210541fd002100410321020c070b41dc002100410121020c060b41002102200421000c050b200542ffffffff8f60834280808080c00084210541dc002100410321020c040b200542ffffffff8f608342808080802084210541fb002100410321020c030b200542ffffffff8f608342808080803084210541f5002100410321020c020b20042005a72209410274411c7176410f712202413072200241d7006a2002410a491b210002402009450d002005427f7c42ffffffff0f83200542808080807083842105410321020c020b200542ffffffff8f6083428080808010842105410321020c010b200141186a28020041272001411c6a28020028021011020021020c020b200728020020002003280200280210110200450d000b41010f0b20020b960201017f024002400240024002400240024020004180104f0d00200041037641f8ffffff017141b093c2006a21010c010b02402000418080044f0d00200041067641606a220141e0074f0d02200141c895c2006a2d0000220141c9004b0d032001410374419098c0006a21010c010b2000410c7641706a22014180024f0d03200141a89dc2006a2d00004106742000410676413f7172220141ff034b0d04200141e09cc0006a2d0000220141364b0d05200141037441e0a0c0006a21010b200129030042012000413f71ad86834200520f0b41a89fc200200141e007104e000b41b89fc200200141ca00104e000b41c89fc2002001418002104e000b41d89fc2002001418004104e000b41e89fc20020014137104e000bbb0201037f23004180016b220224000240024002400240200128020022034110710d0020034120710d01200020011058210020024180016a240020000f0b20002802002103410021000340200220006a41ff006a2003410f712204413072200441d7006a2004410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d012001410141ac94c0004102200220006a4180016a410020006b1077210020024180016a240020000f0b20002802002103410021000340200220006a41ff006a2003410f712204413072200441376a2004410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d012001410141ac94c0004102200220006a4180016a410020006b1077210020024180016a240020000f0b2003418001107a000b2003418001107a000b08002000200110580b1c00200128021841a8afc000410b2001411c6a28020028020c1100000b1c00200128021841b3afc000410e2001411c6a28020028020c1100000b2601017f20002802002201280200200128020420002802042802002000280208280200107d000baa0603057f027e017f02400240024002400240024002402002450d00200241796a4100200241074b1b210341002104034002400240024002400240200120046a22052d0000220641187441187522074100480d002005410371450d01200441016a22042002490d050c060b4280808080102108200641e68fc0006a2d000022054104460d0120054103460d0220054102470d06200441016a220520024f0d084280808080802021094280808080102108200120056a2d000041c00171418001460d030c0b0b0240200420034f0d000340200120046a220541046a280200200528020072418081828478710d01200441086a22042003490d000b0b0240200420024f0d000340200120046a2c00004100480d01200441016a22042002490d000b0b20042002490d030c040b42002109200441016a220520024f0d07200120056a2d000021050240024020074170470d00200541f0006a41ff0171412f4d0d010b0240200541ff0171220641bf014b0d002007410f6a41ff017141024b0d0020054118744118754100480d010b2006418f014b0d0520074174470d05200541187441187541004e0d050b200441026a220520024f0d07200120056a2d000041c00171418001470d0542002108200441036a220520024f0d09200120056a2d000041c00171418001460d010c080b42002109200441016a220520024f0d06200120056a2d000021050240024020074160470d00200541607141ff017141a001460d010b0240200541ff0171220641bf014b220a0d002007411f6a41ff0171410b4b0d0020054118744118754100480d010b02402006419f014b0d002007416d470d0020054118744118754100480d010b200a0d04200741fe017141ee01470d04200541187441187541004e0d040b42002108200441026a220520024f0d08200120056a2d000041c00171418001470d040b200541016a22042002490d000b0b20002001360204200041086a2002360200200041003602000f0b4280808080802021090c040b428080808080c000210942808080801021080c030b420021090b420021080c010b428080808080e000210942808080801021080b200020092008842004ad84370204200041013602000b6401027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a106d2100200241206a240020000b3201017f0240410810002202450d0020004288808080800137020420002002360200200220013700000f0b410841011019000bce0101047f024002400240024002400240200141046a2802002202200141086a28020022036b41044f0d00200341046a22042003490d0420024101742203200420042003491b22034100480d042002450d0120012802002105200310002204450d052004200520032002200220034b1b10f8021a200510010c020b200128020021040c020b200310002204450d030b20012004360200200141046a2003360200200141086a28020021030b200141086a200341046a360200200420036a20003600000f0b1018000b200341011019000b4b00200041ddf5c10036020420004100360200200041206a41023602002000411c6a41a8a0c200360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000b340020004182a0c10036020420004100360200200041146a4104360200200041106a41a0a3c200360200200041086a420e3702000b4b00200041ddf5c10036020420004100360200200041206a41023602002000411c6a41b0a5c200360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000bfe0601067f02400240024002400240024002400240200141c0004f0d0020022001410274102420010d010c020b024002400240024002400240024002400240024002400240024002402001418080014f0d00200241046a2802002203200241086a28020022046b41024f0d01200441026a22052004490d1020034101742204200520052004491b22044100480d102003450d0520022802002106200410002205450d122005200620042003200320044b1b10f8021a200610010c060b20014180808080044f0d01200241046a2802002203200241086a28020022046b41044f0d02200441046a22052004490d0f20034101742204200520052004491b22044100480d0f2003450d0720022802002106200410002205450d122005200620042003200320044b1b10f8021a200610010c080b200228020021050c050b200241031024200241046a2802002203200241086a28020022046b41044f0d01200441046a22052004490d0d20034101742204200520052004491b22044100480d0d2003450d0820022802002106200410002205450d112005200620042003200320044b1b10f8021a200610010c090b200228020021050c060b200228020021050c080b200410002205450d0c0b20022005360200200241046a2004360200200241086a28020021040b200241086a200441026a360200200520046a20014102744101723b00000c060b200410002205450d0a0b20022005360200200241046a2004360200200241086a28020021040b200241086a200441046a360200200520046a20014102744102723600000c030b200410002205450d080b20022005360200200241046a2004360200200241086a28020021040b200241086a200441046a360200200520046a20013600000b200020016a2107200241086a2105200241046a210603400240024002400240200628020020052802002201470d00200141016a22042001490d0620014101742203200420042003491b22034100480d062001450d0120022802002108200310002204450d072004200820032001200120034b1b10f8021a200810010c020b200228020021040c020b200310002204450d050b2002200436020020062003360200200528020021010b2005200141016a360200200420016a20002d00003a0000200041016a2201210020072001470d000b0b0f0b1018000b200341011019000b200441011019000b200441011019000b200441011019000bea0601067f02400240024002400240024002402001413f4b0d00200220014102741024200241046a2103200241086a21040c010b024002400240024002400240024002400240024002400240024002402001418080014f0d00200241046a22032802002205200241086a220428020022066b41024f0d01200641026a22072006490d0f20054101742206200720072006491b22064100480d0f2005450d0520022802002108200610002207450d112007200820062005200520064b1b10f8021a200810010c060b20014180808080044f0d01200241046a22032802002205200241086a220428020022066b41044f0d02200641046a22072006490d0e20054101742206200720072006491b22064100480d0e2005450d0720022802002108200610002207450d112007200820062005200520064b1b10f8021a200810010c080b200228020021070c050b200241031024200241046a22032802002205200241086a220428020022066b41044f0d01200641046a22072006490d0c20054101742206200720072006491b22064100480d0c2005450d0820022802002108200610002207450d102007200820062005200520064b1b10f8021a200810010c090b200228020021070c060b200228020021070c080b200610002207450d0b0b20022007360200200241046a2006360200200241086a28020021060b2004200641026a360200200720066a20014102744101723b00000c060b200610002207450d090b20022007360200200241046a2006360200200241086a28020021060b2004200641046a360200200720066a20014102744102723600000c030b200610002207450d070b20022007360200200241046a2006360200200241086a28020021060b2004200641046a360200200720066a20013600000b024002400240024020032802002207200428020022036b20014f0d00200320016a22062003490d0420074101742203200620062003491b22034100480d042007450d0120022802002105200310002206450d052006200520032007200720034b1b10f8021a200510010c020b200228020021060c020b200310002206450d030b20022006360200200241046a2003360200200241086a28020021030b2004200320016a360200200620036a2000200110f8021a0f0b1018000b200341011019000b200641011019000b200641011019000b200641011019000b13002000410236020420004188a7c2003602000b130020004105360204200041a0a8c2003602000bcd1b05037f027e057f047e027f230041e0006b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280200417f6a2203410b4b0d0002400240024020030e0c0008050602090a070b040c01000b2002200141086a10920120004101360200200041106a200241086a290300370300200041086a2002290300370300200241e0006a24000f0b4102210320012d000422044102460d0b4103210320044103470d2d200241186a200141046a220141196a290000370300200241106a200141116a290000370300200241086a200141096a290000370300200220012900013703000c0c0b2002200141086a10930120004105360200200041186a200241106a290300370300200041106a200241086a290300370300200041086a2002290300370300200241e0006a24000f0b200141086a2903004202520d2c20004100360200200041086a4202370300200041106a200141106a290300370300200241e0006a24000f0b200141086a280200417e6a220341044b0d2c024020030e05001b191a18000b41012103200141386a2903002105200141306a29030021062001410c6a2d00004101470d1f0c200b41022103200141086a22042d000022074102460d0f4103210320074103460d0e4104210320074104470d2c20042d000141004721010c100b200141086a2d0000417e6a220841094b0d2c4102210341002109024020080e0a35001d211b242522261c350b2001410c6a28020022094108762107410321030c220b20012d000422034102460d074103210420034103470d2c200241d2006a200141046a220341036a2d00003a0000200241086a200141186a2900003703002002410d6a2001411d6a290000370000200220032f00013b01502002200141106a290000370300200141256a2d00004100472107200141286a280200210a2001410c6a2800002103200141086a280000210b0c080b41022104200141086a28020022034102460d0820034103470d2c410121072001410c6a2d00004101470d0e0c0f0b2002200141086a10940120004106360200200041c0006a200241386a290300370300200041386a200241306a290300370300200041306a200241286a290300370300200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a290300370300200041086a2002290300370300200241e0006a24000f0b2002200141086a10950120004107360200200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a290300370300200041086a2002290300370300200241e0006a24000f0b20012802044102470d2a2002200141086a102b2000428980808020370300200041086a2002290200370200200041106a200241086a280200360200200241e0006a24000f0b41022104200141086a22032d000022074102460d054103210420074103470d2a200141306a2903002105200141286a2903002106200141386a290300210c200241c0006a2001410c6a102b200241d0006a200141186a102b2002410b6a200241c0006a41086a280200360000200241176a200241d0006a41086a280200360000200220022903403700032002200229035037000f4200210d4200210e0c060b200241d0006a200141086a102b2002410b6a200241d0006a41086a280200360000200220022903503700030b20002002290300370005200020033a0004200020022f00503b00252000410c3602002000410d6a200241086a290300370000200041156a200241106a2903003700002000411d6a200241186a290300370000200041276a200241d2006a2d00003a0000200241e0006a24000f0b200141086a280200210b41d00010002203450d2820032001410c6a280200109101410221040b200020022f01503b0005200020043a0004200020073a0025200041083602002000410c6a2003360200200041086a200b360200200041106a2002290300370200200041286a200a360200200041076a200241d2006a2d00003a0000200041186a200241086a2903003702002000411d6a2002410d6a290000370000200241e0006a24000f0b410121072001410c6a2d00004101470d070c080b200241176a200341186a290000370000200241106a200341116a290000370300200241086a200341096a29000037030020022003290001370300200141c0006a290300210e200141386a290300210c200141c8006a290300210f200141286a3100002106200241d0006a2001412c6a102b200241d0006a41086a3502004220862002290350220d4220888421052006200d4220868421064200210d0b200020022903003700092000410b360200200041c0006a200e370300200041386a200d200c84370300200041306a2005370300200041286a2006370300200041086a20043a0000200041c8006a200f370300200041116a200241086a290300370000200041196a200241106a290300370000200041206a200241176a290000370000200241e0006a24000f0b200141106a29030021050c010b200241d4006a200441066a2f00003b0100200241086a200141206a290000370300200241106a200141286a2d00003a00002002200441026a2800003602502002200141186a290000370300200141106a2900002105200141096a2d000021010b200020013a00092000200228025036010a20004103360200200041086a20033a0000200041106a2005370300200041186a20022903003703002000410e6a200241d4006a2f01003b0100200041206a200241086a290300370300200041286a200241106a290300370300200241e0006a24000f0b200141286a3500002001412c6a3100004220868421052001410d6a2f00002001410f6a2d0000411074722103200141246a280000210a200141206a280000210b200141186a2900002106200141146a2800002110410021070b200141c8006a290300210c200141c0006a290300210d410321040c020b200141286a3500002001412c6a3100004220868421052001410d6a2f00002001410f6a2d0000411074722103200141246a280000210a200141206a280000210b200141186a2900002106200141146a2800002110410021070b0b200020033b000d200041023602002000410f6a20034110763a0000200041c8006a200c370300200041c0006a200d370300200041286a2005370200200041246a200a360200200041206a200b360200200041186a2006370200200041146a20103602002000410c6a20073a0000200041086a2004360200200041386a200141386a290300370300200041306a200141306a290300370300200041106a200141106a280000360200200241e0006a24000f0b2001410c6a28020022034108762104410621010c030b200241106a200141206a2903003703002002200141186a2903003703082002200141106a2802003602002001410c6a28020022034108762104200141286a290300210c410421010c080b2001410c6a28020022034108762104410521010c010b2002200141186a2903003703082002200141106a29030037030041032101410021030b0c050b2001410c6a28020022094108762107200141186a2903002106200141206a2802002110200141106a2903002205a7210b2005422088a7210a410621030c180b2001410c6a28020022094108762107410b21030c060b410121092001410c6a2d00004101470d090c0a0b200141286a3500002001412c6a31000042208684210c2001410d6a2f00002001410f6a2d0000411074722104200141246a2800002107200141206a280000210a200141186a290000210d200141146a280000210b410021030b200220073602142002200a3602102002200d3703082002200b3602042002200141106a280000360200410221010b2000410a360200200041386a2005370300200041306a2006370300200041086a2001360200200041106a2002290300370300200041286a200c3703002000410c6a2004410874200341ff017172360200200041186a200241086a290300370300200041206a200241106a290300370300200241e0006a24000f0b2001410c6a28020022094108762107410521030c010b2001410c6a28020022094108762107410921030b0c0f0b200141106a2903002205a7210b2005422088a7210a410721030c0e0b200141106a2903002205a7210b2005422088a7210a410821030c0d0b41002109200141096a2d00004100472111410a21030c0e0b200141286a3500002001412c6a3100004220868421052001410d6a2f00002001410f6a2d0000411074722107200141246a2800002104200141206a2800002110200141186a2900002106200141146a280000210a410021090b200141106a280000210b410421030c0b0b41d8ccc200104f000b41a881c300104f000b41c0ccc200104f000b41acd5c200104f000b41a8ccc200104f000b418cabc200104f000b41c4aec300104f000b4180e8c200104f000b4188a8c200104f000b41d00041081019000b0b0b200020113a0009200020022f01003b010a20004104360200200041186a2006370300200041086a20033a0000200041286a2005370200200041246a2004360200200041206a20103602002000410c6a2007410874200941ff017172360200200041106a200aad422086200bad84370300200241e0006a24000bbb0503037f017e057f230041206b220224000240024002400240024002402001280200417e6a220341054b0d0002400240024002400240024020030e06000402030105000b200241086a200141046a102b200041023602002000410c6a200241106a28020036020020002002290308370204200241206a24000f0b200241086a200141046a102b200041063602002000410c6a200241106a28020036020020002002290308370204200241206a24000f0b200241086a200141046a102b200041043602002000410c6a200241106a28020036020020002002290308370204200241206a24000f0b20004105360200200041086a200141086a290300370300200241206a24000f0b20004103360200200241206a24000f0b2001410c6a2802002204ad42187e2205422088a70d012005a72206417f4c0d0120012802042101024002402006450d002006100022070d01200641041019000b410421070b200220012001200441186c6a102e024002400240200420022802042208200228020022036b41186e22014f0d0020044101742209200120012009491b220aad42187e2205422088a70d052005a722014100480d052004450d01200110002209450d062009200720012006200620014b1b10f8021a2007100120032008470d020c070b2004210a2007210920032008470d010c060b200110002209450d0420032008460d050b200241086a410c6a210641002104200921010340200241086a2003102b20062003410c6a102b200141106a200241086a41106a290300370200200141086a200241086a41086a29030037020020012002290308370200200441016a2104200141186a2101200341186a22032008470d000c060b0b41f089c300104f000b102c000b1018000b200141041019000b410021040b20002009360204200041073602002000410c6a2004360200200041086a200a360200200241206a24000bd70201017f02400240024020012d0000417e6a220241054b0d0002400240024002400240024020020e06000402030105000b41d00010002202450d062002200141046a280200109c02200041046a2002360200200041106a200141106a290300370300200041086a200141086a290300370300200041023a00000f0b200041046a200141046a280200360200200041063a00000f0b200020012d00013a0001200041046a200141046a280200360200200041043a00000f0b41d00010002202450d042002200141046a280200109c02200041046a2002360200200041086a200141086a290300370300200020012d00013a0001200041053a00000f0b200041046a200141046a280200360200200041033a00000f0b200041086a200141086a290300370300200041046a200141046a280200360200200041073a00000f0b41a8e6c200104f000b41d00041081019000b41d00041081019000bb00901047f230041206b22022400024002402001280200417e6a220341084b0d000240024002400240024002400240024002400240024002400240024002400240024020030e09000502030106070408000b2001410c6a2802002203417f4c0d11200128020421042003450d0e2003100022050d0f200341011019000b4101210320012d00044101470d07200141086a28020021040c080b2000410436020020002001280204360204200241206a24000f0b2000410536020020002001280204360204200241206a24000f0b20004109360200200041086a200141086a290300370300200241206a24000f0b2001280204210441012103200141086a22052d00004101470d052001410c6a28020021050c060b2000410736020020002001280204360204200241206a24000f0b4101210320012d00044101470d05200141086a28020021010c060b2000410a360200200041086a200141086a290300370300200241206a24000f0b2002411e6a200141046a220341036a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290000370300200141086a2800002104410021030b200020033a0004200020022f011c3b0005200041086a20043602002000410c6a2002290300370200200041386a200141386a290300370300200041306a200141306a290300370300200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a280200360200200141286a280200210120004106360200200041286a2001360200200241206a24000f0b2002411e6a200541036a2d00003a0000200241086a200141186a290000370300200241106a200141206a290000370300200241186a200141286a2d00003a0000200220052f00013b011c2002200141106a2900003703002001410c6a2800002105410021030b20002004360204200020022f011c3b0009200041086a20033a00002000410c6a2005360200200041106a20022903003702002000410b6a2002411e6a2d00003a0000200041186a200241086a290300370200200041206a200241106a290300370200200041286a200241186a2802003602002000412c6a2001412c6a29020037020020004103360200200241206a24000f0b2002411e6a200141046a220341036a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290000370300200141086a2800002101410021030b200020022f011c3b0005200020033a000420004108360200200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a280200360200200241206a24000f0b410121050b20052004200310f80221042000410c6a2003360200200041086a20033602002000200436020420004102360200200041106a200141106a280200360200200241206a24000f0b41d09fc300104f000b102c000bd71c05047f027e067f047e017f230041e0006b22022400024002400240024002400240024002400240024002400240024002400240024020012d0000417e6a220341044b0d0002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e050004020301000b41d00010002203450d33200141046a2802002201280200417f6a2204410b4b0d06024020040e0c000c090a060d0e0b0f081005000b2002200141086a10920120034101360200200341106a200241086a290300370300200320022903003703080c410b200041063a0000200041086a200141086a290300370300200241e0006a24000f0b200041043a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200241e0006a24000f0b200041053a0000200041086a200141086a290300370300200241e0006a24000f0b200041033a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00004100473a0000200241e0006a24000f0b4102210420012d000422054102460d0b4103210420054103470d2f200241186a200141046a220141196a290000370300200241106a200141116a290000370300200241086a200141096a290000370300200220012900013703000c0c0b2002200141086a10930120034105360200200341186a200241106a290300370300200341106a200241086a290300370300200320022903003703080c3b0b200141086a2903004202520d2e20034202370308200341003602002003200141106a2903003703100c3a0b200141086a280200417e6a220441044b0d2e024020040e05001b191a18000b41012104200141386a2903002106200141306a29030021072001410c6a2d00004101470d1f0c200b41022104200141086a22052d000022084102460d0f4103210420084103460d0e4104210420084104470d2e20052d000141004721010c100b200141086a2d0000417e6a220941094b0d2e4102210a4100210b024020090e0a37001d211b242522261c370b2001410c6a280200220b41087621054103210a0c220b20012d000422044102460d074103210520044103470d2e200241d2006a200141046a220441036a2d00003a0000200241086a200141186a2900003703002002410d6a2001411d6a290000370000200220042f00013b01502002200141106a290000370300200141256a2d00004100472108200141286a280200210c2001410c6a2800002104200141086a280000210d0c080b41022105200141086a28020022044102460d0820044103470d2e410121082001410c6a2d00004101470d0e0c0f0b2002200141086a10940120034106360200200341c0006a200241386a290300370300200341386a200241306a290300370300200341306a200241286a290300370300200341286a200241206a290300370300200341206a200241186a290300370300200341186a200241106a290300370300200341106a200241086a290300370300200320022903003703080c340b2002200141086a10950120034107360200200341286a200241206a290300370300200341206a200241186a290300370300200341186a200241106a290300370300200341106a200241086a290300370300200320022903003703080c330b20012802044102470d2c2002200141086a102b200342898080802037030020032002290200370208200341106a200241086a2802003602000c320b41022105200141086a22042d000022084102460d054103210520084103470d2c200141306a2903002106200141286a2903002107200141386a290300210e200241c0006a2001410c6a102b200241d0006a200141186a102b2002410b6a200241c0006a41086a280200360000200241176a200241d0006a41086a280200360000200220022903403700032002200229035037000f4200210f420021100c060b200241d0006a200141086a102b2002410b6a200241d0006a41086a280200360000200220022903503700030b20032002290300370005200320043a0004200320022f00503b00252003410c3602002003410d6a200241086a290300370000200341156a200241106a2903003700002003411d6a200241186a290300370000200341276a200241d2006a2d00003a00000c2f0b200141086a280200210d41d00010002204450d2a20042001410c6a280200109101410221050b200320022f01503b0005200320053a00042003200436020c2003200d36020820032002290300370210200320083a00252003200c360228200320022f01403b012620034108360200200341076a200241d2006a2d00003a0000200341186a200241086a2903003702002003411d6a2002410d6a2900003700000c2d0b410121082001410c6a2d00004101470d070c080b200241176a200441186a290000370000200241106a200441116a290000370300200241086a200441096a29000037030020022004290001370300200141c0006a2903002110200141386a290300210e200141c8006a2903002111200141286a3100002107200241d0006a2001412c6a102b200241d0006a41086a3502004220862002290350220f4220888421062007200f4220868421074200210f0b2003200737032820032002290300370009200320053a0008200320113703482003410b360200200341c0006a20103703002003200f200e84370338200341306a2006370300200341116a200241086a290300370000200341196a200241106a290300370000200341206a200241176a2900003700000c2a0b200141106a29030021060c010b200241d4006a200541066a2f00003b0100200241086a200141206a290000370300200241106a200141286a2d00003a00002002200541026a2800003602502002200141186a290000370300200141106a2900002106200141096a2d000021010b200320013a0009200320043a00082003200228025036010a2003200637031020032002290300370318200341033602002003410e6a200241d4006a2f01003b0100200341206a200241086a290300370300200341286a200241106a2903003703000c270b200141286a3500002001412c6a3100004220868421062001410d6a2f00002001410f6a2d0000411074722104200141246a280000210c200141206a280000210d200141186a2900002107200141146a2800002112410021080b200141c8006a290300210e200141c0006a290300210f410321050c020b200141286a3500002001412c6a3100004220868421062001410d6a2f00002001410f6a2d0000411074722104200141246a280000210c200141206a280000210d200141186a2900002107200141146a2800002112410021080b0b200320043b000d2003200f370340200320063702282003200c3602242003200d3602202003200737021820032012360214200320083a000c20032005360208200341023602002003410f6a20044110763a0000200341c8006a200e370300200341386a200141386a2903003703002003200141306a2903003703302003200141106a2800003602100c220b2001410c6a28020022044108762105410621010c030b200241106a200141206a2903003703002002200141186a2903003703082002200141106a2802003602002001410c6a28020022044108762105200141286a290300210e410421010c080b2001410c6a28020022044108762105410521010c010b2002200141186a2903003703082002200141106a29030037030041032101410021040b0c050b2001410c6a280200220b4108762105200141186a2903002107200141206a280200210d200141106a2903002206a7210c2006422088a721084106210a0c1a0b2001410c6a280200220b4108762105410b210a0c060b4101210b2001410c6a2d00004101470d090c0a0b200141286a3500002001412c6a31000042208684210e2001410d6a2f00002001410f6a2d0000411074722105200141246a2800002108200141206a280000210c200141186a290000210f200141146a280000210d410021040b200220083602142002200c3602102002200f3703082002200d3602042002200141106a280000360200410221010b2003200737033020032001360208200320022903003703102003200e3703282003410a360200200341386a200637030020032005410874200441ff01717236020c200341186a200241086a290300370300200341206a200241106a2903003703000c170b2001410c6a280200220b41087621054105210a0c010b2001410c6a280200220b41087621054109210a0b0c110b200141106a2903002206a7210c2006422088a721084107210a0c100b200141106a2903002206a7210c2006422088a721084108210a0c0f0b4100210b200141096a2d00004100472112410a210a0c100b200141286a3500002001412c6a3100004220868421062001410d6a2f00002001410f6a2d0000411074722105200141246a2800002104200141206a280000210d200141186a2900002107200141146a28000021084100210b0b200141106a280000210c4104210a0c0d0b41c081c300104f000b41d00041081019000b41d8ccc200104f000b41a881c300104f000b41c0ccc200104f000b41acd5c200104f000b41a8ccc200104f000b418cabc200104f000b41c4aec300104f000b4180e8c200104f000b4188a8c200104f000b41d00041081019000b0b0b200320123a00092003200a3a000820032006370228200320043602242003200d360220200320022f01003b010a20034104360200200341186a200737030020032005410874200b41ff01717236020c20032008ad422086200cad843703100b200041023a0000200041046a2003360200200241e0006a24000bce0603067f037e037f230041306b22022400200241003a0020200241206a2001280200220320012802042204410047220510f8021a0240024002400240024020042005490d00200141046a200420056b22063602002001200320056a2205360200024002402004450d000240024020022d002022034103712204450d00024020044101460d0020044102470d02200241003a001e200241003b011c2002411c6a200520064103200641034922071b220410f8021a200141046a200620046b3602002001200520046a36020020070d0320022f011c20022d001e41107472410874200372410276ad21080c080b200241003a0020200241206a20052006410047220410f8021a20062004490d06200141046a200620046b3602002001200520046a3602002006450d0220022d002041087420037241fcff0371410276ad21080c070b2003410276ad21080c060b0240024020034102762204450d00024020044104460d002004410c470d024200210a2002420037032820024200370320200241206a200520064110200641104922031b220410f8021a200141046a200620046b3602002001200520046a36020020030d04200241286a2903002109200229032021084201210a0c090b4200210a20024200370320200241206a200520064108200641084922031b220410f8021a200141046a200620046b3602002001200520046a36020020030d03200229032021080c070b20024100360220200241206a200520064104200641044922031b220410f8021a200141046a200620046b3602002001200520046a36020020030d01200235022021080c060b200441046a220b41104b0d00200141046a210c200241106a210d4200210842002109410021030340200241003a0020200241206a20052006410047220410f8021a20062004490d04200c200620046b22073602002001200520046a22053602002006450d01200241086a20023100204200200341037441f8007110fe02200d2903002009842109200229030820088421084201210a20072106200341016a22042103200441ff0171200b490d000c070b0b4200210a0b0c040b20052004107a000b20042006107a000b20042006107a000b420021094201210a0b200020083703082000200a370300200041106a2009370300200241306a24000bc00503057f027e037f230041106b22022400200241003a0008200241086a2001280200220320012802042204410047220510f8021a02400240024020042005490d00200141046a200420056b22063602002001200320056a22053602000240024002402004450d000240024020022d000822044103712203450d002004ad2107024020034101460d0020034102470d02200241003a0006200241003b0104200241046a200520064103200641034922031b220410f8021a200141046a200620046b3602002001200520046a36020020030d0320023301042002310006421086844208862007844202882107420121080c050b200241003a0008200241086a20052006410047220410f8021a20062004490d07200141046a200620046b3602002001200520046a3602002006450d0220023100084208862007844202882107420121080c040b2004410276ad2107420121080c030b0240024020044102762204450d0020044104470d014200210820024200370308200241086a200520064108200641084922031b220410f8021a200141046a200620046b3602002001200520046a36020020030d0320022903082107420121080c040b20024100360208200241086a200520064104200641044922031b220410f8021a200141046a200620046b3602002001200520046a36020020030d0120023502082107420121080c030b200441046a220941084b0d0042002107200141046a210a410021030340200241003a0008200241086a20052006410047220410f8021a20062004490d05200a200620046b220b3602002001200520046a22053602002006450d0120023100082003410374413871ad86200784210742012108200b2106200341016a22042103200441ff01712009490d000c030b0b420021080b0b2000200737030820002008370300200241106a24000f0b20052004107a000b20042006107a000b20042006107a000bd20603047f037e037f230041206b22022400200241003a001020012802002001280204200241106a410120012802081004210320012001280208200341016a220341014b6a220436020802400240024020034102490d000240024002400240024020022d001022054103712203450d0020034101460d0120034102470d0220024100360210200220053a0010200141086a220341002001280200200141046a280200200241106a41017241032004100422012001417f461b22014103200141034922011b20032802006a36020020010d052002280210410276ad21060c030b2005410276ad21060c020b200241003b0110200220053a00102001280200200141046a280200200241106a4101724101200410042103200141086a22012001280200200341016a220141014b6a36020020014102490d0320022f0110410276ad21060c010b0240024020054102762203450d0020034104460d012003410c470d03420021072002420037031820024200370310200141086a220341002001280200200141046a280200200241106a41102004100422012001417f461b22014110200141104922011b20032802006a36020020010d05200241106a41086a290300210820022903102106420121070c060b200141046a280200210320024100360210200141086a2205410020012802002003200241106a41042004100422012001417f461b22014104200141044922011b20052802006a36020020010d03200235021021060c010b4200210720024200370310200141086a220341002001280200200141046a280200200241106a41082004100422012001417f461b22014108200141084922011b20032802006a36020020010d03200229031021060b42002108420121070c030b200341046a220941104b0d00200141046a210a200141086a21054200210642002108410021030340200241003a00102001280200200a280200200241106a410120041004210420052005280200200441016a220b41014b6a2204360200200b4102490d01200220023100104200200341037441f8007110fe02200241086a29030020088421082002290300200684210642012107200341016a220341ff01712009490d000c030b0b420021070b0b2000200637030820002007370300200041106a2008370300200241206a24000bbd0503047f027e037f230041106b22022400200241003a000820012802002001280204200241086a410120012802081004210320012001280208200341016a220441014b6a220336020802400240024020044102490d0002400240024020022d000822054103712204450d0020044101460d0120044102470d0220024100360208200220053a0008200141086a220441002001280200200141046a280200200241086a41017241032003100422012001417f461b22014103200141034922011b20042802006a36020020010d032002280208410276ad2106420121070c050b2005410276ad2106420121070c040b200241003b0108200220053a00082001280200200141046a280200200241086a4101724101200310042103200141086a22012001280200200341016a220141014b6a36020020014102490d0120022f0108410276ad2106420121070c030b0240024020054102762204450d0020044104470d014200210720024200370308200141086a220441002001280200200141046a280200200241086a41082003100422012001417f461b22014108200141084922011b20042802006a36020020010d0320022903082106420121070c040b200141046a280200210420024100360208200141086a2205410020012802002004200241086a41042003100422012001417f461b22014104200141044922011b20052802006a36020020010d0120023502082106420121070c030b200441046a220841084b0d0042002106200141046a2109200141086a2105410021040340200241003a000820012802002009280200200241086a410120031004210320052005280200200341016a220a41014b6a2203360200200a4102490d0120023100082004410374413871ad86200684210642012107200441016a220441ff01712008490d000c030b0b420021070b0b2000200637030820002007370300200241106a24000bdb0601057f230041e0006b2203240002402000423f56200142005220015022041b0d0020022000a74102741024200341e0006a24000f0b02400240024002400240024002400240024002400240024002400240024020004280800154410020041b450d00200241046a2802002205200241086a28020022046b41024f0d01200441026a22062004490d0a20054101742204200620062004491b22044100480d0a2005450d0420022802002107200410002206450d0d2006200720042005200520044b1b10f8021a200710010c050b200042808080800454410020041b450d01200241046a2802002205200241086a28020022046b41044f0d02200441046a22062004490d0920054101742204200620062004491b22044100480d092005450d0620022802002107200410002206450d0d2006200720042005200520044b1b10f8021a200710010c070b200228020021060c040b411020017920007942c0007c20014200521ba74103766b22044104490d082002200441027441736a10242003200137030820032000370300034020022000a7102420004208882001423886842100200142088821012004417f6a22040d000b200320003703002003200137030820032003360210200341e8bec000360214200020018450450d09200341e0006a24000f0b200228020021060c050b200410002206450d080b20022006360200200241046a2004360200200241086a28020021040b200241086a200441026a360200200620046a2000a74102744101723b0000200341e0006a24000f0b200410002206450d060b20022006360200200241046a2004360200200241086a28020021040b200241086a200441046a360200200620046a2000a7410274410272360000200341e0006a24000f0b1018000b41d4abc200104f000b200341c8006a41146a4100360200200341306a41146a4109360200200341306a410c6a410a360200200341186a41146a4103360200200341186a410c6a410336020020034188f0c1003602582003420137024c200341bcabc2003602482003410a360234200341b0b3c1003602202003410336021c200341d883c3003602182003200341c8006a3602402003200341146a3602382003200341106a3602302003200341306a360228200341186a41ecabc2001071000b200441011019000b200441011019000b900605027f027e017f027e027f230041a0016b22022400200028020021000240024002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0120054290ce005441002004501b0d0241272100200241186a21060340200241106a200520044290ce00420010fb022002200229031022072006290300220842f0b17f427f10fc02200241206a20006a2203417c6a200520022903007ca7220941e4006e220a410174419892c0006a2f00003b00002003417e6a200a419c7f6c20096a410174419892c0006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000b41e40021092007a7220341e4004e0d030c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d032001410141ac94c0004102200241206a20006a41800120006b10772100200241a0016a240020000f0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d032001410141ac94c0004102200241206a20006a41800120006b10772100200241a0016a240020000f0b4127210041e40021092005a7220341e400480d030b200241206a2000417e6a22006a2003200341ffff037120096e2209419c7f6c6a41ffff0371410174419892c0006a2f00003b0000200941094a0d030c040b2000418001107a000b2000418001107a000b2003220941094c0d010b200241206a2000417e6a22006a22032009410174419892c0006a2f00003b00000c010b200241206a2000417f6a22006a2203200941306a3a00000b200141014188f0c10041002003412720006b10772100200241a0016a240020000b9c0601057f230041e0006b2202240002402000423f560d0020012000a74102741024200241e0006a24000f0b0240024002400240024002400240024002400240024002400240024002402000428080015a0d00200141046a2802002203200141086a28020022046b41024f0d01200441026a22052004490d0a20034101742204200520052004491b22044100480d0a2003450d0420012802002106200410002205450d0d2005200620042003200320044b1b10f8021a200610010c050b20004280808080045a0d01200141046a2802002203200141086a28020022046b41044f0d02200441046a22052004490d0920034101742204200520052004491b22044100480d092003450d0620012802002106200410002205450d0d2005200620042003200320044b1b10f8021a200610010c070b200128020021050c040b4108200079a74103766b22044104490d082001200441027441736a102420022000370308034020012000a71024200042088821002004417f6a22040d000b200220003703082002200241086a360210200241e8bdc000360214200050450d09200241e0006a24000f0b200128020021050c050b200410002205450d080b20012005360200200141046a2004360200200141086a28020021040b200141086a200441026a360200200520046a2000a74102744101723b0000200241e0006a24000f0b200410002205450d060b20012005360200200141046a2004360200200141086a28020021040b200141086a200441046a360200200520046a2000a7410274410272360000200241e0006a24000f0b1018000b41a4abc200104f000b200241c8006a41146a4100360200200241306a41146a4109360200200241306a410c6a410b360200200241186a41146a4103360200200241186a410c6a410336020020024188f0c1003602582002420137024c200241bcabc2003602482002410b360234200241b0b3c1003602202002410336021c200241d883c3003602182002200241c8006a3602402002200241146a3602382002200241106a3602302002200241306a360228200241186a41c4abc2001071000b200441011019000b200441011019000bca0202027f017e23004180016b22022400200028020021000240024002400240200128020022034110710d002000290300210420034120710d0120042001107b210020024180016a240020000f0b200029030021044180012100024003402000450d01200220006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b0b20004181014f0d012001410141ac94c0004102200220006a41800120006b1077210020024180016a240020000f0b4180012100024003402000450d01200220006a417f6a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b0b20004181014f0d012001410141ac94c0004102200220006a41800120006b1077210020024180016a240020000f0b2000418001107a000b2000418001107a000bd70d06037f057e037f057e017f057e230041206b22012400200141106a41086a220242003703002001420037031041f8bec0004118200141106a1002200141086a200229030037030020012001290310370300411021030240024002400240024002400240024002400240200141104188f0c100410041001004417f460d0020014200370310410020014110200141106a41084100100422022002417f461b220241084922030d022001290310210420014200370310410020014110200141106a41082002410820031b2203100422022002417f461b220241074d0d022001290310210520014200370310410020014110200141106a41082002410820024108491b20036a2203100422022002417f461b220241074d0d022001290310210620014200370310410020014110200141106a41082002410820024108491b20036a2203100422022002417f461b220241074d0d022001290310210720014200370310410020014110200141106a41082002410820024108491b20036a2203100422022002417f461b220241074d0d02200129031021082001410036021020014110200141106a41042002410820024108491b20036a2202100441016a4105490d02200128021021092001410036021020014110200141106a4104200241046a100441016a4105490d02200128021021030c010b42012108418080042109420121074201210642012105420121040b200141106a41086a220242003703002001420037031041bef0c100411b200141106a1002200141086a220a20022903003703002001200129031037030002400240200141104188f0c100410041001004417f460d00200142003703182001420037031020014110200141106a411041001004220b417f460d06200b410f4d0d06200141186a290300210c2001290310210d0c010b4200210d4200210c0b20024200370300200142003703104190bfc0004111200141106a1002200a20022903003703002001200129031037030002400240200141104188f0c100410041001004417f460d002001410036021020014110200141106a41044100100441016a41044d0d052001280210210a0c010b41e400210a0b4200210e200141106a41086a220242003703002001420037031041a1bfc0004114200141106a1002200141086a20022903003703002001200129031037030002400240200141104188f0c100410041001004417f460d00200142003703182001420037031020014110200141106a4110410010042202417f460d072002410f4d0d07200141186a290300210e2001290310210f0c010b4215210f0b42002110200141106a41086a220242003703002001420037031041e7f5c1004114200141106a1002200141086a220b20022903003703002001200129031037030002400240200141104188f0c100410041001004417f460d00200142003703182001420037031020014110200141106a4110410010042211417f460d082011410f4d0d08200141186a2903002112200129031021130c010b42002113420021120b200242003703002001420037031041fbf5c1004114200141106a1002200b20022903003703002001200129031037030002400240200141104188f0c100410041001004417f460d00200142003703182001420037031020014110200141106a4110410010042202417f460d092002410f4d0d09200141186a2903002114200129031021100c010b420021140b200141106a41086a220242003703002001420037031041b5bfc0004114200141106a1002200141086a20022903003703002001200129031037030002400240200141104188f0c100410041001004417f460d002001420037031020014110200141106a41084100100441016a41084d0d03200129031021150c010b42870121150b200141106a41086a220242003703002001420037031041c9bfc0004116200141106a1002200141086a20022903003703002001200129031037030002400240200141104188f0c100410041001004417f460d002001420037031020014110200141106a41084100100441016a41084d0d04200129031021160c010b42af0121160b2000200d37033020002010370360200020133703502000200f3703402000200a360280012000200336022c2000200936022820002008370320200020073703182000200637031020002005370308200020043703002000201637037820002015370370200041386a200c370300200041e8006a2014370300200041d8006a2012370300200041c8006a200e370300200141206a24000f0b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b02000be00401027f0240024002400240024002400240024002400240024002400240024020002802002201410b4b0d0020010e0c0d010d0d0d02030405060d070d0b20002d00044102470d0c2000410c6a280200450d0c200041086a28020010010f0b200041086a280200220141064b0d08024020010e070c0c000c0a0c0b0c0b200041106a280200450d0b2000410c6a28020010010f0b200041086a2d000022014105460d0520014102470d0a2000410c6a220028020010a001200028020010010f0b200041086a2802004102470d09200041106a280200450d092000410c6a28020010010f0b200041086a2d00004102470d082000410c6a220028020010a001200028020010010f0b20002d00044102470d072000410c6a220028020010a001200028020010010f0b20002802044102490d062000410c6a280200450d06200041086a28020010010f0b200041086a2d000022014102490d0520014102470d01200041306a280200450d052000412c6a28020010010f0b2000410c6a220028020010a001200028020010010f0b0240200041106a280200450d002000410c6a28020010010b2000411c6a280200450d03200041186a28020010010f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141186a2101200241686a22020d000b0b200041106a280200450d022000410c6a28020010010f0b200041106a280200450d012000410c6a28020010010f0b200041106a280200450d002000410c6a28020010010f0b0b1b002000200128020422012f01063602042000200141086a3602000b8f0801067f230041f0006b22022400200241003a0050200241d0006a2001280200220320012802042204410047220510f8021a0240024020042005490d00200141046a200420056b22063602002001200320056a2205360200024002402004450d0020022d0050220441f0014f0d01410121010c030b200041023a0000200241f0006a24000f0b02400240024002400240200441847e6a220441034b0d00024002400240024020040e0400010203000b200241003b0150200241d0006a20052006410220064102491b220410f8021a200141046a200620046b3602002001200520046a36020041012101200641014d0d0441ef01210420022f015041ef014b0d09200041023a0000200241f0006a24000f0b20024100360250200241d0006a20052006410420064104491b220410f8021a200141046a200620046b3602002001200520046a360200200641034d0d0441ffff03210441012101200228025041ffff034b0d08200041023a0000200241f0006a24000f0b200041023a0000200141046a20062006410420064104491b22006b3602002001200520006a360200200241f0006a24000f0b41002103200241d0006a2006412020064120491b22046a41004100412020046b2004411f4b1b10f7021a200241d0006a2005200410f8021a200141046a200620046b3602002001200520046a3602002006411f4d0d032002412c6a41026a200241d0006a41026a2d00003a0000200241186a200241df006a290000370300200241206a200241e7006a290000370300200241286a200241d0006a411f6a2d00003a0000200220022f00503b012c2002200229005737031020022800532104410121030c040b200041023a0000200241f0006a24000f0b200041023a0000200241f0006a24000f0b200041023a0000200241f0006a24000f0b0b200241cc006a41026a22012002412c6a41026a2d00003a0000200241306a41086a2205200241106a41086a290300370300200241306a41106a2206200241106a41106a290300370300200241306a41186a2207200241106a41186a2d00003a0000200220022f012c3b014c2002200229031037033002402003450d002002410c6a41026a20012d00003a0000200241d0006a41086a2005290300370300200241d0006a41106a2006290300370300200241d0006a41186a20072d00003a0000200220022f014c3b010c20022002290330370350410021010c020b200041023a0000200241f0006a24000f0b20052004107a000b200020022f010c3b0001200020013a0000200041046a2004360200200041086a2002290350370200200041036a2002410e6a2d00003a0000200041106a200241d0006a41086a290300370200200041186a200241d0006a41106a290300370200200041206a200241d0006a41186a280200360200200241f0006a24000be70801067f230041f0006b22022400200241003a005020012802002001280204200241d0006a410120012802081004210320012001280208200341016a220341014b6a220436020802400240024020034102490d0020022d0050220341f0014f0d01410121010c020b200041023a0000200241f0006a24000f0b024002400240024002400240200341847e6a220341034b0d0002400240024020030e0400040102000b200141046a2802002103200241003b0150200141086a2205410020012802002003200241d0006a41022004100422012001417f461b2203410220034102491b20052802006a36020041012101200341014d0d0641ef01210320022f015041ef014b0d08200041023a0000200241f0006a24000f0b200141046a280200210320024100360250200141086a2205410020012802002003200241d0006a41042004100422012001417f461b2201410420014104491b20052802006a360200200041023a0000200241f0006a24000f0b200241d0006a41186a4200370300200241d0006a41106a4200370300200241d0006a41086a42003703002002420037035041002105200141086a220341002001280200200141046a280200200241d0006a41202004100422012001417f461b2201412020014120491b20032802006a3602002001411f4d0d022002412e6a20022d00523a0000200241106a41086a200241df006a290000370300200241106a41106a200241e7006a290000370300200241106a41186a200241d0006a411f6a2d00003a0000200220022f01503b012c2002200229005737031020022800532103410121050c030b200041023a0000200241f0006a24000f0b200141046a280200210320024100360250200141086a2205410020012802002003200241d0006a41042004100422012001417f461b2201410420014104491b20052802006a360200200141034d0d0341ffff03210341012101200228025041ffff034b0d04200041023a0000200241f0006a24000f0b0b200241cc006a41026a22012002412c6a41026a2d00003a0000200241306a41086a2204200241106a41086a290300370300200241306a41106a2206200241106a41106a290300370300200241306a41186a2207200241106a41186a2d00003a0000200220022f012c3b014c2002200229031037033002402005450d002002410c6a41026a20012d00003a0000200241d0006a41086a2004290300370300200241d0006a41106a2006290300370300200241d0006a41186a20072d00003a0000200220022f014c3b010c20022002290330370350410021010c030b200041023a0000200241f0006a24000f0b200041023a0000200241f0006a24000f0b200041023a0000200241f0006a24000f0b200020022f010c3b0001200020013a0000200041046a2003360200200041086a2002290350370200200041036a2002410e6a2d00003a0000200041106a200241d0006a41086a290300370200200041186a200241d0006a41106a290300370200200041206a200241d0006a41186a280200360200200241f0006a24000b900101017f230041106b220224000240024020002d00004101470d002002200041046a280200220036020c200041ffff034d0d01200141fd01102420002001108901200241106a24000f0b200141ff011024200041016a2001101e200241106a24000f0b0240200041ef014b0d00200120001024200241106a24000f0b200141fc011024200120001021200241106a24000b960706047f017e017f027e067f027e230041f0056b22022400200241c8026a200110a601200241d8026a280200210320022802d402210420022802d002210520022903c802210620024180056a200241dc026a41e40010f8021a02400240024002400240024002400240024002402005450d00200241106a20024180056a41e40010f8021a200241086a2001103a2002280208450d05200228020c2207ad220842d8017e2209422088a70d082009a7220a417f4c0d08200a450d01200a1000220b450d0920070d020c030b20004100360208200241f0056a24000f0b4108210b2007450d010b200241c8026a41f8006a210c4100210d0340200241c8026a200110a70120024180056a200241c8026a41f00010f8021a200241c8026a41f0006a2903002109200241a0046a200c41e00010f8021a20094203510d02200241d8016a20024180056a41f00010f8021a200241f8006a200241a0046a41e00010f8021a02402008422088a7220a2008a7470d00200a41016a220e200a490d05200a410174220f200e200e200f491bad221042d8017e2211422088a70d052011a7220e4100480d0502400240200a450d00200e1000220f450d08200f200b200e200a41d8016c220a200a200e4b1b10f802210a200b1001200a210b0c010b200e1000220b450d070b20084280808080708320108421080b200b2008422088a741d8016c6a200241d8016a41f00010f802220a2009370370200a41f8006a200241f8006a41e00010f8021a20084280808080107c2108200d41016a220d2007490d000b0b200b450d01200241c8026a200241106a41e40010f8021a200041106a20033602002000200436020c2000200536020820002006370300200041146a200241c8026a41e40010f8021a200041fc006a2008370200200041f8006a200b360200200241f0056a24000f0b02402008422088a7220a450d00200a41d8016c210d200b4188016a210a0340200a1028200a41d8016a210a200d41a87e6a220d0d000b0b2008a7450d00200b10010b2000410036020802402003450d00200341286c210b2005210a03400240200a2d0000220d450d000240200d4101470d00200a41086a280200450d01200a41046a2802001001200a41286a210a200b41586a220b0d020c030b200a41146a280200450d00200a41106a28020010010b200a41286a210a200b41586a220b0d000b0b02402004450d00200510010b200241f0056a24000f0b1018000b200e41081019000b102c000b200a41081019000bcd0c05087f037e027f017e017f230041d0016b22022400200241b0016a41186a22034200370300200241b0016a41106a22044200370300200241b0016a41086a22054200370300200242003703b001200241b0016a20012802002206200128020422074120200741204922081b220910f8021a2001200720096b3602042001200620096a3602000240024002400240024020080d0020024190016a41186a2207200329030037030020024190016a41106a2209200429030037030020024190016a41086a22062005290300370300200220022903b0013703900120032007290300220a37030020042009290300220b37030020052006290300220c370300200241306a41086a200c370300200241306a41106a200b370300200241306a41186a200a3703002002200229039001220a3703302002200a3703b001200220011097012002290300a7450d012002290308210a200241b0016a41186a22054200370300200241b0016a41106a22064200370300200241b0016a41086a22084200370300200242003703b001200241b0016a2001280200220d200141046a22042802002207412020074120491b220910f8021a2004200720096b22033602002001200d20096a22093602002007411f4d0d0220024190016a41186a2207200529030037030020024190016a41106a220d200629030037030020024190016a41086a220e2008290300370300200220022903b0013703900120052007290300220b3703002006200d290300220c3703002008200e290300220f370300200241d0006a41086a200f370300200241d0006a41106a200c370300200241d0006a41186a200b3703002002200229039001220b3703502002200b3703b001200241b0016a2003412020034120491b22076a41004100412020076b2007411f4b1b10f7021a200241b0016a2009200710f8021a2004200320076b3602002001200920076a3602002003411f4d0d0320024190016a41186a2207200241b0016a41186a220929030037030020024190016a41106a2203200241b0016a41106a220429030037030020024190016a41086a2205200241b0016a41086a2206290300370300200220022903b0013703900120092007290300220b37030020042003290300220c37030020062005290300220f370300200241f0006a41086a2208200f370300200241f0006a41106a220d200c370300200241f0006a41186a220e200b3703002002200229039001220b3703702002200b3703b001200241b0016a200110fd0120022802b0012201450d0420022902b401210b2009200241306a41186a2903003703002004200241306a41106a2903003703002006200241306a41086a2903003703002005200241d0006a41086a2903003703002003200241d0006a41106a2903003703002007200241d0006a41186a290300370300200241106a41086a22102008290300370300200241106a41106a2208200d290300370300200241106a41186a220d200e290300370300200220022903303703b0012002200229035037039001200220022903703703102000200b37020c200020013602082000200a370300200041146a20022903b0013702002000411c6a2006290300370200200041246a20042903003702002000412c6a2009290300370200200041346a2002290390013702002000413c6a2005290300370200200041c4006a2003290300370200200041cc006a2007290300370200200041ec006a200d290300370200200041e4006a2008290300370200200041dc006a2010290300370200200041d4006a2002290310370200200241d0016a24000f0b200320024190016a41186a290000370300200420024190016a41106a290000370300200520024190016a41086a29000037030020022002290090013703b00120004100360208200241d0016a24000f0b20004100360208200241d0016a24000f0b200520024190016a41186a290000370300200620024190016a41106a290000370300200820024190016a41086a29000037030020022002290090013703b00120004100360208200241d0016a24000f0b200241b0016a41186a20024190016a41186a290000370300200241b0016a41106a20024190016a41106a290000370300200241b0016a41086a20024190016a41086a29000037030020022002290090013703b00120004100360208200241d0016a24000f0b20004100360208200241d0016a24000ba41404027f017e107f067e230041a0046b22022400200241086a2001103a02400240024002400240024002400240024002402002280208450d000240200228020c2203450d002003ad2104410021054100210603402005417f460d04200442ffffffff0f832004422088a741016a2205ad422086842104200641016a22062003490d000b0b200241003a00f001200241f0016a2001280200220320012802042205410047220610f8021a20052006490d03200141046a200520066b3602002001200320066a3602002005450d0720022d00f001220541ff00714101470d072005411874411875417f4c0d01420221040c090b20004203370370200241a0046a24000f0b200241b8036a200110a20102400240024020022d00b8034102460d0020024190036a41206a200241b8036a41206a28020036020020024190036a41186a200241b8036a41186a29030037030020024190036a41106a200241b8036a41106a29030037030020024190036a41086a200241b8036a41086a290300370300200220022903b80337039003200241f0016a41386a22074200370300200241f0016a41306a22084200370300200241f0016a41286a22094200370300200241f0016a41206a220a4200370300200241f0016a41186a220b4200370300200241f0016a41106a220c4200370300200241f0016a41086a220d4200370300200242003703f001200241f0016a2001280200220e200141046a220f280200220541c000200541c000491b220610f8021a200f200520066b22033602002001200e20066a220636020002402005413f4d0d00200241c0026a41386a22052007290300370300200241c0026a41306a220e2008290300370300200241c0026a41286a22102009290300370300200241c0026a41206a2211200a290300370300200241c0026a41186a2212200b290300370300200241c0026a41106a2213200c290300370300200241c0026a41086a2214200d290300370300200220022903f0013703c0022007200529030022043703002008200e2903002215370300200920102903002216370300200a20112903002217370300200b20122903002218370300200c20132903002219370300200d2014290300221a370300200241e0036a41086a201a370300200241e0036a41106a2019370300200241e0036a41186a2018370300200241e0036a41206a2017370300200241e0036a41286a2016370300200241e0036a41306a2015370300200241e0036a41386a2004370300200220022903c00222043703e003200220043703f001200242003703f001200241f0016a20062003410820034108491b220510f8021a200f200320056b22073602002001200620056a2205360200200341074d0d0120022903f0012115200241003a00f001200241f0016a20052007410047220610f8021a20072006490d06200141046a200720066b22033602002001200520066a22053602002007450d0120023100f0012217500d02200241003a00f001200241f0016a20052003410047220610f8021a20032006490d07200141046a200320066b3602002001200520066a3602002003450d0142022017420f838622164204540d014201210420023100f0014208862017844204882016420c882217420120174201561b7e22172016540d030c010b2007200241c0026a41386a2900003703002008200241c0026a41306a2900003703002009200241c0026a41286a290000370300200a200241c0026a41206a290000370300200b200241c0026a41186a290000370300200c200241c0026a41106a290000370300200d200241c0026a41086a290000370300200220022900c0023703f0010b420221040c060b420021040b200241f8006a41206a20024190036a41206a280200360200200241f8006a41186a20024190036a41186a290300370300200241f8006a41106a20024190036a41106a290300370300200241f8006a41086a20024190036a41086a290300370300200241a0016a41086a200241e0036a41086a290300370300200241a0016a41106a200241e0036a41106a290300370300200241a0016a41186a200241e0036a41186a290300370300200241a0016a41206a200241e0036a41206a290300370300200241a0016a41286a200241e0036a41286a290300370300200241a0016a41306a200241e0036a41306a290300370300200241a0016a41386a200241e0036a41386a2903003703002002200229039003370378200220022903e0033703a0010c040b1018000b20062005107a000b20062007107a000b20062003107a000b200241c0026a41206a2205200241f8006a41206a280200360200200241c0026a41186a2206200241f8006a41186a290300370300200241c0026a41106a2203200241f8006a41106a290300370300200241c0026a41086a2207200241f8006a41086a290300370300200241f0016a41086a2208200241a0016a41086a290300370300200241f0016a41106a2209200241a0016a41106a290300370300200241f0016a41186a220a200241a0016a41186a290300370300200241f0016a41206a220b200241a0016a41206a290300370300200241f0016a41286a220c200241a0016a41286a290300370300200241f0016a41306a220d200241a0016a41306a290300370300200241f0016a41386a220f200241a0016a41386a290300370300200220022903783703c002200220022903a0013703f00120044202520d010b20004203370370200241a0046a24000f0b200241d0006a41206a2005280200360200200241d0006a41186a2006290300370300200241d0006a41106a2003290300370300200241d0006a41086a2007290300370300200241106a41086a2008290300370300200241106a41106a2009290300370300200241106a41186a200a290300370300200241106a41206a200b290300370300200241106a41286a200c290300370300200241106a41306a200d290300370300200241106a41386a200f290300370300200220022903c002370350200220022903f0013703100b200241f0016a200110d50220022802f0012105200241c0026a200241f0016a41047241cc0010f8021a02402005410d470d0020004203370370200241a0046a24000f0b200241a0016a200241c0026a41cc0010f8021a2000201537030020002002290350370308200041106a200241d0006a41086a290300370300200041186a200241d0006a41106a290300370300200041206a200241d0006a41186a290300370300200041286a200241d0006a41206a2802003602002000200229031037022c200041346a200241106a41086a2903003702002000413c6a200241106a41106a290300370200200041c4006a200241106a41186a290300370200200041cc006a200241106a41206a290300370200200041d4006a200241106a41286a290300370200200041dc006a200241c0006a290300370200200041e4006a200241c8006a29030037020020004188016a200536020020004180016a201737030020002016370378200020043703702000418c016a200241a0016a41cc0010f8021a200241a0046a24000bee0404017f017e027f017e230041d0006b2205240042002106200541306a41086a220742003703002005420037033041d0b0c0004111200541306a1002200541206a41086a220820072903003703002005200529033037032042002109024002400240200541206a41104188f0c100410041001004417f460d0020054200370340200541206a4110200541c0006a41084100100441016a41084d0d01200529034021090b2005200242002003200410fc022005200920017c20027d370340200742003703002005420037033041d0b0c0004111200541306a10022008200729030037030020052005290330370320200541206a4110200541c0006a41081003200541106a200010a90120002005290300220920052903107c2202200541086a2903002201200541106a41086a2903007c2002200954ad7c10aa01200742003703002005420037033041d9f0c1004116200541306a1002200820072903003703002005200529033037032002400240200541206a41104188f0c100410041001004417f460d002005420037034820054200370340200541206a4110200541c0006a4110410010042207417f460d032007410f4d0d03200541c8006a2903002102200529034021060c010b420021020b0240200620097c22092006542207200220017c2007ad7c220620025420062002511b0d002005200937034020052006370348200541306a41086a220742003703002005420037033041d9f0c1004116200541306a1002200541206a41086a200729030037030020052005290330370320200541206a4110200541c0006a411010030b200541d0006a24000f0b41eac4c10041331042000b41eac4c10041331042000bbf0204047f017e017f017e230041206b22022400024002400240411410002203450d002002421437021420022003360210200241106a41eeefc10041141025200241086a220320022802183602002002200229031037030020012002101e20032802002104200228020421052002280200210142002106200241106a41086a220742003703002002420037031020012004200241106a1002200320072903003703002002200229031037030002400240200241104188f0c100410041001004417f460d00200242003703182002420037031020024110200241106a4110410010042203417f460d012003410f4d0d01200241186a2903002108200229031021062005450d040c030b4200210820050d020c030b41eac4c10041331042000b411441011019000b200110010b2000200637030020002008370308200241206a24000bee1207017f017e017f017e037f017e047f230041d0006b2203240042002104200341106a41086a220542003703002003420037031041bef0c100411b200341106a1002200341086a2005290300370300200320032903103703000240024002400240200341104188f0c100410041001004417f460d00200342003703282003420037032020034110200341206a4110410010042205417f460d022005410f4d0d02200341286a29030021062003290320210441142105411410002207450d010c030b42002106411421054114100022070d020b200541011019000b41eac4c10041331042000b2003421437022420032007360220200341206a41eeefc10020051025200341106a41086a22052003280228360200200320032903203703102000200341106a101e2005280200210820032802142109200328021021072003200237032820032001370320200542003703002003420037031020072008200341106a1002200341086a20052903003703002003200329031037030020034110200341206a4110100302402009450d00200710010b02402004200158200620025820062002511b0d00024002400240411410002205450d002003421437022420032005360220200341206a41eeefc10041141025200341106a41086a22052003280228360200200320032903203703102000200341106a101e20052802002108200328021421092003280210210742002106200542003703002003420037031020072008200341106a1002200341086a20052903003703002003200329031037030002400240200341104188f0c100410041001004417f460d00200342003703282003420037032020034110200341206a4110410010042205417f460d012005410f4d0d01200341286a2903002104200329032021062009450d040c030b4200210420090d020c030b41eac4c10041331042000b411441011019000b200710010b42002102200341106a41086a220542003703002003420037031041d9f0c1004116200341106a1002200341086a2005290300370300200320032903103703000240024002400240024002400240024002400240024002400240200341104188f0c100410041001004417f460d00200342003703282003420037032020034110200341206a4110410010042205417f460d022005410f4d0d02200341286a2903002101200329032021020c010b420021010b0240200220067d220a200256200120047d2002200654ad7d220220015620022001511b0d002003200a37032020032002370328200341106a41086a220542003703002003420037031041d9f0c1004116200341106a1002200341086a20052903003703002003200329031037030020034110200341206a411010030b411410002205450d022003421437022420032005360220200341206a41eeefc10041141025200341106a41086a22052003280228360200200320032903203703102000200341106a101e200528020021082003280214210920032802102107200542003703002003420037031020072008200341106a1002200341086a20052903003703002003200329031037030020034110100802402009450d00200710010b410f10002205450d032003420f37022420032005360220200341206a41ddd2c000410f1025200341106a41086a22052003280228360200200320032903203703102000200341106a101e200528020021072003280214210820032802102105200341086a22094200370300200342003703002005200720031002200341206a41086a200929030037030020032003290300370320200341206a4110100802402008450d00200510010b410f10002205450d042003420f37022420032005360220200341206a41c1b0c000410f1025200341106a41086a22052003280228360200200320032903203703102000200341106a101e200528020021072003280214210820032802102105200341086a22094200370300200342003703002005200720031002200341206a41086a2207200929030037030020032003290300370320200341206a4110100802402008450d00200510010b200341206a41186a200041186a290000370300200341206a41106a200041106a2900003703002007200041086a290000370300200320002900003703202003410036024820034201370340200341c0006a418b9ec100410810252003200341206a10f5012003280204210b2003280200210c02400240024002402003280244220d200328024822076b200328020822094f0d00200720096a22052007490d09200d4101742208200520052008491b22084100480d09200d450d012003280240210e200810002205450d0c2005200e2008200d200d20084b1b10f8021a200e10010c020b20032802402105200d21080c020b200810002205450d0a0b20032008360244200320053602400b200520076a200c200910f8021a200341c0006a41086a200720096a22073602000240200b450d00200c10010b200341086a22094200370300200342003703002005200720031002200341106a41086a20092903003703002003200329030037031002402008450d00200510010b200341106a41101015411110002205450d062003421137022420032005360220200341206a41f384c10041111025200341106a41086a22052003280228360200200320032903203703102000200341106a101e200528020021072003280214210820032802102105200341086a22094200370300200342003703002005200720031002200341206a41086a200929030037030020032003290300370320200341206a4110100802402008450d00200510010b411810002205450d072003421837022420032005360220200341206a4193f1c10041181025200341106a41086a22052003280228360200200320032903203703102000200341106a101e200528020021082003280214210920032802102107200542003703002003420037031020072008200341106a1002200341086a2005290300370300200320032903103703000240200341104188f0c100410041001004417f460d00200342003703282003420037032020034110200341206a4110410010042205417f460d022005410f4d0d02200341286a290300210220032903202101410021052009450d0b0c0a0b4101210520090d090c0a0b41eac4c10041331042000b41eac4c10041331042000b411441011019000b410f41011019000b410f41011019000b1018000b411141011019000b411841011019000b200841011019000b200710010b20012002844200522005410173710d00200010f1020b200341d0006a24000bd40a02027f097e230041f0006b22032400200341d0006a41086a220442003703002003420037035041e1b0c0004116200341d0006a1002200341c0006a41086a2004290300370300200320032903503703400240024002400240024002400240200341c0006a41104188f0c100410041001004417f460d0020034200370360200341c0006a4110200341e0006a41084100100441016a41084d0d02200329036021050c010b42c0843d21050b42002106200341d0006a41086a220442003703002003420037035041d0b0c0004111200341d0006a1002200341c0006a41086a2004290300370300200320032903503703400240200341c0006a41104188f0c100410041001004417f460d0020034200370360200341c0006a4110200341e0006a41084100100441016a41084d0d02200329036021060b02400240200520067d20025a0d00200041f8c1c000360204200041086a411a360200410121040c010b42002105200341d0006a41086a220442003703002003420037035041d3b5c0004111200341d0006a1002200341c0006a41086a20042903003703002003200329035037034002400240200341c0006a41104188f0c100410041001004417f460d002003420037036820034200370360200341c0006a4110200341e0006a4110410010042204417f460d052004410f4d0d05200341e8006a2903002105200329036021060c010b420121060b42002107200341106a200542002002420010fc02200341206a200242002006420010fc022003420042002006420010fc02200341306a200110a90102402003290308200329031884420052200341206a41086a2903002208200329030020032903107c7c220920085472450d0020004192c2c000360204200041086a4127360200410121040c010b200341306a41086a290300210a2003290320210b20032903302108200341d0006a41086a220442003703002003420037035041bef0c100411b200341d0006a1002200341c0006a41086a20042903003703002003200329035037034002400240200341c0006a41104188f0c100410041001004417f460d002003420037036820034200370360200341c0006a4110200341e0006a4110410010042204417f460d062004410f4d0d06200341e8006a290300210c200329036021070c010b4200210c0b02402008200b7d220d200856200a20097d2008200b54ad7d2208200a562008200a511b200d2007542008200c542008200c511b72450d00200041eff0c100360204200041086a4124360200410121040c010b2001200d200810aa0142002108200341d0006a41086a220442003703002003420037035041d9f0c1004116200341d0006a1002200341c0006a41086a20042903003703002003200329035037034002400240200341c0006a41104188f0c100410041001004417f460d002003420037036820034200370360200341c0006a4110200341e0006a4110410010042204417f460d072004410f4d0d07200341e8006a290300210a200329036021080c010b4200210a0b02402008200b7d2207200856200a20097d2008200b54ad7d2208200a562008200a511b0d002003200737036020032008370368200341d0006a41086a220442003703002003420037035041d9f0c1004116200341d0006a1002200341c0006a41086a200429030037030020032003290350370340200341c0006a4110200341e0006a411010030b200041206a2005370300200041186a2006370300200041106a2002370300200041086a2002370300410021040b20002004360200200341f0006a24000f0b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b3400200041cd9fc10036020420004100360200200041146a4115360200200041106a41f0acc200360200200041086a42073702000bfb1705147f027e017f047e017f230041d0026b2202240002400240024002402001450d00200241f1016a2103200241d1016a210420024180026a2105200241f8016a2106200241f4016a2107410021080340024002400240024002400240024002400240411210002209450d00200242123702cc01200220093602c801200241c8016a4181cfc00041121025200241a8016a41086a2209200241c8016a41086a220a280200360200200220022903c8013703a8012000200241a8016a101e2009280200210b20022802ac01210c20022802a801210d20094200370300200242003703a801200d200b200241a8016a1002200241b8026a41086a220e2009290300370300200220022903a8013703b8024100210b0240024002400240200241b8026a41104188f0c100410041001004417f460d00200241003602c801200241b8026a4110200241c8016a41044100100441016a41044d0d0120022802c801210b0b0240200c450d00200d10010b200241c8016a41186a220c200041186a220f290000370300200241c8016a41106a2210200041106a2211290000370300200a200041086a2212290000370300200220002900003703c80141121000220d450d04200242123702ac012002200d3602a801200241a8016a4181cfc00041121025200e2009280200360200200220022903a8013703b802200241c8016a200241b8026a101e200e280200211320022802bc02211420022802b802210d2002200b41016a3602cc0220094200370300200242003703a801200d2013200241a8016a1002200e2009290300370300200220022903a8013703b802200241b8026a4110200241cc026a4104100302402014450d00200d10010b20094200370300200242003703a8014193cfc0004119200241a8016a1002200e2009290300370300200220022903a8013703b8024100210d0240200241b8026a41104188f0c100410041001004417f460d00200241003602c801200241b8026a4110200241c8016a41044100100441016a41044d0d0220022802c801210d0b0240200b200d4f0d00200241a8016a41186a200f290000370300200241a8016a41106a201129000037030020092012290000370300200220002900003703a8014101210d200b21150c0c0b4200211620094200370300200242003703a80141accfc000411b200241a8016a1002200e2009290300370300200220022903a8013703b802024002400240200241b8026a41104188f0c100410041001004417f460d00200242003703d001200242003703c801200241b8026a4110200241c8016a4110410010042213417f460d082013410f4d0d08200a290300211720022903c8012116200b200d6b2214210d201441ff004b0d010c020b42002117200b200d6b2214210d201441ff004d0d010b200c200f29000037030020102011290000370300200a2012290000370300200220002900003703c80141121000220d450d08200242123702ac012002200d3602a801200241a8016a4181cfc00041121025200e2009280200360200200220022903a8013703b802200241c8016a200241b8026a101e200e280200211320022802bc02211820022802b802210d2002200b3602cc0220094200370300200242003703a801200d2013200241a8016a1002200e2009290300370300200220022903a8013703b802200241b8026a4110200241cc026a4104100302402018450d00200d10010b41ff00210d2014417f6a4180014f0d090b20024198016a20162017200d41ff007110fe0220094200370300200242003703a80141e7d0c0004112200241a8016a1002200e2009290300370300200220022903a8013703b802200229039801211920024198016a41086a290300211a02400240200241b8026a41104188f0c100410041001004417f460d00200242103702ac012002200241b8026a3602a801200241c8016a200241a8016a103620022802c8012218450d08200a280200210b20022802cc01210d0c010b4100210d410121184100210b0b20094200370300200242003703a80141f9d0c000411d200241a8016a1002200e2009290300370300200220022903a8013703b8020240200241b8026a41104188f0c100410041001004417f460d00200241003602c801200241b8026a4110200241c8016a41044100100441016a41044d0d0320022802c8012113200d450d0b0c0a0b41042113200d0d090c0a0b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b411241011019000b411241011019000b41eac4c10041331042000b41eac4c10041331042000b411241011019000b41c7cfc00041a0011042000b201810010b0240200b20134d0d0020024180016a20002019201a10ae01200229038001a74101470d0020024180016a41106a290300211b200229038801211c200241c8016a200010af0120022802c80121180240200a280200220b450d0042002116200b4105742213210d420021172018210b0340200241f0006a200b10b001200241f0006a41086a29030020177c2002290370221720167c2216201754ad7c2117200b41206a210b200d41606a220d0d000b2016201784500d002018210b0340200241e0006a200b10b001200241386a2002290360200241e0006a41086a290300201c201b10fc02200241286a2002290338200241386a41086a2903002016201710fb02200241c8006a200b2002290328200241286a41086a29030010ae01200b41206a210b201341606a22130d000b0b20022802cc01450d00201810010b411c1000220b450d032002421c3702cc012002200b3602c801200241c8016a4196d1c000411c10252009200a280200360200200220022903c8013703a8012000200241a8016a101e20022802ac01210b200241c8016a20022802a8012213200928020010b101200c280200410320022903c8014201511b210d0240200b450d00201310010b024002402014200d4f0d002019423f88211b201a420186211c200241c8016a200010b201200a280200210b20022802c8012113200241186a200010b001200241186a41086a2903002116200229031821170240200b450d00200b410574210d2013210b0340200241086a200b10b001200241086a41086a29030020167c2002290308221620177c2217201654ad7c2116200b41206a210b200d41606a220d0d000b0b201c201b84211b2019420186211c024020022802cc01450d00201310010b2017201c5a2016201b5a2016201b511b0d010b20094200370300200242003703a80141e7d0c0004112200241a8016a1002200e2009290300370300200220022903a8013703b8020240200241b8026a41104188f0c100410041001004417f460d00200242103702ac012002200241b8026a3602a801200241c8016a200241a8016a103620022802c8012218450d0620022802cc01211d0240200a280200220b450d00200b41057421134100210d2018210b024002400340200b41086a2900002116200b41106a2900002117200b290000211b200c200b41186a29000037030020102017370300200a20163703002002201b3703c801200241c8016a2000460d01200d200241c8016a2000412010fa0222144100476a210d2014450d02200b41206a210b201341606a22130d000c030b0b4100210d0b2000200d10b301220b0d080b201d450d00201810010b20094200370300200242003703a80141b1d2c0004115200241a8016a1002200e2009290300370300200220022903a8013703b802200241b8026a41104188f0c10041001003200241003a00c80120094200370300200242003703a80141eef1c0004119200241a8016a1002200e2009290300370300200220022903a8013703b802200241b8026a4110200241c8016a410110030b200241a8016a41186a200f290000370300200241a8016a41106a201129000037030020092012290000370300200220002900003703a8014102210d0b2005201a37030020062019370300200a200d3a0000200420022903a801370000200320022f00b8023b000020072015360200200441086a2009290300370000200441106a200241a8016a41106a290300370000200441186a200241a8016a41186a290300370000200341026a200241b8026a41026a2d00003a0000200241033a00c801200241c8016a10b401200841016a22082001490d000b0b200241d0026a24000f0b411c41011019000b41eac4c10041331042000b200b10b501000b8f0602057f077e230041d0006b22042400024002400240411410002205450d002004421437024420042005360240200441c0006a41eeefc10041141025200441306a41086a22052004280248360200200420042903403703302001200441306a101e20052802002106200428023421072004280230210842002109200542003703002004420037033020082006200441306a1002200441206a41086a20052903003703002004200429033037032002400240200441206a41104188f0c100410041001004417f460d002004420037034820044200370340200441206a4110200441c0006a4110410010042205417f460d012005410f4d0d01200441c8006a290300210a200429034021092007450d040c030b4200210a20070d020c030b41eac4c10041331042000b411441011019000b200810010b20012009200220092009200256200a200356200a20035122051b22081b220b7d200a2003200a20081b220c7d2009200b54ad7d10aa014200210d200441306a41086a220842003703002004420037033041d9f0c1004116200441306a1002200441206a41086a200829030037030020042004290330370320024002400240200441206a41104188f0c100410041001004417f460d002004420037034820044200370340200441206a4110200441c0006a4110410010042208417f460d022008410f4d0d02200441c8006a290300210e2004290340210d0c010b4200210e0b0240200d200b7d220f200d56200e200c7d200d200b54ad7d220d200e56200d200e511b0d002004200f3703402004200d370348200441306a41086a220842003703002004420037033041d9f0c1004116200441306a1002200441206a41086a200829030037030020042004290330370320200441206a4110200441c0006a411010030b02400240200920025a200a20035a20051b0d00200441086a20012002200b7d2003200c7d2002200b54ad7d10d402200441186a29030021092004290310210a200429030821030c010b420021030b2000200a37030820002003370300200041106a2009370300200441d0006a24000f0b41eac4c10041331042000baa0201057f230041306b220224000240024002400240411c10002203450d002002421c37022420022003360220200241206a41ddd3c000411c1025200241086a220320022802283602002002200229032037030020012002101e200328020021042002280204210520022802002101200241206a41086a220642003703002002420037032020012004200241206a100220032006290300370300200220022903203703000240200241104188f0c100410041001004417f460d002002421037021420022002360210200241206a200241106a103620022802202203450d0220002002290224370204200020033602002005450d040c030b200041003602082000420137020020050d020c030b411c41011019000b41eac4c10041331042000b200110010b200241306a24000be50404057f017e017f037e230041206b22022400024002400240411410002203450d002002421437021420022003360210200241106a41eeefc10041141025200241086a220320022802183602002002200229031037030020012002101e20032802002104200228020421052002280200210642002107200241106a41086a220842003703002002420037031020062004200241106a1002200320082903003703002002200229031037030002400240200241104188f0c100410041001004417f460d00200242003703182002420037031020024110200241106a4110410010042203417f460d012003410f4d0d01200241186a2903002109200229031021072005450d040c030b4200210920050d020c030b41eac4c10041331042000b411441011019000b200610010b024002400240411810002203450d002002421837021420022003360210200241106a4193f1c10041181025200241086a220320022802183602002002200229031037030020012002101e2003280200210620022802042104200228020021014200210a200241106a41086a220542003703002002420037031020012006200241106a1002200320052903003703002002200229031037030002400240200241104188f0c100410041001004417f460d00200242003703182002420037031020024110200241106a4110410010042203417f460d012003410f4d0d01200241186a290300210b2002290310210a2004450d040c030b4200210b20040d020c030b41eac4c10041331042000b411841011019000b200110010b2000200a20077c22073703002000200b20097c2007200a54ad7c370308200241206a24000bf30103017f017e017f230041c0006b2203240042002104200341306a41086a220542003703002003420037033020012002200341306a1002200341206a41086a20052903003703002003200329033037032002400240200341206a41104188f0c100410041001004417f460d00200342103702342003200341206a360230200341186a200341306a10352003280218450d01200328021c21012003200341306a1098012003290300a7450d01200341106a290300210420002003290308370308200041186a2001360200200041106a2004370300420121040b20002004370300200341c0006a24000f0b41eac4c10041331042000baa0201057f230041306b220224000240024002400240411510002203450d002002421537022420022003360220200241206a41c8d3c00041151025200241086a220320022802283602002002200229032037030020012002101e200328020021042002280204210520022802002101200241206a41086a220642003703002002420037032020012004200241206a100220032006290300370300200220022903203703000240200241104188f0c100410041001004417f460d002002421037021420022002360210200241206a200241106a103620022802202203450d0220002002290224370204200020033602002005450d040c030b200041003602082000420137020020050d020c030b411541011019000b41eac4c10041331042000b200110010b200241306a24000bc70c03067f037e047f230041306b22022400200241206a41086a220342003703002002420037032041e7d0c0004112200241206a1002200241086a2003290300370300200220022903203703000240024002400240024002400240200241104188f0c100410041001004417f460d002002421037021420022002360210200241206a200241106a103620022802202203450d02200241286a2802002104200228022421050c010b410021030b2005410020031b21062003410120031b2107024002402004410020031b220420014d0d002000200720014105746a2203460d0120032000412010fa02450d010b41ecd2c00021032006450d0520071001200241306a240041ecd2c0000f0b20072004417f6a22054105746a22012900002108200129000821092001290010210a200341186a200141186a2900003700002003200a370010200320093700082003200837000020024100360228200242013703202005200241206a101b0240024002400240024002402005450d00200441057441606a210b4100200241206a41086a28020022016b210c2002280220210d200228022421052007210e0340200e210302402005200c6a411f4b0d00200141206a22042001490d042005410174220e20042004200e491b22044100480d0420041000210e024002402005450d00200e450d07200e200d20042005200520044b1b10f8021a200d10010c010b200e450d060b200e210d200421050b200341206a210e200d20016a22042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a290000370000200c41606a210c200141206a2101200b41606a220b0d000b200241286a2001360200200220053602242002200d3602200c010b200241286a2802002101200228022421052002280220210d0b200241206a41086a220342003703002002420037032041e7d0c0004112200241206a1002200241086a20032903003703002002200229032037030020024110200d2001100302402005450d00200d10010b02402006450d00200710010b411c10002203450d052002421c37022420022003360220200241206a4196d1c000411c1025200241086a220320022802283602002002200229032037030020002002101e200328020021042002280204210520022802002101200241206a41086a220c42003703002002420037032020012004200241206a10022003200c2903003703002002200229032037030020024110100802402005450d00200110010b411210002203450d062002421237022420022003360220200241206a4181cfc00041121025200241086a220320022802283602002002200229032037030020002002101e200328020021052002280204210c2002280200210442002108200241206a41086a220142003703002002420037032020042005200241206a100220032001290300370300200220022903203703002002411010080240200c450d00200410010b200142003703002002420037032041f0f1c100410d200241206a100220032001290300370300200220022903203703000240200241104188f0c100410041001004417f460d002002420037032020024110200241206a41084100100441016a41084d0d03200229032021080b200241206a41086a220342003703002002420037032041c6d2c0004117200241206a1002200241086a20032903003703002002200229032037030002400240200241104188f0c100410041001004417f460d002002420037032020024110200241206a41084100100441016a41084d0d0520022903202109410f2103410f10002201450d010c090b42e8072109410f2103410f100022010d080b200341011019000b1018000b200441011019000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b411c41011019000b411241011019000b2002420f37022420022001360220200241206a41ddd2c00020031025200241086a220320022802283602002002200229032037030020002002101e2003280200210420022802042105200228020021012002200920087c370310200241206a41086a220c42003703002002420037032020012004200241206a10022003200c2903003703002002200229032037030020024110200241106a41081003410021032005450d00200110010b200241306a240020030bffa80104057f017e0b7f017e23004180036b22012400200141086a10f001200128020c210220012802082103200141a0016a41086a22044200370300200142003703a00141cef1c100410d200141a0016a1002200141106a41086a2004290300370300200120012903a001370310024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141106a41104188f0c100410041001004417f460d00200142103702242001200141106a3602202001200141206a10352001280200450d6520012802042205ad42f8007e2206422088a70d032006a72204417f4c0d032004450d01200410002207450d042005450d020c050b410021074100210a4100210d4100210b0c060b4108210720050d030b410021044100210c0c030b102c000b200441081019000b200141a0016a4101722108200141286a21094100210a4100210b410021042005210c02400340200141003a00910220092009280200220d2001280220220e2001280224220f20014191026a4101200d100441016a220d41014b6a2210360200200d4102490d010240024020012d009102220d450d004101210e200d4101460d010c030b200141003602a00120094100200e200f200141a0016a410420101004220d200d417f461b220d4104200d410449220d1b20106a360200200d0d0220012802a001210f4100210e0b200141a0016a200141206a10cb0220012d00a001211020014191026a200841ef0010f8021a2010410c460d01200141316a20014191026a41ef0010f8021a200141a0016a200141316a41ef0010f8021a02402004200c470d00200a200441016a220d200d200a491b220cad42f8007e2206422088a70d052006a7220d4100480d0502402004450d00200d10002211450d6220112007200d200b200b200d4b1b10f802210d20071001200d21070c010b200d10002207450d610b2007200b6a220d20103a0000200d41016a200141a0016a41ef0010f8021a200d41f4006a200f360200200d41f0006a200e360200200a41026a210a200b41f8006a210b200441016a22042005490d000c020b0b02402004450d00200741186a2101034002400240200141686a2d000022044108460d00024020044105460d0020044104470d02200141706a2d00000d022001417c6a280200450d02200141786a2802001001200141f8006a2101200b41887f6a220b0d030c040b2001416c6a2d00004103470d010240200141746a280200450d00200141706a28020010010b2001280200450d012001417c6a2802001001200141f8006a2101200b41887f6a220b0d020c030b200141706a280200450d002001416c6a28020010010b200141f8006a2101200b41887f6a220b0d000b0b200c450d5f200710010c5f0b2007450d5e2007210a2007210d2007210b0b200141a0016a200041f00010f8021a024002400240024020044100200b1b2205200c4100200b1b2200470d00200541016a22042005490d042005410174220d20042004200d491b2200ad42f8007e2206422088a70d042006a722044100480d042005450d01200410002211450d5f2011200a4108200b1b220b2004200541f8006c220d200d20044b1b10f8021a200b10010c020b200d4108200b1b210c20074108200b1b21110c020b200410002211450d5d0b2011210c0b200c200541f8006c6a200141a0016a41f00010f802220441f4006a20023602002004200345360270200141003602a801200142013703a001200541016a2208200141a0016a101b02402008450d00200441f8006a210e200141a0016a41086a2104200c210b034002400240024002400240024002400240024002400240024002400240024002400240200b2802704101470d0020012802a4012004280200220d470d01200d41016a2207200d490d13200d410174220a20072007200a491b220a4100480d13200d450d0320012802a0012110200a10002207450d0a20072010200a200d200d200a4b1b10f8021a201010010c040b20012802a4012004280200220d470d01200d41016a2207200d490d12200d410174220a20072007200a491b220a4100480d12200d450d0520012802a0012110200a10002207450d0a20072010200a200d200d200a4b1b10f8021a201010010c060b20012802a00121070c030b20012802a00121070c050b200a10002207450d060b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41013a0000200b2d0000417f6a220d410a4b0d030c0a0b200a10002207450d040b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a0000200b41f4006a2802002110024002400240024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d0e200a410174220d20072007200d491b220d4100480d0e200a450d0120012802a0012109200d10002207450d0720072009200d200a200a200d4b1b10f8021a200910010c020b20012802a00121070c020b200d10002207450d050b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b2d0000417f6a220d410a4d0d070b024002400240024020012802a4012004280200220d470d00200d41016a2207200d490d0d200d410174220a20072007200a491b220a4100480d0d200d450d0120012802a0012110200a10002207450d0720072010200a200d200d200a4b1b10f8021a201010010c020b20012802a00121070c020b200a10002207450d050b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a00002004280200210d20012802a4012107024002400240024002400240024002400240200b41016a2d00004101470d002007200d470d01200d41016a2207200d490d12200d410174220a20072007200a491b220a4100480d12200d450d0320012802a0012110200a10002207450d0d20072010200a200d200d200a4b1b10f8021a201010010c040b2007200d470d01200d41016a2207200d490d11200d410174220a20072007200a491b220a4100480d11200d450d0520012802a0012110200a10002207450d0d20072010200a200d200d200a4b1b10f8021a201010010c060b20012802a00121070c030b20012802a00121070c050b200a10002207450d090b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41013a0000200b41f8006a220b200e470d0a0c0b0b200a10002207450d070b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a0000200b41f8006a220b200e470d070c080b200a41011019000b200a41011019000b200d41011019000b200a41011019000b200a41011019000b200a41011019000b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200d0e0b00060304010708050a0209000b20012802a4012004280200220d470d0f200d41016a2207200d490db902200d410174220a20072007200a491b220a4100480db902200d450d2120012802a0012110200a10002207450dc20220072010200a200d200d200a4b1b10f8021a201010010c220b20012802a4012004280200220d470d09200d41016a2207200d490db802200d410174220a20072007200a491b220a4100480db802200d450d1420012802a0012110200a10002207450dbd0220072010200a200d200d200a4b1b10f8021a201010010c150b20012802a4012004280200220d470d09200d41016a2207200d490db802200d410174220a20072007200a491b220a4100480db802200d450d1620012802a0012110200a10002207450dbd0220072010200a200d200d200a4b1b10f8021a201010010c170b20012802a4012004280200220d470d09200d41016a2207200d490db602200d410174220a20072007200a491b220a4100480db602200d450d1820012802a0012110200a10002207450dbd0220072010200a200d200d200a4b1b10f8021a201010010c190b20012802a4012004280200220d470d09200d41016a2207200d490db502200d410174220a20072007200a491b220a4100480db502200d450d1a20012802a0012110200a10002207450dbd0220072010200a200d200d200a4b1b10f8021a201010010c1b0b20012802a4012004280200220d470d09200d41016a2207200d490db502200d410174220a20072007200a491b220a4100480db502200d450d1f20012802a0012110200a10002207450dbe0220072010200a200d200d200a4b1b10f8021a201010010c200b20012802a4012004280200220d470d0a200d41016a2207200d490db302200d410174220a20072007200a491b220a4100480db302200d450d2120012802a0012110200a10002207450dbe0220072010200a200d200d200a4b1b10f8021a201010010c220b20012802a4012004280200220d470d0a200d41016a2207200d490db202200d410174220a20072007200a491b220a4100480db202200d450d2320012802a0012110200a10002207450dbe0220072010200a200d200d200a4b1b10f8021a201010010c240b20012802a4012004280200220d470d0a200d41016a2207200d490db102200d410174220a20072007200a491b220a4100480db102200d450d2b20012802a0012110200a10002207450dc00220072010200a200d200d200a4b1b10f8021a201010010c2c0b20012802a4012004280200220d470d0a200d41016a2207200d490db102200d410174220a20072007200a491b220a4100480db102200d450d2d20012802a0012110200a10002207450dc00220072010200a200d200d200a4b1b10f8021a201010010c2e0b20012802a4012004280200220d470d0a200d41016a2207200d490db002200d410174220a20072007200a491b220a4100480db002200d450d2f20012802a0012110200a10002207450dc00220072010200a200d200d200a4b1b10f8021a201010010c300b20012802a00121070c0c0b20012802a00121070c0e0b20012802a00121070c100b20012802a00121070c120b20012802a00121070c170b20012802a00121070c130b20012802a00121070c180b20012802a00121070c1a0b20012802a00121070c220b20012802a00121070c240b20012802a00121070c260b200a10002207450da8020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41053a000002400240200b41046a2d0000220d4101460d000240200d4102460d00200d4103470d0220012802a4012004280200220d470d37200d41016a2207200d490da402200d410174220a20072007200a491b220a4100480da402200d450d970120012802a0012110200a10002207450dd10220072010200a200d200d200a4b1b10f8021a201010010c98010b20012802a4012004280200220d470d34200d41016a2207200d490da302200d410174220a20072007200a491b220a4100480da302200d450d930120012802a0012110200a10002207450dcf0220072010200a200d200d200a4b1b10f8021a201010010c94010b20012802a4012004280200220d470d34200d41016a2207200d490da202200d410174220a20072007200a491b220a4100480da202200d450d980120012802a0012110200a10002207450dd00220072010200a200d200d200a4b1b10f8021a201010010c99010b20012802a4012004280200220d470d35200d41016a2207200d490da102200d410174220a20072007200a491b220a4100480da102200d450d9a0120012802a0012110200a10002207450dd00220072010200a200d200d200a4b1b10f8021a201010010c9b010b200a10002207450da6020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a410a3a0000200b41086a220d41216a2107200d41016a210a024002400240200d2d00004101470d0020012802a4012004280200220d470d01200d41016a2210200d490da202200d4101742209201020102009491b22094100480da202200d450d4020012802a001210f200910002210450db4022010200f2009200d200d20094b1b10f8021a200f10010c410b20012802a4012004280200220d470d01200d41016a2210200d490da102200d4101742209201020102009491b22094100480da102200d450d4220012802a001210f200910002210450db4022010200f2009200d200d20094b1b10f8021a200f10010c430b20012802a00121100c400b20012802a00121100c420b200a10002207450da4020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41033a000002400240200b41086a22072d0000220d4101460d00200d4102470d0120012802a4012004280200220d470d26200d41016a220a200d490d9d02200d4101742210200a200a2010491b22104100480d9d02200d450d6920012802a001210920101000220a450dbe02200a20092010200d200d20104b1b10f8021a200910010c6a0b20012802a4012004280200220d470d23200d41016a220a200d490d9c02200d4101742210200a200a2010491b22104100480d9c02200d450d6520012802a001210920101000220a450dbc02200a20092010200d200d20104b1b10f8021a200910010c660b20012802a4012004280200220d470d25200d41016a2207200d490d9b02200d410174220a20072007200a491b220a4100480d9b02200d450d6a20012802a0012110200a10002207450dbd0220072010200a200d200d200a4b1b10f8021a201010010c6b0b200a10002207450da2020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41043a0000200b41086a2d0000417f6a220d41044b0d280240200d0e05002621251f000b20012802a4012004280200220d470d5e200d41016a2207200d490d9802200d410174220a20072007200a491b220a4100480d9802200d450de20120012802a0012110200a10002207450de20220072010200a200d200d200a4b1b10f8021a201010010ce3010b200a10002207450da0020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41013a000002400240200b41086a220d2d000022074101460d0020074102470d0120012802a40120042802002207470d25200741016a220a2007490d970220074101742210200a200a2010491b22104100480d97022007450d6f20012802a001210920101000220a450dbc02200a200920102007200720104b1b10f8021a200910010c700b20012802a40120042802002207470d21200741016a220a2007490d960220074101742210200a200a2010491b22104100480d96022007450d6820012802a001210920101000220a450db902200a200920102007200720104b1b10f8021a200910010c690b200141003a00910220012802a40120042802002207470d24200741016a220a2007490d950220074101742210200a200a2010491b22104100480d95022007450d7020012802a001210920101000220a450dbb02200a200920102007200720104b1b10f8021a200910010c710b200a10002207450d9e020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41083a0000024020012802a4012004280200220d470d00200d41016a2207200d490d9402200d410174220a20072007200a491b220a4100480d9402200d450d0720012802a0012110200a10002207450da00220072010200a200d200d200a4b1b10f8021a201010010c080b20012802a00121070c080b200a10002207450d9c020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41023a0000024020012802a4012004280200220d470d00200d41016a2207200d490d9002200d410174220a20072007200a491b220a4100480d9002200d450d0720012802a0012110200a10002207450d9e0220072010200a200d200d200a4b1b10f8021a201010010c080b20012802a00121070c080b200a10002207450d9a020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41063a0000200b41056a21072004280200210d20012802a401210a024002400240200b41046a2d00004101470d00200a200d470d01200d41016a220a200d490d8f02200d4101742210200a200a2010491b22104100480d8f02200d450d3420012802a001210920101000220a450da502200a20092010200d200d20104b1b10f8021a200910010c350b200a200d470d01200d41016a220a200d490d8e02200d4101742210200a200a2010491b22104100480d8e02200d450d3620012802a001210920101000220a450da502200a20092010200d200d20104b1b10f8021a200910010c370b20012802a001210a0c340b20012802a001210a0c360b200a10002207450d98020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a0000200141a0016a200b41046a1022200b41f8006a220b200e470d87020c88020b200a10002207450d96020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a0000200b41086a2903002106024020012802a401220a2004280200220d6b41084f0d00200d41086a2207200d490d8702200a410174220d20072007200d491b220d4100480d8702200a450d0a20012802a0012110200d10002207450d990220072010200d200a200a200d4b1b10f8021a201010010c0b0b20012802a00121070c0b0b200a10002207450d94020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41073a00000240024002400240200b41046a2d0000417f6a220d41034b0d000240200d0e0400040203000b20012802a4012004280200220d470d22200d41016a2207200d490d8702200d410174220a20072007200a491b220a4100480d8702200d450d920120012802a0012110200a10002207450dbc0220072010200a200d200d200a4b1b10f8021a201010010c93010b20012802a4012004280200220d470d1b200d41016a2207200d490d8602200d410174220a20072007200a491b220a4100480d8602200d450d850120012802a0012110200a10002207450db70220072010200a200d200d200a4b1b10f8021a201010010c86010b20012802a4012004280200220d470d1c200d41016a2207200d490d8602200d410174220a20072007200a491b220a4100480d8602200d450d870120012802a0012110200a10002207450db70220072010200a200d200d200a4b1b10f8021a201010010c88010b20012802a4012004280200220d470d1d200d41016a2207200d490d8502200d410174220a20072007200a491b220a4100480d8502200d450d920120012802a0012110200a10002207450dba0220072010200a200d200d200a4b1b10f8021a201010010c93010b20012802a4012004280200220d470d1f200d41016a2207200d490d8302200d410174220a20072007200a491b220a4100480d8302200d450d940120012802a0012110200a10002207450dba0220072010200a200d200d200a4b1b10f8021a201010010c95010b200a10002207450d92020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a410b3a0000024002400240200b2d00014101470d0020012802a4012004280200220d470d01200d41016a2207200d490d8402200d410174220a20072007200a491b220a4100480d8402200d450d2e20012802a0012110200a10002207450d9b0220072010200a200d200d200a4b1b10f8021a201010010c2f0b20012802a4012004280200220d470d01200d41016a2207200d490d8302200d410174220a20072007200a491b220a4100480d8302200d450d3020012802a0012110200a10002207450d9b0220072010200a200d200d200a4b1b10f8021a201010010c310b20012802a00121070c2e0b20012802a00121070c300b200a10002207450d90020b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41093a00000240024002400240200b41086a22072d0000417f6a220d41034b0d000240200d0e0400040203000b20012802a4012004280200220d470d1e200d41016a2207200d490d8202200d410174220a20072007200a491b220a4100480d8202200d450d950120012802a0012110200a10002207450db90220072010200a200d200d200a4b1b10f8021a201010010c96010b20012802a4012004280200220d470d16200d41016a220a200d490d8102200d4101742210200a200a2010491b22104100480d8102200d450d850120012802a001210920101000220a450db302200a20092010200d200d20104b1b10f8021a200910010c86010b20012802a4012004280200220d470d17200d41016a2207200d490d8002200d410174220a20072007200a491b220a4100480d8002200d450d960120012802a0012110200a10002207450db80220072010200a200d200d200a4b1b10f8021a201010010c97010b20012802a4012004280200220d470d18200d41016a2207200d490dff01200d410174220a20072007200a491b220a4100480dff01200d450d980120012802a0012110200a10002207450db80220072010200a200d200d200a4b1b10f8021a201010010c99010b20012802a4012004280200220d470d1b200d41016a220a200d490dfe01200d4101742210200a200a2010491b22104100480dfe01200d450d9a0120012802a001210920101000220a450db802200a20092010200d200d20104b1b10f8021a200910010c9b010b200d10002207450d8e020b2001200d3602a401200120073602a0012004280200210d0b2004200d41086a3602002007200d6a2006370000200b41f8006a220b200e470df8010cf9010b20012802a4012004280200220d470d3c200d41016a2207200d490df901200d410174220a20072007200a491b220a4100480df901200d450dba0120012802a0012110200a10002207450dc00220072010200a200d200d200a4b1b10f8021a201010010cbb010b20012802a001210a0c430b20012802a4012004280200220d470d3b200d41016a2207200d490df701200d410174220a20072007200a491b220a4100480df701200d450dbb0120012802a0012110200a10002207450dbf0220072010200a200d200d200a4b1b10f8021a201010010cbc010b20012802a001210a0c440b20012802a00121070c460b20012802a001210a0c480b20012802a4012004280200220d470d38200d41016a2207200d490df301200d410174220a20072007200a491b220a4100480df301200d450dc00120012802a0012110200a10002207450dbe0220072010200a200d200d200a4b1b10f8021a201010010cc1010b20012802a4012004280200220d470d39200d41016a2207200d490df201200d410174220a20072007200a491b220a4100480df201200d450dc20120012802a0012110200a10002207450dbe0220072010200a200d200d200a4b1b10f8021a201010010cc3010b20012802a001210a0c4b0b4100211020012802a001210a0c4d0b20012802a4012004280200220d470d37200d41016a2207200d490def01200d410174220a20072007200a491b220a4100480def01200d450dc80120012802a0012110200a10002207450dbe0220072010200a200d200d200a4b1b10f8021a201010010cc9010b20012802a00121070c600b20012802a00121070c650b20012802a00121070c610b20012802a00121070c660b20012802a00121070c6b0b20012802a001210a0c700b20012802a00121070c6c0b20012802a00121070c80010b20012802a00121070c760b20012802a00121070c81010b20012802a00121070c710b20012802a00121070c760b20012802a00121070c780b20012802a001210a0c80010b200910002210450df3010b200120093602a401200120103602a0012004280200210d0b2004200d41016a3602002010200d6a41013a0000200a200141a0016a101e2007200141a0016a101e200b41f8006a220b200e470ddc010cdd010b200910002210450df1010b200120093602a401200120103602a0012004280200210d0b2004200d41016a3602002010200d6a41003a0000200a200141a0016a101e2007200141a0016a101e200b41d8006a2903002106200b41d0006a2903002112024002400240024020012802a401220a2004280200220d6b41104f0d00200d41106a2207200d490de001200a410174220d20072007200d491b220d4100480de001200a450d0120012802a0012110200d10002207450df40120072010200d200a200a200d4b1b10f8021a201010010c020b20012802a00121070c020b200d10002207450df2010b2001200d3602a401200120073602a0012004280200210d0b2007200d6a22072006370008200720123700002004200d41106a360200200b41f8006a220b200e470dd9010cda010b20101000220a450df0010b200120103602a4012001200a3602a0012004280200210d0b2004200d41016a360200200a200d6a41013a00002007200141a0016a101e200b41286a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490dd901200a410174220d20072007200d491b220d4100480dd901200a450d0a20012802a0012109200d10002207450df30120072009200d200a200a200d4b1b10f8021a200910010c0b0b20012802a00121070c0b0b20101000220a450dee010b200120103602a4012001200a3602a0012004280200210d0b2004200d41016a360200200a200d6a41003a00002007200141a0016a101e200b41286a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490dd601200a410174220d20072007200d491b220d4100480dd601200a450d0a20012802a0012109200d10002207450df10120072009200d200a200a200d4b1b10f8021a200910010c0b0b20012802a00121070c0b0b200a10002207450dec010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41013a0000200b41026a200141a0016a101e200b41f8006a220b200e470dd0010cd1010b200a10002207450dea010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a0000200b41f8006a220b200e470dcd010cce010b200d10002207450de8010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b412c6a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490dcd01200a410174220d20072007200d491b220d4100480dcd01200a450d0420012802a0012109200d10002207450de90120072009200d200a200a200d4b1b10f8021a200910010c050b20012802a00121070c050b200d10002207450de6010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b412c6a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490dca01200a410174220d20072007200d491b220d4100480dca01200a450d0420012802a0012109200d10002207450de70120072009200d200a200a200d4b1b10f8021a200910010c050b20012802a00121070c050b200d10002207450de4010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41306a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490dc701200a410174220d20072007200d491b220d4100480dc701200a450d0420012802a0012109200d10002207450de50120072009200d200a200a200d4b1b10f8021a200910010c050b20012802a00121070c050b200d10002207450de2010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41306a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490dc401200a410174220d20072007200d491b220d4100480dc401200a450d0420012802a0012109200d10002207450de30120072009200d200a200a200d4b1b10f8021a200910010c050b20012802a00121070c050b200d10002207450de0010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41f8006a220b200e470dbe010cbf010b200d10002207450dde010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41f8006a220b200e470dbb010cbc010b20012802a00121070c7f0b20012802a00121070c81010b20012802a00121070c89010b20012802a00121070c85010b20012802a00121070c8a010b20012802a00121070c92010b20101000220a450dd6010b200120103602a4012001200a3602a0012004280200210d0b2004200d41016a360200200a200d6a41013a0000200741016a200141a0016a101e200741246a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490db501200a410174220d20072007200d491b220d4100480db501200a450d0a20012802a0012109200d10002207450dd90120072009200d200a200a200d4b1b10f8021a200910010c0b0b20012802a00121070c0b0b20101000220a450dd4010b200120103602a4012001200a3602a0012004280200210d0b2004200d41016a360200200a200d6a41023a0000200741016a200141a0016a101e200b41386a2903002106200b41306a2903002112024020012802a401220a2004280200220d6b41104f0d00200d41106a2207200d490db201200a410174220d20072007200d491b220d4100480db201200a450d1020012802a0012110200d10002207450dd90120072010200d200a200a200d4b1b10f8021a201010010c110b20012802a00121070c110b200a10002207450dd2010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a0000200b41186a2903002106200b41106a2903002112024020012802a401220a2004280200220d6b41104f0d00200d41106a2207200d490daf01200a410174220d20072007200d491b220d4100480daf01200a450d1020012802a0012110200d10002207450dd70120072010200d200a200a200d4b1b10f8021a201010010c110b20012802a00121070c110b20101000220a450dd0010b200120103602a4012001200a3602a001200428020021070b2004200741016a360200200a20076a41013a0000200d41016a200141a0016a101e200b41f8006a220b200e470da9010caa010b200d10002207450dce010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41f8006a220b200e470da6010ca7010b20101000220a450dcc010b200120103602a4012001200a3602a001200428020021070b2004200741016a360200200a20076a41023a0000200d41016a200141a0016a101e200d41216a200141a0016a101e200b41d8006a2903002106200b41d0006a2903002112024020012802a40122102004280200220d6b41104f0d00200d41106a2207200d490da6012010410174220d20072007200d491b22074100480da6012010450d0a20012802a001210d20071000220a450dcf01200a200d20072010201020074b1b10f8021a200d10010c0b0b20012802a001210a201021070c0b0b20101000220a450dca010b200120103602a4012001200a3602a0012004280200210720012d00910221100b2004200741016a360200200a20076a20103a0000200d41016a200141a0016a101e200d41246a2802002109024020012802a4012210200428020022076b41044f0d00200741046a220a2007490da30120104101742207200a200a2007491b22074100480da3012010450d0a20012802a001210f20071000220a450dcd01200a200f20072010201020074b1b10f8021a200f10010c0b0b20012802a001210a0c0b0b200d10002207450dc8010b2001200d3602a401200120073602a0012004280200210d0b2007200d6a22072006370008200720123700002004200d41106a360200200b41f8006a220b200e470d9d010c9e010b200d10002207450dc6010b2001200d3602a401200120073602a0012004280200210d0b2007200d6a22072006370008200720123700002004200d41106a360200200b41f8006a220b200e470d9a010c9b010b20071000220a450dc4010b200120073602a4012001200a3602a0012004280200210d0b200a200d6a22102006370008201020123700002004200d41106a220d360200200b41e8006a2903002106200b41e0006a290300211202402007200d6b410f4b0d00200d41106a2210200d490d9a012007410174220d20102010200d491b220d4100480d9a01200d100021102007450d042010450dc5012010200a200d20072007200d4b1b10f8021a200a10010c050b200a21100c050b20071000220a450dc2010b200120073602a4012001200a3602a001200428020021070b2004200741046a360200200a20076a200936000002400240200d41216a2d0000220d4101460d00200d4102470d0120012802a4012004280200220d470d06200d41016a2207200d490d9801200d410174220a20072007200a491b220a4100480d9801200d450d870120012802a0012110200a10002207450dee0120072010200a200d200d200a4b1b10f8021a201010010c88010b20012802a4012004280200220d470d04200d41016a2207200d490d9701200d410174220a20072007200a491b220a4100480d9701200d450d830120012802a0012110200a10002207450dec0120072010200a200d200d200a4b1b10f8021a201010010c84010b20012802a4012004280200220d470d05200d41016a2207200d490d9601200d410174220a20072007200a491b220a4100480d9601200d450d880120012802a0012110200a10002207450ded0120072010200a200d200d200a4b1b10f8021a201010010c89010b2010450dc0010b2001200d3602a401200120103602a0012004280200210d0b2010200d6a22072006370008200720123700002004200d41106a360200200b41f8006a220b200e470d91010c92010b20012802a00121070c80010b20012802a00121070c82010b20012802a00121070c84010b200a10002207450dbb010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41023a0000200b41086a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d8e01200a410174220d20072007200d491b220d4100480d8e01200a450d0a20012802a0012109200d10002207450dbe0120072009200d200a200a200d4b1b10f8021a200910010c0b0b20012802a00121070c0b0b200a10002207450db9010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41033a0000200b41086a280200210d200b2802102207200141a0016a101b02402007450d002007410574210f2004280200210a20012802a4012110034002400240024002402010200a6b41204f0d00200a41206a2207200a490d90012010410174220a20072007200a491b220a4100480d90012010450d0120012802a0012107200a10002209450d920120092007200a20102010200a4b1b10f8021a200710010c020b20012802a0012109200a21070c020b200a10002209450d90010b2001200a3602a401200120093602a00120042802002107200a21100b2004200741206a220a360200200920076a220741086a200d41086a290000370000200741106a200d41106a290000370000200741186a200d41186a2900003700002007200d290000370000200d41206a210d200f41606a220f0d000b0b200b41146a280200210d200b411c6a2802002207200141a0016a101b2007450d722007410574210f2004280200210a20012802a4012110034002400240024002402010200a6b41204f0d00200a41206a2207200a490d8f012010410174220a20072007200a491b220a4100480d8f012010450d0120012802a0012107200a10002209450d920120092007200a20102010200a4b1b10f8021a200710010c020b20012802a0012109200a21070c020b200a10002209450d90010b2001200a3602a401200120093602a00120042802002107200a21100b2004200741206a220a360200200920076a220741086a200d41086a290000370000200741106a200d41106a290000370000200741186a200d41186a2900003700002007200d290000370000200d41206a210d200f41606a220f0d000c730b0b200a10002207450db7010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41013a0000200b41056a200141a0016a101e200b41f8006a220b200e470d85010c86010b200a10002207450db5010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a0000200b41056a200141a0016a101e200b41256a200141a0016a101e200b41f8006a220b200e470d82010c83010b200d10002207450db3010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41f8006a220b200e470d7f0c80010b200a10002207450db1010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a0000200b41056a200141a0016a101e200b41c8006a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d7f200a410174220d20072007200d491b220d4100480d7f200a450d0720012802a0012109200d10002207450db30120072009200d200a200a200d4b1b10f8021a200910010c080b20012802a00121070c080b200a10002207450daf010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41033a0000200b41056a200141a0016a101e200b41f8006a220b200e470d790c7a0b20101000220a450dad010b200120103602a4012001200a3602a0012004280200210d0b2004200d41016a360200200a200d6a41003a0000200741046a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d7a200a410174220d20072007200d491b220d4100480d7a200a450d1920012802a0012109200d10002207450db50120072009200d200a200a200d4b1b10f8021a200910010c1a0b20012802a00121070c1a0b200d10002207450dab010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41256a200141a0016a101e200b41cc006a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d76200a410174220d20072007200d491b220d4100480d76200a450d1920012802a0012109200d10002207450db30120072009200d200a200a200d4b1b10f8021a200910010c1a0b20012802a00121070c1a0b200a10002207450da9010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41013a0000200b41056a200141a0016a101e200b41256a200141a0016a101e024020012802a4012004280200220d470d00200d41016a2207200d490d73200d410174220a20072007200a491b220a4100480d73200d450d1c20012802a0012110200a10002207450db20120072010200a200d200d200a4b1b10f8021a201010010c1d0b20012802a00121070c1d0b200a10002207450da7010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41043a0000200b41056a200141a0016a101e024020012802a4012004280200220d470d00200d41016a2207200d490d71200d410174220a20072007200a491b220a4100480d71200d450d1c20012802a0012110200a10002207450db00120072010200a200d200d200a4b1b10f8021a201010010c1d0b20012802a00121070c1d0b200a10002207450da5010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41023a0000200b41056a200141a0016a101e200b41f8006a220b200e470d6a0c6b0b200a10002207450da3010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41013a0000200b41186a2903002106200b41106a2903002112024020012802a401220a2004280200220d6b41104f0d00200d41106a2207200d490d6b200a410174220d20072007200d491b220d4100480d6b200a450d1920012802a0012110200d10002207450dab0120072010200d200a200a200d4b1b10f8021a201010010c1a0b20012802a00121070c1a0b200a10002207450da1010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41033a0000200b41186a2903002106200b41106a2903002112024020012802a401220a2004280200220d6b41104f0d00200d41106a2207200d490d68200a410174220d20072007200d491b220d4100480d68200a450d0d20012802a0012110200d10002207450da50120072010200d200a200a200d4b1b10f8021a201010010c0e0b20012802a00121070c0e0b200a10002207450d9f010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41043a0000200b41186a2903002106200b41106a2903002112024020012802a401220a2004280200220d6b41104f0d00200d41106a2207200d490d65200a410174220d20072007200d491b220d4100480d65200a450d1620012802a0012110200d10002207450da60120072010200d200a200a200d4b1b10f8021a201010010c170b20012802a00121070c170b20101000220a450d9d010b200120103602a4012001200a3602a0012004280200210d0b2004200d41016a360200200a200d6a41023a0000200741246a2802002109024020012802a40122102004280200220d6b41044f0d00200d41046a220a200d490d622010410174220d200a200a200d491b220d4100480d622010450d1620012802a001210f200d1000220a450da401200a200f200d20102010200d4b1b10f8021a200f10010c170b20012802a001210a0c170b200d10002207450d9b010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41f8006a220b200e470d5b0c5c0b200d10002207450d99010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41f8006a220b200e470d580c590b200d10002207450d97010b2001200d3602a401200120073602a0012004280200210d0b2007200d6a22072006370008200720123700002004200d41106a360200200b41f8006a220b200e470d550c560b200a10002207450d95010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a200b41c5006a2d00003a0000200b41c8006a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d55200a410174220d20072007200d491b220d4100480d55200a450d0d20012802a0012109200d10002207450d990120072009200d200a200a200d4b1b10f8021a200910010c0e0b20012802a00121070c0e0b200a10002207450d93010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a200b41256a2d00003a0000200b41f8006a220b200e470d4f0c500b200d10002207450d91010b2001200d3602a401200120073602a0012004280200210d0b2007200d6a22072006370008200720123700002004200d41106a360200200b41f8006a220b200e470d4c0c4d0b200d10002207450d8f010b2001200d3602a401200120073602a0012004280200210d0b2007200d6a22072006370008200720123700002004200d41106a360200200b41f8006a220b200e470d490c4a0b200d1000220a450d8d010b2001200d3602a4012001200a3602a0012004280200210d0b2004200d41046a360200200a200d6a2009360000200b41386a2903002106200b41306a2903002112024020012802a40122102004280200220d6b41104f0d00200d41106a220a200d490d4a2010410174220d200a200a200d491b220d4100480d4a2010450d0420012802a0012109200d1000220a450d8e01200a2009200d20102010200d4b1b10f8021a200910010c050b20012802a001210a0c050b200d10002207450d8b010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41cc006a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d46200a410174220d20072007200d491b220d4100480d46200a450d0420012802a0012109200d10002207450d8c0120072009200d200a200a200d4b1b10f8021a200910010c050b20012802a00121070c050b200d1000220a450d89010b2001200d3602a4012001200a3602a0012004280200210d0b200a200d6a220a2006370008200a20123700002004200d41106a360200200741016a200141a0016a101e200b41f8006a220b200e470d400c410b200d10002207450d87010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41f8006a220b200e470d3d0c3e0b200a10002207450d85010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41053a0000200b410c6a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d3d200a410174220d20072007200d491b220d4100480d3d200a450d0420012802a0012109200d10002207450d860120072009200d200a200a200d4b1b10f8021a200910010c050b20012802a00121070c050b200a10002207450d83010b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41033a0000200b410c6a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d3a200a410174220d20072007200d491b220d4100480d3a200a450d0d20012802a0012109200d10002207450d870120072009200d200a200a200d4b1b10f8021a200910010c0e0b20012802a00121070c0e0b200d10002207450d81010b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000024020012802a4012004280200220d470d00200d41016a2207200d490d37200d410174220a20072007200a491b220a4100480d37200d450d0d20012802a0012110200a10002207450d850120072010200a200d200d200a4b1b10f8021a201010010c0e0b20012802a00121070c0e0b200a10002207450d7f0b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41013a0000200b410c6a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d34200a410174220d20072007200d491b220d4100480d34200a450d1020012802a0012109200d10002207450d840120072009200d200a200a200d4b1b10f8021a200910010c110b20012802a00121070c110b200a10002207450d7d0b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41043a0000200b410c6a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d31200a410174220d20072007200d491b220d4100480d31200a450d1020012802a0012109200d10002207450d820120072009200d200a200a200d4b1b10f8021a200910010c110b20012802a00121070c110b200a10002207450d7b0b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41023a0000200b410c6a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d2e200a410174220d20072007200d491b220d4100480d2e200a450d1020012802a0012109200d10002207450d800120072009200d200a200a200d4b1b10f8021a200910010c110b20012802a00121070c110b200d10002207450d790b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41f8006a220b200e470d280c290b200a10002207450d770b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a200b41096a2d00003a0000200b41f8006a220b200e470d250c260b200a10002207450d750b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a0000200b410c6a2802002110024020012802a401220a2004280200220d6b41044f0d00200d41046a2207200d490d25200a410174220d20072007200d491b220d4100480d25200a450d0a20012802a0012109200d10002207450d7820072009200d200a200a200d4b1b10f8021a200910010c0b0b20012802a00121070c0b0b200d10002207450d730b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a201036000002400240200b41096a2d0000220d4101460d00200d4102470d0120012802a4012004280200220d470d0d200d41016a2207200d490d23200d410174220a20072007200a491b220a4100480d23200d450d1b20012802a0012110200a10002207450d7c20072010200a200d200d200a4b1b10f8021a201010010c1c0b20012802a4012004280200220d470d0b200d41016a2207200d490d22200d410174220a20072007200a491b220a4100480d22200d450d1720012802a0012110200a10002207450d7a20072010200a200d200d200a4b1b10f8021a201010010c180b20012802a4012004280200220d470d0c200d41016a2207200d490d21200d410174220a20072007200a491b220a4100480d21200d450d1c20012802a0012110200a10002207450d7b20072010200a200d200d200a4b1b10f8021a201010010c1d0b200d10002207450d710b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41f8006a220b200e470d1c0c1d0b200d10002207450d6f0b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41f8006a220b200e470d190c1a0b200d10002207450d6d0b2001200d3602a401200120073602a0012004280200210d0b2004200d41046a3602002007200d6a2010360000200b41286a2903002106200b41206a2903002112024002400240024020012802a401220a2004280200220d6b41104f0d00200d41106a2207200d490d1c200a410174220d20072007200d491b220d4100480d1c200a450d0120012802a0012110200d10002207450d7020072010200d200a200a200d4b1b10f8021a201010010c020b20012802a00121070c020b200d10002207450d6e0b2001200d3602a401200120073602a0012004280200210d0b2007200d6a22072006370008200720123700002004200d41106a360200200b41106a280200210d200b2802182207200141a0016a101b2007450d002007410574210f2004280200210a20012802a4012110034002400240024002402010200a6b41204f0d00200a41206a2207200a490d1d2010410174220a20072007200a491b220a4100480d1d2010450d0120012802a0012107200a10002209450d2120092007200a20102010200a4b1b10f8021a200710010c020b20012802a0012109200a21070c020b200a10002209450d1f0b2001200a3602a401200120093602a00120042802002107200a21100b2004200741206a220a360200200920076a220741086a200d41086a290000370000200741106a200d41106a290000370000200741186a200d41186a2900003700002007200d290000370000200d41206a210d200f41606a220f0d000b0b200b41f8006a220b200e470d150c160b20012802a00121070c0d0b20012802a00121070c0f0b20012802a00121070c110b200a10002207450d680b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41013a0000200b41f8006a220b200e470d0f0c100b200a10002207450d660b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41023a0000200b41f8006a220b200e470d0c0c0d0b200a10002207450d640b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a0000200b41f8006a220b200e470d090c0a0b200a10002207450d620b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41013a0000200b41f8006a220b200e470d060c070b200a10002207450d600b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41023a0000200b41f8006a220b200e470d030c040b200a10002207450d5e0b2001200a3602a401200120073602a0012004280200210d0b2004200d41016a3602002007200d6a41003a0000200b41f8006a220b200e470d000b0b200141a0016a41086a2204280200210d20012802a401210720012802a001210b20044200370300200142003703a00141cef1c100410d200141a0016a1002200141106a41086a2004290300370300200120012903a001370310200141106a4110200b200d100302402007450d00200b10010b02402008450d00200541f8006c41f8006a210741002104034002400240200c20046a220b2d0000220d4108460d000240200d4105460d00200d4104470d02200b41086a2d00000d02200b41146a280200450d02200b41106a28020010012007200441f8006a2204470d030c040b200b41046a2d00004103470d010240200b410c6a280200450d00200b41086a28020010010b200b41186a280200450d01200b41146a28020010012007200441f8006a2204470d020c030b200b41086a280200450d00200b41046a28020010010b2007200441f8006a2204470d000b0b02402000450d00201110010b20014180036a24000f0b1018000b1018000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200d41011019000b200941011019000b200941011019000b200d41011019000b201041011019000b201041011019000b200a41011019000b200a41011019000b200d41011019000b200d41011019000b200d41011019000b200d41011019000b200d41011019000b200d41011019000b201041011019000b201041011019000b200a41011019000b201041011019000b200d41011019000b201041011019000b201041011019000b200d41011019000b200d41011019000b200741011019000b200741011019000b200d41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200d41011019000b200a41011019000b200a41011019000b201041011019000b200d41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b201041011019000b200d41011019000b200d41011019000b200d41011019000b200a41011019000b200a41011019000b200d41011019000b200d41011019000b200d41011019000b200d41011019000b200d41011019000b200d41011019000b200a41011019000b200a41011019000b200d41011019000b200a41011019000b200a41011019000b200a41011019000b200d41011019000b200a41011019000b200a41011019000b200d41011019000b200d41011019000b200d41011019000b200d41011019000b200d41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200a41011019000b200441081019000b200d41081019000b41eac4c10041331042000b9f0101017f230041c0006b22012400200141ff0036020c200141b2d1c0003602082001410d36021420012000360210200141306a410c6a410c3602002001412c6a4102360200200141186a410c6a4102360200200141013602342001418489c2003602202001410236021c200141a4aec3003602182001200141106a3602382001200141086a3602302001200141306a360228200141186a41b4aec3001071000b4b00200041ddf5c10036020420004100360200200041206a410a3602002000411c6a41f4b7c200360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000b3400200041ada0c10036020420004100360200200041146a4108360200200041106a41ecbdc200360200200041086a42083702000b4b00200041ddf5c10036020420004100360200200041206a41053602002000411c6a4194c2c200360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000bba0c05077f017e037f047e047f23004190016b2202240002400240024002400240411210002203450d002002421237027420022003360270200241f0006a4197e5c000411210252002280270210302400240024020022802742204200228027822056b41044f0d00200541046a22062005490d0420044101742207200620062007491b22074100480d042004450d01200710002208450d072008200320072004200420074b1b10f80221082003100120072104200821030c020b200541046a21060c010b200710002203450d05200721040b200320056a200136000042002109200241f0006a41086a220542003703002002420037037020032006200241f0006a1002200241086a20052903003703002002200229037037030002400240200241104188f0c100410041001004417f460d00200241f0006a41186a22064200370300200241f0006a41106a42003703002005420037030020024200370370410020024110200241f0006a41204100100422052005417f461b220141204922080d04200241d0006a41186a220a2006290300370300200241d0006a41106a220b200241f0006a41106a2207290300370300200241d0006a41086a220c200241f0006a41086a2205290300370300200220022903703703502006200a29030022093703002007200b290300220d3703002005200c290300220e370300200241106a41086a200e370300200241106a41106a200d370300200241106a41186a2009370300200220022903502209370310200220093703702002420037037820024200370370410020024110200241f0006a41102001412020081b2201100422062006417f461b2206410f4d0d05200529030021092002290370210d200241f0006a41186a2208420037030020074200370300200542003703002002420037037020024110200241f0006a41202006411020064110491b20016a220510042206417f460d012006411f4d0d01200241d0006a41186a2206200241f0006a41186a2207290300370300200241d0006a41106a2201200241f0006a41106a2208290300370300200241d0006a41086a220a200241f0006a41086a220b2903003703002002200229037037035020072006290300220e37030020082001290300220f370300200b200a2903002210370300200241306a41086a2010370300200241306a41106a200f370300200241306a41186a200e37030020022002290350220e3703302002200e370370200242003703782002420037037020024110200241f0006a4110200541206a10042205417f460d052005410f4d0d05200241f0006a41086a2205290300210e2002290370210f200241f0006a41186a220c200241106a41186a2206290300370300200241f0006a41106a2211200241106a41106a22072903003703002005200241106a41086a2201290300370300200241d0006a41086a2212200241306a41086a2208290300370300200241d0006a41106a2213200241306a41106a220a290300370300200241d0006a41186a2214200241306a41186a220b2903003703002002200229031037037020022002290330370350200b200c290300370300200a2011290300370300200820052903003703002001201229030037030020072013290300370300200620142903003703002002200229037037033020022002290350370310200041206a200e370300200041186a200f370300200041106a20093703002000200d370308200041286a2002290330370300200041306a2008290300370300200041386a200a290300370300200041c0006a200b290300370300200041c8006a2002290310370300200041d0006a2001290300370300200041d8006a2007290300370300200041e0006a2006290300370300420121090b2000200937030002402004450d00200310010b20024190016a24000f0b2008200241d0006a41186a290000370300200241f0006a41106a200241d0006a41106a290000370300200241f0006a41086a200241d0006a41086a2900003703002002200229005037037041eac4c10041331042000b411241011019000b1018000b2006200241d0006a41186a290000370300200241f0006a41106a200241d0006a41106a290000370300200241f0006a41086a200241d0006a41086a290000370300200220022900503703700b41eac4c10041331042000b200741011019000bc20201037f23004180016b22022400200028020021000240024002400240200128020022034110710d0020034120710d01200020011058210020024180016a240020000f0b20002802002103410021000340200220006a41ff006a2003410f712204413072200441d7006a2004410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d012001410141ac94c0004102200220006a4180016a410020006b1077210020024180016a240020000f0b20002802002103410021000340200220006a41ff006a2003410f712204413072200441376a2004410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d012001410141ac94c0004102200220006a4180016a410020006b1077210020024180016a240020000f0b2003418001107a000b2003418001107a000bc21002117f017e230041206b220224002000280204210320002802002104410121050240200128021841222001411c6a2802002802101102000d000240024002402003450d00200420036a2106200141186a21072001411c6a2108200421094100210a4100210b02400240024003402009210c200941016a2100024002400240024020092c0000220d4100480d00200d41ff0171210d0c010b02400240024020002006460d0020002d0000413f71210e200941026a22092100200d411f71210f200d41ff0171220d41e001490d010c020b4100210e20062109200d411f71210f200d41ff0171220d41e0014f0d010b200e200f41067472210d0c010b0240024020092006460d00200941016a2200211020092d0000413f71200e41067472210e200d41f001490d010c030b200621104100200e41067472210e200d41f0014f0d020b200e200f410c7472210d0b200021090c010b0240024020102006460d00201041016a210920102d0000413f71210d0c010b4100210d200021090b200e410674200f411274418080f0007172200d72220d418080c400460d020b41022100024002400240024002400240200d41776a220f411e4b0d0041f400210e0240200f0e1f06000303050303030303030303030303030303030303030303020303030302060b41ee00210e0c050b200d41dc00470d010b0c010b0240200d1080010d00024002400240024002400240200d41ffff034b0d00200d4180fe037141087621114198a4c000210e4100210f0240024002400340200e41026a2112200f200e2d000122006a211002400240200e2d0000220e2011470d002010200f490d05201041b0024f0d04200f41e8a4c0006a210e03402000450d022000417f6a2100200e2d0000210f200e41016a210e200f200d41ff0171470d000c0d0b0b200e20114b0d022010210f2012210e201241e8a4c000470d010c020b2010210f2012210e201241e8a4c000470d000b0b200d41ffff0371210f4197a7c00021004101210e0340200041016a21100240024020002d000022124118744118752211417f4c0d0020102100200f20126b220f4100480d060c010b0240201041d3a9c000460d00200041016a2110200041026a2100200f201141ff007141087420102d0000726b220f41004e0d010c060b41b092c200104f000b200e410173210e200041d3a9c000470d000c040b0b201041af021076000b200f2010107a000b200d41ffff074b0d03200d4180fe0371410876211141d3a9c000210e4100210f02400340200e41026a2112200f200e2d000122006a211002400240200e2d0000220e2011470d002010200f490d062010419f014f0d05200f4195aac0006a210e03402000450d022000417f6a2100200e2d0000210f200e41016a210e200f200d41ff0171470d000c0a0b0b200e20114b0d022010210f2012210e20124195aac000470d010c020b2010210f2012210e20124195aac000470d000b0b200d41ffff0371210f41b3abc00021004101210e0340200041016a21100240024020002d000022124118744118752211417f4c0d0020102100200f20126b220f4100480d030c010b0240201041b0aec000460d00200041016a2110200041026a2100200f201141ff007141087420102d0000726b220f41004e0d010c030b41b092c200104f000b200e410173210e200041b0aec000470d000b0b200e410171450d040c030b2010419e011076000b200f2010107a000b200d4190fc476a4190fc0b490d01200d41e28b746a41e28d2c490d01200d419fa8746a419f18490d01200d41dee2746a410e490d01200d41feffff0071419ef00a460d01200d41a9b2756a4129490d01200d41cb91756a410a4d0d010b200b200c6b20096a210b20062009470d040c050b200d41017267410276410773ad4280808080d000842113410321000b200d210e0c010b41f200210e0b20022003360204200220043602002002200a3602082002200b36020c200b200a490d030240200a450d00200a2003460d00200a20034f0d042004200a6a2c000041bf7f4c0d040b0240200b450d00200b2003460d00200b20034f0d042004200b6a2c000041bf7f4c0d040b20072802002004200a6a200b200a6b200828020028020c1100000d0202400340024002400240024002400240024020004101460d0041dc00210a024020004102460d0020004103470d092013422088a741ff0171417f6a220041044b0d09024020000e050006040503000b201342ffffffff8f608321134103210041fd00210a0c070b410121000c060b41002100200e210a0c050b201342ffffffff8f60834280808080c0008421130c030b201342ffffffff8f60834280808080208421134103210041fb00210a0c030b201342ffffffff8f60834280808080308421134103210041f500210a0c020b200e2013a7220f410274411c7176410f712200413072200041d7006a2000410a491b210a0240200f450d002013427f7c42ffffffff0f832013428080808070838421130c010b201342ffffffff8f60834280808080108421130b410321000b2007280200200a2008280200280210110200450d000c040b0b410121000240200d418001490d0041022100200d418010490d0041034104200d41808004491b21000b2000200b6a210a200b200c6b20096a210b20062009470d000b0b200a450d03200a2003460d030240200a20034f0d002004200a6a22002c000041bf7f4a0d050b20042003200a2003107d000b200241206a240041010f0b20022002410c6a3602182002200241086a36021420022002360210200241106a108501000b4100210a0b2004200a6a21000b200141186a220b28020020002003200a6b2001411c6a220a28020028020c1100000d00200b2802004122200a28020028021011020021050b200241206a240020050b3400200041cda0c10036020420004100360200200041146a4101360200200041106a4184c6c200360200200041086a420a3702000b4b00200041ddf5c10036020420004100360200200041206a41023602002000411c6a41c0c6c200360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000b130020004102360204200041d0c7c2003602000b130020004103360204200041b8c8c2003602000b13002000410536020420004184cac2003602000b975a09017f017e017f047e097f027e017f027e077f230041b0046b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001450d00200241f0036a41086a22014200370300200242003703f00341daa3c1004115200241f0036a1002200241d0036a41086a2001290300370300200220022903f0033703d003200241d0036a41104188f0c100410041001004417f460d01200242003703e002200241d0036a4110200241e0026a41084100100441016a41084d0d0320022903e00221030c020b200241f0036a21040c070b420521030b200241f0036a41086a22014200370300200242003703f00341d9f1c0004115200241f0036a1002200241d0036a41086a2001290300370300200220022903f0033703d00302400240200241d0036a41104188f0c100410041001004417f460d00200242003703e002200241d0036a4110200241e0026a41084100100441016a41084d0d034200210520022903e00220037e22034200510d010c050b4200210542e80720037e22034200520d040b200241f0036a41086a22012005370300200220053703f00341b1ecc000411c200241f0036a1002200241d0036a41086a2001290300370300200220022903f0033703d0030240200241d0036a41104188f0c100410041001004417f460d00200242003703e802200242003703e002200241d0036a4110200241e0026a4110410010042201417f460d032001410f4d0d03200241e8026a290300210820022903e00221050c050b420021080c040b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b2000200320032000541b22062005510d0a42002100200241f0036a41086a22014200370300200242003703f00341b1ecc000411c200241f0036a1002200241d0036a41086a2001290300370300200220022903f0033703d00302400240200241d0036a41104188f0c100410041001004417f460d00200242003703e802200242003703e002200241d0036a4110200241e0026a4110410010042201417f460d0b2001410f4d0d0b200241e8026a290300210720022903e00221000c010b420021070b200241d0026a200020072003421086200680420010fc0220022903d002421088200241d8026a2903002200423086842105200042108821080b200241e0026a41086a22014200370300200242003703e00241c8f2c0004112200241e0026a1002200241f0036a41086a2001290300370300200220022903e0023703f003024002400240200241f0036a41104188f0c100410041001004417f460d00200242103702d4032002200241f0036a3602d003200241e0026a200241d0036a103620022802e0022209450d0d20022802e402210a2009410120091b210b200241e8026a280200410020091b22040d010c020b410021094100410141001b210b4100410041001b2204450d010b200b20044105746a210c200241f0026a210d200b210e0340411c10002201450d032002421c3702e402200220013602e002200241e0026a4196d1c000411c1025200241f0036a41086a220f200241e0026a41086a2201280200360200200220022903e0023703f003200e200241f0036a101e20022802f4032110200241e0026a20022802f0032211200f28020010b101200d290300420020022903e002420151220f1b210020012903004200200f1b210302402010450d00201110010b02400240024002402005200320052003200554200020085420002008511b220f1b22127d2206200820002008200f1b22137d2005201254ad7d220784500d00200241e0026a200e10af012001280200211120022802e0022114200241c0026a200e10b001200241c0026a41086a290300210020022903c00221032011450d0120114105742210210f201421010340200241b0026a200110b001200241b0026a41086a29030020007c20022903b002220020037c2203200054ad7c2100200141206a2101200f41606a220f0d000b20004200200342015620004200522000501b22011b21002003420120011b210302402011450d002003200084500d0b201421010340200241a0026a200110b00120024190026a20022903a002200241a0026a41086a2903002006200710fc0220024180026a20022903900220024190026a41086a2903002003200010fb02200120022903800220024180026a41086a29030010c201200141206a2101201041606a22100d000b0b200241e0016a200e10b00120032000844200510d09200241e0016a41086a290300211520022903e00121160c020b42002100420021030c020b200241d0016a200e10b00120004200200342015620004200522000501b22011b21002003420120011b2103200241d0016a41086a290300211520022903d00121160b200241c0016a201620152006200710fc02200241b0016a20022903c001200241c0016a41086a2903002003200010fb02200241b0016a41086a290300210320022903b001210020022802e402450d00201410010b200e200020127c2206200320137c2006200054ad7c10c201200e41206a2201210e2001200c470d000b0b200241a0016a200520082004ad2206420010fc02200241f8026a2008370300200241e0026a41106a2005370300200241e0026a41086a41003a0000200241033a00e002200241e0026a10b401200241f0036a41086a22014200370300200242003703f00341cdecc0004112200241f0036a1002200241d0036a41086a2001290300370300200220022903f0033703d003200241d0036a41104188f0c1004100410010042101200241a0016a41086a290300210020022903a0012103024002402001417f460d00200242003703e802200242003703e002200241d0036a4110200241e0026a4110410010042201417f460d0920014110490d09200242003703e802200242003703e002200241d0036a4110200241e0026a4110411010042201417f460d092001410f4d0d09200241e8026a290300210720022903e00221050c010b42002105420021070b20024190016a200520072006420010fc0202402003200084500d00200229039001220620024190016a41086a290300220584500d0042002107200241f0036a41086a22014200370300200242003703f00341d9f0c1004116200241f0036a1002200241d0036a41086a220f2001290300370300200220022903f0033703d00302400240200241d0036a41104188f0c100410041001004417f460d00200242003703e802200242003703e002200241d0036a4110200241e0026a4110410010042210417f460d0e2010410f4d0d0e200241e8026a290300211220022903e00221080c010b42002108420021120b20024180016a200820067d201220057d2008200654ad7d2006200510fb02200241f0006a20022903800120024180016a41086a2903002003200010fc0220014200370300200242003703f00341cdc2c000410c200241f0036a1002200f2001290300370300200220022903f0033703d003200241d0036a41104188f0c1004100410010042101200241f0006a41086a290300210020022903702103024002402001417f460d00200242003703e802200242003703e002200241d0036a4110200241e0026a4110410010042201417f460d0f2001410f4d0d0f200241e8026a290300210620022903e00221070c010b420021060b2002200720037c22033703e0022002200620007c2003200754ad7c3703e802200241f0036a41086a22014200370300200242003703f00341cdc2c000410c200241f0036a1002200241d0036a41086a2001290300370300200220022903f0033703d003200241d0036a4110200241e0026a411010030b200241f0036a21042009450d00200a450d00200b10010b200441086a220f420037000020044200370000419bf2c000411420041002200241d0036a41086a2201200f290000370300200220042900003703d003420021000240200241d0036a41104188f0c100410041001004417f460d00200242003703e002200241d0036a4110200241e0026a41084100100441016a41084d0d0220022903e00221000b20014200370300200242003703d00341b1d2c0004115200241d0036a1002200241f0036a41086a2001290300370300200220022903d0033703f0030240200241f0036a41104188f0c100410041001004417f460d00200241d0036a41086a22014200370300200242003703d00341b1d2c0004115200241d0036a1002200441086a2001290300370000200420022903d0033700002004411010080c0d0b200441086a220142003700002004420037000041dfecc000411b20041002200241d0036a41086a220f2001290000370300200220042900003703d003420021030240200241d0036a41104188f0c100410041001004417f460d00200242003703e002200241d0036a4110200241e0026a41084100100441016a41084d0d0520022903e00221030b200142003700002004420037000041faecc000411620041002200f2001290000370300200220042900003703d00302400240200241d0036a41104188f0c100410041001004417f460d00200242003703e002200241d0036a4110200241e0026a41084100100441016a41084d0d0720022903e00222064200520d0141d8acc200104f000b42e80721060b200020037d2006824200510d0c0c0d0b411c41011019000b41eac4c10041331042000b41b8c7c200104f000b200241f0016a201410b00141b8c7c200104f000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41b8c7c200104f000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b200441086a22014200370000200442003700004190edc000411220041002200241d0036a41086a2001290000370300200220042900003703d003024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200241d0036a41104188f0c100410041001004417f460d00200242003703e002200241d0036a4110200241e0026a41084100100441016a41084d0d0220022903e00242017c21000c010b420121000b200220003703e002200441086a22014200370000200442003700004190edc000411220041002200241d0036a41086a220f2001290000370300200220042900003703d003200241d0036a4110200241e0026a41081003200142003700002004420037000041a2edc000411a20041002200f2001290000370300200220042900003703d0030240200241d0036a41104188f0c100410041001004417f460d00200242003703e002200241d0036a4110200241e0026a41084100100441016a41084d0d02200220022903e00222003703a004200441086a220142003700002004420037000041faecc000411620041002200241d0036a41086a2001290000370300200220042900003703d00302400240200241d0036a41104188f0c100410041001004417f460d00200242003703e002200241d0036a4110200241e0026a41084100100441016a41084d0d05200020022903e002520d010c020b200042e807510d010b200220003703e002200441086a220142003700002004420037000041faecc000411620041002200241d0036a41086a220f2001290000370300200220042900003703d003200241d0036a4110200241e0026a410810032001420037000020044200370000419bf2c000411420041002200f2001290000370300200220042900003703d003420021000240200241d0036a41104188f0c100410041001004417f460d00200242003703e002200241d0036a4110200241e0026a41084100100441016a41084d0d0520022903e00221000b200220003703e002200142003700002004420037000041dfecc000411b20041002200f2001290000370300200220042900003703d003200241d0036a4110200241e0026a410810030b4108210b200441086a220142003700002004420037000041e7d0c000411220041002200241d0036a41086a2001290000370300200220042900003703d00341002117024002400240200241d0036a41104188f0c100410041001004417f460d00200242103702f4032002200241d0036a3602f003200241e0026a200241f0036a103620022802e002220a450d0720022802e40221184105210f200241e8026a2802004100200a1b221041057422010d010c020b4100210a4105210f4100410041001b22104105742201450d010b2001200f752217ad42307e2200422088a70d092000a7220f4100480d09200f1000220b450d060b0240200a4101200a1b221920016a22092019460d00201041057441606a410576211a200b21102019210e0340200241e0026a41186a2214200e41186a290000370300200241e0026a41106a220c200e41106a290000370300200241e0026a41086a220d200e41086a2900003703002002200e2900003703e002200241f0036a200241e0026a10b201200241f0036a41086a280200210120022802f0032111200241e0006a200241e0026a10b001200241e0006a41086a29030021002002290360210302402001450d002001410574210f201121010340200241d0006a200110b001200241d0006a41086a29030020007c2002290350220020037c2203200054ad7c2100200141206a2101200f41606a220f0d000b0b200e41206a210e024020022802f403450d00201110010b200241d0036a41186a22012014290300370300200241d0036a41106a220f200c290300370300200241d0036a41086a2211200d290300370300200220022903e0023703d0032010200037030820102003370300201041286a2001290300370300201041206a200f290300370300201041186a2011290300370300201020022903d003370310201041306a2110200e2009470d000b201a41016a2101200a450d080c070b41002101200a0d060c070b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b200f41081019000b2018450d00201910010b200441086a220f42003700002004420037000041f9d0c000411d20041002200241d0036a41086a200f290000370300200220042900003703d003024002400240024002400240200241d0036a41104188f0c100410041001004417f460d00200241003602e002200241d0036a4110200241e0026a41044100100441016a41044d0d02200120022802e0024f0d010c190b20014104490d180b41002109200b2001410041202001676b10c30142002100200441086a220f42003700002004420037000041bcedc000411620041002200241d0036a41086a200f290000370300200220042900003703d0030240200241d0036a41104188f0c100410041001004417f460d00200241003602e002200241d0036a4110200241e0026a41044100100441016a41044d0d0220022802e00221090b024002402001450d00200120012009200920014b1b417f6a220f4d0d04200b41086a2903002103200b200f41306c6a220f2903002107200f41086a2903002105200b29030021004110210f411010002210450d010c050b4200210342002107420021054110210f4110100022100d040b200f41011019000b41eac4c10041331042000b41eac4c10041331042000b41f0ccc200200f2001104e000b2010200037000020102003370008024002400240024041201000220f450d00200f2010290000370000200f41086a201041086a29000037000020101001200f41186a2005370000200f2007370010200441086a221042003700002004420037000041cdecc000411220041002200241d0036a41086a2010290000370300200220042900003703d003200241d0036a4110200f41201003200f10014100211a02402009200141306c221041306d220f200f20094b1b221b450d00201bad4205862200422088a70d052000a7220f4100480d05200f1000221c450d022009450d040c030b4101211c4100211b20090d020c030b412041011019000b200f41011019000b200b20106a200b460d00200141306c210d200241e0026a41106a21104101210e201c210f200b21010340200241e0026a41286a200141286a290300370300200241e0026a41206a200141206a290300370300200241e0026a41186a200141186a2903003703002010200141106a290300370300200241e0026a41086a200141086a290300370300200241d0036a41086a2211201041086a290300370300200241d0036a41106a2214201041106a290300370300200241d0036a41186a220c201041186a290300370300200220012903003703e002200220102903003703d003200f41186a200c290300370000200f41106a2014290300370000200f41086a2011290300370000200f20022903d0033700002009200e221a460d01200141306a2101201a41016a210e200f41206a210f200d41506a220d0d000b0b02402017450d00200b10010b200241e0026a41086a22014200370300200242003703e00241c8f2c0004112200241e0026a1002200241f0036a41086a2001290300370300200220022903e0023703f003024002400240200241f0036a41104188f0c100410041001004417f460d00200242103702d4032002200241f0036a3602d003200241e0026a200241d0036a103620022802e0022219450d1220022802e40221184101210a2019410120191b2117200241e8026a280200410020191b22010d010c020b410021194101210a4100410141001b21174100410041001b2201450d010b2001410574210d201721100340411c10002201450d052002421c3702e402200220013602e002200241e0026a41ddd3c000411c1025200241f0036a41086a2201200241e0026a41086a220c280200360200200220022903e0023703f0032010200241f0036a101e2001280200210f20022802f403211420022802f0032111200441086a220e4200370000200442003700002011200f20041002200241d0036a41086a220f200e290000370300200220042900003703d003200241d0036a4110100802402014450d00201110010b411210002211450d06200242123702e402200220113602e002200241e0026a4181cfc000411210252001200c280200360200200220022903e0023703f0032010200241f0036a101e2001280200211420022802f403210920022802f0032111200f4200370300200242003703d00320112014200241d0036a10022001200f290300370300200220022903d0033703f003024002400240200241f0036a41104188f0c100410041001004417f470d004100410041001b211420090d010c020b200241003602e002200241f0036a4110200241e0026a410441001004200a6a41044d0d0620022802e002210b200f4200370300200242003703d00320112014200241d0036a1002200e200f290300370000200420022903d003370000200441101008200b410041011b21142009450d010b201110010b024020144102490d00411210002211450d0b200242123702e402200220113602e002200241e0026a4181cfc000411210252001200c280200360200200220022903e0023703f0032010200241f0036a101e2001280200211120022802f403210c20022802f003210120022014417f6a3602e002200e4200370000200442003700002001201120041002200f200e290000370300200220042900003703d003200241d0036a4110200241e0026a41041003200c450d00200110010b201041206a2110200d41606a220d0d000b0b02402019450d002018450d00201710010b201c201a4105746a211d0240201a450d00201c21090340200241a0046a200910b201411c10002201450d072002421c3702e402200220013602e002200241e0026a41ddd3c000411c1025200241f0036a41086a2201200241e0026a41086a220b280200360200200220022903e0023703f0032009200241f0036a101e2001280200211720022802f403211820022802f003210a200b4100360200200242013703e00220022802a0042119200241a0046a41086a2802002201200241e0026a101b024002402001450d002001410574210c4100200b280200220f6b211120022802e002211420022802e402210e2019210d0340200d21010240200e20116a411f4b0d00200f41206a2210200f490d06200e410174220d20102010200d491b22104100480d0620101000210d02400240200e450d00200d450d09200d20142010200e200e20104b1b10f8021a201410010c010b200d450d080b200d21142010210e0b200141206a210d2014200f6a22102001290000370000201041186a200141186a290000370000201041106a200141106a290000370000201041086a200141086a290000370000201141606a2111200f41206a210f200c41606a220c0d000b200b200f3602002002200e3602e402200220143602e0020c010b200b280200210f20022802e402210e20022802e00221140b200441086a2201420037000020044200370000200a201720041002200241d0036a41086a2001290000370300200220042900003703d003200241d0036a41102014200f10030240200e450d00201410010b02402018450d00200a10010b200941206a2109024020022802a404450d00201910010b2009201d470d000b0b201aad2200421b88a70d0d2000420586a72201417f4c0d0d024002402001450d0020011000220f0d01200141011019000b4101210f0b200f201c201a410574220c10f8022109200241003602e802200242013703e002201a200241e0026a101b02400240201a450d004100200241e0026a41086a280200220f6b211120022802e002211420022802e402210e2009210d0340200d21010240200e20116a411f4b0d00200f41206a2210200f490d04200e410174220d20102010200d491b22104100480d0420101000210d02400240200e450d00200d450d0f200d20142010200e200e20104b1b10f8021a201410010c010b200d450d0e0b200d21142010210e0b200141206a210d2014200f6a22102001290000370000201041186a200141186a290000370000201041106a200141106a290000370000201041086a200141086a290000370000201141606a2111200f41206a210f200c41606a220c0d000b200241e8026a200f3602002002200e3602e402200220143602e0020c010b200241e8026a280200210f20022802e402210e20022802e00221140b200441086a220142003700002004420037000041c8f2c000411220041002200241d0036a41086a2001290000370300200220042900003703d003200241d0036a41102014200f10030240200e450d00201410010b0240201a450d00200910010b200241c8006a201c201d102e41002111024002400240200228024c220c200228024822016b220f410576220b450d00200f416071220f4100480d03200f1000220d450d132001200c470d010c020b4101210d4100210b2001200c460d010b200c416020016b6a4105762109200d210f0340200141086a2900002100200141106a290000210320012900002106200241e0026a41186a2210200141186a290000370300200241e0026a41106a220e2003370300200241e0026a41086a22112000370300200220063703e002200241f0036a41186a22142010290300370300200241f0036a41106a2210200e290300370300200241f0036a41086a220e2011290300370300200220022903e0023703f003200f41186a2014290300370000200f41106a2010290300370000200f41086a200e290300370000200f20022903f003370000200f41206a210f200c200141206a2201470d000b200941016a21110b410610002201450d0e200242063702e402200220013602e002200241e0026a41bab6c10041061025200241f8036a220120022802e802360200200220022903e0023703f003200241f0036a41b7b6c1004103102520022802f403210f20022802f003220e200128020010c40121100240200f450d00200e10010b41002101200241d0036a410020101046024002400240024020022802d8032011470d004100210e20022802d0032214210f200d21100240410020114f0d00034002402014200d460d00200f2010412010fa020d030b200f41206a210f201041206a2110200e41016a220e2011490d000b0b20022802d403450d01201410010c010b200241e0026a41086a220c200241d0036a41086a280200360200200220022903d0033703e002200241e0026a10c50102402011450d002011410574211041002101200d210f0340200220013602a00441061000220e450d0b200242063702e4022002200e3602e002200241e0026a41bab6c10041061025200241f0036a41086a220e200c280200360200200220022903e0023703f003200241f0036a200241a0046a4104102520022802f403211120022802f0032214200e280200200f10c60102402011450d00201410010b200f41206a210f200141016a2101201041606a22100d000b0b41061000220f450d14200242063702e4022002200f3602e002200241e0026a41bab6c10041061025200241f8036a220f20022802e802360200200220022903e0023703f003200241f0036a41b7b6c1004103102520022802f403211020022802f003220e200f28020010c401210902402010450d00200e10010b0240200920014d0d002001210f0340410610002210450d0c200242063702e402200220103602e002200241e0026a41bab6c10041061025200241f0036a41086a2210200241e0026a41086a220c280200360200200220022903e0023703f003200241f0036a41b7b6c1004103102520022802f403210e20022802f0032214201028020010c40121110240200e450d00201410010b02402011200f4d0d002002200f3602a00441061000220e450d10200242063702e4022002200e3602e002200241e0026a41bab6c100410610252010200c280200360200200220022903e0023703f003200241f0036a200241a0046a4104102520022802f403210e20022802f003221120102802001008200e450d00201110010b2009200f41016a220f470d000b0b41061000220f450d15200242063702e4022002200f3602e002200241e0026a41bab6c10041061025200241f8036a220f20022802e802360200200220022903e0023703f003200241f0036a41b7b6c10041031025200f280200211020022802f403210e20022802f003210f200220013602e002200f2010200241e0026a41041003200e450d00200f1001200b0d010c020b200b450d010b200d10010b200441086a220142003700002004420037000041d2edc000411420041002200241d0036a41086a2001290000370300200220042900003703d00302400240200241d0036a41104188f0c100410041001004417f460d00200241003602e002200241d0036a4110200241e0026a41044100100441016a41044d0d0d20022802e00221010c010b41c0843d21010b200241386a200720052001ad420010fc02200241286a2002290338200241386a41086a290300428094ebdc03420010fb022002200241286a41086a2903003703e802200220022903283703e002200441086a220142003700002004420037000041accfc000411b20041002200241d0036a41086a220f2001290000370300200220042900003703d003200241d0036a4110200241e0026a41101003200142003700002004420037000041e6edc000411520041002200f2001290000370300200220042900003703d00302400240200241d0036a41104188f0c100410041001004417f460d00200241003602e002200241d0036a4110200241e0026a41044100100441016a41044d0d0e20022802e00221010c010b413c21010b200241186a200720052001ad420010fc02200241086a2002290318200241186a41086a290300428094ebdc03420010fb022002200241086a41086a2903003703e802200220022903083703e002200441086a220142003700002004420037000041b1ecc000411c20041002200241d0036a41086a2001290000370300200220042900003703d003200241d0036a4110200241e0026a41101003201b450d14201c10010c140b1018000b201041011019000b41eac4c10041331042000b411c41011019000b411241011019000b411c41011019000b410641011019000b410641011019000b411241011019000b201041011019000b410641011019000b41eac4c10041331042000b41eac4c10041331042000b102c000b410641011019000b41eac4c10041331042000b200f41011019000b410641011019000b410641011019000b2017450d00200b10010b200241f0036a41086a22014200370300200242003703f00341c8f2c0004112200241f0036a1002200241e0026a41086a2001290300370300200220022903f0033703e00202400240024002400240200241e0026a41104188f0c100410041001004417f460d00200242103702d4032002200241e0026a3602d003200241f0036a200241d0036a103620022802f0032201450d02200241f8036a280200211020022802f403210e0c010b410021010b20022001410120011b220f3602e8022002200e410020011b3602e4022002200f3602e0022002200f2010410020011b4105746a3602ec0220024190046a200241e0026a10400240410e10002201450d002002420e3702e402200220013602e002200241e0026a41d79bc100410e1025200241f8036a220120022802e802360200200220022903e0023703f003200241f0036a41b7b6c1004103102520022802f403210f20022802f003220e200128020010c40121100240200f450d00200e10010b41002101200241a0046a41002010104120022802a004210d200228029004210c02400240024002400240024002400240200228029804220920022802a804470d00200c210f200d21100340200120094f0d02200141016a220e2001490d020240200c200d460d00200f2010412010fa020d020b201041206a2111200f41206a2114200f41286a210f201041286a2110200e210120142903002011290300510d000b0b2002280294042101200241e0026a10c70120022802f002220f450d0120022802f402450d02200f100120010d030c040b024020022802a404450d00200d10010b200228029404450d04200c10010c040b200441086a220f42003700002004420037000041f0f1c100410d20041002200241d0036a41086a200f290000370300200220042900003703d003420021000240200241d0036a41104188f0c100410041001004417f460d00200242003703e002200241d0036a4110200241e0026a41084100100441016a41084d0d0520022903e00221000b200241f8026a2009360200200241f4026a20013602002002200c3602f002200242003703e802200220003703e002200241003602f803200242013703f00341081000220f450d07200f20003700002002428880808080013702f4032002200f3602f003411010002210450d082010200f290000370000200f1001201042003700082002429080808080023702f403200220103602f003200241f0036a200241e0026a41106a1022200241f0036a41086a280200211020022802f403210e20022802f003210f200441086a221142003700002004420037000041e59bc100411d20041002200241d0036a41086a2011290000370300200220042900003703d003200241d0036a4110200f20101003200e450d00200f10010b2001450d010b200c10010b20022802a404450d00200d1001200241b0046a24000f0b200241b0046a24000f0b41eac4c10041331042000b410e41011019000b41eac4c10041331042000b410841011019000b411041011019000ba20504057f017e017f027e230041c0006b220324002003200010b001024002402003290300200341086a29030084500d00024002400240411410002204450d002003421437023420032004360230200341306a41eeefc10041141025200341206a41086a22042003280238360200200320032903303703202000200341206a101e20042802002105200328022421062003280220210742002108200341306a41086a220942003703002003420037033020072005200341306a1002200420092903003703002003200329033037032002400240200341206a41104188f0c100410041001004417f460d002003420037033820034200370330200341206a4110200341306a4110410010042204417f460d012004410f4d0d01200341386a290300210a200329033021082006450d040c030b4200210a20060d020c030b41eac4c10041331042000b411441011019000b200710010b2000200820017c220b200a20027c200b200854ad7c10aa014200210a200341306a41086a220042003703002003420037033041d9f0c1004116200341306a1002200341206a41086a20002903003703002003200329033037032002400240200341206a41104188f0c100410041001004417f460d002003420037033820034200370330200341206a4110200341306a4110410010042200417f460d032000410f4d0d03200341386a29030021082003290330210a0c010b420021080b200a20017c2201200a542200200820027c2000ad7c220a200854200a2008511b0d00200320013703102003200a370318200341306a41086a220042003703002003420037033041d9f0c1004116200341306a1002200341206a41086a200029030037030020032003290330370320200341206a4110200341106a411010030b200341c0006a24000f0b41eac4c10041331042000bc12d09087f047e0f7f017e077f017e017f017e027f230041d0026b220424000240024020014115490d00410121054101210602400240024002400340200620057141017321070340024002402003450d0020054101710d012000200110da012003417f6a21030c010b2000200110db01200441d0026a24000f0b2001410276220641036c2108200641017421094100210a024020014132490d00410241012000200641306c6a220b41506a290300220c200b290300220d54200b41586a290300220e200b41086a290300220f54200e200f511b22101b2010200c200d20101b220c200b41306a290300220d54200e200f20101b220e200b41386a290300220f54200e200f511b22111b200020062006417f6a221220101b221341306c6a220b290300200d200c20111b54200b41086a290300220c200f200e20111b220e54200c200e511b22146a2000200941306c6a220b41506a290300220c200b290300220d54200b41586a290300220e200b41086a290300220f54200e200f511b22156a200c200d20151b220c20002009410172221641306c6a220b290300220d54200e200f20151b220e200b41086a290300220f54200e200f511b22176a200020092009417f6a221820151b221941306c6a220b290300200d200c20171b54200b41086a290300220c200f200e20171b220e54200c200e511b221a6a2000200841306c6a220b41506a290300220c200b290300220d54200b41586a290300220e200b41086a290300220f54200e200f511b221b6a200c200d201b1b220c200b41306a290300220d54200e200f201b1b220e200b41386a290300220f54200e200f511b220b6a200020082008417f6a221c201b1b221d41306c6a220a290300200d200c200b1b54200a41086a290300220c200f200e200b1b220e54200c200e511b221e6a210a201d200841016a201c2008201b1b200b1b201e1b2108201920162018200920151b20171b201a1b21092013200641016a2012200620101b20111b20141b21060b200a2000200641306c6a220b290300220c2000200941306c6a2210290300220d54200b41086a290300220e201041086a290300220f54200e200f511b220b6a200c200d200b1b220c2000200841306c6a2210290300220d54200e200f200b1b220e201041086a290300220f54200e200f511b22106a210a0240024002400240200020092006200b1b221e41306c6a2215290300200d200c20101b5a201541086a290300220c200f200e20101b220e5a200c200e511b0d00200a41016a220a410b4d0d01024020014101762208450d002000200141306c6a41506a2106200021090340200441a0026a41286a220b200941286a2210290300370300200441a0026a41206a220a200941206a2215290300370300200441a0026a41186a221b200941186a2211290300370300200441a0026a41106a2217200941106a2212290300370300200441a0026a41086a2213200941086a2214290300370300200420092903003703a002200641086a2216290300210e200641106a2218290300210f200641186a2219290300210c200641206a221a290300210d2006290300211f2010200641286a221c2903003703002015200d3703002011200c3703002012200f3703002014200e3703002009201f370300201c200b290300370300201a200a2903003703002019201b2903003703002018201729030037030020162013290300370300200620042903a002370300200941306a2109200641506a21062008417f6a22080d000b0b2001201e417f736a211e4101452007724101710d030c020b200820062009200b1b20101b211e0b200a45452007724101710d010b2000200110dc010d080b024002400240024002402002450d00201e20014f0d0a2000201e41306c6a2206290300200229030054200641086a2209290300220e200241086a290300220f54200e200f511b0d01200441a0026a41286a220a200041286a2212290300370300200441a0026a41206a2215200041206a2213290300370300200441a0026a41186a221b200041186a2214290300370300200441a0026a41106a2211200041106a2208290300370300200441a0026a41086a2217200041086a220b290300370300200420002903003703a0022009290300210e200641106a2210290300210f200641186a2216290300210c200641206a2218290300210d2006290300211f2012200641286a22192903003703002013200d3703002014200c3703002008200f370300200b200e3703002000201f3703002019200a290300370300201820152903003703002016201b2903003703002010201129030037030020092017290300370300200620042903a002370300200b290300210e2000290300210c200441186a22202012290300370300200441106a22212013290300370300200441086a2222201429030037030020042008290300370300200041506a2116200041306a211841002109410020012208417f6a220b4f0d02410621230c030b2001450d080b201e20014f0d06200441a0026a41286a2218200041286a2226290300370300200441a0026a41206a2219200041206a2228290300370300200441a0026a41186a221a200041186a2220290300370300200441a0026a41106a221c200041106a2221290300370300200441a0026a41086a221d200041086a2222290300370300200420002903003703a0022000201e41306c6a2206290300210e200641086a2209290300210f200641106a2208290300210c200641186a220b290300210d200641206a2210290300211f2026200641286a220a2903003703002028201f3703002020200d3703002021200c3703002022200f3703002000200e370300200a201829030037030020102019290300370300200b201a2903003703002008201c2903003703002009201d290300370300200620042903a0023703002022290300210e2000290300210f200441186a22052026290300370300200441106a22072028290300370300200441086a222a202029030037030020042021290300370300200041306a21154100212402402001417f6a2208450d00201521060340200f20062903005a200e200641086a290300220c5a200e200c511b0d01200641306a2106202441016a22242008490d000b0b2000200141306c6a210620082109024003402006210b2009222520244d0d012025417f6a2109200f200b41506a220629030054200e200b41586a290300220c54200e200c511b450d000b0b20252024490d0520082025490d0241800121144100210a41002112410021104100211741800121162015202441306c6a222b21150340200b20156b220641306e21090240024002400240024002400240200641afe0004b221e0d00200941807f6a20092012200a492017201049220872221b1b2106201b450d012016200620081b21162006201420081b21140b20172010470d020c010b2006200641017622166b211420172010470d010b2016450d0141002109200441206a22172110201521060340201020093a00002010200f20062903005a200e200641086a290300220c5a200e200c511b6a2110200641306a2106200941016a22092016490d000b0b2012200a470d020c010b200441206a221021172012200a470d010b02402014450d00200b41506a210641002109200441a0016a2212210a0340200a20093a0000200a200f200629030054200e200641086a290300220c54200e200c511b6a210a200641506a2106200941016a22092014490d000c020b0b200441a0016a220a21120b0240200a20126b2206201020176b2209200920064b1b2213450d002018201520172d000041306c6a220641286a2903003703002019200641206a290300370300201a200641186a290300370300201c200641106a290300370300201d200641086a290300370300200420062903003703a002201520172d000041306c6a2206200b20122d0000417f7341306c6a2209290300370300200641286a200941286a290300370300200641206a200941206a290300370300200641186a200941186a290300370300200641106a200941106a290300370300200641086a200941086a290300370300024020134101460d00410021080340200b201220086a221b2d0000417f7341306c6a22062015201720086a41016a22112d000041306c6a2209290300370300200641286a200941286a290300370300200641206a200941206a290300370300200641186a200941186a290300370300200641106a200941106a290300370300200641086a200941086a290300370300201520112d000041306c6a2206200b201b41016a2d0000417f7341306c6a2209290300370300200641286a200941286a290300370300200641206a200941206a290300370300200641186a200941186a290300370300200641106a200941106a290300370300200641086a200941086a290300370300200841026a2106200841016a2209210820062013490d000b201220096a2112201720096a21170b200b20122d0000417f7341306c6a220620042903a002370300200641286a2018290300370300200641206a2019290300370300200641186a201a290300370300200641106a201c290300370300200641086a201d290300370300201241016a2112201741016a21170b2015201641306c6a201520172010461b2115200b410020146b41306c6a200b2012200a461b210b201e0d000b02400240201720104f0d000340201820152010417f6a22102d000041306c6a220941286a22082903003703002019200941206a220a290300370300201a200941186a221b290300370300201c200941106a2211290300370300201d200941086a2212290300370300200420092903003703a002200b41506a2206290300210c200b41586a2213290300210d200b41606a2214290300211f200b41686a22162903002127200b41706a221e29030021292008200b41786a220b290300370300200a2029370300201b20273703002011201f3703002012200d3703002009200c370300200b2018290300370300201e20192903003703002016201a2903003703002014201c2903003703002013201d290300370300200620042903a0023703002006210b20172010490d000c020b0b201521062012200a4f0d000340200a417f6a220a2d000021092018200641286a22082903003703002019200641206a2210290300370300201a200641186a2215290300370300201c200641106a221b290300370300201d200641086a2211290300370300200420062903003703a002200b2009417f7341306c6a2209290300210c200941086a2217290300210d200941106a2213290300211f200941186a22142903002127200941206a221629030021292008200941286a221e2903003703002010202937030020152027370300201b201f3703002011200d3703002006200c370300201e2018290300370300201620192903003703002014201a2903003703002013201c2903003703002017201d290300370300200920042903a002370300200641306a21062012200a490d000b0b2000200e3703082000200f37030020262005290300370300202820072903003703002020202a290300370300200020042903003703100240024020012006202b6b41306e20246a22094d0d002018202629030037030020192028290300370300201a2020290300370300201c2021290300370300201d2022290300370300200420002903003703a0022000200941306c6a2206290300210e200641086a2208290300210f200641106a220b290300210c200641186a2210290300210d200641206a220a290300211f2026200641286a22152903003703002028201f3703002020200d3703002021200c3703002022200f3703002000200e37030020152018290300370300200a20192903003703002010201a290300370300200b201c2903003703002008201d290300370300200620042903a002370300200120096b2208450d0120082009200920084b1b210b20014103762110200641306a210a024020092008417f6a22014f0d00200020092002200310c30120062102200a2100200b20104f2105202520244d2106200141154f0d070c0c0b200a20012006200310c301200b20104f2105202520244d21062009220141154f0d060c0b0b4190d4c20020092001104e000b41a0d4c200104f000b410021230b03400240024002400240024002400240024002400240024002400240024002400240024020230e09040507080603000102020b2018200941306c6a2106410721230c100b2006290300200c54200641086a290300220f200e54200f200e511b0d0a410821230c0f0b200641306a2106200941016a2209200b490d070c080b200a2018200941306c6a220641286a220b2903003703002015200641206a2219290300370300201b200641186a221a2903003703002011200641106a221c2903003703002017200641086a221d290300370300200420062903003703a002201041306a221e290300210f201041386a2224290300210d201041c0006a2225290300211f201041c8006a22262903002127201041d0006a22282903002129200b201041d8006a221029030037030020192029370300201a2027370300201c201f370300201d200d3703002006200f3703002010200a290300370300202820152903003703002026201b2903003703002025201129030037030020242017290300370300201e20042903a002370300200941016a22092008417f6a220b490d09410021230c0d0b2016200841306c6a2106410121230c0c0b20092008417f6a22084f0d0a410421230c0b0b2006290300210f200641086a210b200641506a22102106200f200c54200b290300220f200e54200f200e511b0d070c080b2000200c3703002000200e370308201220202903003703002013202129030037030020142022290300370300200020042903003703102001200941016a2206490d01410321230c090b2000200641306c6a2100200120066b220141154f0d0a0c100b20062001107a000b410721230c060b410021230c050b410021230c040b410621230c030b410121230c020b410521230c010b410221230c000b0b0b0b202520081076000b20242025107a000b4190d4c200201e2001104e000b4180d4c20041004100104e000b41b8d4c200201e2001104e000b20014102490d00200041a07f6a21104100210a410121090340200941016a210b02402000200941306c6a220841506a22062903002008290300220c5a200841586a290300220f200841086a2215290300220e5a200f200e511b0d00200441186a2211200841286a221b290300370300200441106a2217200841206a2212290300370300200441086a2213200841186a221429030037030020042008290310370300200820062903003703002015200641086a290300370300200841106a200641106a2903003703002014200641186a2903003703002012200641206a290300370300201b200641286a29030037030020002009417f6a221541306c6a211b02400240024002402015450d00200a210920102106200841a07f6a290300200c5a200841a87f6a290300220f200e5a200f200e511b0d03034020064188016a200641d8006a29030037030020064180016a200641d0006a290300370300200641f8006a200641c8006a290300370300200641f0006a200641c0006a290300370300200641e8006a200641386a290300370300200641e0006a200641306a29030037030020094101460d022006290300210f200641086a21082009417f6a2109200641506a2106200f200c542008290300220f200e54200f200e511b0d000c030b0b410021150c020b410021090b2000200941306c6a211b200921150b201b200c370300201b200e3703082000201541306c6a220641286a2011290300370300200641206a2017290300370300200641186a2013290300370300200620042903003703100b200a41016a210a201041306a2110200b2109200b2001490d000b0b200441d0026a24000b6401027f230041106b220224004100210302400240200020014188f0c100410041001004417f460d002002410036020c200020012002410c6a41044100100441016a41044d0d01200228020c21030b200241106a240020030f0b41eac4c10041331042000bc30603037f017e067f230041306b22012400200141206a41086a2202420037030020014200370320419ab6c100411d200141206a1002200141086a200229030037030020012001290320370300024002400240024002400240200141104188f0c100410041001004417f460d002001421037021420012001360210200141206a200141106a103420012802202202450d0402402001280224450d00200210010b20002802002202450d01200041046a280200450d0120021001200141306a24000f0b0240024020002802002203450d002000290204210420012003360210200120043702142004422088a721000c010b410610002200450d052001420637022420012000360220200141206a41bab6c10041061025200141086a2200200128022836020020012001290320370300200141b7b6c100410310252001280204210220012802002205200028020010c401210002402002450d00200510010b200141106a41002000104620012802102103200128021821000b20014100360228200142013703202000200141206a101b024002402000450d0020004105742106200141206a41086a280200210720012802202108200128022421052003210903402009210002400240024002402005200722026b41204f0d00200241206a22072002490d0820054101742209200720072009491b22094100480d0820091000210a2005450d01200a450d09200a200820092005200520094b1b10f8021a200810010c020b200241206a21070c020b200a450d070b200a2108200921050b200041206a2109200820026a22022000290000370000200241186a200041186a290000370000200241106a200041106a290000370000200241086a200041086a290000370000200641606a22060d000b200141286a200736020020012005360224200120083602200c010b200141286a280200210720012802242105200128022021080b200141206a41086a2200420037030020014200370320419ab6c100411d200141206a1002200141086a2000290300370300200120012903203703002001411020082007100302402005450d00200810010b2001280214450d00200310010b200141306a24000f0b1018000b200941011019000b41eac4c10041331042000b410641011019000b6001017f0240412010002203450d0020032002290000370000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a29000037000020002001200341201003200310010f0b412041011019000bcc0202037f027e230041306b22012400200141206a41086a220242003703002001420037032041e59bc100411d200141206a1002200141086a20022903003703002001200129032037030002400240200141104188f0c100410041001004417f460d002001200136021020014110360214200142003703202001410020014110200141206a41084100100422022002417f461b22024108200241084922031b220236021820030d012001290320210420014200370320200141106a41086a410020014110200141206a41082002100422032003417f461b2203410820034108491b20026a360200200341074d0d0120012903202105200141206a200141106a103c20012802202202450d0120002001290224370214200020023602102000200537030820002004370300200141306a24000f0b20004100360210200141306a24000f0b41eac4c10041331042000bc00301057f230041d0006b22022400024002400240411210002203450d002002421237023420022003360230200241306a4185efc00041121025200241086a220320022802383602002002200229033037030020012002101e200328020021042002280204210520022802002101200241306a41086a220342003703002002420037033020012004200241306a1002200241206a41086a20032903003703002002200229033037032002400240200241206a41104188f0c100410041001004417f460d00200241c8006a4200370300200241306a41106a42003703002003420037030020024200370330200241206a4110200241306a4120410010042203417f460d012003411f4d0d01200241186a2203200241306a41186a290300370300200241106a2204200241306a41106a290300370300200241086a2206200241306a41086a29030037030020022002290330370300200041013a000020002002290300370001200041096a2006290300370000200041116a2004290300370000200041196a20032903003700002005450d040c030b200041003a000020050d020c030b41eac4c10041331042000b411241011019000b200110010b200241d0006a24000bcb04010c7f230041206b220224000240411510002203450d002002421537021420022003360210200241106a41c8d3c00041151025200241086a220320022802183602002002200229031037030020002002101e20032802002104200228020421052002280200210620024100360218200242013703102001280200210720012802082200200241106a101b02400240024002402000450d0020004105742108200241106a41086a28020021092002280210210a2002280214210b2007210c0340200c21000240024002400240200b200922036b41204f0d00200341206a22092003490d07200b410174220c20092009200c491b220c4100480d07200c1000210d200b450d01200d450d08200d200a200c200b200b200c4b1b10f8021a200a10010c020b200341206a21090c020b200d450d060b200d210a200c210b0b200041206a210c200a20036a22032000290000370000200341186a200041186a290000370000200341106a200041106a290000370000200341086a200041086a290000370000200841606a22080d000b200241186a20093602002002200b3602142002200a3602100c010b200241106a41086a28020021092002280214210b2002280210210a0b200241106a41086a220042003703002002420037031020062004200241106a1002200241086a20002903003703002002200229031037030020024110200a200910030240200b450d00200a10010b02402005450d00200610010b0240200141046a280200450d00200710010b200241206a24000f0b1018000b200c41011019000b411541011019000bbb0604057f017e017f017e230041206b2202240002400240410f10002203450d002002420f37021420022003360210200241106a41ddd2c000410f1025200241086a220320022802183602002002200229031037030020012002101e20032802002104200228020421052002280200210642002107200241106a41086a220842003703002002420037031020062004200241106a1002200320082903003703002002200229031037030002400240024002400240200241104188f0c100410041001004417f460d002002420037031020024110200241106a41084100100441016a41084d0d01200229031021070b02402005450d00200610010b42002109200241106a41086a220342003703002002420037031041f0f1c100410d200241106a1002200241086a2003290300370300200220022903103703000240200241104188f0c100410041001004417f460d002002420037031020024110200241106a41084100100441016a41084d0d02200229031021090b418485c1002103024020072009560d00411110002203450d062002421137021420022003360210200241106a41f384c10041111025200241086a220320022802183602002002200229031037030020012002101e20032802002101200228020421042002280200210642002107200241106a41086a220542003703002002420037031020062001200241106a100220032005290300370300200220022903103703000240200241104188f0c100410041001004417f460d002002420037031020024110200241106a41084100100441016a41084d0d04200229031021070b02402004450d00200610010b42002109200241106a41086a220342003703002002420037031041f0f1c100410d200241106a1002200241086a2003290300370300200220022903103703000240200241104188f0c100410041001004417f460d002002420037031020024110200241106a41084100100441016a41084d0d05200229031021090b418485c100410020072009561b21030b2000411e36020420002003360200200241206a24000f0b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b410f41011019000b411141011019000bb30301097f23002102200128020821032001280204210420012802002105200241306b2201411c6a22064100360200200141186a2207200536020020012004360214200120044100472208360210024002402004450d002004417f6a2102200141106a41047221092005210a0340200a28029002210a200641003602002007200a36020020012002360214200120024100473602102002417f6a2202417f470d000c020b0b200141106a41047221090b200141086a200941086a280200360200200120092902003703002001411c6a220a4100360200200141106a41086a22062005360200200120043602142001200836021002402004450d002004417f6a21020340200520052f01064102746a4190026a2802002105200a41003602002006200536020020012002360214200120024100473602102002417f6a2202417f470d000b0b2001411c6a2802002105200141106a41086a28020022022f0106210a20012802142106200020033602202000411c6a200a360200200041186a2005360200200041146a2002360200200020063602102000410036020c200041086a200141086a280200360200200020012903003702000bf20202067f027e230041206b22012400200141086a200010cd01024020012802082202450d00200141186a2103200141146a2104034020032802002105200428020021060240200128020c450d00200210010b02402006450d002005450d00200610010b200141086a200010cd01200128020822020d000b0b024002402000280204220641e8bdc000460d0020002802002102200028020821000240024020062802002205450d00200633010421072001200536020c2001200241016a2202360208200120074220862000ad842207370310200610012005450d020c010b2000ad210741002105200610014100450d010b0240024020052802002206450d00200533010421082001200636020c2001200241016a36020820012008422086200742ffffffff0f8384370310200510012006450d020c010b41002106200510014100450d010b034020062802002205450d02200610012005210620050d000b0b200141206a24000f0b20061001200141206a24000bee0903077f017e017f230041f0006b220224000240024020012802202203450d00200141206a2003417f6a36020020012802082104200128020c2205200128020422032f01064f0d01200241186a41086a220620032005410c6c6a220741106a2802003602002002200741086a290200370318200241086a220820074194016a2802003602002007418c016a29020021092001410c6a200541016a360200200141086a2004360200200141046a200336020020022009370300200241c8006a41086a22032006280200360200200241dc006a200828020036020020002002290318220937020020022002290300370254200041086a2003290300370200200041106a200241c8006a41106a29030037020020022009370348200241f0006a24000f0b20004100360200200241f0006a24000f0b200128020021070240024020032802002205450d00200333010421092002200536024c2002200741016a2207360248200220094220862004ad8422093703500c010b2004ad2109410021050b2003100120052f01062103200241086a22042005360200200220073602040240024002402009422088a7220620034f0d00200241106a20063602002002410c6a20093e02002002410036020020024104722108200241186a21070c010b2002410c6a2206200937020020024101360200200241047221080240200528020022030d004103210a0c020b4100210a0c010b4105210a0b03400240024002400240024002400240024002400240024002400240024002400240200a0e0a01030002040508090607070b20062009370200200420033602002002200736020420024101360200200322052802002203450d094100210a0c0f0b2005330104422086200942ffffffff0f83842109200741016a21070c090b200942ffffffff0f832109410021034101210a0c0d0b200510012009422088a7220520032f01064f0d084104210a0c0c0b200241106a20053602002002410c6a20093e0200200241086a20033602002002200736020420024100360200200241186a21074105210a0c0b0b20072008290200370200200741086a200841086a290200370200200241286a41086a200228021c220520022802242204410c6c6a220341106a2802003602002002200341086a290200370328200241386a41086a20034194016a28020036020020022003418c016a290200370338200520044102746a4194026a280200210520072802002108200241c8006a410c6a220720022802202204360200200241c8006a41086a2206200536020020022008417f6a220336024c200220034100473602482003450d074108210a0c0a0b2008417e6a2103200241c8006a41047221084109210a0c090b200528029002210520072004360200200620053602002002200336024c200220034100473602482003417f6a2203417f470d060c070b200241c8006a41047221084107210a0c070b20012008290200370200200141086a200841086a2802003602002001410c6a4100360200200241c8006a41086a2203200241286a41086a280200360200200241dc006a200241386a41086a28020036020020002002290328220937020020022002290338370254200041086a2003290300370200200041106a200241c8006a41106a29030037020020022009370348200241f0006a24000f0b4103210a0c050b4101210a0c040b4102210a0c030b4106210a0c020b4109210a0c010b4107210a0c000b0bf30502067f027e230041206b220124002000280208210220002802042103200028020021042001411c6a22054100360200200141186a22062004360200200120033602142001200341004736021002402003450d002003417f6a21000340200428026c2104200541003602002006200436020020012000360214200120004100473602102000417f6a2200417f470d000b0b2001411c6a2802002104200141186a28020021052001280214210602402003450d0003402003417f6a22030d000b0b41002100024003402002450d010240200020052f01064f0d0020004103742103200041016a21002002417f6a2102200520036a41146a290200a74103470d010c020b0240024020052802002200450d00200641016a210620053301044220862004ad8421070c010b2004ad2107410021000b20051001024002402007422088a7220320002f01064f0d00200021040c010b03400240024020002802002204450d002000330104422086200742ffffffff0f83842107200641016a21060c010b200742ffffffff0f832107410021040b20001001200421002007422088a7220320042f01064f0d000b0b200420034102746a41f0006a2802002105200420034103746a41146a29020021082007a72104024020064101460d00410120066b21000340200528026c2105200041016a22000d000b0b41002106410021002002417f6a21022008a74103470d000b0b02400240200541e8bdc000460d000240024020052802002203450d0020053301042107200120033602142001200641016a2206360210200120074220862004ad842207370318200510012003450d020c010b2004ad210741002103200510014100450d010b0240024020032802002200450d0020033301042108200120003602142001200641016a36021020012008422086200742ffffffff0f8384370318200310012000450d020c010b41002100200310014100450d010b034020002802002204450d02200010012004210020040d000b0b200141206a24000f0b20001001200141206a24000bb30301097f23002102200128020821032001280204210420012802002105200241306b2201411c6a22064100360200200141186a2207200536020020012004360214200120044100472208360210024002402004450d002004417f6a2102200141106a41047221092005210a0340200a2802f806210a200641003602002007200a36020020012002360214200120024100473602102002417f6a2202417f470d000c020b0b200141106a41047221090b200141086a200941086a280200360200200120092902003703002001411c6a220a4100360200200141106a41086a22062005360200200120043602142001200836021002402004450d002004417f6a21020340200520052f01064102746a41f8066a2802002105200a41003602002006200536020020012002360214200120024100473602102002417f6a2202417f470d000b0b2001411c6a2802002105200141106a41086a28020022022f0106210a20012802142106200020033602202000411c6a200a360200200041186a2005360200200041146a2002360200200020063602102000410036020c200041086a200141086a280200360200200020012903003702000bb50302077f027e230041a0016b22012400200141086a200010d101024020012903284202510d00200141d8006a4104722102200141c8006a2103200141c4006a2104200141c0006a2105200141286a21060340200141d8006a41086a200341086a29030037030020012003290300370358024020052802002207450d002004280200450d00200710010b20014190016a41086a200241086a2802003602002001200229020037039001200141e8006a20014190016a10cb01200141e8006a10cc01200141086a200010d10120062903004202520d000b0b02400240024002402000280204220241e8bdc000460d0020022802002203450d0120002802082107200233010421082001200028020041016a2200360208200120084220862007ad8422083703102001200336020c2002100120032802002202450d02200333010421092001200236020c2001200041016a36020820012009422086200842ffffffff0f838437031020031001034020022802002203450d04200210012003210220030d000b0b200141a0016a24000f0b20021001200141a0016a24000f0b20031001200141a0016a24000f0b20021001200141a0016a24000ba20d030d7f017e017f230041e0016b220224000240024020012802202203450d00200141206a2003417f6a36020020012802082104200128020c2205200128020422032f01064f0d01200241306a41186a2206200320054105746a220741206a290000370300200241306a41106a2208200741186a290000370300200241306a41086a2209200741106a2900003703002002200741086a290000370330200241d0006a41286a220a2003200541306c6a22074190036a290300370300200241d0006a41206a220b20074188036a290300370300200241d0006a41186a220c20074180036a290300370300200241d0006a41106a220d200741f8026a290300370300200241d0006a41086a220e200741f0026a290300370300200741e8026a290300210f2001410c6a200541016a360200200141086a2004360200200141046a20033602002002200f37035020024180016a41186a200629030037030020024180016a41106a200829030037030020024180016a41086a200929030037030020024180016a41286a200e29030037030020024180016a41306a200d290300370300200241b8016a200c290300370300200241c0016a200b290300370300200241c8016a200a2903003703002002200229033037038001200220022903503703a001200020024180016a41d00010f8021a200241e0016a24000f0b20004202370320200241e0016a24000f0b200128020021050240024020032802002207450d002003330104210f20022007360284012002200541016a2205360280012002200f4220862004ad84220f370388010c010b2004ad210f410021070b20031001200241106a220420073602002002200536020c024002400240200f422088a7220320072f01064f0d00200241186a2003360200200241146a200f3e020020024100360208200241086a4104722108200241206a21050c010b200241146a2206200f37020020024101360208200241086a41047221080240200728020022030d00410321100c020b410021100c010b410521100b0340024002400240024002400240024002400240024002400240024002400240024020100e0a01030002040508090607070b2006200f37020020024101360208200322072802002203450d09410021100c0f0b2007330104422086200f42ffffffff0f8384210f200541016a21050c090b200f42ffffffff0f83210f41002103410121100c0d0b20071001200420033602002002200536020c200f422088a7220720032f01064f0d08410421100c0c0b200241186a2007360200200241146a200f3e020020024100360208200241206a2105410521100c0b0b20052008290200370200200541086a200841086a290200370200200241306a41086a20022802242207200228022c22044105746a220341106a290000370300200241306a41106a200341186a290000370300200241306a41186a200341206a2900003703002002200341086a290000370330200241f8006a2007200441306c6a22034190036a290300370300200241d0006a41206a20034188036a290300370300200241d0006a41186a20034180036a290300370300200241d0006a41106a200341f8026a290300370300200241d0006a41086a200341f0026a2903003703002002200341e8026a290300370350200720044102746a41fc066a2802002107200528020021082002418c016a22052002280228220436020020024180016a41086a2206200736020020022008417f6a22033602840120022003410047360280012003450d07410821100c0a0b2008417e6a210320024180016a4104722108410921100c090b20072802f80621072005200436020020062007360200200220033602840120022003410047360280012003417f6a2203417f470d060c070b20024180016a4104722108410721100c070b20012008290200370200200141086a200841086a2802003602002001410c6a410036020020024180016a41186a200241306a41186a29030037030020024180016a41106a200241306a41106a29030037030020024180016a41086a200241306a41086a29030037030020024180016a41286a200241d0006a41086a290300370300200241b0016a200241d0006a41106a290300370300200241b8016a200241d0006a41186a290300370300200241c0016a200241f0006a290300370300200241c8016a200241d0006a41286a2903003703002002200229033037038001200220022903503703a001200020024180016a41d00010f8021a200241e0016a24000f0b410321100c050b410121100c040b410221100c030b410621100c020b410921100c010b410721100c000b0bf906020a7f027e230041206b220124002000280208210220002802042103200028020021042001411c6a22054100360200200141186a22062004360200200120033602142001200341004736021002402003450d002003417f6a2100034020042802e8022104200541003602002006200436020020012000360214200120004100473602102000417f6a2200417f470d000b0b2001411c6a2802002107200141186a28020021052001280214210602402003450d0003402003417f6a22030d000b0b02402002450d0041002100034002400240200020052f01064f0d002005200041146c6a22084194016a280200210920084190016a280200210a20052000410c6c6a2203410c6a2802002104200341086a2802002103200041016a21002008419d016a2d000041ff01714105460d030c010b0240024020052802002200450d00200641016a210620053301044220862007ad84210b0c010b2007ad210b410021000b2005100102400240200b422088a7220320002f01064f0d00200021040c010b03400240024020002802002204450d002000330104422086200b42ffffffff0f8384210b200641016a21060c010b200b42ffffffff0f83210b410021040b2000100120042100200b422088a7220320042f01064f0d000b0b200420034102746a41ec026a28020021052004200341146c6a2200419d016a2d0000210820004194016a280200210920004190016a280200210a20042003410c6c6a2200410c6a2802002104200041086a2802002103200ba72107024020064101460d00410120066b2100034020052802e8022105200041016a22000d000b0b4100210641002100200841ff01714105460d020b02402004450d00200310010b2002417f6a210202402009450d00200a10010b20020d000b0b02400240200541e8bdc000460d000240024020052802002204450d002005330104210b200120043602142001200641016a22063602102001200b4220862007ad84220b370318200510012004450d020c010b2007ad210b41002104200510014100450d010b0240024020042802002200450d002004330104210c200120003602142001200641016a3602102001200c422086200b42ffffffff0f8384370318200410012000450d020c010b41002100200410014100450d010b034020002802002204450d02200010012004210020040d000b0b200141206a24000f0b20001001200141206a24000b810703047f017e087f230041d0006b21020240024020012802202203450d00200141206a2003417f6a360200200128020c2204200128020422032f01064f0d012001410c6a200441016a36020020002003200441146c6a418c016a360204200020032004410c6c6a41086a3602000f0b20004100360204200041003602000f0b0240024020032802002205450d002003330104422086200141086a350200842106200128020041016a21040c010b410021050b20052f01062103200241106a220720053602002002200436020c0240024002402006422088a7220820034f0d00200241186a2008360200200241146a20063e020020024100360208200241086a4104722109200241206a21030c010b200241146a220a200637020020024101360208200241086a41047221090240200528020022030d004103210b0c020b4100210b0c010b4105210b0b03400240024002400240024002400240024002400240024002400240024002400240200b0e0a01030002040508090607070b200a200637020020024101360208200322052802002203450d094100210b0c0f0b200642ffffffff0f832005330104422086842106200441016a21040c090b410021034101210b0c0d0b20032f01062105200720033602002002200436020c2006422088a7220820054f0d084104210b0c0c0b200241186a2008360200200241146a20063e020020024100360208200241206a21034105210b0c0b0b200341086a200941086a2902003702002003200929020022063702002002280224200228022c4102746a41ec026a2802002104200241086a41086a2802002103200241186a280200210a200241306a410c6a220520022802282207360200200241306a41086a2208200436020020022006a7220c417f6a2209360234200220094100473602302003200a41146c6a210d2003200a410c6c6a210e2009450d074108210b0c0a0b200c417e6a2103200241306a410472210a4109210b0c090b20042802e8022104200520073602002008200436020020022003360234200220034100473602302003417f6a2203417f470d060c070b200241306a410472210a4107210b0c070b2001200a290200370200200141086a200a41086a2802003602002001410c6a41003602002000200d418c016a3602042000200e41086a3602000f0b4103210b0c050b4101210b0c040b4102210b0c030b4106210b0c020b4109210b0c010b4107210b0c000b0b3400200041bf9fc10036020420004100360200200041146a4108360200200041106a41e0cdc200360200200041086a42073702000b4b00200041ddf5c10036020420004100360200200041206a41033602002000411c6a4188d2c200360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000bce1601157f230041c0056b220424000240024020014115490d00410121054101210602400240024002400340200620057141017321070340024002402003450d0020054101710d012000200110d7012003417f6a21030c010b2000200110d801200441c0056a24000f0b2001410276220841036c2109200841017421064100210a024020014132490d0020092009417f6a220b2000200941e0016c6a220a280200220c200a41a07e6a280200220d49220e1b220f200941016a200b2009200e1b200a41e0016a2802002209200d200c200e1b220a49220c1b2009200a200c1b2000200f41e0016c6a2802004922101b210920062006417f6a220a2000200641e0016c6a220b280200220d200b41a07e6a280200220f49220b1b221120064101722212200a2006200b1b2000201241e0016c6a2802002206200f200d200b1b220a49220d1b2006200a200d1b2000201141e0016c6a2802004922111b210620082008417f6a22122000200841e0016c6a220f2802002213200f41a07e6a280200221449220a1b2215200841016a20122008200a1b200f41e0016a280200220820142013200a1b221249220f1b20082012200f1b2000201541e0016c6a2802004922121b210841024101200a1b200a200f1b20126a200b6a200d6a20116a200e6a200c6a20106a210a0b200a2000200641e0016c6a280200220b2000200841e0016c6a280200220c49220e6a2000200941e0016c6a280200220a200c200b200e1b220d49220c6a210b0240024002400240200a200d200c1b200020062008200e1b220a41e0016c6a2802004f0d00200b41016a220b410b4d0d01024020014101762209450d002000200141e0016c6a41a07e6a2108200021060340200441e0036a200641e00110f8021a2006200841e00110f90241e0016a21062008200441e0036a41e00110f80241a07e6a21082009417f6a22090d000b0b2001200a417f736a210a4101452007724101710d030c020b200920082006200e1b200c1b210a0b200b45452007724101710d010b2000200110d9010d080b024002400240024002402002450d00200a20014f0d0a20022802002000200a41e0016c6a2208280200490d01200441e0036a200041e00110f8021a2000200841e00110f902210c2008200441e0036a41e00110f8021a200c280200210e200441046a200c41046a221041dc0110f8021a200c41a07e6a210d200c41e0016a210f41002106410020012209417f6a220a4f0d02410621160c030b2001450d080b200a20014f0d06200441e0036a200041e00110f8021a20002000200a41e0016c6a220841e00110f90221152008200441e0036a41e00110f8021a20152802002110200441046a201541046a221741dc0110f8021a201541e0016a210e4100211302402001417f6a2209450d00200e21080340200828020020104f0d01200841e0016a2108201341016a22132009490d000b0b2015200141e0016c6a210820092106024003402008210a2006221420134d0d012014417f6a2106200a41a07e6a220828020020104f0d000b0b20142013490d0520092014490d024180012107410021094100210f410021064100210d4180012111200e201341e0016c6a2218210e0340200a200e6b220841e0016e210b0240024002400240024002400240200841dfc1034b22120d00200b41807f6a200b200f200949200d200649220c7222051b21082005450d0120112008200c1b211120082007200c1b21070b200d2006470d020c010b2008200841017622116b2107200d2006470d010b2011450d0141002108200441e0016a220d2106200e210b0340200620083a00002006200b28020020104f6a2106200b41e0016a210b200841016a22082011490d000b0b200f2009470d020c010b200441e0016a2206210d200f2009470d010b02402007450d00200a41a07e6a21084100210b200441e0026a220f210903402009200b3a0000200920082802002010496a2109200841a07e6a2108200b41016a220b2007490d000c020b0b200441e0026a2209210f0b02402009200f6b22082006200d6b220b200b20084b1b2205450d00200441e0036a200e200d2d000041e0016c6a41e00110f8021a200e200d2d000041e0016c6a200a200f2d0000417f7341e0016c6a41e00110f8021a024020054101460d00410021080340200a200f20086a220b2d0000417f7341e0016c6a200e200d20086a41016a220c2d000041e0016c6a41e00110f8021a200e200c2d000041e0016c6a200a200b41016a2d0000417f7341e0016c6a41e00110f8021a200841026a210b200841016a220c2108200b2005490d000b200f200c6a210f200d200c6a210d0b200a200f2d0000417f7341e0016c6a200441e0036a41e00110f8021a200f41016a210f200d41016a210d0b200e201141e0016c6a200e200d2006461b210e200a410020076b41e0016c6a200a200f2009461b210a20120d000b02400240200d20064f0d00200a21080340200441e0036a200e2006417f6a22062d000041e0016c6a220941e00110f8021a2009200841a07e6a220841e00110f9021a2008200441e0036a41e00110f8021a200d2006490d000c020b0b200e2108200f20094f0d0003402009417f6a22092d00002106200441e0036a200841e00110f8021a2008200a2006417f7341e0016c6a220641e00110f90221082006200441e0036a41e00110f8021a200841e0016a2108200f2009490d000b0b201520103602002017200441046a41dc0110f8021a024002402001200820186b41e0016e20136a22084d0d00200441e0036a201541e00110f8021a20152015200841e0016c6a220641e00110f902210c2006200441e0036a41e00110f8022109200120086b2206450d0120062008200820064b1b210a2001410376210e200941e0016a210b024020082006417f6a22014f0d00200c20082002200310d60120092102200b2100200a200e4f2105201420134d2106200141154f0d070c0c0b200b20012009200310d601200a200e4f2105201420134d21062008220141154f0d060c0b0b4190d4c20020082001104e000b41a0d4c200104f000b410021160b03400240024002400240024002400240024002400240024002400240024002400240024020160e09040507080603000102020b200f200641e0016c6a2108410721160c100b200e2008280200490d0a410821160c0f0b200841e0016a2108200641016a2206200a490d070c080b200441e0036a200f200641e0016c6a220841e00110f8021a2008200b41e0016a220a41e00110f9021a200a200441e0036a41e00110f8021a200641016a22062009417f6a220a490d09410021160c0d0b200d200941e0016c6a2108410121160c0c0b20062009417f6a22094f0d0a410421160c0b0b2008280200210a200841a07e6a220b2108200e200a490d070c080b200c200e3602002010200441046a41dc0110f8021a2001200641016a2208490d01410321160c090b200c200841e0016c6a2100200120086b220141154f0d0a0c100b20082001107a000b410721160c060b410021160c050b410021160c040b410621160c030b410121160c020b410521160c010b410221160c000b0b0b0b201420091076000b20132014107a000b4190d4c200200a2001104e000b4180d4c20041004100104e000b41b8d4c200200a2001104e000b20014102490d00200041a07e6a210b4100210c410121060340200641016a210e02402000200641e0016c6a2209280200220a200941a07e6a22082802004f0d00200441046a200941046a41dc0110f8021a2009200841e00110f802210d02402006417f6a450d00200c2106200b2109200a200d41c07c6a2802004f0d0003402009220841e0016a200841e00110f8021a200641016a2206450d01200a200841a07e6a2209280200490d000b0b2008200a360200200841046a200441046a41dc0110f8021a0b200c417f6a210c200b41e0016a210b200e2106200e2001490d000b0b200441c0056a24000ba70301087f230041e0016b22022400024002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d032001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d0120022000200441e0016c6a220841e00110f802210420082000200541e0016c6a220541e00110f9021a2005200441e00110f8021a200320014f0d022006410d7420067322054111762005732205410574200573220620077122054100200120052001491b6b220520014f0d0120042000200341e0016c6a220941e00110f802210820092000200541e0016c6a220541e00110f9021a2005200841e00110f8021a2003410172220420014f0d032006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d0120082000200441e0016c6a220141e00110f802210320012000200541e0016c6a220041e00110f9021a2000200341e00110f8021a0b200241e0016a24000f0b4190d4c20020052001104e000b200321040b4180d4c20020042001104e000b8d0401087f230041e0016b2202240002400240024002400240024020014101762203450d0003402003417f6a2203210403402004410174220641017221070240200641026a220620014f0d00200720014f0d06200620072000200741e0016c6a2802002000200641e0016c6a280200491b21070b0240200720014f0d00200420014f0d042000200441e0016c6a22042802002000200741e0016c6a22062802004f0d002002200441e00110f80221052004200641e00110f9021a2006200541e00110f8021a200721040c010b0b20030d000b0b024020014102490d002001210603402006417f6a220620014f0d062002200041e00110f802210820002000200641e0016c6a220741e00110f90221052007200841e00110f8021a4100210403402004410174220341017221070240200341026a220320064f0d00200720064f0d07200320072005200741e0016c6a2802002005200341e0016c6a280200491b21070b0240200720064f0d00200420064f0d052005200441e0016c6a22042802002005200741e0016c6a22032802004f0d002008200441e00110f80221092004200341e00110f9021a2003200941e00110f8021a200721040c010b0b200641014b0d000b0b200241e0016a24000f0b41d8d4c20020042001104e000b41d8d4c20020042006104e000b41c8d4c20020072001104e000b41c8d4c20020072006104e000b4190d4c20020062001104e000b9d0501107f230041e0016b2202240020004180796a2103200041a07e6a210441002105200141324921064101210702400240024002400340024002400240200720014f0d002004200741e0016c6a21080340200841e0016a22092802002008280200490d0220092108200741016a22072001490d000b0b41002108200720014622090d030c010b41012108200720014622090d020b20060d012007417f6a220920014f0d032008450d0420022000200941e0016c6a220841e00110f802210a20082000200741e0016c220b6a220941e00110f80221082009200a41e00110f8022109024020074102490d002008280200220c20002007417e6a220d41e0016c6a220e2802004f0d00200a200841046a41dc0110f802210f2008200e41e00110f8021a0240200d450d00200c200941e07a6a2802004f0d00410220076b210d2003200b6a21080340200841c0036a200841e0016a220e41e00110f8021a200d41016a220d450d012008280200210b200841a07e6a2108200c200b490d000b0b200e200c360200200e41046a200f41dc0110f8021a0b200541016a21050240200120076b220d4102490d0020092802e0012009280200220e4f0d00200a200941046a41dc0110f80221102009200941e0016a220b41e00110f80221090240200d4103490d0020092802c003200e4f0d00200941c0036a210c410321084102210f03402009200f41e0016c6a41a07e6a200c220b41e00110f8021a2008200d4f0d01200841016a220c2008490d01200841e0016c21112008210f200c2108200920116a220c280200200e490d000b0b200b200e360200200b41046a201041dc0110f8021a0b20054105490d000c020b0b200241e0016a240020090f0b200a41e0016a240041000f0b4180d4c20020092001104e000b4190d4c20020072001104e000b86090b107f017e017f017e017f017e017f017e017f017e017f230041306b22022400024002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d032001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200241286a22082000200441306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e2903003703002013201029030037030020052002290300370300200320014f0d022006410d7420067322044111762004732204410574200473220620077122044100200120042001491b6b220520014f0d01200241286a22082000200341306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e29030037030020132010290300370300200520022903003703002003410172220420014f0d032006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200241286a22032000200441306c6a220141286a2204290300370300200241206a2206200141206a2207290300370300200241186a2208200141186a2209290300370300200241106a220a200141106a220b290300370300200241086a220c200141086a220d290300370300200220012903003703002000200541306c6a22002903002112200041086a22052903002114200041106a220e2903002116200041186a220f2903002118200041206a2210290300211a2004200041286a22112903003703002007201a37030020092018370300200b2016370300200d2014370300200120123703002011200329030037030020102006290300370300200f2008290300370300200e200a2903003703002005200c290300370300200020022903003703000b200241306a24000f0b4190d4c20020052001104e000b200321040b4180d4c20020042001104e000bb50a090d7f017e037f017e017f017e017f027e027f230041306b2202240002400240024002400240024020014101762203450d0003402003417f6a22032104034020044101742211410172211a0240201141026a221120014f0d00201a20014f0d062011201a2000201141306c6a220e2903002000201a41306c6a221029030054200e41086a290300220f201041086a290300221354200f2013511b1b211a0b0240201a20014f0d00200420014f0d042000201a41306c6a22112903002000200441306c6a220429030054201141086a2210290300220f200441086a220e290300221354200f2013511b450d00200241286a2205200441286a2206290300370300200241206a2207200441206a2208290300370300200241186a2209200441186a220a290300370300200241106a220b200441106a220c290300370300200241086a220d200e290300370300200220042903003703002010290300210f201141106a22122903002113201141186a22142903002115201141206a22162903002117201129030021182006201141286a221929030037030020082017370300200a2015370300200c2013370300200e200f370300200420183703002019200529030037030020162007290300370300201420092903003703002012200b2903003703002010200d29030037030020112002290300370300201a21040c010b0b20030d000b0b024020014102490d002001210e0340200e417f6a220e20014f0d06200241286a2206200041286a2211290300370300200241206a2207200041206a221a290300370300200241186a2208200041186a2210290300370300200241106a2209200041106a2205290300370300200241086a220a200041086a220b290300370300200220002903003703002000200e41306c6a2204290300210f200441086a220c2903002113200441106a220d2903002115200441186a22122903002117200441206a221429030021182011200441286a2216290300370300201a20183703002010201737030020052015370300200b20133703002000200f370300201620062903003703002014200729030037030020122008290300370300200d2009290300370300200c200a2903003703002004200229030037030041002104034020044101742211410172211a0240201141026a2211200e4f0d00201a200e4f0d072011201a2000201141306c6a22102903002000201a41306c6a220529030054201041086a290300220f200541086a290300221354200f2013511b1b211a0b0240201a200e4f0d002004200e4f0d052000201a41306c6a22112903002000200441306c6a220429030054201141086a2205290300220f200441086a2210290300221354200f2013511b450d002006200441286a220b2903003703002007200441206a220c2903003703002008200441186a220d2903003703002009200441106a2212290300370300200a2010290300370300200220042903003703002005290300210f201141106a22142903002113201141186a22162903002115201141206a2219290300211720112903002118200b201141286a2203290300370300200c2017370300200d2015370300201220133703002010200f37030020042018370300200320062903003703002019200729030037030020162008290300370300201420092903003703002005200a29030037030020112002290300370300201a21040c010b0b200e41014b0d000b0b200241306a24000f0b41d8d4c20020042001104e000b41d8d4c2002004200e104e000b41c8d4c200201a2001104e000b41c8d4c200201a200e104e000b4190d4c200200e2001104e000bf50b05087f027e107f017e017f230041306b22022400200041c07e6a2103200041506a21044100210520014132492106410121070240024002400340024002400240200720014f0d002004200741306c6a210803402008290300200841306a220929030054200841086a290300220a200841386a290300220b54200a200b511b0d0220092108200741016a22072001490d000b0b41002108200720014622090d030c010b41012108200720014622090d020b20060d012007417f6a220920014f0d022008450d032000200941306c6a2208290300210a20082000200741306c220c6a2209290300370300200241286a220d200841286a220e290300370300200241206a220f200841206a2210290300370300200241186a2211200841186a2212290300370300200241106a2213200841106a2214290300370300200241086a2215200841086a22162903003703002016200941086a22172903003703002014200941106a22182903003703002012200941186a22192903003703002010200941206a221a290300370300200e200941286a221b2903003703002002200a370300201b200d290300370300201a200f29030037030020192011290300370300201820132903003703002017201529030037030020092002290300370300024020074102490d0020002007417e6a220f41306c6a220d2903002008290300221c5a200d41086a221d290300220b2016290300220a5a200b200a511b0d002008200d2903003703002016201d2903003703002008290310210b2014200d41106a2903003703002011200e29030037030020132010290300370300201520122903003703002012200d41186a2903003703002010200d41206a290300370300200e200d41286a2903003703002002200b3703000240024002400240200f450d0020002007417d6a221641306c6a2208290300201c5a200841086a290300220b200a5a200b200a511b0d032003200c6a2108034020084188016a200841d8006a29030037030020084180016a200841d0006a290300370300200841f8006a200841c8006a290300370300200841f0006a200841c0006a290300370300200841e8006a200841386a290300370300200841e0006a200841306a2903003703002016450d022008290300210b200841086a210d200841506a21082016417f6a2116200b201c54200d290300220b200a54200b200a511b0d000b201641016a210f0c020b4100210f0c020b4100210f0b2000200f41306c6a210d0b200d201c370300200d200a3703082000200f41306c6a22082002290300370310200841286a2011290300370300200841206a2013290300370300200841186a20152903003703000b200541016a21050240200120076b220e4102490d002009290300220b20092903305a2017290300220a200941386a290300221c5a200a201c511b0d002009200941306a22082903003703002017200841086a2903003703002009290310211c2018200841106a2903003703002011201b2903003703002013201a290300370300201520192903003703002019200841186a290300370300201a200841206a290300370300201b200841286a2903003703002002201c370300410121120240200e4103490d00200b20092903605a200a200941e8006a290300221c5a200a201c511b0d00200941e0006a21164103210d41022117034020092017221241306c6a220841786a201641286a290300370300200841706a201641206a290300370300200841686a201641186a290300370300200841606a201641106a290300370300200841586a201641086a290300370300200841506a2016290300370300200d200e4f0d01200d41016a2216200d490d01200d41306c2110200d21172016210d200b200920106a221629030054200a201641086a290300221c54200a201c511b0d000b0b2008200b3703002008200a3703082009201241306c6a22082002290300370310200841286a2011290300370300200841206a2013290300370300200841186a20152903003703000b20054105490d000b410021090b200241306a240020090f0b4180d4c20020092001104e000b4190d4c20020072001104e000b130020004101360204200041e8d4c2003602000b9e0101057f20002802042102024003402000280200220441086a210520042f01064105742100417f210302400240024003402000450d01200341016a210320012005412010fa022206450d05200041606a2100200541206a21052006417f4a0d000b20020d010c020b20042f010621032002450d010b2002417f6a2102200420034102746a41f8066a21000c010b0b41000f0b2004200341306c6a41e8026a0b980301077f230041f0066b220324000240024002402001280200220441e8bdc000460d00200128020421050c010b41f80610002204450d0141002105200441003b010620044100360200200441086a200341f00610f8021a20014100360204200120043602000b024002400340200441086a210720042f010641057421084100210602400240024003402008450d0120022007412010fa022209450d05200841606a2108200641016a2106200741206a21072009417f4a0d000b2006417f6a210620050d010c020b20042f010621062005450d010b2005417f6a2105200420064102746a41f8066a28020021040c010b0b41012107410021050c010b410021070b20002005360204200041146a200141086a360200200041106a20063602002000410c6a2001360200200041086a20043602004101210802402007450d00200041186a2002290000370000200041306a200241186a290000370000200041286a200241106a290000370000200041206a200241086a290000370000410021080b20002008360200200341f0066a24000f0b41f80641081019000be91905087f017e017f017e087f230041c0036b2204240020022802082105200228020421062002280200210702400240024002402001280200220241e8bdc000460d00200128020421080c010b41900210002202450d0141002108200241003b010620024100360200200241086a20044188016a41880210f8021a20014100360204200120023602000b20044188016a41086a21092001210a03402009200a3602002004200236028c012004200836028801200441106a20044188016a10a101200428021022022004280214410c6c6a2108428080808070210c417f210b0240034002400240024020022008460d002002450d00024020072002280200200241086a280200220a20052005200a4b1b10fa02220d450d00200c4280808080107c210c417f4101200d4100481b220a450d020c030b200c4280808080107c210c4100417f41012005200a491b2005200a461b220a0d020c010b200441086a20044188016a10a101200428020c210b0c030b200141086a2102200c20044188016a41086a35020084210c200428028c01210a200428028801210502402006450d00200710010b200420023602980120042005360288012004200a36028c012004200c37039001200441f8006a41086a2202200341086a28020036020020042003290200370378200441186a41086a2205200a200c422088a7410c6c6a220a4194016a220b2802003602002004200a418c016a220a290200370318200b2002280200360200200a200429037837020020022005280200360200200420042903183703782005200228020036020020042004290378370318200041013602002000410c6a200528020036020020002004290318370204200441c0036a24000f0b2002410c6a2102200b41016a210b200a4101460d000b0b2009280200210a200428028c01210202402004280288012208450d002008417f6a21082002200b4102746a4190026a28020021020c010b0b200441286a20023602002001200128020841016a3602082004412c6a200bad422086200aad84220e3702002004200636021c2004200736021820042005ad370320200441e8006a41086a220b200341086a28020036020020042003290200370368024020022f01062201410b4f0d00200241086a220a200e422088a72208410c6c220d410c6a22096a200a200d6a220a200120086b410c6c10f9021a200a2005360208200a2006360204200a20073602002002418c016a220520096a2005200d6a2205200241066a22022f010020086b410c6c10f9021a200541086a200b28020036020020052004290368370200200220022f010041016a3b01000c020b0240024041900210002209450d00200941003b010620094100360200200941086a20044188016a41880210f802210b20044188016a41086a2201200241dc016a280200360200200420022902d40137038801200241d4006a290200210c200241d0006a280200210f200b200241dc006a200241066a220a2f010041796a2208410c6c220d10f80221032009418c016a200241e0016a200d10f802210d200a41063b0100200920083b0106200441f8006a41086a2001280200360200200420042903880137037802400240200e422088a7220b41064b0d002001200441e8006a41086a2802003602002004200429036837038801200241086a2208200b410c6c220d410c6a22036a2008200d6a2208200a2f0100200b6b410c6c10f9021a2008200536020820082006360204200820073602002002418c016a220520036a2005200d6a2205200a2f0100200b6b410c6c10f9021a200541086a20012802003602002005200429038801370200200a200a2f010041016a3b01000c010b2003200b410c6c220a41b87f6a22016a2003200a41ac7f6a22106a220a200841ffff0371200b41796a220b6b410c6c10f9021a200a2005360208200a2006360204200a2007360200200d20016a200d20106a2205200941066a220a2f0100200b6b410c6c10f9021a200541086a200441e8006a41086a28020036020020052004290368370200200a200a2f010041016a3b01000b200441d8006a41086a2205200441f8006a41086a28020036020020042004290378370358200441386a41086a200528020036020020042004290358370338200ea7211102400240024002400240024020022802002208450d00200420022f0104220d3602940120042011360290012004200836028c0141012105200441013602880141000d010c020b20042011360290012004200236028c012004410036028801201121054101450d010b20044188016a210a41c002210b41c002100022020d010c050b0340200441d8006a41086a2210200441386a41086a22132802003602002004200429033837035820082f01062202410a4d0d0241c0021000220b450d03200b41003b0106200b4100360200200b41086a20044188016a41b80210f80221022008290254210e2008280250211220044188016a41086a2203200841dc016a280200360200200420082902d401370388012002200841dc006a200841066a22072f0100220541796a220a410c6c220110f8022114200b418c016a200841e0016a200110f8022115200b4190026a200841ac026a2005417a6a220141027410f8022106200741063b0100200b200a3b010602402001450d00410021022006210503402005280200220a20023b0104200a200b360200200541046a2105200241016a22022001490d000b0b200441f8006a41086a220220032802003602002004200429038801370378200441e8006a41086a221620022802003602002004200429037837036802400240200d41064b0d00200320102802003602002004200429035837038801200841086a2205200d410c6c2202410c6a220a6a200520026a220520072f0100200d6b410c6c10f9021a2005200c3702042005200f3602002008418c016a2205200a6a200520026a220220072f0100200d6b410c6c10f9021a200241086a20032802003602002002200429038801370200200720072f010041016a22053b010020084190026a220a200d41027422016a41086a200a200d41016a22024102746a220a200541ffff037120026b41027410f9021a200a2009360200200220072f0100220d4b0d01200820016a4194026a21050340200241016a220a2002490d022005280200220120023b010420012008360200200541046a2105200a2102200a200d4d0d000c020b0b2014200d410c6c220241b87f6a220a6a2014200241ac7f6a22016a2202200b41066a22052f0100200d41796a22076b410c6c10f9021a2002200c3702042002200f3602002015200a6a201520016a220220052f010020076b410c6c10f9021a200241086a201028020036020020022004290358370200200520052f010041016a220a3b01002006200d41027422076a416c6a2006200d417a6a22024102746a2201200a41ffff037120026b41027410f9021a20012009360200200220052f0100220d4b0d00200b20076a41f8016a21050340200241016a220a2002490d012005280200220120023b01042001200b360200200541046a2105200a2102200a200d4d0d000b0b200441c8006a41086a22022016280200360200200420042903683703482013200228020036020020042004290348370338024020082802002202450d0020082f0104210d20022108200e210c2012210f200b21090c010b0b20044188016a210a200e210c2012210f20112105200b210941c002210b41c00210002202450d040b200241003b010620024100360200200241086a200a41b80210f802210a2002200528020036029002200520023602002005200528020441016a360204200228029002220541003b010420052002360200200a20022f01062205410c6c220b6a220a200c3702042002200b6a220b4194016a200441386a41086a2802002201360200200b418c016a2004290338220c370200200a200f36020020024190026a200541016a22054102746a2009360200200220022f010641016a3b010620044188016a41086a2001360200200920053b0104200920023602002004200c370388010c050b20044188016a41086a220b200441d8006a41086a2802003602002004200429035837038801200841086a220a200d410c6c2205410c6a22016a200a20056a220a2002200d6b410c6c10f9021a200a200c370204200a200f3602002008418c016a220220016a200220056a2202200841066a22052f0100200d6b410c6c10f9021a200241086a200b2802003602002002200429038801370200200520052f010041016a3b010020084190026a220a200d410274220b6a41086a200a200d41016a22024102746a220a20052f010020026b41027410f9021a200a2009360200200220052f010022014b0d042008200b6a4194026a21050340200241016a220a2002490d052005280200220b20023b0104200b2008360200200541046a2105200a2102200a20014d0d000c050b0b41c00241041019000b41900241041019000b200b41041019000b41900241041019000b20004100360200200441c0036a24000bc31d05087f017e017f017e0c7f230041c0046b2204240020022802082105200228020421062002280200210702400240024002402001280200220241e8bdc000460d00200128020421080c010b41e80210002202450d0141002108200241003b010620024100360200200241086a200441b0016a41e00210f8021a20014100360204200120023602000b200441b0016a41086a21092001210a03402009200a360200200420023602b401200420083602b001200441106a200441b0016a10a101200428021022022004280214410c6c6a2108428080808070210c417f210b0240034002400240024020022008460d002002450d00024020072002280200200241086a280200220a20052005200a4b1b10fa02220d450d00200c4280808080107c210c417f4101200d4100481b220a450d020c030b200c4280808080107c210c4100417f41012005200a491b2005200a461b220a0d020c010b200441086a200441b0016a10a101200428020c210b0c030b200141086a2102200c200441b0016a41086a220a35020084210c20042802b401210b20042802b001210502402006450d00200710010b200420023602a80120042005360298012004200b36029c012004200c3703a001200441186a41106a2202200341106a280200360200200441186a41086a2205200341086a29020037030020042003290200370318200441b0016a41106a2201200b200c422088a741146c6a220b419c016a2208280200360200200a200b4194016a220d2902003703002004200b418c016a220b2902003703b00120082002280200360200200d2005290300370200200b2004290318370200200220012802003602002005200a290300370300200420042903b001370318200041106a2002280200360200200041086a200529030037020020002004290318370200200441c0046a24000f0b2002410c6a2102200b41016a210b200a4101460d000b0b2009280200210a20042802b4012102024020042802b0012208450d002008417f6a21082002200b4102746a41e8026a28020021020c010b0b200441186a41106a20023602002001200128020841016a360208200441186a41146a200bad422086200aad84220e3702002004200636021c2004200736021820042005ad37032020044180016a41106a2201200341106a28020036020020044180016a41086a2208200341086a2902003703002004200329020037038001024020022f0106220d410b4f0d002002200e422088a7220a410c6c6a220b41146a200b41086a2209200d200a6b410c6c10f9021a200b41106a2005360200200b410c6a2006360200200920073602002002200a41146c6a220541a0016a2005418c016a220b200241066a22022f0100200a6b41146c10f9021a2005419c016a200128020036020020054194016a2008290300370200200b200429038001370200200220022f010041016a3b01000c020b0240024041e80210002209450d00200941003b010620094100360200200941086a200441b0016a41e00210f802210a200441b0016a41106a220820024194026a280200360200200441b0016a41086a220d2002418c026a29020037030020042002290284023703b001200241d4006a290200210c200241d0006a280200210f200a200241dc006a200241066a220b2f010041796a2201410c6c10f80221032009418c016a20024198026a200141146c10f8022110200b41063b0100200920013b010620044198016a41106a200828020036020020044198016a41086a200d290300370300200420042903b0013703980102400240200e422088a7220a41064b0d00200820044180016a41106a280200360200200d20044180016a41086a29030037030020042004290380013703b001200241086a200a410c6c6a2201410c6a2001200b2f0100200a6b410c6c10f9021a2001200536020820012006360204200120073602002002418c016a200a41146c6a220541146a2005200b2f0100200a6b41146c10f9021a200541106a2008280200360200200541086a200d290300370200200520042903b001370200200b200b2f010041016a3b01000c010b2003200a410c6c6a220b41b87f6a200b41ac7f6a2208200141ffff0371200a41796a22016b410c6c10f9021a200b41b47f6a2005360200200b41b07f6a2006360200200820073602002010200a41146c6a220541887f6a200541f47e6a220b200941066a220a2f010020016b41146c10f9021a200541847f6a20044180016a41106a280200360200200541fc7e6a20044180016a41086a290300370200200b200429038001370200200a200a2f010041016a3b01000b200441e8006a41106a220520044198016a41106a280200360200200441e8006a41086a220a20044198016a41086a2903003703002004200429039801370368200441386a41106a2005280200360200200441386a41086a200a29030037030020042004290368370338200ea7211102400240024002400240024020022802002208450d00200420022f0104220d3602bc01200420113602b801200420083602b40141012105200441013602b00141000d010c020b200420113602b801200420023602b401200441003602b001201121054101450d010b200441b0016a210a419803210b419803100022020d010c050b0340200441e8006a41106a2213200441386a41106a2214280200360200200441e8006a41086a2215200441386a41086a22162903003703002004200429033837036820082f01062202410a4d0d024198031000220b450d03200b41003b0106200b4100360200200b41086a200441b0016a41900310f80221052008290254210e20082802502112200441b0016a41106a220320084194026a280200360200200441b0016a41086a22062008418c026a29020037030020042008290284023703b0012005200841dc006a200841066a22072f0100220a41796a2202410c6c10f8022117200b418c016a20084198026a200241146c10f8022118200b41e8026a20084184036a200a417a6a220141027410f8022110200741063b0100200b20023b010602402001450d00410021022010210503402005280200220a20023b0104200a200b360200200541046a2105200241016a22022001490d000b0b20044198016a41106a2202200328020036020020044198016a41086a22052006290300370300200420042903b0013703980120044180016a41106a2219200228020036020020044180016a41086a221a200529030037030020042004290398013703800102400240200d41064b0d002003201328020036020020062015290300370300200420042903683703b001200841086a200d410c6c6a2202410c6a200220072f0100200d6b410c6c10f9021a2002200c3702042002200f3602002008418c016a200d41146c6a220241146a200220072f0100200d6b41146c10f9021a200241106a2003280200360200200241086a2006290300370200200220042903b001370200200720072f010041016a22053b0100200841e8026a220a200d41027422016a41086a200a200d41016a22024102746a220a200541ffff037120026b41027410f9021a200a2009360200200220072f0100220d4b0d01200820016a41ec026a21050340200241016a220a2002490d022005280200220120023b010420012008360200200541046a2105200a2102200a200d4d0d000c020b0b2017200d410c6c6a220241b87f6a200241ac7f6a220a200b41066a22052f0100200d41796a22016b410c6c10f9021a200241b07f6a200c370200200a200f3602002018200d41146c6a220241887f6a200241f47e6a220a20052f010020016b41146c10f9021a200241847f6a2013280200360200200241fc7e6a2015290300370200200a2004290368370200200520052f010041016a220a3b01002010200d41027422076a416c6a2010200d417a6a22024102746a2201200a41ffff037120026b41027410f9021a20012009360200200220052f0100220d4b0d00200b20076a41d0026a21050340200241016a220a2002490d012005280200220120023b01042001200b360200200541046a2105200a2102200a200d4d0d000b0b200441d0006a41106a22022019280200360200200441d0006a41086a2205201a2903003703002004200429038001370350201420022802003602002016200529030037030020042004290350370338024020082802002202450d0020082f0104210d20022108200e210c2012210f200b21090c010b0b200441b0016a210a200e210c2012210f20112105200b2109419803210b41980310002202450d040b200241003b010620024100360200200241086a200a41900310f802210a200220052802003602e802200520023602002005200528020441016a36020420022802e802220541003b010420052002360200200a20022f01062205410c6c6a220b200c3702042002200541146c6a220a419c016a200441386a41106a2802002201360200200a4194016a200441386a41086a290300220c370200200a418c016a2004290338220e370200200b200f360200200241e8026a200541016a22054102746a2009360200200220022f010641016a3b0106200441b0016a41106a2001360200200441b0016a41086a200c370300200920053b0104200920023602002004200e3703b0010c050b200441b0016a41106a220a200441e8006a41106a280200360200200441b0016a41086a220b200441e8006a41086a290300370300200420042903683703b0012008200d410c6c6a220541146a200541086a22012002200d6b410c6c10f9021a2005410c6a200c3702002001200f3602002008200d41146c6a220241a0016a2002418c016a2201200841066a22052f0100200d6b41146c10f9021a2002419c016a200a28020036020020024194016a200b290300370200200120042903b001370200200520052f010041016a3b0100200841e8026a220a200d410274220b6a41086a200a200d41016a22024102746a220a20052f010020026b41027410f9021a200a2009360200200220052f010022014b0d042008200b6a41ec026a21050340200241016a220a2002490d052005280200220b20023b0104200b2008360200200541046a2105200a2102200a20014d0d000c050b0b41980341041019000b41e80241041019000b200b41041019000b41e80241041019000b200041053a0011200441c0046a24000bbd2a012f7f230041a00a6b2202240020002802102203200328020041016a360200200028020c210420002802082105200028020021062000280204210320024192016a2207200041166a2d00003a0000200220002f00143b0190012002200041276a29000037031820022000412c6a29000037001d200041176a28000021082000411b6a28000021092000411f6a280000210a200041236a280000210b200241c0096a41286a220c200141286a290300370300200241c0096a41206a220d200141206a290300370300200241c0096a41186a220e200141186a290300370300200241c0096a41106a220f200141106a290300370300200241c0096a41086a2210200141086a290300370300200220012903003703c009024020032f01062201410b4f0d00200320044105746a220041286a200041086a2206200120046b41057410f9021a200041206a200229001d370000200041176a200b360000200041136a200a3600002000410f6a20093600002000410b6a20083600002000410a6a20072d00003a0000200620022f0190013b00002000411b6a20022903183700002003200441306c6a22004198036a200041e8026a2201200341066a22032f010020046b41306c10f9021a20004190036a200c29030037030020004188036a200d29030037030020004180036a200e290300370300200041f8026a200f290300370300200041f0026a2010290300370300200120022903c009370300200320032f010041016a3b0100200241a00a6a240020010f0b0240024002400240024041f80610002207450d00200741003b010620074100360200200741086a200241a0026a41f00610f8022100200241a0026a41086a220d20034190056a290300370300200241a0026a41106a220e20034198056a290300370300200241a0026a41186a220f200341a0056a290300370300200241a0026a41206a2210200341a8056a290300370300200241a0026a41286a2211200341b0056a2903003703002002200341ca016a2d00003a0086022002200341c8016a2f00003b0184022002200341db016a2900003703f0012002200341e0016a2900003700f501200220034188056a2903003703a002200341cb016a2800002112200341cf016a2800002113200341d3016a2800002114200341d7016a28000021152000200341e8016a200341066a22012f010041796a220c41057410f8022100200741e8026a200341b8056a200c41306c10f8022116200141063b01002007200c3b0106200241ec016a41026a20022d0086023a0000200220022f0184023b01ec01200220022903f0013703d801200220022900f5013700dd01200241f0096a41286a2011290300370300200241f0096a41206a2010290300370300200241f0096a41186a200f290300370300200241f0096a41106a200e290300370300200241f0096a41086a200d290300370300200220022903a0023703f00902400240200441064b0d00200341086a20044105746a220041206a200020012f010020046b41057410f9021a200041186a200229001d3700002000200b36000f2000200a36000b2000200936000720002008360003200041026a20024190016a41026a2d00003a0000200020022f0190013b000020002002290318370013200341e8026a200441306c6a221741306a201720012f010020046b41306c10f9021a201741286a200241c0096a41286a290300370300201741206a200241c0096a41206a290300370300201741186a200241c0096a41186a290300370300201741106a200241c0096a41106a290300370300201741086a200241c0096a41086a290300370300201720022903c009370300200120012f010041016a3b01000c010b200020044105746a41c07e6a2000200441796a22014105746a2200200c41ffff037120016b41057410f9021a200041186a200229001d3700002000200b36000f2000200a36000b2000200936000720002008360003200041026a20024190016a41026a2d00003a0000200020022f0190013b0000200020022903183700132016200441306c6a220041e07d6a200041b07d6a2217200741066a22042f010020016b41306c10f9021a200041d87d6a200241c0096a41286a290300370300200041d07d6a200241c0096a41206a290300370300200041c87d6a200241c0096a41186a290300370300200041c07d6a200241c0096a41106a290300370300200041b87d6a200241c0096a41086a290300370300201720022903c009370300200420042f010041016a3b01000b200241f8006a41026a2200200241ec016a41026a2d00003a0000200241a8016a41086a2201200241f0096a41086a290300370300200241a8016a41106a2204200241f0096a41106a290300370300200241a8016a41186a2208200241f0096a41186a290300370300200241a8016a41206a2209200241f0096a41206a290300370300200241a8016a41286a220a200241f0096a41286a290300370300200220022f01ec013b0178200220022903d801370348200220022900dd0137004d200220022903f0093703a801200241146a41026a20002d00003a0000200241186a41086a2001290300370300200241186a41106a2004290300370300200241186a41186a2008290300370300200241186a41206a2009290300370300200241186a41286a200a290300370300200220022f01783b0114200220022903483703002002200229004d370005200220022903a8013703180240024020032802002208450d00200220032f0104220a3602ac02200220053602a802200220083602a4022002200641016a22163602a0024100450d010c030b200220053602a802200220033602a402200220063602a0022005211641010d020b024002400340200241a4016a41026a2218200241146a41026a22192d00003a0000200220022f01143b01a40120022002290300370390012002200229000537009501200241a8016a41286a221a200241186a41286a221b290300370300200241a8016a41206a221c200241186a41206a221d290300370300200241a8016a41186a221e200241186a41186a221f290300370300200241a8016a41106a2220200241186a41106a2221290300370300200241a8016a41086a2222200241186a41086a2223290300370300200220022903183703a80120082f01062203410a4d0d0141a80710002204450d02200441003b010620044100360200200441086a200241a0026a41a00710f80221032002419c026a41026a220c200841ca016a2d00003a0000200220082f00c8013b019c022002200841db016a290000370388022002200841e0016a29000037008d02200841cb016a2800002124200841cf016a2800002125200841d3016a2800002126200841d7016a2800002127200241a0026a41286a2206200841b0056a290300370300200241a0026a41206a220d200841a8056a290300370300200241a0026a41186a220e200841a0056a290300370300200241a0026a41106a220f20084198056a290300370300200241a0026a41086a221020084190056a29030037030020022008290388053703a0022003200841e8016a200841066a220b2f0100220141796a220041057410f8022128200441e8026a200841b8056a200041306c10f8022129200441f8066a20084194076a2001417a6a220941027410f8022111200b41063b0100200420003b010602402009450d00410021002011210303402003280200220120003b010420012004360200200341046a2103200041016a22002009490d000b0b200241f0096a41286a22002006290300370300200241f0096a41206a2203200d290300370300200241f0096a41186a2201200e290300370300200241f0096a41106a2209200f290300370300200241f0096a41086a222a2010290300370300200220022903a0023703f009200220022f019c023b01840220022002290388023703f0012002200229008d023700f5012002200c2d00003a008602200241ec016a41026a222b20022d0086023a0000200220022f0184023b01ec01200220022903f0013703d801200220022900f5013700dd01200241c0096a41286a222c2000290300370300200241c0096a41206a222d2003290300370300200241c0096a41186a222e2001290300370300200241c0096a41106a222f2009290300370300200241c0096a41086a2230202a290300370300200220022903f0093703c00902400240200a41064b0d00200c20182d00003a0000200220022f01a4013b019c02200220022903900137038802200220022900950137008d022006201a290300370300200d201c290300370300200e201e290300370300200f202029030037030020102022290300370300200220022903a8013703a002200841086a2203200a41016a22004105746a2003200a4105746a2203200b2f0100200a6b41057410f9021a2003201536000f2003201436000b2003201336000720032012360003200341026a200c2d00003a0000200320022f019c023b0000200341186a200229008d023700002003200229038802370013200841e8026a200a41306c6a220341306a2003200b2f0100200a6b41306c10f9021a200341286a2006290300370300200341206a200d290300370300200341186a200e290300370300200341106a200f290300370300200341086a2010290300370300200320022903a002370300200b200b2f010041016a22033b0100200841f8066a2201200a41027422096a41086a200120004102746a2201200341ffff037120006b41027410f9021a200120073602002000200b2f0100220b4b0d01200820096a41fc066a21030340200041016a22012000490d022003280200220920003b010420092008360200200341046a2103200121002001200b4d0d000c020b0b2028200a417a6a22004105746a2028200a41796a22094105746a2203200441066a22012f010020096b41057410f9021a200341186a2002290095013700002003201536000f2003201436000b2003201336000720032012360003200341026a20182d00003a0000200320022f01a4013b000020032002290390013700132029200a41306c6a220341e07d6a200341b07d6a220b20012f010020096b41306c10f9021a200341d87d6a201a290300370300200341d07d6a201c290300370300200341c87d6a201e290300370300200341c07d6a2020290300370300200341b87d6a2022290300370300200b20022903a801370300200120012f010041016a22033b01002011200a410274220c6a416c6a201120004102746a2209200341ffff037120006b41027410f9021a20092007360200200020012f0100220b4b0d002004200c6a41e0066a21030340200041016a22012000490d012003280200220920003b010420092004360200200341046a2103200121002001200b4d0d000b0b2002418c016a41026a2200202b2d00003a0000200241c8006a41086a22032030290300370300200241c8006a41106a2201202f290300370300200241c8006a41186a2209202e290300370300200241c8006a41206a220b202d290300370300200241c8006a41286a2207202c290300370300200220022f01ec013b018c01200220022903d801370378200220022900dd0137007d200220022903c009370348201b2007290300370300201d200b290300370300201f20092903003703002021200129030037030020232003290300370300201920002d00003a000020022002290348370318200220022903783703002002200229007d370005200220022f018c013b01140240024020082802002203450d00201641016a211620082f0104210a41002100200321080c010b41012100200521160b20262114202521132024211220272115200421072000450d000b200241a0026a2103202621142025211320242112202721152004210741a807210141a807100022000d040c060b2002419c026a41026a2204200241a4016a41026a2d00003a0000200220022f01a4013b019c02200220022903900137038802200220022900950137008d02200241a0026a41286a2209200241a8016a41286a290300370300200241a0026a41206a220b200241a8016a41206a290300370300200241a0026a41186a220c200241a8016a41186a290300370300200241a0026a41106a2206200241a8016a41106a290300370300200241a0026a41086a220d200241a8016a41086a290300370300200220022903a8013703a002200841086a2201200a41016a22004105746a2001200a4105746a22012003200a6b41057410f9021a2001201536000f2001201436000b2001201336000720012012360003200141026a20042d00003a0000200120022f019c023b0000200141186a200229008d0237000020012002290388023700132008200a41306c6a22034198036a200341e8026a2204200841066a22012f0100200a6b41306c10f9021a20034190036a200929030037030020034188036a200b29030037030020034180036a200c290300370300200341f8026a2006290300370300200341f0026a200d290300370300200420022903a002370300200120012f010041016a3b0100200841f8066a2203200a41027422046a41086a200320004102746a220320012f010020006b41027410f9021a20032007360200200020012f010022094b0d04200820046a41fc066a21030340200041016a22012000490d052003280200220420003b010420042008360200200341046a210320012100200120094d0d000c050b0b41a80741081019000b41f80641081019000b200241a0026a210341a807210141a80710002200450d020b200041003b010620004100360200200041086a200341a00710f8022103200020162802003602f806201620003602002016201628020441016a36020420002802f806220141003b010420012000360200200220022900053700f509200220022903003703f009200241a0026a41286a2204200241186a41286a290300370300200241a0026a41206a2208200241186a41206a290300370300200241a0026a41186a2209200241186a41186a290300370300200241a0026a41106a220a200241186a41106a290300370300200241a0026a41086a220b200241186a41086a290300370300200320002f010622014105746a220320022f01143b0000200341026a200241146a41026a2d00003a0000200220022903183703a0022003201536000f2003201436000b2003201336000720032012360003200341186a20022900f509370000200320022903f0093700132000200141306c6a22034190036a200429030037030020034188036a200829030037030020034180036a2009290300370300200341f8026a200a290300370300200341f0026a200b290300370300200341e8026a20022903a002370300200041f8066a200141016a22034102746a2007360200200020002f010641016a3b0106200720033b0104200720003602000b200241a00a6a240020170f0b200141081019000be40801097f230041106b22022400200241003602082002420137030041c59ec10041042002108e0141c99ec100410e2002108e010240024002400240024002400240024002400240024020022802042203200228020822046b41044f0d00200441046a22052004490d0420034101742206200520052006491b22074100480d042003450d0120022802002108200710002206450d072006200820072003200320074b1b10f8021a200810010c020b200441046a2105200228020021060c020b200710002206450d050b20022007360204200220063602000b200241086a22032005360200200620046a4101360000024002400240024020022802042207200328020022056b41034b0d00200541046a22042005490d0420074101742208200420042008491b22084100480d042008100021042007450d012004450d082004200620082007200720084b1b10f8021a200610010c020b200621040c020b2004450d060b20022008360204200220043602000b2003200541046a360200200420056a4101360000024002400240024020022802042205200328020022036b41034b0d00200341046a22062003490d0420054101742207200620062007491b22064100480d042006100021072005450d012007450d092007200420062005200520064b1b10f8021a200410010c020b200421070c020b2007450d070b20022006360204200220073602000b200241086a2205200341046a360200200720036a410036000002400240024002402002280204220420052802002206470d00200641016a22042006490d0420064101742203200420042003491b22044100480d042004100021052006450d012005450d0a2005200720042006200620044b1b10f8021a200710010c020b200228020021050c020b2005450d080b20022004360204200220053602000b200241086a2208200641016a2203360200200520066a41183a000041d89ec100210603400240024002400240200420036b41084f0d00200341086a22092003490d0520044101742207200920092007491b220a4100480d05200a100021072004450d012007450d0620072005200a20042004200a4b1b10f8021a200510010c020b200341086a2109200521070c020b2007450d040b2002200a360204200220073602000b20082009360200200720036a2006290000370000200641086a2802002109024002400240024020022802042203200828020022076b41044f0d00200741046a22042007490d0520034101742205200420042005491b22044100480d052003450d012002280200210a200410002205450d072005200a20042003200320044b1b10f8021a200a10010c020b20022802002105200321040c020b200410002205450d050b20022004360204200220053602000b2008200741046a2203360200200520076a20093600002006410c6a220641a09fc100470d000b200241106a24002003ad4220862005ad840f0b1018000b200a41011019000b200441011019000b200741011019000b200841011019000b200641011019000b200441011019000b9204010a7f230041206b22022400024002400240410610002203450d002002420637021420022003360210200241106a41bab6c10041061025200241086a2203200228021836020020022002290310370300200241b7b6c100410310252002280204210420022802002205200328020010c401210302402004450d00200510010b200241002003104620024100360218200242013703102002280200210620022802082203200241106a101b0240024002402003450d0020034105742107200241106a41086a280200210820022802102109200228021421052006210a0340200a210302400240024002402005200822046b41204f0d00200441206a22082004490d062005410174220a20082008200a491b220a4100480d06200a1000210b2005450d01200b450d07200b2009200a20052005200a4b1b10f8021a200910010c020b200441206a21080c020b200b450d050b200b2109200a21050b200341206a210a200920046a22042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a290000370000200741606a22070d000b200241186a200836020020022005360214200220093602102002280204450d050c040b200241186a28020021082002280210210920022802040d030c040b1018000b200a41011019000b410641011019000b200610010b200241206a24002008ad4220862009ad840bec1703027f017e0f7f230041d0086b22022400024002402001450d00200220003602200c010b20024188f0c1003602200b20022001360224200241f8066a200241206a10a50102400240024002400240200228028007450d00200241286a200241f8066a41880110f8021a200241b0016a200241286a41880110f8021a20022903b001200241c4016a220120024184026a220310e601024020022903b0012204500d00200241f8066a2004427f7c10e701200241f8066a2001412010fa020d00200241186a20022802a80222012001200241b0026a28020041d8016c6a102e200228021c2205200228021822006b220141d8016e21064100210741042108410021090240200141d801490d002006410c6c220110002208450d06200621090b024020002005460d0041002107200821010340200220003602a004200241f8066a200241a0046a10e801200141086a200241f8066a41086a280200360200200120022903f806370200200741016a21072001410c6a21012005200041d8016a2200470d000b0b200241106a200820082007410c6c6a102e200241a0046a200228021020022802141045200241f8066a20022802a004220120022802a804106b024020022802a404450d00200110010b02402007450d002007410c6c21002008210103400240200141046a280200450d00200128020010010b2001410c6a2101200041746a22000d000b0b02402009450d00200810010b02402003200241f8066a412010fa02450d0041b18dc000410e1006200341201009200241f8066a412010090b20024184026a200241f8066a412010fa020d02200241ac026a2802002109200241b0016a41f8006a2802002103200241b0026a2802002107200241b8026a200241b0016a41f80010f8021a2003200741d8016c6a210020032101024002400240024002402007450d00200241a0046a41f8006a2105200241f8066a41086a2108200321010340200241b0036a200141f00010f8021a200141f0006a290300210420024198066a200141f8006a41e00010f8021a20044203510d02200241a0046a200241b0036a41f00010f8021a200241a0046a41f0006a2004370300200520024198066a41e00010f8021a2002200241a0046a3602f805200241f8066a200241f8056a10e80120082802002107024020022802fc06450d0020022802f80610010b200241f8066a200241a0046a41d80110f8021a200241f8056a200241f8066a200710e90120022802f8054101460d05024020022802fc052207450d002007200241f8056a41086a28020010060b200141d8016a22012000470d000b200021010b20012000470d010c020b200141d8016a22012000460d010b20024180086a2107200241f8066a41f8006a21050340200241f8066a200141f00010f8021a200141f0006a2903002104200241b0036a200141f8006a41e00010f8021a20044203510d01200241a0046a200241f8066a41f00010f8021a20024198066a200241b0036a41e00010f8021a200241f8066a200241a0046a41f00010f8021a200241f8066a41f0006a2004370300200520024198066a41e00010f8021a20071028200141d8016a22012000470d000b0b02402009450d00200310010b10ea0120022903b80210eb01200241f8066a10ec012002200241b8026a41106a280200220a36028c062002200241f8066a41106a28020022013602900620022002418c066a36029406200220024190066a3602f805200a2001470d0420022802c002210b200241086a200228028007220c200c200a41286c6a102e02400240200228020c2002280208220d6b41286e2201200a200a20014b1b220e450d004100210f034002400240200b200f41286c22076a22002d00002201200d20076a22072d0000470d000240024020014101460d0020014102470d01200041086a290300200741086a290300520d02200041186a2802002210200741186a280200470d0241002105200041106a28020022112108200741106a280200221221030340200520104f0d04200541016a22092005490d04024020112012460d0020082003412010fa020d040b200341206a2106200841206a2113200841286a2108200341286a21032009210520132903002006290300510d000c030b0b2000410c6a28020022062007410c6a280200470d0141002105200041046a28020022132108200741046a28020022102103410020064f0d020340200541016a22092005490d03024020132010460d0020082003412010fa020d030b200841206a2108200341206a21032009220520064f0d030c000b0b200b200d460d01200041016a200741016a412010fa02450d010b41939ec10041141006200241a0046a2000102020022802a0042205200241a0046a41086a22012802001009024020022802a404450d00200510010b200241a0046a2007102020022802a004220520012802001009024020022802a404450d00200510010b20002d000020072d00002201470d030b02400240024020014102460d0020014101470d012000410c6a28020022082007410c6a280200470d0541002101200041046a28020022032100200741046a28020022092107410020084f0d020340200141016a22052001490d03024020032009460d0020002007412010fa020d070b200041206a2100200741206a21072005220120084f0d030c000b0b200041086a290300200741086a290300520d04200041186a2802002209200741186a280200470d0441002101200041106a28020022062100200741106a280200221321070340200120094f0d02200141016a22052001490d02024020062013460d0020002007412010fa020d060b200741206a2108200041206a2103200041286a2100200741286a21072005210120032903002008290300510d000c050b0b200b200d460d00200041016a200741016a412010fa020d030b200f41016a220f200e490d000b0b200241a0046a41186a22014200370300200241a0046a41106a22004200370300200241a0046a41086a22074200370300200242003703a004200241a0046a100a200241b0036a41186a2001290300370300200241b0036a41106a2000290300370300200241b0036a41086a2007290300370300200220022903a0043703b0030240200241ec026a2201200241b0036a412010fa02450d0041b18dc000410e1006200141201009200241b0036a412010090b2001200241b0036a412010fa020d060240200a450d00200a41286c2100200c21010340024020012d00002207450d00024020074101470d00200141086a280200450d01200141046a2802001001200141286a2101200041586a22000d020c030b200141146a280200450d00200141106a28020010010b200141286a2101200041586a22000d000b0b024020024184076a280200450d00200c10010b0240200241b8026a41106a2802002200450d00200241b8026a41086a2802002101200041286c21000340024020012d00002207450d00024020074101470d00200141086a280200450d01200141046a2802001001200141286a2101200041586a22000d020c030b200141146a280200450d00200141106a28020010010b200141286a2101200041586a22000d000b0b0240200241c4026a280200450d00200241c0026a28020010010b200241d0086a240042010f0b418084c300104f000b0240024020022802fc052202450d0020024103460d01418883c300104f000b41b883c300104f000b41a083c300104f000b41d882c300104f000b200241b4046a4101360200200241ac046a4101360200200241013602b401200241dcd5c2003602b001200241e0c3c1003602a804200241013602a404200241e4d5c2003602a0042002200241b0016a3602b004200241a0046a41ecd5c2001071000b41f082c300104f000b200241a0046a41146a4100360200200241b0036a41146a4109360200200241b0036a410c6a410d36020020024198066a41146a410336020020024198066a410c6a410336020020024188f0c1003602b004200242013702a404200241d083c3003602a0042002410d3602b403200241b0b3c1003602a0062002410336029c06200241d883c300360298062002200241a0046a3602c0032002200241f8056a3602b803200220024194066a3602b0032002200241b0036a3602a80620024198066a41f083c3001071000b419884c300104f000b200141041019000bdf1801267f230041900d6b220324002003410036021041bef1c1004110200341106a41041003200320003703f00c200341106a41086a220442003703002003420037031041f0f1c100410d200341106a1002200341086a220520042903003703002003200329031037030020034110200341f00c6a41081003200442003703002003420037031041fdf1c1004111200341106a1002200520042903003703002003200329031037030020034110200141201003024002400240411010002204450d002003421037021420032004360210200341106a41dbf1c100411010252003280210210502400240024020032802142206200328021822046b41084f0d00200441086a22072004490d0420064101742208200720072008491b22084100480d042006450d01200810002209450d052009200520082006200620084b1b10f80221092005100120082106200921050c020b200441086a21070c010b200810002205450d03200821060b200520046a2000427f7c370000200341106a41086a220442003703002003420037031020052007200341106a1002200341086a22072004290300370300200320032903103703002003411020014120100302402006450d00200510010b2004420037030020034200370310418ef2c1004115200341106a1002200720042903003703002003200329031037030020034110200241201003200442003703002003420037031041f0f1c100410d200341106a100220072004290300370300200320032903103703000240200341104188f0c100410041001004417f460d00200342003703100240024020034110200341106a41084100100441016a41084d0d0020032903104200510d02200341106a41086a220442003703002003420037031041f0f1c100410d200341106a1002200341086a20042903003703002003200329031037030002400240200341104188f0c100410041001004417f460d002003420037031020034110200341106a41084100100441016a41084d0d032003290310427f7c21000c010b427f21000b41002109200341106a410041e00c10f7021a4100210a4100210b4100210c4100210d4100210e4100210f410021104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f410021204100212141002122410021234100212441002125410021264100212741002108410021280340200341f00c6a42002000427f7c2000501b220010e701200341106a202822064103704105746a220441186a200341f00c6a41186a290200370000200441106a200341f00c6a41106a290200370000200441086a200341f00c6a41086a290200370000200420032902f00c370000200641016a21284100210541002107024003402006200641036e2201417d6c6a4102470d01200341106a20056a220441df006a2d000022082004411f6a2d000022027120082002722004413f6a2d000071722119200441de006a2d000022082004411e6a2d000022027120082002722004413e6a2d000071722118200441dd006a2d000022082004411d6a2d000022027120082002722004413d6a2d000071722117200441dc006a2d000022082004411c6a2d000022027120082002722004413c6a2d000071722116200441db006a2d000022082004411b6a2d000022027120082002722004413b6a2d000071722115200441da006a2d000022082004411a6a2d000022027120082002722004413a6a2d000071722114200441d9006a2d00002208200441196a2d00002202712008200272200441396a2d000071722113200441d8006a2d00002208200441186a2d00002202712008200272200441386a2d000071722112200441d7006a2d00002208200441176a2d00002202712008200272200441376a2d000071722111200441d6006a2d00002208200441166a2d00002202712008200272200441366a2d000071722110200441d5006a2d00002208200441156a2d00002202712008200272200441356a2d00007172210f200441d4006a2d00002208200441146a2d00002202712008200272200441346a2d00007172210e200441d3006a2d00002208200441136a2d00002202712008200272200441336a2d00007172210d200441d2006a2d00002208200441126a2d00002202712008200272200441326a2d00007172210c200441d1006a2d00002208200441116a2d00002202712008200272200441316a2d00007172210b200441d0006a2d00002208200441106a2d00002202712008200272200441306a2d00007172210a200441cf006a2d000022082004410f6a2d000022027120082002722004412f6a2d000071722109200441ce006a2d000022082004410e6a2d000022027120082002722004412e6a2d00007172211a200441cd006a2d000022082004410d6a2d000022027120082002722004412d6a2d00007172211b200441cc006a2d000022082004410c6a2d000022027120082002722004412c6a2d00007172211c200441cb006a2d000022082004410b6a2d000022027120082002722004412b6a2d00007172211d200441ca006a2d000022082004410a6a2d000022027120082002722004412a6a2d00007172211e200441c9006a2d00002208200441096a2d00002202712008200272200441296a2d00007172211f200441c8006a2d00002208200441086a2d00002202712008200272200441286a2d000071722120200441c7006a2d00002208200441076a2d00002202712008200272200441276a2d000071722121200441c6006a2d00002208200441066a2d00002202712008200272200441266a2d000071722122200441c5006a2d00002208200441056a2d00002202712008200272200441256a2d000071722123200441c4006a2d00002208200441046a2d00002202712008200272200441246a2d000071722124200441c3006a2d00002208200441036a2d00002202712008200272200441236a2d000071722125200441c2006a2d00002208200441026a2d00002202712008200272200441226a2d000071722126200441c1006a2d00002208200441016a2d00002202712008200272200441216a2d000071722127200441c0006a2d0000220820042d00002202712008200272200441206a2d000071722108200541800c460d01200341106a20052001410574200641096e41e0006c6b6a6a220441ff006a20193a0000200441fe006a20183a0000200441fd006a20173a0000200441fc006a20163a0000200441fb006a20153a0000200441fa006a20143a0000200441f9006a20133a0000200441f8006a20123a0000200441f7006a20113a0000200441f6006a20103a0000200441f5006a200f3a0000200441f4006a200e3a0000200441f3006a200d3a0000200441f2006a200c3a0000200441f1006a200b3a0000200441f0006a200a3a0000200441ef006a20093a0000200441ee006a201a3a0000200441ed006a201b3a0000200441ec006a201c3a0000200441eb006a201d3a0000200441ea006a201e3a0000200441e9006a201f3a0000200441e8006a20203a0000200441e7006a20213a0000200441e6006a20223a0000200441e5006a20233a0000200441e4006a20243a0000200441e3006a20253a0000200441e2006a20263a0000200441e1006a20273a0000200441e0006a20083a0000200541e0006a210520012106200741016a22074111490d000b0b202841d100470d000b200320193a008f0d200320183a008e0d200320173a008d0d200320163a008c0d200320153a008b0d200320143a008a0d200320133a00890d200320123a00880d200320113a00870d200320103a00860d2003200f3a00850d2003200e3a00840d2003200d3a00830d2003200c3a00820d2003200b3a00810d2003200a3a00800d200320093a00ff0c2003201a3a00fe0c2003201b3a00fd0c2003201c3a00fc0c2003201d3a00fb0c2003201e3a00fa0c2003201f3a00f90c200320203a00f80c200320213a00f70c200320223a00f60c200320233a00f50c200320243a00f40c200320253a00f30c200320263a00f20c200320273a00f10c200320083a00f00c200341106a41086a220442003703002003420037031041a3f2c1004111200341106a1002200341086a220520042903003703002003200329031037030020034110200341f00c6a41201003200442003703002003420037031041cef1c100410d200341106a10022005200429030037030020032003290310370300200341101008200341900d6a24000f0b41eac4c10041331042000b41eac4c10041331042000b4180a0c300104f000b411041011019000b1018000b200841011019000bf30402097f037e230041d0006b2202240002400240024002400240411010002203450d002002421037023420022003360230200241306a41dbf1c1004110102520022802302103024002400240024020022802342204200228023822056b41084f0d00200541086a22062005490d0520044101742207200620062007491b22074100480d052004450d01200710002208450d062008200320072004200420074b1b10f802210420031001200421030c020b200541086a21060c020b200710002203450d040b200721040b200320056a2001370000200241306a41086a220542003703002002420037033020032006200241306a1002200241206a41086a20052903003703002002200229033037032002400240200241206a41104188f0c100410041001004417f460d00200241c8006a4200370300200241306a41106a42003703002005420037030020024200370330200241206a4110200241306a4120410010042205417f460d012005411f4d0d01200241186a2205200241306a41186a2206290300370300200241106a2207200241306a41106a2208290300370300200241086a2209200241306a41086a220a2903003703002002200229033037030020062005290300220137030020082007290300220b370300200a2009290300220c37030020002002290300220d370000200041086a200c370000200041106a200b370000200041186a20013700002002200d3703302004450d060c050b20004200370000200041186a4200370000200041106a4200370000200041086a420037000020040d040c050b41eac4c10041331042000b411041011019000b1018000b200741011019000b200310010b200241d0006a24000ba41703067f027e047f230041d0006b220224000240024002400240024002400240024002400240024002400240024002400240024041da0110002203450d00200242da0137021420022003360210200241106a4102102702400240024002400240024002400240200128020022012903704202520d00200241186a220428020022032002280214470d03200341016a22052003490d1620034101742206200520052006491b22054100480d162003450d0120022802102107200510002206450d0a2006200720052003200320054b1b10f8021a200710010c020b200241106a41086a220428020022032002280214470d05200341016a22052003490d1520034101742206200520052006491b22054100480d152003450d0320022802102107200510002206450d0a2006200720052003200320054b1b10f8021a200710010c040b200510002206450d080b2002200536021420022006360210200241186a28020021030b200228021020036a41013a00002004200428020041016a3602000c030b200510002206450d060b2002200536021420022006360210200241186a28020021030b200228021020036a4181013a00002004200428020041016a360200200141086a200241106a10a401024002400240024020022802142207200428020022036b41c0004f0d00200341c0006a22042003490d1320074101742203200420042003491b22054100480d132007450d0120022802102103200510002206450d092006200320052007200720054b1b10f8021a200310010c020b20022802102106200721050c020b200510002206450d070b2002200536021420022006360210200241186a28020021030b200241106a41086a2207200341c0006a2204360200200620036a220341386a200141e4006a290000370000200341306a200141dc006a290000370000200341286a200141d4006a290000370000200341206a200141cc006a290000370000200341186a200141c4006a290000370000200341106a2001413c6a290000370000200341086a200141346a2900003700002003200129002c370000200129030021080240024002400240200520046b41074b0d00200441086a22032004490d1320054101742204200320032004491b22044100480d132004100021032005450d012003450d0a2003200620042005200520044b1b10f8021a200610010c020b200621030c020b2003450d080b2002200436021420022003360210200241186a28020021040b2007200441086a360200200320046a200837000002400240024002400240024002400240200141f0006a2903004201520d00200141f8006a2903002208420c882209420120094201561b22094200510d0f20014180016a290300200980210920022802142205200241186a28020022036b41024f0d01200341026a22042003490d1720054101742203200420042003491b22034100480d172005450d0520022802102106200310002204450d112004200620032005200520034b1b10f8021a200610010c060b02402002280214200241186a2802002203470d00200341016a22042003490d1720034101742205200420042005491b22054100480d172003450d0220022802102106200510002204450d102004200620052003200320054b1b10f8021a200610010c030b200228021021040c030b200228021021040c050b200510002204450d0d0b2002200536021420022004360210200241186a28020021030b200241186a200341016a360200200420036a41003a00000c030b200310002204450d0b0b2002200336021420022004360210200241186a28020021030b200241186a200341026a360200200420036a2009a741047420087aa7417f6a22034101200341014b1b2203410f2003410f491b723b00000b20014188016a200241106a101c0240024002400240200241186a28020022034102460d004101210120034103460d012003417e6a21034101210103402001220441016a22012003490d000b200441016a2201413f4d0d012001418080014f0d024102210341021000220a450d0d200a20014102744101723b00002002280218220141014b0d110c030b410021010b4101210341011000220a450d03200a20014102743a00002002280218220141014d0d010c0f0b024020014180808080044f0d004104210341041000220a450d0c200a20014102744102723600002002280218220141014b0d0f0c010b410110002204450d0c200441033a00004105210341051000220a450d0d200a20042d00003a000020041001200a20013600012002280218220141014b0d0e0b41d08ec200104f000b41da0141011019000b410141011019000b200541011019000b200541011019000b200541011019000b200441011019000b418cacc300104f000b200541011019000b200341011019000b410241011019000b410441011019000b410141011019000b410541011019000b200241186a2205410036020020022802102104200241086a200a200a20036a102e200241386a200228020c220b360200200241023602202002412c6a200441026a220436020020022001417e6a2201360224200220022802082203360234200220043602282002200241106a360230200241346a210c02400240024002400240024002402001450d000240200528020022014102460d0020022802102106200241346a2105200241186a2104200241386a21072003200b460d07024003402005200341016a360200200620016a20032d00003a00002004200428020041016a36020020014101460d01200141016a2101200528020022032007280200460d090c000b0b200241386a280200210b200241346a28020021030b200b20036b2201450d05200241306a280200220641046a28020022072002280224220d200228022022046a22056b20014f0d01200520016a22042005490d0720074101742205200420042005491b22044100480d072007450d022006280200210d200410002205450d082005200d20042007200720044b1b10f8021a200d10010c030b200241106a200c103f0c050b200628020021050c020b200410002205450d050b20062005360200200641046a20043602002002280224210d200228022021040b2005200420016a22016a200520046a200d10f9021a200220013602202001200241306a28020022062802082207460d00200b20046a200320076a6b2105200628020020076a2101200241386a2107200241346a2104200641086a21060340200428020022032007280200460d022004200341016a360200200120032d00003a00002006200628020041016a360200200141016a21012005417f6a22050d000b0b2002410036024820024201370340200241c0006a200c103f200228024421072002280240210b024020022802482201450d000240024002400240200241306a280200220541046a28020022062002280224220c200228022022036a22046b20014f0d00200420016a22032004490d0620064101742204200320032004491b22034100480d062006450d012005280200210c200310002204450d082004200c20032006200620034b1b10f8021a200c10010c020b200528020021040c020b200310002204450d060b20052004360200200541046a20033602002002280224210c200228022021030b2004200320016a22056a200420036a200c10f9021a200220053602202005200241306a2802002204280208220c460d00200c20036b21062004280200200c6a2103200441086a2105200b210403402001450d01200320042d00003a00002005200528020041016a360200200441016a2104200341016a210320062001417f6a2201470d000b0b2007450d00200b10010b0240200241286a22012802002002412c6a2802002203460d00200120033602000b024020022802242201450d00024020022802202205200241306a280200220641086a22042802002203460d002006280200220620036a200620056a200110f9021a200228022421010b2004200120036a3602000b200a1001200041086a200241106a41086a28020036020020002002290310370200200241d0006a24000f0b1018000b200441011019000b200341011019000bce0c05017f017e027f017e047f230041a0066b2203240020034188046a200141d80110f8021a20034180036a20034188046a10f70102402003280280034101470d00200329028403210420034190016a20034188026a41f80010f8021a200041086a200437020020004201370200200341a0066a24000f0b20034180036a41086a290300210420034188026a20034180036a41106a41f80010f8021a20034190016a20034188026a41f80010f8021a20032004370310410021050240024002400240200341106a41086a20034190016a41f80010f80222014100200329031022044201511b2206450d002006450d00024002400240200610f901220420062903202207520d002006200210f801450d0220004281808080303702000c010b2000410136020020004101410220072004541b3602040b200341c0006a10fa01200341a0066a24000f0b411310002202450d022003421337028c04200320023602880420034188046a41abf1c1004113102520034180036a41086a2202200328029004360200200320032903880437038003200620034180036a101e200228020021082003280284032109200328028003210a20034188046a41086a220b42003703002003420037038804200a200820034188046a10022002200b29030037030020032003290388043703800302400240024020034180036a41104188f0c100410041001004417f460d00200342003703880420034180036a411020034188046a41084100100441016a41084d0d0420032903880442017c210420090d010c020b420121042009450d010b200a10010b411310002202450d032003421337028c04200320023602880420034188046a41abf1c1004113102520034180036a41086a2202200328029004360200200320032903880437038003200620034180036a101e2002280200210a20032802840321082003280280032106200320043703880220034188046a41086a2209420037030020034200370388042006200a20034188046a10022002200929030037030020032003290388043703800320034180036a411020034188026a4108100302402008450d00200610010b200329031021040b20034188046a200341386a41d80010f8021a20034180036a20034188046a41086a41d00010f8021a20034188026a41186a2206200141186a29030037030020034188026a41106a200141106a29030037030020034188026a41086a200141086a2903003703002003200129030037038802024020044201520d0020034190016a41186a200629030037030020034190016a41106a20034188026a41106a29030037030020034190016a41086a20034188026a41086a290300370300200320032903880237039001410121050b20034188026a20034180036a41d00010f8021a20034180066a41186a220a20034190016a41186a29030037030020034180066a41106a220820034190016a41106a220129030037030020034180066a41086a220920034190016a41086a220229030037030020032003290390013703800620034180036a20034188026a41d00010f8021a200341e0056a41186a220b200a290300370300200341e0056a41106a220a2008290300370300200341e0056a41086a2208200929030037030020032003290380063703e00520034188046a20034180036a41d00010f8021a2006200b29030037030020034188026a41106a2209200a29030037030020034188026a41086a220a2008290300370300200320032903e005370388024102210602402005450d0020034190016a41186a20034188026a41186a290300370300200120092903003703002002200a290300370300200320032903880237039001410121060b20034192026a20022903003701002003419a026a2001290300370100200341a2026a200341a8016a290300370100200320063a008902200341003a008802200320032903900137018a02200341086a20034188046a20034188026a10cc02200328020c210620032802082101200341003a008804200320014100473a00890420034188046a10b401200310f0012003200328020441016a410120032802001b3602880441bef1c100411020034188046a41041003024002402001450d00200020013602040c010b200041003602040b20004100360200200041086a2006360200200341a0066a24000f0b41eac4c10041331042000b411341011019000b411341011019000bd40101037f230041306b2200240002400240024041bef1c10041104188f0c100410041001004417f460d00200041003602204101210141bef1c1004110200041206a41044100100441016a41044d0d022000280220210241bef1c100411010080c010b410021010b20002002410020011b36020c200041206a41086a220142003703002000420037032041c8f5c1004115200041206a1002200041106a41086a200129030037030020002000290320370310200041106a41102000410c6a41041003200041306a24000f0b41eac4c10041331042000bf8a90107037f017e057f037e187f0e7e027f23004190086b220124000240024002400240024041f2a1c100411310a702220241ff01714102460d002002410171450d00200141c0036a41086a22024200370300200142003703c003419ab6c100411d200141c0036a100220014190036a41086a2002290300370300200120012903c0033703900320014190036a41104188f0c100410041001004417f460d04200142103702bc06200120014190036a3602b806200141a0076a200141b8066a103420012802a0072203450d0120012902a4072104200141c0036a41086a22024200370300200142003703c003419ab6c100411d200141c0036a1002200141e0036a41086a2002290300370300200120012903c0033703e003200141e0036a41101008410610002202450d02200142063702a407200120023602a007200141a0076a41bab6c10041061025200141b8066a41086a220220012802a807360200200120012903a0073703b806200141b8066a41b7b6c1004103102520012802bc06210520012802b8062206200228020010c401210702402005450d00200610010b41002102200141e0046a410020071046024020012802e80422082004422088a7470d0020012802e00422092105200321070240410020084f0d000340200241016a22062002490d01024020092003460d0020052007412010fa020d030b200541206a2105200741206a2107200622022008490d000b0b024020012802e404450d00200910010b2004a7450d050c040b200141c3066a200141e0046a41086a280200360000200120012903e0043700bb06200141a0076a41086a200141bf066a290000370000200141013a00a007200120012900b8063700a107200141a0076a10e0022004a70d030c040b41d4f6c200104f000b41eac4c10041331042000b410641011019000b200310010b200141c0036a41086a22024200370300200142003703c00341c1f1c0004118200141c0036a100220014190036a41086a22052002290300370300200120012903c0033703900342002104024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020014190036a41104188f0c100410041001004417f460d00200142003703a00720014190036a4110200141a0076a41084100100441016a41084d0d0120012903a00721040b20024200370300200142003703c00341d9f1c0004115200141c0036a100220052002290300370300200120012903c003370390030240024020014190036a41104188f0c100410041001004417f460d00200142003703a00720014190036a4110200141a0076a41084100100441016a41084d0d0320012903a007220a4200520d0141c8cdc200104f000b42e807210a0b200020047d200a82210402400240024002400240024041eef1c000411910a702220541ff017122074102470d0020044200520d010b4200210b200141c0036a41086a22024200370300200142003703c00341a0a5c100410d200141c0036a100220014190036a41086a22062002290300370300200120012903c003370390034200210a024020014190036a41104188f0c100410041001004417f460d00200142003703a00720014190036a4110200141a0076a41084100100441016a41084d0d0a20012903a007210a0b20024200370300200142003703c0034187f2c0004114200141c0036a100220062002290300370300200120012903c00337039003024020014190036a41104188f0c100410041001004417f460d00200142003703a00720014190036a4110200141a0076a41084100100441016a41084d0d0b20012903a007210b0b200141c0036a41086a22024200370300200142003703c003419bf2c0004114200141c0036a100220014190036a41086a2002290300370300200120012903c003370390030240024020014190036a41104188f0c100410041001004417f460d00200142003703a00720014190036a4110200141a0076a41084100100441016a41084d0d0d20012903a00742017c210c0c010b4201210c0b2004502106200141a0076a41086a200c370300200141023a00a007200141a0076a10b4012001200c3703a007200141c0036a41086a22024200370300200142003703c003419bf2c0004114200141c0036a100220014190036a41086a22032002290300370300200120012903c0033703900320014190036a4110200141a0076a410810032001200a3703a00720024200370300200142003703c0034187f2c0004114200141c0036a100220032002290300370300200120012903c0033703900320014190036a4110200141a0076a4108100320014180036a41aff2c000411910a602024002400240200129038003a74101470d0020012001290388033703a00720024200370300200142003703c00341d9f1c0004115200141c0036a100220032002290300370300200120012903c0033703900320014190036a4110200141a0076a410810030c010b20060d010b200141c0036a41086a22024200370300200142003703c00341f0f1c100410d200141c0036a100220014190036a41086a22032002290300370300200120012903c0033703900342002104024020014190036a41104188f0c100410041001004417f460d00200142003703a00720014190036a4110200141a0076a41084100100441016a41084d0d0e20012903a00721040b200120043703a00720024200370300200142003703c00341c1f1c0004118200141c0036a100220032002290300370300200120012903c0033703900320014190036a4110200141a0076a410810030b200a200b7d2006200541017120074102461b10c101200141c0036a41086a22024200370300200142003703c00341c8f2c0004112200141c0036a100220014190036a41086a2002290300370300200120012903c0033703900302400240024020014190036a41104188f0c100410041001004417f460d00200142103702bc06200120014190036a3602b806200141a0076a200141b8066a103620012802a007220d450d1220012802a407210e4101210f200d4101200d1b2110200141a8076a2802004100200d1b22020d010c020b4100210d4101210f4100410141001b21104100410041001b2202450d010b2002410574211120102109410021080340411210002202450d04200142123702a407200120023602a007200141a0076a41daf2c00041121025200141b8066a41086a2202200141a0076a41086a2205280200360200200120012903a0073703b8062009200141b8066a101e2002280200211420012802bc06211520012802b806210620014190036a41086a2203420037030020014200370390032006201420014190036a1002200141e0036a41086a2216200329030037030020012001290390033703e00302400240200141e0036a41104188f0c100410041001004417f460d00200141c0036a41186a22174200370300200141c0036a41106a22184200370300200141c0036a41086a22194200370300200142003703c003200141e0036a4110200141c0036a4120410010042207417f460d052007411f4d0d05200141a0076a41186a22122017290300370300200141a0076a41106a2213201829030037030020052019290300370300200120012903c0033703a007200141a0036a41186a221a20122903002204370300200141a0036a41106a221b2013290300220a370300200141a0036a41086a221c2005290300220c3703002002200c370300200141b8066a41106a221d200a370300200141b8066a41186a221e2004370300200120012903a00722043703b806200120043703a003200141e0046a41186a221f201e290300370300200141e0046a41106a2220201d290300370300200141e0046a41086a22072002290300370300200120012903b8063703e0042003420037030020014200370390032006201420014190036a10022019200329030037030020012001290390033703c003200141c0036a4110100820014180046a41186a2203201f29030037030020014180046a41106a2214202029030037030020014180046a41086a22212007290300370300200120012903e00437038004200141e8056a41186a22222003290300370300200141e8056a41106a22232014290300370300200141e8056a41086a2224202129030037030020012001290380043703e80502402015450d00200610010b200320222903003703002014202329030037030020212024290300370300200120012903e80537038004200120083602e004410610002206450d08200142063702a407200120063602a007200141a0076a41bab6c1004106102520022005280200360200200120012903a0073703b806200141b8066a200141e0046a4104102520012802bc06210302400240024020012802b8062206200228020022144188f0c100410041001004417f470d00201242003703002013420037030020054200370300200142003703a00720030d010c020b201742003703002018420037030020194200370300200142003703c00320062014200141c0036a4120410010042214417f460d092014411f4d0d09201220172903003703002013201829030037030020052019290300370300200120012903c0033703a007201a20122903002204370300201b2013290300220a370300201c2005290300220c3703002002200c370300201d200a370300201e2004370300200120012903a00722043703b806200120043703a003201f201e2903003703002020201d29030037030020072002290300370300200120012903b8063703e004200141e0036a41186a2219201f290300370300200141e0036a41106a2214202029030037030020162007290300370300200120012903e0043703e003201f2019290300220437030020202014290300220a37030020072016290300220c3703002005200c3703002013200a37030020122004370300200120012903e00322043703e004200120043703a0072003450d010b200610010b200141a0076a20014180046a412010fa02450d01200141003602b806200141b8066a10c501410610002205450d0c200142063702bc06200120053602b806200141b8066a41bab6c1004106102520072002280200360200200120012903b8063703e004200141e0046a41b7b6c1004103102520012802e404210520012802e0042203200728020010c401210602402005450d00200310010b200620084d0d01200120083602e003410610002205450d11200142063702bc06200120053602b806200141b8066a41bab6c1004106102520072002280200360200200120012903b8063703e004200141e0046a200141e0036a4104102520012802e404210220012802e0042205200728020020014180046a10c6012002450d0120051001200941206a21092008200f6a2108201141606a22110d020c030b20014180046a41186a200141e0046a41186a29030037030020014180046a41106a200141e0046a41106a29030037030020014180046a41086a200141e0046a41086a290300370300200120012903e004370380042015450d00200610010b200941206a21092008200f6a2108201141606a22110d000b0b200d450d00200e450d00201010010b200141c0036a41086a22024200370300200142003703c00341a285c1004116200141c0036a100220014190036a41086a2002290300370300200120012903c003370390030240024020014190036a41104188f0c100410041001004417f460d00200142003703a00720014190036a4110200141a0076a41084100100441016a41084d0d0820012903a00722044200510d0f4200212520002004824200520d180c010b42002125200042e807824200520d170b41082119200141c0036a41086a22022025370300200120253703c00341b885c1004115200141c0036a100220014190036a41086a2002290300370300200120012903c003370390030240024002400240024020014190036a41104188f0c100410041001004417f460d00200142103702bc06200120014190036a3602b806200141a0076a200141b8066a103720012802a0072219450d1420012902a4072226422088a722140d010c020b420021264200422088a72214450d010b2019201441f8006c6a2108200141a0076a2019280250109102201941f8006a2102024002400240024020012802b0072205450d00200141f0026a20012903a007200141a0076a41086a290300200141b8076a350200420010fc02200141f0026a41086a290300210420012903f002210c024020012802b407450d00200510010b4100210620022008470d010c020b4200210c420021044100210620022008460d010b200141b0076a2109200141b8076a2112200141b4076a211341012107201921030340200141a0076a200241d0006a2802001091020240024020092802002205450d00200141e0026a20012903a007200141a0076a41086a2903002012350200420010fc02200141e0026a41086a290300210a20012903e002210b2013280200450d01200510010c010b4200210b4200210a0b2004200a200c200b562004200a562004200a511b22051b2104200c200b20051b210c2006200720051b21062003200220051b2103200741016a2107200241f8006a22022008470d000b2003450d010b200620144f0d1520192014417f6a220741f8006c6a220541c0006a290300210b200541c8006a2903002127200541d0006a2903002128200541d8006a2903002129200541206a290300212a200541286a290300212b200541306a290300212c200541386a290300212d2005290300212e2005290308212f200529031021302019200641f8006c6a220241186a22062900002131200541f0006a2903002104200541e8006a290300210a200541e0006a290300210c2006200541186a2903003700002002290010213220022030370010200229000821302002202f3700082002290000212f2002202e370000200241386a2205290000212e2005202d370000200241306a2205290000212d2005202c370000200241286a2205290000212c2005202b370000200241206a2205290000212b2005202a370000200241d8006a2029370000200241d0006a2205280000210820052028370000200241c8006a2205290000212820052027370000200241c0006a220529000021272005200b370000200241e0006a200c370000200241e8006a200a370000200141a8076a200a370300200241f0006a2004370000200141b0076a20043703002001200c3703a007200141b8066a41c8006a2028370300200141b8066a41c0006a2027370300200141b8066a41386a202e370300200141b8066a41306a202d370300200141b8066a41286a202c370300200141b8066a41206a202b370300200141b8066a41186a2031370300200120323703c806200120303703c0062001202f3703b8062001202642ffffffff0f832007ad422086843702a407200120193602a007200141153602e404200141b885c1003602e004200141a0076a200141e0046a101d2026a7210602402007450d00201441f8006c41887f6a210520192102034020021028200241f8006a2102200541887f6a22050d000b0b02402006450d00201910010b411310002202450d16200142133702a407200120023602a007200141a0076a41cd85c1004113102520012802a0072103024020012802a407220720012802a80722056b41034b0d00200541046a22022005490d2e20074101742206200220022006491b22064100480d2e2007450d03200610002202450d182002200320062007200720064b1b10f8021a200310010c040b20032102200721060c030b2014450d00201441f8006c210520192102034020021028200241f8006a2102200541887f6a22050d000b0b2026a7450d18201910010c180b200610002202450d140b200220056a2008360000200141c0036a41086a22074200370300200142003703c0032002200541046a2209200141c0036a100220014190036a41086a2007290300370300200120012903c0033703900341002107024020014190036a41104188f0c100410041001004417f460d00200120014190036a3602e004200141103602e404200142003703a807200142003703a0072001410020014190036a4110200141a0076a41104100100422052005417f461b2205411020054110491b3602e8042005410f4d0d11200141a0076a41086a2205290300210420012903a007210a200141a0076a200141e0046a103620012802a0072207450d112005280200210320012802a4072112200141c0036a41086a22054200370300200142003703c00320022009200141c0036a1002200141e0036a41086a2005290300370300200120012903c0033703e003200141e0036a411010082006450d160c150b20060d140c150b200141a0036a41186a200141a0076a41186a290000370300200141a0036a41106a200141a0076a41106a290000370300200141a0036a41086a200141a0076a41086a290000370300200120012900a0073703a00341eac4c10041331042000b411241011019000b200141a0036a41186a200141a0076a41186a290000370300200141a0036a41106a200141a0076a41106a290000370300200141a0036a41086a200141a0076a41086a290000370300200120012900a0073703a00341eac4c10041331042000b410641011019000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b410641011019000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b410641011019000b41c4d6c200104f000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41dcd6c20020062014104e000b411341011019000b200641011019000b200210010b0240024002402007450d0002402003450d00200341057421052007210203402002200a200410e102200241206a2102200541606a22050d000b0b200141c8076a2004370300200141c0076a200a370300200141b8076a2003360200200141b4076a2012360200200141a0076a41106a2007360200200141ac076a2008360200200141a0076a41086a41003a0000200141043a00a007200141a0076a10b401200141c0036a41086a22024200370300200142003703c00341e085c1004116200141c0036a100220014190036a41086a2002290300370300200120012903c0033703900320014190036a41104188f0c100410041001004417f460d01200142003703a00720014190036a4110200141a0076a41084100100441016a41084d0d0420012903a007210a0c020b200141b8066a10a0010c020b42e807210a0b200141a0076a200141b8066a41d00010f8021a42002104200141c0036a41086a22024200370300200142003703c00341f685c1004115200141c0036a100220014190036a41086a2002290300370300200120012903c00337039003024020014190036a41104188f0c100410041001004417f460d00200142003703e00420014190036a4110200141e0046a41084100100441016a41084d0d0320012903e00421040b200141e0046a200a20007c200141a0076a4100200410920220012802e0044101470d0020012802e404200141e0046a41086a2802001006200141e0046a211a200141a0036a212020014180046a2116200141c0036a211e200141e0036a21180c120b200120003703a003200141c0036a41086a22022025370300200120253703c003418b86c1004113200141c0036a100220014190036a41086a2002290300370300200120012903c003370390034100210502400240024020014190036a41104188f0c100410041001004417f460d00200141003602a00720014190036a4110200141a0076a41044100100441016a41044d0d0120012802a00721050b200141c0036a41086a22024200370300200142003703c003419e86c1004119200141c0036a100220014190036a41086a2002290300370300200120012903c0033703900341002106024020014190036a41104188f0c100410041001004417f460d00200141003602a00720014190036a4110200141a0076a41044100100441016a41044d0d0220012802a00721060b200141003a00ec03200120053602e003200120063602e4032001200141a0036a3602e80302400240200520064f0d002001200541016a22023602e003200141a8076a210302400340200141a0076a200510930220032802002207410d470d01200220064f0d022001200241016a22073602e00320022105200721020c000b0b20012903a0072104200141b8066a200141a0076a410c6a41dc0010f8021a200141b0076a22022007360200200120043703a807200120053602a007200141b4076a200141b8066a41dc0010f80221050240200420012903a003520d0020014180046a41086a2202200141a0076a41086a290300370300200120012903a00737038004200141e0046a200541dc0010f8021a200141b8066a41086a2205200229030037030020012001290380043703b806200141a0076a200141e0046a41dc0010f8021a41f00010002233450d07203320012903b80637030020332007360210203341086a2005290300370300203341146a200141a0076a41dc0010f8021a200141e8056a41086a200141e0036a41086a290300370300200120012903e0033703e80520012d00f4050d0920012802e805220220012802ec054f0d092001200241016a3602e805200141a8076a21050340200141a0076a200210930220052802002207410d470d0320012802e805220220012802ec054f0d0a2001200241016a3602e8050c000b0b200141e0036a410c6a41013a0000200210280b410021344108213341082116410021020c080b20012903a0072104200141b8066a200141a0076a410c6a41dc0010f8021a200141b0076a22052007360200200120043703a807200120023602a007200141b4076a200141b8066a41dc0010f802210202400240200420012802f005290300520d0020014180046a41086a200141a0076a41086a290300370300200120012903a00737038004200141e0046a200241dc0010f8021a41002106410d21032007410d470d010c080b41012106200141e8056a410c6a41013a000020051028410d2107410d2103410d410d460d070b200141a0076a41106a2119200141a0076a41146a2114200141ac076a211f203321122033211641012105410121020340200141b8066a41086a220820014180046a41086a221329030037030020012001290380043703b806200141a0076a200141e0046a41dc0010f8021a024002400240024020022005470d00200541016a22092005490d1920054101742220200920092020491b2234ad42f0007e2204422088a70d192004a722094100480d192005450d01200910002233450d0a203320122009200541f0006c2205200520094b1b10f8021a201210010c020b200521340c020b200910002233450d080b20332112203321160b2016200241f0006c6a220520012903b806370300200541086a2008290300370300200541106a2007360200200541146a200141a0076a41dc0010f8021a200241016a2102200641ff01710d0820012802e805220620012802ec0522094f0d082001200641016a22053602e80502400340200141a0076a2006109302200141a0076a41086a220828020022072003470d01200520094f0d0a2001200541016a22073602e80520052106200721050c000b0b20012903a0072104200141b8066a201f41dc0010f8021a2019200736020020082004370300200120063602a0072014200141b8066a41dc0010f802210502402004200141e8056a41086a280200290300520d0020132008290300370300200120012903a00737038004200141e0046a200541dc0010f8021a41002106203421050c010b0b200141f4056a41013a00002019102841f000211b2016200241f0006c22026a210f20020d080c090b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41f00041081019000b200941081019000b4101213441f000211b20332216410141f0006c22026a210f20020d010c020b41f000211b2016200241f0006c22026a210f2002450d010b200141a0076a41086a2121200141e0046a41086a211a200141a0076a4104722105200141e0046a410c6a211c200141c0056a210d200141e0046a41d8006a2110200141a9076a210e0340201641106a28020021022016290208210420162802002109200141a0076a201641146a41dc0010f8021a2016201b6a21162002410d460d0120014180046a200141a0076a41dc0010f8021a201a2002360200200120043703e004201c20014180046a41dc0010f8021a200120093602c805200141b8066a200910950220012802b8062112024002400240200141b8066a41086a22062802002202450d00200241057421034200210a2012210242002104420021264200212842002125420021270340200141d0026a200210b001200141d0026a41086a290300210b20012903d002210c20022900002129200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a29000037000020052029370000200120093602a007200141c0026a200c200b200141a0076a1099022207411874411875220841077620077341016aad423886423887420010fc02200b20047c200c200a7c220a200c54ad7c21044200200141c0026a41086a290300220c200841004822071b20287c420020012903c002220b20071b222820267c2226202854ad7c2128200c420020071b20277c200b420020071b220c20257c2225200c54ad7c2127200241206a2102200341606a22030d000b20012802bc06450d020c010b420021254200212742002126420021284200210a4200210420012802bc06450d010b201210010b4200210b200141c0036a41086a22024200370300200142003703c00341d9f0c1004116200141c0036a1002200141e0036a41086a22082002290300370300200120012903c0033703e003024002400240024002400240200141e0036a41104188f0c100410041001004417f460d00200142003703a807200142003703a007200141e0036a4110200141a0076a4110410010042207417f460d022007410f4d0d022021290300210c20012903a007210b0c010b4200210c0b200d2d00002112024002400240200a4202882004423e868422292004420288222a84500d002029200a85202a20048584500d004100210702400340200141b0026a200a2004200741046a41fe007110ff02200741026a210720012903b0022229200141b0026a41086a290300222a84500d012029200a85202a2004858450450d000b0b200141a0026a200a2004200741fe007110ff0220012903a002200141a0026a41086a2903008421294200212a2007450d012029420052ad2129034020014180026a200a200441002007417e6a2203200320074b1b220741ff007110ff0220014190026a2029420186222c420184222b202a4201862029423f8884222a202b202a10fc02202c202b2001290390022001290380025620014190026a41086a290300222920014180026a41086a290300222d562029202d511b1b212920070d000c030b0b4200212a200a200484420052ad21290c010b2029420052ad21290b02400240200b420288200c423e86842204200c420288220a84500d002004200b85200a200c8584500d004100210702400340200141f0016a200b200c200741046a41fe007110ff02200741026a210720012903f0012204200141f0016a41086a290300220a84500d012004200b85200a200c858450450d000b0b200141e0016a200b200c200741fe007110ff0220012903e001200141e0016a41086a2903008421044200210a2007450d012004420052ad21040340200141c0016a200b200c41002007417e6a2203200320074b1b220741ff007110ff02200141d0016a2004420186222c420184222b200a4201862004423f8884220a202b200a10fc02202c202b20012903d00120012903c00156200141d0016a41086a2903002204200141c0016a41086a290300222d562004202d511b1b210420070d000b2029202a84500d040c030b4200210a200b200c84420052ad21042029202a8450450d020c030b2004420052ad21042029202a8450450d010c020b41eac4c10041331042000b024020124102460d00024020124101470d000340202a212a2029212b2004200a844200510d0c200141a0016a20252027202b202a10fb02200141b0016a202620282004200a10fb024101210720012903b001222920012903a001222c54200141b0016a41086a290300220c200141a0016a41086a290300220b54200c200b5122031b0d04202c202954200b200c5420031b0d0320014190016a2029200c2004200a10fc0220014180016a202c200b202b202a10fc022025200129038001220c7d220b202720014180016a41086a2903007d2025200c54ad7d220c84500d03202820014190016a41086a2903007d212c20262001290390012225542103202620257d212920042125200a2127200b2104200c210a202b2126202a21282029202c2003ad7d222a8450450d000c040b0b0340200141f0006a202620282029202a10fb022004220b200a222b844200510d0a200141f0006a41086a29030021042001290370210a200141e0006a20252027200b202b10fb0241012107200a2001290360222c542004200141e0006a41086a290300220c542004200c5122031b0d03202c200a54200c20045420031b0d02200141d0006a200a20042029202a10fc02200141c0006a202c200c200b202b10fc022025200129034022047d220a2027200141c0006a41086a2903007d2025200454ad7d220c84500d022028200141d0006a41086a2903007d212c202620012903502204542103202620047d210420292125202a2127200a2129200c212a200b2126202b21282004202c2003ad7d220a8450450d000c030b0b2025202656202720285620272028511b21070c010b410021070b200120073a00cf054200210b20024200370300200142003703c00341f685c1004115200141c0036a100220014190036a41086a22222002290300370300200120012903c00337039003024020014190036a41104188f0c100410041001004417f460d00200142003703a00720014190036a4110200141a0076a41084100100441016a41084d0d0920012903a007210b20012802c80521090b200141a0076a200910950220012802a4072107200141d0056a410c6a222320012802a0072203202128020022094105746a360200200141d0056a41086a22202003360200200141d0056a41146a2217200141cf056a360200200141d0056a41106a2224200141c8056a360200200120073602d405200120033602d00502402009450d002020200341206a360200200141b8066a41186a2213200341186a2900002204370300200141b8066a41106a2219200341106a290000220a3703002006200341086a290000220c370300200141e8056a41086a2207200c370300200141e8056a41106a2214200a370300200141e8056a41186a221f20043703002001200329000022043703b806200120043703e805200520012903b806370000200541086a221d2006290300370000200541106a221e2019290300370000200541186a22152013290300370000200120012802c8053602a007200141a0076a10990221030340200141c0036a41186a2209201f290300370300200141c0036a41106a2212201429030037030020022007290300370300200120012903e8053703c003200141e0036a41186a22112009290300370300200141e0036a41106a2209201229030037030020082002290300370300200120012903c0033703e0030240024002400240024002402003411874411875221241004820172802002d00004573450d00200141a0036a41186a22182011290300370300200141a0036a41106a22112009290300370300200141a0036a41086a22092008290300370300200120012903e0033703a003200141a0076a41186a2018290300370300200141a0076a41106a201129030037030020212009290300370300200120012903a0033703a007411110002209450d03200142113702bc06200120093602b806200141b8066a41f384c1004111102520072006280200360200200120012903b8063703e805200141a0076a200141e8056a101e2007280200211120012802ec05211820012802e805210920024200370300200142003703c00320092011200141c0036a100220222002290300370300200120012903c0033703900320014190036a41104188f0c100410041001004417f460d01200142003703b80620014190036a4110200141b8066a41084100100441016a41084d0d0220012903b806210a20024200370300200142003703c00320092011200141c0036a100220082002290300370300200120012903c0033703e003200141e0036a411010084201210c2018450d050c040b20012802d805220320012802dc05460d062020200341206a3602002013200341186a29000022043703002019200341106a290000220a3703002006200341086a290000220c3703002007200c3703002014200a370300201f20043703002001200329000022043703b806200120043703e805200520012903b806370000201d2006290300370000201e201929030037000020152013290300370000200120012802e0052802003602a007200141a0076a10990221030c050b4200210c20180d020c030b41eac4c10041331042000b411141011019000b200910010b411110002209450d04200142113702bc06200120093602b806200141b8066a41f384c1004111102520072006280200360200200120012903b8063703e805200141a0076a200141e8056a101e2007280200211120012802ec05211820012802e80521092001200b201241077620037341016aad4238864238877e20007c2204200a4200200ca71b220a200a2004541b3703b80620024200370300200142003703c00320092011200141c0036a100220082002290300370300200120012903c0033703e003200141e0036a4110200141b8066a4108100302402018450d00200910010b202028020022032023280200460d012020200341206a3602002013200341186a29000022043703002019200341106a290000220a3703002006200341086a290000220c3703002007200c3703002014200a370300201f20043703002001200329000022043703b806200120043703e805200520012903b806370000201d2006290300370000201e201929030037000020152013290300370000200120242802002802003602a007200141a0076a10990221030c000b0b024020012802d405450d0020012802d00510010b20012802c80510960220012802c805210702400240024002400240024020012d00cf05450d00200141a0076a410c6a22062007360200202141023a0000200141043a00a007200141a0076a10b40120102903002204500d01200141b8066a200141e0046a41e80010f8021a200141e0036a200420007c2204109402200141a0076a200141b8066a41e80010f8021a200141e8056a202141d00010f8021a20012802c80521062008280200220720012802e403470d04200741016a22032007490d1220074101742209200320032009491b2212ad42d8007e220a422088a70d12200aa722034100480d122007450d0220012802e0032113200310002209450d0a200920132003200741d8006c2219201920034b1b10f8021a201310010c030b200141a0076a410c6a2007360200202141033a0000200141043a00a007200141a0076a10b401200120012802c80541016a3602a00720024200370300200142003703c003418b86c1004113200141c0036a100220082002290300370300200120012903c0033703e003200141e0036a4110200141a0076a41041003201a10a0012016200f470d050c040b20012802c8052107200141a0076a201a41d00010f8021a200141003b01b806200141386a200141a0076a200141b8066a10cc022001280238210320062007360200200e2003453a0000202141053a0000200141043a00a007200141a0076a10b401200120012802c80541016a3602a00720024200370300200142003703c003418b86c1004113200141c0036a100220082002290300370300200120012903c0033703e003200141e0036a4110200141a0076a410410032016200f470d040c030b200310002209450d070b200120123602e403200120093602e0030b20012802e003200741d8006c6a200141e8056a41d00010f80221032008200741016a360200200341d0006a2006360200411710002207450d04200142173702a407200120073602a007200141a0076a41b786c1004117102520012802a007210702400240024020012802a4072203202128020022066b41084f0d00200641086a22092006490d1020034101742212200920092012491b22094100480d102003450d01200910002212450d092012200720092003200320094b1b10f802210320071001200321070c020b200321090c010b200910002207450d070b200720066a20043700002001200641086a3602a407200120073602a007200141e0036a200141a0076a101a02402009450d00200710010b20012802e0032103024020082802002207450d00200741d8006c210620032107034002402007280200410d460d00200710280b200741d8006a2107200641a87f6a22060d000b0b024020012802e403450d00200310010b200120012802c80541016a3602a00720024200370300200142003703c003418b86c1004113200141c0036a100220082002290300370300200120012903c0033703e003200141e0036a4110200141a0076a410410032016200f470d010b0b200f21160b02402016200f460d00200141a0076a41106a2105200141a0076a41146a21030340200141e0046a41086a2207201641086a290300370300200120162903003703e004201641106a2802002102200141a0076a201641146a41dc0010f8021a2002410d460d0120014180046a41086a22062007290300370300200120012903e00437038004200141b8066a200141a0076a41dc0010f8021a20052002360200200141a0076a41086a200629030037030020012001290380043703a0072003200141b8066a41dc0010f8021a20051028201641f0006a2216200f470d000b0b02402034450d00203310010b200141a0076a200010940220012802a4072102200120012802a007220520012802a807220641d8006c6a22073602f405200120053602f005200120023602ec05200120053602e8050240024002402006450d00200141e8056a41086a2203200541d8006a220236020020052802002106200141a0076a200541046a41cc0010f8021a2006410e460d01200541d0006a2102200141a0076a4104722108200141a9076a2109034020022802002102200141e0046a200141a0076a41cc0010f8021a200141a0076a200141e0046a41cc0010f8021a024002402006410d470d0020012802f005220520012802f4052207460d052003200541d8006a220236020020052802002106200141a0076a200541046a41cc0010f8021a2006410e470d010c040b20014180046a200141a0076a41cc0010f8021a200120063602a007200820014180046a41cc0010f8021a200141003b01b806200141306a200141a0076a200141b8066a10cc0220012802302105200141a0076a410c6a200236020020092005453a0000200141a0076a41086a41053a0000200141043a00a007200141a0076a10b40120032802002205200141e8056a410c6a2802002207460d042003200541d8006a220236020020052802002106200141a0076a200541046a41cc0010f8021a2006410e460d030b200541d0006a21020c000b0b20052107200521020b20022007460d090c080b2005220220052207470d070c080b411141011019000b411741011019000b200341081019000b200941011019000b41ecd6c200104f000b41ecd6c200104f000b41eac4c10041331042000b200141a0076a4104722108200141f0056a2103200141f4056a210903402003200241d8006a220636020020022802002105200141a0076a200241046a41d40010f8021a2005410e460d01200141b8066a200141a0076a41d40010f8021a200120053602a0072008200141b8066a41d40010f8021a2006210202402005410d460d00200141a0076a102820092802002107200328020021020b20022007470d000b0b024020012802ec05450d0020012802e80510010b200141a0036a2120200141c0036a211e200141e0036a211820014180046a2116200141e0046a211a0b200010e202200141a0076a410472211b200141a0076a4105722111200141a0076a41206a2105200141e0046a4104722122200141e0046a410c6a210f200141d0076a2123200141cc076a212402400240024002400240024002400240024002400240024002400340200141a0076a109f0220012802a0072206410820061b2102200141a0076a41086a210920012802a4072103410d21070240024002400240024002400240024002402006450d00410d210720092802002208450d0020022903002104201841186a2212200241206a290000370000201841106a2213200241186a290000370000201841086a2219200241106a29000037000020182002290008370000410d210720042000520d002008417f6a2214ad42287e2204422088a70d022004a7221f417f4c0d0202400240201f450d00201f1000221d0d010c060b4108211d0b2001200241286a3602a00720012002200841286c6a3602a407200141286a200141a0076a10c902200128022821150240024002402014200128022c22074f0d0020144101742208200720072008491b2208ad42287e2204422088a70d1a2004a722214100480d1a2014450d01202110002217450d082017201d2021201f201f20214b1b10f8021a201d10010c020b201d2117201421080c010b202110002217450d060b20172015200741286c10f802211420092007360200200120083602a407200120143602a007200141a0076a10a50202402008450d00201410010b200141e8056a41186a2012290000370300200141e8056a41106a2013290000370300200141e8056a41086a2019290000370300200120182900003703e805411810002207450d03200142183702a407200120073602a007200141a0076a4188a3c10041181025200141b8066a41086a22072009280200360200200120012903a0073703b806200141e8056a200141b8066a101e2007280200211420012802bc06211720012802b806210820094200370300200142003703a00720082014200141a0076a1002200141c0036a41086a221f2009290300370300200120012903a0073703c003200141c0036a41104188f0c100410041001004417f460d01200142103702d4052001200141c0036a3602d005200141a0076a200141d0056a103820012802a0072207410d460d06201a201b41cc0010f802211d201f4200370300200142003703c00320082014200141c0036a100220014190036a41086a201f290300370300200120012903c0033703900320014190036a41101008200141b8066a201d41cc0010f8021a2016200141b8066a41cc0010f8021a02402017450d00200810010b20202018290000370000202041186a2012290000370000202041106a2013290000370000202041086a20192900003700000b2006450d070c060b200141b8066a201a41cc0010f8021a02402017450d00200810010b410d210720060d050c060b102c000b411841011019000b201f41081019000b202141081019000b41eac4c10041331042000b2003450d00200210010b2007410d460d01200120073602e0042022201641cc0010f8021a200141e8056a41186a2219202041186a290000370300200141e8056a41106a2214202041106a290000370300200141e8056a41086a221f202041086a290000370300200120202900003703e805200141a0076a109e024100211220012802a0072217410820171b211d20012802a40721214100211302402009280200410020171b221541286c2206450d004100211341002112201d2102034020052002290000370000200141a0076a41186a2019290300370300200141a0076a41106a20142903003703002009201f290300370300200541086a200241086a290000370000200541106a200241106a290000370000200541186a200241186a290000370000200120012903e8053703a007411b10002207450d042001421b3702bc06200120073602b806200141b8066a419faec100411b1025200141e0036a41086a2207200141b8066a41086a280200360200200120012903b8063703e003200141a0076a200141e0036a10af0220012802e403210320012802e0032208200728020010a702210702402003450d00200810010b0240200741ff01714102460d00201320074101716a211320122007417f734101716a21120b200241286a2102200641586a22060d000b0b201220136a210202402017450d002021450d00201d10010b201520026b210202400240024020012802e0044105470d00200141e0046a41086a2d000041ff01714106470d00200f28020021072023200236020020242012360200200141a0076a41286a2013360200201120012903e805370000201141086a201f290300370000201141106a2014290300370000201141186a2019290300370000200141003a00a407200141063a00a007200141a0076a10b40120120d0120020d01200141a0076a410c6a2007360200200941043a0000200141043a00a007200141a0076a10b40120071096020c010b201e20012903e805370000201e41186a2019290300370000201e41106a2014290300370000201e41086a201f2903003700002023200236020020242012360200200141a0076a41286a2013360200201120012903e805370000201141086a201f290300370000201141106a2014290300370000201141186a2019290300370000200141013a00a407200141063a00a007200141a0076a10b4012013200220126a4b0d010b200141e0046a10a0010c010b411c10002207450d062001421c3702a407200120073602a007200141a0076a41a0a3c100411c1025200141b8066a41086a22072009280200360200200120012903a0073703b806200141e8056a200141b8066a101e2007280200210620012802bc06210320012802b806210720094200370300200142003703a00720072006200141a0076a1002200141c0036a41086a22062009290300370300200120012903a0073703c003200141c0036a4110100802402003450d00200710010b420021044200210a02402012450d0020094200370300200142003703a00741bca3c100411e200141a0076a100220062009290300370300200120012903a0073703c0030240200141c0036a41104188f0c100410041001004417f460d00200142003703a007200141c0036a4110200141a0076a41084100100441016a41084d0d0720012903a007210a0c010b4200210a0b200141b8066a200141e0046a41d00010f8021a20094200370300200142003703a00741f0f1c100410d200141a0076a100220062009290300370300200120012903a0073703c0030240200141c0036a41104188f0c100410041001004417f460d00200142003703a007200141c0036a4110200141a0076a41084100100441016a41084d0d0420012903a00721040b20094200370300200142003703a00741e085c1004116200141a0076a1002200141e0036a41086a22072009290300370300200120012903a0073703e00302400240200141e0036a41104188f0c100410041001004417f460d00200142003703a007200141e0036a4110200141a0076a41084100100441016a41084d0d0620012903a007210c0c010b42e807210c0b200141a0076a200141b8066a41d00010f8021a200141e0036a200c20047c200141a0076a4102410120022012721b200a10920220012802e0034101470d0020012802e4032202450d000b20072802002105419ac9c100410f10062002200510060b200141a0076a10c70120012802b0072211450d0b200141e0046a41086a2202200141a0076a41086a2207290300370300200141a0036a41086a2205200141a0076a411c6a280200360200200120012903a0073703e004200120012902b4073703a003200141b8066a41086a2002290300370300200141cc066a20012903a003370200200141b8066a411c6a2005280200360200200120113602c806200120012903e00422043703b806200141b8066a41106a21020240024020042000520d0020012903c006210a20014180046a2002102f2007200a370300200141a0076a41106a200129038004370300200141b8076a20014180046a41086a280200360200200141023a00a007200141a0076a10e002200a20047c2000510d010c0c0b20012903c00620047c2000520d0b0b200141e8056a2002102f200141083a00a0072001418b046a200141e8056a41086a2208280200360000200120012903e80537008304200141a0076a41086a220920014187046a29000037000020012001290080043700a107200141a0076a10b401200141cc066a28020021170240200141b8066a41186a28020041286c2202450d00201120026a212041002106201121050340200141a0076a41186a2202200541186a290300370300200141a0076a41106a2212200541106a2903003703002009200541086a290300370300200120052903003703a007200541206a2903002104200120063602e003410e10002207450d072001420e37028404200120073602800420014180046a41d79bc100410e1025200820014180046a41086a28020036020020012001290380043703e805200141e8056a200141e0036a410410252008280200211320012802ec05211920012802e8052103412010002207450d08200720012903a007370000200741186a22142002290300370000200741106a221f2012290300370000200741086a2212200929030037000041c00010002202450d0920022007290000370000200241186a2014290000370000200241106a201f290000370000200241086a20122900003700002007100120022004370020200320132002412810032002100102402019450d00200310010b200641016a2106200541286a22052020470d000b2017450d0a0c090b4100210620170d080c090b411b41011019000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b411c41011019000b410e41011019000b412041011019000b41c00041011019000b201110010b02400240410e10002202450d002001420e3702a407200120023602a007200141a0076a41d79bc100410e102520014188046a220220012802a807360200200120012903a0073703800420014180046a41b7b6c1004103102520012802840421052001280280042207200228020010c401211202402005450d00200710010b024002400240201220064d0d00200621020340410e10002205450d022001420e3702a407200120053602a007200141a0076a41d79bc100410e102520014180046a41086a2205200141a0076a41086a2209280200360200200120012903a0073703800420014180046a41b7b6c1004103102520012802840421072001280280042208200528020010c401210302402007450d00200810010b0240200320024d0d00200120023602e805410e10002207450d042001420e3702a407200120073602a007200141a0076a41d79bc100410e102520052009280200360200200120012903a0073703800420014180046a200141e8056a4104102520012802840421072001280280042203200528020010082007450d00200310010b2012200241016a2202470d000b0b410e10002202450d032001420e3702a407200120023602a007200141a0076a41d79bc100410e102520014180046a41086a220220012802a807360200200120012903a0073703800420014180046a41b7b6c100410310252002280200210520012802840421072001280280042102200120063602a00720022005200141a0076a4104100302402007450d00200210010b200141e0036a41086a22024200370300200142003703e00341e59bc100411d200141e0036a1002200141c0036a41086a2002290300370300200120012903e0033703c003200141c0036a411010080c050b410e41011019000b410e41011019000b410e41011019000b410e41011019000b200141cc066a280200450d00201110010b200141e0036a41086a22024200370300200142003703e00341b9c2c0004114200141e0036a1002200141c0036a41086a2002290300370300200120012903e0033703c00302400240200141c0036a41104188f0c100410041001004417f460d00200142003703a007200141c0036a4110200141a0076a41084100100441016a41084d0d0a20012903a00722044200510d094200212520002004824200520d0e0c010b4200212520004201824200520d0d0b200141e0036a41086a22022025370300200120253703e00341cdc2c000410c200141e0036a1002200141c0036a41086a22052002290300370300200120012903e0033703c00302400240200141c0036a41104188f0c100410041001004417f460d00200142003703a807200142003703a007200141c0036a4110200141a0076a4110410010042207417f460d082007410f4d0d08200141a8076a290300210420012903a007210c0c010b4200210c420021040b200141b8076a2004370300200141a0076a41106a200c370300200141a0076a41086a41013a0000200141093a00a007200141a0076a10b40120024200370300200142003703e00341d9c2c0004112200141e0036a100220052002290300370300200120012903e0033703c003200141c0036a41104188f0c100410041001004417f460d09200142103702bc062001200141c0036a3602b806200141a0076a200141b8066a103b20012802a0072212450d05200120012902a407220a3702ec05200120123602e80541002103200141003602f005200aa72120200a422088a72205450d0a200141a0076a41096a2111200141a0056a211f20014180056a211e200141b8066a41086a2109200141e0046a41186a2115200141d8076a2121200141d0076a2116200141cc076a2122410021134100210341002114410021020340024002400240024002402014450d0020024102742107201220134102746a21190340200220054f0d03200141b8066a201220076a2206280200220810b90120012903b8064201520d02200141e0046a200941e00010f8021a200c20012903e004220b542004200141e0046a41086a290300220a542004200a511b450d05201320026a220320054f0d04201920076a2006280200360200200741046a2107410121032005200241016a2202470d000c120b0b201220024102746a21070340200220054f0d02200141b8066a2007280200220810b90120012903b8064201520d01200141e0046a200941e00010f8021a200c20012903e004220b5a2004200141e0046a41086a290300220a5a2004200a511b0d04200741046a2107410121032005200241016a2202470d000c100b0b2013417f6a2113201441016a2114200241016a22022005470d030c0f0b41b08dc20020022005104e000b41c08dc20020032005104e000b200241016a2102411210002207450d02200142123702a407200120073602a007200141a0076a4197e5c0004112102520012802a007211d02400240024020012802a4072206200141a0076a41086a221728020022076b41034b0d00200741046a22192007490d0420064101742218201920192018491b22184100480d042006450d01201810002219450d062019201d20182006200620184b1b10f8021a201d10010c020b201d2119200621180c010b201810002219450d040b201920076a2008360000200141e0036a41086a22064200370300200142003703e0032019200741046a200141e0036a1002200141c0036a41086a221d2006290300370300200120012903e0033703c003200141c0036a4110100802402018450d00201910010b201e200141e0046a41106a290300201529030010e102411410002207450d04200142143702a407200120073602a007200141a0076a41eeefc1004114102520014180046a41086a22072017280200360200200120012903a00737038004201f20014180046a101e20072802002119200128028404211820012802800421074200212620064200370300200142003703e00320072019200141e0036a1002201d2006290300370300200120012903e0033703c003024002400240200141c0036a41104188f0c100410041001004417f460d00200142003703a807200142003703a007200141c0036a4110200141a0076a4110410010042206417f460d082006410f4d0d082017290300212720012903a00721262004200a7d2104200c200b54ad21282018450d020c010b420021272004200a7d2104200c200b54ad21282018450d010b200710010b200420287d2104200c200b7d210c201f2026200b7c22282027200a7c2028202654ad7c10c2021a2021200a3703002016200b370300201741023a0000202220083602002011201f290000370000201141086a201f41086a290000370000201141106a201f41106a290000370000201141186a201f41186a290000370000200141093a00a007200141a0076a10b4012013417f6a2113201441016a211420022005470d000c0c0b0b1018000b411241011019000b201841011019000b411441011019000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41d8acc200104f000b41eac4c10041331042000b41002105200141003602f005200142043703e8054104211241002120410021030b410021140b200141f0056a200520146b360200200141e8056a10a00202402020450d00201210010b0240200341ff01710d00200141e0036a41086a22024200370300200142003703e00341ebc2c000410d200141e0036a1002200141c0036a41086a2002290300370300200120012903e0033703c00302400240200141c0036a41104188f0c100410041001004417f460d00200141003602a007200141c0036a4110200141a0076a41044100100441016a41044d0d0420013502a007210a0c010b4200210a0b200141186a200c2004200a420010fc02200141086a2001290318200141186a41086a29030042c0843d420010fb02200141a0076a41086a41033a0000200141b8076a2004200141086a41086a290300220a2001290308220b200c56200a200456200a2004511b22021b2226370300200141a0076a41106a200c200b20021b220a370300200141093a00a007200420267d200c200a54ad7d2104200c200a7d210c200141a0076a10b4010b200141b8076a2004370300200141a0076a41106a200c370300200141a0076a41086a41043a0000200141093a00a007200141a0076a10b401200120043703a8072001200c3703a007200141e0036a41086a22024200370300200142003703e00341cdc2c000410c200141e0036a1002200141c0036a41086a2002290300370300200120012903e0033703c003200141c0036a4110200141a0076a411010030b200141e0036a41086a22022025370300200120253703e00341d0b0c0004111200141e0036a1002200141c0036a41086a2002290300370300200120012903e0033703c003200141c0036a4110100820014190086a24000f0b41eac4c10041331042000bcd1405037f017e067f037e047f230041d0016b22012400200141b0016a41086a22024200370300200142003703b00141a3f2c1004111200141b0016a100220014190016a41086a22032002290300370300200120012903b0013703900120014190016a4110100820024200370300200142003703b00141c8f5c1004115200141b0016a100220032002290300370300200120012903b0013703900120014190016a41101008200141f0f1c100410d10a602200129030821042001280200210520024200370300200142003703b00141fdf1c1004111200141b0016a100220032002290300370300200120012903b00137039001024002400240024002400240024020014190016a41104188f0c100410041001004417f460d00200141c8016a4200370300200141b0016a41106a420037030020024200370300200142003703b00120014190016a4110200141b0016a4120410010042202417f460d022002411f4d0d02200141f0006a41186a2206200141b0016a41186a2203290300370300200141f0006a41106a2207200141b0016a41106a2208290300370300200141f0006a41086a2209200141b0016a41086a2202290300370300200120012903b00137037020024200370300200142003703b00141fdf1c1004111200141b0016a100220014190016a41086a220a2002290300370300200120012903b0013703900120014190016a41101008200320062903003703002008200729030037030020022009290300370300200120012903703703b00120014190016a41186a2003290300220b37030020014190016a41106a2008290300220c370300200a2002290300220d370300200141106a41086a200d370300200141106a41106a200c370300200141106a41186a200b370300200120012903b001220b370390012001200b3703100c010b200141b0016a41186a200141f0006a41186a290300370300200141b0016a41106a200141f0006a41106a2903003703002002200141f0006a41086a290300370300200120012903703703b001200141106a41186a4200370300200141106a41106a4200370300200141106a41086a4200370300200142003703100b4108210720014190016a41086a2202420037030020014200370390014190f3c100410d20014190016a1002200141b0016a41086a200229030037030020012001290390013703b0014100210202400240200141b0016a41104188f0c100410041001004417f460d00200142103702742001200141b0016a36027020014190016a200141f0006a10ea022001280290012207450d05200129029401210b20014190016a41086a2202420037030020014200370390014190f3c100410d20014190016a1002200141b0016a41086a200229030037030020012001290390013703b001200141b0016a41101008200b422088a72102200ba721090c010b410021090b200141b0016a41086a22034200370300200142003703b001418ef2c1004115200141b0016a100220014190016a41086a2003290300370300200120012903b001370390010240024020014190016a41104188f0c100410041001004417f460d00200141c8016a4200370300200141b0016a41106a420037030020034200370300200142003703b00120014190016a4110200141b0016a4120410010042203417f460d032003411f4d0d03200141f0006a41186a220a200141b0016a41186a2208290300370300200141f0006a41106a220e200141b0016a41106a2206290300370300200141f0006a41086a220f200141b0016a41086a2203290300370300200120012903b00137037020034200370300200142003703b001418ef2c1004115200141b0016a100220014190016a41086a22102003290300370300200120012903b0013703900120014190016a411010082008200a2903003703002006200e2903003703002003200f290300370300200120012903703703b00120014190016a41186a2008290300220b37030020014190016a41106a2006290300220c37030020102003290300220d370300200141306a41086a200d370300200141306a41106a200c370300200141306a41186a200b370300200120012903b001220b370390012001200b3703300c010b200141b0016a41186a200141f0006a41186a290300370300200141b0016a41106a200141f0006a41106a2903003703002003200141f0006a41086a290300370300200120012903703703b001200141306a41186a4200370300200141306a41106a4200370300200141306a41086a4200370300200142003703300b200141f0006a41186a22034200370300200141f0006a41106a22084200370300200141f0006a41086a2206420037030020014200370370200141f0006a100a200141d0006a41186a2003290300370300200141d0006a41106a2008290300370300200141d0006a41086a200629030037030020012001290370370350200141b0016a41186a220a200141106a41186a290300370300200141b0016a41106a220e200141106a41106a290300370300200141b0016a41086a220f200141106a41086a290300370300200120012903103703b001200342003703002008420037030020064200370300200142003703700240200141b0016a41202004420020051b2204427f7c200141f0006a1016450d0020014190016a41186a2205200329030037030020014190016a41106a2210200829030037030020014190016a41086a2211200629030037030020012001290370370390012003200529030037030020082010290300370300200620112903003703002001200129039001370370200a2003290300370300200e2008290300370300200f2006290300370300200120012903703703b001024020022009470d00200241016a22032002490d0420024101742208200320032008491b2209ad42287e220b422088a70d04200ba722034100480d0402402002450d00200310002208450d07200820072003200241286c2206200620034b1b10f802210320071001200321070c010b200310002207450d060b2007200241286c6a220341003a0000200341196a200141c8016a290300370000200341116a200141c0016a290300370000200341096a200141b8016a290300370000200320012903b001370001200341216a200128009001360000200341256a20014194016a2f00003b0000200341276a20014196016a2d00003a0000200241016a21020b2000200129031037001420002004370300200020012903503700342000412c6a200141106a41186a290300370000200041246a200141106a41106a2903003700002000411c6a200141106a41086a2903003700002000413c6a200141d0006a41086a290300370000200041c4006a200141d0006a41106a290300370000200041cc006a200141d0006a41186a290300370000200041ec006a200141306a41186a290300370000200041e4006a200141306a41106a290300370000200041dc006a200141306a41086a29030037000020002001290330370054200041106a20023602002000410c6a200936020020002007360208200141d0016a24000f0b41eac4c10041331042000b41eac4c10041331042000b1018000b41eac4c10041331042000b200341081019000b8e0301027f23004180026b22022400024002402001450d00200220003602000c010b20024188f0c1003602000b2002200136020420024188016a200210a6010240200228029001450d00200241086a20024188016a41f80010f8021a20024188016a200241086a41f80010f8021a20022903880120024188016a41146a200241dc016a10e601024020024188016a41106a2802002200450d002002280290012101200041286c21000340024020012d00002203450d00024020034101470d00200141086a280200450d01200141046a2802001001200141286a2101200041586a22000d020c030b200141146a280200450d00200141106a28020010010b200141286a2101200041586a22000d000b0b024020024194016a280200450d0020024190016a28020010010b20024180026a240042010f0b2002411c6a4101360200200241146a41013602002002410136028401200241fcd5c20036028001200241e0c3c1003602102002410136020c200241e4d5c200360208200220024180016a360218200241086a41ecd5c2001071000baf0902087f027e230041206b22022400200241003602182002420137031041a09fc1004105200241106a1064410c200241106a106541b0e8c200210303402003280200200341046a280200200241106a1064200241086a200328020811010020022802082104200228020c2205200241106a10652003410c6a210302402005450d002005412c6c2106410021070340200420076a220541046a280200200541086a280200200241106a1064200541106a2802002108024002402005410c6a2802004101470d002008200541186a280200200241106a10630c010b2008200541146a280200200241106a10630b200541206a280200210802402005411c6a2802004101470d002008200541286a280200200241106a106320062007412c6a2207470d010c020b2008200541246a280200200241106a106320062007412c6a2207470d000b0b200341c0e9c200470d000b410f200241106a106541d8752105200241186a2108024002400240024002400340200541ecf3c2006a280200200541f0f3c2006a280200200241106a1064200541f4f3c2006a200241106a1067024002400240024002400240024002400240200541a0f4c2006a22042802004102470d00200228021420082802002207470d01200741016a22042007490d0b20074101742206200420042006491b22064100480d0b2007450d0320022802102103200610002204450d0d2004200320062007200720064b1b10f8021a200310010c040b200228021420082802002207470d01200741016a22062007490d0a20074101742203200620062003491b22034100480d0a2007450d0520022802102109200310002206450d0d2006200920032007200720034b1b10f8021a200910010c060b200228021021040c030b200228021021060c050b200610002204450d090b2002200636021420022004360210200828020021070b2008200741016a360200200420076a41003a0000200541d8006a22050d030c040b200310002206450d070b2002200336021420022006360210200828020021070b2008200741016a360200200620076a41013a00002004200241106a1069200541d8006a22050d000b0b41e3f5c1004104200241106a1064410d200241106a106541947d2105200241186a21060340200541d8f6c2006a280200200541dcf6c2006a280200200241106a1064200541e4f6c2006a280200200541e8f6c2006a280200200241106a1064024002400240024020022802142204200628020022076b41024f0d00200741026a22082007490d0520044101742207200820082007491b22074100480d052004450d0120022802102103200710002208450d062008200320072004200420074b1b10f8021a200310010c020b200228021021080c020b200710002208450d040b2002200736021420022008360210200628020021070b2006200741026a360200200820076a200541ecf6c2006a2f01003b00002005411c6a22050d000b200241186a28020021072002280214210820022802102105200241003602182002420137031020052007200241106a108e012002350218210a2002350210210b02402008450d00200510010b200241206a2400200a422086200b840f0b1018000b200741011019000b200641011019000b200341011019000bf306010a7f230041c0056b22022400024002402001450d00200220003602100c010b20024188f0c1003602100b20022001360214200241d8036a200241106a10a7010240024002400240024002400240024020022903c8044203510d00200241186a200241d8036a41d80110f8021a200241f0016a200241186a41d80110f8021a2002200241f0016a3602d803200241c8036a200241d8036a10e80120022802cc03210320022802c803210420022802d0032105200241086a10f00120022802082106200228020c2107411410002201450d01200242143702dc03200220013602d803200241d8036a419df3c1004114102520022802d803210102400240024020022802dc03220820022802e00322006b41044f0d00200041046a22092000490d052008410174220a20092009200a491b220a4100480d052008450d01200a1000220b450d06200b2001200a20082008200a4b1b10f802210820011001200821010c020b200041046a21092008210a0c010b200a10002201450d040b200120006a2007410020061b360000200241003602e003200242013703d80320042005200241d8036a108e0120022802dc03210820022802e003210620022802d8032100200241d8036a41086a22074200370300200242003703d80320012009200241d8036a1002200241b0056a41086a2007290300370300200220022903d8033703b005200241b0056a411020002006100302402008450d00200010010b0240200a450d00200110010b02402003450d00200410010b200241d8036a200241f0016a41d80110f8021a200241b0056a200241d8036a200510e90120022802b4052201200141004720022802b00541014622001b2108410110002101024002402000450d002001450d06200141013a0000410210002200450d07200020012d00003a00000c010b2001450d07200141003a0000410210002200450d08200020012d00003a00000b20011001200020083a0001200241c0056a24002000ad428080808020840f0b20024184026a4101360200200241fc016a41013602002002410136021c20024184d6c200360218200241e0c3c1003602f801200241013602f401200241e4d5c2003602f0012002200241186a36028002200241f0016a41ecd5c2001071000b411441011019000b1018000b200a41011019000b410141011019000b410241011019000b410141011019000b410241011019000b7f01037f230041106b220124004100210202400240024041bef1c10041104188f0c100410041001004417f460d002001410036020c4101210241bef1c10041102001410c6a41044100100441016a41044d0d02200128020c21030c010b0b2000200336020420002002360200200141106a24000f0b41eac4c10041331042000bf90c04037f017e0a7f017e230041d0016b2202240010ea01200241186a41086a220342003703002002420037031841f0f1c100410d200241186a100220024190016a41086a220420032903003703002002200229031837039001420021050240024002400240024020024190016a41104188f0c100410041001004417f460d002002420037031820024190016a4110200241186a41084100100441016a41084d0d01200229031821050b200510eb0120044200370300200242003703900141c8f5c100411520024190016a1002200241c0016a41086a200429030037030020022002290390013703c00102400240024002400240024002400240200241c0016a41104188f0c100410041001004417f460d00410021062002410036021841042107200241c0016a4110200241186a41044100100441016a41044d0d0a20022802182208450d012008ad420c7e2205422088a70d022005a722044100480d02200410002207450d0b200241186a41086a2109200721034100210a0340411410002204450d042002421437021c20022004360218200241186a419df3c100411410252002280218210b024002400240200228021c220c200928020022046b41034b0d00200441046a22062004490d06200c410174220d20062006200d491b220d4100480d06200c450d01200d10002206450d0b2006200b200d200c200c200d4b1b10f8021a200b10010c020b200b2106200c210d0c010b200d10002206450d090b200620046a200a360000200241c0016a41086a220b4200370300200242003703c0012006200441046a220e200241c0016a10022009200b290300370300200220022903c00137031802400240024002400240200241186a41104188f0c100410041001004417f460d00200242103702a4012002200241186a3602a001200241106a200241a0016a10352002280210450d0c20022802142204417f4c0d0a2004450d0120041000220c450d0f200c4100200410f7021a0c020b410021044101210c4100210b200a41016a210a200d0d020c030b4101210c0b200241a0016a41086a220f200f280200220f2004410020022802a00120022802a401200c2004200f1004220f200f417f461b220f200f20044b1b6a3602002004200f4b0d08200c450d09200b4200370300200242003703c0012006200e200241c0016a100220024190016a41086a200b290300370300200220022903c0013703900120024190016a411010082004ad22054220862005842205422088a7210b2005a72104200a41016a210a200d450d010b200610010b2003200c360200200341086a200b360200200341046a20043602002003410c6a21032008200a470d000b200821060c010b41002106410421070b200241086a200720072006410c6c6a102e200241186a2002280208200228020c1045200241a0016a200228021822042002280220106b0240200228021c450d00200410010b02402006450d002006410c6c21032007210403400240200441046a280200450d00200428020010010b2004410c6a2104200341746a22030d000b2006450d00200710010b200241186a41186a200241a0016a41186a290300370300200241186a41106a2204200241a0016a41106a290300370300200241186a41086a2203200241a0016a41086a290300370300200220022903a00137031820024190016a41086a220642003703002002420037039001418ef2c100411520024190016a1002200241c0016a41086a200629030037030020022002290390013703c001200241c0016a4110200241186a41201003200241186a10ec01200241003602a801200242013703a001200241186a41146a200241a0016a101e2002290318200241a0016a109c01200241cc006a200241a0016a101e200241ec006a200241a0016a101e200241a0016a2003101f20023502a801210520023502a00121102002280220210a024020042802002204450d00200441286c2103200a21040340024020042d00002206450d00024020064101470d00200441086a280200450d01200441046a2802001001200441286a2104200341586a22030d020c030b200441146a280200450d00200441106a28020010010b200441286a2104200341586a22030d000b0b0240200241246a280200450d00200a10010b200241d0016a240020054220862010840f0b1018000b411441011019000b102c000b200c10010b41eac4c10041331042000b200d41011019000b41eac4c10041331042000b200441011019000b41eac4c10041331042000b200441041019000bd60d03027f037e0b7f230041b0046b22022400200242003703d002200241d0026a20004188f0c10020011b20014108200141084922001b220310f8021a0240024020000d00200120036b41074d0d0020022903d0022104200241d0026a41086a22014200370300200242003703d00241a0a5c100410d200241d0026a1002200241d8016a41086a22002001290300370300200220022903d0023703d80142002105024002400240200241d8016a41104188f0c100410041001004417f460d00200242003703d002200241d8016a4110200241d0026a41084100100441016a41084d0d0120022903d00221050b20014200370300200242003703d00241daa3c1004115200241d0026a100220002001290300370300200220022903d0023703d80102400240200241d8016a41104188f0c100410041001004417f460d00200242003703d002200241d8016a4110200241d0026a41084100100441016a41084d0d0320022903d002210641182101411810002207450d010c050b42052106411821014118100022070d040b200141081019000b41eac4c10041331042000b41eac4c10041331042000b200241e4026a4101360200200241dc026a4101360200200241013602dc012002418cd6c2003602d801200241e0c3c1003602d802200241013602d402200241e4d5c2003602d0022002200241d8016a3602e002200241d0026a41ecd5c2001071000b200742023703082007410036020020072004200620057c220520052004541b37031002400240024002400240024002400240024041e00110002208450d00200720016a2100410021034100210920082101024002400340200720036a220a41086a29030022044203510d01200a2903002105200141a0016a200a41106a29030037020020014198016a200437020020014190016a4100360200200141f8006a4202370200200120053e0200200141e0016a2101200941016a2109200341186a22034118470d000c020b0b200a41186a21000b2007411820006b6a2101024003402001450d01200141686a210120002903082104200041186a210020044203520d000b0b200710014100210b20082009410041202009676b10d601200941e0016c220141e0016d210c024002402001450d00200cad42d8017e2204422088a70d072004a722004100480d0720001000220d450d03200820016a22032008460d010c040b4108210d4100210c200820016a22032008470d030b200320082201470d030c040b41e00141081019000b200041081019000b200241d8026a210a4100210b20082101200d210002400340200241d8016a200141f80010f8021a200141f8006a2903002104200241f8006a20014180016a41e00010f8021a20044203510d01200241d0026a200241d8016a41f80010f8021a200241086a200a41f00010f8021a2000200241086a41f00010f802220041f0006a2004370300200041f8006a200241f8006a41e00010f8021a200041d8016a2100200b41016a210b200141e0016a22012003470d000b200320032201470d010c020b2003200141e0016a2201460d010b200241e0036a2100200241d0026a4180016a210a0340200241d0026a200141f80010f8021a200141f8006a2903002104200241086a20014180016a41e00010f8021a20044203510d01200241d8016a200241d0026a41f80010f8021a200241f8006a200241086a41e00010f8021a200241d0026a200241d8016a41f80010f8021a200241d0026a41f8006a2004370300200a200241f8006a41e00010f8021a20001028200141e0016a22012003470d000b0b20081001200241003602e001200242013703d801200b200241d8016a101b0240200b450d00200b41d8016c210e200241d8016a41086a220f280200210120022802dc012103200d210a03402002200a360208200241d0026a200241086a10e80120022802d00221080240024002400240200320016b200241d0026a41086a28020022094f0d00200120096a22002001490d0620034101742207200020002007491b22104100480d062003450d0120022802d8012111201010002207450d072007201120102003200320104b1b10f8021a201110010c020b200120096a210020022802d80121070c020b201010002207450d050b200220103602dc01200220073602d801201021030b200f2000360200200720016a2008200910f8021a024020022802d402450d00200810010b200a41d8016a210a20002101200e41a87e6a220e0d000b0240200b450d00200b41d8016c2103200d4188016a2101034020011028200141d8016a2101200341a87e6a22030d000b0b200c450d040c030b200241e0016a280200210020022802d8012107200c0d020c030b1018000b201041011019000b200d10010b200241b0046a24002000ad4220862007ad840bd21102097f057e230041b0016b22022400024002402001450d00200220003602000c010b20024188f0c1003602000b20022001360204200241086a200210a50102400240024002400240024002400240024020022802102203450d0020024188016a280200210420024184016a2802002105200241186a2802002106200241146a2802002107200228028001210820024200370308200241086a200228020022092002280204220141082001410849220a1b220010f8021a2002200120006b22013602042002200920006a22003602000240200a0d002002290308210b20024200370308200241086a20002001410820014108491b220910f8021a2002200120096b3602042002200020096a360200200141074d0d0002400240024002402004450d002008280288010d002008290390014202520d002002290308210c200829039801210d41012100200841f0006a2903004202520d01200241086a41086a220142003703002002420037030841a0a5c100410d200241086a100220024190016a41086a2209200129030037030020022002290308370390014200210e024020024190016a41104188f0c100410041001004417f460d002002420037030820024190016a4110200241086a41084100100441016a41084d0d072002290308210e0b200142003703002002420037030841daa3c1004115200241086a100220092001290300370300200220022903083703900120024190016a41104188f0c100410041001004417f460d022002420037030820024190016a4110200241086a41084100100441016a41084d0d072002290308210f200d200b423c7c580d030c080b02402006450d00200641286c2100200321010340024020012d00002209450d00024020094101470d00200141086a280200450d01200141046a2802001001200141286a2101200041586a22000d020c030b200141146a280200450d00200141106a28020010010b200141286a2101200041586a22000d000b0b02402007450d00200310010b02402004450d00200441d8016c210020084188016a2101034020011028200141d8016a2101200041a87e6a22000d000b0b421c210b4101210941eca0c100210a2005450d0c200810010c0c0b4224210b41a0b0c100210a0c070b4205210f200d200b423c7c560d050b0240200d200f200e7c220b5a0d004201210e0c070b410221000c050b2002411c6a4101360200200241146a4101360200200241013602940120024194d6c20036029001200241e0c3c1003602102002410136020c200241e4d5c200360208200220024190016a360218200241086a41ecd5c2001071000b200241a4016a41013602002002419c016a4101360200200241013602ac0120024194d6c2003602a801200241e0c3c100360298012002410136029401200241e4d5c200360290012002200241a8016a3602a00120024190016a41ecd5c2001071000b41eac4c10041331042000b41eac4c10041331042000b4225210b41c4b0c100210a0b2002200b37020c2002200a3602084200210e20004102460d002006450d020c010b024020044102490d0020082802e0024101470d0020082802e8024103470d00421e210b41ba8cc000210a20060d010c020b02402006450d00200641286c2100200321010340024020012d00002209450d00024020094101470d00200141086a280200450d01200141046a2802001001200141286a2101200041586a22000d020c030b200141146a280200450d00200141106a28020010010b200141286a2101200041586a22000d000b0b200e50210902402007450d00200310010b200b200b20091b210f200441d8016c210020084188016a2101034020011028200141d8016a2101200041a87e6a22000d000b02402005450d00200810010b200241086a41086a220142003703002002420037030841daa3c1004115200241086a100220024190016a41086a20012903003703002002200229030837039001024002400240024020024190016a41104188f0c100410041001004417f460d002002420037030820024190016a4110200241086a41084100100441016a41084d0d022002290308210b0c010b4205210b0b427f200b200b7c220e200e200b541b220b4200510d01410041aebdc100200d200b80220d200c5122011b210a02402009450d004102410120011b21094231210b0c050b200f423120011b210b200d200c5221090c040b41eac4c10041331042000b41a485c300104f000b200641286c2100200321010340024020012d00002209450d00024020094101470d00200141086a280200450d01200141046a2802001001200141286a2101200041586a22000d020c030b200141146a280200450d00200141106a28020010010b200141286a2101200041586a22000d000b0b02402007450d00200310010b200441d8016c210020084188016a2101034020011028200141d8016a2101200041a87e6a22000d000b02402005450d00200810010b200b42ffffffff0f83210b410121090b20024100360210200242013703084101100021010240024002400240024002400240024020094102470d002001450d02200242818080801037020c20022001360208200141003a0000428080808010210b0c010b2001450d02200242818080801037020c20022001360208200141013a0000410210002100024020094101470d002000450d04200020012d00003a000020011001200242828080802037020c20022000360208200041013a0001200a200ba7200241086a108e01200241106a350200422086210b200228020821010c010b2000450d04200020012d00003a000020011001200242828080802037020c20022000360208200041003a000102400240200228020c2209417e6a41074b0d0020094101742201410a2001410a4b1b22044100480d07200410002201450d082001200020042009200920044b1b10f8022109200010012002200436020c200220093602080c010b200021010b200241106a410a3602002001200b3700024280808080a001210b0b200241b0016a2400200b2001ad840f0b410141011019000b410141011019000b410241011019000b410241011019000b1018000b200441011019000bb90302077f037e230041e0006b22022400200241c0006a41086a220342003703002002420037034041a3f2c1004111200241c0006a1002200241086a2204200329030037030020022002290340370300024002400240200241104188f0c100410041001004417f460d00200241d8006a4200370300200241c0006a41106a4200370300200342003703002002420037034020024110200241c0006a4120410010042203417f460d022003411f4d0d02200241206a41186a2203200241c0006a41186a2204290300370300200241206a41106a2205200241c0006a41106a2206290300370300200241206a41086a2207200241c0006a41086a22082903003703002002200229034037032020042003290300220937030020062005290300220a37030020082007290300220b370300200241086a200b370300200241106a200a370300200241186a2009370300200220022903202209370340200220093703000c010b200241186a4200370300200241106a420037030020044200370300200242003703000b200241c0006a200210f501200235024821092002350240210a200241e0006a2400200a2009422086840f0b41eac4c10041331042000b6501017f0240412010002202450d00200042a080808080043702042000200236020020022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a2900003700000f0b412041011019000bc80c05027f017e017f017e077f230041a0076b22022400024002402001450d00200220003602080c010b20024188f0c1003602080b2002200136020c200241c8056a200241086a10a701024002400240024002400240024002400240024020022903b8064203510d00200241106a200241c8056a41d80110f8021a200241e8016a200241106a41d80110f8021a2002200241e8016a3602c004200241c8056a200241c0046a10e80120022802d0052100024020022802cc05450d0020022802c80510010b200241c8056a200241e8016a41d80110f8021a200241c0046a200241c8056a10f701024002400240024020022802c0044101470d004100210320022802c8044115470d01024020022802c4042201418987c200460d002001418987c200411510fa020d020b410221030c010b200241c0036a200241c0046a41086a41800110f8021a410021030240200241c0036a41086a410020022903c0034201511b2201450d002001450d002001200010f8010d00200110f9012104200141206a410020011b220529030022062004540d0041022103200620044280027c580d020b200241f0036a10fa010b200241003602d005200242013703c80502400240024020034101460d0020034102470d01410110002207450d0620024281808080103702cc05200220073602c805200741023a00000c020b41012100410110002201450d030c090b410110002207450d0520024281808080103702cc05200220073602c805200741003a00000b42808080801021040c080b02400240200420065a0d0041042109200241c8056a41086a210a410021074100210c410021080340200a2004370300200220013602c805200241c0046a200241c8056a10fb0102402008200c470d00200c41016a2203200c490d0c200c410174220b20032003200b491b220bad420c7e2206422088a70d0c2006a722034100480d0c02400240200c450d0020031000220d450d0a200d20092003200c410c6c220c200c20034b1b10f802210320091001200321090c010b200310002209450d090b200b210c0b200920076a220320022903c004370200200341086a200241c0046a41086a2802003602002007410c6a2107200841016a2108200442017c22042005290300540d000c020b0b4100210c41042109410021080b410c1000220a450d05200220013602c805200220052903003703d005200241c0046a200241c8056a10fb01200a41086a200241c0046a41086a280200360200200a20022903c004370200200241f0036a10fa01200241003602d005200242013703c8052000ad210441012103410121004101100022010d060b200020001019000b200241fc016a4101360200200241f4016a4101360200200241013602142002419cd6c200360210200241e0c3c1003602f001200241013602ec01200241e4d5c2003602e8012002200241106a3602f801200241e8016a41ecd5c2001071000b410141011019000b410141011019000b200341041019000b410c41041019000b20024281808080103702cc05200220013602c805200120003a0000410910002200450d02200020012d00003a0000200110012002428980808090013702cc05200220003602c805200020043700012008200241c8056a101b02402008450d0020092008410c6c6a21002009210103402001280200200141086a280200200241c8056a108e012001410c6a22012000470d000b0b4101200241c8056a101b200a280200200a280208200241c8056a108e01024002400240024020022802cc052200200241c8056a41086a28020022016b41084f0d00200141086a22072001490d0520004101742205200720072005491b22054100480d052000450d0120022802c805210b200510002207450d072007200b20052000200020054b1b10f8021a200b10010c020b20022802c80521070c020b200510002207450d050b200220053602cc05200220073602c8050b200241c8056a41086a200141086a2200360200200720016a427f3700002000ad422086210420034101470d0002402008450d002008410c6c21002009210103400240200141046a280200450d00200128020010010b2001410c6a2101200041746a22000d000b0b0240200c450d00200910010b0240200a41046a280200450d00200a28020010010b200a10010b200241a0076a240020042007ad840f0b1018000b410941011019000b200541011019000bdb1405017f037e017f037e057f230041a0046b2202240002400240200129037022034202520d00200220014188016a41d00010f8021a420021030c010b200241f0006a41206a200141286a280200360200200241f0006a41186a200141206a290200370300200241f0006a41106a200141186a290200370300200241f0006a41086a200141106a29020037030020022001290208370370200241d0016a200141e4006a290000370300200241c8016a200141dc006a29000037030020024198016a41286a200141d4006a29000037030020024198016a41206a200141cc006a29000037030020024198016a41186a200141c4006a29000037030020024198016a41106a2001413c6a29000037030020024198016a41086a200141346a2900003703002002200129002c3703980120012903002105200241d8016a41106a200141f0006a220641106a290300370300200241d8016a41086a200641086a290300370300200220062903003703d80120014180016a2903002107200129037821084200210920024190026a41086a22064200370300200242003703900241f0f1c100410d20024190026a1002200241086a200629030037030020022002290390023703004200210402400240024002400240024002400240200241104188f0c100410041001004417f460d0020024200370390022002411020024190026a41084100100441016a41084d0d0120022903900221040b024020034201520d002008500d022004200720072004541b2203200320077d2008827d21090b20024190026a200910e7012002418c026a41026a220620022d0092023a0000200241086a220a20024190026a41136a2900003703002002410d6a220b20024190026a41186a290000370000200220022f0190023b018c022002200229009b023703002002290093022103200241f0016a410d6a220c200b290000370000200241f0016a41086a220b200a290300370300200220022903003703f001200220053703900220024190026a41086a20014188016a41d00010f802210a20024183036a2003370000200241f8026a200241e8016a290300370300200241f0026a200241d8016a41086a29030037030020024182036a20062d00003a00002002418b036a20022903f00137000020024193036a200b29030037000020024190026a4188016a200c290000370000200220022903d8013703e802200220022f018c023b018003200241f0006a41086a28020021062002280274210120022d0070210b200241fc036a41026a220c20022d00733a0000200241e0036a41086a220d20024184016a290200370300200241e0036a410d6a220e20024189016a290000370000200220022f00713b01fc032002200241fc006a2902003703e003024002400240200b4101470d002002200141067610ce0220022802082001413f7122014d0d012002419c046a41026a220b2002280200220e20014105746a220141026a2d00003a000020024180046a41086a220c200141136a29000037030020024180046a410d6a220d200141186a290000370000200220012f00003b019c042002200129000b37038004200128000721062001280003210102402002280204450d00200e10010b200241026a200b2d0000220b3a0000200241136a200c2903002203370000200241186a200d2900002204370000200241dc036a41026a200b3a0000200241d0006a41086a2003370300200241d0006a410d6a20043700002002200636000720022001360003200220022f019c04220b3b01002002200229038004220337000b2002200b3b01dc03200220033703504100210b0c020b200241026a200c2d0000220b3a0000200241136a200d2903002203370000200241186a200e2900002204370000200241dc036a41026a200b3a0000200241d0006a41086a2003370300200241d0006a410d6a20043700002002200636000720022001360003200220022f01fc03220b3b0100200220022903e003220337000b2002200b3b01dc03200220033703504100210b0c010b02402002280204450d00200228020010010b4101210b41152106418987c20021010b200241d8036a41026a220c200241dc036a41026a2d00003a0000200241c0036a41086a220d200241d0006a41086a290300370300200241c0036a41106a200241d0006a41106a290300370300200220022f01dc033b01d803200220022903503703c003024002400240200b450d002000200136020420004101360200200041086a20063602000c010b200241b3036a200d290300370000200241b8036a200241cd036a290000370000200220022f01d8033b01a003200220063600a703200220013600a303200220022903c0033700ab032002200c2d00003a00a20320024100360208200242013703002002290390022103410810002201450d0420024108360204200241086a22062006280200220b41086a360200200220013602002001200b6a2003370000200a2002101c02400240024002400240024002400240024020022903e8024201520d00200241f0026a2903002203420c882204420120044201561b22044200510d0f200241f8026a29030020048021042002280204220b200241086a28020022016b41024f0d01200141026a22062001490d0e200b4101742201200620062001491b22014100480d0e200b450d052002280200210c200110002206450d112006200c2001200b200b20014b1b10f8021a200c10010c060b0240200228020420062802002201470d00200141016a22062001490d0e2001410174220b20062006200b491b220b4100480d0e2001450d022002280200210c200b10002206450d102006200c200b20012001200b4b1b10f8021a200c10010c030b200228020021060c030b200228020021060c050b200b10002206450d0d0b2002200b36020420022006360200200241086a28020021010b200241086a200141016a360200200620016a41003a00000c030b200110002206450d0b0b2002200136020420022006360200200241086a28020021010b200241086a200141026a360200200620016a2004a741047420037aa7417f6a22014101200141014b1b2201410f2001410f491b723b00000b20024180036a2002101e200228020421012002280200220b200241086a28020020024198016a200241a0036a100f210602402001450d00200b10010b2006450d01200041ccb7c10036020420004101360200200041086a411a3602000b200a10fa01200241a0046a24000f0b200241d0006a41186a200241a0036a41186a290300370300200241d0006a41106a200241a0036a41106a290300370300200241d0006a41086a200241a0036a41086a290300370300200220022903a00337035020022903900221042002200a41d00010f8021a420121030c070b41eac4c10041331042000b41a090c200104f000b410841011019000b1018000b418cacc300104f000b200b41011019000b200141011019000b200041086a2003370300200041306a2004370300200041106a2002290350370300200041186a200241d0006a41086a290300370300200041206a200241d0006a41106a290300370300200041286a200241d0006a41186a290300370300200041386a200241d00010f8021a20004100360200200241a0046a24000bf00904057f017e017f087e230041c0006b22022400024002400240411410002203450d002002421437023420022003360230200241306a41eeefc10041141025200241206a41086a22032002280238360200200220022903303703202000200241206a101e20032802002104200228022421052002280220210642002107200241306a41086a220842003703002002420037033020062004200241306a1002200320082903003703002002200229033037032002400240200241206a41104188f0c100410041001004417f460d002002420037033820024200370330200241206a4110200241306a4110410010042203417f460d012003410f4d0d01200241386a2903002109200229033021072005450d040c030b4200210920050d020c030b41eac4c10041331042000b411441011019000b200610010b4200210a200241306a41086a22034200370300200242003703304188f0c100411b200241306a1002200241206a41086a2206200329030037030020022002290330370320024002400240024002400240200241206a41104188f0c100410041001004417f460d002002420037033820024200370330200241206a4110200241306a4110410010042204417f460d022004410f4d0d02200241386a290300210b2002290330210c0c010b4200210c4200210b0b200342003703002002420037033041a3f0c100411b200241306a1002200620032903003703002002200229033037032002400240200241206a41104188f0c100410041001004417f460d002002420037033820024200370330200241206a4110200241306a4110410010042203417f460d032003410f4d0d03200241386a290300210d2002290330210a0c010b4200210d0b4200210e2002200a200d2001ad420010fc02200241306a41086a220342003703002002420037033041bef0c100411b200241306a1002200241206a41086a200329030037030020022002290330370320200241086a290300210f2002290300210d02400240200241206a41104188f0c100410041001004417f460d002002420037033820024200370330200241206a4110200241306a4110410010042203417f460d042003410f4d0d04200241386a29030021102002290330210e0c010b420021100b41eff0c100210302402007200e200d200c7c220a7c220c5420092010200f200b7c200a200d54ad7c220d7c200c200e54ad7c220e542009200e511b0d0020002007200a7d2009200d7d2007200a54ad7d10aa0142002107200241306a41086a220342003703002002420037033041d9f0c1004116200241306a1002200241206a41086a2003290300370300200220022903303703204100210302400240200241206a41104188f0c100410041001004417f460d002002420037033820024200370330200241206a4110200241306a4110410010042206417f460d062006410f4d0d06200241386a290300210e200229033021070c010b4200210e0b2007200a7d2209200756200e200d7d2007200a54ad7d220a200e56200a200e511b0d00200220093703102002200a370318200241306a41086a220642003703002002420037033041d9f0c1004116200241306a1002200241206a41086a200629030037030020022002290330370320200241206a4110200241106a411010030b200241c0006a240020030f0b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b8c0203047f017e017f230041206b220124000240411310002202450d002001421337021420012002360210200141106a41abf1c10041131025200141086a220220012802183602002001200129031037030020002001101e20022802002103200128020421042001280200210042002105200141106a41086a220642003703002001420037031020002003200141106a1002200220062903003703002001200129031037030002400240200141104188f0c100410041001004417f460d002001420037031020014110200141106a41084100100441016a41084d0d01200129031021050b02402004450d00200010010b200141206a240020050f0b41eac4c10041331042000b411341011019000b880301017f0240024002400240024002400240024002400240024020002802002201410b4b0d0020010e0c0a010a0a0a02030405060a070a0b20002d00044102470d092000410c6a280200450d09200041086a28020010010f0b200041086a10290f0b200041086a2d000022014105460d0520014102470d072000410c6a220028020010fa01200028020010010f0b200041086a2802004102470d06200041106a280200450d062000410c6a28020010010f0b200041086a2d00004102470d052000410c6a220028020010fa01200028020010010f0b20002d00044102470d042000410c6a220028020010fa01200028020010010f0b20002802044102490d032000410c6a280200450d03200041086a28020010010f0b200041086a2d000022014102490d0220014102470d01200041306a280200450d022000412c6a28020010010f0b2000410c6a220028020010fa01200028020010010f0b0240200041106a280200450d002000410c6a28020010010b2000411c6a280200450d00200041186a28020010010f0b0bcc0102057f017e2001280200210202400240412010002203450d0020032002290000370000200341186a2204200241186a290000370000200341106a2205200241106a290000370000200341086a2206200241086a2900003700002001290308210741c00010002202450d0120022003290000370000200241186a2004290000370000200241106a2005290000370000200241086a200629000037000020031001200042c0808080800537020420002002360200200220073700200f0b412041011019000b41c00041011019000ba40803067f017e017f230041d0006b22022400024002402001450d00200220003602180c010b20024188f0c1003602180b2002200136021c200241c0006a200241186a10fd010240024002400240024020022802402203450d0020022802442104200241106a20032003200241c8006a280200220541286c6a102e200228021421062002280210210102400240034020062001460d0120012d00002100200141286a2207210120004102470d00200741606a2903002108200241086a200741686a28020022012001200741706a28020041286c6a102e20022002280208200228020c102e200241286a2002280200200228020410442002200229022c3703400240200228022822090d00200721010c010b0b200241346a2002290340370200200241286a41146a200241c0006a41086a280200360200200220093602302002200837032802402005450d00200541286c2100200321010340024020012d00002207450d00024020074101470d00200141086a280200450d01200141046a2802001001200141286a2101200041586a22000d020c030b200141146a280200450d00200141106a28020010010b200141286a2101200041586a22000d000b0b200241286a41086a21002004450d01200310010c010b410021092002410036023002402005450d00200541286c2100200321010340024020012d00002207450d00024020074101470d00200141086a280200450d01200141046a2802001001200141286a2101200041586a22000d020c030b200141146a280200450d00200141106a28020010010b200141286a2101200041586a22000d000b0b200241286a41086a210002402004450d0020031001410021090b0b20024100360248200242013703404101100021010240024002400240024002402009450d002001450d07200141013a0000200242818080801037024420022001360240200241c0006a2000102220022802442206200241c0006a41086a28020022076b41084f0d01200741086a22002007490d0820064101742201200020002001491b22034100480d082006450d0220022802402105200310002201450d0a2001200520032006200620034b1b10f8021a200510010c030b2001450d08200141003a0000200242818080801037024420022001360240410121000c040b200741086a2100200228024021010c020b200310002201450d070b20022003360244200220013602400b200241c8006a2000360200200120076a2008370000200241346a280200450d00200910010b200241d0006a24002000ad4220862001ad840f0b2002413c6a4101360200200241346a410136020020024101360224200241a4d6c200360220200241e0c3c1003602302002410136022c200241e4d5c2003602282002200241206a360238200241286a41ecd5c2001071000b410141011019000b1018000b410141011019000b200341011019000bdb190a027f027e117f027e017f027e037f017e077f017e230041d0026b22022400200241086a2001103a024002400240024002400240024002402002280208450d00200228020c2203ad220442287e2205422088a70d042005a72206417f4c0d04024002400240024002402006450d00200610002207450d0a20030d010c020b410821072003450d010b200241c7016a2108200241f8006a41116a2109200241b8016a41106a2106200241b8016a410172210a200241106a410172210b200141046a210c20024188026a41026a210d200241b8016a41076a210e20024180026a210f410021100340200c2802002111200241003a00b801200241b8016a200128020022122011410047221310f8021a20112013490d06200c201120136b22143602002001201220136a22133602000240024002400240024002400240024002400240024002402011450d004104211220022d00b801221141034b0d0b024020110e0400040203000b20022001103a2002280200450d0b20022802042211417f4c0d142011450d08201110002215450d1620154100201110f7021a0c090b410421120c0a0b200241b8016a2014412020144120491b22116a41004100412020116b2011411f4b1b10f7021a200241b8016a2013201110f8021a200c201420116b3602002001201320116a3602002014411f4d0d04200241c0026a41026a200241b8016a41026a2d00003a000020024188026a41086a200841086a29000037030020024188026a41106a200841106a2d00003a0000200220022f00b8013b01c0022002200829000037038802200241b8016a41036a2800002116200e2900002117410121110c050b200242003703b801200241b8016a20132014410820144108491b221510f8021a200c201420156b22113602002001201320156a2215360200201441074d0d0120022903b8012118200241b8016a201141c000201141c000491b22136a4100410041c00020136b2013413f4b1b10f7021a200241b8016a2015201310f8021a200c201120136b3602002001201520136a3602002011413f4d0d0120024188026a41086a200841086a29000037030020024188026a41106a200841106a29000037030020024188026a41186a200841186a29000037030020024188026a41206a200841206a29000037030020024188026a41286a200841286a29000037030020024188026a41306a200841306a2d00003a0000200220022f00b8013b01c00220022008290000370388022002200241b8016a41026a2d00003a00c202200241b8016a41036a2800002119200e290000211a410121112018211b0c020b200241b8016a2001103920022802b8012211450d0720022902bc012105200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a2006290300370300200241f8006a41186a200241b8016a41186a290300370300200241f8006a41206a200241b8016a41206a290300370300200241f8006a41286a200241b8016a41286a290300370300200241f8006a41306a200241b8016a41306a2903003703002002200d2d00003a00b201200220022f0088023b01b001200220022903b801370378410021122011211c0c060b410021110b200241b8016a41086a221320024188026a41086a290300370300200620024188026a41106a290300370300200241b8016a41186a221420024188026a41186a290300370300200241b8016a41206a221520024188026a41206a290300370300200241b8016a41286a221d20024188026a41286a290300370300200241b8016a41306a221e20024188026a41306a2d00003a0000200220022d00c2023a00ca02200220022f01c0023b01c80220022002290388023703b8012011450d05200241f8006a41086a2013290300370300200241f8006a41106a2006290300370300200241f8006a41186a2014290300370300200241f8006a41206a2015290300370300200241f8006a41286a201d290300370300200241f8006a41306a201e2d00003a0000200220022d00ca023a00b201200220022f01c8023b01b001200220022903b801370378410221122019211c201a2105201b211f0c050b410021110b200241c8026a41026a2214200241c0026a41026a2d00003a0000200241b8016a41086a221320024188026a41086a290300370300200620024188026a41106a2d00003a0000200220022f01c0023b01c80220022002290388023703b8012011450d03200241f8006a41086a2013290300370300200241f8006a41106a20062d00003a0000200220022f01c8023b01b001200220022903b801370378200220142d00003a00b2012009411f6a200241b8016a411f6a290000370000200941186a200241b8016a41186a290000370000200941106a2006290000370000200941086a2013290000370000200920022900b801370000410121122016211c201721050c020b410121150b20152001280200200c2802002214201120142011491b221310f8022115200c280200221d2013490d0d200c201d20136b3602002001200128020020136a3602000240201420114f0d00201510010c020b2015450d012011ad22054220862005842105200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a2006290300370300200241f8006a41186a200241b8016a41186a290300370300200241f8006a41206a200241b8016a41206a290300370300200241f8006a41286a200241b8016a41286a290300370300200241f8006a41306a200241b8016a41306a290300370300200220022f0088023b01b001200220022903b8013703782002200d2d00003a00b201410321122015211c0b0b200d20022d00b2013a0000200241b8016a41086a2211200241f8006a41086a22142903003703002006200241f8006a41106a2215290300370300200241b8016a41186a2213200241f8006a41186a221d290300370300200241b8016a41206a221e200241f8006a41206a290300370300200241b8016a41286a2220200241f8006a41286a290300370300200241b8016a41306a2221200241f8006a41306a290300370300200220022f01b0013b018802200220022903783703b80120124104460d02200241f4006a41026a2222200d2d00003a0000200241386a41086a22232011290300370300200241386a41106a22242006290300370300200241386a41186a22252013290300370300200241386a41206a2226201e290300370300200241386a41286a221e2020290300370300200241386a41306a22202021290300370300200220022f0188023b0174200220022903b80137033820112005370300200a20022f01743b0000200a41026a20222d00003a000020062002290338370000200641086a2023290300370000200641106a2024290300370000200641186a2025290300370000200641206a2026290300370000200641286a201e290300370000200641306a2020290300370000200220123a00b8012002201c3602bc01200f201f370300200241106a200241b8016a10d60220022d00102112200241b8016a411f6a221e200b411f6a2900003700002013200b41186a2900003703002006200b41106a2900003703002011200b41086a2900003703002002200b2900003703b80120124103460d03200241f8006a411f6a2220201e290000370000201d20132903003703002015200629030037030020142011290300370300200220022903b80137037802402004422088a722112004a7470d00201141016a22132011490d062011410174221e20132013201e491bad221842287e2227422088a70d062027a722134100480d06024002402011450d0020131000221e450d0a201e20072013201141286c2211201120134b1b10f802211120071001201121070c010b201310002207450d090b20044280808080708320188421040b20072004422088a741286c6a221120123a0000201141206a2020290000370000201141196a201d290300370000201141116a2015290300370000201141096a20142903003700002011200229037837000120044280808080107c2104201041016a22102003490d000b0b2007450d022000200437020420002007360200200241d0026a24000f0b200241033a0010200241b8016a411f6a200b411f6a290000370000200241b8016a41186a200b41186a290000370300200241b8016a41106a200b41106a290000370300200241b8016a41086a200b41086a2900003703002002200b2900003703b8010b02402004422088a72206450d00200641286c2111200721060340024020062d0000220b450d000240200b4101470d00200641086a280200450d01200641046a2802001001200641286a2106201141586a22110d020c030b200641146a280200450d00200641106a28020010010b200641286a2106201141586a22110d000b0b2004a7450d00200710010b20004100360200200241d0026a24000f0b1018000b20132011107a000b201341081019000b102c000b200641081019000b201141011019000b2013201d107a000bc004020b7f017e230041206b22022400200210ff0120024100360218200242013703102002280200210320022802082204200241106a101b0240024002400240024002402004450d002003200441286c6a2105200241106a41086a22062802002107200228021421082003210403400240024002400240200820076b41204f0d00200741206a22092007490d062008410174220a20092009200a491b220a4100480d062008450d012002280210210b200a1000220c450d07200c200b200a20082008200a4b1b10f8021a200b10010c020b200741206a21092002280210210c2008210a0c020b200a1000220c450d050b2002200a3602142002200c3602100b20062009360200200c20076a220741186a200441186a290000370000200741106a200441106a290000370000200741086a200441086a29000037000020072004290000370000200441206a290300210d0240024002400240200a20096b41084f0d00200941086a22072009490d06200a4101742208200720072008491b22084100480d0620081000210b200a450d01200b450d08200b200c2008200a200a20084b1b10f8021a200c10010c020b200941086a2107200c210b200a21080c020b200b450d060b200220083602142002200b3602100b20062007360200200b20096a200d3700002005200441286a2204470d000b2002280204450d050c040b200241186a28020021072002280210210b20022802040d030c040b1018000b200a41011019000b200841011019000b200310010b200241206a24002007ad422086200bad840b940101047f230041206b220124000240410e10002202450d002001420e37021420012002360210200141106a41d79bc100410e1025200141086a2202200128021836020020012001290310370300200141b7b6c100410310252001280204210320012802002204200228020010c401210202402003450d00200410010b2000410020021041200141206a24000f0b410e41011019000bd10102027f027e230041206b22022400200241106a41086a220342003703002002420037031041daa3c1004115200241106a1002200241086a200329030037030020022002290310370300024002400240200241104188f0c100410041001004417f460d002002420037031020024110200241106a41084100100441016a41084d0d02200229031021040c010b420521040b200241106a427f200420047c220520052004541b1088012002350218210420023502102105200241206a240020052004422086840f0b41eac4c10041331042000b5201027e02402003450d0020022802000d002001280224220342002003290308220420023502047d220520052004562005507222021b37030820004105410420021b3602000f0b41ff80c10041f4031042000bbe0702067f017e230041b0016b22042400024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d03200241146a2802002105200241246a2802002106200241346a2802002107200441106a200120022802044120108302024002400240024020042802102208450d00200441186a2802002103200428021421092005450d01200441106a20012006200710830220042802102205450d032004290214210a2003417f4a0d020c080b410521020c0a0b410021052003417f4c0d060b20012802002802002102024002402003450d002003100022010d01200341011019000b410121010b200441003602182004200336021420042001360210200441106a200820031025200441086a20042802183602002004200429031037030020022802000d062002417f360200200441c8006a41186a2203200241c4006a290000370300200441c8006a41106a22012002413c6a290000370300200441c8006a41086a200241346a2900003703002004200229002c370348200441106a200241046a200441c8006a10df010240024020042802104101470d00200441186a2802002103200441106a41106a28020021012004420037028401200441e8bdc000360280012003200141306c6a41e8026a2103200441c8006a20044180016a10cb01200441c8006a10cc010c010b200441f8006a200441106a41346a280200360200200441c8006a41286a2004413c6a290200370300200441e8006a200441346a29020037030020032004412c6a2902003703002001200441246a290200370300200441c8006a41086a2004411c6a2902003703002004200429021437034820044180016a41186a410036020020044180016a41106a420037030020044180016a41086a420037030020044180016a41286a42003703002004420037038001200441e8bdc0003602a401200441c8006a20044180016a10e20121030b20044180016a41086a200441086a28020036020020042004290300370380012004200a37024c20042005360248200441106a200341246a20044180016a200441c8006a10e00102402004280210450d0020042802142203450d00200441186a280200450d00200310010b2002200228020041016a360200410421022009450d080c070b4105210220090d060c070b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b102c000b108402000b200810010b20002002360200200441b0016a24000b880202027f027e230041206b220424002004200128021c29031842002003ad420010fc02024020042903084200510d0020004100360200200441206a24000f0b2001280224220542002005290308220620042903007d220720072006562007507222051b37030802402005450d0020004100360200200441206a24000f0b2004410036021820044201370310200441106a200310270240024020012802202802082002200428021022032004280218100b2201417e460d0020010d0120002004290310370200200041086a200441106a41086a280200360200200441206a24000f0b2000410036020002402004280214450d00200310010b200441206a24000f0b41d08dc200104f000b900101017f230041c0006b220024002000411036020c200041fb9dc100360208200041286a410c6a410e360200200041246a4102360200200041106a410c6a41023602002000410136022c2000418489c20036021820004102360214200041a4aec3003602102000200041386a3602302000200041086a3602282000200041286a360220200041106a41b4aec3001071000b810301067f230041306b220424000240024002402003450d0020022802000d00200441206a2001200228020441201083020240024020042802202203450d00200428022421052004200128020028020022022002412c6a2003200441206a41086a220228020010860220042802002206450d01200441106a41086a200441086a2207280200360200200420042903003703102002200728020036020020042004290300370320200141106a21020240200141146a280200450d00200228020010010b20022004290320370200200241086a200441206a41086a28020036020041002101410121072005450d040c030b20004105360200200441306a24000f0b41002107410021080240200141186a22092802002202450d00410021010340200141016a22012002490d000b200220016b21080b200920083602004101210120050d010c020b41ff80c10041f4031042000b200310010b02402007200645720d002004280204450d00200610010b2000410036020020002001360204200441306a24000b860401087f230041306b220524000240200128020022064100480d00200641ffffffff07460d002001200641016a36020002400240200141046a200210de012206450d0020062802282107200541286a2108200641246a22092106034020062802002106200820093602002005200636022420052007360220200541086a200541206a10a10120052802082206200528020c410c6c6a210b4180012107417f210a024003400240024002402006200b460d002006450d0002402003200628020020062802082209200420092004491b10fa02220c450d002007410c6a2107417f4101200c4100481b2209450d020c030b2007410c6a21074100417f4101200920044b1b20092004461b22090d020c010b2005200541206a10a1012005280204210a0c030b200528022420076a2206450d04024002402006280200450d00200541206a2006102b0c010b200541003602200b200541106a41086a2206200541206a41086a28020036020020052005290320370310200041086a2006280200360200200020052903103702000c050b2006410c6a2106200a41016a210a20094101460d000b0b20052802202206450d01200828020021092006417f6a21072005280224200a4102746a4190026a21060c000b0b20002001280210200220032004200141146a28020028020c1103000b20012001280200417f6a360200200541306a24000f0b10c602000bec0804017f017e077f037e230041a0016b2204240002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d06200241286a2903002105200241346a2802002106200241c4006a2802002107200241d4006a2802002108200241e4006a280200210920044180016a20012002280204200241146a2802001083020240024002402004280280012203450d00200428028401210a20044180016a20044180016a41086a220b280200220241202002412049220c1b22026a41004100412020026b2002411f4b1b10f7021a20044180016a2003200210f8021a02400240200c0d00200441106a41186a20044180016a41186a290000370300200441106a41106a20044180016a41106a290000370300200441106a41086a200b29000037030020042004290080013703100240200a450d00200310010b20044180016a2001200620071083022004280280012203450d0220044188016a2207280200210220042802840121062004420037038801200442003703800120044180016a20032002411020024110491b10f8021a2002410f4d0d012007290300210d200429038001210e02402006450d00200310010b20044180016a200120082009108302200428028001450d02200441306a41086a20044180016a41086a2802003602002004200429038001370330200141186a22062802002203450d03410021020340200241016a22022003490d000b200320026b21020c040b200a450d01200310010c010b2006450d00200310010b20004105360200200441a0016a24000f0b410021020b2006200236020041012102024020012802242203290308220f200f20052005501b2205540d00200341086a2206200f20057d3703002003290310210f200441c0006a41186a200341186a29030037030020042005370348200420053703402004200f3703502004280230210320042802382107200441e0006a41186a2001280200280200220241c4006a290000370300200441e0006a41106a2002413c6a290000370300200441e0006a41086a200241346a2900003703002004200229002c37036020044180016a41186a200441106a41186a29030037030020044180016a41106a200441106a41106a29030037030020044180016a41086a200441106a41086a2903003703002004200429031037038001200441086a2002200441e0006a20044180016a200e200d200441c0006a20032007200141106a108802200428020821022006200429034820062903007c370300200241004721020b02402004280234450d00200428023010010b2000410036020020002002360204200441a0016a24000f0b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000be20702027f027e230041a0016b220a240002400240024020012802182001280228220b28028001470d0041a6b8c1002103412921010c010b200642002006290308220c200b2903707d220d200d200c56200d5072220b1b3703080240200b450d0041cfb8c1002103412321010c010b2001280200220b4100480d01200b41ffffffff07460d012001200b41016a360200024002400240200141046a200310de01220b450d00200b280218450d00200a41186a200b41186a102b200a280218450d01200a41086a41086a200a41186a41086a280200360200200a200a2903183703080c020b200a41003602180b200a41086a20012802102003200141146a2802002802101104000b20012001280200417f6a360200200a413c6a4100360200200a412c6a41b084c300360200200a41186a41086a4200370300200a41cc006a200341086a290000370200200a41d4006a200341106a290000370200200a41dc006a200341186a290000370200200a4208370234200a2001360228200a41e8bdc00036021c200a4100360218200a2003290000370244200a200141286a280200360240200a200141186a28020041016a360230024002402004200584500d00200a200641002001412c6a200320042005200a41186a10e302200a2802002203450d00200a28020421010c010b02400240200a2802102203450d00200a280208210b200a41f4006a200241086a290000370200200a41fc006a200241106a290000370200200a4184016a200241186a290000370200200a200229000037026c200141286a2802002102200a200a41186a360268200b2003200720082009200a41e8006a2002200610e40241ff01714108470d010b200a41e8006a41086a2206200a41186a41086a220b290300370300200a4190016a41086a2202200a41f4006a280200360200200a200a290318370368200a200a29026c37039001200a41386a2802002107200a41186a411c6a2802002103200a413c6a280200210820062002280200360200200a200a29039001370368200b2006280200360200200a200a2903683703182001200a41186a10c702200a2003200841d8006c6a360224200a2003360220200a200736021c200a20033602182001411c6a200a41186a10170240200a28020c450d00200a28020810010b410021030c020b41f2b8c1002103412421010b200a4190016a41086a200a41186a410472220641086a280200360200200a200629020037039001200a41e8006a200a4190016a10cf01200a41e8006a10d0010240200a41386a280200450d00200a41346a28020010010b200a28020c450d00200a28020810010b2000200136020420002003360200200a41a0016a24000f0b10c602000be80805017f017e037f037e047f23004190016b220424000240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d06200241286a2903002105200241346a2802002103200241c4006a2802002106200241d4006a2802002107200241e4006a2802002108200441c8006a20012002280204200241146a2802001083020240024002402004280248450d00200441086a41086a200441c8006a41086a220228020036020020042004290348370308200441c8006a200120032006108302024020042802482203450d0020022802002102200428024c21062004420037035020044200370348200441c8006a20032002411020024110491b10f8021a02402002410f4d0d00200441d0006a29030021092004290348210a02402006450d00200310010b200441c8006a2001200720081083022004280248450d01200441186a41086a200441c8006a41086a28020036020020042004290348370318200141186a22062802002203450d03410021020340200241016a22022003490d000b200320026b21020c040b2006450d00200310010b200428020c450d00200428020810010b2000410536020020044190016a24000f0b410021020b200620023602000240024020012802242202290308220b200b20052005501b2205540d00200241086a2203200b20057d3703002002290310210b200441286a41186a200241186a29030037030020042005370330200420053703282004200b3703382004280208210620042802102107200428021821082004280220210c200441f0006a41186a220d2001280200280200220241c4006a29000037030020044180016a220e2002413c6a290000370300200441f0006a41086a220f200241346a2900003703002004200229002c370370200441c8006a2002200441f0006a200a2009200441286a200620072008200c108a0241012102024020042d00484101460d00200d200441e1006a290000370300200e200441d9006a290000370300200f200441d1006a29000037030020042004290049370370410021020b2003200441286a41086a29030020032903007c3703002002450d010b41012102200428021c450d090c080b200441c8006a41186a200441f0006a41186a290300370300200441c8006a41106a200441f0006a41106a290300370300200441c8006a41086a200441f0006a41086a29030037030020042004290370370348200441c8006a200141106a101e41002102200428021c0d070c080b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b200428021810010b0240200428020c450d00200428020810010b200041003602002000200236020420044190016a24000bbf1103027f027e057f230041c0026b220a2400024020012802182001280228220b28028001470d00200041013a0000200041086a4124360200200041046a41c5b9c100360200200a41c0026a24000f0b200542002005290308220c200b2903787d220d200d200c56200d5072220b1b3703080240200b450d00200041013a0000200041086a4125360200200041046a41e9b9c100360200200a41c0026a24000f0b200a41306a41186a220b4200370300200a41306a41106a220e4200370300200a41306a41086a220f4200370300200a420037033020062007200a41306a100d200a41d8016a41186a200b290300370300200a41d8016a41106a200e290300370300200a41d8016a41086a200f290300370300200a200a2903303703d801200b4200370300200e4200370300200f4200370300200a420037033020082009200a41306a100d200a41a0016a41186a200b290300370300200a41a0016a41106a200e290300370300200a41a0016a41086a200f290300370300200a200a2903303703a001200a410036029802200a420137039002200a4190026a200a41d8016a41201025200a4190026a200a41a0016a41201025200a4190026a2001412c6a221041201025200a280298022111200a280290022112200b4200370300200e4200370300200f4200370300200a420037033020122011200a41306a100d200a41106a41186a200b290300370300200a41106a41106a200e290300370300200a41106a41086a200f290300370300200a200a2903303703100240200a28029402450d00201210010b024002402001280200220b4100480d00200b41ffffffff07460d002001200b41016a360200024002400240200141046a200a41106a10de01220b450d00200b280218450d00200a41306a200b41186a102b200a280230450d01200a41a0016a41086a200a41306a41086a280200360200200a200a2903303703a0010c020b200a41003602300b200a41a0016a2001280210200a41106a200141146a2802002802101104000b20012001280200417f6a360200200a2802a801210b0240200a2802a401450d00200a2802a00110010b0240200b450d00200041013a0000200041086a4117360200200041046a418ebac100360200200a41c0026a24000f0b200a41d4006a4100360200200a41c4006a41b084c300360200200a41306a41086a4200370300200a41e4006a200a41106a41086a290300370200200a41ec006a200a41206a290300370200200a41f4006a200a41106a41186a290300370200200a420837024c200a41e8bdc000360234200a4100360230200a200a29031037025c200a2001360240200a200141286a280200220b360258200a200141186a28020041016a3602480240024002400240024020032004844200510d00200a41086a200541012010200a41106a20032004200a41306a10e3020240200a280208220b450d00200a28020c2101200041013a0000200041086a2001360200200041046a200b3602000c020b200141286a280200210b0b200a410036028801200a420137038001200a41ac016a200241086a290000370200200a41b4016a200241106a290000370200200a41bc016a200241186a290000370200200a20022900003702a401200a200a41306a3602a00102402006200720082009200a4180016a200a41a0016a200b200510e40241ff01714108470d00200a4190016a41086a200a4180016a41086a280200360200200a200a2903800137039001200a2802300d06200a417f360230200a41d8016a41186a2205200a41106a41186a290300370300200a41d8016a41106a220b200a41106a41106a290300370300200a41d8016a41086a220e200a41106a41086a290300370300200a200a2903103703d801200a41a0016a200a41306a410472200a41d8016a10df01200a2802a0014101470d02200a41a0016a41086a2802002105200a41a0016a41106a280200210b200a420037029402200a41e8bdc00036029002200a41d8016a200a4190026a10cb01200a41d8016a10cc014118210e2005200b41306c6a41e8026a220b41186a2105200b280218220f0d030c040b200041013a0000200041086a4126360200200041046a41a5bac100360200200a28028401450d00200a2802800110010b200a41d8016a41086a200a41306a410472220141086a280200360200200a20012902003703d801200a41a0016a200a41d8016a10cf01200a41a0016a10d0010240200a41d0006a280200450d00200a41cc006a28020010010b200a41c0026a24000f0b200a4188026a200a41d4016a280200360200200a41d8016a41286a200a41cc016a290200370300200a41f8016a200a41c4016a2902003703002005200a41bc016a290200370300200b200a41b4016a290200370300200e200a41ac016a290200370300200a200a2902a4013703d801200a4190026a41186a4100360200200a4190026a41106a4200370300200a4190026a41086a4200370300200a4190026a41286a4200370300200a420037039002200a41e8bdc0003602b4024118210e200a41d8016a200a4190026a10e201220b41186a2105200b280218220f450d010b200b411c6a280200450d00200f10010b2005200a29039001370200200541086a200a4190016a41086a280200360200200a200a28023041016a360230200a41a0016a41086a220b200a41306a41086a220f290300370300200a41d8016a41086a2206200a41ac016a280200360200200a200a2903303703a001200a200a2902a4013703d801200a41d0006a2802002107200a41306a411c6a2802002105200a41d4006a2802002108200b2006280200360200200a200a2903d8013703a001200f200b280200360200200a200a2903a0013703302001200a41306a10c702200a2005200841d8006c6a36023c200a2005360238200a2007360234200a20053602302001411c6a200a41306a1017200041003a0000200041196a200a41106a200e6a290300370000200041116a200a41206a290300370000200041096a200a41106a41086a2903003700002000200a290310370001200a41c0026a24000f0b10c602000b108402000bf00102027f027e230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d01200228020421032004200128021c2903104200200241146a2802002202ad420010fc02024020042903084200520d002001280224220542002005290308220620042903007d220720072006562007507222051b37030820050d00200128020c2002102720012802202802082003200128020c22022802002002280208100b2202417e460d0020020d03200141013a00280b20004105360200200441106a24000f0b41ff80c10041f4031042000b41ff80c10041f4031042000b41d08dc200104f000b5e01027f230041106b220424002004200128020041046a10f501200141106a21050240200141146a280200450d00200528020010010b20052004290300370200200541086a200441086a28020036020020004104360200200441106a24000b1600200041003602002000200141086a2802003602040ba70202057f027e230041106b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d02410521030240200141086a2802002205200241146a2802002206490d00200520066b200241246a2802002205470d0020022802042102200128020421072004200128021c29032042002005ad420010fc0220042903084200520d002001280224220842002008290308220920042903007d220a200a200956200a507222081b37030820080d00200141206a2802002802082002200720066a2005100c2202417e460d0020020d04410421030b20002003360200200441106a24000f0b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b41e88dc200104f000b1600200041003602002000200141186a2802003602040ba70202057f027e230041106b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d02410521030240200141186a2802002205200241146a2802002206490d00200520066b200241246a2802002205470d0020022802042102200128021021072004200128021c29032042002005ad420010fc0220042903084200520d002001280224220842002008290308220920042903007d220a200a200956200a507222081b37030820080d00200141206a2802002802082002200720066a2005100c2202417e460d0020020d04410421030b20002003360200200441106a24000f0b41ff80c10041f4031042000b41ff80c10041f4031042000b41ff80c10041f4031042000b41e88dc200104f000bac0402077f027e230041c0006b2202240002400240024002400240411310002203450d002002421337023420022003360230200241306a41cd85c1004113102520022802302103024002400240024020022802342204200228023822056b41044f0d00200541046a22062005490d0520044101742207200620062007491b22074100480d052004450d01200710002208450d062008200320072004200420074b1b10f802210420031001200421030c020b200541046a21060c020b200710002203450d040b200721040b200320056a2001360000200241306a41086a220542003703002002420037033020032006200241306a1002200241086a20052903003703002002200229033037030002400240200241104188f0c100410041001004417f460d00200220023602102002411036021420024200370338200242003703302002410020024110200241306a41104100100422052005417f461b2205411020054110491b3602182005410f4d0d01200241306a41086a220529030021092002290330210a200241306a200241106a103620022802302206450d0120022002290234370320200020093703082000200a3703002005200241206a41086a2802003602002002200229032037033020002006360210200020022903303702142000411c6a20052802003602002004450d060c050b2000410036021020040d040c050b41eac4c10041331042000b411341011019000b1018000b200741011019000b200310010b200241c0006a24000ba80d03027f017e077f230041f0016b22052400200541086a41086a2206420037030020054200370308419e86c1004119200541086a1002200541f0006a41086a200629030037030020052005290308370370410021060240024002400240024002400240024002400240200541f0006a41104188f0c100410041001004417f460d002005410036028001200541f0006a411020054180016a41044100100441016a41044d0d0102402005280280012206450d00200541086a2006417f6a1093022005280210410d460d0120054180016a200541086a41e80010f8021a200529038001210720054180016a41086a10a00120072001580d01200041f887c10036020420004101360200200041086a41c700360200200210a001200541f0016a24000f0b410021060b2005200641016a360270200541086a41086a2208420037030020054200370308419e86c1004119200541086a100220054180016a41086a22092008290300370300200520052903083703800120054180016a4110200541f0006a4104100320052001370380012009200241d00010f802210a200520043703d801200520033a00e001411a10002202450d022005421a37020c20052002360208200541086a41ce86c100411a102520052802082109024002400240200528020c2202200528021022086b41034b0d00200841046a220b2008490d042002410174220c200b200b200c491b220c4100480d042002450d01200c1000220b450d07200b2009200c20022002200c4b1b10f8021a200910010c020b2009210b2002210c0c010b200c1000220b450d050b200b20086a200636000020054100360210200542013703082005290380012101410810002202450d032005410836020c200541086a41086a22092009280200220941086a36020020052002360208200220096a2001370000200a200541086a101c024002400240024002400240024002400240024002400240024002400240200541e0016a2d000022024101460d0020024102470d01200528020c200541106a2802002202470d03200241016a22092002490d102002410174220d20092009200d491b220d4100480d102002450d082005280208210e200d10002209450d162009200e200d20022002200d4b1b10f8021a200e10010c090b200528020c200541106a2802002202470d01200241016a22092002490d0f2002410174220d20092009200d491b220d4100480d0f2002450d042005280208210e200d10002209450d142009200e200d20022002200d4b1b10f8021a200e10010c050b200528020c200541106a2802002202470d02200241016a22092002490d0e2002410174220d20092009200d491b220d4100480d0e2002450d092005280208210e200d10002209450d152009200e200d20022002200d4b1b10f8021a200e10010c0a0b200528020821090c040b200528020821090c060b200528020821090c080b200d10002209450d0f0b2005200d36020c20052009360208200541106a28020021020b200541106a200241016a360200200920026a41013a00000c060b200d10002209450d0d0b2005200d36020c20052009360208200541106a28020021020b200541106a200241016a360200200920026a41023a00000c030b200d10002209450d0b0b2005200d36020c20052009360208200541106a28020021020b200541106a200241016a360200200920026a41003a00000b200541d8016a29030021010240024002400240200528020c2209200541086a41086a28020022026b41084f0d00200241086a220d2002490d0520094101742202200d200d2002491b22024100480d052009450d012005280208210e20021000220d450d09200d200e20022009200920024b1b10f8021a200e10010c020b2005280208210d0c020b20021000220d450d070b2005200236020c2005200d360208200541106a28020021020b200541086a41086a2209200241086a360200200d20026a20013700002009280200210d200528020c210e200528020821022009420037030020054200370308200b200841046a200541086a1002200541f0006a41086a200929030037030020052005290308370370200541f0006a41102002200d10030240200e450d00200210010b0240200c450d00200b10010b200a10a0012005418c016a200636020020054189016a20033a000020054188016a41013a0000200541043a00800120054180016a10b4012000410036020020002006360204200541f0016a24000f0b41eac4c10041331042000b1018000b411a41011019000b410841011019000b200c41011019000b200241011019000b200d41011019000b200d41011019000b200d41011019000bdd0702077f027e230041e0026b220224000240024002400240024002400240411a10002203450d002002421a3702c401200220033602c001200241c0016a41ce86c100411a102520022802c0012103024002400240024020022802c401220420022802c80122056b41044f0d00200541046a22062005490d0520044101742207200620062007491b22074100480d052004450d01200710002208450d082008200320072004200420074b1b10f802210420031001200421030c020b200541046a21060c020b200710002203450d060b200721040b200320056a2001360000200241c0016a41086a22054200370300200242003703c00120032006200241c0016a1002200241086a2005290300370300200220022903c00137030002400240200241104188f0c100410041001004417f460d002002200236021020024110360214200242003703c0012002410020024110200241c0016a41084100100422052005417f461b22054108200541084922051b36021820050d0520022903c0012109200241c0016a200241106a103820022802c001210520024194026a200241c0016a41047241cc0010f8021a2005410d460d05200241f4006a20024194026a41cc0010f8021a20022005360220200241206a410472200241f4006a41cc0010f8022106200241003a00c00120022802102002280214200241c0016a4101200241186a22052802001004210720052005280200200741016a220741014b6a220136020020074102490d0120022d00c001220741034f0d01200242003703c001200241106a41086a2208410020022802102002280214200241c0016a41082001100422052005417f461b2205410820054108491b20082802006a360200200541074d0d0420022903c001210a20022802202105200241c0016a200641cc0010f8021a20024194026a41066a2206200241206a41066a2d00003a000020024194026a41046a2201200241206a41046a2f00003b010020022002280020360294022005410d460d05200241206a200241c0016a41cc0010f8021a200241f4006a41066a220820062d00003a0000200241f4006a41046a220620012f01003b0100200220022802940236027420002005360208200020093703002000410c6a200241206a41cc0010f8021a200041e0006a20073a0000200041d8006a200a37030020002002280274360061200041e5006a20062f01003b0000200041e7006a20082d00003a00002004450d080c070b2000410d36020820040d060c070b200241206a10a00141eac4c10041331042000b411a41011019000b1018000b200241206a10a0010b41eac4c10041331042000b200741011019000b200310010b200241e0026a24000bb30a04087f017e067f017e230041f0026b2202240002400240024002400240411710002203450d002002421737029c02200220033602980220024198026a41b786c100411710252002280298022104024002400240024002400240200228029c02220520022802a00222036b41084f0d00200341086a22062003490d0320054101742207200620062007491b22074100480d032005450d01200710002208450d072008200420072005200520074b1b10f80221082004100120072105200821040c020b200341086a21060c010b200710002204450d05200721050b200420036a2001370000200241c8016a41086a22034200370300200242003703c80120042006200241c8016a1002200241106a41086a2003290300370300200220022903c801370310024002400240024002400240024002400240200241106a41104188f0c100410041001004417f460d00200242103702242002200241106a360220200241086a200241206a10352002280208450d08200228020c2209ad220142d8007e220a422088a70d0b200aa72203417f4c0d0b2003450d0120031000220b450d0e20090d020c030b20004100360208200042083702002005450d0f0c0e0b4108210b2009450d010b200241c8016a410472210c200241286a21034100210d0340200241003a0098022002280220200228022420024198026a410120032802001004210720032003280200200741016a220741014b6a36020020074102490d040240024020022d0098022207450d0020074101470d0620024198026a200241206a1038200228029802410d460d05200241c8016a20024198026a41d00010f8021a200241003602ec022003410020022802202002280224200241ec026a41042003280200100422072007417f461b2207410420074104491b20032802006a360200200741034d0d0420022802ec02210e20022802c8012108200241fc006a200c41cc0010f8021a20024198026a200241fc006a41cc0010f8021a2008410d460d06200241306a20024198026a41cc0010f8021a20024198026a200241306a41cc0010f8021a2008410e470d010c070b20024198026a200241306a41cc0010f8021a410d21080b200241c8016a20024198026a41cc0010f8021a02402001422088a722072001a7470d00200741016a220f2007490d0820074101742210200f200f2010491bad220a42d8007e2211422088a70d082011a7220f4100480d08024002402007450d00200f10002210450d0b2010200b200f200741d8006c22072007200f4b1b10f8022107200b10012007210b0c010b200f1000220b450d0a0b200142808080807083200a8421010b200b2001422088a741d8006c6a22072008360200200741046a200241c8016a41cc0010f8021a200741d0006a200e36020020014280808080107c2101200d41016a220d2009490d000b0b200b450d04200241c8016a41086a22034200370300200242003703c80120042006200241c8016a100220024198026a41086a2003290300370300200220022903c8013703980220024198026a41101008200020013702042000200b36020020050d0b0c0c0b200241c8016a10280b20024198026a200241fc006a41cc0010f8021a0b20024198026a200241306a41cc0010f8021a0b02402001422088a72202450d00200241d8006c2103200b2102034002402002280200410d460d00200210280b200241d8006a2102200341a87f6a22030d000b0b2001a7450d00200b10010b41eac4c10041331042000b1018000b200f41081019000b102c000b411741011019000b200741011019000b200341081019000b200410010b200241f0026a24000b9d0301077f230041306b22022400024002400240024002400240411310002203450d002002421337022420022003360220200241206a41e886c1004113102520022802202103024002400240024020022802242204200228022822056b41044f0d00200541046a22062005490d0520044101742207200620062007491b22074100480d052004450d01200710002208450d072008200320072004200420074b1b10f802210420031001200421030c020b200541046a21060c020b200710002203450d050b200721040b200320056a2001360000200241206a41086a220542003703002002420037032020032006200241206a1002200241086a2005290300370300200220022903203703000240200241104188f0c100410041001004417f460d002002421037021420022002360210200241206a200241106a103620022802202205450d0320002002290224370204200020053602002004450d060c050b200041003602082000420137020020040d040c050b411341011019000b1018000b41eac4c10041331042000b200741011019000b200310010b200241306a24000ba707010b7f230041d0006b220124000240024002400240411a10002202450d002001421a37020c20012002360208200141086a41ce86c100411a10252001280208210202400240024002400240200128020c2203200128021022046b41044f0d00200441046a22052004490d0420034101742206200520052006491b22064100480d042003450d01200610002207450d072007200220062003200320064b1b10f802210320021001200321020c020b200441046a21050c020b200610002202450d050b200621030b200220046a2000360000200141c0006a41086a220442003703002001420037034020022005200141c0006a1002200141306a41086a200429030037030020012001290340370330200141306a4110100802402003450d00200210010b411310002202450d022001421337020c20012002360208200141086a41e886c1004113102520012802082106024002400240200128020c2204200128021022026b41034b0d00200241046a22032002490d0320044101742205200320032005491b22054100480d032004450d01200510002203450d072003200620052004200420054b1b10f8021a200610010c020b20062103200421050c010b200510002203450d050b200320026a2000360000200141c0006a41086a22044200370300200142003703402003200241046a200141c0006a1002200141306a41086a200429030037030020012001290340370330200141306a4110100802402005450d00200310010b200141086a2000109502200128020c2108200128020821090240024020012802102202450d0020024105742107200141086a410472210320092102034020032002290000370000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a29000037000020012000360208411010002204450d022001421037024420012004360240200141c0006a41fb86c10041101025200141306a41086a2204200141c0006a41086a220528020036020020012001290340370330200141086a200141306a1097022004280200210a2001280234210b2001280230210620054200370300200142003703402006200a200141c0006a10022004200529030037030020012001290340370330200141306a411010080240200b450d00200610010b200241206a2102200741606a22070d000b0b02402008450d00200910010b200141d0006a24000f0b411041011019000b1018000b411a41011019000b411341011019000b200641011019000b200541011019000b8d0201047f20002802002001108901024002400240024002400240200141046a2802002202200141086a28020022036b41204f0d00200341206a22042003490d0420024101742203200420042003491b22034100480d042002450d0120012802002105200310002204450d052004200520032002200220034b1b10f8021a200510010c020b200128020021040c020b200310002204450d030b20012004360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200420036a220141186a2000411c6a290000370000200141106a200041146a290000370000200141086a2000410c6a290000370000200120002900043700000f0b1018000b200341011019000b3400200041db9fc10036020420004100360200200041146a410f360200200041106a4184d7c200360200200041086a42093702000b890201057f230041206b2201240002400240411010002202450d002001421037021420012002360210200141106a41fb86c10041101025200141086a220220012802183602002001200129031037030020002001109702200228020021032001280204210420012802002100200141106a41086a220542003703002001420037031020002003200141106a10022002200529030037030020012001290310370300410021020240200141104188f0c100410041001004417f460d00200141003a001020014110200141106a41014100100441016a41014d0d0220012d001021020b02402004450d00200010010b200141206a240020020f0b411041011019000b41eac4c10041331042000b4b00200041ddf5c10036020420004100360200200041206a41063602002000411c6a4188dfc200360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000b130020004106360204200041e0e3c2003602000bd71b05037f027e057f047e027f230041e0006b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280200417f6a2203410b4b0d0002400240024020030e0c0008050602090a070b040c01000b2002200141086a10920120004101360200200041106a200241086a290300370300200041086a2002290300370300200241e0006a24000f0b4102210320012d000422044102460d0b4103210320044103470d2d200241186a200141046a220141196a290000370300200241106a200141116a290000370300200241086a200141096a290000370300200220012900013703000c0c0b2002200141086a10930120004105360200200041186a200241106a290300370300200041106a200241086a290300370300200041086a2002290300370300200241e0006a24000f0b200141086a2903004202520d2c20004100360200200041086a4202370300200041106a200141106a290300370300200241e0006a24000f0b200141086a280200417e6a220341044b0d2c024020030e05001b191a18000b41012103200141386a2903002105200141306a29030021062001410c6a2d00004101470d1f0c200b41022103200141086a22042d000022074102460d0f4103210320074103460d0e4104210320074104470d2c20042d000141004721010c100b200141086a2d0000417e6a220841094b0d2c4102210341002109024020080e0a35001d211b242522261c350b2001410c6a28020022094108762107410321030c220b20012d000422034102460d074103210420034103470d2c200241d2006a200141046a220341036a2d00003a0000200241086a200141186a2900003703002002410d6a2001411d6a290000370000200220032f00013b01502002200141106a290000370300200141256a2d00004100472107200141286a280200210a2001410c6a2800002103200141086a280000210b0c080b41022104200141086a28020022034102460d0820034103470d2c410121072001410c6a2d00004101470d0e0c0f0b2002200141086a10940120004106360200200041c0006a200241386a290300370300200041386a200241306a290300370300200041306a200241286a290300370300200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a290300370300200041086a2002290300370300200241e0006a24000f0b2002200141086a10950120004107360200200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a290300370300200041086a2002290300370300200241e0006a24000f0b20012802044102470d2a2002200141086a102b2000428980808020370300200041086a2002290200370200200041106a200241086a280200360200200241e0006a24000f0b41022104200141086a22032d000022074102460d054103210420074103470d2a200141306a2903002105200141286a2903002106200141386a290300210c200241c0006a2001410c6a102b200241d0006a200141186a102b2002410b6a200241c0006a41086a280200360000200241176a200241d0006a41086a280200360000200220022903403700032002200229035037000f4200210d4200210e0c060b200241d0006a200141086a102b2002410b6a200241d0006a41086a280200360000200220022903503700030b20002002290300370005200020033a0004200020022f00503b00252000410c3602002000410d6a200241086a290300370000200041156a200241106a2903003700002000411d6a200241186a290300370000200041276a200241d2006a2d00003a0000200241e0006a24000f0b200141086a280200210b41d00010002203450d2820032001410c6a280200109101410221040b200020022f01503b0005200020043a0004200020073a0025200020022f01403b0126200041083602002000410c6a2003360200200041086a200b360200200041106a2002290300370200200041286a200a360200200041076a200241d2006a2d00003a0000200041186a200241086a2903003702002000411d6a2002410d6a290000370000200241e0006a24000f0b410121072001410c6a2d00004101470d070c080b200241176a200341186a290000370000200241106a200341116a290000370300200241086a200341096a29000037030020022003290001370300200141c0006a290300210e200141386a290300210c200141c8006a290300210f200141286a3100002106200241d0006a2001412c6a102b200241d0006a41086a3502004220862002290350220d4220888421052006200d4220868421064200210d0b200020022903003700092000410b360200200041c0006a200e370300200041386a200d200c84370300200041306a2005370300200041286a2006370300200041086a20043a0000200041c8006a200f370300200041116a200241086a290300370000200041196a200241106a290300370000200041206a200241176a290000370000200241e0006a24000f0b200141106a29030021050c010b200241d4006a200441066a2f00003b0100200241086a200141206a290000370300200241106a200141286a2d00003a00002002200441026a2800003602502002200141186a290000370300200141106a2900002105200141096a2d000021010b200020013a00092000200228025036010a20004103360200200041086a20033a0000200041106a2005370300200041186a20022903003703002000410e6a200241d4006a2f01003b0100200041206a200241086a290300370300200041286a200241106a290300370300200241e0006a24000f0b200141286a3500002001412c6a3100004220868421052001410d6a2f00002001410f6a2d0000411074722103200141246a280000210a200141206a280000210b200141186a2900002106200141146a2800002110410021070b200141c8006a290300210c200141c0006a290300210d410321040c020b200141286a3500002001412c6a3100004220868421052001410d6a2f00002001410f6a2d0000411074722103200141246a280000210a200141206a280000210b200141186a2900002106200141146a2800002110410021070b0b200020033b000d200041023602002000410f6a20034110763a0000200041c8006a200c370300200041c0006a200d370300200041286a2005370200200041246a200a360200200041206a200b360200200041186a2006370200200041146a20103602002000410c6a20073a0000200041086a2004360200200041386a200141386a290300370300200041306a200141306a290300370300200041106a200141106a280000360200200241e0006a24000f0b2001410c6a28020022034108762104410621010c030b200241106a200141206a2903003703002002200141186a2903003703082002200141106a2802003602002001410c6a28020022034108762104200141286a290300210c410421010c080b2001410c6a28020022034108762104410521010c010b2002200141186a2903003703082002200141106a29030037030041032101410021030b0c050b2001410c6a28020022094108762107200141186a2903002106200141206a2802002110200141106a2903002205a7210b2005422088a7210a410621030c180b2001410c6a28020022094108762107410b21030c060b410121092001410c6a2d00004101470d090c0a0b200141286a3500002001412c6a31000042208684210c2001410d6a2f00002001410f6a2d0000411074722104200141246a2800002107200141206a280000210a200141186a290000210d200141146a280000210b410021030b200220073602142002200a3602102002200d3703082002200b3602042002200141106a280000360200410221010b2000410a360200200041386a2005370300200041306a2006370300200041086a2001360200200041106a2002290300370300200041286a200c3703002000410c6a2004410874200341ff017172360200200041186a200241086a290300370300200041206a200241106a290300370300200241e0006a24000f0b2001410c6a28020022094108762107410521030c010b2001410c6a28020022094108762107410921030b0c0f0b200141106a2903002205a7210b2005422088a7210a410721030c0e0b200141106a2903002205a7210b2005422088a7210a410821030c0d0b41002109200141096a2d00004100472111410a21030c0e0b200141286a3500002001412c6a3100004220868421052001410d6a2f00002001410f6a2d0000411074722107200141246a2800002104200141206a2800002110200141186a2900002106200141146a280000210a410021090b200141106a280000210b410421030c0b0b41d8ccc200104f000b41a881c300104f000b41c0ccc200104f000b41acd5c200104f000b41a8ccc200104f000b418cabc200104f000b41c4aec300104f000b4180e8c200104f000b4188a8c200104f000b41d00041081019000b0b0b200020113a0009200020022f01003b010a20004104360200200041186a2006370300200041086a20033a0000200041286a2005370200200041246a2004360200200041206a20103602002000410c6a2007410874200941ff017172360200200041106a200aad422086200bad84370300200241e0006a24000bfb0503077f027e057f230041206b22022400024002400240411310002203450d002002421337021420022003360210200241106a41cd85c10041131025200228021021040240024002400240024020022802142205200228021822036b41044f0d00200341046a22062003490d0320054101742207200620062007491b22084100480d032005450d01200810002207450d072007200420082005200520084b1b10f802210520041001200521040c020b200341046a2106200521080c010b200810002204450d050b200420036a20003600002002410036021820024201370310200141086a29030021092001290300210a411010002203450d032003200a37000020032009370008200242908080808002370214200220033602102001280210210b200141186a2802002203200241106a101b024002402003450d002003410574210c200241106a41086a28020021072002280210210d20022802142100200b210e0340200e210302400240024002402000200722056b41204f0d00200541206a22072005490d072000410174220e20072007200e491b220e4100480d07200e1000210f2000450d01200f450d08200f200d200e20002000200e4b1b10f8021a200d10010c020b200541206a21070c020b200f450d060b200f210d200e21000b200341206a210e200d20056a22052003290000370000200541186a200341186a290000370000200541106a200341106a290000370000200541086a200341086a290000370000200c41606a220c0d000b200241186a2007360200200220003602142002200d3602100c010b200241186a2802002107200228021421002002280210210d0b200241106a41086a220342003703002002420037031020042006200241106a1002200241086a20032903003703002002200229031037030020024110200d2007100302402000450d00200d10010b02402008450d00200410010b0240200141146a280200450d00200b10010b200241206a24000f0b1018000b200e41011019000b411341011019000b411041011019000b200841011019000bb80704037f027e0c7f037e23004190016b22012400200141f0006a41086a220242003703002001420037037041ddc6c1004115200141f0006a1002200141106a41086a2002290300370300200120012903703703100240024002400240024002400240024002400240200141106a41104188f0c100410041001004417f460d00200142103702242001200141106a360220200141086a200141206a10352001280208450d05200128020c2203ad220442287e2205422088a70d082005a72202417f4c0d082002450d01200210002206450d0920030d020c030b2000410036020020014190016a24000f0b410821062003450d010b200141206a41086a22072802002108200128022421092001280220210a200141f0006a41186a210b200141f0006a41106a210c4100210d0340200b4200370300200c4200370300200141f0006a41086a220e42003703002001420037037020074100200a2009200141f0006a41202008100422022002417f461b2202412020024120491b20086a22083602002002411f4d0d02200141d0006a41186a220f200b290300370300200141d0006a41106a2210200c290300370300200141d0006a41086a2211200e290300370300200120012903703703502001420037037020074100200a2009200141f0006a41082008100422022002417f461b2202410820024108491b20086a2208360200200241074d0d0220012903702105200141306a41186a2202200f290300370300200141306a41106a220f2010290300370300200141306a41086a2210201129030037030020012001290350370330200b2002290300370300200c200f290300370300200e20102903003703002001200129033037037002402004422088a72004a72202470d00200241016a220f2002490d0520024101742210200f200f2010491bad221242287e2213422088a70d052013a7220f4100480d05024002402002450d00200f10002210450d0820102006200f200241286c22022002200f4b1b10f802210220061001200221060c010b200f10002206450d070b20044280808080708320128421040b20062004422088a741286c6a22022001290370370300200e2903002112200c2903002113200b290300211420022005370320200241186a2014370300200241106a2013370300200241086a201237030020044280808080107c2104200d41016a220d2003490d000b0b2006450d01200020043702042000200636020020014190016a24000f0b2004a7450d00200610010b41eac4c10041331042000b1018000b200f41081019000b102c000b200241081019000be90604037f027e0b7f027e230041f0006b22012400200141d0006a41086a220242003703002001420037035041f1a2c1004117200141d0006a1002200141106a41086a2002290300370300200120012903503703100240024002400240024002400240024002400240200141106a41104188f0c100410041001004417f460d00200142103702242001200141106a360220200141086a200141206a10352001280208450d05200128020c2203ad220442287e2205422088a70d082005a72202417f4c0d082002450d01200210002206450d0920030d020c030b20004100360200200141f0006a24000f0b410821062003450d010b200141206a41086a22072802002108200128022421092001280220210a200141d0006a41186a210b200141d0006a41106a210c4100210d03402001420037035020074100200a2009200141d0006a41082008100422022002417f461b2202410820024108491b20086a2208360200200241074d0d0220012903502105200b4200370300200c4200370300200141d0006a41086a220e42003703002001420037035020074100200a2009200141d0006a41202008100422022002417f461b2202412020024120491b20086a22083602002002411f4d0d02200141306a41186a2202200b290300370300200141306a41106a220f200c290300370300200141306a41086a2210200e29030037030020012001290350370330200b2002290300370300200c200f290300370300200e20102903003703002001200129033037035002402004422088a72004a72202470d00200241016a220f2002490d0520024101742210200f200f2010491bad221142287e2212422088a70d052012a7220f4100480d05024002402002450d00200f10002210450d0820102006200f200241286c22022002200f4b1b10f802210220061001200221060c010b200f10002206450d070b20044280808080708320118421040b20062004422088a741286c6a22022005370300200241206a200b290300370300200241186a200c290300370300200241106a200e2903003703002002200129035037030820044280808080107c2104200d41016a220d2003490d000b0b2006450d012000200437020420002006360200200141f0006a24000f0b2004a7450d00200610010b41eac4c10041331042000b1018000b200f41081019000b102c000b200241081019000b930401097f230041206b2201240020002802002102024002400240024002400240024002400240024020002802082200413f4b0d0041012103410110002204450d05200420004102743a00004101210520000d010c020b02402000418080014f0d0041022103410210002204450d06200420004102744101723b00000c010b024020004180808080044f0d0041042103410410002204450d07200420004102744102723600000c010b410110002205450d07200541033a000041052103410510002204450d08200420052d00003a000020051001200420003600010b200041027421062003210503402002280200210702400240024002402003200522006b41044f0d00200041046a22052000490d0620034101742208200520052008491b22084100480d062003450d01200810002209450d072009200420082003200320084b1b10f802210320041001200321040c020b200041046a21050c020b200810002204450d050b200821030b200241046a2102200420006a20073600002006417c6a22060d000b0b200141106a41086a220042003703002001420037031041d9c2c0004112200141106a1002200141086a2000290300370300200120012903103703002001411020042005100302402003450d00200410010b200141206a24000f0b1018000b200841011019000b410141011019000b410241011019000b410441011019000b410141011019000b410541011019000bee0402097f017e230041206b2201240020014100360218200142013703102000280200210220002802082200200141106a101b024002400240024002402000450d002002200041286c6a2103200141106a41086a220428020021002001280214210503400240024002400240200520006b41204f0d00200041206a22062000490d0720054101742207200620062007491b22074100480d072005450d0120012802102108200710002209450d082009200820072005200520074b1b10f8021a200810010c020b200041206a210620012802102109200521070c020b200710002209450d060b20012007360214200120093602100b20042006360200200920006a220041186a200241186a290000370000200041106a200241106a290000370000200041086a200241086a29000037000020002002290000370000200241206a290300210a0240024002400240200720066b41084f0d00200641086a22002006490d0720074101742205200020002005491b22054100480d072005100021082007450d012008450d092008200920052007200720054b1b10f8021a200910010c020b200641086a210020072105200921080c020b2008450d070b20012005360214200120083602100b20042000360200200820066a200a3700002003200241286a2202470d000c020b0b200141186a280200210020012802142105200128021021080b200141106a41086a220242003703002001420037031041ddc6c1004115200141106a1002200141086a2002290300370300200120012903103703002001411020082000100302402005450d00200810010b200141206a24000f0b1018000b200741011019000b200541011019000bea0403057f027e037f230041206b2201240020014100360218200142013703102000280200210220002802082200200141106a101b024002400240024002402000450d002002200041306c6a2103200141106a41086a280200210420012802102105200128021421000340200241086a2903002106200229030021070240024002400240200020046b41104f0d00200441106a22082004490d0720004101742209200820082009491b22094100480d0720091000210a2000450d01200a450d08200a200520092000200020094b1b10f8021a200510010c020b200441106a21080c020b200a450d060b200a2105200921000b200520046a22042006370008200420073700000240024002400240200020086b41204f0d00200841206a22042008490d0720004101742209200420042009491b22094100480d0720091000210a2000450d01200a450d09200a200520092000200020094b1b10f8021a200510010c020b200841206a21040c020b200a450d070b200a2105200921000b200520086a220841186a200241286a290000370000200841106a200241206a290000370000200841086a200241186a2900003700002008200241106a290000370000200241306a22022003470d000b200141186a200436020020012000360214200120053602100c010b200141186a280200210420012802142100200128021021050b200141106a41086a220242003703002001420037031041eec7c1004113200141106a1002200141086a2002290300370300200120012903103703002001411020052004100302402000450d00200510010b200141206a24000f0b1018000b200941011019000b200941011019000b8207010a7f230041206b2203240020034100360218200342013703102002280200210402400240410410002205450d0020034284808080c000370214200320053602102005200436000020022802042106410810002204450d0120042005280000360000200510012003428880808080013702142004200636000420032004360210200241086a2802002105200241106a2802002204200341106a101b02400240024002402004450d0020044105742107200341106a41086a220828020021042003280214210903400240024002400240200920046b41204f0d00200441206a22062004490d062009410174220a20062006200a491b220b4100480d062009450d012003280210210c200b1000220a450d07200a200c200b20092009200b4b1b10f8021a200c10010c020b200441206a21062003280210210a0c020b200b1000220a450d050b2003200b3602142003200a360210200b21090b20082006360200200a20046a220441086a200541086a290000370000200441106a200541106a290000370000200441186a200541186a2900003700002004200529000037000020062104200541206a2105200741606a22070d000b0b200241146a28020021052002411c6a2802002204200341106a101b024002402004450d00200441057421074100200341106a41086a220828020022046b21092003280214210603400240024002400240200620096a41204f0d00200441206a220a2004490d072006410174220b200a200a200b491b220b4100480d072006450d012003280210210c200b1000220a450d09200a200c200b20062006200b4b1b10f8021a200c10010c020b2003280210210a0c020b200b1000220a450d070b2003200b3602142003200a360210200b21060b2008200441206a220b360200200a20046a220441086a200541086a290000370000200441106a200541106a290000370000200441186a200541186a29000037000020042005290000370000200941606a2109200b2104200541206a2105200741606a22070d000c020b0b200341186a280200210b200328021421062003280210210a0b200341106a41086a220542003703002003420037031020002001200341106a1002200341086a20052903003703002003200329031037030020034110200a200b100302402006450d00200a10010b200341206a24000f0b1018000b200b41011019000b200b41011019000b410441011019000b410841011019000b7501027f230041206b220324000240410410002204450d0020042002360000200341106a41086a220242003703002003420037031020002001200341106a1002200341086a2002290300370300200320032903103703002003411020044104100320041001200341206a24000f0b410441011019000bf00403057f017e047f230041206b2201240020014100360218200142013703102000280200210220002802082200200141106a101b024002400240024002402000450d002002200041286c6a2103200141106a41086a22042802002100200128021421050340200229030021060240024002400240200520006b41084f0d00200041086a22072000490d0720054101742208200720072008491b22084100480d072005450d012001280210210920081000220a450d08200a200920082005200520084b1b10f8021a200910010c020b200041086a21072001280210210a200521080c020b20081000220a450d060b200120083602142001200a3602100b20042007360200200a20006a20063700000240024002400240200820076b41204f0d00200741206a22002007490d0720084101742205200020002005491b22054100480d072005100021092008450d012009450d092009200a20052008200820054b1b10f8021a200a10010c020b200741206a210020082105200a21090c020b2009450d070b20012005360214200120093602100b20042000360200200920076a220741086a200241106a290000370000200741106a200241186a290000370000200741186a200241206a2900003700002007200241086a290000370000200241286a22022003470d000c020b0b200141186a280200210020012802142105200128021021090b200141106a41086a220242003703002001420037031041f1a2c1004117200141106a1002200141086a2002290300370300200120012903103703002001411020092000100302402005450d00200910010b200141206a24000f0b1018000b200841011019000b200541011019000bf50104017f017e017f017e230041206b2203240042002104200341086a22054200370300200342003703002001200220031002200341106a41086a200529030037030020032003290300370310024002400240200341106a41104188f0c100410041001004417f460d0020034200370300200341106a4110200341084100100441016a41084d0d0220032903002106200341086a22054200370300200342003703002001200220031002200341106a41086a200529030037030020032003290300370310200341106a41101008420121040c010b0b2000200437030020002006370308200341206a24000f0b41eac4c10041331042000be00101037f230041206b22022400200241086a22034200370300200242003703002000200120021002200241106a41086a20032903003703002002200229030037031002400240200241106a41104188f0c100410041001004417f460d00200241003a0000200241106a4110200241014100100441016a41014d0d0120022d00002103200241086a22044200370300200242003703002000200120021002200241106a41086a200429030037030020022002290300370310200241106a41101008200241206a240020030f0b200241206a240041020f0b41eac4c10041331042000bc504020d7f017e230041c0006b22032400200128020022042001280208220541047422066a2107200128020421080240024002400240024002402005450d00200341306a41017221094100210a200341306a41026a210b200341206a410172220c41076a210d0340200b2004200a6a220141036a2d00003a00002003200141016a2f00003b013020012d0000220e41ac01460d022003410c6a41026a220f200b2d00003a0000200320032f01303b010c200141046a2902002110200341306a410c6a2001410c6a280200360200200920032f010c3b0000200941026a200f2d00003a00002003200e3a003020032010370234200341206a200341306a200210a9022003200c2900003703102003200d29000037001720032d0020220e411a470d052006200a41106a220a470d000c040b0b200422012007470d010c020b200141106a22012007460d010b03400240024020012d0000220a4109460d00200a41ac01470d010c030b200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a22012007470d000b0b02402008450d00200410010b2000411a3a00000c010b200020032903103700012000200e3a0000200041086a20032900173700000240200541047441706a200a460d00200141186a2101034002400240200141786a220a2d0000220b4109460d00200b41ac01470d010c030b200128020041ffffffff0371450d002001417c6a28020010010b200141106a2101200a41106a2007470d000b0b2008450d0020041001200341c0006a24000f0b200341c0006a24000be84903057f017e027f230041106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220441aa014b0d00024020040eab0100020304057576777806070879090a0b7a0c0d0e0f1011127b7c13147d7e7f15161780011881018201191a1b1c83011d1e1f840120212223850186012487018801252689018a012728292a2b2c8b018c012d8d018e018f012e90012f910130313233920193013494019501960135363738393a97013b3c3d980199019a013e3f409b0141424344454647489c01499d014a9e019f014ba001a1014c4d4e4fa201505152a3015354a401a50155565758595a5b5ca601a7015da8015e5fa901aa016061ab0162636465666768696a6b6c6d6e6f7071727374000b200341013a0008200241046a200341086a410110250cab010b200341003a0008200241046a200341086a410110250caa010b20012d00012104200341023a0008200241046a2202200341086a41011025200342fffdf7e78f182004410374ad42f8018388a72204413f7141c00072200420044118744118754100481b3a00082002200341086a410110250ca9010b20012d00012104200341033a0008200241046a2202200341086a41011025200342fffdf7e78f182004410374ad42f8018388a72204413f7141c00072200420044118744118754100481b3a00082002200341086a410110250ca8010b20012d00012104200341043a0008200241046a2202200341086a41011025200342fffdf7e78f182004410374ad42f8018388a72204413f7141c00072200420044118744118754100481b3a00082002200341086a410110250ca7010b200341053a0008200241046a200341086a410110250ca6010b2003410f3a0008200241046a200341086a410110250ca5010b200141046a2802002104200341103a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000ca5010b0b200141046a280200210420012d00012106200341113a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000b200320063a00082005200341086a410110250ca3010b2003411b3a0008200241046a200341086a410110250ca2010b200141046a2802002104200341203a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000ca2010b0b200141046a2802002104200341213a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000ca1010b0b200141046a2802002104200341233a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000ca0010b0b200141046a2802002104200341243a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000c9f010b0b200141086a2802002104200141046a2802002105200341283a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c9e010b0b200141086a2802002104200141046a2802002105200341293a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c9d010b0b200141086a2802002104200141046a28020021052003412a3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c9c010b0b200141086a2802002104200141046a28020021052003412b3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c9b010b0b200141086a2802002104200141046a28020021052003412c3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c9a010b0b200141086a2802002104200141046a28020021052003412f3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c99010b0b200141086a2802002104200141046a2802002105200341303a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c98010b0b200141086a2802002104200141046a2802002105200341343a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c97010b0b200141086a2802002104200141046a2802002105200341353a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c96010b0b200141086a2802002104200141046a2802002105200341363a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c95010b0b200141086a2802002104200141046a2802002105200341383a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c94010b0b200141086a2802002104200141046a28020021052003413b3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c93010b0b200141086a2802002104200141046a28020021052003413c3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c92010b0b200141086a2802002104200141046a28020021052003413d3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c91010b0b200141086a2802002104200141046a28020021052003413e3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c90010b0b20012d00012104200341c0003a0008200241046a2202200341086a41011025200320043a00082002200341086a410110250c8e010b200141046a2802002106200341c1003a0008200241046a2207200341086a410110252003200641ff00713a0008024020064107752204200641c00071220272452004417f4720024572734101470d00034020032006418001723a00082007200341086a410110252003200441ff00713a0008200441c000712102200421062004410775220521042005200272452005417f4720024572470d000b0b2007200341086a410110250c8d010b200141086a2903002108200341c2003a0008200241046a2205200341086a4101102520032008a7220441ff00713a000802402008420787220850200441c00071452202712008427f52200272734101470d00034020032004418001723a00082005200341086a4101102520032008a7220441ff00713a00082008420787220850200441c00071452202712008427f52200272470d000b0b2005200341086a410110250c8c010b200141086a2903002108200341c4003a0008200241046a2204200341086a41011025200320083703082004200341086a410810250c8b010b200341c5003a0008200241046a200341086a410110250c8a010b200341c6003a0008200241046a200341086a410110250c89010b200341c7003a0008200241046a200341086a410110250c88010b200341ca003a0008200241046a200341086a410110250c87010b200341cd003a0008200241046a200341086a410110250c86010b200341ce003a0008200241046a200341086a410110250c85010b200341d1003a0008200241046a200341086a410110250c84010b200341d2003a0008200241046a200341086a410110250c83010b200341d3003a0008200241046a200341086a410110250c82010b200341d4003a0008200241046a200341086a410110250c81010b200341d5003a0008200241046a200341086a410110250c80010b200341d6003a0008200241046a200341086a410110250c7f0b200341d9003a0008200241046a200341086a410110250c7e0b200341dd003a0008200241046a200341086a410110250c7d0b200341df003a0008200241046a200341086a410110250c7c0b200341e1003a0008200241046a200341086a410110250c7b0b200341e2003a0008200241046a200341086a410110250c7a0b200341e3003a0008200241046a200341086a410110250c790b200341e4003a0008200241046a200341086a410110250c780b200341e7003a0008200241046a200341086a410110250c770b200341eb003a0008200241046a200341086a410110250c760b200341ec003a0008200241046a200341086a410110250c750b200341ed003a0008200241046a200341086a410110250c740b200341ee003a0008200241046a200341086a410110250c730b200341ef003a0008200241046a200341086a410110250c720b200341f0003a0008200241046a200341086a410110250c710b200341f2003a0008200241046a200341086a410110250c700b200341f3003a0008200241046a200341086a410110250c6f0b200341f4003a0008200241046a200341086a410110250c6e0b200341f8003a0008200241046a200341086a410110250c6d0b200341f9003a0008200241046a200341086a410110250c6c0b200341fa003a0008200241046a200341086a410110250c6b0b200341fc003a0008200241046a200341086a410110250c6a0b200341fd003a0008200241046a200341086a410110250c690b200341fe003a0008200241046a200341086a410110250c680b200341ff003a0008200241046a200341086a410110250c670b20034180013a0008200241046a200341086a410110250c660b20034181013a0008200241046a200341086a410110250c650b20034182013a0008200241046a200341086a410110250c640b20034183013a0008200241046a200341086a410110250c630b20034185013a0008200241046a200341086a410110250c620b20034187013a0008200241046a200341086a410110250c610b2003418a013a0008200241046a200341086a410110250c600b2003418d013a0008200241046a200341086a410110250c5f0b2003418e013a0008200241046a200341086a410110250c5e0b2003418f013a0008200241046a200341086a410110250c5d0b20034190013a0008200241046a200341086a410110250c5c0b20034192013a0008200241046a200341086a410110250c5b0b20034193013a0008200241046a200341086a410110250c5a0b20034194013a0008200241046a200341086a410110250c590b20034196013a0008200241046a200341086a410110250c580b20034197013a0008200241046a200341086a410110250c570b2003419a013a0008200241046a200341086a410110250c560b2003419b013a0008200241046a200341086a410110250c550b2003419c013a0008200241046a200341086a410110250c540b2003419d013a0008200241046a200341086a410110250c530b2003419e013a0008200241046a200341086a410110250c520b2003419f013a0008200241046a200341086a410110250c510b200341a0013a0008200241046a200341086a410110250c500b200341a1013a0008200241046a200341086a410110250c4f0b200341a4013a0008200241046a200341086a410110250c4e0b200341a6013a0008200241046a200341086a410110250c4d0b200341a7013a0008200241046a200341086a410110250c4c0b200341aa013a0008200241046a200341086a410110250c4b0b200341ab013a0008200241046a200341086a410110250c4a0b200341ad013a0008200241046a200341086a410110250c490b200341ae013a0008200241046a200341086a410110250c480b200341af013a0008200241046a200341086a410110250c470b200341b0013a0008200241046a200341086a410110250c460b200341b1013a0008200241046a200341086a410110250c450b200341b2013a0008200241046a200341086a410110250c440b200341b3013a0008200241046a200341086a410110250c430b200341b4013a0008200241046a200341086a410110250c420b200341b5013a0008200241046a200341086a410110250c410b200341b6013a0008200241046a200341086a410110250c400b200341b7013a0008200241046a200341086a410110250c3f0b200341b8013a0008200241046a200341086a410110250c3e0b200341b9013a0008200241046a200341086a410110250c3d0b200341ba013a0008200241046a200341086a410110250c3c0b200341bb013a0008200241046a200341086a410110250c3b0b200341bc013a0008200241046a200341086a410110250c3a0b200341bd013a0008200241046a200341086a410110250c390b200341be013a0008200241046a200341086a410110250c380b200341bf013a0008200241046a200341086a410110250c370b2003410b3a0008200241046a200341086a410110250c360b200141046a28020021042003410c3a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000c360b0b200141046a28020021042003410d3a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000c350b0b2001410c6a2802002105200141086a2802002109200141046a280200210a2003410e3a0008200241046a2202200341086a41011025200341003a00082009210103402003200141800172200141ff0071200141077622041b3a00082002200341086a410110252004210120040d000b2003200a200a20094102746a102e02402003280200220620032802042207460d00034020062802002101200341003a000803402003200141800172200141ff0071200141077622041b3a00082002200341086a410110252004210120040d000b200641046a22062007470d000b0b200341003a000803402003200541800172200541ff0071200541077622011b3a00082002200341086a410110252001210520010d000b0240200941ffffffff0371450d00200a10010b2000411a3a0000200341106a24000f0b2003411a3a0008200241046a200341086a410110250c320b200141046a2802002104200341223a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000c320b0b200141086a2802002104200141046a28020021052003412d3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c310b0b200141086a2802002104200141046a28020021052003412e3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c300b0b200141086a2802002104200141046a2802002105200341313a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2f0b0b200141086a2802002104200141046a2802002105200341323a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2e0b0b200141086a2802002104200141046a2802002105200341333a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2d0b0b200141086a2802002104200141046a2802002105200341373a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2c0b0b200141086a2802002104200141046a2802002105200341393a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2b0b0b200141086a2802002104200141046a28020021052003413a3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2a0b0b20012d000121042003413f3a0008200241046a2202200341086a41011025200320043a00082002200341086a410110250c280b200141046a2802002104200341c3003a0008200241046a2202200341086a41011025200320043602082002200341086a410410250c270b200341c8003a0008200241046a200341086a410110250c260b200341c9003a0008200241046a200341086a410110250c250b200341cb003a0008200241046a200341086a410110250c240b200341cc003a0008200241046a200341086a410110250c230b200341cf003a0008200241046a200341086a410110250c220b200341d0003a0008200241046a200341086a410110250c210b200341d7003a0008200241046a200341086a410110250c200b200341d8003a0008200241046a200341086a410110250c1f0b200341da003a0008200241046a200341086a410110250c1e0b200341db003a0008200241046a200341086a410110250c1d0b200341dc003a0008200241046a200341086a410110250c1c0b200341de003a0008200241046a200341086a410110250c1b0b200341e0003a0008200241046a200341086a410110250c1a0b200341e5003a0008200241046a200341086a410110250c190b200341e6003a0008200241046a200341086a410110250c180b200341e8003a0008200241046a200341086a410110250c170b200341e9003a0008200241046a200341086a410110250c160b200341ea003a0008200241046a200341086a410110250c150b200341f1003a0008200241046a200341086a410110250c140b200341f5003a0008200241046a200341086a410110250c130b200341f6003a0008200241046a200341086a410110250c120b200341f7003a0008200241046a200341086a410110250c110b200341fb003a0008200241046a200341086a410110250c100b20034184013a0008200241046a200341086a410110250c0f0b20034186013a0008200241046a200341086a410110250c0e0b20034188013a0008200241046a200341086a410110250c0d0b20034189013a0008200241046a200341086a410110250c0c0b2003418b013a0008200241046a200341086a410110250c0b0b2003418c013a0008200241046a200341086a410110250c0a0b20034191013a0008200241046a200341086a410110250c090b20034195013a0008200241046a200341086a410110250c080b20034198013a0008200241046a200341086a410110250c070b20034199013a0008200241046a200341086a410110250c060b200341a2013a0008200241046a200341086a410110250c050b200341a3013a0008200241046a200341086a410110250c040b200341a5013a0008200241046a200341086a410110250c030b200341a8013a0008200241046a200341086a410110250c020b200341a9013a0008200241046a200341086a410110250c010b200341ac013a0008200241046a200341086a410110250b2000411a3a0000024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200341106a24000bef03030a7f017e017f230041306b22022400200241216a220341076a210441002105410021064100210741002108410821090240024002400340200241186a200110ab0220022802184101460d01200220032900003703082002200429000037000f200241186a41086a2d0000210a2002200229000f37001f20022002290308370318024020072008470d00200741016a220b2007490d032005200b200b2005491b2208ad420486220c422088a70d03200ca7220b4100480d0302402007450d00200b1000220d450d05200d2009200b20062006200b4b1b10f802210b20091001200b21090c010b200b10002209450d040b200920066a220b200a3a0000200b41086a200229001f370000200b41016a2002290318370000200541026a2105200641106a2106200741016a2107200a41ff01714106470d000b20002009360204200041003602002000410c6a2007360200200041086a2008360200200241306a24000f0b2000200229021c370204200041013602002000410c6a200241186a410c6a29020037020002402007450d00200921070340024020072d00004109470d00200741086a28020041ffffffff0371450d00200741046a28020010010b200741106a2107200641706a22060d000b0b02402008450d00200910010b200241306a24000f0b1018000b200b41081019000bdf5103067f017e037f230041e0006b22022400024020012802082203200128020c2204470d00200241013a0040200241dc006a4101360200200241c8006a410c6a41013602002002410f360234200241e0c3c1003602502002410136024c200241b08fc2003602482002200241c0006a3602302002200241306a360258200241086a200241c8006a104d200241d3006a200241106a2802003600002002200229030837004b2002200241cf006a29000037001f20022002290048370318200041053a000420004101360200200020022903183700052000410c6a200229001f370000200241e0006a24000f0b200441016a2105024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402004417f460d0020032005490d012001280200220620046a2d000021072001410c6a20053602000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200741bf014b0d000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020070ec001ac02ac0200840124ac02aa01aa01aa01aa01aa01a801a501a701a101200b11aa01aa01aa01aa01aa01aa01aa01aa01a60103aa01aa01aa01aa0112189801511aaa01aa01aa0121520533069f0186016f238f019e01a40132080d8801379b01a20104013841714970548b010209441476783f8101752226778701070c252c1016920194011f96019a01a3015ba0011599015e1b5a0f9c019d011d900174720a0e42452813950119602f91018e01890129173497013a27644b5565624a7c407b2e8a0185012b8c0193011c463e2d8d016e3b1e7d5f487982012a3130363d6d5c6c80017f3583014e4f7e7366617a695d39533c674c436a4d6b5768634756505859ac020b20032005470dc301200241013a002f200241dc006a4101360200200241d4006a41013602002002410f360244200241e0c3c1003602502002410136024c200241b08fc20036024820022002412f6a3602402002200241c0006a360258200241306a200241c8006a104d200241d2006a200241386a2802003601002002200229033037014a2002200241ce006a29010037011e20022002290148370318410521010cf2010b200241186a200110ac0220022802184101470da9012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200320056b41084f0da901200241013a0030200241dc006a4101360200200241d4006a41013602002002410f36020c200241e0c3c1003602502002410136024c200241b08fc2003602482002200241306a3602082002200241086a360258200241186a200241c8006a104d20022903182108200041106a2002280220360200200041086a200837020020004281808080d000370300200241e0006a24000f0b410e21070ca5010b200241186a200110ac0220022802184101470da8012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241186a200110ac0220022802184101470da8012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241186a200110ac0220022802184101470da8012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b413d21070ca1010b200241186a200110ac0220022802184101470da7012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b413121070c9f010b41d70021070c9e010b200241c8006a200110ac0220022802484101470da5012000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b413e21070c9c010b200241186a200110ac0220022802184101470da4012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41d80021070c9a010b41d00021070c99010b41c10021070c98010b200241c8006a200110ac0220022802484101470da1012000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200241c8006a200110ac0220022802484101470da1012000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b41dc0021070c95010b413321070c94010b41cb0021070c93010b41c20021070c92010b41e50021070c91010b200241c8006a200110ac0220022802484101470d9c012000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b41de0021070c8f010b200241c8006a200110ac0220022802484101470d9b012000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b41ce0021070c8d010b41f90021070c8c010b41d30021070c8b010b41800121070c8a010b41c50021070c89010b410a21070c88010b200241186a200110ac0220022802184101470d95012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b413921070c86010b200241186a200110ac0220022802184101470d94012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b20032005470d9401200241013a002f200241dc006a4101360200200241d4006a41013602002002410f360244200241e0c3c1003602502002410136024c200241b08fc20036024820022002412f6a3602402002200241c0006a360258200241306a200241c8006a104d200241d2006a200241386a2802003601002002200229033037014a2002200241ce006a29010037011e20022002290148370318410521010cca010b413f21070c83010b413a21070c82010b41e90021070c81010b41db0021070c80010b41e40021070c7f0b41860121070c7e0b41f60021070c7d0b41c00021070c7c0b41fc0021070c7b0b41f30021070c7a0b41e00021070c790b41880121070c780b41870121070c770b200241186a200110ac0220022802184101470d87012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241186a200110ac0220022802184101470d87012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41e60021070c740b41900121070c730b41890121070c720b200241186a200110ac0220022802184101470d84012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241186a200110ac0220022802184101470d84012000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b419b0121070c6f0b41e80021070c6e0b41ff0021070c6d0b419d0121070c6c0b418a0121070c6b0b41fb0021070c6a0b413621070c690b41f10021070c680b200241186a200110ac0220022802184101470d7c2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41d90021070c660b41a00121070c650b413221070c640b41da0021070c630b41fa0021070c620b41a70121070c610b41830121070c600b20032005470d75200241013a0040200241dc006a4101360200200241c8006a410c6a41013602002002410f360234200241e0c3c1003602502002410136024c200241b08fc2003602482002200241c0006a3602302002200241306a360258200241086a200241c8006a104d200241d3006a200241106a2802003600002002200229030837004b2002200241cf006a29000037001f20022002290048370318200041053a000420004101360200200020022903183700052000410c6a200229001f370000200241e0006a24000f0b41ef0021070c5e0b41eb0021070c5d0b419f0121070c5c0b41a20121070c5b0b41920121070c5a0b41930121070c590b41a90121070c580b200241c8006a200110ac0220022802484101470d6e2000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200241186a200110ac0220022802184101470d6e2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b419c0121070c550b42002108410021042001410c6a21090340410e210a2004413f4b0dac0120032005460d7f2005417f460dbc012003200541016a2201490dbd01200620056a2d0000210720092001360200200741ff0071220bad2004413f71ad862008842108200441076a21042001210520074118744118752201417f4c0d000b200141c0007121072004413f4b0da1012007450da1012008427f2004413f71ad86842108412e21070cd5010b41ec0021070c530b41a80121070c520b41a40121070c510b41aa0121070c500b41ab0121070c4f0b41cf0021070c4e0b41c90021070c4d0b418c0121070c4c0b419a0121070c4b0b41cd0021070c4a0b41820121070c490b41df0021070c480b41970121070c470b41ee0021070c460b41a60121070c450b41ea0021070c440b41ed0021070c430b41960121070c420b419e0121070c410b41a50121070c400b41990121070c3f0b41a10121070c3e0b41a30121070c3d0b418d0121070c3c0b418b0121070c3b0b41fe0021070c3a0b200241186a200110ac0220022802184101470d522000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b2001410c6a210b410021014100210a0340410d21092001411f4b0db90120032005460d642005417f460da2012003200541016a2204490da301200620056a2d00002107200b2004360200200741ff00712001411f7174200a72210a200141076a210120042105200741187441187522044100480d000b200441c0007121072001411f4b0d86012007450d8601200a417f2001411f717472210a412d21070cba010b20032005470d51200241013a0040200241dc006a4101360200200241c8006a410c6a41013602002002410f360234200241e0c3c1003602502002410136024c200241b08fc2003602482002200241c0006a3602302002200241306a360258200241086a200241c8006a104d200241d3006a200241106a2802003600002002200229030837004b2002200241cf006a29000037001f20022002290048370318200041053a000420004101360200200020022903183700052000410c6a200229001f370000200241e0006a24000f0b41d60021070c360b41950121070c350b41d50021070c340b413821070c330b413421070c320b413b21070c310b413521070c300b41840121070c2f0b41980121070c2e0b41f20021070c2d0b41f00021070c2c0b41810121070c2b0b41940121070c2a0b418f0121070c290b418e0121070c280b413721070c270b41850121070c260b41910121070c250b20032005470d40200241013a002f200241dc006a4101360200200241d4006a41013602002002410f360244200241e0c3c1003602502002410136024c200241b08fc20036024820022002412f6a3602402002200241c0006a360258200241306a200241c8006a104d200241d2006a200241386a2802003601002002200229033037014a2002200241ce006a29010037011e20022002290148370318410521010c700b41f50021070c230b200241186a200110ac0220022802184101470d3f2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b413c21070c210b200241186a200110ac0220022802184101470d3e2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41e30021070c1f0b41f40021070c1e0b200320056b41044f0d3c200241013a0030200241dc006a4101360200200241d4006a41013602002002410f36020c200241e0c3c1003602502002410136024c200241b08fc2003602482002200241306a3602082002200241086a360258200241186a200241c8006a104d20004281808080d000370300200041086a2002290218370200200041106a200241186a41086a280200360200200241e0006a24000f0b41f70021070c1c0b41fd0021070c1b0b41e20021070c1a0b200241186a200110ac0220022802184101470d392000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41d40021070c180b41e10021070c170b41c30021070c160b41f80021070c150b41c40021070c140b41dd0021070c130b41c60021070c120b41e70021070c110b200241c8006a200110ac0220022802484101470d312000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b41cc0021070c0f0b41c70021070c0e0b200241186a200110ac0220022802184101470d2f2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41d10021070c0c0b41d20021070c0b0b200241186a200110ac0220022802184101470d2d2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241186a200110ac0220022802184101470d2d2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41ca0021070c080b200241c8006a200110ad0220022802484101470d2c200041013602002000200241c8006a41047222012902003702042000410c6a200141086a290200370200200241e0006a24000f0b200241186a200110ac0220022802184101470d2c2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b41c80021070c050b200241186a200110ac0220022802184101470d2b2000200229021c370204200041013602002000410c6a200241186a410c6a290200370200200241e0006a24000f0b200241c8006a200110ac0220022802484101470d2b2000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b410d21070c020b200241c8006a200110ac0220022802484101470d2a2000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b410621070b0c80010b2000410b3a000420004101360200200041056a20073a0000200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d292000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200441096a2104200541784f0d6720032004490d68200620056a29000021082001410c6a2004360200413021070c7d0b200228021c210a200241c8006a200110ac0220022802484101470d282000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d282000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d282000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d282000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228024c210a410b21070c790b200228021c210a200241c8006a200110ac0220022802484101470d272000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200141086a28020022072001410c6a2802002204470d27200241013a0040200241dc006a4101360200200241c8006a410c6a41013602002002410f360234200241e0c3c1003602502002410136024c200241b08fc2003602482002200241c0006a3602302002200241306a360258200241086a200241c8006a104d200241d3006a200241086a41086a2802003600002002200229030837004b2002200241cf006a29000037001f20022002290048370318200041053a000420004101360200200020022903183700052000410c6a200229001f370000200241e0006a24000f0b200228024c210a410f21070c760b200228024c210a411021070c750b200228024c210a411321070c740b200228021c210a200241c8006a200110ac0220022802484101470d242000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d242000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200441026a21072005417f460d5c20032007490d5d200620056a2c000021042001410c6a20073602004100210920044100480d34200441017441807f71200472220441ff0171220741847e6a220141034b0d3e024020010e04004e4c4d000b41032109410421070c720b200228021c210a200241c8006a200110ac0220022802484101470d232000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d232000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d232000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d232000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d232000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200441026a21042005417f460d5820032004490d59200620056a2d000021072001410c6a20043602002007450d30200041153a000420004101360200200041056a20073a0000200241e0006a24000f0b200228024c210a411221070c6a0b200228021c210a200241c8006a200110ac0220022802484101470d212000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d212000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200441026a21042005417f460d5620032004490d57200620056a2d000021072001410c6a20043602002007450d2d200041153a000420004101360200200041056a20073a0000200241e0006a24000f0b200441026a21072005417f460d5720032007490d58200620056a2c000021042001410c6a20073602004100210920044100480d2d200441017441807f71200472220441ff0171220741847e6a220141034b0d34024020010e0400464445000b41032109410221070c670b200441026a21072005417f460d5820032007490d59200620056a2c000021042001410c6a20073602004100210920044100480d2e200441017441807f71200472220441ff0171220741847e6a220141034b0d34024020010e0400484647000b41032109410321070c660b200228021c210a200241c8006a200110ac0220022802484101470d1e2000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d1e2000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200441056a21042005417c4f0d5720032004490d58200620056a280000210a2001410c6a2004360200412f21070c620b200228021c210a200241c8006a200110ac0220022802484101470d1d2000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228024c210a411121070c600b200228021c210a200241c8006a200110ac0220022802484101470d1c2000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d1c2000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d1c2000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200241d4006a2802002107200241d0006a28020021052002200228024c22043602202002200536021c200220043602182002200420074102746a360224200241086a200241186a104320022802082105200228020c220720022802102204470d1c2005210a200721040c2f0b200228021c210a200241c8006a200110ac0220022802484101470d1c2000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228021c210a200241c8006a200110ac0220022802484101470d1c2000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200241e0006a24000f0b200228024c210a410721070c590b200228024c210a410821070c580b200241013a0040200241dc006a4101360200200241d4006a41013602002002410f36020c200241e0c3c1003602502002410136024c200241b08fc2003602482002200241c0006a3602082002200241086a360258200241186a200241c8006a104d20022802202101200229031821084105210a0c2d0b200241013a0030200241dc006a4101360200200241d4006a41013602002002410f36020c200241e0c3c1003602502002410136024c200241b08fc2003602482002200241306a3602082002200241086a360258200241186a200241c8006a104d410521090c540b200235024c2108412821070c550b200235024c2108412721070c540b200235024c2108411621070c530b200235024c2108411821070c520b200235024c2108412121070c510b200235024c2108412221070c500b200441016a21052004417f460d4620072005490d47200228024c210a200128020020046a2d00002104410c21072001410c6a20053602002004450d1f200041163a000420004101360200200041056a20043a0000200241e0006a24000f0b200235024c2108411421070c4e0b200235024c2108411c21070c4d0b200235024c2108412021070c4c0b200235024c2108411721070c4b0b200235024c2108412421070c4a0b200235024c2108412921070c490b200235024c2108412a21070c480b200235024c2108411521070c470b200235024c2108411b21070c460b200235024c2108411a21070c450b200235024c2108412321070c440b200235024c2108411d21070c430b200235024c2108412521070c420b200235024c2108411e21070c410b200235024c2108411921070c400b20072004490d382004450d10200441027422031000220a450d39200a2005200320074102742207200720034b1b10f8021a0c110b200235024c2108412621070c3e0b200235024c2108411f21070c3d0b411821010b2002200229011e37010e200220022903183703080c380b412c2107410021090c3b0b412b2107410021090c3a0b411821010b2002200229011e37010e200220022903183703080c330b411821010b2002200229011e37010e200220022903183703080c300b200441c000490d082007450d08200b41ff00470d090c0b0b20014120490d0b2007450d0b2004417f7341ff00716741686a41ff01714105490d310c0c0b41062101200741c001470d2f41042109410421070c330b41062101200741c001470d2d41042109410221070c320b41062101200741c001470d2b41042109410321070c310b410021090c300b410021044104210a2007450d010b200510010b200241c8006a200110ac02024020022802484101470d002000200229024c370204200041013602002000410c6a200241c8006a410c6a290200370200200441ffffffff0371450d2f200a1001200241e0006a24000f0b200235024c4220862004ad842108410921070c2c0b200441c000490d022001450d020b0b200020022f00303b00052000200a3a000420004101360200200041106a2001360200200041086a2008370200200041076a200241326a2d00003a0000200241e0006a24000f0b412e21070c270b200441ff01716741686a41ff017141044b0d0020014120490d002007450d250b412d21070c260b410121090b410421070c250b41022109410421070c240b410121090b410221070c220b41022109410221070c210b410121090b410321070c1f0b41022109410321070c1e0b417f2005107a000b200520031076000b417f200541016a107a000b200541016a20031076000b417f200541016a107a000b200541016a20031076000b20052004107a000b200420031076000b417f2007107a000b200720031076000b417f2004107a000b200420031076000b417f2004107a000b200420031076000b417f2007107a000b200720031076000b417f2007107a000b200720031076000b20052004107a000b200420031076000b417f2005107a000b200520071076000b4190a0c200104f000b200341041019000b200020043a0005200020013a000420002002290308370106200041013602002000410c6a200229010e370100200241e0006a24000f0b200020043a0005200020013a000420002002290308370106200041013602002000410c6a200229010e370100200241e0006a24000f0b200020043a0005200020013a000420002002290308370106200041013602002000410c6a200229010e370100200241e0006a24000f0b2000200936020420004101360200200041086a2002290218370200200041106a200241186a41086a280200360200200241e0006a24000f0b0b0b20004100360200200041106a20083703002000410c6a200a360200200041096a20093a0000200041086a20073a00000b200241e0006a24000bab0301087f230041c0006b22022400410021032001410c6a2104200141086a210541002106024002400240024002400340200341204f0d012005280200220720042802002208460d02200841016a21092008417f460d0420072009490d05200128020020086a2d0000210820042009360200200841ff00712003411f71742006722106200341076a21032008418001710d000b20034120490d0220086741686a41ff017141044f0d02200041013602002000410d3a0004200241c0006a24000f0b200041013602002000410f3a0004200241c0006a24000f0b200241013a000f200241346a4101360200200241206a410c6a41013602002002410f36023c200241e0c3c10036022820024101360224200241b08fc20036022020022002410f6a3602382002200241386a360230200241106a200241206a104d2002412b6a200241186a28020036000020022002290310370023200041053a000420004101360200200020022900203700052000410c6a200241276a290000370000200241c0006a24000f0b2000410036020020002006360204200241c0006a24000f0b417f2009107a000b200920071076000bbc08030d7f017e017f230041c0006b22022400410021032001410c6a2104200141086a21054100210602400240024002400240024002400240024002400240024002400240024003402003411f4b0d012005280200220720042802002208460d02200841016a21092008417f460d0820072009490d09200128020020086a2d0000210820042009360200200841ff00712003411f71742006722106200341076a21032008418001710d000b200241086a200241186a41086a280200360200200220022902183703004104210a4100210b410d200641ff01712003411f4b20086741686a41ff01714104497122031b4100200641807e7120031b72210520030d034100210c02402005450d002001410c6a2104200141086a210d4100210b4100210c4104210a0340200b220e41016a210b410021034100210603402003411f4b0d07200d280200220720042802002208460d08200841016a21092008417f460d0c20072009490d0d200128020020086a2d0000210820042009360200200841ff00712003411f71742006722106200341076a21032008418001710d000b024020034120490d0020086741686a41ff01714104490d090b0240200e200c470d00200e4101742203200e41016a220820082003491b220cad420286220f422088a70d0e200fa722034100480d0e0240200e450d00200310002208450d102008200a2003200e4102742209200920034b1b10f8022103200a10012003210a0c010b20031000220a450d0f0b200a200e4102746a20064108762210410874200641ff017172360200200b2005490d000b0b2000200a360204200041003602002000410c6a200b360200200041086a200c360200200241c0006a24000f0b410f21050c010b200241013a000f2002413c6a4101360200200241346a41013602002002410f360214200241e0c3c1003602302002410136022c200241b08fc20036022820022002410f6a3602102002200241106a360238200241186a200241286a104d410521050b200241086a200241186a41086a280200360200200220022902183703000b2000200536020420004101360200200041086a2002290300370200200041106a200241086a2802003602000c0a0b410f21030c080b200241013a00002002413c6a4101360200200241346a4101360200200241286a41086a41e0c3c1003602002002410f360214200241386a200241106a3602002002410136022c200241b08fc20036022820022002360210200241186a200241286a104d200241186a41086a2802002106200228021c21092002280218210841002110410521030c070b410d21030c060b417f2009107a000b200920071076000b417f2009107a000b200920071076000b1018000b200341041019000b20004101360200200041106a20063602002000410c6a2009360200200041086a200836020020002010410874200372360204200c450d00200a1001200241c0006a24000f0b200241c0006a24000be84903057f017e027f230041106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220441aa014b0d00024020040eab0100020304057576777806070879090a0b7a0c0d0e0f1011127b7c13147d7e7f15161780011881018201191a1b1c83011d1e1f840120212223850186012487018801252689018a012728292a2b2c8b018c012d8d018e018f012e90012f910130313233920193013494019501960135363738393a97013b3c3d980199019a013e3f409b0141424344454647489c01499d014a9e019f014ba001a1014c4d4e4fa201505152a3015354a401a50155565758595a5b5ca601a7015da8015e5fa901aa016061ab0162636465666768696a6b6c6d6e6f7071727374000b200341013a0008200241046a200341086a410110250cab010b200341003a0008200241046a200341086a410110250caa010b20012d00012104200341023a0008200241046a2202200341086a41011025200342fffdf7e78f182004410374ad42f8018388a72204413f7141c00072200420044118744118754100481b3a00082002200341086a410110250ca9010b20012d00012104200341033a0008200241046a2202200341086a41011025200342fffdf7e78f182004410374ad42f8018388a72204413f7141c00072200420044118744118754100481b3a00082002200341086a410110250ca8010b20012d00012104200341043a0008200241046a2202200341086a41011025200342fffdf7e78f182004410374ad42f8018388a72204413f7141c00072200420044118744118754100481b3a00082002200341086a410110250ca7010b200341053a0008200241046a200341086a410110250ca6010b2003410f3a0008200241046a200341086a410110250ca5010b200141046a2802002104200341103a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000ca5010b0b200141046a280200210420012d00012106200341113a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000b200320063a00082005200341086a410110250ca3010b2003411b3a0008200241046a200341086a410110250ca2010b200141046a2802002104200341203a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000ca2010b0b200141046a2802002104200341213a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000ca1010b0b200141046a2802002104200341233a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000ca0010b0b200141046a2802002104200341243a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000c9f010b0b200141086a2802002104200141046a2802002105200341283a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c9e010b0b200141086a2802002104200141046a2802002105200341293a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c9d010b0b200141086a2802002104200141046a28020021052003412a3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c9c010b0b200141086a2802002104200141046a28020021052003412b3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c9b010b0b200141086a2802002104200141046a28020021052003412c3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c9a010b0b200141086a2802002104200141046a28020021052003412f3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c99010b0b200141086a2802002104200141046a2802002105200341303a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c98010b0b200141086a2802002104200141046a2802002105200341343a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c97010b0b200141086a2802002104200141046a2802002105200341353a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c96010b0b200141086a2802002104200141046a2802002105200341363a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c95010b0b200141086a2802002104200141046a2802002105200341383a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c94010b0b200141086a2802002104200141046a28020021052003413b3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c93010b0b200141086a2802002104200141046a28020021052003413c3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c92010b0b200141086a2802002104200141046a28020021052003413d3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c91010b0b200141086a2802002104200141046a28020021052003413e3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c90010b0b20012d00012104200341c0003a0008200241046a2202200341086a41011025200320043a00082002200341086a410110250c8e010b200141046a2802002106200341c1003a0008200241046a2207200341086a410110252003200641ff00713a0008024020064107752204200641c00071220272452004417f4720024572734101470d00034020032006418001723a00082007200341086a410110252003200441ff00713a0008200441c000712102200421062004410775220521042005200272452005417f4720024572470d000b0b2007200341086a410110250c8d010b200141086a2903002108200341c2003a0008200241046a2205200341086a4101102520032008a7220441ff00713a000802402008420787220850200441c00071452202712008427f52200272734101470d00034020032004418001723a00082005200341086a4101102520032008a7220441ff00713a00082008420787220850200441c00071452202712008427f52200272470d000b0b2005200341086a410110250c8c010b200141086a2903002108200341c4003a0008200241046a2204200341086a41011025200320083703082004200341086a410810250c8b010b200341c5003a0008200241046a200341086a410110250c8a010b200341c6003a0008200241046a200341086a410110250c89010b200341c7003a0008200241046a200341086a410110250c88010b200341ca003a0008200241046a200341086a410110250c87010b200341cd003a0008200241046a200341086a410110250c86010b200341ce003a0008200241046a200341086a410110250c85010b200341d1003a0008200241046a200341086a410110250c84010b200341d2003a0008200241046a200341086a410110250c83010b200341d3003a0008200241046a200341086a410110250c82010b200341d4003a0008200241046a200341086a410110250c81010b200341d5003a0008200241046a200341086a410110250c80010b200341d6003a0008200241046a200341086a410110250c7f0b200341d9003a0008200241046a200341086a410110250c7e0b200341dd003a0008200241046a200341086a410110250c7d0b200341df003a0008200241046a200341086a410110250c7c0b200341e1003a0008200241046a200341086a410110250c7b0b200341e2003a0008200241046a200341086a410110250c7a0b200341e3003a0008200241046a200341086a410110250c790b200341e4003a0008200241046a200341086a410110250c780b200341e7003a0008200241046a200341086a410110250c770b200341eb003a0008200241046a200341086a410110250c760b200341ec003a0008200241046a200341086a410110250c750b200341ed003a0008200241046a200341086a410110250c740b200341ee003a0008200241046a200341086a410110250c730b200341ef003a0008200241046a200341086a410110250c720b200341f0003a0008200241046a200341086a410110250c710b200341f2003a0008200241046a200341086a410110250c700b200341f3003a0008200241046a200341086a410110250c6f0b200341f4003a0008200241046a200341086a410110250c6e0b200341f8003a0008200241046a200341086a410110250c6d0b200341f9003a0008200241046a200341086a410110250c6c0b200341fa003a0008200241046a200341086a410110250c6b0b200341fc003a0008200241046a200341086a410110250c6a0b200341fd003a0008200241046a200341086a410110250c690b200341fe003a0008200241046a200341086a410110250c680b200341ff003a0008200241046a200341086a410110250c670b20034180013a0008200241046a200341086a410110250c660b20034181013a0008200241046a200341086a410110250c650b20034182013a0008200241046a200341086a410110250c640b20034183013a0008200241046a200341086a410110250c630b20034185013a0008200241046a200341086a410110250c620b20034187013a0008200241046a200341086a410110250c610b2003418a013a0008200241046a200341086a410110250c600b2003418d013a0008200241046a200341086a410110250c5f0b2003418e013a0008200241046a200341086a410110250c5e0b2003418f013a0008200241046a200341086a410110250c5d0b20034190013a0008200241046a200341086a410110250c5c0b20034192013a0008200241046a200341086a410110250c5b0b20034193013a0008200241046a200341086a410110250c5a0b20034194013a0008200241046a200341086a410110250c590b20034196013a0008200241046a200341086a410110250c580b20034197013a0008200241046a200341086a410110250c570b2003419a013a0008200241046a200341086a410110250c560b2003419b013a0008200241046a200341086a410110250c550b2003419c013a0008200241046a200341086a410110250c540b2003419d013a0008200241046a200341086a410110250c530b2003419e013a0008200241046a200341086a410110250c520b2003419f013a0008200241046a200341086a410110250c510b200341a0013a0008200241046a200341086a410110250c500b200341a1013a0008200241046a200341086a410110250c4f0b200341a4013a0008200241046a200341086a410110250c4e0b200341a6013a0008200241046a200341086a410110250c4d0b200341a7013a0008200241046a200341086a410110250c4c0b200341aa013a0008200241046a200341086a410110250c4b0b200341ab013a0008200241046a200341086a410110250c4a0b200341ad013a0008200241046a200341086a410110250c490b200341ae013a0008200241046a200341086a410110250c480b200341af013a0008200241046a200341086a410110250c470b200341b0013a0008200241046a200341086a410110250c460b200341b1013a0008200241046a200341086a410110250c450b200341b2013a0008200241046a200341086a410110250c440b200341b3013a0008200241046a200341086a410110250c430b200341b4013a0008200241046a200341086a410110250c420b200341b5013a0008200241046a200341086a410110250c410b200341b6013a0008200241046a200341086a410110250c400b200341b7013a0008200241046a200341086a410110250c3f0b200341b8013a0008200241046a200341086a410110250c3e0b200341b9013a0008200241046a200341086a410110250c3d0b200341ba013a0008200241046a200341086a410110250c3c0b200341bb013a0008200241046a200341086a410110250c3b0b200341bc013a0008200241046a200341086a410110250c3a0b200341bd013a0008200241046a200341086a410110250c390b200341be013a0008200241046a200341086a410110250c380b200341bf013a0008200241046a200341086a410110250c370b2003410b3a0008200241046a200341086a410110250c360b200141046a28020021042003410c3a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000c360b0b200141046a28020021042003410d3a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000c350b0b2001410c6a2802002105200141086a2802002109200141046a280200210a2003410e3a0008200241046a2202200341086a41011025200341003a00082009210103402003200141800172200141ff0071200141077622041b3a00082002200341086a410110252004210120040d000b2003200a200a20094102746a102e02402003280200220620032802042207460d00034020062802002101200341003a000803402003200141800172200141ff0071200141077622041b3a00082002200341086a410110252004210120040d000b200641046a22062007470d000b0b200341003a000803402003200541800172200541ff0071200541077622011b3a00082002200341086a410110252001210520010d000b0240200941ffffffff0371450d00200a10010b2000411a3a0000200341106a24000f0b2003411a3a0008200241046a200341086a410110250c320b200141046a2802002104200341223a0008200241046a2205200341086a41011025200341003a000803402003200441800172200441ff0071200441077622021b3a00082005200341086a410110252002210420020d000c320b0b200141086a2802002104200141046a28020021052003412d3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c310b0b200141086a2802002104200141046a28020021052003412e3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c300b0b200141086a2802002104200141046a2802002105200341313a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2f0b0b200141086a2802002104200141046a2802002105200341323a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2e0b0b200141086a2802002104200141046a2802002105200341333a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2d0b0b200141086a2802002104200141046a2802002105200341373a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2c0b0b200141086a2802002104200141046a2802002105200341393a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2b0b0b200141086a2802002104200141046a28020021052003413a3a0008200241046a2206200341086a41011025200341003a000803402003200541800172200541ff0071200541077622021b3a00082006200341086a410110252002210520020d000b200341003a000803402003200441800172200441ff0071200441077622021b3a00082006200341086a410110252002210420020d000c2a0b0b20012d000121042003413f3a0008200241046a2202200341086a41011025200320043a00082002200341086a410110250c280b200141046a2802002104200341c3003a0008200241046a2202200341086a41011025200320043602082002200341086a410410250c270b200341c8003a0008200241046a200341086a410110250c260b200341c9003a0008200241046a200341086a410110250c250b200341cb003a0008200241046a200341086a410110250c240b200341cc003a0008200241046a200341086a410110250c230b200341cf003a0008200241046a200341086a410110250c220b200341d0003a0008200241046a200341086a410110250c210b200341d7003a0008200241046a200341086a410110250c200b200341d8003a0008200241046a200341086a410110250c1f0b200341da003a0008200241046a200341086a410110250c1e0b200341db003a0008200241046a200341086a410110250c1d0b200341dc003a0008200241046a200341086a410110250c1c0b200341de003a0008200241046a200341086a410110250c1b0b200341e0003a0008200241046a200341086a410110250c1a0b200341e5003a0008200241046a200341086a410110250c190b200341e6003a0008200241046a200341086a410110250c180b200341e8003a0008200241046a200341086a410110250c170b200341e9003a0008200241046a200341086a410110250c160b200341ea003a0008200241046a200341086a410110250c150b200341f1003a0008200241046a200341086a410110250c140b200341f5003a0008200241046a200341086a410110250c130b200341f6003a0008200241046a200341086a410110250c120b200341f7003a0008200241046a200341086a410110250c110b200341fb003a0008200241046a200341086a410110250c100b20034184013a0008200241046a200341086a410110250c0f0b20034186013a0008200241046a200341086a410110250c0e0b20034188013a0008200241046a200341086a410110250c0d0b20034189013a0008200241046a200341086a410110250c0c0b2003418b013a0008200241046a200341086a410110250c0b0b2003418c013a0008200241046a200341086a410110250c0a0b20034191013a0008200241046a200341086a410110250c090b20034195013a0008200241046a200341086a410110250c080b20034198013a0008200241046a200341086a410110250c070b20034199013a0008200241046a200341086a410110250c060b200341a2013a0008200241046a200341086a410110250c050b200341a3013a0008200241046a200341086a410110250c040b200341a5013a0008200241046a200341086a410110250c030b200341a8013a0008200241046a200341086a410110250c020b200341a9013a0008200241046a200341086a410110250c010b200341ac013a0008200241046a200341086a410110250b2000411a3a0000024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200341106a24000bfa0301047f0240024002400240024002400240200141046a2802002202200141086a28020022036b41204f0d00200341206a22042003490d0420024101742203200420042003491b22034100480d042002450d0120012802002105200310002204450d052004200520032002200220034b1b10f8021a200510010c020b200128020021040c020b200310002204450d030b20012004360200200141046a2003360200200141086a28020021030b200141086a2205200341206a360200200420036a220341186a200041186a290000370000200341106a200041106a290000370000200341086a200041086a290000370000200320002900003700000240024002400240200141046a2802002202200528020022036b41204f0d00200341206a22042003490d0420024101742203200420042003491b22034100480d042002450d0120012802002105200310002204450d062004200520032002200220034b1b10f8021a200510010c020b200128020021040c020b200310002204450d040b20012004360200200141046a2003360200200141086a28020021030b200141086a200341206a360200200420036a220141186a200041386a290000370000200141106a200041306a290000370000200141086a200041286a290000370000200120002900203700000f0b1018000b200341011019000b200341011019000b3400200041829cc10036020420004100360200200041146a4101360200200041106a41d8e6c200360200200041086a420f3702000b4b00200041ddf5c10036020420004100360200200041206a41013602002000411c6a4194e7c200360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000b130020004101360204200041c4e7c2003602000b8fcd01040b7f017e0d7f017e230041b0016b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2204410d4b0d00024020040e0e00090607030a0c080e050d02040b000b200141186a2802002105200141146a2802002104200141106a28020021062001410c6a2802002107200141086a2802002108200141046a2802002109200341f8006a4100200210b402200320032900793703002003200341f8006a41086a29000037000720032d0078220a411a470d16200341f8006a41146a2005360200200341f8006a41106a2004360200200320063602840120032007360280012003200836027c200320093602782003200341f8006a200210b502200320032900013703a0012003200341086a2900003700a70120032d00002204411a470d2241012102410021090c530b2001410c6a2802002106200141086a2802002104200141046a2802002108200341f8006a20012d0001200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782209411a470d0d200241046a2802002207200241086a28020022096b20064f0d20200920066a22052009490d8d0120074101742209200520052009491b22094100480d8d012007450d462002280200210a200910002205450d9f012005200a20092007200720094b1b10f8021a200a10010c470b200341d8006a41086a2001410c6a2802003602002003200141046a290200370358200341f8006a410b200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782204411a470d0d200328025c21072003280258210920032802602105200341a0016a410c6a4100360200200342013702a401200320023602a001200341003a005720092005411c6c6a210b200341a0016a41047221062005210403402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b2003200b36020c20032009360208200320073602042003200936020002402005450d00200341f8006a410172210c0340200341086a2009411c6a22023602002009280204220a450d01200941186a2802002105200941146a280200210d200941086a290200210e2009280210210720092802002104200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b2003200e37021c2003200a360218200341f8006a200341186a200341a0016a10a80220032d00782204411a470d42200341003a00572005210403402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b20062007200510250240200d450d00200710010b200320032900970137006f2003200329039001370368200221092002200b470d000b0b20031030200341ac016a280200210d200341a0016a41086a280200210c20032802a401210b20032802a0012102200341003a0057200241046a2107200d210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d910120044101742209200620062009491b22094100480d91012004450d012002280200210a200910002206450d97012006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d95010b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b200241046a2802002206200241086a28020022046b200d4f0d242004200d6a22082004490d8c0120064101742204200820082004491b22044100480d8c012006450d6420022802002109200410002208450da4012008200920042006200620044b1b10f8021a200910010c650b2001410c6a2802002106200141086a280200210d200141046a280200210a200341f8006a4104200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782204411a470d0d200341f8006a410c6a41003602002003420137027c20032002360278200341003a00a001200341f8006a41047221022006210403402003200441800172200441ff0071200441077622081b3a00a0012002200341a0016a410110252008210420080d000b200a2006410c6c6a21072006450d27200a210403402004410c6a2109200428020422054102460d29200441086a280200210620042802002104200341f0003a00572002200341d7006a41011025200320054101463a00572002200341d7006a41011025200341003a005703402003200441800172200441ff0071200441077622081b3a00572002200341d7006a410110252008210420080d000b024020054101470d00200341003a005703402003200641800172200641ff0071200641077622041b3a00572002200341d7006a410110252004210620040d000b0b2009210420092007470d000b200721090c280b200341106a200141146a280200360200200341086a2001410c6a2902003703002003200141046a290200370300200341f8006a4100200210b402200320032900793703a0012003200341f8006a41086a2900003700a70120032d00782204411a470d0d410410002204450d9a012003420437027c20032004360278200341f8006a41df9dc10041041025200328028001210f200328027c211020032802782111200341106a28020021122003410c6a2802002113200341086a28020021142003280204211520032d000022164101460d3920164102460d3620164103470d3a20032d00012104200320133600532003201436004f2003201536004b200341c8006a41036a21084100211741012118410121194101211a0c740b2001410c6a2802002105200141086a2802002107200141046a2802002109200341f8006a4109200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782204411a470d0d200341a0016a410c6a4100360200200342013702a401200320023602a001200341003a005720092005411c6c6a210b200341a0016a41047221062005210403402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b2003200b36020c20032009360208200320073602042003200936020002402005450d00200341f8006a410172210c0340200341086a2009411c6a22053602002009280204220a450d01200941186a2802002102200941146a280200210d200941086a290200210e2009280210210720092802002104200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b2003200e37021c2003200a360218200341f8006a200341186a200341a0016a10a80220032d00782204411a470d40200341003a00572002210403402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b02402002450d00200720024102746a210920072102034020022802002104200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b200241046a22022009470d000b0b0240200d450d00200710010b200320032900970137006f2003200329039001370368200521092005200b470d000b0b20031030200341ac016a280200210d200341a0016a41086a280200210c20032802a401210b20032802a0012102200341003a0057200241046a2107200d210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d8e0120044101742209200620062009491b22094100480d8e012004450d012002280200210a200910002206450d95012006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d93010b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b200241046a2802002206200241086a28020022046b200d4f0d222004200d6a22082004490d890120064101742204200820082004491b22044100480d89012006450d6420022802002109200410002208450da2012008200920042006200620044b1b10f8021a200910010c650b2001410c6a2802002109200141086a2802002111200141046a2802002113200341f8006a4102200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782204411a470d0d2003410c6a41003602002003420137020420032002360200200341003a00782013200941286c6a2105200341047221082009210403402003200441800172200441ff0071200441077622061b3a00782008200341f8006a410110252006210420060d000b2009450d26200341f8006a410172221541076a2110201321090340200341f8006a41086a220a2009220241086a28020036020020032002290200370378200241286a210920022d001822074104460d28200241246a2800002106200241206a280000211b2002411c6a28000021042002411a6a2d00002114200241196a2c00002116200241146a280200210c200241106a280200210d200228020c210b200341a0016a41086a2202200a280200360200200320032903783703a001200341d8006a41086a220a2002280200360200200320032903a0013703582002200a280200360200200320032903583703a001200341f8006a200341a0016a200310b60220032d00782202411a470d56200341c8006a41086a200c3602002003200d36024c2003200b360248200341f8006a200341c8006a200310b602200320152900003703a001200320102900003700a70120032d00782202411a470d5802400240024020074101460d00024020074102460d0020074103470d02200341033a00a0012008200341a0016a4101102520032016417f732204413f7141c0007220042016417f4a1b3a00a0012008200341a0016a410110252003201441ff01714100473a00a0012008200341a0016a410110252003200341f8006a41076a29000037004f200320032900783703480c030b200341023a00a0012008200341a0016a410110252003201b4101463a00a0012008200341a0016a41011025200341003a005703402003200441800172200441ff0071200441077622021b3a00572008200341d7006a410110252002210420020d000b201b4101470d02200341003a00a00103402003200641800172200641ff0071200641077622041b3a00a0012008200341a0016a410110252004210620040d000c030b0b200341013a00a0012008200341a0016a41011025200341f0003a00a0012008200341a0016a410110252003201b4101463a00a0012008200341a0016a41011025200341003a005703402003200441800172200441ff0071200441077622021b3a00572008200341d7006a410110252002210420020d000b201b4101470d01200341003a00a00103402003200641800172200641ff0071200641077622041b3a00a0012008200341a0016a410110252004210620040d000c020b0b200341003a00a0012008200341a0016a41011025200341003a00a00103402003200441800172200441ff0071200441077622061b3a00a0012008200341a0016a410110252006210420060d000b0b200320032900970137006f200320032903900137036820092005470d000b200522092005470d280c290b2001410c6a2802002109200141086a2802002107200141046a2802002105200341f8006a4103200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782204411a470d0d200341f8006a410c6a41003602002003420137027c20032002360278200341003a0057200341f8006a41047221062009210403402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b02402009450d00200520094102746a210920052102034020022802002104200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b200241046a22022009470d000b0b02402007450d00200510010b20034184016a280200210d200341f8006a41086a280200210c200328027c210b20032802782102200341003a0057200241046a2107200d210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d8c0120044101742209200620062009491b22094100480d8c012004450d012002280200210a200910002206450d8d012006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d8b010b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b200241046a2802002206200241086a28020022046b200d4f0d1d2004200d6a22082004490d870120064101742204200820082004491b22044100480d87012006450d4620022802002109200410002208450d9b012008200920042006200620044b1b10f8021a200910010c470b2001410c6a2802002105200141086a280200210d200141046a280200210a200341f8006a4107200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782204411a470d0d2003410c6a41003602002003420137020420032002360200200341003a0057200a200541146c6a2109200341047221062005210403402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b2005450d28200341f8006a410172210b200341306a2107200a21080340200841146a2102200828020c22054104460d2a200841106a28020021042008290200210e200720082802083602002003200e370328200341f8006a200341286a200310b60220032d00782208411a470d3d200320053a00572006200341d7006a41011025200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b200320032900a70137009701200320032903a001370390012002210820022009470d000c2b0b0b2001410c6a2802002109200141086a280200210c200141046a280200210b200341f8006a4101200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782204411a470d0e200341f8006a410c6a41003602002003420137027c20032002360278200341003a00a001200b20094104746a210d200341f8006a41047221062009210403402003200441800172200441ff0071200441077622081b3a00a0012006200341a0016a410110252008210420080d000b2009450d2a200b21040340200441106a210520042d000d22074105460d2c200428020821022004290200210e200320042d000c3a00572006200341d7006a41011025200341003a0057200ea7210a2002210403402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b02402002450d00200a2104034020042c000022084104460d01200441016a210420032008417f732209413f7141c0007220092008417f4a1b3a00572006200341d7006a410110252002417f6a22020d000b0b0240200e428080808010540d00200a10010b024020074104470d00200341003a00572006200341d7006a41011025200521042005200d470d010c2e0b200341013a00572006200341d7006a410110252003200741ff00733a00572006200341d7006a41011025200521042005200d470d000c2d0b0b2001410c6a280200210d200141086a280200210b200141046a280200210a200341f8006a4105200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782204411a470d12200341f8006a410c6a41003602002003420137027c20032002360278200341003a00a001200a200d410c6c6a2107200341f8006a4104722102200d210403402003200441800172200441ff0071200441077622081b3a00a0012002200341a0016a410110252008210420080d000b200d450d2c200a210403402004410c6a2109200428020422054102460d2e200441086a280200210620042802002104200320054101463a00572002200341d7006a41011025200341003a005703402003200441800172200441ff0071200441077622081b3a00572002200341d7006a410110252008210420080d000b024020054101470d00200341003a005703402003200641800172200641ff0071200641077622041b3a00572002200341d7006a410110252004210620040d000b0b2009210420092007470d000b200721090c2d0b200141286a280200210c200141246a280200210a200141206a28020021072001411c6a2802002109200141186a280200210b200141146a280200210d2001410c6a290200210e200141086a2802002104200141046a2802002108200341f8006a4100200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782206411a470d122003410c6a410036020020034201370204200320023602002003200e3e02702003200436026c20032008360268200341f8006a200341e8006a200310b60220032d00782204411a470d1820034104722106200341003a0057200e422088a7210403402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b410121160240200d450d00200320093602702003200b36026c2003200d360268200341f8006a200341e8006a200310b60220032d00782204411a470d52410021160b200341003a00572007200c4104746a211b200c210403402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b201b2007460d7a2007210203402002220841106a21022008280200220541074b0d7c2008410c6a2802002109200841086a280200210420082802042108024002400240024002400240024002400240024020050e080005020301060704000b200341003a00572006200341d7006a41011025200341003a005703402003200841800172200841ff0071200841077622091b3a00572006200341d7006a410110252009210820090d000b200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000c080b0b200341043a00572006200341d7006a41011025200341003a005703402003200841800172200841ff0071200841077622051b3a00572006200341d7006a410110252005210820050d000b200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b2003200941ff00713a0057024020094107752204200941c00071220872452004417f4720084572734101470d00034020032009418001723a00572006200341d7006a410110252003200441ff00713a0057200441c000712108200421092004410775220521042005200872452005417f4720084572470d000b0b2006200341d7006a410110252002201b470d080c070b200341023a00572006200341d7006a41011025200341003a005703402003200841800172200841ff0071200841077622091b3a00572006200341d7006a410110252009210820090d000b200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000c060b0b200341033a00572006200341d7006a41011025200341003a005703402003200841800172200841ff0071200841077622051b3a00572006200341d7006a410110252005210820050d000b200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b2003200941ff00713a0057024020094107752204200941c00071220872452004417f4720084572734101470d00034020032009418001723a00572006200341d7006a410110252003200441ff00713a0057200441c000712108200421092004410775220521042005200872452005417f4720084572470d000b0b2006200341d7006a410110252002201b470d060c050b200341073a00572006200341d7006a41011025200341003a005703402003200841800172200841ff0071200841077622091b3a00572006200341d7006a410110252009210820090d000b200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000c040b0b200341013a00572006200341d7006a41011025200341003a005703402003200841800172200841ff0071200841077622091b3a00572006200341d7006a410110252009210820090d000b200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000c030b0b200341053a00572006200341d7006a41011025200341003a005703402003200841800172200841ff0071200841077622051b3a00572006200341d7006a410110252005210820050d000b200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b2003200941ff00713a0057024020094107752204200941c00071220872452004417f4720084572734101470d00034020032009418001723a00572006200341d7006a410110252003200441ff00713a0057200441c000712108200421092004410775220521042005200872452005417f4720084572470d000b0b2006200341d7006a410110252002201b470d030c020b200341063a00572006200341d7006a41011025200341003a005703402003200841800172200841ff0071200841077622091b3a00572006200341d7006a410110252009210820090d000b200341003a005703402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b0b2002201b470d010b0b201b21020c7b0b2001410c6a2802002105200141086a2802002107200141046a2802002109200341f8006a4106200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782204411a470d12200341a0016a410c6a4100360200200342013702a401200320023602a001200341003a0057200920054104746a2102200341a0016a41047221062005210403402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b2003200236020c20032009360208200320073602042003200936020002402005450d0020054104742108200341086a2107200341f8006a410172220a41076a210d03402007200941106a22023602002009410d6a2d000022044102460d012009290200210e200941086a280200210520032009410c6a2d000041ff00733a00572006200341d7006a41011025200320043a00572006200341d7006a41011025200341286a41086a20053602002003200e3e02282003200e4220883e022c200341f8006a200341286a200341a0016a10a8022003200a290000370390012003200d2900003700970120032d00782204411a470d3b20022109200841706a22080d000b0b20031033200341ac016a280200210d200341a0016a41086a280200210c20032802a401210b20032802a0012102200341003a0057200241046a2107200d210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d870120044101742209200620062009491b22094100480d87012004450d012002280200210a200910002206450d8f012006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d8d010b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b200241046a2802002206200241086a28020022046b200d4f0d1c2004200d6a22082004490d820120064101742204200820082004491b22044100480d82012006450d6420022802002109200410002208450d9d012008200920042006200620044b1b10f8021a200910010c650b2001410c6a2802002105200141086a2802002107200141046a2802002109200341f8006a410a200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782204411a470d1220034190016a410c6a410036020020034201370294012003200236029001200341003a00572009200541186c6a210220034190016a41047221062005210403402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b200320023602ac01200320093602a801200320073602a401200320093602a0012005450d342003410172220841076a2106034020092802002204450d33200941046a290200210e2009410c6a290200211c200341f8006a41146a200941146a280200360200200341f8006a410c6a201c3702002003200e37027c200320043602782003200341f8006a20034190016a10b702200320082900003703682003200629000037006f20032d00002204411a470d3a200941186a22092002470d000c340b0b200141046a2802002104200341f8006a4108200210b402200320032900793703002003200341f8006a41086a29000037000720032d00782208411a470d1220034184016a41003602002003420137027c20032002360278200341003a0057200341f8006a410472210603402003200441800172200441ff0071200441077622081b3a00572006200341d7006a410110252008210420080d000b20034184016a280200210d200341f8006a41086a280200210c200328027c210b20032802782102200341003a0057200241046a2107200d210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d850120044101742209200620062009491b22094100480d85012004450d012002280200210a200910002206450d87012006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d85010b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b200241046a2802002206200241086a28020022046b200d4f0d172004200d6a22082004490d800120064101742204200820082004491b22044100480d80012006450d4920022802002109200410002208450d97012008200920042006200620044b1b10f8021a200910010c4a0b20002003290300370001200020093a0000200041086a20032900073700004100210d410121154101210b4101210c4101211b410121164101210541012107410121144101210a410121004100450da7010ca9010b20002003290300370001200020043a0000200041086a200329000737000020032802582109024020032802602204450d0020092004411c6c6a210220092106034002402006410c6a2802002208450d0020062802042104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b0240200641086a280200450d00200641046a28020010010b2006411c6a21040240200641146a280200450d00200628021010010b2004210620042002470d000b0b410021074101210a200328025c450d1920091001410121140cab010b20002003290300370001200020043a0000200041086a200329000737000041002106410121150240200d450d00200a10010b410121004101210b410121020c0a0b200020032903a001370001200020043a0000200041086a20032900a70137000020032d000022044102460d2920044101460d2720040d2a4101210a41002114200341086a280200450da801200328020410010ca8010b20002003290300370001200020043a0000200041086a200329000737000002402005450d0020092005411c6c6a210220092106034002402006410c6a2802002208450d0020062802042104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b0240200641086a280200450d00200641046a28020010010b2006411c6a21040240200641146a280200450d00200628021010010b2004210620042002470d000b0b410021164101211502402007450d00200910010b410121004101210b4101210241012106410121094101210c4101211b0cac010b20002003290300370001200020043a0000200041086a200329000737000002402009450d00200941286c21082013210403400240200441046a280200450d00200428020010010b0240200441106a280200450d002004410c6a28020010010b200441286a2104200841586a22080d000b0b4100210b4101211502402011450d00201310010b410121000c050b20002003290300370001200020043a0000200041086a2003290007370000410021024101211502402007450d00200510010b410121004101210b0c050b20002003290300370001200020043a0000200041086a200329000737000002402005450d00200541146c2108200a210403400240200441046a280200450d00200428020010010b200441146a21042008416c6a22080d000b0b4100211b410121150240200d450d00200a10010b410121004101210b4101210241012106410121094101210c0ca8010b200020032903003700012000200a3a0000200041086a200329000737000002402008450d00200910010b02402004450d00200610010b410121004100211541010d014101210b4101210241012106410121094101210c4101211b410121164101210541012107410121144101210a4101210d20030da0010ca2010b20002003290300370001200020043a0000200041086a200329000737000002402009450d0020094104742108200b210403400240200441046a280200450d00200428020010010b200441106a2104200841706a22080d000b0b4100210041012115200c450d00200b10010b4101210b0b410121020b410121060b410121090ca0010b20002003290300370001200020043a0000200041086a200329000737000041002109410121150240200b450d00200a10010b410121004101210b41012102410121060c9f010b20002003290300370001200020063a0000200041086a200329000737000002402004450d00200810010b0240200d450d00200b450d00200d10010b0240200a450d00200710010b4100210a410121140c9c010b20002003290300370001200020043a0000200041086a200329000737000002402005450d00200920054104746a2102200921060340024020062802082208450d0020062802002104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b200641106a21040240200641046a280200450d00200628020010010b2004210620042002470d000b0b4100210c4101211502402007450d00200910010b410121004101210b4101210241012106410121090c9e010b20002003290300370001200020043a0000200041086a200329000737000002402005450d002009200541186c6a21022009210603400240200641046a280200450d00200628020010010b0240200641146a2802002208450d00200628020c2104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b200641186a21040240200641106a280200450d002006410c6a28020010010b2004210620042002470d000b0b410021054101211502402007450d00200910010b410121004101210b4101210241012106410121094101210c4101211b410121160ca0010b20002003290300370001200020083a0000200041086a2003290007370000410121154101210b0c3f0b200228020021050c270b200020032903a001370001200020043a0000200041086a20032900a7013700004101210b410021150c3c0b200320032900793703a001200320034180016a2900003700a70141002108200341086a280200450d91010c90010b200228020021080c2a0b200228020021080c330b200228020021080c410b200228020021080c430b200228020021080c490b410121140c91010b200a21090b200720096b2104024003402004450d01200441746a2104200928020421082009410c6a210920084102470d000b0b0240200d450d00200a10010b20034184016a280200210d200341f8006a41086a280200210c200328027c210b20032802782102200341003a0057200241046a2107200d210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d6720044101742209200620062009491b22094100480d672004450d012002280200210a200910002206450d6a2006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d680b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b0240200241046a2802002206200241086a28020022046b200d4f0d002004200d6a22082004490d6320064101742204200820082004491b22044100480d632006450d1f20022802002109200410002208450d762008200920042006200620044b1b10f8021a200910010c200b200228020021080c200b201321090b20092005460d010b0340200941186a2d00004104460d01200941106a28020021042009410c6a28020021080240200941046a280200450d00200928020010010b02402004450d00200810010b200941286a22092005470d000b0b02402011450d00201310010b2003410c6a280200210d200341086a280200210c2003280204210b20032802002102200341003a0057200241046a2107200d210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d6320044101742209200620062009491b22094100480d632004450d012002280200210a200910002206450d6f2006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d6d0b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b200241046a2802002206200241086a28020022046b200d4f0d082004200d6a22082004490d5e20064101742204200820082004491b22044100480d5e2006450d4920022802002109200410002208450d7c2008200920042006200620044b1b10f8021a200910010c4a0b200a21020b20022009460d0003402002410c6a2802004104460d010240200241046a280200450d00200228020010010b200241146a22022009470d000b0b0240200d450d00200a10010b2003410c6a280200210d200341086a280200210c2003280204210b20032802002102200341003a0057200241046a2107200d210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d6020044101742209200620062009491b22094100480d602004450d012002280200210a200910002206450d692006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d670b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b0240200241046a2802002206200241086a28020022046b200d4f0d002004200d6a22082004490d5c20064101742204200820082004491b22044100480d5c2006450d3a20022802002109200410002208450d762008200920042006200620044b1b10f8021a200910010c3b0b200228020021080c3b0b200b21050b2005200d460d0003402005410d6a2d00004105460d010240200541046a280200450d00200528020010010b200541106a2205200d470d000b0b0240200c450d00200b10010b20034184016a280200210d200341f8006a41086a280200210c200328027c210b20032802782102200341003a0057200241046a2107200d210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d5d20044101742209200620062009491b22094100480d5d2004450d012002280200210a200910002206450d612006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d5f0b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b0240200241046a2802002206200241086a28020022046b200d4f0d002004200d6a22082004490d5920064101742204200820082004491b22044100480d592006450d1b20022802002109200410002208450d6e2008200920042006200620044b1b10f8021a200910010c1c0b200228020021080c1c0b200a21090b200a200d410c6c6a20096b2104024003402004450d01200441746a2104200928020421082009410c6a210920084102470d000b0b0240200b450d00200a10010b20034184016a280200210d200341f8006a41086a280200210c200328027c210b20032802782102200341003a0057200241046a2107200d210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d5b20044101742209200620062009491b22094100480d5b2004450d012002280200210a200910002206450d602006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d5e0b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b0240200241046a2802002206200241086a28020022046b200d4f0d002004200d6a22082004490d5720064101742204200820082004491b22044100480d572006450d1d20022802002109200410002208450d6d2008200920042006200620044b1b10f8021a200910010c1e0b200228020021080c1e0b200228020021080c420b0240200341106a2802002208450d00200341086a28020021042008410c6c21080340024020042802002206450d00200441046a280200450d00200610010b2004410c6a2104200841746a22080d000b0b4101210a410021142003410c6a280200450d8001200341086a28020010010c80010b2003410036027020034201370368200341003a0057200341f0006a210d4101210a41002104410021082015210603402003200641807f72200641ff0071200641077622091b22053a0057024020082004470d00200441016a22062004490d5520044101742205200620062005491b22064100480d55200610002107024002402004450d002007450d652007200a20062004200420064b1b10f8021a200a10010c010b2007450d640b2003200636026c2003200736026820032d005721052007210a200621040b200d200841016a2206360200200a20086a20053a0000200621082009210620090d000b200341f8006a41106a220b201436020020034184016a20133602002003418c016a201420124104746a220d36020020032014360280012003201536027c20034100360278200341f8006a41086a211a2015450d3c41002104201421092015211803402009200d460d3d02400340200b200941106a2208360200200941046a280200220c0d01200441016a210420082109200d2008470d000c3e0b0b200941086a290200210e2003200441016a22193602782009280200211720032018417f6a221836027c200341003a0057200941106a2109200341e8006a41086a221b2802002106200328026c210803402003200441807f72200441ff0071200441077622051b220a3a0057024002400240024020062008470d00200841016a22042008490d5920084101742207200420042007491b22074100480d592008450d012003280268210a200710002204450d682004200a20072008200820074b1b10f8021a200a10010c020b200328026821040c020b200710002204450d660b2003200736026c2003200436026820032d0057210a200721080b201b200641016a2207360200200420066a200a3a0000200721062005210420050d000b200341a0016a41086a200e3703002003200c3602a401200320173602a00120034190016a200341a0016a200341e8006a10b80220032d0090012208411a470d532019210420180d000c3d0b0b0240200341106a2802002204450d00200341086a280200220920044104746a210003402009220241106a2109024020022802042204450d0002402002410c6a2802002208450d002008410c6c21080340024020042802002206450d00200441046a280200450d00200610010b2004410c6a2104200841746a22080d000b0b200241086a280200450d00200241046a28020010010b20092000470d000b0b4101210a410021142003410c6a280200450d7e200341086a28020010010c7e0b4101210a41002114200341086a280200450d7d200328020410010c7d0b4100211820034100360298012003420137039001200341f8006a410c6a2012360200200341f8006a41086a20133602002003201436027c20032015360278200341a0016a200341f8006a20034190016a10b80220032d00a0012208411a470d49200341d3006a20034198016a280200360000200320032903900137004b200341cb006a2108410121194100211a41002117410121040c3a0b4100211a20034100360298012003420137039001200320133602a801200320143602a401200320153602a001200341f8006a200341a0016a20034190016a10b90220032d00782208411a470d49200341d3006a20034190016a41086a280200360000200320032903900137004b200341cb006a2108410121184101211941012117410021040c390b200941186a21020b200341a8016a20023602000b200341a0016a10312003419c016a280200210d20034190016a41086a280200210c200328029401210b2003280290012102200341003a0057200241046a2107200d210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d5120044101742209200620062009491b22094100480d512004450d012002280200210a200910002206450d5b2006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d590b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b0240200241046a2802002206200241086a28020022046b200d4f0d002004200d6a22082004490d4d20064101742204200820082004491b22044100480d4d2006450d3220022802002109200410002208450d692008200920042006200620044b1b10f8021a200910010c330b200228020021080c330b2003200c290000370390012003200c41076a290000370097010240200d450d00200710010b200320032900970137006f20032003290390013703682003200329006f37004f20032003290368370348200310302003200329004f37003f200320032903483703380240200341a0016a41086a280200450d0020032802a40110010b2003200329003f37002f20032003290338370328200020043a000020002003290328370001200041086a200329002f37000041002107410121154101210b4101210c4101211b41012116410121050c220b2003200c290000370390012003200c41076a290000370097010240200d450d00200710010b200320032900970137006f20032003290390013703682003200329006f37004f20032003290368370348200310302003200329004f37003f200320032903483703380240200341a0016a41086a280200450d0020032802a40110010b2003200329003f37002f20032003290338370328200020043a000020002003290328370001200041086a200329002f37000041002116410121154101210b4101210c4101211b0c1f0b2003200b2900003703a0012003200b41076a2900003700a701200320032900a70137009701200320032903a00137039001200320032900970137006f2003200329039001370368024020022009460d0003402002410c6a2802004104460d010240200241046a280200450d00200228020010010b200241146a22022009470d000b0b0240200d450d00200a10010b2003200329006f37004f200320032903683703480240200341086a280200450d00200328020410010b2003200329004f37003f200320032903483703382008411a460d2a20002003290338370001200020083a0000200041086a200329003f3700004100211b410121154101210b4101210c0c1d0b200320032900970137006f2003200329039001370368200310332003200329006f37004f200320032903683703480240200341a0016a41086a280200450d0020032802a40110010b2003200329004f37003f20032003290348370338200020043a000020002003290338370001200041086a200329003f3700004100210c410121154101210b0c1b0b200341a0016a41086a200941186a360200200320032903683703482003200329006f37004f200341a0016a10312003200329004f37003f20032003290348370338024020034190016a41086a280200450d0020032802940110010b2003200329003f37002f20032003290338370328200020043a000020002003290328370001200041086a200329002f37000041002105410121154101210b4101210c4101211b410121160c1d0b200910002205450d580b20022005360200200241046a2009360200200241086a28020021090b200241086a200920066a360200200520096a2008200610f8021a41002105410121094101210241012113410121074101210a4101210d4101210b4101210c4101211b410121064101211641012114410121154100450d680c690b200410002208450d560b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200d6a360200200820046a200b200d10f8021a0240200c450d00200b10010b4100210a410121094101210241012113410121070c320b200410002208450d540b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200d6a360200200820046a200b200d10f8021a0240200c450d00200b10010b410021074101210941012102410121130c2e0b200410002208450d520b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200d6a360200200820046a200b200d10f8021a0240200c450d00200b10010b41002102410121090b0c060b200410002208450d4f0b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200d6a360200200820046a200b200d10f8021a0240200c450d00200b10010b4100210d410121094101210241012113410121074101210a0c290b200410002208450d4d0b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200d6a360200200820046a200b200d10f8021a0240200c450d00200b10010b41012109410121020b410121130c220b20032015290000370390012003201541076a29000037009701200d450d02200b10010c020b200320032900793703a001200320034180016a2900003700a70141012108200341086a2802000d570c580b200320032900a70137009701200320032903a001370390010b200320032900970137006f20032003290390013703682003200329006f37003f20032003290368370338024020092005460d000340200941186a2d00004104460d01200941106a28020021042009410c6a28020021080240200941046a280200450d00200928020010010b02402004450d00200810010b200941286a22092005470d000b0b02402011450d00201310010b2003200329003f37002f200320032903383703280240200341086a280200450d00200328020410010b2003200329002f37001f200320032903283703182002411a460d1d20002003290318370001200020023a0000200041086a200329001f3700004100210b410121150b0b4101210c0b4101211b0b410121160b410121050b410121070b410121144101210a4101210d4101210041010d520c500b200410002208450d3f0b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200d6a360200200820046a200b200d10f8021a0240200c450d00200b10010b2003200329003f37002f2003200329033837032841002116410121094101210241012113410121074101210a4101210d4101210b4101210c4101211b410121064101211441012115410121054101450d490c4a0b200410002208450d3d0b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200d6a360200200820046a200b200d10f8021a0240200c450d00200b10010b2003200329003f37002f200320032903383703284100211b410121094101210241012113410121074101210a4101210d4101210b4101210c0c170b200410002208450d3b0b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200d6a360200200820046a200b200d10f8021a0240200c450d00200b10010b2003200329004f37003f200320032903483703380b4100210c410121094101210241012113410121074101210a4101210d4101210b0c120b200410002208450d380b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200d6a360200200820046a200b200d10f8021a0240200c450d00200b10010b2003200329004f37003f200320032903483703384100210b410121094101210241012113410121074101210a4101210d0c0e0b200410002208450d360b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200d6a360200200820046a200b200d10f8021a0240200c450d00200b10010b2003200329003f37002f2003200329033837032841002106410121094101210241012113410121074101210a4101210d4101210b4101210c4101211b0c0e0b200320043602780b201a1032200341d3006a200341e8006a41086a2802003600002003200329036837004b200341cb006a21084102210441002119410121184100211a410021170b2008280000210c2003280053210a200328004f211b410110002207450d26200720043a0000200341003a00574101210441012108200a210603402003200641807f72200641ff0071200641077622091b22063a0057024002400240024020042008470d00200441016a22082004490d1a20044101742206200820082006491b22054100480d1a2004450d01200510002208450d252008200720052004200420054b1b10f802210820071001200821070c020b200421050c020b200510002207450d230b20032d0057210620042108200521040b200720086a20063a0000200841016a21082009210620090d000b0240024002400240200520086b200a4f0d002008200a6a22042008490d1920054101742206200420042006491b220d4100480d192005450d01200d1000220b450d36200b2007200d20052005200d4b1b10f802210420071001200420086a200c200a10f8021a201b0d020c030b2005210d2007220b20086a200c200a10f8021a201b0d010c020b200d1000220b450d34200b20086a200c200a10f8021a201b450d010b200c10010b2008200a6a210c024002402016450d000240024020164101460d0020164102470d03411a21072019450d3b2012450d01201420124104746a210a2014210503402005220941106a2105024020092802042204450d0002402009410c6a2802002208450d002008410c6c21080340024020042802002206450d00200441046a280200450d00200610010b2004410c6a2104200841746a22080d000b0b200941086a280200450d00200941046a28020010010b2005200a470d000c020b0b411a21072018450d3a2012450d002012410c6c2108201421040340024020042802002206450d00200441046a280200450d00200610010b2004410c6a2104200841746a22080d000b0b2013450d39201410010c390b411a21072017201445720d380c370b411a2107201a20144572450d360c370b200410002208450d320b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200d6a360200200820046a200b200d10f8021a0240200c450d00200b10010b2003200329002f37001f200320032903283703180b4100211341012109410121020b410121070b4101210a0b4101210d0b4101210b0b4101210c0b4101211b0b410121060b4101211641012114410121154101210541010d2e0c2d0b200721020b2007200c4104746a21080240034020082002460d0120022802002104200241106a210220044108470d000b0b0240200a450d00200710010b2003410c6a280200210c200341086a28020021142003280204211b20032802002102200341003a0057200241046a2107200c210403402003200441807f72200441ff0071200441077622081b22093a005702400240024002402007280200200241086a22052802002204470d00200441016a22062004490d0c20044101742209200620062009491b22094100480d0c2004450d012002280200210a200910002206450d192006200a20092004200420094b1b10f8021a200a10010c020b200228020021060c020b200910002206450d170b20022006360200200720093602002005280200210420032d005721090b2005200441016a360200200620046a20093a00002008210420080d000b0240200241046a2802002206200241086a28020022046b200c4f0d002004200c6a22082004490d0820064101742204200820082004491b22044100480d082006450d0420022802002109200410002208450d272008200920042006200620044b1b10f8021a200910010c050b200228020021080c050b200341a0016a41086a290300210e20032802a401210420032f00a10120032d00a301411074724108742008722107200328029401450d0120032802900110010c010b200341f8006a41086a290300210e200328027c210420032f007920032d007b411074724108742008722107200328029401450d0020032802900110010b4100210d4101210b0c240b200410002208450d220b20022008360200200241046a2004360200200241086a28020021040b200241086a2004200c6a360200200820046a201b200c10f8021a02402014450d00201b10010b02402016450d00200d450d00200b450d00200d10010b200320032900a70137009701200320032903a0013703900141002115410121094101210241012113410121074101210a4101210d4101210b4101210c4101211b410121064101211641012114410121054101450d250c260b20032d009301210620032f009101210920034190016a41086a290300210e2003280294012104201a1032200920064110747241087421060240200328026c450d00200328026810010b200620087221074101210b0240024002402016450d004100210d20164101460d0220164102460d234101210b20140d010c230b4100210d41000d222014450d220b201510010c210b02402012450d002012410c6c2106201421080340024020082802002209450d00200841046a280200450d00200910010b2008410c6a2108200641746a22060d000b0b4101210b2013450d20201410010c200b1018000b200941011019000b200941011019000b200941011019000b200941011019000b200941011019000b200941011019000b200941011019000b200941011019000b200941011019000b200941011019000b200541011019000b200941011019000b200941011019000b200641011019000b200741011019000b410441011019000b410141011019000b200941011019000b200441011019000b200441011019000b200441011019000b200441011019000b200441011019000b200441011019000b200441011019000b200441011019000b200441011019000b200441011019000b200d41011019000b200441011019000b200441011019000b4100210c0c020b201510010b0b024002400240200741ff0171411a470d002003418c016a200c36020020034188016a200d3602002003200b360284012003200f360280012003201036027c20032011360278200341a0016a200341f8006a200210b502200320032900a101370390012003200341a0016a41086a2900003700970120032d00a0012204411a470d0141002114410121094101210241012113410121074101210a4101210d4101210b4101210c4101211b410121064101211641012115410121054101450d030c040b0240200d450d00200b10010b20002007360200200041086a200e370200200041046a200436020041002114410121152010450d01201110010c010b2000200329039001370001200020043a0000200041086a20032900970137000041002114410121150b4101210b4101210c4101211b4101211641012105410121074101210a4101210d410121004101450d040c060b2004450d00200810010b2000411a3a0000024002400240024020012d00002204410e4b0d000240024002400240024002400240024002400240024002400240024020040e0f0009080703050a0b0d0e0c02060401000b2005450d24200141086a280200450d24200141046a2802001001200341b0016a24000f0b2015450d230240200141086a280200450d00200141046a28020010010b0240200141146a2802002204450d00200141186a280200450d00200410010b200141246a280200450d23200141206a2802001001200341b0016a24000f0b2006450d2202402001410c6a2802002204450d00200141046a2802002206200441186c6a210203400240200641046a280200450d00200628020010010b0240200641146a2802002208450d00200628020c2104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b200641186a21040240200641106a280200450d002006410c6a28020010010b2004210620042002470d000b0b200141086a280200450d22200141046a2802001001200341b0016a24000f0b2007450d21200141086a280200450d21200141046a2802001001200341b0016a24000f0b2014450d20200141046a2d000022044102460d0b20044101460d0a20040d0c2001410c6a280200450d20200141086a2802001001200341b0016a24000f0b200a450d1f200141086a280200450d1f200141046a2802001001200341b0016a24000f0b2016450d1e02402001410c6a2802002204450d00200141046a28020022062004411c6c6a2102034002402006410c6a2802002208450d0020062802042104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b0240200641086a280200450d00200641046a28020010010b2006411c6a21040240200641146a280200450d00200628021010010b2004210620042002470d000b0b200141086a280200450d1e200141046a2802001001200341b0016a24000f0b2013450d1d02402001410c6a2802002208450d00200141046a2802002104200841286c210803400240200441046a280200450d00200428020010010b0240200441106a280200450d002004410c6a28020010010b200441286a2104200841586a22080d000b0b200141086a280200450d1d200141046a2802001001200341b0016a24000f0b2002450d1c02402001410c6a2802002208450d00200141046a28020021042008410474210803400240200441046a280200450d00200428020010010b200441106a2104200841706a22080d000b0b200141086a280200450d1c200141046a2802001001200341b0016a24000f0b2009450d1b0240200141086a280200450d00200141046a28020010010b200141146a280200450d1b200141106a2802001001200341b0016a24000f0b200d450d1a200141086a280200450d1a200141046a2802001001200341b0016a24000f0b200b450d1902402001410c6a2802002204450d00200141046a280200220620044104746a21020340024020062802082208450d0020062802002104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b200641106a21040240200641046a280200450d00200628020010010b2004210620042002470d000b0b200141086a280200450d19200141046a2802001001200341b0016a24000f0b201b450d1802402001410c6a2802002204450d00200141046a28020022062004411c6c6a2102034002402006410c6a2802002208450d0020062802042104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b0240200641086a280200450d00200641046a28020010010b2006411c6a21040240200641146a280200450d00200628021010010b2004210620042002470d000b0b200141086a280200450d18200141046a2802001001200341b0016a24000f0b200c450d1702402001410c6a2802002208450d00200141046a2802002104200841146c210803400240200441046a280200450d00200428020010010b200441146a21042008416c6a22080d000b0b200141086a280200450d17200141046a2802001001200341b0016a24000f0b2001102a200341b0016a24000f0b0240200141146a2802002208450d002001410c6a28020021042008410c6c21080340024020042802002206450d00200441046a280200450d00200610010b2004410c6a2104200841746a22080d000b0b200141106a280200450d152001410c6a2802001001200341b0016a24000f0b0240200141146a2802002204450d002001410c6a280200220920044104746a210003402009220241106a2109024020022802042204450d0002402002410c6a2802002208450d002008410c6c21080340024020042802002206450d00200441046a280200450d00200610010b2004410c6a2104200841746a22080d000b0b200241086a280200450d00200241046a28020010010b20092000470d000b0b200141106a280200450d142001410c6a2802001001200341b0016a24000f0b2001410c6a280200450d13200141086a2802001001200341b0016a24000f0b200328020410010b0240200d452008720d00200b450d00200d10010b0240200a450d00200710010b200320032900a70137009701200320032903a00137039001200020043a00002000200329039001370001200041086a2003290097013700004100210a410121154101210b4101210c4101211b410121164101210541012107410121144101210d4101210041010d020b4101210241012106410121092004450d020b20081001410121000b4101210241012106410121090b20012d00002204410e4d0d080c090b410121070b41012115410121004101210b4101210241012106410121094101210c4101211b41012116410121050c050b4101210c0b4101211b0b410121160b410121050b41012107410121144101210a0b4101210d20012d00002204410e4b0d010b0240024002400240024002400240024002400240024002400240024020040e0f0009080703050a0b0d0e0c02060401000b200d450d11200141086a280200450d11200141046a2802001001200341b0016a24000f0b200a450d100240200141086a280200450d00200141046a28020010010b0240200141146a2802002204450d00200141186a280200450d00200410010b200141246a280200450d10200141206a2802001001200341b0016a24000f0b2005450d0f02402001410c6a2802002204450d00200141046a2802002206200441186c6a210203400240200641046a280200450d00200628020010010b0240200641146a2802002208450d00200628020c2104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b200641186a21040240200641106a280200450d002006410c6a28020010010b2004210620042002470d000b0b200141086a280200450d0f200141046a2802001001200341b0016a24000f0b2002450d0e200141086a280200450d0e200141046a2802001001200341b0016a24000f0b2014450d0d200141046a2d000022044102460d0b20044101460d0a20040d0c2001410c6a280200450d0d200141086a2802001001200341b0016a24000f0b2006450d0c200141086a280200450d0c200141046a2802001001200341b0016a24000f0b2007450d0b02402001410c6a2802002204450d00200141046a28020022062004411c6c6a2102034002402006410c6a2802002208450d0020062802042104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b0240200641086a280200450d00200641046a28020010010b2006411c6a21040240200641146a280200450d00200628021010010b2004210620042002470d000b0b200141086a280200450d0b200141046a2802001001200341b0016a24000f0b200b450d0a02402001410c6a2802002208450d00200141046a2802002104200841286c210803400240200441046a280200450d00200428020010010b0240200441106a280200450d002004410c6a28020010010b200441286a2104200841586a22080d000b0b200141086a280200450d0a200141046a2802001001200341b0016a24000f0b2000450d0902402001410c6a2802002208450d00200141046a28020021042008410474210803400240200441046a280200450d00200428020010010b200441106a2104200841706a22080d000b0b200141086a280200450d09200141046a2802001001200341b0016a24000f0b2015450d080240200141086a280200450d00200141046a28020010010b200141146a280200450d08200141106a2802001001200341b0016a24000f0b2009450d07200141086a280200450d07200141046a2802001001200341b0016a24000f0b200c450d0602402001410c6a2802002204450d00200141046a280200220620044104746a21020340024020062802082208450d0020062802002104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b200641106a21040240200641046a280200450d00200628020010010b2004210620042002470d000b0b200141086a280200450d06200141046a2802001001200341b0016a24000f0b2016450d0502402001410c6a2802002204450d00200141046a28020022062004411c6c6a2102034002402006410c6a2802002208450d0020062802042104200841047421080340024020042d00004109470d00200441086a28020041ffffffff0371450d00200441046a28020010010b200441106a2104200841706a22080d000b0b0240200641086a280200450d00200641046a28020010010b2006411c6a21040240200641146a280200450d00200628021010010b2004210620042002470d000b0b200141086a280200450d05200141046a2802001001200341b0016a24000f0b201b450d0402402001410c6a2802002208450d00200141046a2802002104200841146c210803400240200441046a280200450d00200428020010010b200441146a21042008416c6a22080d000b0b200141086a280200450d04200141046a2802001001200341b0016a24000f0b2001102a0c030b0240200141146a2802002208450d002001410c6a28020021042008410c6c21080340024020042802002206450d00200441046a280200450d00200610010b2004410c6a2104200841746a22080d000b0b200141106a280200450d022001410c6a2802001001200341b0016a24000f0b0240200141146a2802002204450d002001410c6a280200220920044104746a210003402009220241106a2109024020022802042204450d0002402002410c6a2802002208450d002008410c6c21080340024020042802002206450d00200441046a280200450d00200610010b2004410c6a2104200841746a22080d000b0b200241086a280200450d00200241046a28020010010b20092000470d000b0b200141106a280200450d012001410c6a2802001001200341b0016a24000f0b2001410c6a280200450d00200141086a2802001001200341b0016a24000f0b200341b0016a24000bd00101047f024002400240024002400240200241046a280200200241086a2802002203470d00200341016a22042003490d0420034101742205200420042005491b22054100480d042003450d0120022802002106200510002204450d052004200620052003200320054b1b10f8021a200610010c020b200228020021040c020b200510002204450d030b20022004360200200241046a2005360200200241086a28020021030b200241086a200341016a360200200420036a20013a00002000411a3a00000f0b1018000b200541011019000bb505010c7f230041306b220324002003410c6a220441003602002003420137020420032002360200200341206a41086a200141086a28020036020020032001290200370320200341106a200341206a200310b60202400240024002400240024002400240024020032d0010411a470d002003410472200128020c2205200141146a2802001025200341086a2802002106200328020421072003280200220841046a21092004280200220a2104034002400240024002402009280200200841086a220b2802002202470d00200241016a220c2002490d0b2002410174220d200c200c200d491b220d4100480d0b2002450d012008280200210e200d1000220c450d0c200c200e200d20022002200d4b1b10f8021a200e10010c020b2008280200210c0c020b200d1000220c450d0a0b2008200c3602002009200d360200200b28020021020b200b200241016a360200200c20026a200441807f72200441ff0071200441077622021b3a00002002210420020d000b200841046a280200220c200841086a28020022026b200a4f0d012002200a6a22042002490d06200c4101742202200420042002491b22024100480d06200c450d022008280200210b200210002204450d082004200b2002200c200c20024b1b10f8021a200b10010c030b20002003290310370200200041086a200341106a41086a2903003702000240200341086a280200450d00200328020410010b200141106a280200450d042001410c6a2802001001200341306a24000f0b200828020021040c020b200210002204450d050b20082004360200200841046a2002360200200841086a28020021020b200841086a2002200a6a360200200420026a2007200a10f8021a02402006450d00200710010b2000411a3a0000200141106a280200450d00200510010b200341306a24000f0b1018000b200d41011019000b200241011019000b860101047f230041106b22032400200141086a2802002104200341003a000f200241046a21052004210203402003200241800172200241ff0071200241077622061b3a000f20052003410f6a410110252006210220060d000b200128020421022005200128020022062004102502402002450d00200610010b2000411a3a0000200341106a24000bdf0803087f017e047f230041e0006b22032400200341146a41003602002003420137020c20032002360208200128020421042001280200210520012802082106200341003a0050200520064103746a2107200341086a41047221082006210203402003200241800172200241ff0071200241077622091b3a00502008200341d0006a410110252009210220090d000b024002402006450d00200521020340200241086a210a2002290200220b422088a7220241ff01714104460d022002411874411875210c200341003a0050200ba7210203402003200241800172200241ff0071200241077622091b3a00502008200341d0006a410110252009210220090d000b2003200c417f732202413f7141c000722002200c417f4a1b3a00502008200341d0006a41011025200a2102200a2007470d000b2007210a0c010b2005210a0b200520064103746a2109024003402009200a460d01200a2d00042102200a41086a210a20024104470d000b0b02402004450d00200510010b200128020c2205200141146a280200220d41047422046a2106200141106a280200210e024002400240024002400240200d450d00200341d0006a410172210a41002109200341d0006a41026a2108200341c0006a410172220141076a210f03402008200520096a220241036a2d00003a00002003200241016a2f00003b015020022d0000220c41ac01460d022003412c6a41026a220720082d00003a0000200320032f01503b012c200241046a290200210b200341d0006a410c6a2002410c6a280200360200200a20032f012c3b0000200a41026a20072d00003a00002003200c3a00502003200b370254200341c0006a200341d0006a200341086a10ae02200320012900003703302003200f29000037003720032d0040220c411a470d052004200941106a2209470d000c040b0b200522022006470d010c020b200241106a22022006460d010b03400240024020022d000022094109460d00200941ac01470d010c030b200241086a28020041ffffffff0371450d00200241046a28020010010b200241106a22022006470d000b0b0240200e450d00200510010b200341146a280200210a200341106a2802002107200328020c210c20032802082102200341003a0050200241046a2108200a210203402003200241800172200241ff0071200241077622091b3a00502008200341d0006a410110252009210220090d000b2008200c200a102502402007450d00200c10010b2000411a3a00000c010b2003200329003737001f200320032903303703180240200d41047441706a2009460d00200241186a2102034002400240200241786a22092d000022084109460d00200841ac01470d010c030b200228020041ffffffff0371450d002002417c6a28020010010b200241106a2102200941106a2006470d000b0b0240200e450d00200510010b200020032903183700012000200c3a0000200041086a200329001f370000200341086a41086a280200450d00200328020c1001200341e0006a24000f0b200341e0006a24000b900703107f017e017f230041306b22032400200241086a2104200241046a2105200128020022062107024002400240024003400240024002400240200528020020042802002208470d00200841016a22092008490d052008410174220a20092009200a491b220a4100480d052008450d012002280200210b200a10002209450d062009200b200a20082008200a4b1b10f8021a200b10010c020b200228020021090c020b200a10002209450d040b200220093602002005200a360200200428020021080b2004200841016a360200200920086a200741807f72200741ff0071200741077622081b3a00002008210720080d000b2001280204220c2001410c6a280200220d410c6c6a210e200141086a280200210f200c21080240024002402006450d00200341106a4101722110200241086a210a200c21114100211203402011200e460d02201221072011210902400340200928020022010d01200741016a2107200e2009410c6a2209470d000c040b0b2009410c6a2111200741016a21122006417f6a2106200941046a290200211303400240024002400240200241046a220b280200200a2802002208470d00200841016a22042008490d0920084101742205200420042005491b22054100480d092008450d0120022802002114200510002204450d0b2004201420052008200820054b1b10f8021a201410010c020b200228020021040c020b200510002204450d090b20022004360200200b2005360200200a28020021080b200a200841016a360200200420086a200741807f72200741ff0071200741077622081b3a00002008210720080d000b2003201337022420032001360220200341106a200341206a200210b902200320102900003703002003201041076a29000037000720032d00102208411a470d0320060d000b2009410c6a21080b2008200e460d00200c200d410c6c6a2102034020082207410c6a2108024020072802002209450d00200741046a280200450d00200910010b20022008470d000b0b0240200f450d00200c10010b2000411a3a00000c040b20002003290300370001200020083a0000200041086a20032900073700000240200c200d410c6c6a220241746a2009460d002009410c6a2108034020082207410c6a2108024020072802002209450d00200741046a280200450d00200910010b20022008470d000b0b200f450d03200c1001200341306a24000f0b1018000b200a41011019000b200541011019000b200341306a24000bd60301087f200241046a2103200141086a28020022042105024002400240034002400240024002402003280200200241086a22062802002207470d00200741016a22082007490d0520074101742209200820082009491b22094100480d052007450d012002280200210a200910002208450d062008200a20092007200720094b1b10f8021a200a10010c020b200228020021080c020b200910002208450d040b2002200836020020032009360200200628020021070b2006200741016a360200200820076a200541807f72200541ff0071200541077622071b3a00002007210520070d000b20012802042109200128020021080240024002400240200241046a2802002206200241086a28020022076b20044f0d00200720046a22052007490d0420064101742207200520052007491b22074100480d042006450d0120022802002103200710002205450d062005200320072006200620074b1b10f8021a200310010c020b200228020021050c020b200710002205450d040b20022005360200200241046a2007360200200241086a28020021070b200241086a200720046a360200200520076a2008200410f8021a02402009450d00200810010b2000411a3a00000f0b1018000b200941011019000b200741011019000bc0c20108097f017e017f017e077f017e117f017e230041f080046b22022400024002402001280204220320012802082204470d00200241013a0020200241ec006a4101360200200241e4006a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc2003602582002200241206a3602182002200241186a360268200241d880046a200241d8006a104d20022802dc8004210120022802d88004210520004101360200200041003a00042001450d01200510010c010b200441016a2105024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402004417f460d00024020032005490d002001280200220620046a2d00002104200141086a20053602000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402004410b4b0d0002400240024002400240024002400240024002400240024020040e0c00070405020809060b030a01000b41002104200141086a21074100210803402004411f4b0d6520032005460d632005417f460d262003200541016a2209490d25200620056a2d0000210a20072009360200200a41ff00712004411f71742008722108200441076a210420092105200a418001710d000b20044120490d38200a6741686a41ff017141044f0d38410d21010c650b200241d8006a200110bb0220022802584101470d0b200228025c22094108762101200241e8006a280200210a200241d8006a41086a290300210b0c600b200241d8006a200110bb0220022802584101470d0b200228025c22014108762105200241e8006a2802002103200241d8006a41086a290300210b0c5b0b200241d8006a200110bb0220022802584101470d0b200228025c220a4108762101200241e8006a2802002109200241d8006a41086a290300210b0c560b200241d8006a200110bb0220022802584101470d0b200228025c22054108762101200241e8006a2802002103200241d8006a41086a290300210b0c510b200241d8006a200110bb0220022802584101470d0b200228025c22014108762105200241e8006a2802002103200241d8006a41086a290300210b0c4c0b200241d8006a200110bb0220022802584101470d0b200228025c22054108762103200241e8006a2802002101200241d8006a41086a290300210b0c460b200241d8006a200110bb0220022802584101470d0b200228025c220c4108762105200241e8006a2802002101200241d8006a41086a290300210b0c410b200241d8006a200110bb0220022802584101470d63200228025c22054108762101200241e8006a2802002103200241d8006a41086a290300210b0c6a0b200241d8006a200110bb0220022802584101470d60200228025c22014108762105200241e8006a280200210a200241d8006a41086a290300210b0c610b200241d8006a200110bb0220022802584101470d5d200228025c22034108762101200241e8006a280200210a200241d8006a41086a290300210b0c5e0b200241d8006a200110bb02200241d8006a410472210120022802584101470d5b20004101360200200020012902003702042000410c6a200141086a290200370200200241f080046a24000f0b200041123a000420004101360200200041056a20043a0000200241f080046a24000f0b200241306a200241ec006a280200360200200241286a2208200241d8006a410c6a2902003703002002200229025c370320410021014100210303402001411f4b0d522008280200220a200241206a410c6a22092802002205460d37200541016a21042005417f460d17200a2004490d16200228022020056a2d0000210520092004360200200541ff00712001411f71742003722103200141076a21012005418001710d000b41042104410d200341ff01712001411f4b20056741686a41ff01714104497122011b4100200341807e7120011b72210920010d522009450d204200210d41042104200241d8006a410c6a210e200241d8006a41086a210f410021100340200241d8006a200241206a10ac02200228025c211120022802584101460d1e200241d8006a200241206a10aa02200228025c211220022802584101460d1d200e280200210c200f2802002113200241d8006a200241206a10ac02200228025c210820022802584101460d1c41002105200241c8006a41086a2214410036020020024201370348200241d8006a41004180800410f7021a024002402008450d00410021030340200241206a41086a2802002206200241206a410c6a220728020022056b200820036b220141808004200141808004491b2201490d26200520016a220a2005490d0c2006200a490d0b200241d8006a200228022020056a200110f8021a2007200a360200200241c8006a200241d8006a200110252008200120036a22034b0d000b20142802002105200228024c21032002280248210a0c010b4101210a410021030b0240200d422088a72201200da7470d00200141016a22082001490d6120014101742206200820082006491bad220b421c7e2215422088a70d612015a722084100480d61024002402001450d00200810002206450d0a2006200420082001411c6c2201200120084b1b10f802210120041001200121040c010b200810002204450d090b200d42808080807083200b84210d0b2004200d422088a7411c6c6a2201201141087622083b00012001200a36021020012012360204200120113a0000200141036a20084110763a0000200141186a2005360200200141146a20033602002001410c6a200c360200200141086a2013360200200d4280808080107c210d201041016a22102009490d000c220b0b200241e880046a200241ec006a280200360200200241e080046a2201200241e4006a2902003703002002200229025c3703d88004200128020021044100210520022802e48004210120022802d8800421084100210303402005411f4b0d4d20042001460d342001417f460d142004200141016a220a490d13200820016a2d0000220941ff00712005411f71742003722103200541076a2105200a21012009418001710d000b200241e480046a200a36020041042104410d200341ff01712005411f4b20096741686a41ff01714104497122051b4100200341807e7120051b7221012005450d294200210d0c4d0b200241e880046a200241ec006a280200360200200241e080046a2208200241d8006a410c6a2902003703002002200229025c3703d88004410021014100210303402001411f4b0d482008280200220a200241d880046a410c6a22092802002205460d31200541016a21042005417f460d11200a2004490d1020022802d8800420056a2d0000210520092004360200200541ff00712001411f71742003722103200141076a21012005418001710d000b41042104410d200341ff01712001411f4b20056741686a41ff01714104497122011b4100200341807e7120011b7221102001450d272010210a0c480b200241e880046a200241ec006a280200360200200241e080046a2208200241d8006a410c6a2902003703002002200229025c3703d88004410021014100210303402001411f4b0d432008280200220a200241d880046a410c6a22092802002205460d2e200541016a21042005417f460d0e200a2004490d0d20022802d8800420056a2d0000210520092004360200200541ff00712001411f71742003722103200141076a21012005418001710d000b41042104410d20032001411f4b20056741686a41ff01714104497122011b41ff01714100200341807e7120011b7221052001450d254200210d4200210b0c430b200241e880046a200241ec006a280200360200200241e080046a2201200241e4006a2902003703002002200229025c3703d88004200128020021044100210520022802e48004210120022802d8800421084100210303402005411f4b0d3d20042001460d2c2001417f460d0b2004200141016a220a490d0a200820016a2d0000220941ff00712005411f71742003722103200541076a2105200a21012009418001710d000b200241e480046a200a36020041042104410d200341ff01712005411f4b20096741686a41ff01714104497122051b4100200341807e7120051b7221012005450d234200210d0c3d0b200241e880046a200241ec006a280200360200200241e080046a2201200241e4006a2902003703002002200229025c3703d88004200128020021044100210520022802e48004210120022802d8800421084100210303402005411f4b0d3820042001460d292001417f460d082004200141016a220a490d07200820016a2d0000220941ff00712005411f71742003722103200541076a2105200a21012009418001710d000b200241e480046a200a36020041042104410d200341ff01712005411f4b20096741686a41ff01714104497122011b4100200341807e7120011b7221052001450d214200210d0c380b200241e880046a200241ec006a280200360200200241e080046a2208200241d8006a410c6a2902003703002002200229025c3703d88004410021014100210303402001411f4b0d332008280200220a200241d880046a410c6a22092802002205460d27200541016a21042005417f460d05200a2004490d0420022802d8800420056a2d0000210520092004360200200541ff00712001411f71742003722103200141076a21012005418001710d000b41042104410d20032001411f4b20056741686a41ff01714104497122011b41ff01714100200341807e7120011b72210c20010d33200c450d184200210d200241d880046a410c6a2111200241d880046a41086a210e200241ec006a2114200241d8006a41106a210f2002412a6a2116200241296a2117200241ea006a2118200241e9006a211941042104410021100240034002400240200e280200220920112802002203470d0041012113200241013a004820144101360200200241d8006a410c6a4101360200200241d8006a41086a41e0c3c1003602002002410f360204200f20023602002002410136025c200241b08fc2003602582002200241c8006a360200200241206a200241d8006a104d20162f0100210820172d00002109200241206a41086a2d000021012002280224210620022802202103410521050c010b200341016a210102400240024002400240024002400240024002400240024002402003417f460d0020092001490d0120022802d88004221220036a2d0000210a2011200136020041012113411721050240024002400240024002400240200a41e000470d00200341036a210641002105410021070340200621082005411f4b0d0220092001460d032001417f460d062009200141016a220a490d07201220016a2d000021032011200a360200200341ff00712005411f71742007722107200841016a2106200541076a2105200a21012003418001710d000b410d20072005411f4b20036741686a41ff01714104497122011b41ff01714100200741807e7120011b7221072001450d04200721050c030b0c130b410f21050c010b200241013a004820144101360200200241d8006a410c6a4101360200200241d8006a41086a41e0c3c1003602002002410f360204200f20023602002002410136025c200241b08fc2003602582002200241c8006a360200200241206a200241d8006a104d200241206a41086a280200211a2002280224211b2002280220211c410521050b201c2103201b2106201a21010c0f0b41012105024002400240024002400240024002402007450d00410120096b211d410021034100210603402006210a201d20086a4102460d032008450d0d20092008490d0e201220086a417f6a2c000021012011200836020020014100480d04200141017441807f71200172220141ff017141847e6a220641034b0d054100210102400240024002400240024020060e0400010203000b41032101200a2003460d030c040b41022101200a2003460d020c030b410121010b200a2003470d010b200341016a22062003490d752003410174221e20062006201e491b22064100480d75024002402003450d0020061000221e450d12201e200520062003200320064b1b10f802210320051001200321050c010b200610002205450d110b200621030b2005200a6a20013a0000200841016a2108200a41016a22062007490d000c020b0b41002103410021060b200241d8006a200241d880046a10ac02024020022802584101470d0020182f0100210820192d00002109200f2d00002101200241d8006a410c6a2802002106200241d8006a41086a280200211d20022f015e210720022d005d210a20022d005c2112410121132003450d140c130b41042112200228025c2201450d0320014101470d04200e280200220a20112802002201470d05200241013a004820144101360200200241d8006a410c6a4101360200200241d8006a41086a41e0c3c1003602002002410f360204200f20023602002002410136025c200241b08fc2003602582002200241c8006a360200200241206a200241d8006a104d4105211220162f0100221f210820172d000022202109200241206a41086a2d00002221210120022802242222210620022802202223211d4101211320030d120c130b200241013a000020144101360200200241d8006a410c6a4101360200200241d8006a41086a41e0c3c1003602002002410f36021c200f200241186a3602002002410136025c200241b08fc20036025820022002360218200241206a200241d8006a104d200241206a41086a28020021242002280224212520022802202126410041ff0171410874410572210a2003450d100c0f0b200141ff0171410874411872210a20030d0e0c0f0b200141ff0171410874410672210a20030d0d0c0e0b410421090c0b0b41c6c4c100211d412421064101211320030d0d0c0e0b200141016a21092001417f460d07200a2009490d0820022802d8800420016a2c0000210a2011200936020002400240200a4100480d0041062112200a41017441807f71200a72220a41ff017141fc01490d01200a417f7321090c0b0b411821120b201f21082020210920212101202221062023211d4101211320030d0c0c0d0b417f200141016a107a000b200141016a20091076000b417f2001107a000b200120091076000b417f2008107a000b200820091076000b200641011019000b417f2009107a000b2009200a1076000b200541107621072005410876210a4100211341e00021010c050b200510010b202621032025210620242101200a21050c020b200510010b201d2103201221050c010b2001411076210820014108762109200541107621072005410876210a0b200941ff0171410874200141ff0171722008411074722101200a41ff0171410874200541ff017172200741107472210a024020130d000240200d422088a72205200da7470d00200541016a22092005490d5d20054101742208200920092008491bad220b4204862215422088a70d5d2015a722094100480d5d024002402005450d00200910002208450d052008200420092005410474220520092005491b10f802210520041001200521040c010b200910002204450d040b200d42808080807083200b84210d0b2004200d422088a74104746a2205200136020c20052006360208200520033602042005200a360200200d4280808080107c210d201041016a2210200c490d010c1c0b0b2006ad422086210b2003ad21150240200d422088a72205450d00200541047421032004210503400240200541046a280200450d00200528020010010b200541106a2105200341706a22030d000b0b200b201584210b0240200da7450d00200410010b200a220c410876210520022802dc80040d350c360b200941041019000b200841041019000b200a20061076000b2005200a107a000b2004200a1076000b417f2004107a000b200141016a20041076000b417f200141016a107a000b200141016a20041076000b417f200141016a107a000b2004200a1076000b417f2004107a000b2004200a1076000b417f2004107a000b200141016a20041076000b417f200141016a107a000b2004200a1076000b417f2004107a000b200541016a20031076000b417f200541016a107a000b200520031076000b417f2005107a000b20084108762106200241e8006a280200210a200241e4006a2802002103200241d8006a41086a280200210920082111200c0d070c080b20124108762106200241e8006a280200210a200241e4006a2802002103200241d8006a41086a2802002109201221110c080b20114108762106200241e8006a280200210a200241e4006a2802002103200241d8006a41086a28020021090c070b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410221010c470b20024103410220012005461b3a0000200241ec006a4101360200200241e4006a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d200228022821012002290320210b0240200d422088a72205450d00200541047421032004210503400240200541046a280200450d00200528020010010b200541106a2105200341706a22030d000b0b4105210c41002105200da7450d1b200410010c1b0b4200210d0b2002412c6a28020021012002280230210502402002280224450d00200228022010010b024020012005470d00410c21010c450b20024103410220012005461b3a0000200241d8006a41146a4101360200200241d8006a410c6a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241d880046a200241d8006a104d20022802e08004210a20022903d88004210b0240200d422088a72201450d0020042001411c6c6a210920042103034002402003410c6a2802002205450d0020032802042101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b2001210320012009470d000b0b4105210941002101200da7450d32200410010c320b200241013a0038200241ec80046a4101360200200241e480046a4101360200200241d880046a41086a41e0c3c1003602002002410f36021c200241e880046a200241186a360200200241013602dc8004200241b08fc2003602d880042002200241386a3602182002200241d880046a104d200241086a280200210a20022802042103200228020021090240200228024c450d00200228024810010b4100210641052111200c450d010b200c4104742105201221010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b2013450d00201210010b201141ff01712108200641087421062003ad422086210b2009ad21150240200d422088a72201450d0020042001411c6c6a210920042103034002402003410c6a2802002205450d0020032802042101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b2001210320012009470d000b0b20062008722109200b201584210b200da7450d11200410012009410876210120022802240d2d0c2e0b024002400240024002400240024002400240024002400240024002402005450d004200210d41042104200241d8006a410c6a210c200241d8006a41086a2112410021060340200241d8006a200241d880046a10bc02200c280200210a20122802002109200228025c210820022802584101460d03200241d880046a41086a2802002207200241d880046a410c6a22112802002201460d04200141016a21032001417f460d0a20072003490d0b20022802d8800420016a2d0000210120112003360200200141034b0d050240024002400240024020010e0400030102000b200241d8006a200241d880046a10ac02200228025c210320022802584101460d0d410021070c030b200241d8006a200241d880046a10ac02200228025c210320022802584101460d0a410221070c020b200241d8006a200241d880046a10ac02200228025c210320022802584101460d08410321070c010b200241d8006a200241d880046a10ac02200228025c210320022802584101460d09410121070b0240200d422088a72201200da7470d00200141016a22112001490d4820014101742213201120112013491bad220b42147e2215422088a70d482015a722114100480d48024002402001450d00201110002213450d0f201320042011200141146c2201200120114b1b10f802210120041001200121040c010b201110002204450d0e0b200d42808080807083200b84210d0b2004200d422088a741146c6a22012003ad4220862007ad84220b37020c2001200a3602082001200936020420012008360200200d4280808080107c210d200641016a22062005490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410821010c4c0b20024103410220012005461b3a0000200241d8006a41146a4101360200200241e4006a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d200228022821012002290320210b0240200d422088a72205450d00200541146c21032004210503400240200541046a280200450d00200528020010010b200541146a21052003416c6a22030d000b0b4105210541002103200da7450d24200410010c240b200b42808080807083200241e8006a35020084212720082105200921060c0a0b200241013a0000200241ec006a4101360200200241e4006a4101360200200241e0006a41e0c3c1003602002002410f36021c200241e8006a200241186a3602002002410136025c200241b08fc20036025820022002360218200241206a200241d8006a104d20022902242115200228022021064105210341002105410021010c080b410a2103410021050c070b20034180807c71210520034108762101200241e4006a2902002115200241d8006a41086a28020021060c060b20034180807c71210520034108762101200241e4006a2902002115200241d8006a41086a28020021060c050b20034180807c71210520034108762101200241e4006a2902002115200241d8006a41086a28020021060c040b20034180807c71210520034108762101200241e4006a2902002115200241d8006a41086a28020021060c030b417f2003107a000b200320071076000b201141041019000b200b428080808070832015422088842127200141ff0171410874200572200341ff01717221052015a7210a2009450d00200810010b200aad422086210b2006ad21150240200d422088a72201450d00200141146c21032004210103400240200141046a280200450d00200128020010010b200141146a21012003416c6a22030d000b0b200b201584210b2027a72101200da7450d07200410012005410876210320022802dc80040d170c180b02400240024002402001450d004200210d41042104410021030340200241d8006a200241d880046a10ac02200228025c210a20022802584101460d030240200d422088a72205200da7470d00200541016a22092005490d3d20054101742208200920092008491bad220b4202862215422088a70d3d2015a722094100480d3d024002402005450d00200910002208450d072008200420092005410274220520092005491b10f802210520041001200521040c010b200910002204450d060b200d42808080807083200b84210d0b2004200d422088a74102746a200a360200200d4280808080107c210d200341016a22032001490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410421010c410b20024103410220012005461b3a0000200241ec006a4101360200200241e4006a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d200228022821032002290320210b4105210141002105200da7450d1e200410010c1e0b200241e8006a2802002103200241e0006a290300210b0240200da7450d00200410010b200a2201410876210520022802dc80040d1c0c1d0b200941041019000b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402005450d004200210d41042104200241d8006a410c6a2107200241d8006a41086a21084100210e0340200241d8006a200241d880046a10bc02200728020021112008280200210c200228025c211220022802584101460d03200241d8006a200241d880046a10bc022007280200210f20082802002113200228025c211020022802584101460d04200241d880046a41086a2802002209200241d880046a410c6a22062802002203460d05200341016a210a2003417f460d152009200a490d1620022802d88004221420036a2d000021012006200a360200200141034b0d0602400240024002400240024002400240024020010e0400030102000b200241d8006a200241d880046a10ac0220022802584101460d12200228025c2103410021060c070b200241d8006a200241d880046a10bd022008290300210b200228025c210320022802584101460d10410221060c060b2009200a460d0d200341026a2116200a417f460d2220092016490d232014200a6a2c000021012006201636020020014100480d12200141017441807f71200172220141ff017141847e6a220641034b0d164100210a024020060e0400020304000b4103210a20092016470d040c170b2009200a460d0d200341026a2103200a417f460d1d20092003490d1e2014200a6a2c000021012006200336020020014100480d10200141017441807f71200172220141ff017141f001470d12200241d8006a200241d880046a10bd022008290300210b200228025c210320022802584101460d17410121060c040b4102210a20092016470d020c150b4101210a0b20092016460d130b200341036a21062016417f460d1b20092006490d1c201420166a2d00002101410c2103200241d880046a410c6a2006360200410321064100210902402001450d0020014101470d22410121090b0b0240200d422088a72201200da7470d00200141016a22142001490d5a20014101742216201420142016491bad221542287e2227422088a70d5a2027a722144100480d5a024002402001450d00201410002216450d1a201620042014200141286c2201200120144b1b10f802210120041001200121040c010b201410002204450d190b200d42808080807083201584210d0b2004200d422088a741286c6a220120063a00182001201036020c200120113602082001200c36020420012012360200200141206a200b3702002001411c6a20033602002001411a6a20093a0000200141196a200a3a0000200141146a200f360200200141106a2013360200200d4280808080107c210d200e41016a220e2005490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410321010c5e0b20024103410220012005461b3a0000200241ec006a4101360200200241d8006a410c6a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d200228022821032002290320210b0240200d422088a72201450d00200141286c21052004210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101200541586a22050d000b0b4105210541002101200da7450d3f200410010c3f0b200241e8006a280200210320122105200c21090c1e0b200241e8006a28020021032010210520132109200f2111200c0d1c0c1d0b200241013a0000200241ec006a4101360200200241e4006a4101360200200241e0006a41e0c3c1003602002002410f36021c200241e8006a200241186a3602002002410136025c200241b08fc20036025820022002360218200241206a200241d8006a104d0c190b410921030c170b200241013a0048200241ec006a4101360200200241e4006a4101360200200241e0006a41e0c3c1003602002002410f360204200241e8006a20023602002002410136025c200241b08fc2003602582002200241c8006a360200200241206a200241d8006a104d0c170b200241013a0048200241ec006a4101360200200241e4006a4101360200200241d8006a41086a41e0c3c1003602002002410f360204200241e8006a20023602002002410136025c200241b08fc2003602582002200241c8006a360200200241206a200241d8006a104d200241206a41086a28020021052002290320210b410521030c060b200241d8006a41086a200241d8006a41106a2802003602002003411876211420034110762116200341087621010c0a0b200241e4006a2902002115200241e0006a280200210920022d005f211420022d005e211620022d005d210120022d005c21030c150b411821030c020b411821030c110b410721030b0b200141ff017141087420037221030c030b410621030c0d0b200241013a0048200241ec006a4101360200200241e4006a4101360200200241e0006a41e0c3c1003602002002410f360204200241e8006a20023602002002410136025c200241b08fc2003602582002200241c8006a360200200241206a200241d8006a104d0c0d0b200241e8006a28020021050b200241d8006a41086a20053602002003411876211420034110762116200341087621010b2002200b370358200229025c2115200ba721090c0b0b417f200a107a000b200a20091076000b201441041019000b417f2003107a000b200320091076000b417f2006107a000b200620091076000b417f2016107a000b201620091076000b0c010b2002290224211520022802202109410521030b200141ff0171410874200341ff017172201641ff01714110747220144118747221052015422088a721032015a7211102402013450d00201010010b200c450d010b201210010b2011ad422086210b2009ad21150240200d422088a72201450d00200141286c210a2004210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141286a2101200a41586a220a0d000b0b200b201584210b200da7450d08200410012005410876210120022802dc80040d1e0c1f0b02400240024002400240024002402010450d004200210d41042104200241d8006a410c6a2109200241d8006a41086a2108410021070340200241d8006a200241d880046a10ac02200228025c210a20022802584101460d03200241d8006a200241d880046a10aa022009280200210520082802002103200228025c210620022802584101460d04200241d8006a200241d880046a10ad0220022802584101460d05200828020021112009280200210c200241206a41086a200228025c2201360200200241206a410c6a2001200c4102746a36020020022011360224200220013602202002200241206a1043200241086a28020021112002280204210c200228020021120240200d422088a72201200da7470d00200141016a22132001490d3e2001410174220e20132013200e491bad220b421c7e2215422088a70d3e2015a722134100480d3e024002402001450d0020131000220e450d0a200e200420132001411c6c2201200120134b1b10f802210120041001200121040c010b201310002204450d090b200d42808080807083200b84210d0b2004200d422088a7411c6c6a2201200a41087622133b000120012012360210200120063602042001200a3a0000200141036a20134110763a0000200141186a2011360200200141146a200c3602002001410c6a2005360200200141086a2003360200200d4280808080107c210d200741016a22072010490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410a21010c420b20024103410220012005461b3a0000200241d8006a41146a4101360200200241d8006a410c6a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d200228022821092002290320210b0240200d422088a72201450d0020042001411c6c6a210a20042103034002402003410c6a2802002205450d0020032802042101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b200121032001200a470d000b0b4105210a41002101200da7450d27200410010c270b200241e8006a2802002109200241e4006a2802002105200241e0006a28020021030c020b200241e8006a28020021092006210a0c010b200241d8006a41106a2802002109200241e4006a2802002108200241d8006a41086a2802002107200228025c210a02402005450d0020054104742105200621010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b02402003450d00200610010b20072103200821050b2005ad422086210b2003ad21150240200d422088a72201450d0020042001411c6c6a210820042103034002402003410c6a2802002205450d0020032802042101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b0240200341086a280200450d00200341046a28020010010b2003411c6a21010240200341146a280200450d00200328021010010b2001210320012008470d000b0b200b201584210b200da7450d0a20041001200a410876210120022802dc80040d220c230b201341041019000b0240024002400240024002400240024002400240024002402001450d004200210d41042104200241d880046a410c6a2109200241d880046a41086a210c410021110340200c280200220a20092802002205460d03200541016a21032005417f460d0a200a2003490d0b20022802d8800420056a2c000021052009200336020020054100480d04200541017441807f71200572220541ff017141f001470d05200241d8006a200241d880046a10bd0220022f005d20022d005f41107472210a200241d8006a410c6a2802002108200241d8006a41086a280200210620022d005c210720022802584101460d080240200d422088a72205200da7470d00200541016a22032005490d4220054101742212200320032012491bad220b420c7e2215422088a70d422015a722034100480d42024002402005450d00200310002212450d0f2012200420032005410c6c2205200520034b1b10f802210520041001200521040c010b200310002204450d0e0b200d42808080807083200b84210d0b2004200d422088a7410c6c6a2205200a3b00012005200836020820052006360204200520073a0000200541036a200a4110763a0000200d4280808080107c210d201141016a22112001490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410521010c460b20024103410220012005461b3a0000200241ec006a4101360200200241e4006a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d200228022821032002290320210b4105210141002105200da7450d2f200410010c2f0b200241013a0000200241ec006a4101360200200241e4006a4101360200200241d8006a41086a41e0c3c1003602002002410f36021c200241e8006a200241186a3602002002410136025c200241b08fc20036025820022002360218200241206a200241d8006a104d200241206a41086a28020021032002280224210820022802202106410521070c030b411821070c010b410721070b0b200541ff0171210a0c010b200241e8006a28020021030b200a410874200741ff01717221012008ad4220862006ad84210b200da7450d0d200410012001410876210520022802dc80040d270c280b417f2003107a000b2003200a1076000b200341041019000b410021032002410036020820024201370300200241d8006a41004180800110f7021a41002105410021074101210602400240024002400240024002400240024002400240024002402008450d004100210a200141086a2106200141046a2111034020112802002207200628020022046b2008200a6b220541808001200541808001491b2205490d02200420056a22092004490d0720072009490d08200241d8006a200128020020046a200510f8021a200620093602002002200241d8006a2005102520082005200a6a220a4b0d000b200241086a280200210520022802042107200228020021060b410021014100210403402001411f4b0d0220052003460d03200520034d0d08200620036a2d0000220a41ff00712001411f71742004722104200141076a2101200341016a22092103200a418001710d000b20014120490d04200a6741686a41ff017141044f0d04410d21010c030b200241013a0048200241ec80046a4101360200200241e480046a41013602002002410f36021c200241e0c3c1003602e08004200241013602dc8004200241b08fc2003602d880042002200241c8006a3602182002200241186a3602e88004200241206a200241d880046a104d200228022821052002290320210d2002280204450d35200228020010010c350b410f21010c010b200241013a0020200241ec006a4101360200200241e4006a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc2003602582002200241206a3602182002200241186a360268200241d880046a200241d8006a104d20022802e08004210520022903d88004210d410521010b200d42808080807083200d42ffffffff0f8384210d2007450d340c070b024002400240024002402004450d00410021032002410036025020024201370348200241d8006a410041800810f7021a0340200520096b200420036b22014180082001418008491b2201490d02200920016a220a2009490d092005200a490d0a200241d8006a200620096a200110f8021a200241c8006a200241d8006a20011025200a21092004200120036a22034b0d000b200228024c2104200241d8006a20022802482203200241d0006a28020022091086014101210120022802584101470d02200241306a200229025c37030020022003360224200241206a41047221030c030b41002104410121034200210d20052009490d030c090b200241013a0038200241ec80046a4101360200200241e480046a41013602002002410f36021c200241e0c3c1003602e08004200241013602dc8004200241b08fc2003602d880042002200241386a3602182002200241186a3602e880042002200241d880046a104d2002290300210d200228020821050240200228024c450d00200228024810010b41052101200d42808080807083200d42ffffffff0f8384210d20070d090c360b20022003360224200241206a4104722103410021010b2002412c6a2009360200200241206a41086a220920043602002002200136022002402001450d0002402009280200450d00200328020010010b410821014200210d20070d080c350b2002280224220341087621042009290300210d2005200a22094f0d060b20092005107a000b20042009107a000b200920071076000b200341016a20051076000b2009200a107a000b200a20051076000b0240200520096b2201417f4c0d00024002402001450d002001100022050d01200141011019000b410121050b200241003602602002200136025c20022005360258200241d8006a200620096a20011025200229025c210b2002280258210502402007450d00200610010b2004410874200341ff0171722104410121010c3c0b102c000b200610010c2c0b200241013a0048200241ec006a4101360200200241e4006a41013602002002410f360204200241e0c3c1003602602002410136025c200241b08fc2003602582002200241c8006a36020020022002360268200241206a200241d8006a104d200228022821012002290320210b4105210c4105410876210520022802dc8004450d0e0c0d0b200241d880046a410c6a2004360200200241013a0000200241ec006a4101360200200241d8006a410c6a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d20022802282101410521052002350224422086200235022084210b0b2005410876210320022802dc8004450d100c0f0b200241d880046a410c6a2004360200200241013a0000200241ec006a4101360200200241d8006a410c6a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d2002350224422086210d200228022821032002350220210b410521010c120b200241013a0048200241ec006a4101360200200241e4006a41013602002002410f360204200241e0c3c1003602602002410136025c200241b08fc2003602582002200241c8006a36020020022002360268200241206a200241d8006a104d20022802282103410521052002350224422086200235022084210b0b2005410876210120022802dc8004450d160c150b200241013a0000200241ec006a4101360200200241e4006a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d200228022821094105210a2002350224422086200235022084210b0b200a410876210120022802dc8004450d180c170b200241d880046a410c6a2004360200200241013a0000200241ec006a4101360200200241d8006a410c6a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d20022802282103410521012002350224422086200235022084210b0b2001410876210520022802dc8004450d1a0c190b200241013a0000200241ec006a4101360200200241e4006a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241d880046a200241d8006a104d20022802e08004210a4105210920023502dc800442208620023502d8800484210b0b200941087621012002280224450d1c0c1b0b410f210c0b200c410876210520022802dc8004450d010b20022802d8800410010b20004101360200200041106a2001360200200041086a200b37020020002005410874200c41ff017172360204200241f080046a24000f0b200241e480046a20013602004200210d410f21050b200d420084210b2005410876210320022802dc8004450d010b20022802d8800410010b20004101360200200041106a2001360200200041086a200b37020020002003410874200541ff017172360204200241f080046a24000f0b200241e480046a20013602004200210d410f21010b4200210b0b200d200b84210b2001410876210520022802dc8004450d010b20022802d8800410010b20004101360200200041106a2003360200200041086a200b37020020002005410874200141ff017172360204200241f080046a24000f0b410f21054200210b4200210d0b200d200b84210b2005410876210120022802dc8004450d010b20022802d8800410010b20004101360200200041106a2003360200200041086a200b37020020002001410874200541ff017172360204200241f080046a24000f0b410f210a0b4200420084210b200a410876210120022802dc8004450d010b20022802d8800410010b20004101360200200041106a2009360200200041086a200b37020020002001410874200a41ff017172360204200241f080046a24000f0b200241e480046a20013602004200210d410f21010b200d420084210b2001410876210520022802dc8004450d010b20022802d8800410010b20004101360200200041106a2003360200200041086a200b37020020002005410874200141ff017172360204200241f080046a24000f0b410f21090b4200420084210b200941087621012002280224450d010b200228022010010b20004101360200200041106a200a360200200041086a200b37020020002001410874200941ff017172360204200241f080046a24000f0b200241013a0020200241ec006a4101360200200241e4006a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc2003602582002200241206a3602182002200241186a360268200241d880046a200241d8006a104d20022802e08004210520022903d88004210d0b410521010c010b410f21010b2000200136020420004101360200200041106a2005360200200041086a200d370200200241f080046a24000f0b200241d880046a41106a200141106a280200360200200241d880046a41086a200141086a290200370300200220012902003703d88004200241d8006a200241d880046a10ac02024020022802584101470d002000200229025c370204200041013602002000410c6a200241d8006a410c6a29020037020020022802dc8004450d0e20022802d880041001200241f080046a24000f0b200228025c210420022802e4800420022802e88004462101024020022802dc8004450d0020022802d8800410010b02402001450d00410921010c0d0b20024103410220011b3a0000200241ec006a4101360200200241d8006a410c6a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d200241e3006a200241286a2802003600002002200229032037005b200041053a000420004101360200200020022900583700052000410c6a200241df006a290000370000200241f080046a24000f0b200241106a200241ec006a280200360200200241086a2201200241e4006a2902003703002002200229025c3703002001280200210441002105200228020c210120022802002108410021030240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024003402005411f4b0d0120042001460d032001417f460d152004200141016a220a490d16200820016a2d0000220941ff00712005411f71742003722103200541076a2105200a21012009418001710d000b2002410c6a200a36020041042104410d20032005411f4b20096741686a41ff01714104497122011b41ff01714100200341807e7120011b72210320010d012003450d03200241e1006a21124200210d200241386a41086a211d200241206a41106a2126200241206a410c6a2111200241d8006a41146a211b410421044100211a0340200241d8006a200210ac0220022802584101460d0b200228025c21064100210a201d410036020020024201370338200241d8006a41004180800110f7021a024002402006450d002002410c6a220e2802002101200241086a2802002107410021092002280200210c0340200720016b200620096b220541808001200541808001491b2205490d09200120056a22082001490d1a20072008490d1b200241d8006a200c20016a200510f8021a200241386a200241d8006a20051025200821012006200520096a22094b0d000b200e2008360200201d2802002108200228023c2101200228023821070c010b4101210741002101410021080b201a41016a211a2026200836020020114100360200200241206a41086a220e20083602002002200136022420022007360220410021014100210603402001411f4b0d092008200a460d0a200a417f460d1a2008200a41016a2209490d1b2007200a6a2d0000210520112009360200200541ff00712001411f71742006722106200141076a21012009210a2005418001710d000b410d20062001411f4b20056741686a41ff01714104497122011b41ff01714100200641807e7120011b72210720010d1341002105024002402007450d004100210c410421094104211e410021170340200241d8006a200241206a10ac02200228025c210620022802584101460d0f200e280200220820112802002201460d10200141016a210a2001417f460d1f2008200a490d20200228022020016a2c000021012011200a36020020014100480d11200141017441807f71200172220141ff017141fb014d0d1202402017200c470d00200c41016a220a200c490d2f200c4101742208200a200a2008491b2208ad420386220b422088a70d2f200ba7220a4100480d2f02400240200c450d00200a1000220f450d21200f201e200a200c410374220c200c200a4b1b10f802210a201e1001200a211e0c010b200a1000221e450d200b2008210c0b201e20096a220a201c41807e712001417f7341ff017172221c3a0000200a417c6a2006360200200941086a2109201741016a22172007490d000c020b0b4104211e4100210c410021170b4101210a4108210e41002109410021080340200241d8006a200241206a10ab0220022802584101460d0b200241d880046a41026a2201201241026a2d00003a0000200220122f00003b01d88004200241d8006a410c6a2802002114200241d8006a41106a280200210f201b280200211602400240200241d8006a41086a2d000022074106470d00200a417f6a210a0c010b2007417e6a41024b0d004104200a41016a22252025200a4922241b21064115201020241b211041c29bc100201320241b21132025200a490d142006210a0b200241d8006a41026a220620012d00003a0000200220022f01d880043b0158024020082009470d00200941016a22012009490d2d20094101742225200120012025491b2225ad420486220b422088a70d2d200ba722014100480d2d024002402009450d00200110002224450d222024200e200120094104742209200920014b1b10f8022101200e10012001210e0c010b20011000220e450d210b202521090b200e20056a220120073a00002001410c6a2016360200200141086a200f360200200141046a2014360200200141036a20062d00003a0000200141016a20022f01583b0000200541106a2105200841016a2108200a0d000b202628020021012011280200210502402002280224450d00200228022010010b20052001470d140240200d422088a72201200da7470d00200141016a22052001490d2c2001410174220a20052005200a491bad220b42187e2215422088a70d2c2015a722054100480d2c024002402001450d0020051000220a450d22200a20042005200141186c2201200120054b1b10f802210120041001200121040c010b200510002204450d210b200d42808080807083200b84210d0b2004200d422088a741186c6a2201200e36020c200120173602082001200c3602042001201e360200200141146a2008360200200141106a2009360200200d4280808080107c210d201a2003490d000c050b0b2002410c6a2001360200410f21030b2003410876210120022802040d230c240b2002410c6a2004360200200241013a0020200241ec006a4101360200200241d8006a410c6a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc2003602582002200241206a3602182002200241186a360268200241d880046a200241d8006a104d20022802e08004210a20022903d88004210b410521034105410876210120022802040d220c230b4200210d0b2002410c6a28020021012002280210210502402002280204450d00200228020010010b20012005470d01410b21010c2c0b2002410c6a2001360200200241013a0047200241ec80046a4101360200200241d880046a410c6a4101360200200241d880046a41086a41e0c3c1003602002002410f36021c200241e880046a200241186a360200200241013602dc8004200241b08fc2003602d880042002200241c7006a360218200241c8006a200241d880046a104d200241c8006a41086a280200210a200228024c21102002280248211341052106200228023c450d1e200228023810010c1e0b20024103410220012005461b3a0020200241d8006a41146a4101360200200241d8006a410c6a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc2003602582002200241206a3602182002200241186a360268200241d880046a200241d8006a104d20022802e08004210a20022903d88004210b0240200d422088a72201450d002004200141186c6a21092004210303400240200341046a280200450d00200328020010010b0240200341146a2802002205450d00200328020c2101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b200341186a21010240200341106a280200450d002003410c6a28020010010b2001210320012009470d000b0b4105210341002101200da7450d1f200410010c1f0b410f210620022802240d1b0c1c0b200241013a0048200241ec006a4101360200200241e4006a4101360200200241d8006a41086a41e0c3c1003602002002410f36021c200241e8006a200241186a3602002002410136025c200241b08fc2003602582002200241c8006a360218200241d880046a200241d8006a104d200241d880046a41086a280200210a20022802dc8004211020022802d8800421134105210620022802240d1a0c1b0b200241e8006a280200210a200241e4006a2802002110200241e0006a2802002113200228025c21062008450d160c150b200241e8006a280200210a200241e4006a2802002110200241e0006a2802002113200228025c21060c190b200241e8006a280200210a200241e4006a2802002110200241e0006a2802002113200c0d150c160b200241013a0048200241ec006a4101360200200241e4006a4101360200200241d8006a41086a41e0c3c1003602002002410f36021c200241e8006a200241186a3602002002410136025c200241b08fc2003602582002200241c8006a360218200241d880046a200241d8006a104d200241e280046a2f01002105200241e180046a2d00002103200241d880046a41086a2d0000210a20022802dc8004211020022802d880042113410521090c030b411821090c010b410621090b0b200341ff0171410874200a41ff017172200541107472210a200141ff01714108742009722106200c450d110c100b024020074109470d00200f41ffffffff0371450d00201410010b20080d0d0c0e0b2007210620022802240d100c110b20024103410220052001461b3a0048200241ec006a4101360200200241e4006a4101360200200241d8006a41086a41e0c3c1003602002002410f36021c200241d8006a41106a200241186a3602002002410136025c200241b08fc2003602582002200241c8006a360218200241d880046a200241d8006a104d200241d880046a41086a280200210a20022802dc8004211020022802d88004211302402008450d0020084104742105200e21010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b02402009450d00200e10010b41052106200c450d10201e10010c100b417f200141016a107a000b200141016a20041076000b20012008107a000b200820071076000b417f200a41016a107a000b200a41016a20081076000b200a41041019000b417f200a107a000b200a20081076000b200141081019000b200541041019000b200e21010340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b02402009450d00200e10010b200c450d010b201e10010b2002280224450d010b200228022010010b2010ad422086210b2013ad21150240200d422088a72201450d002004200141186c6a21092004210303400240200341046a280200450d00200328020010010b0240200341146a2802002205450d00200328020c2101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b200341186a21010240200341106a280200450d002003410c6a28020010010b2001210320012009470d000b0b200b201584210b0240200da7450d00200410010b2006220341087621012002280204450d010b200228020010010b20004101360200200041106a200a360200200041086a200b37020020002001410874200341ff017172360204200241f080046a24000f0b200241e880046a200241ec006a280200360200200241e080046a2208200241d8006a410c6a2902003703002002200229025c3703d88004410021014100210302400240024002400240024002400240024002400240024003402001411f4b0d012008280200220a200241d880046a410c6a22092802002205460d02200541016a21042005417f460d05200a2004490d0620022802d8800420056a2d0000210520092004360200200541ff00712001411f71742003722103200141076a21012005418001710d000b41042104410d20032001411f4b20056741686a41ff01714104497122051b41ff01714100200341807e7120051b7221012005450d034200210d4200210b0c020b410f21014200210b4200210d0c010b200241013a0048200241ec006a4101360200200241e4006a41013602002002410f360204200241e0c3c1003602602002410136025c200241b08fc2003602582002200241c8006a36020020022002360268200241206a200241d8006a104d2002350224422086210d2002280228210a2002350220210b410521010b200d200b84210b2001410876210520022802dc8004450d090c080b0240024002400240024002400240024002400240024002402001450d004200210d200241d880046a410c6a2108200241d880046a41086a211341042104410021120340201328020022092008280200220a460d03200a41016a2105200a417f460d0f20092005490d1020022802d880042207200a6a2c000021032008200536020020034100480d04200341017441807f71200372220341ff017141847e6a221141034b0d05410021060240024002400240024020110e0400010203000b4103210620092005470d030c0c0b4102210620092005470d020c0b0b410121060b20092005460d090b200a41026a21032005417f460d1120092003490d12200720056a2d00002105200820033602004100210302402005450d0020054101470d0a41800221030b200241d8006a200241d880046a10aa02200241d8006a410c6a2802002109200241d8006a41086a2802002107200228025c211120022802584101460d0b0240200d422088a72205200da7470d00200541016a220a2005490d1820054101742210200a200a2010491bad220b4204862215422088a70d182015a7220a4100480d18024002402005450d00200a10002210450d1620102004200a20054104742205200a2005491b10f802210520041001200521040c010b200a10002204450d150b200d42808080807083200b84210d0b2004200d422088a74104746a2205200c4180807c71200672200372220c36020c200520093602082005200736020420052011360200200d4280808080107c210d201241016a22122001490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410721010c1c0b20024103410220012005461b3a0000200241ec006a4101360200200241e4006a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d2002280228210a2002290320210b0240200d422088a72201450d00200420014104746a2109200421030340024020032802082205450d0020032802002101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b200341106a21010240200341046a280200450d00200328020010010b2001210320012009470d000b0b4105210141002105200da7450d12200410010c120b200241013a0048200241ec006a4101360200200241e4006a4101360200200241d8006a41086a41e0c3c1003602002002410f360204200241e8006a20023602002002410136025c200241b08fc2003602582002200241c8006a360200200241206a200241d8006a104d200241206a41086a280200210a2002280224210920022802202107410521010c030b411821010c010b410621010b0b200341ff017141087420017221110c040b200241013a0000200241ec006a4101360200200241e4006a4101360200200241d8006a41086a41e0c3c1003602002002410f36021c200241e8006a200241186a3602002002410136025c200241b08fc20036025820022002360218200241206a200241d8006a104d200241206a41086a280200210a2002280224210920022802202107410521010c010b410c21010b200541ff017141087420017221110c010b200241e8006a280200210a0b2009ad422086210b2007ad21150240200d422088a72201450d00200420014104746a2109200421030340024020032802082205450d0020032802002101200541047421050340024020012d00004109470d00200141086a28020041ffffffff0371450d00200141046a28020010010b200141106a2101200541706a22050d000b0b200341106a21010240200341046a280200450d00200328020010010b2001210320012009470d000b0b200b201584210b0240200da7450d00200410010b20112201410876210520022802dc80040d070c080b417f2004107a000b2004200a1076000b417f2005107a000b200520091076000b417f2003107a000b200320091076000b200a41041019000b20022802d8800410010b20004101360200200041106a200a360200200041086a200b37020020002005410874200141ff017172360204200241f080046a24000f0b200241e880046a200241ec006a280200360200200241e080046a2201200241e4006a2902003703002002200229025c3703d88004200128020021044100210520022802e48004210120022802d88004210841002103024002400240024003402005411f4b0d0120042001460d032001417f460d062004200141016a220a490d07200820016a2d0000220941ff00712005411f71742003722103200541076a2105200a21012009418001710d000b200241e480046a200a36020041042104410d200341ff01712005411f4b20096741686a41ff01714104497122011b4100200341807e7120011b7221052001450d034200210d0c010b200241e480046a20013602004200210d410f21050b200d420084210b2005410876210120022802dc80040d070c080b200241d880046a410c6a2004360200200241013a0000200241ec006a4101360200200241d8006a410c6a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d20022802282103410521052002350224422086200235022084210b0c050b0240024002402005450d004200210d41042104200241d8006a410c6a210c200241d8006a41086a21124100210a0340200241d8006a200241d880046a10bd0220022d005c210320022802584101460d0320022d005f210920022f005d2108200c2802002106201228020021070240200d422088a72201200da7470d00200141016a22112001490d0520014101742213201120112013491bad220b420c7e2215422088a70d052015a722114100480d05024002402001450d00201110002213450d0a2013200420112001410c6c2201200120114b1b10f802210120041001200121040c010b201110002204450d090b200d42808080807083200b84210d0b2004200d422088a7410c6c6a2201200820094110747222093b000120012007360204200120033a0000200141036a20094110763a0000200141086a2006360200200d4280808080107c210d200a41016a220a2005490d000c020b0b4200210d0b200241e480046a280200210120022802e880042105024020022802dc8004450d0020022802d8800410010b024020012005470d00410621010c090b20024103410220012005461b3a0000200241ec006a4101360200200241e4006a41013602002002410f36021c200241e0c3c1003602602002410136025c200241b08fc200360258200220023602182002200241186a360268200241206a200241d8006a104d200228022821032002290320210b4105210541002101200da7450d07200410010c070b20022f005d20022d005f411074724108742003722105200241d8006a41106a2802002103200241d8006a41086a290300210b200da7450d04200410012005410876210120022802dc80040d050c060b1018000b417f200141016a107a000b200141016a20041076000b201141041019000b2005410876210120022802dc8004450d010b20022802d8800410010b20004101360200200041106a2003360200200041086a200b37020020002001410874200541ff017172360204200241f080046a24000f0b200020013a000420004100360200200041056a20022f00d880043b0000200041186a200b370200200041146a20053602002000410c6a200d370200200041086a2004360200200041206a2002290258370200200041076a200241da80046a2d00003a0000200041286a200241d8006a41086a290200370200200241f080046a24000f0b200241f080046a24000be30602097f017e230041d080016b2202240041002103200141086a2104200141046a21054100210602400240024002400240024002400240024003402003411f4b0d012005280200220720042802002208460d02200841016a21092008417f460d0520072009490d06200128020020086a2d0000210820042009360200200841ff00712003411f71742006722106200341076a21032008418001710d000b024020034120490d00410d210320086741686a41ff01714104490d030b2002410036021020024201370308200241186a41004180800110f7021a4100210302402006450d0041002109200141086a2107200141046a210a0340200a2802002205200728020022086b200620096b220341808001200341808001491b2203490d05200820036a22042008490d0820052004490d09200241186a200128020020086a200310f8021a20072004360200200241086a200241186a200310252006200320096a22094b0d000b200241106a28020021030b2002290308210b200041146a2003360200200041106a41003602002000410c6a20033602002000200b37020420004100360200200241d080016a24000f0b410f21030c010b200241013a00a880012002412c6a4101360200200241246a41013602002002410f36029c8001200241e0c3c1003602202002410136021c200241b08fc2003602182002200241a880016a360298800120022002419880016a360228200241b880016a200241186a104d410521030b2000200336020420004101360200200041086a20022902b88001370200200041106a200241b880016a41086a2802003602000c050b200241013a00a78001200241cc80016a4101360200200241b880016a410c6a41013602002002410f36029c8001200241e0c3c1003602c08001200241013602bc8001200241b08fc2003602b880012002200241a780016a360298800120022002419880016a3602c88001200241a880016a200241b880016a104d200241c380016a200241b080016a280200360000200220022903a880013700bb8001200041053a000420004101360200200020022900b880013700052000410c6a200241bf80016a290000370000200228020c450d0420022802081001200241d080016a24000f0b417f2009107a000b200920071076000b20082004107a000b200420051076000b200241d080016a24000bdc0501097f230041e0086b22022400200241286a200110ac02024020022802284101470d002000200229022c370204200041013602002000410c6a200241286a410c6a290200370200200241e0086a24000f0b024002400240024002400240200228022c2203450d00410021042002410036022020024201370318200241286a410041800810f7021a2001410c6a2105200141086a2106034020062802002207200528020022086b200320046b22094180082009418008491b2209490d02200820096a220a2008490d052007200a490d06200241286a200128020020086a200910f8021a2005200a360200200241186a200241286a200910252003200920046a22044b0d000b200228021c2104200241286a20022802182208200241206a280200220a1086014101210920022802284101470d02200241106a200229022c37030020022008360204200241047221080c030b2000428080808010370200200041086a4200370200200241e0086a24000f0b200241013a00af08200241d4086a4101360200200241c0086a410c6a41013602002002410f3602dc08200241e0c3c1003602c808200241013602c408200241b08fc2003602c0082002200241af086a3602d8082002200241d8086a3602d008200241b0086a200241c0086a104d200241cb086a200241b8086a280200360000200220022903b0083700c308200041053a000420004101360200200020022900c0083700052000410c6a200241c7086a2900003700000240200228021c450d00200228021810010b200241e0086a24000f0b2002200836020420024104722108410021090b2002410c6a200a360200200241086a220a20043602002002200936020002402009450d000240200a280200450d00200828020010010b200041083a000420004101360200200241e0086a24000f0b200020082902003702042000410c6a200841086a28020036020020004100360200200241e0086a24000f0b2008200a107a000b200a20071076000ba20401047f230041c0006b2202240002400240024002400240024020012802082203200128020c2204470d00200241013a000f200241346a41013602002002412c6a41013602002002410f36023c200241e0c3c10036022820024101360224200241b08fc20036022020022002410f6a3602382002200241386a360230200241106a200241206a104d2002412a6a200241186a280200360100200220022903103701222002200241266a29010037010620022002290120370300410521030c010b200441016a21052004417f460d0320032005490d04200128020020046a2d00002104410c21032001410c6a20053602002004450d014101210520044101460d020b200020043a0005200020033a000420002002290300370106200041013602002000410c6a2002290106370100200241c0006a24000f0b410021050b200241206a200110ac02024020022802204101470d0020002002290224370204200041013602002000410c6a200241206a410c6a290200370200200241c0006a24000f0b200228022421040240024002402005450d00200241206a200110ac024101210120022802204101470d0120002002290224370204200041013602002000410c6a200241206a410c6a290200370200200241c0006a24000f0b410021010c010b200228022421030b20002004360204200041003602002000410c6a2003360200200041086a2001360200200241c0006a24000f0b417f2005107a000b200520031076000b3802017f017e230041106b220324002003200210a901200329030021042000200341086a29030037030820002004370300200341106a24000bda0402027f017e23004180016b22052400200541106a41186a200241186a290000370300200541106a41106a200241106a290000370300200541106a41086a200241086a2900003703002005200229000037031002400240024002402004417f4c0d00024002402004450d002004100022020d01200441011019000b410121020b200520043602542005200236025020054100360258200541d0006a200320041025200541306a41086a2204200528025836020020052005290350370330200541d0006a41186a200541106a41186a290300370300200541d0006a41106a200541106a41106a290300370300200541d0006a41086a200541106a41086a29030037030020052005290310370350200541f0006a41086a200428020036020020052005290330370370200541c0006a200541d0006a200541f0006a10c0020240024002400240024020052802402203200528024822044188f0c100410041001004417f460d00200541003602582005200436025420052003360250200541086a200541d0006a10352005280208450d07200528020c2204417f4c0d052004450d01200410002202450d0820024100200410f7021a0c020b2000410036020020052802440d020c030b410121020b200541d8006a2206200628020022062004410020052802502005280254200220042006100422062006417f461b2206200620044b1b6a360200200420064b0d032002450d0420002004ad2207422086200784370204200020023602002005280244450d010b200310010b20054180016a24000f0b102c000b200210010b41eac4c10041331042000b200441011019000baf0601087f230041e0006b22032400200341c0006a41186a200141186a290000370300200341c0006a41106a200141106a290000370300200341c0006a41086a200141086a290000370300200320012900003703402003410036023820034201370330200341306a418b9ec10041081025200341106a200341c0006a10f50120032802142104200328021021050240024002400240024002400240024020032802342206200328023822076b200328021822084f0d00200720086a22012007490d0420064101742209200120012009491b22094100480d042006450d012003280230210a200910002201450d072001200a20092006200620094b1b10f8021a200a10010c020b20032802302101200621090c020b200910002201450d050b20032009360234200320013602300b200120076a2005200810f8021a200341306a41086a200720086a220736020002402004450d00200510010b200341106a41086a220842003703002003420037031020012007200341106a1002200341086a20082903003703002003200329031037030002402009450d00200110010b2003410036024820034201370340200228020022042002280208200341c0006a108e01200328024421072003280248210920032802402101200341c0006a41186a22084200370300200341c0006a41106a22064200370300200341c0006a41086a220542003703002003420037034020012009200341c0006a100d200341106a41186a2008290300370300200341106a41106a2006290300370300200341106a41086a20052903003703002003200329034037031002402007450d00200110010b411010002207450d0120072003290300370000200741086a2209200341086a290300370000413010002201450d0220012007290000370000200141086a200929000037000020071001200042b0808080800637020420002001360200200141286a200341106a41186a290300370000200141206a200341206a290300370000200141186a200341106a41086a290300370000200120032903103700100240200241046a280200450d00200410010b200341e0006a24000f0b1018000b411041011019000b413041011019000b200941011019000bcd0c05027f017e0e7f027e097f23004190036b2202240020024188016a41086a2203200141086a2802003602002002200129020037038801200241086a20024188016a10cf01200241306a41206a200241086a41206a280200360200200241306a41186a200241086a41186a290300370300200241306a41106a200241086a41106a290300370300200241306a41086a200241086a41086a2903003703002002200229030837033020024188016a200241306a10d1010240024020022903a80122044202510d00200241cc016a2105200241b8016a2106200241b0016a2107200241c0016a2108200241c4016a2109200241c8016a210a20024188016a41206a210b200241ec026a210c200241f4026a210d0340200241e8006a41186a220120024188016a41186a220e290300370300200241e8006a41106a220f20024188016a41106a2210290300370300200241e8006a41086a22112003290300370300200241d8006a41086a2212200541086a28020036020020022002290388013703682002200529020037035820062903002113200729030021142008280200211520092802002116200a2802002117200241d8016a41186a22182001290300370300200241d8016a41106a2219200f290300370300200241d8016a41086a221a2011290300370300200220022903683703d801200241f8016a41086a22012012280200360200200220022903583703f8010240024020044201520d00200241d8016a2014201310c202450d0002402015450d002016450d00201510010b20024188026a41086a2001280200360200200220022903f8013703880220024188016a20024188026a10cb0120024188016a10cc010c010b024002402015450d00410f1000220f450d052002420f37028c012002200f3602880120024188016a41c1b0c000410f102520024188026a41086a220f2003280200360200200220022903880137038802200241d8016a20024188026a101e200f280200211b200228028c02211c20022802880221112003410036020020024201370388012015201720024188016a108e0120032802002117200228028c01211d20022802880121122003420037030020024200370388012011201b20024188016a1002200f200329030037030020022002290388013703880220024188026a41102012201710030240201d450d00201210010b0240201c450d00201110010b4101211b2016450d01201510010c010b4100211b0b20032001280200360200200220022903f8013703880120024188026a20024188016a10cb01200b20024188026a41206a280200360200200e20024188026a41186a290300370300201020024188026a41106a290300370300200320024188026a41086a290300370300200220022903880237038801200241e0026a20024188016a10cd01024020022802e002450d000340200241b0026a41086a2211200241e0026a41086a2201280200360200200220022903e0023703b002200c280200210f200241e0026a41106a22122802002110200d2802002117200241c0026a41086a220e2011280200360200200220022903b0023703c00202400240200f450d00200241e0026a41186a2018290300370300201220192903003703002001201a290300370300200220022903d8013703e00220024180036a41086a200e280200360200200220022903c00237038003200241d0026a200241e0026a20024180036a10c002200241d0026a41086a280200211220022802d002211120014100360200200242013703e002200f2017200241e0026a108e0120022802e402210e2011201220022802e0022217200128020010030240200e450d00201710010b024020022802d402450d00201110010b2010450d01200f10010c010b200241e0026a41186a2018290300370300201220192903003703002001201a290300370300200220022903d8013703e00220024180036a41086a200e280200360200200220022903c00237038003200241d0026a200241e0026a20024180036a10c00220022802d0022201200241d0026a41086a280200100820022802d402450d00200110010b200241e0026a20024188016a10cd0120022802e0020d000b0b20024188016a10cc01201b201545720d002016450d00201510010b20024188016a200241306a10d101200b29030022044202520d000b0b200241306a10d00120024190036a24000f0b410f41011019000bbb1106027f017e047f017e067f037e230041b0016b22032400200341a0016a41086a22044200370300200342003703a00141bef0c100411b200341a0016a100220034190016a41086a2004290300370300200320032903a001370390010240024002400240024002400240024020034190016a41104188f0c100410041001004417f460d00200342003703282003420037032020034190016a4110200341206a4110410010042204417f460d012004410f4d0d012003290320200158200341286a290300220520025820052002511b0d0020002001200210aa01200341b0016a240041010f0b411410002204450d022003421437022420032004360220200341206a41eeefc10041141025200341a0016a41086a22042003280228360200200320032903203703a0012000200341a0016a101e2004280200210620032802a401210720032802a001210820044200370300200342003703a00120082006200341a0016a100220034190016a41086a2004290300370300200320032903a0013703900120034190016a4110100e210402402007450d00200810010b02402004450d0020002001200210aa01200341b0016a240041000f0b200341a0016a41086a22044200370300200342003703a001419d85c2004114200341a0016a100220034190016a41086a2004290300370300200320032903a00137039001410021040240024020034190016a41104188f0c100410041001004417f460d002003410036022020034190016a4110200341206a41044100100441016a41044d0d0320032802202204410e744180807c71418080046a22080d0141a4acc300104f000b4180800421080b200341106a200120022008ad420010fd0241002109024002402003280210220841ff017141e900470d00200341a0016a2008410e76220610ce0202402008410876220720064106746b220820032802a8014f0d00200320032802a00120084105746a220810b0014200210a2003290300200341086a290300844200510d020b024020032802a401450d0020032802a00110010b410221090b200341206a200410ce02024020032802282208413f4d0d00200341286a21060340200441016a210402402003280224450d00200328022010010b200341206a200410ce022006280200220841c0004f0d000b0b2003280220210620032802242107200341206a41186a220b200041186a290000370300200341206a41106a220c200041106a290000370300200341206a41086a220d200041086a2900003703002003200029000037032002400240024020082007470d00200841016a22072008490d072008410174220e20072007200e491b2207ad4205862205422088a70d072005a7220f4100480d072008450d01200f1000220e450d08200e2006200f200841057422102010200f4b1b10f8021a200610010c020b2006210e0c010b200f1000220e450d060b200441067420086a210f200e20084105746a22062003290320370000200641186a200b290300370000200641106a200c290300370000200641086a200d2903003700000240200841016a220841c000470d002003200441016a360220200341a0016a41086a22064200370300200342003703a001419d85c2004114200341a0016a100220034190016a41086a2006290300370300200320032903a0013703900120034190016a4110200341206a410410030b20032008360228200320073602242003200e3602202004200341206a10f402200341206a41086a41003a0000200341cc006a200f360200200341c9006a20093a0000200341296a2000290000370000200341316a200041086a290000370000200341396a200041106a290000370000200341c1006a200041186a290000370000200341013a0020200341206a10b40120012105200221110c070b200341206a41186a200041186a220e2900002205370300200341206a41106a200041106a22092900002212370300200341206a41086a2204200041086a220b2900002211370300200820002900002213370000200841086a2011370000200841106a2012370000200841186a2005370000200320133703202004200341a0016a41086a2208280200360200200320032903a0013703202006200341206a10f402200441003a0000200341cc006a2007360200200341c9006a41013a0000200341296a2000290000370000200341316a200b290000370000200341396a2009290000370000200341c1006a200e290000370000200341013a0020200341206a10b40120084200370300200342003703a00141b185c2004116200341a0016a100220034190016a41086a2008290300370300200320032903a001370390010240024020034190016a41104188f0c100410041001004417f460d00200342003703282003420037032020034190016a4110200341206a4110410010042204417f460d072004410f4d0d07200341286a29030021052003290320210a0c010b420021050b200520027c200a20017c2205200a54ad7c21110c060b41eac4c10041331042000b41eac4c10041331042000b411441011019000b1018000b200f41011019000b41eac4c10041331042000b20002005201110aa0142002112200341a0016a41086a22044200370300200342003703a00141d9f0c1004116200341a0016a100220034190016a41086a2004290300370300200320032903a0013703900102400240024020034190016a41104188f0c100410041001004417f460d00200342003703282003420037032020034190016a4110200341206a4110410010042204417f460d022004410f4d0d02200341286a290300210a200329032021120c010b4200210a0b02402012200520017d7c22132012542204200a201120027d2005200154ad7d7c2004ad7c2202200a542002200a511b0d002003201337032020032002370328200341a0016a41086a22044200370300200342003703a00141d9f0c1004116200341a0016a100220034190016a41086a2004290300370300200320032903a0013703900120034190016a4110200341206a411010030b200341b0016a240041000f0b41eac4c10041331042000bc60302057f017e230041306b2203240002400240024002400240410f10002204450d002003420f37022420032004360220200341206a41c1b0c000410f1025200341106a41086a22042003280228360200200320032903203703102002200341106a101e200428020021022003280214210520032802102106200341206a41086a220742003703002003420037032020062002200341206a1002200420072903003703002003200329032037031002400240024002400240200341106a41104188f0c100410041001004417f460d00200342103702242003200341106a360220200341086a200341206a10352003280208450d08200328020c2204417f4c0d062004450d01200410002202450d0920024100200410f7021a0c020b200041003602082000420137020020050d020c030b410121020b200341286a2207200728020022072004410020032802202003280224200220042007100422072007417f461b2207200720044b1b6a360200200420074b0d042002450d0520002004ad2208422086200884370204200020023602002005450d010b200610010b200341306a24000f0b410f41011019000b102c000b200210010b41eac4c10041331042000b200441011019000b9a0201027f0240024002402000280200220241074b0d000240024002400240024020020e080706050001020304070b2001410110240f0b20014102102420002802042000410c6a2802002001108e010f0b200141031024200041086a290300200110230f0b20014104102420002802042000410c6a2802002001108e010f0b200141051024200028020421032000410c6a28020022002001101b02402000450d002003200041186c6a210003402003280200200341086a2802002001108e012003410c6a280200200341146a2802002001108e01200341186a22032000470d000b20024101460d022002450d030b0f0b20014100102420002802042000410c6a2802002001108e010f0b41f089c300104f000b41f089c300104f000bb50102027f027e230041106b220324000240200128020022044100480d00200441ffffffff07460d002001200441016a36020002400240200141046a200210de012204450d002004280200450d00200441106a2903002105200441086a29030021060c010b200320012802102002200141146a280200280214110400200341086a2903002105200329030021060b20012001280200417f6a3602002000200537030820002006370300200341106a24000f0b10c602000b900101017f230041c0006b220024002000411836020c200041e39dc100360208200041286a410c6a4110360200200041246a4102360200200041106a410c6a41023602002000410136022c2000418489c20036021820004102360214200041a4aec3003602102000200041386a3602302000200041086a3602282000200041286a360220200041106a41b4aec3001071000b840b05027f017e0f7f027e057f230041a0036b22022400024020002802000d002000417f36020020024188016a41086a2203200141086a2802003602002002200129020037038801200241086a20024188016a10cf01200241306a41206a200241086a41206a280200360200200241306a41186a200241086a41186a290300370300200241306a41106a200241086a41106a290300370300200241306a41086a200241086a41086a2903003703002002200229030837033020024188016a200241306a10d101024020022903a80122044202510d00200041046a2105200241a0026a41246a2106200241cc016a2107200241dc026a210120024188016a410472210820024188016a41306a210920024188016a41286a210a200241c0016a210b200241c4016a210c200241c8016a210d200241bc026a210e0340200241e8006a41186a220f20024188016a41186a290300370300200241e8006a41106a221020024188016a41106a2211290300370300200241e8006a41086a22122003290300370300200241d8006a41086a2213200741086a28020036020020022002290388013703682002200729020037035820092903002114200a2903002115200b2802002116200c2802002117200d2802002118200241d8016a41086a22192013280200360200200220022903583703d801200241e8016a41186a2213200f290300370300200241e8016a41106a221a2010290300370300200241e8016a41086a220f2012290300370300200220022903683703e80120024188016a2005200241e8016a10df0102400240024002402002280288014101470d00200328020041e8026a201128020041306c6a2110024020044201520d002010420137030020102015370308201041106a20143703000b2016450d01201041186a2112024020102802182211450d00201241046a280200450d00201110010b201220173602042012201636020020102018360220410121180c020b200241e8016a41306a200841306a280200360200200241e8016a41286a200841286a290200370300200241e8016a41206a200841206a2902003703002013200841186a290200370300201a200841106a290200370300200f200841086a290200370300200220082902003703e801200241a0026a41106a2014370300200241a0026a41086a2015370300200241a0026a41206a2018360200200e2017360200200241a0026a41186a2016360200200620022903d801370200200641086a2019280200360200200220043703a002200241e8016a200241a0026a10e2011a0c020b410021180b200f2019280200360200200220022903d8013703e801200241a0026a200241e8016a10cb01200241e8016a41206a200241a0026a41206a2802003602002013200241a0026a41186a290300370300201a200241a0026a41106a290300370300200f200241a0026a41086a290300370300200220022903a0023703e801200241e8026a200241e8016a10cd01024020022802e802450d00201041246a21120340200241d0026a41106a200241e8026a41106a290300370300200241d0026a41086a220f200241e8026a41086a2210290300370300200220022903e8023703d00220024190036a41086a200f280200360200200220022903d002370390032010200141086a280200360200200220012902003703e80220024180036a201220024190036a200241e8026a10e0010240200228028003450d00200228028403220f450d0020024180036a41086a280200450d00200f10010b200241e8026a200241e8016a10cd0120022802e8020d000b0b200241e8016a10cc012018201645720d002017450d00201610010b20024188016a200241306a10d10120024188016a41206a29030022044202520d000b0b200241306a10d0012000200028020041016a360200200241a0036a24000f0b108402000bb50101027f230041106b220324000240200128020022044100480d00200441ffffffff07460d002001200441016a360200024002400240200141046a200210de012204450d002004280218450d002003200441186a102b2003280200450d0120002003290300370200200041086a200341086a2802003602000c020b200341003602000b200020012802102002200141146a2802002802101104000b20012001280200417f6a360200200341106a24000f0b10c602000b2001017f2000200128020022023602002000200128020420026b41286e3602040bb70703037f017e067f230041106b2202240020024100360208200242013703000240024002400240024002400240024002400240024002400240200128020022034101460d00024020034102460d0020034103470d0220012802042101410110002203450d09200242818080801037020420022003360200200341003a0000200128020020012802082002108e010c050b200141086a280200210320012802042104410110002201450d07200242818080801037020420022001360200200141033a000020042903002105410910002204450d09200420012d00003a00002001100120024289808080900137020420022004360200200420053700012002280204220641776a413f4b0d022006410174220141c900200141c9004b1b22074100480d05200710002201450d0c2001200420072006200620074b1b10f80221062004100120022007360204200220063602000c030b20012802042103410110002201450d09200242818080801037020420022001360200200141023a000020032002101e0c030b200141086a280200210320012802042101410110002204450d09200242818080801037020420022004360200200441013a000020032002101b2003450d0220034105742108200241086a220928020021032002280204210603400240024002400240200620036b41204f0d00200341206a22042003490d0820064101742207200420042007491b220a4100480d082006450d012002280200210b200a10002207450d092007200b200a20062006200a4b1b10f8021a200b10010c020b200341206a2104200228020021070c020b200a10002207450d070b2002200a36020420022007360200200a21060b20092004360200200720036a220341086a200141086a290000370000200341106a200141106a290000370000200341186a200141186a2900003700002003200129000037000020042103200141206a2101200841606a22080d000c030b0b200421010b200241086a41c900360200200141116a200341086a290000370000200141196a200341106a290000370000200141216a200341186a290000370000200141296a200341206a290000370000200141316a200341286a290000370000200141396a200341306a290000370000200141c1006a200341386a290000370000200120032900003700090b20002002290300370200200041086a200241086a280200360200200241106a24000f0b1018000b200a41011019000b410141011019000b410141011019000b410941011019000b410141011019000b410141011019000b200741011019000b8b71070d7f027e027f057e047f017e017f230041f0016b22022400200241003a0000200128020020012802042002410120012802081004210320012001280208200341016a220341014b6a2204360208024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020034102490d0020022d00002203410b4b0d08024020030e0c00020304050a0b060c070d08000b41002105200241003a00002001280200200141046a28020020024101200410042103200141086a22012001280200200341016a220141014b6a36020020014102490d0f024020022d00002201450d0020014101462201450d104101410220011b21050b200041003a0000200020054101713a0001200041026a200241ee0010f8021a200241f0016a24000f0b2000410c3a0000200241f0016a24000f0b200241003a00002001280200200141046a28020020024101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d1a20022d00002203450d1720034101460d1820034102470d1a200241186a22064200370300200241106a4200370300200241086a2207420037030020024200370300200141086a220541002001280200200141046a2208280200200241202004100422032003417f461b2203412020034120491b20052802006a22093602002003411f4d0d1a2002280003210320022f0001210420022d0000210a20022f0007210b20022d0009210c20022f010a210d200228020c210e2002290310210f200241e1016a20062903003700002002200f3700d9012002200e3600d5012002200d3b00d3012002200c3a00d2012002200b3b01d001200642003703002007420037030020024200370310200242003703002005410020012802002008280200200241202009100422062006417f461b22064120200641204922061b20052802006a220736020020060d1a200241186a290300210f20022903102110200228020c210d20022f010a210e20022d0009211120022f000721122002280003210520022f0001210c20022d0000210b2002420037030820024200370300200141086a220841002001280200200141046a2209280200200241102007100422062006417f461b2206411020064110491b20082802006a22073602002006410f4d0d1a200241086a29030021132002290300211420024200370308200242003703002008410020012802002009280200200241102007100422012001417f461b2201411020014110491b20082802006a3602002001410f4d0d1a200241086a29030021152002290300211620024190016a41116a200f370000200241b0016a41186a200241d0016a41186a2d00003a0000200241b0016a41106a200241d0016a41106a290300370300200241b0016a41086a200241d0016a41086a29030037030020022010370099012002200d360095012002200e3b009301200220113a009201200220123b019001200220022903d0013703b001200241f0006a41086a20024190016a41086a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41186a20024190016a41186a2d00003a00002002200229039001370370200241b0016a41116a290000210f20022900b901211020022800b501210620022f00b301210720022d00b201210820022f01b0012109410221120c190b200241003a00002001280200200141046a28020020024101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d0a20022d00000d0a20024200370300200141086a220341002001280200200141046a280200200241082004100422012001417f461b2201410820014108491b20032802006a360200200141074d0d0a2002290300210f200041023a0000200041086a200f370300200020022800d001360001200041056a200241d0016a41046a2f00003b0000200041076a200241d6016a2d00003a0000200041106a200241e00010f8021a200241f0016a24000f0b200241003a00002001280200200141046a28020020024101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d1d20022d00002203450d1920034101460d1b20034102470d1d200241186a220a4200370300200241106a4200370300200241086a420037030020024200370300200141086a220541002001280200200141046a2206280200200241202004100422032003417f461b2203412020034120491b20052802006a22073602002003411f4d0d1d200a290300211720022903102113200228020c210820022f010a210920022d0009210b20022f0007210c2002280003210320022f0001210420022d0000210a20024200370308200242003703002005410020012802002006280200200241102007100422012001417f461b22014110200141104922011b20052802006a36020020010d1d200241086a290300210f20022903002110200220133700d901200241e1016a2017370000200220083600d501200220093b00d3012002200b3a00d2012002200c3b01d0012013423888201742088684a721012017423088a721062017421088a72107200241d0016a41086a290300211320022903d00121142017a72108410221050c1a0b200241003a00002001280200200141046a28020020024101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d3a20022d0000220341054b0d3a024020030e06003435363739000b200141046a220a280200210320024100360200200141086a2205410020012802002003200241042004100422032003417f461b2203410420034104491b20052802006a2206360200200341034d0d3a200228020021042002420037030820024200370300200541002001280200200a280200200241102006100422032003417f461b2203411020034110491b20052802006a3602002003410f4d0d3a200241086a290300210f2002290300211020022001103620022802002201450d3a200141187621032001410876210620022902042213423088a721072013422888a721082013421888a721092013a7210b410021050c390b200241003a00002001280200200141046a28020020024101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d2920022d0000220341044b0d29024020030e050023242527000b200241186a22054200370300200241106a4200370300200241086a420037030020024200370300200141086a220941002001280200200141046a220b280200200241202004100422032003417f461b2203412020034120491b20092802006a220c3602002003411f4d0d292005290300210f20022903102110200228020c210320022f010a210420022d0009210520022f0007210a2002280003210620022f0001210720022d00002108200b280200210b20024100360200200941002001280200200b20024104200c1004220b200b417f461b220b4104200b410449220b1b20092802006a220c360200200b0d2920022802002118200241186a220b4200370300200241106a4200370300200241086a420037030020024200370300200141086a221941002001280200200141046a221a28020020024120200c100422092009417f461b2209412020094120491b20192802006a221b3602002009411f4d0d29200b290300211320022903102114200228020c210920022f010a210b20022d0009210c20022f0007210d2002280003210e20022f0001211120022d00002112201a280200211a20024100360200201941002001280200201a20024104201b100422012001417f461b22014104200141044922011b20192802006a36020020010d29200228020021014100211a0c270b200241003a00002001280200200141046a28020020024101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d3020022d0000220341044b0d30024020030e05002a2b2c2e000b200141046a28020021054100210320024100360200200141086a220a410020012802002005200241042004100422012001417f461b2201410420014104491b200a2802006a360200200141034d0d30200228020021010c2f0b41002105200241003a00002001280200200141046a28020020024101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d0620022d00002203450d0920034101470d06200241186a22054200370300200241106a4200370300200241086a420037030020024200370300200141086a220341002001280200200141046a280200200241202004100422012001417f461b2201412020014120491b20032802006a3602002001411f4d0d062005290300210f20022903102110200228020c210120022f010a210320022d0009210420022f0007210a2002280003210620022f0001210720022d00002108410121050c0a0b2000410c3a0000200241f0016a24000f0b200241003a00002001280200200141046a28020020024101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d3720022d0000220341034b0d37024020030e0400191a1b000b200241186a22064200370300200241106a4200370300200241086a2207420037030020024200370300200141086a220a41002001280200200141046a2208280200200241202004100422032003417f461b2203412020034120491b200a2802006a22093602002003411f4d0d372002280003210320022f0001210420022d0000210520022f0007210b20022d0009210c20022f010a210d200228020c210e2002290310210f200241d0016a41116a20062903003700002002200f3700d9012002200e3600d5012002200d3b00d3012002200c3a00d2012002200b3b01d00120064200370300200742003703002002420037031020024200370300200a410020012802002008280200200241202009100422012001417f461b22014120200141204922011b200a2802006a36020020010d372002280003210c20022f0001210e20022d0000210d20022f0007210120022d0009210a20022f010a2106200228020c21072002290310210f20024190016a41116a200241186a290300370000200241b0016a41086a200241d0016a41086a290300370300200241b0016a41106a200241d0016a41106a290300370300200241b0016a41186a200241d0016a41186a2d00003a00002002200f370099012002200736009501200220063b0093012002200a3a009201200220013b019001200220022903d0013703b001200241f0006a41086a20024190016a41086a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41186a20024190016a41186a2d00003a00002002200229039001370370200241b0016a41116a290000211320022900b901211420022800b501211120022f00b301211220022d00b201211820022f01b00121194100211a0c1d0b200241003a00002001280200200141046a28020020024101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d0a20022d00002203450d0820034101470d0a200241186a22054200370300200241106a4200370300200241086a420037030020024200370300200141086a220341002001280200200141046a220a280200200241202004100422042004417f461b2204412020044120491b20032802006a22063602002004411f4d0d0a2005290300210f20022903102110200228020c210b20022f010a210c20022d0009210d20022f0007210e2002280003210720022f0001210820022d00002109200a2802002104200241003602002003410020012802002004200241042006100422042004417f461b22044104200441044922041b20032802006a220536020020040d0a2002280200210a200141046a2206280200210420024100360200200141086a2203410020012802002004200241042005100422042004417f461b2204410420044104491b20032802006a2205360200200441034d0d0a2002280200210420062802002106200241003602002003410020012802002006200241042005100422012001417f461b2201410420014104491b20032802006a360200200141034d0d0a20022802002101200241e1016a200f370000200241f0006a41186a200241d0016a41186a2d00003a0000200220103700d901200241f0006a41106a200241d0016a41106a2903003703002002200b3600d501200241f0006a41086a200241d0016a41086a2903003703002002200c3b00d3012002200d3a00d2012002200e3b01d001200220022903d001370370410121030c090b200241003a00002001280200200141046a28020020024101200410042103200141086a22042004280200200341016a220341014b6a36020020034102490d3620022d0000450d040c360b200241003a00002001280200200141046a28020020024101200410042103200141086a22042004280200200341016a220341014b6a220436020020034102490d0b20022d00002203450d0920034101470d0b200241186a220a4200370300200241106a4200370300200241086a2206420037030020024200370300200141086a220541002001280200200141046a2207280200200241202004100422032003417f461b2203412020034120491b20052802006a22043602002003411f4d0d0b200a290300210f20022903102110200228020c210820022f010a210920022d0009210b20022f0007210c2002280003210d20022f0001210e20022d00002111200a42003703002006420037030020024200370310200242003703002005410020012802002007280200200241202004100422012001417f461b2201412020014120491b20052802006a3602002001411f4d0d0b200241186a290300211320022903102114200228020c210120022f010a210620022d0009210720022f000721122002280003210320022f0001210420022d000021054101210a0c0a0b2000410c3a0000200241f0016a24000f0b2000410c3a0000200241f0016a24000f0b2000410c3a0000200241f0016a24000f0b20022001103c20022802002201450d312002290204210f200041083a0000200041086a200f370000200041046a2001360000200020022f00d0013b0001200041036a200241d2016a2d00003a0000200041106a200241e00010f8021a200241f0016a24000f0b0b200020053a00012000410b3a00002000411a6a200f370000200041126a20103700002000410e6a20013600002000410c6a20033b00002000410b6a20043a0000200041096a200a3b0000200041056a2006360000200041036a20073b0000200041026a20083a0000200041226a200241ce0010f8021a200241f0016a24000f0b200241186a220a4200370300200241106a4200370300200241086a420037030020024200370300200141086a220541002001280200200141046a2206280200200241202004100422032003417f461b2203412020034120491b20052802006a22043602002003411f4d0d012002280003210720022f0001210820022d0000210920022f0007210320022d0009210b20022f010a210c200228020c210d2002290310210f200241c1016a200a2903003700002002200f3700b9012002200d3600b5012002200c3b00b3012002200b3a00b201200220033b01b00120062802002103200241003602002005410020012802002003200241042004100422032003417f461b22034104200341044922031b20052802006a220436020020030d012002280200210a200141046a2206280200210320024100360200200141086a2205410020012802002003200241042004100422032003417f461b2203410420034104491b20052802006a220b360200200341034d0d01200228020021042006280200210320024100360200200541002001280200200320024104200b100422012001417f461b2201410420014104491b20052802006a360200200141034d0d012002280200210120024190016a41186a2203200241b0016a41186a2d00003a000020024190016a41106a2205200241b0016a41106a29030037030020024190016a41086a2206200241b0016a41086a290300370300200220022903b00137039001200241f0006a41186a20032d00003a0000200241f0006a41106a2005290300370300200241f0006a41086a20062903003703002002200229039001370370410021030b200241186a2205200241f0006a41186a2d000022063a0000200241106a220b200241f0006a41106a290300220f370300200241086a220c200241f0006a41086a2903002210370300200241d0016a41086a220d2010370300200241d0016a41106a220e200f370300200241d0016a41186a221120063a000020022002290370220f3703d0012002200f370300200041063a0000200041086a2007360000200041066a20083b0000200041056a20093a0000200041046a20033a0000200041306a20013600002000412c6a2004360000200041286a200a360000200020022f00b0013b0001200041036a200241b2016a2d00003a00002000410c6a20022903d001370000200041146a200d2903003700002000411c6a200e290300370000200041246a20112d00003a0000200041ec006a200241386a280200360200200041e4006a200241306a290200370200200041dc006a200241286a290200370200200041d4006a200241206a290200370200200041cc006a2005290200370200200041c4006a200b2902003702002000413c6a200c290200370200200041346a2002290200370200200241f0016a24000f0b200241186a200241f0006a41186a2d00003a0000200241106a200241f0006a41106a290300370300200241086a200241f0006a41086a290300370300200220022903703703002000410c3a0000200241f0016a24000f0b200241186a220a4200370300200241106a4200370300200241086a2206420037030020024200370300200141086a220541002001280200200141046a2207280200200241202004100422032003417f461b2203412020034120491b20052802006a22043602002003411f4d0d01200a290300210f20022903102110200228020c210820022f010a210920022d0009210b20022f0007210c2002280003210d20022f0001210e20022d00002111200a42003703002006420037030020024200370310200242003703002005410020012802002007280200200241202004100422032003417f461b2203412020034120491b20052802006a22063602002003411f4d0d012002280003210320022f0001210420022d0000210520022f0007210a20022d0009210720022f010a2112200228020c211820022903102113200241a1016a2219200241186a29030037000020022013370099012002201836009501200220123b009301200220073a0092012002200a3b01900120024200370308200242003703004100210a200141086a220741002001280200200141046a280200200241102006100422012001417f461b22014110200141104922011b20072802006a36020020010d01200241086a290300211c200229030021172019290000211320024199016a2900002114200228009501210120022f009301210620022d009201210720022f01900121120b200020022800d0013600012000410a3a0000200041d8006a201c370000200041d0006a2017370000200041c1006a2013370000200041396a2014370000200041216a200f370000200041196a2010370000200041356a2001360000200041336a20063b0000200041326a20073a0000200041306a20123b00002000412c6a20033600002000412a6a20043b0000200041296a20053a0000200041156a2008360000200041136a20093b0000200041126a200b3a0000200041106a200c3b00002000410c6a200d3600002000410a6a200e3b0000200041096a20113a0000200041086a200a3a0000200041056a200241d4016a2f00003b0000200041076a200241d6016a2d00003a0000200041e8006a200241086a290300370300200041e0006a2002290300370300200241f0016a24000f0b2000410c3a0000200241f0016a24000f0b200241186a220a4200370300200241106a4200370300200241086a420037030020024200370300200141086a220541002001280200200141046a220b280200200241202004100422032003417f461b2203412020034120491b20052802006a220c3602002003411f4d0d02200a290300210f20022903102110200228020c210620022f010a210720022d0009210820022f000721092002280003210320022f0001210420022d0000210a200b280200210b20024100360200200541002001280200200b20024104200c1004220b200b417f461b220b4104200b410449220b1b20052802006a220c360200200b0d0220022802002105200241003a00002001280200200141046a28020020024101200c1004210b200141086a22012001280200200b41016a220141014b6a36020020014102490d0220022d0000220b41034f0d02200241f0006a41186a200241186a2d00003a0000200241f0006a41106a200241106a290300370300200241f0006a41086a200241086a29030037030020022002290300370370410021120c010b200241186a22054200370300200241106a220b4200370300200241086a220c420037030020024200370300200141086a220341002001280200200141046a280200200241202004100422012001417f461b2201412020014120491b20032802006a3602002001411f4d0d012005290300210f20022903102110200228020c210620022f010a210720022d0009210820022f000721092002280003210320022f0001210420022d0000210a200241f0006a41186a20052d00003a0000200241f0006a41106a200b290000370300200241f0006a41086a200c29000037030020022002290000370370410121120b200241186a200241f0006a41186a2d000022013a0000200241106a200241f0006a41106a2903002217370300200241086a200241f0006a41086a290300221c370300200241d0016a41086a220d201c370300200241d0016a41106a220e2017370300200241d0016a41186a221120013a00002002200229037022173703d00120022017370300200041216a200f370000200041196a2010370000200041013a00002000412c6a20053600002000412a6a200c3b0000200041296a200b3a0000200041156a2006360000200041136a20073b0000200041126a20083a0000200041106a20093b00002000410c6a20033600002000410a6a20043b0000200041096a200a3a0000200041086a20123a000020002002280000360001200041056a200241046a2f00003b0000200041076a200241066a2d00003a0000200041e8006a2015370000200041e0006a2016370000200041d8006a2013370000200041d0006a2014370000200041c8006a20112d00003a0000200041c0006a200e290300370000200041386a200d290300370000200041306a20022903d001370000200241f0016a24000f0b200241186a200241f0006a41186a2d00003a0000200241106a200241f0006a41106a290300370300200241086a200241f0006a41086a290300370300200220022903703703002000410c3a0000200241f0016a24000f0b200242003703082002420037030041002105200141086a220341002001280200200141046a280200200241102004100422012001417f461b2201411020014110491b20032802006a3602002001410f4d0d03200241086a2903002113200229030021140b0c010b200241186a22064200370300200241106a4200370300200241086a420037030020024200370300200141086a220541002001280200200141046a2207280200200241202004100422032003417f461b2203412020034120491b20052802006a22083602002003411f4d0d012002280003210320022f0001210420022d0000210a20022f0007210920022d0009210b20022f010a210c200228020c210d2002290310210f200241c1016a20062903003700002002200f3700b9012002200d3600b5012002200c3b00b3012002200b3a00b201200220093b01b00120072802002106200241003602002005410020012802002006200241042008100422012001417f461b22014104200141044922011b20052802006a36020020010d012002280200210920024190016a41186a200241b0016a41186a2d00003a000020024190016a41106a2201200241b0016a41106a29030037030020024190016a41086a2205200241b0016a41086a290300370300200220022903b001370390012005290300211320012d00002101200229039001211420022f00a701210620022800a301210720022f00a1012108410121050b200020022800d001360001200041033a0000200041386a200f370000200041306a2010370000200041186a2013370000200041106a20143700002000412c6a2009360000200041276a20063b0000200041236a2007360000200041216a20083b0000200041206a20013a00002000410c6a20033600002000410a6a20043b0000200041096a200a3a0000200041086a20053a0000200041056a200241d4016a2f00003b0000200041076a200241d6016a2d00003a0000200041e8006a200241286a290300370300200041e0006a200241206a290300370300200041d8006a200241186a290300370300200041d0006a200241106a290300370300200041c8006a200241086a290300370300200041c0006a2002290300370300200241f0016a24000f0b2000410c3a0000200241f0016a24000f0b200241186a220a4200370300200241106a22064200370300200241086a2207420037030020024200370300200141086a220341002001280200200141046a280200200241202004100422012001417f461b2201412020014120491b20032802006a3602002001411f4d0d1e200a290300211320022903102114200228020c211120022f010a211220022d0009211820022f000721192002280003210320022f0001210420022d00002105200241f0006a41186a200a2d00003a0000200241f0006a41106a2006290000370300200241f0006a41086a2007290000370300200220022900003703704101211a0c030b200141046a280200210320024100360200200141086a2205410020012802002003200241042004100422012001417f461b2201410420014104491b20052802006a360200200141034d0d1d20022802002103200241f0006a41186a200241186a2d00003a0000200241f0006a41106a200241106a290200370300200241f0006a41086a200241086a290200370300200220022902003703704102211a0c010b20022001103620022802002203450d1c2002290204210f20022001103620022802002201450d1b200220022902043702d401200220013602d001200241f0006a41086a200241086a290200370300200241f0006a41106a200241106a290200370300200241f0006a41186a200241186a2d00003a0000200220022902003703702001411874200f422888a7722111200241d9016a330000200241db016a310000421086842113200f42ffffffffff1f832210421888a721122010421088a7211820022900d1012114200fa721194103211a0b0b0b200241186a2201200241f0006a41186a2d0000220a3a0000200241106a2206200241f0006a41106a290300220f370300200241086a2207200241f0006a41086a2903002210370300200241d0016a41086a22082010370300200241d0016a41106a2209200f370300200241d0016a41186a220b200a3a000020022002290370220f3703d0012002200f3703002000411d6a2013370000200041156a2014370000200041053a0000200041286a200c360000200041266a200e3b0000200041256a200d3a0000200041116a20113600002000410f6a20123b00002000410e6a20183a00002000410c6a20193b0000200041086a2003360000200041066a20043b0000200041056a20053a0000200041046a201a3a0000200020022f00b0013b0001200041036a200241b2016a2d00003a00002000412c6a20022903d001370000200041346a20082903003700002000413c6a2009290300370000200041c4006a200b2d00003a0000200041e8006a200241206a290300370300200041e0006a2001290300370300200041d8006a2006290300370300200041d0006a2007290300370300200041c8006a2002290300370300200241f0016a24000f0b200241186a220b4200370300200241106a4200370300200241086a220c420037030020024200370300200141086a220941002001280200200141046a220d280200200241202004100422032003417f461b2203412020034120491b20092802006a220e3602002003411f4d0d06200b290300210f20022903102110200228020c210320022f010a210420022d0009210520022f0007210a2002280003210620022f0001210720022d00002108200b4200370300200c42003703002002420037031020024200370300200941002001280200200d28020020024120200e1004220b200b417f461b220b4120200b4120491b20092802006a2218360200200b411f4d0d06200241186a290300211320022903102114200228020c210920022f010a210b20022d0009210c20022f0007210d2002280003210e20022f0001211120022d00002112200241003a00002001280200200141046a221a28020020024101201810042119200141086a22182018280200201941016a221941014b6a221b36020020194102490d0620022d00002119201a280200211a20024100360200201841002001280200201a20024104201b1004221a201a417f461b221a4104201a4104491b20182802006a221b360200201a41034d0d0620022802002118200141046a280200211a20024100360200200141086a221d41002001280200201a20024104201b100422012001417f461b2201410420014104491b201d2802006a360200200141034d0d06200228020021014101211a0c050b200241186a22054200370300200241106a4200370300200241086a420037030020024200370300200141086a220341002001280200200141046a280200200241202004100422012001417f461b2201412020014120491b20032802006a3602002001411f4d0d052005290300210f20022903102110200228020c210320022f010a210420022d0009210520022f0007210a2002280003210620022f0001210720022d000021084102211a0c010b200241186a22054200370300200241106a4200370300200241086a420037030020024200370300200141086a220341002001280200200141046a280200200241202004100422012001417f461b2201412020014120491b20032802006a3602002001411f4d0d042005290300210f20022903102110200228020c210320022f010a210420022d0009210520022f0007210a2002280003210620022f0001210720022d000021084103211a0b0c020b200241186a22054200370300200241106a4200370300200241086a420037030020024200370300200141086a220941002001280200200141046a220b280200200241202004100422032003417f461b2203412020034120491b20092802006a220c3602002003411f4d0d022005290300210f20022903102110200228020c210320022f010a210420022d0009210520022f0007210a2002280003210620022f0001210720022d00002108200241003a00002001280200200b28020020024101200c1004210120092009280200200141016a220141014b6a36020020014102490d0220022d000021124104211a0b0b200020022f00d0013b0001200041073a00002000413d6a2013370000200041356a20143700002000411d6a200f370000200041156a2010370000200041cc006a2001360000200041c8006a2018360000200041c5006a20193a0000200041316a20093600002000412f6a200b3b00002000412e6a200c3a00002000412c6a200d3b0000200041286a200e360000200041266a20113b0000200041256a20123a0000200041116a20033600002000410f6a20043b00002000410e6a20053a00002000410c6a200a3b0000200041086a2006360000200041066a20073b0000200041056a20083a0000200041046a201a3a0000200041036a200241d2016a2d00003a0000200041e8006a200241186a290300370300200041e0006a200241106a290300370300200041d8006a200241086a290300370300200041d0006a2002290300370300200241f0016a24000f0b2000410c3a0000200241f0016a24000f0b2002420037030820024200370300200141086a220341002001280200200141046a280200200241102004100422012001417f461b2201411020014110491b20032802006a3602002001410f4d0d06200241086a290300211420022903002113200241a1016a2900002110200229009901210f200228009501210420022f009301210620022d009201210820022f0190012107410121030c020b200141046a220a280200210520024100360200200141086a2203410020012802002005200241042004100422042004417f461b2204410420044104491b20032802006a2205360200200441034d0d05200228020021042002420037030820024200370300200341002001280200200a280200200241102005100422052005417f461b2205411020054110491b20032802006a220a3602002005410f4d0d05200241086a220329030021102002290300210f200241186a22054200370300200241106a42003703002003420037030020024200370300200141086a220341002001280200200141046a28020020024120200a100422012001417f461b2201412020014120491b20032802006a3602002001411f4d0d052002280003210120022f0001210a20022d0000210c20022f0007210320022d0009210620022f010a2107200228020c210820022903102113200241c1016a20052903002217370000200220133700b901200220083600b501200220073b00b301200220063a00b201200220033b01b0012013423888201742088684a7210b2017423088a721072017421088a72109200241b0016a41086a290300211420022903b00121132017a72105410221030c040b2002420037030820024200370300200141086a220341002001280200200141046a280200200241102004100422012001417f461b2201411020014110491b20032802006a3602002001410f4d0d04200241086a290300211420022903002113200241e1016a290000211020022900d901210f20022800d501210420022f00d301210620022d00d201210820022f01d0012107410321030b0c010b200242003703082002420037030041042103200141086a220541002001280200200141046a280200200241102004100422012001417f461b2201411020014110491b20052802006a3602002001410f4d0d02200241086a2903002114200229030021130b0b200020022800d001360001200041093a0000200041386a2010370000200041306a200f370000200041186a2014370000200041106a20133700002000412c6a20043600002000412a6a20063b0000200041296a20083a0000200041276a20073b0000200041236a2009360000200041216a20053b0000200041206a200b3a00002000410c6a20013600002000410a6a200a3b0000200041096a200c3a0000200041086a20033a0000200041056a200241d4016a2f00003b0000200041076a200241d6016a2d00003a0000200041e8006a200241286a290300370300200041e0006a200241206a290300370300200041d8006a200241186a290300370300200041d0006a200241106a290300370300200041c8006a200241086a290300370300200041c0006a2002290300370300200241f0016a24000f0b2000410c3a0000200241f0016a24000f0b200141046a220a280200210320024100360200200141086a2205410020012802002003200241042004100422032003417f461b2203410420034104491b20052802006a2206360200200341034d0d0620022802002104200241003a00002001280200200a2802002002410120061004210120052005280200200141016a220141014b6a36020020014102490d0620022d0000220a41034f0d06200241c1016a290000210f20022900b901211020022800b501210c20022f00b301210720022d00b201210820022f01b001210941012105410021034100210b0c050b200141046a28020021054100210320024100360200200141086a220a410020012802002005200241042004100422012001417f461b2201410420014104491b200a2802006a360200200141034d0d0520022802002104200241e1016a290000210f20022900d901211020022800d501210c20022f00d301210720022d00d201210820022f01d0012109410221054100210b0c040b200141046a28020021054100210320024100360200200141086a220a410020012802002005200241042004100422012001417f461b2201410420014104491b200a2802006a36020041032105200141034b0d010c040b41042105200141046a280200210a4100210320024100360200200141086a220641002001280200200a200241042004100422012001417f461b2201410420014104491b20062802006a360200200141034d0d030b200228020021044100210b0c010b200141046a220a2802002103200241003602d001200141086a2205410020012802002003200241d0016a41042004100422032003417f461b2203410420034104491b20052802006a2206360200200341034d0d0120022802d0012104200241003a00d0012001280200200a280200200241d0016a410120061004210120052005280200200141016a41014b22016a3602002001450d0120022d00d001210a20022800032203410876210b200241186a290300210f20022903102110200228020c210c20022f010a210720022d0009210820022f0007210920022f0001210620022d00002101410521050b200020022800d001360001200041043a0000200041286a200f370000200041206a20103700002000411c6a200c3600002000411a6a20073b0000200041196a20083a0000200041176a20093b0000200041116a20063b0000200041106a20013a00002000410c6a2004360000200041096a200a3a0000200041086a20053a0000200041056a200241d0016a41046a2f00003b0000200041076a200241d6016a2d00003a0000200041136a200b410874200341ff017172360000200041e8006a200241386a290300370300200041e0006a200241306a290300370300200041d8006a200241286a290300370300200041d0006a200241206a290300370300200041c8006a200241186a290300370300200041c0006a200241106a290300370300200041386a200241086a290300370300200041306a2002290300370300200241f0016a24000f0b2000410c3a0000200241f0016a24000f0b200fa7450d00200310010b200241186a200241f0006a41186a2d00003a0000200241106a200241f0006a41106a290300370300200241086a200241f0006a41086a290300370300200220022903703703002000410c3a0000200241f0016a24000f0b2000410c3a0000200241f0016a24000bcef10209057f017e027f017e067f057e077f047e017f230041e0076b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280200417f6a2204410b4b0d0002400240024020040e0c0008050602090a070c040b01000b200341f0066a41086a200141106a2903003703002003200141086a2903003703f006200341f0046a41206a200241206a280200360200200341f0046a41186a200241186a290200370300200341f0046a41106a200241106a290200370300200341f0046a41086a200241086a290200370300200320022902003703f004200341086a200341f0066a200341f0046a10cd02200328020c21042003280208210541012106410021070cfa010b200341d8026a41026a200141076a2d00003a0000200341b8036a41086a2001411c6a290200370300200341b8036a41106a200141246a280200360200200320012f00053b01d8022003200141146a2902003703b8032002411d6a350000200241216a310000422086842108200241026a2f0100200241046a2d0000411074722104200241196a2800002109200241156a280000210a2002410d6a290000210b200241096a280000210c200241056a280000210d200141106a28020021052001410c6a2802002107200141086a280200210620022d0001210e20022d0000210220012d0004220f4102460d0b200f4103470daa01200341f8056a41026a200341d8026a41026a220f2d00003a00002003418f066a200341b8036a41086a221029030037000020034197066a200341b8036a41106a22112d00003a00002003200536008306200320073600ff05200320063600fb05200320032f01d8023b01f805200320032903b80337008706200341f8026a41026a200f2d00003a000020034198036a41086a201029030037030020034198036a41106a20112d00003a0000200320032f01d8023b01f802200320032903b80337039803200241ff01710d11200e41ff01714101470d11200341b8026a411f6a200842208822123c0000200320083e00d302200320043b01b802200320093600cf022003200a3600cb022003200b3700c3022003200c3600bf022003200d3600bb022003200441107622023a00ba02200341d8036a411f6a20123c0000200320083e00f303200320023a00da03200320043b01d803200320093600ef032003200a3600eb032003200b3700e3032003200c3600df032003200d3600db03200341c8016a41086a22024200370300200342003703c80141f8f0c000410e200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d3720034190026a4200370300200341f8016a41106a4200370300200341f8016a41086a4200370300200342003703f801200341b8016a4110200341f8016a4120410010042202417f460dba012002411f4d0dba01200341b8026a41186a2202200341f8016a41186a290300370300200341b8026a41106a2204200341f8016a41106a290300370300200341b8026a41086a2209200341f8016a41086a290300370300200320032903f8013703b802200341f0046a41186a220a2002290300370300200341f0046a41106a22022004290300370300200341f0046a41086a22042009290300370300200320032903b8023703f004200341d0046a41186a200a2903002208370300200341d0046a41106a2002290300220b370300200341d0046a41086a20042903002212370300200341f0066a41086a2012370300200341f0066a41106a200b370300200341f0066a41186a2008370300200320032903f00422083703d004200320083703f0060c380b200141086a2d0000220f417e6a220441054b0daa012002411d6a350000200241216a310000422086842108200241026a2f0100200241046a2d0000411074722107200141106a2903002112200241196a2800002106200241156a280000210a2002410d6a290000210b200241096a280000210c200241056a280000210d2001410c6a280200210920022d0001210520022d0000210220012d0009210e024020040e0600201e1f1d22000b200241ff01710d3d200541ff01714101470d3d200141186a290300211320034198026a411f6a200842208822143c0000200320083e00b302200320073b019802200320063600af022003200a3600ab022003200b3700a3022003200c36009f022003200d36009b022003200741107622023a009a02200341f0066a411f6a20143c0000200320083e008b07200320023a00f206200320073b01f00620032006360087072003200a360083072003200b3700fb062003200c3600f7062003200d3600f306200341b8016a41086a22024200370300200342003703b80141a599c1004118200341b8016a1002200341d8036a41086a2002290300370300200320032903b8013703d803200341d8036a41104188f0c100410041001004417f460d42200342003703f804200342003703f004200341d8036a4110200341f0046a4110410010042202417f460dc2012002410f4d0dc201201220032903f004542013200341f8046a29030022085420132008511b450d4241bd99c1002105410d21040c430b200141086a2903004202520daa01412d21044101210741c1efc100410041c1efc100410320022d000120022d00001b41ff017122024102461b20024103461b22050df301200141106a2903002108200341c8016a41086a22024200370300200342003703c80141f2a1c1004113200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a4110100e0db501200310f00120032802004101470db40120032802040db401200341c8016a41086a22024200370300200342003703c80141a0a5c100410d200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460db002200342003703f004200341b8016a4110200341f0046a41084100100441016a41084d0da70120032903f004500db002200341c8016a41086a22024200370300200342003703c80141a0a5c100410d200341c8016a1002200341b8016a41086a22052002290300370300200320032903c8013703b8014200210b0240200341b8016a41104188f0c100410041001004417f460d00200342003703f004200341b8016a4110200341f0046a41084100100441016a41084d0db30120032903f004210b0b20024200370300200342003703c80141daa3c1004115200341c8016a100220052002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d43200342003703f004200341b8016a4110200341f0046a41084100100441016a41084d0db301200820032903f004200b7c540d440cb0020b200341a0016a41086a200141186a290300370300200341a0016a41106a200141206a2903003703002003200141106a2903003703a001200141086a280200417e6a220441044b0daa01200241026a2f0100200241046a2d0000411074722107200241056a2800002106200141286a29030021082001410c6a280200210a20022d0001210920022d00002105024020040e050019161715000b200541ff01710d2a200941ff01714101470d2a200141386a2903002114200141306a2903002115200241196a2800002109200241156a280000210c2002410d6a290000210b200241096a280000210d20032802b401210e20032802b001210f20032903a801211620032802a401210420032802a0012105200341d0046a411f6a2002411d6a350000200241216a31000042208684221242208822133c0000200320123e00eb04200320073b01d004200320093600e7042003200c3600e3042003200b3700db042003200d3600d704200320063600d3042003200741107622023a00d204200341c8066a41026a200341f0046a41026a2d00003a0000200320032f00f0043b01c806200341f0066a411f6a20133c0000200320123e008b07200320023a00f206200320073b01f00620032009360087072003200c360083072003200b3700fb062003200d3600f706200320063600f306200a41ff01714101470d49200341f0046a200541067610ce0220032802f8042005413f7122024d0d5f200341b0046a41086a220420032802f004220620024105746a220241086a290000370300200341b0046a41106a2205200241106a290000370300200341b0046a41186a2207200241186a290000370300200320022900003703b004024020032802f404450d00200610010b200341d0046a41186a2007290300370300200341d0046a41106a2005290300370300200341d0046a41086a2004290300370300200320032903b0043703d00420032800b704210420032800b304210541000d980220033500cb04200341cf046a31000042208684210820032f01b00420032d00b20441107472210620032800c704210e20032800c304210f20032900bb0421160c93020b200341d0046a41046a22052001410e6a2f01003b0100200341d8036a41086a220a200141206a290300370300200341d8036a41106a220c200141286a2903003703002003200128010a3602d0042003200141186a2903003703d803200141106a290300210820022d0001210620022d0000210720012d00092109200141086a2d000022044102460d0c20044103460d0b20044104470daa0141efeec10041efeec100410041032006200741ff01711b41ff017122021b20024103461b22050d32200320093a00f004200341c8016a41086a22024200370300200342003703c80141eef1c0004119200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b80141012107200341b8016a4110200341f0046a410110030c520b200141086a2d0000417e6a220441094b0daa012002411d6a350000200241216a310000422086842108200241026a2f0100200241046a2d0000411074722107200141186a2903002113200141106a2903002112200241196a2800002109200241156a280000210a2002410d6a290000210b200241096a280000210c200241056a280000210d200141206a280200210f2001410c6a280200210e20022d0001210620022d00002102024020040e0a002d282b262e2f2c3127000b200241ff01710d44200641ff01714101470d44200341d8016a411f6a200842208822123c0000200320083e00f301200320073b01d801200320093600ef012003200a3600eb012003200b3700e3012003200c3600df012003200d3600db012003200741107622023a00da01200341d0046a41026a200341f0046a41026a2d00003a0000200320032f00f0043b01d004200341f0066a411f6a20123c0000200320083e008b07200320023a00f206200320073b01f00620032009360087072003200a360083072003200b3700fb062003200c3600f7062003200d3600f306200341f0046a200341f0066a10c80120032d00f0044101470d5f419aeec0002105412321040c96020b20034198036a41026a200141076a2d00003a0000200341d0046a41086a200141186a290200370300200341d0046a410d6a2001411d6a290000370000200320012f00053b0198032003200141106a2902003703d0042002411d6a350000200241216a310000422086842108200241026a2f0100200241046a2d0000411074722104200241196a2800002105200241156a28000021062002410d6a290000210b200241096a2800002109200241056a280000210a2001410c6a2802002107200141086a280200210e20022d0001210c20022d0000210220012d0004220d4102460d06200d4103470daa01200141286a280200210f20012d00252110200341db066a200341d8046a290300370000200341e0066a200341dd046a290000370000200320073600cf062003200e3600cb06200320032f0198033b01c806200320032903d0043700d30620032003419a036a2d00003a00ca06200241ff01710d0d200c41ff01714101470d0d20034198026a411f6a200842208822123c0000200320083e00b302200320043b019802200320053600af02200320063600ab022003200b3700a3022003200936009f022003200a36009b022003200441107622023a009a02200341f8056a411f6a20123c0000200320083e009306200320023a00fa05200320043b01f8052003200536008f062003200636008b062003200b37008306200320093600ff052003200a3600fb05200341f8056a10cf02450d1f411510002202450dba01200342153702f404200320023602f004200341f0046a41c3c0c00041151025200341f0066a41086a220220032802f804360200200320032903f0043703f006200341c8066a200341f0066a101e2002280200210420032802f406210520032802f0062102200341c8016a41086a22064200370300200342003703c80120022004200341c8016a1002200341b8016a41086a2006290300370300200320032903c8013703b80141002106200341b8016a41104188f0c100410041001004417f460d4a2003200341b8016a3602d803200341103602dc03200341003602f00420034100200341b8016a4110200341f0046a41044100100422042004417f461b2204410420044104491b22063602e003200441034d0dbf0120032802f0042117200341003602f004200341e0036a4100200341b8016a4110200341f0046a41042006100422042004417f461b2204410420044104491b20066a360200200441034d0dbf0120032802f0042118200341f0066a200341d8036a103620032802f0062206450dbf01200341f0066a41086a280200210a20032802f4062119200341f0046a200341d8036a103620032802f004220c450dbe01200341f0046a41086a280200211120032802f404211a2005450da0020c9f020b200341b0046a41026a220e2001412f6a2d00003a0000200320012f002d3b01b004200141286a3502002001412c6a31000042208684210820012f000d2001410f6a2d0000411074722107200141386a2903002112200141306a2903002113200141246a2802002109200141206a280200210a200141186a290200210b200141146a280200210c200141106a28020021062001410c6a2d0000210d20022d0001210420022d00002105200141086a280200220f4102460d06200f4103470daa01200141c8006a2903002114200141c0006a290300211520034190056a20084220883c00002003418c056a20083e020020034188056a200936020020034184056a200a360200200341fc046a200b370200200341f8046a200c36020020034191056a20032f01b0043b000020034193056a200341b2046a2d00003a0000200320063602f4042003200d3a00f004200320073b00f104200320074110763a00f30441efeec10041efeec100410041032004200541ff01711b41ff017122021b20024103461b22050d2f200d41ff01714101470d36200341d8036a200641067610ce0220032802e0032006413f7122024d0d46200341f8016a41086a220420032802d803220620024105746a220241086a290000370300200341f8016a41106a2205200241106a290000370300200341f8016a41186a2207200241186a290000370300200320022900003703f801024020032802dc03450d00200610010b20034198026a41186a200729030037030020034198026a41106a200529030037030020034198026a41086a2004290300370300200320032903f8013703980220033500930220034197026a31000042208684210820032f01f80120032d00fa01411074722107200328008f022109200328008b02210a200329008302210b20032800ff01210420032800fb0121054100450d470c94020b200341f0046a41386a200141c0006a290300370300200341f0046a41306a200141386a290300370300200341f0046a41286a200141306a290300370300200341f0046a41206a200141286a290300370300200341f0046a41186a200141206a290300370300200341f0046a41106a200141186a290300370300200341f0046a41086a200141106a2903003703002003200141086a2903003703f004200341f0066a41206a200241206a280200360200200341f0066a41186a200241186a290200370300200341f0066a41106a200241106a290200370300200341f0066a41086a200241086a290200370300200320022902003703f006200341386a200341f0046a200341f0066a10d002200328023c2104200328023821054100210941012107410121060cf3010b200341f0046a41206a200141286a290300370300200341f0046a41186a200141206a290300370300200341f0046a41106a200141186a290300370300200341f0046a41086a200141106a2903003703002003200141086a2903003703f004200341f0066a41206a200241206a280200360200200341f0066a41186a200241186a290200370300200341f0066a41106a200241106a290200370300200341f0066a41086a200241086a290200370300200320022902003703f006200341c0006a200341f0046a200341f0066a10d10220032802442104200328024021054100210a4101210741012106410121090cf3010b200341f8026a41026a22052001410b6a2d00003a0000200320012f00093b01f8022002411d6a350000200241216a310000422086842108200241026a2f0100200241046a2d0000411074722104200141386a2903002113200241196a2800002110200241156a28000021112002410d6a2900002112200241096a280000211a200241056a2800002119200141346a2802002118200141306a280200210d2001412c6a280200210e200141286a280200210f200141206a290300210b2001411c6a2802002107200141186a280200210a200141146a2802002109200141106a28020021062001410c6a280200210c20022d0001211b20022d00002117200141086a2d000022024102460d0420024103470da801200320093602a0032003200636029c032003200c360298032003200ba7221c3602c003200320073602bc032003200a3602b803201741ff01710d0b201b41ff01714101470d0b20034198026a411f6a2008422088220b3c0000200320083e00b302200320043b019802200320103600af02200320113600ab02200320123700a3022003201a36009f022003201936009b022003200441107622053a009a02200341b0046a411f6a200b3c0000200320083e00cb04200320053a00b204200320043b01b004200320103600c704200320113600c304200320123700bb042003201a3600b704200320193600b304200341f0046a200341b0046a201310ab01200341f0046a41086a280200210420032802f0044101470d1d20032802f404210520070d96020c97020b2001410c6a2802002107200141086a280200210a20012802042104200341d0046a41026a2205200241046a2d00003a0000200341d8036a41086a2206200241156a290000370300200341d8036a410d6a22092002411a6a2900003700002003200241026a2f01003b01d00420032002410d6a2900003703d80320044102470da801200241096a2800002104200241056a280000210d20022d0001210c20022d00002102200341f8056a41026a20052d00003a0000200341f0046a41086a2006290300370300200341f0046a410d6a2009290000370000200320032f01d0043b01f805200320032903d8033703f004024002400240200241ff01710d00200341c8066a41026a2202200341f8056a41026a2d00003a0000200341f0066a41086a2205200341f0046a41086a290300370300200341f0066a410d6a2206200341f0046a410d6a290000370000200320032f01f8053b01c806200320032903f0043703f006200c41ff01714101470d00200341ab026a2005290300370000200341b0026a20062900003700002003200436009f022003200d36009b02200320032f01c8063b019802200320032903f0063700a302200320022d00003a009a024100210520070d010c020b412a21044197efc10021052007450d010b200a10010b4100210c4101210741012106410121094101210a4101210d0cf2010b2003200536028006200320073602fc05200320063602f805200241ff01710d06200e41ff01714101470d06200341b8026a411f6a200842208822123c0000200320083e00d302200320043b01b802200320093600cf022003200a3600cb022003200b3700c3022003200c3600bf022003200d3600bb022003200441107622023a00ba02200341d8036a411f6a20123c0000200320083e00f303200320023a00da03200320043b01d803200320093600ef032003200a3600eb032003200b3700e3032003200c3600df032003200d3600db03200341c8016a41086a22024200370300200342003703c80141f8f0c000410e200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d2d200341f0016a4200370300200341d8016a41106a4200370300200341d8016a41086a4200370300200342003703d801200341b8016a4110200341d8016a4120410010042202417f460daf012002411f4d0daf01200341b8026a41186a2202200341d8016a41186a290300370300200341b8026a41106a2204200341d8016a41106a290300370300200341b8026a41086a2209200341d8016a41086a290300370300200320032903d8013703b802200341f0046a41186a220a2002290300370300200341f0046a41106a22022004290300370300200341f0046a41086a22042009290300370300200320032903b8023703f004200341d0046a41186a200a2903002208370300200341d0046a41106a2002290300220b370300200341d0046a41086a20042903002212370300200341f0066a41086a2012370300200341f0066a41106a200b370300200341f0066a41186a2008370300200320032903f00422083703d004200320083703f0060c2e0b200241ff01710d07200c41ff01714101470d0720034198026a411f6a200842208822123c0000200320083e00b302200320043b019802200320053600af02200320063600ab022003200b3700a3022003200936009f022003200a36009b022003200441107622023a009a02200341f8056a411f6a20123c0000200320083e009306200320023a00fa05200320043b01f8052003200536008f062003200636008b062003200b37008306200320093600ff052003200a3600fb05200341f8056a10cf02450d19200341003602f804200342013703f0042007200341f0046a101c20032802f404210420032802f804210520032802f004210220034198026a41186a2206420037030020034198026a41106a2209420037030020034198026a41086a220a420037030020034200370398022002200520034198026a100d200341d8036a41186a22052006290300370300200341d8036a41106a2009290300370300200341d8036a41086a2206200a29030037030020032003290398023703d80302402004450d00200210010b200341f0046a41186a2005290300370300200341f0046a41106a200341d8036a41106a290300370300200341f0046a41086a2006290300370300200320032903d8033703f004411910002202450db401200342193702f406200320023602f006200341f0066a41dfbfc00041191025200341c8066a41086a220220032802f806360200200320032903f0063703c806200341f0046a200341c8066a101e2002280200210420032802cc06210520032802c8062102200341c8016a41086a22064200370300200342003703c80120022004200341c8016a1002200341b8016a41086a2006290300370300200320032903c8013703b801200341b8016a4110100e210402402005450d00200210010b2004450d4441a3b1c1002105411f21040ca3020b200241216a31000021142002411d6a3500002115200241046a2d00002111200241026a2f0100211a200241196a2800002119200241156a28000021172002410d6a2900002116200241056a280000210f200241096a2800002102200341f0066a41206a20084220883c00002003418c076a20083e0200200341f0066a41186a2009360200200341f0066a41146a200a360200200341f0066a410c6a200b370200200341f0066a41086a200c360200200341f0066a41216a20032f01b0043b000020034193076a200e2d00003a0000200320063602f4062003200d3a00f006200320073b00f106200320074110763a00f306200341d0046a41026a200341c8066a41026a2d00003a0000200320032f01c8063b01d0042002412a200541ff0171220e45200441ff017122104101467122051b2104200f4197efc10020051b2105200e0d8d0220104101470d8d022003201520144220868422143e009306200341f8056a411f6a20144220883c00002003201936008f062003201736008b062003201637008306200320043600ff05200320053600fb052003201a20114110747222023b01f805200320024110763a00fa05200d41ff01714101470d1a200341f0046a200641067610ce0220032802f8042006413f7122024d0d34200341f8016a41086a220420032802f004220620024105746a220241086a290000370300200341f8016a41106a2205200241106a290000370300200341f8016a41186a2207200241186a290000370300200320022900003703f801024020032802f404450d00200610010b20034198026a41186a200729030037030020034198026a41106a200529030037030020034198026a41086a2004290300370300200320032903f8013703980220032800ff01210c20032800fb0121064100450d5120062105200c21040c8d020b200141c0006a2903002115200141c8006a29030021142003200f3a00cf042003200b3700c704200320073600c3042003200a3600bf04200320093600bb04200320063600b7042003200c3600b304200320032f01f8023b01b004200320052d00003a00b204200320183602a0032003200d36029c032003200e360298032003200f3a00d7022003200b3700cf02200320073600cb022003200a3600c702200320093600c302200320063600bf022003200c3600bb02200320052d00003a00ba02200320032f01f8023b01b802201741ff01710d07201b41ff01714101470d0720034198026a411f6a2008422088220b3c0000200320083e00b302200320043b019802200320103600af02200320113600ab02200320123700a3022003201a36009f022003201936009b022003200441107622053a009a02200341d0046a411f6a200b3c0000200320083e00eb04200320053a00d204200320043b01d004200320103600e704200320113600e304200320123700db042003201a3600d704200320193600d304200341f0046a200341d0046a201410ab01200341f0046a41086a280200210420032802f0044101470d1a20032802f4042105200d0d8f020c90020b4100210541efeec10041efeec100410041032006200741ff01711b41ff017122021b20024103461b2202450d14412821044101210741012106410121094101210a4101210d4101210c4101210e4101210f2002210520012802002202410b4d0df0010cef010b200241216a31000021122002411d6a3500002113200241046a2d0000210f200241026a2f01002110200241196a280000210d200241156a280000210e2002410d6a290000210b200241096a2800002104200241056a2800002102200341d8016a41176a200a290300370000200341d8016a411f6a200c2d00003a0000200320093a00d801200320083700df01200320032802d0043600d901200320032903d8033700e701200320052f01003b00dd01200341f8016a41176a200a290300370000200341f8016a411f6a200c2d00003a0000200320093a00f801200320083700ff01200320032802d0043600f901200320052f01003b00fd01200320032903d80337008702200741ff01710d1d200641ff01714101470d1d20034198026a411f6a2013201242208684220842208822123c0000200320083e00b30220032010200f4110747222053b0198022003200d3600af022003200e3600ab022003200b3700a3022003200436009f022003200236009b022003200541107622073a009a02200341f0066a411f6a20123c0000200320083e008b07200320073a00f206200320053b01f0062003200d360087072003200e360083072003200b3700fb06200320043600f706200320023600f306200341f0046a41186a200341f8016a41186a290300370300200341f0046a41106a200341f8016a41106a290300370300200341f0046a41086a200341f8016a41086a290300370300200320032903f8013703f004411210002202450dac01200342123702fc05200320023602f805200341f8056a41daf2c00041121025200341c8066a41086a2202200328028006360200200320032903f8053703c806200341f0066a200341c8066a101e2002280200210720032802cc06210620032802c8062105412010002202450dad01200220032903f004370000200241186a200341f0046a41186a290300370000200241106a200341f0046a41106a290300370000200241086a200341f0046a41086a290300370000200341c8016a41086a22094200370300200342003703c80120052007200341c8016a1002200341b8016a41086a2009290300370300200320032903c8013703b801200341b8016a41102002412010032002100102402006450d00200510010b410021050c8a020b412a21044197efc10021050c480b412a21044197efc100210520070d280c470b412a21044197efc10021050c9d020b412a21044197efc10021050c9b020b4197efc1002105412a21042007450d8b020c8a020b4197efc1002105412a2104200d450d88020c87020b200320063600f304200320073b01f004200320074110763a00f204200541ff0171450d0220032801f2044104490d02411210002202450db201200342123702f404200320023602f004200341f0046a4197e5c0004112102520032802f004210620032802f404220520032802f80422026b41034b0d43200241046a22042002490d8f0220054101742207200420042007491b22074100480d8f022005450d61200710002204450dbd012004200620072005200520074b1b10f8021a200610010c620b41efeec10041efeec100410041032009200541ff01711b41ff017122021b20024103461b22050d1d200341a0016a41106a290300210b20032802a001210420032903a8012112419af0c0004115200a10a4022003200b3703f804200320123703f004200341b8016a41086a22024200370300200342003703b80141feefc000411c200341b8016a1002200341d8036a41086a22052002290300370300200320032903b8013703d803200341d8036a4110200341f0046a41101003200320083703f00420024200370300200342003703b80141b9c2c0004114200341b8016a100220052002290300370300200320032903b8013703d803200341d8036a4110200341f0046a4108100341ebc2c000410d200410a4020c030b200320063600f304200320073b01f004200320074110763a00f204200541ff0171450d0020032801f20441024f0d260b41c00021044181b0c00021050c80020b41efeec10041efeec100410041032009200541ff01711b41ff017122021b20024103461b22050d1a20032903a00121082003200341a0016a41086a2903003703f804200320083703f004200341b8016a41086a22024200370300200342003703b80141cdc2c000410c200341b8016a1002200341d8036a41086a2002290300370300200320032903b8013703d803200341d8036a4110200341f0046a411010030b410021050cfe010b41002106412821044101210741efeec10041efeec100410041032005200241ff01711b41ff017122021b20024103461b22050dd8012009109602410021060cf7010b200241ff01710d02200541ff01714101470d0220034198026a411f6a200842208822123c0000200320083e00b302200320073b019802200320063600af022003200a3600ab022003200b3700a3022003200c36009f022003200d36009b022003200741107622023a009a02200341f0066a411f6a20123c0000200320083e008b07200320023a00f206200320073b01f00620032006360087072003200a360083072003200b3700fb062003200c3600f7062003200d3600f306200341b8016a41086a22024200370300200342003703b80141bb9ac1004118200341b8016a1002200341d8036a41086a2002290300370300200320032903b8013703d803410021020240200341d8036a41104188f0c100410041001004417f460d00200341003a00f004200341d8036a4110200341f0046a41014100100441016a41014d0daf0120032d00f00421020b200e411874411875410776200e7341187441808080086a41187520024118744118754c0d3341d39ac1002105411d21040cf8010b4100210641efeec10041efeec100410041032005200241ff01711b41ff017122021b20024103461b2205450d1f200910a001200910010c030b200241ff01710d00200541ff01714101470d0020034198026a411f6a200842208822123c0000200320083e00b302200320073b019802200320063600af022003200a3600ab022003200b3700a3022003200c36009f022003200d36009b022003200741107622023a009a02200341f0066a411f6a20123c0000200320083e008b07200320023a00f206200320073b01f00620032006360087072003200a360083072003200b3700fb062003200c3600f7062003200d3600f306200341f0046a20091091022003280280052207450d3b2003418c056a2802002105200341f0046a41186a28020021042003280284052102200341206a200341f0066a20032902f404220842208620033502f00484220b200341fc046a350200422086200842208884220810d2022003280220450d4941a19ac1002105411a21042002450df601200710010cf6010b412a210441002106410121074197efc10021050cd6010b4100210641efeec10041efeec100410041032005200241ff01711b41ff017122021b20024103461b2205450d1e0b41282104410121070cd6010b200320083703f004200341c8016a41086a22024200370300200342003703c80141aff2c0004119200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a4110200341f0046a410810030cf7010b41d8c0c000210541142104200d4102460d8a020c8b020b41f8bfc0002105411721040c89020b200341f0046a410c6a290200210820034194056a2802002105200341f0046a41206a28020021102003418c056a2802002111200341f0046a41186a280200211a200341d0046a410c6a200341f0046a41146a3502003e0200200320083702d404200320053602ec04200320103602e804200320113602e4042003201a3602e004200320043602d004200341f0046a109e01200341f8056a41206a4200370300200341f8056a41146a4194acc200360200200341f8056a41086a4200370300200341bc066a200341b0046a41186a2204290300370200200341b4066a200341b0046a41106a2210290300370200200341ac066a200341b0046a41086a22112903003702002003428080808080013703900620034188f0c10036028806200341e8bdc0003602fc0541002105200341003602f805200320032903b0043702a4062003200341f0046a3602a006200341f0066a41186a2004290300370300200341f0066a41106a2010290300370300200341f0066a41086a2011290300370300200320032903b0043703f006200341c8066a200341f8056a200341f0066a200ead422086200fad842018ad422086200dad84200341d0046a200c2009200a201c108a024101210920032d00c806221a0d4b200341f0066a41086a2210200341f8056a41086a290300370300200341d8036a41086a200341fc066a280200360200200320032903f8053703f006200320032902f4063703d803200341d8026a200341d8036a10c10220034194066a28020022192003419c066a280200220941d8006c6a210f20034198066a2802002117201921042009450d4a200341f9066a211120192104034020042d00002109200341d8036a200441016a41d70010f8021a20094102460d4a201020093a00002003410a3a00f0062011200341d8036a41d70010f8021a200341f0066a10b401200441d8006a2204200f470d000b200f21040c4a0b200320083e00f301200341d8016a411f6a20084220883c0000200320093600ef012003200a3600eb012003200b3700e3012003200c3600df01200320063600db01200320073b01d801200320074110763a00da010cef010b200341f0046a410c6a290200210820034194056a2802002105200341f0046a41206a28020021092003418c056a280200210f200341f0046a41186a2802002110200341c8066a410c6a200341f0046a41146a3502003e0200200320083702cc06200320053602e406200320093602e0062003200f3602dc06200320103602d806200320043602c806200341f0046a109e01200341f8056a41206a4200370300200341f8056a41146a4194acc200360200200341f8056a41086a4200370300200341bc066a200341d0046a41186a2204290300370200200341b4066a200341d0046a41106a2205290300370200200341ac066a200341d0046a41086a22092903003702002003428080808080013703900620034188f0c10036028806200341e8bdc0003602fc05200341003602f805200320032903d0043702a4062003200341f0046a3602a006200341003602c003200342013703b803200341d8036a41186a2004290300370300200341d8036a41106a2005290300370300200341d8036a41086a2009290300370300200320032903d0043703d803200341f0066a41186a200341b8026a41186a290300370300200341f0066a41106a200341b8026a41106a290300370300200341f0066a41086a200341b8026a41086a290300370300200320032903b8023703f00620034198016a200341f8056a200341d8036a200341f0066a20132015200341c8066a200e2018200341b8036a108802200328029c0121044101210920032802980122050d4c200341f0066a41086a2211200341f8056a41086a290300370300200341d8036a41086a200341fc066a280200360200200320032903f8053703f006200320032902f4063703d803200341d8026a200341d8036a10c10220034194066a28020022192003419c066a280200220f41d8006c6a211020034198066a280200211720192109200f450d4b200341f9066a211a20192109034020092d0000210f200341d8036a200941016a41d70010f8021a200f4102460d4b2011200f3a00002003410a3a00f006201a200341d8036a41d70010f8021a200341f0066a10b401200941d8006a22092010470d000b201021090c4b0b200241ff01710d1c200641ff01714101470d1c200341d8016a411f6a200842208822143c0000200320083e00f301200320073b01d801200320093600ef012003200a3600eb012003200b3700e3012003200c3600df012003200d3600db012003200741107622023a00da01200341d0046a41026a200341f0046a41026a2d00003a0000200320032f00f0043b01d004200341f0066a411f6a20143c0000200320083e008b07200320023a00f206200320073b01f00620032009360087072003200a360083072003200b3700fb062003200c3600f7062003200d3600f306200341c8016a41086a22024200370300200342003703c80141e7d0c0004112200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d40200342103702dc032003200341b8016a3602d803200341f0046a200341d8036a103620032802f0042202450da801200341f8046a280200210520032802f40421040c410b41002105412821044101210741efeec10041efeec100410041032006200241ff01711b41ff017122021b20024103461b2202450d2741012106410121094101210a4101210d4101210c4101210e4101210f2002210520012802002202410b4d0dd6010cd5010b200241ff01710d1b200641ff01714101470d1b2001412c6a3100002115200141286a3502002116200141246a28020021022012a72105200341d8016a411f6a200842208822143c0000200320083e00f301200320073b01d801200320093600ef012003200a3600eb012003200b3700e3012003200c3600df012003200d3600db012003200741107622043a00da01200341c8066a41026a200341f0046a41026a2d00003a0000200320032f00f0043b01c806200341d8036a411f6a20143c0000200320083e00f303200320043a00da03200320073b01d803200320093600ef032003200a3600eb032003200b3700e3032003200c3600df032003200d3600db03200e41ff01714101470d34200341f0046a200541067610ce0220032802f8042005413f7122024d0d4a20034198026a41086a220420032802f004220620024105746a220241086a29000037030020034198026a41106a2205200241106a29000037030020034198026a41186a2207200241186a2900003703002003200229000037039802024020032802f404450d00200610010b200341d8016a41186a2007290300370300200341d8016a41106a2005290300370300200341d8016a41086a200429030037030020032003290398023703d80120033500b302200341b7026a31000042208684210820032f01980220032d009a024110747221074100210620032800af02210220032800ab02210f20032900a3022113200328009f022104200328009b0221050c4b0b200341c8066a41026a200341f0046a41026a2d00003a0000200320032f00f0043b01c8060b412a21044197efc10021050cec010b200241ff01710d1b200641ff01714101470d1b200341d8016a411f6a200842208822123c0000200320083e00f301200320073b01d801200320093600ef012003200a3600eb012003200b3700e3012003200c3600df012003200d3600db012003200741107622023a00da01200341d8036a411f6a20123c0000200320083e00f303200320023a00da03200320073b01d803200320093600ef032003200a3600eb032003200b3700e3032003200c3600df032003200d3600db03200341f0046a200341d8036a10c80120032d00f0044101470d33200341fc046a290200210820034184056a290200210b2003418c056a350200211220034190056a310000211320032902f404211420032f00f104210220032d00f3042104200341c8066a41026a200341d0046a41026a2d00003a0000200320032f01d0043b01c806200341f0066a411f6a20133c0000200320123e008b07200320043a00f206200320023b01f0062003200b37008307200320083700fb06200320143700f306200341d0046a200341f0066a10b201024020032802d8042204200e4d0d00200341d8036a20032802d0042205200e4105746a2202460d5d2002200341d8036a412010fa02450d5d0b024020032802d404450d0020032802d00410010b41b1efc0002105411421040ceb010b41002105412821044101210741efeec10041efeec100410041032006200241ff01711b41ff017122021b20024103461b2202450d2341012106410121094101210a4101210d4101210c4101210e4101210f2002210520012802002202410b4d0dd3010cd2010b200241ff01710d18200641ff01714101470d18200341d8016a411f6a200842208822123c0000200320083e00f301200320073b01d801200320093600ef012003200a3600eb012003200b3700e3012003200c3600df012003200d3600db012003200741107622023a00da01200341d0046a41026a200341f0066a41026a2d00003a0000200320032f00f0063b01d004200341f0046a411f6a20123c0000200320083e008b05200320023a00f204200320073b01f00420032009360087052003200a360083052003200b3700fb042003200c3600f7042003200d3600f304200341c8016a41086a22024200370300200342003703c80141e7d0c0004112200341c8016a1002200341b8016a41086a22072002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d3b200342103702dc032003200341b8016a3602d803200341f0066a200341d8036a103620032802f0062204450da201200341f8066a280200210520032802f40621060c3c0b41efeec10041efeec100410041032006200241ff01711b41ff017122021b20024103461b22050d03200320123703f004200341c8016a41086a22024200370300200342003703c80141a2edc000411a200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a4110200341f0046a410810030c010b41efeec10041efeec100410041032006200241ff01711b41ff017122021b20024103461b22050d02200320123703f004200341c8016a41086a22024200370300200342003703c80141c6d2c0004117200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a4110200341f0046a410810030b410121070c210b41efeec10041efeec100410041032006200241ff01711b41ff017122021b20024103461b2205450d1f0b412821040ce4010b20034188076a4200370300200341f0066a41106a4200370300200341f0066a41086a4200370300200342003703f0060b0240200341d8036a200341f0066a412010fa02450d004186f1c0002105413b21040c220b200341c8016a41086a22024200370300200342003703c80141f8f0c000410e200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d1e200341b0026a420037030020034198026a41106a420037030020034198026a41086a42003703002003420037039802200341b8016a411020034198026a4120410010042202417f460d89012002411f4d0d8901200341b8026a41186a220220034198026a41186a290300370300200341b8026a41106a220420034198026a41106a290300370300200341b8026a41086a220920034198026a41086a29030037030020032003290398023703b802200341f0046a41186a220a2002290300370300200341f0046a41106a22022004290300370300200341f0046a41086a22042009290300370300200320032903b8023703f004200341d0046a41186a200a2903002208370300200341d0046a41106a2002290300220b370300200341d0046a41086a20042903002212370300200341b0046a41086a2012370300200341b0046a41106a200b370300200341b0046a41186a2008370300200320032903f00422083703d004200320083703b0040c1f0b20034188076a4200370300200341f0066a41106a4200370300200341f0066a41086a4200370300200342003703f0060b200341d8036a200341f0066a412010fa02450d01413b21044186f1c00021052007450d1f0b200610010c1e0b41d9c1c100410520062005100302402007450d00200610010b2003410b3b01f004200341f0046a10b4010c1c0b200320083e00f301200341f7016a20084220883c0000200320093600ef012003200a3600eb012003200b3700e3012003200c3600df01200320063600db01200320073b01d801200320074110763a00da01200c21040c110b412a21044197efc10021050c050b200341b8016a41086a22024200370300200342003703b80141f0f1c100410d200341b8016a1002200341c8016a41086a2002290300370300200320032903b8013703c801420021080240200341c8016a41104188f0c100410041001004417f460d00200342003703f004200341c8016a4110200341f0046a41084100100441016a41084d0d7920032903f00421080b20024200370300200342003703b80141e085c1004116200341b8016a1002200341d8036a41086a2002290300370300200320032903b8013703d803200341d8036a41104188f0c100410041001004417f460d26200342003703f004200341d8036a4110200341f0046a41084100100441016a41084d0d7920032903f004210b0c270b411210002202450d8a01200342123702f406200320023602f006200341f0066a4197e5c0004112102520032802f006210620032802f406220520032802f80622046b41034b0d1c200441046a22022004490de60120054101742207200220022007491b22074100480de6012005450d3a200710002202450d95012002200620072005200520074b1b10f8021a200610010c3b0b200341f0066a2012109402024020032802f80620094d0d00024020032802f006200941d8006c6a2202280200410d460d00200210a0010b2002410d360200200241046a200341f0046a41d40010f8021a0b411710002202450d8a01200342173702f404200320023602f004200341f0046a41b786c1004117102520032802f004210220032802f404220520032802f80422046b41084f0d1c200441086a22072004490de50120054101742206200720072006491b22074100480de5012005450d3c200710002206450d95012006200220072005200520074b1b10f802210520021001200521020c3d0b024020032802f404450d0020032802f00410010b418987c20021064115210c4101450d1d418987c2002105411521040cd8010b200341186a200341f0066a2012201310d2022003280218450d2441e399c1002105411a21040b200910a001200910010cd2010b20084205200b7c5a0dec010b41a882c300104f000b200341d0046a41026a200341f0046a41026a2d00003a0000200320032f00f0043b01d0040c030b200341c8066a41026a200341f0046a41026a2d00003a0000200320032f00f0043b01c8060c020b200341d0046a41026a200341f0046a41026a2d00003a0000200320032f00f0043b01d0040c010b200341d0046a41026a200341f0066a41026a2d00003a0000200320032f00f0063b01d0040b412a2104410121074197efc10021050ca6010b200341c8066a411f6a20084220883c0000200320083e00e3062003200a41087622063b01c8062003200e3600df062003200f3600db06200320163700d306200320043600cf06200320053600cb06200320064110763a00ca060cc9010b024020032802dc03450d0020032802d80310010b418987c20021054115210441010dcd010b200521060b200320083e008b072003418f076a20084220883c000020032009360087072003200a360083072003200b3700fb06200320043600f706200320063600f306200320073b01f006200320074110763a00f206200341f0066a2013201210aa01200341f0066a2015201410d302410021050ccb010b20050dd4010cd5010b200e41014b0d13200341f0046a200741d00010f8021a200341013a00f006200341013602f406200341c8006a200341f0046a200341f0066a10cc0220034195056a2003280248453a0000200341fd046a200341e0036a29030037000020034185056a200341e8036a2903003700002003418d056a200341f0036a290300370000200341043a00f404200341073a00f004200320032903d8033700f504200341f0046a10b4010c3f0b411a10002202450d7d2003421a3702f404200320023602f004200341f0046a41ce86c100411a102520032802f004210620032802f404220520032802f80422026b41034b0d16200241046a22042002490dd40120054101742207200420042007491b22074100480dd4012005450d37200710002204450d8b012004200620072005200520074b1b10f8021a200610010c380b2003200e3602f004200341c8016a41086a22024200370300200342003703c8014193cfc0004119200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a4110200341f0046a410410030cc9010b2003200e3602f004200341c8016a41086a22024200370300200342003703c80141bcedc0004116200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a4110200341f0046a410410030cc8010b20012d00092104200341c8016a41086a22024200370300200342003703c80141b1d2c0004115200341c8016a1002200341b8016a41086a22052002290300370300200320032903c8013703b801200341b8016a41104188f0c10041001003200320043a00f00420024200370300200342003703c80141eef1c0004119200341c8016a100220052002290300370300200320032903c8013703b80141012107200341b8016a4110200341f0046a410110030b410121060cbe010b200341c8046a4200370300200341b0046a41106a4200370300200341b0046a41086a4200370300200342003703b0040b200341c8066a41186a2202200341b0046a41186a290300370300200341c8066a41106a2204200341b0046a41106a290300370300200341c8066a41086a2209200341b0046a41086a290300370300200320032903b0043703c806200341fa046a200929030037010020034182056a20042903003701002003418a056a20022903003701002003418b023b01f004200320032903c8063701f204200341f0046a10b40120034187056a20034198036a41086a2903003700002003418f056a20034198036a41106a2d00003a0000200320053600fb04200320073600f704200320063600f3042003200341fa026a2d00003a00f204200320032f01f8023b01f00420032003290398033700ff04200341c8016a41086a22024200370300200342003703c80141f8f0c000410e200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a4110200341f0046a412010030b410021050b4100210f4101210741012106410121094101210a4101210d4101210c4101210e20012802002202410b4d0da301412c211d0cd8010b20062104200521070c1e0b41fd99c1002105412421040cba010b20062102200521070c1e0b200521070c200b20033500930220034197026a31000042208684210820032f01f80120032d00fa01411074722107200328008f022109200328008b02210a200329008302210b0cb8010b0cb7010b2003201620154220868422083e009302200341f8016a411f6a20084220883c00002003200e41087622073b01f8012003200236008f022003200f36008b02200320133700830220032012422088a722043600ff01200320053600fb01200320074110763a00fa01410021060c160b024020032802f404450d0020032802f00410010b41152104418987c200210541010db8010cb3010b200341c8066a41026a200341d0046a41026a2d00003a0000200320032f01d0043b01c806411a21044197efc00021050cb7010b200341c8016a41086a22024200370300200342003703c80141e7d0c0004112200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d1f200342103702dc032003200341b8016a3602d803200341f0046a200341d8036a103620032802f0042202450d7c200341f8046a280200210420032802f40421050c200b200341c8016a41086a22024200370300200342003703c801418fc0c000411c200341c8016a1002200341b8016a41086a22042002290300370300200320032903c8013703b8014100210f0240200341b8016a41104188f0c100410041001004417f460d00200341003602f004200341b8016a4110200341f0046a41044100100441016a41044d0d6220032802f004210f0b20024200370300200342003703c801418fc0c000411c200341c8016a100220042002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d20200341003602f004200341b8016a4110200341f0046a41044100100441016a41044d0d6220032802f00441016a21020c210b42e807210b0b200341f0046a200941d00010f8021a200341f0066a200b20087c200341f0046a200e2012109202200341f8066a280200210420032802f406210220032802f00621052009100141012107410021062002410020054101461b21050c8f010b200341b8016a41086a22024200370300200342003703b80141ca99c1004119200341b8016a1002200341d8036a41086a2002290300370300200320032903b8013703d803410021040240200341d8036a41104188f0c100410041001004417f460d00200341003602f004200341d8036a4110200341f0046a41044100100441016a41044d0d6120032802f00421040b2003200441016a3602f004200341b8016a41086a22054200370300200342003703b80141ca99c1004119200341b8016a1002200341c8016a41086a2005290300370300200320032903b8013703c801200341c8016a4110200341f0046a41041003412010002202450d74200220032903f00637000020034184056a428180808010370200200241186a200341f0066a41186a290300370000200241106a200341f0066a41106a290300370000200241086a200341f0066a41086a290300370000200320123703f0042003200236028005200320133703f8042004200341f0046a109d0220054200370300200342003703b80141b885c1004115200341b8016a1002200341d8036a41086a2005290300370300200320032903b8013703d80341002102200341d8036a41104188f0c100410041001004417f460d1f200342103702fc052003200341d8036a3602f805200341f0046a200341f8056a103720032802f004220a450d7a20032902f4042208422088a72105200341f8046a280200210720032802f40421022008a721060c200b20062104200521070c210b200341f8016a41186a200341f0066a41186a290300370300200341f8016a41106a220a200341f0066a41106a290300370300200341f8016a41086a220c200341f0066a41086a290300370300200320032903f0063703f80120042002470d18200241016a22062002490dbc012002410174220d20062006200d491b220dad4205862212422088a70dbc012012a7220e4100480dbc012002450d29200e10002206450d7c20062007200e200241057422022002200e4b1b10f8021a200710010c2a0b410021020b2004410020021b2107410121062002410120021b2104024002402005410020021b200e4d0d000240200341f0066a2004200e4105746a2202460d002002200341f0066a412010fa024521060b02402007450d00200410010b2006450d01200341f0046a41186a200341f0066a41186a290300370300200341f0046a41106a200341f0066a41106a290300370300200341f0046a41086a200341f0066a41086a290300370300200320032903f0063703f004411c10002202450d792003421c3702dc03200320023602d803200341d8036a4196d1c000411c1025200341f8056a41086a220220032802e003360200200320032903d8033703f805200341f0046a200341f8056a101e2002280200210520032802fc05210720032802f8052102200341003602e003200342013703d803200f200341d8036a101b20122013200341d8036a109a0120032802dc03210620032802e003210920032802d8032104200341c8016a41086a220a4200370300200342003703c80120022005200341c8016a1002200341b8016a41086a200a290300370300200320032903c8013703b801200341b8016a411020042009100302402006450d00200410010b2007450da901200210010ca9010b2007450d00200410010b41ecd2c00021050c020b410021040b20024200370300200342003703c80141f9d0c000411d200341c8016a100220072002290300370300200320032903c8013703b801024002400240200341b8016a41104188f0c100410041001004417f460d00200341003602f006200341b8016a4110200341f0066a41044100100441016a41044d0d5320032802f00621022005410020041b210520040d010c020b410421022005410020041b21052004450d010b2006450d002004410120041b10010b200520024d0d01200341f0046a200e10b30121050b410d21040cab010b41c5efc0002105413921040caa010b200441d8006a21040b02400340200f2004460d0120042d00002109200441d8006a210420094102470d000b0b02402017450d00201910010b200341f8016a41186a200341b0046a41186a2204290300370300200341f8016a41106a200341b0046a41106a2209290300370300200341f8016a41086a200341b0046a41086a220f290300370300200341d8016a41086a200341c8066a41096a2210290000370300200341d8016a41106a200341c8066a41116a2211290000370300200341d8016a41186a200341c8066a41196a2219290000370300200320032903b0043703f801200320032900c9063703d801200341f0066a41086a41013a0000200341f0066a41096a20032903b004370000200341f0066a41116a200f290300370000200341f0066a41196a200929030037000020034191076a200429030037000020034199076a20032900c906370000200341a1076a2010290000370000200341a9076a2011290000370000200341b1076a20192900003700002003410a3a00f006200341f0066a10b401410021090b200341b0046a20032903d00420032903d804200341e0046a290300200341e8046a29030010a801200341d0066a28020021040240201a4101470d0020032802cc0621050b02402009450d00200341d8036a41086a200341f8056a410472220941086a280200360200200320092902003703d803200341f0066a200341d8036a10cf01200341f0066a10d00120034198066a280200450d0020034194066a28020010010b20070dac010cad010b200941d8006a21090b0240034020102009460d0120092d0000210f200941d8006a2109200f4102470d000b0b410021092017450d00201910010b200341d0046a20032903c80620032903d006200341d8066a290300200341e0066a29030010a801024020032802bc03450d0020032802b80310010b02402009450d00200341d8036a41086a200341f8056a410472220941086a280200360200200320092902003703d803200341f0066a200341d8036a10cf01200341f0066a10d00120034198066a280200450d0020034194066a28020010010b200d0da7010ca8010b024020032802f404450d0020032802f00410010b41012106418987c2002105411521040b200341d0046a41026a200341f0046a41026a2d00003a0000200320032f00f0043b01d00420060da201200320083e008b072003418f076a20084220883c000020032002360087072003200f36008307200320133700fb06200320043600f706200320053600f306200320073b01f006200320074110763a00f206200341f0046a200341d8036a10c80141012107024020032d00f0044101470d0041bdeec0002105412621040c7b0b200341c8016a41086a22024200370300200342003703c80141e7d0c0004112200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d14200342103702fc052003200341b8016a3602f805200341f0046a200341f8056a103620032802f0042209450d6f200341f8046a280200210220032802f404210c0c150b200710002204450d5b0b200420026a200a360000200341b8016a41086a22054200370300200342003703b8012004200241046a200341b8016a1002200341d8036a41086a2005290300370300200320032903b8013703d803200341d8036a4110100e210202402007450d00200410010b2002450d02200341b8016a41086a22024200370300200342003703b80141d9c2c0004112200341b8016a1002200341d8036a41086a2002290300370300200320032903b8013703d8034100210502400240200341d8036a41104188f0c100410041001004417f460d00200342103702f4062003200341d8036a3602f006200341f0046a200341f0066a103b20032802f0042204450d60200320032902f40422083702f404200320043602f0042008422088a722052008a72202460d010c090b200341003602f804200342043703f00441042104410021020b200241016a22072002490dac0120024101742206200720072006491b2206ad4202862208422088a70dac012008a722074100480dac012002450d05200710002209450d5d20092004200720024102742202200220074b1b10f802210220041001200221040c060b200710002202450d5a0b200220046a200a360000200341d8036a41086a22054200370300200342003703d8032002200441046a2206200341d8036a1002200341c8016a41086a2005290300370300200320032903d8033703c8014100210402400240200341c8016a41104188f0c100410041001004417f460d00200341b0046a41186a22044200370300200341b0046a41106a4200370300200341b0046a41086a4200370300200342003703b0044100200341c8016a4110200341b0046a41204100100422052005417f461b220541204922090d56200341f0066a41186a220a2004290300370300200341f0066a41106a220c200341b0046a41106a290300370300200341f0066a41086a2204200341b0046a41086a290300370300200320032903b0043703f006200341c8066a41186a200a2903002208370300200341c8066a41106a200c290300220b370300200341c8066a41086a20042903002212370300200341f8016a41086a2012370300200341f8016a41106a200b370300200341f8016a41186a2008370300200320032903f00622083703f801200320083703c806200342003703f806200342003703f0064100200341c8016a4110200341f0066a41102005412020091b2209100422052005417f461b2205410f4d0d572004290300211220032903f0062113200341d0046a41186a4200370300200341d0046a41106a4200370300200341d0046a41086a4200370300200342003703d004200341c8016a4110200341d0046a41202005411020054110491b20096a220410042205417f460d4b2005411f4d0d4b200341f0066a41186a2205200341d0046a41186a290300370300200341f0066a41106a2209200341d0046a41106a290300370300200341f0066a41086a220a200341d0046a41086a290300370300200320032903d0043703f006200341c8066a41186a20052903002208370300200341c8066a41106a2009290300220b370300200341c8066a41086a200a290300221437030020034198026a41086a201437030020034198026a41106a200b37030020034198026a41186a2008370300200320032903f006220837039802200320083703c806200342003703f806200342003703f006200341c8016a4110200341f0066a4110200441206a10042204417f460d572004410f4d0d57200341f0066a41086a2205290300210820032903f006210b200341d8016a41186a2204200341f8016a41186a290300370300200341d8016a41106a2209200341f8016a41106a290300370300200341d8016a41086a220a200341f8016a41086a290300370300200341b8026a41086a220c20034198026a41086a290300370300200341b8026a41106a220d20034198026a41106a290300370300200341b8026a41186a220e20034198026a41186a290300370300200320032903f8013703d80120032003290398023703b802200341f0066a41186a220f2004290300370300200341f0066a41106a221020092903003703002005200a290300370300200341d8036a41086a2204200c290300370300200341d8036a41106a2209200d290300370300200341d8036a41186a220a200e290300370300200320032903d8013703f006200320032903b8023703d803200341f8056a41186a200f290300370300200341f8056a41106a2010290300370300200341f8056a41086a2005290300370300200341c8066a41086a2004290300370300200341c8066a41106a2009290300370300200341c8066a41186a200a290300370300200320032903f0063703f805200320032903d8033703c80620044200370300200342003703d80320022006200341d8036a1002200341b8016a41086a2004290300370300200320032903d8033703b801200341b8016a4110100820134220882012422086842114201242208821122013a72106410121040c010b0b200341f0066a41186a2209200341f8056a41186a290300370300200341f0066a41106a220a200341f8056a41106a290300370300200341f0066a41086a220c200341f8056a41086a290300370300200341d8036a41086a220d200341c8066a41086a290300370300200341d8036a41106a220e200341c8066a41106a290300370300200341d8036a41186a220f200341c8066a41186a290300370300200320032903f8053703f006200320032903c8063703d8034100210502402004450d00200341b8036a41186a2009290300370300200341b8036a41106a200a290300370300200341b8036a41086a200c29030037030020034198036a41086a200d29030037030020034198036a41106a200e29030037030020034198036a41186a200f290300370300200320032903f0063703b803200320032903d80337039803410121050b02402007450d00200210010b2005450d00200341f8026a41186a2202200341b8036a41186a290300370300200341f8026a41106a2204200341b8036a41106a290300370300200341f8026a41086a2205200341b8036a41086a290300370300200341d8026a41086a220720034198036a41086a290300370300200341d8026a41106a220920034198036a41106a290300370300200341d8026a41186a220a20034198036a41186a290300370300200320032903b8033703f80220032003290398033703d802200341f0046a41186a2008370300200341fc046a20123e020020034198056a2005290300370300200341a0056a2004290300370300200341a8056a2002290300370300200341b8056a2007290300370300200341c0056a2009290300370300200341c8056a200a2903003703002003200b37038005200320143702f404200320063602f004200320032903f80237039005200320032903d8023703b00520034180016a20034190056a200b200810d4020c9c010b41dff0c0002105411921040c9d010b200710002202450d580b200220046a20123700002003200441086a3602f404200320023602f004200341f0066a200341f0046a101a02402007450d00200210010b20032802f00621050240200341f0066a41086a2802002202450d00200241d8006c210420052102034002402002280200410d460d00200210280b200241d8006a2102200441a87f6a22040d000b0b20032802f406450d8801200510010c88010b200710002204450d570b200320063602f404200320043602f004200621020b200341f8046a200541016a360200200420054102746a200a360200200341f0046a10a0022002450d9601200410010c96010b200721062002210d0c110b410021020b2005410020021b210d2002410120021b22072004410020021b22064105746a2105200721020340200520026b41ff004d0d11200341f0066a2002460d122002200341f0066a412010fa02450d12200241206a2204200341f0066a460d122004200341f0066a412010fa02450d12200241c0006a2204200341f0066a460d122004200341f0066a412010fa02450d12200241e0006a2204200341f0066a460d1220024180016a21022004200341f0066a412010fa020d000c120b0b410121020b200320023602f004200341c8016a41086a22024200370300200342003703c801418fc0c000411c200341c8016a1002200341b8016a41086a22042002290300370300200320032903c8013703b801200341b8016a4110200341f0046a4104100320024200370300200342003703c80141abc0c0004118200341c8016a100220042002290300370300200320032903c8013703b80102400240200341b8016a41104188f0c100410041001004417f460d00200342103702f4062003200341b8016a3602f006200341f0046a200341f0066a103620032802f0042202450d5c200341f8046a280200210420032802f40421060c010b410021020b200341f8016a41186a200341d8036a41186a290300370300200341f8016a41106a200341d8036a41106a290300370300200341f8016a41086a200341d8036a41086a290300370300200320032903d8033703f8012002410120021b210502402004410020021b22042006410020021b2202470d00200241016a22062002490da00120024101742209200620062009491b2211ad4205862208422088a70da0012008a722064100480da0012002450d08200610002210450d5e20102005200620024105742202200220064b1b10f8021a200510010c090b20052110200221110c080b4108210a4100210741002106410021050b200341f0046a2009109c02200341f8016a41186a220c200341f0066a41186a290300370300200341f8016a41106a220d200341f0066a41106a290300370300200341f8016a41086a220e200341f0066a41086a290300370300200320032903f0063703f801024020052006470d0020022007470d00200241016a22052002490d9e0120024101742206200520052006491b2206ad42f8007e2208422088a70d9e012008a722104100480d9e012002450d09201010002205450d5d2005200a2010200241f8006c2202200220104b1b10f8021a200a10010c0a0b200a2105200221060c090b200710002204450d530b200420026a2009360000200341b8016a41086a22054200370300200342003703b8012004200241046a200341b8016a1002200341c8016a41086a2005290300370300200320032903b8013703c801200341c8016a4110100e210202402007450d00200410010b024002402002450d00200341286a200341f0066a10b0012003290328200341286a41086a29030084500d01200341fc046a200341f0066a41086a29030037020020034184056a200341f0066a41106a2903003702002003418c056a20034188076a290300370200200320093602f004200320032903f0063702f404411010002202450d56200342103702dc03200320023602d803200341d8036a41fb86c10041101025200341f8056a41086a220220032802e003360200200320032903d8033703f805200341f0046a200341f8056a1097022002280200210420032802fc05210520032802f8052102200341b8016a41086a22074200370300200342003703b80120022004200341b8016a1002200341c8016a41086a2007290300370300200320032903b8013703c801200341c8016a4110100e210402402005450d00200210010b20040d7d411310002202450d60200342133702f404200320023602f004200341f0046a41e886c1004113102520032802f004210620032802f404220520032802f80422026b41034b0d0e200241046a22042002490d9d0120054101742207200420042007491b22074100480d9d012005450d15200710002204450d642004200620072005200520074b1b10f8021a200610010c160b41f09ac1002105412221040c8c010b41929bc1002105413021040c8b010b200341d0046a41086a22072004417f6a2204360200200520044105746a220429000021082004290008210b20042900102112200241186a200441186a290000370000200220123700102002200b37000820022008370000200341f0046a41086a2007280200360200200320032903d0043703f004200341f0066a200341f0046a10c901411210002202450d5c200342123702f404200320023602f004200341f0046a4185efc00041121025200341f8056a41086a220220032802f804360200200320032903f0043703f805200341d8036a200341f8056a101e2002280200210420032802fc05210520032802f805210242002108200341c8016a41086a22074200370300200342003703c80120022004200341c8016a1002200341b8016a41086a2007290300370300200320032903c8013703b801200341b8016a4110100802402005450d00200210010b200341f0046a41186a200341d8036a41186a290300370300200341f0046a41106a200341d8036a41106a290300370300200341f0046a41086a200341d8036a41086a290300370300200320032903d8033703f004200341c8016a41086a22024200370300200342003703c80141f0f1c100410d200341c8016a1002200341b8016a41086a22042002290300370300200320032903c8013703b8010240200341b8016a41104188f0c100410041001004417f460d00200342003703f805200341b8016a4110200341f8056a41084100100441016a41084d0d4220032903f80521080b20024200370300200342003703c80141c6d2c0004117200341c8016a100220042002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d0d200342003703f805200341b8016a4110200341f8056a41084100100441016a41084d0d4220032903f805210b410f2102410f10002204450d0e0c86010b410021090b2009410120091b220a2002410020091b4105746a2105200a21020340200520026b41ff004d0d0e200341d8036a2002460d0b2002200341d8036a412010fa02450d0b200341d8036a2106200241206a2204200341d8036a460d182004200341d8036a412010fa02450d0f200241c0006a2204200341d8036a460d182004200341d8036a412010fa02450d10200241e0006a2204200341d8036a460d1820024180016a21022004200341d8036a412010fa020d000b2004210620090d180c190b200610002210450d550b2010200441057422056a220220032903f801370000200241186a200341f8016a41186a290300370000200241106a200341f8016a41106a290300370000200241086a200341f8016a41086a290300370000200341003602f804200342013703f004200441016a2202200341f0046a101b024002402002450d00200541206a210c4100200341f0046a41086a28020022046b210920032802f004210a20032802f40421062010210d0340200d21020240200620096a411f4b0d00200441206a22052004490d9a012006410174220d20052005200d491b22054100480d9a0120051000210d024002402006450d00200d450d31200d200a20052006200620054b1b10f8021a200a10010c010b200d450d300b200d210a200521060b200241206a210d200a20046a22052002290000370000200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a290000370000200941606a2109200441206a2104200c41606a220c0d000b200341f8046a2004360200200320063602f4042003200a3602f0040c010b200341f0046a41086a280200210420032802f404210620032802f004210a0b200341c8016a41086a22024200370300200342003703c80141abc0c0004118200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a4110200a2004100302402006450d00200a10010b02402011450d00201010010b200341f0066a41186a200341d8036a41186a290300370300200341f0066a41106a200341d8036a41106a290300370300200341f0066a41086a200341d8036a41086a290300370300200320032903d8033703f006200341f0046a200741d00010f8021a411910002202450d49200342193702cc06200320023602c806200341c8066a41dfbfc00041191025200341b0046a41086a220220032802d006360200200320032903c8063703b004200341f0066a200341b0046a101e2002280200210520032802b404210620032802b0042102200341003602d006200342013703c806200341f0046a200341c8066a101c20032802cc06210920032802d006210a20032802c8062104200341c8016a41086a220c4200370300200342003703c80120022005200341c8016a1002200341b8016a41086a200c290300370300200320032903c8013703b801200341b8016a41102004200a100302402009450d00200410010b02402006450d00200210010b200341f0046a10a001200341f0066a41186a200341d8036a41186a290300370300200341f0066a41106a200341d8036a41106a290300370300200341f0066a41086a200341d8036a41086a290300370300200320032903d8033703f006412010002202450d4a2003418c056a4100360200200341fc046a428180808010370200200341f8056a41086a2903002108200341f8056a41106a290300210b20032903f8052112200241186a200341f8056a41186a290300370000200241106a200b370000200241086a2008370000200220123700002003420137028405200320023602f8042003200e3602f4042003200f3602f004411510002204450d4b200342153702cc06200320043602c806200341c8066a41c3c0c00041151025200341b0046a41086a220420032802d006360200200320032903c8063703b004200341f0066a200341b0046a101e20032802b404210520032802b00422062004280200200341f0046a10a30202402005450d00200610010b20021001200341fd046a200341f8056a41086a29030037000020034185056a200341f8056a41106a2903003700002003418d056a200341f8056a41186a29030037000020034195056a20032903d8033700002003419d056a200341d8036a41086a290300370000200341a5056a200341d8036a41106a290300370000200341ad056a200341d8036a41186a290300370000200341003a00f404200341073a00f004200320032903f8053700f504200341bc056a200e360200200341b8056a200f360200200341f0046a10b4010b20071001410021050c9f010b201010002205450d530b2005200741f8006c220a6a200341f0046a41d00010f80222022004360250200241ec006a200c290300370200200241e4006a200d290300370200200241dc006a200e290300370200200220032903f8013702542003200741016a22023602f804200320063602f404200320053602f004200341153602dc03200341b885c1003602d803200341f0046a200341d8036a101d02402002450d00200a41f8006a210420052102034020021028200241f8006a2102200441887f6a22040d000b0b02402006450d00200510010b200910a001200910014100210241012107200f4102470d750c7c0b200e10002206450d520b200620044105746a220220032903f801370000200241186a200341f8016a41186a290300370000200241106a200a290300370000200241086a200c29030037000041012107200341f0046a41186a200441016a36020020034184056a200d360200200320083703f8042003200b3703f0042003200536028c0520032006360280052009200341f0046a109d02410021060c7f0b024020022005460d000340200341f0066a2002460d022002200341f0066a412010fa02450d022005200241206a2202470d000b0b410f10002202450d592003420f3702f404200320023602f004200341f0046a41ddd2c000410f1025200341d8036a41086a220220032802f804360200200320032903f0043703d803200341f0066a200341d8036a101e2002280200210420032802dc03210520032802d80321022003427f3703f004200341c8016a41086a22094200370300200342003703c80120022004200341c8016a1002200341b8016a41086a2009290300370300200320032903c8013703b801200341b8016a4110200341f0046a4108100302402005450d00200210010b200341b8026a41186a2204200341f0066a41186a290300370300200341b8026a41106a200341f0066a41106a290300370300200341b8026a41086a200341f0066a41086a290300370300200320032903f0063703b8022006200d470d0a200641016a22022006490d900120064101742205200220022005491b220dad4205862208422088a70d90012008a722024100480d90012006450d0b20021000220e450d5a200e2007200220064105742205200520024b1b10f8021a200710010c0c0b41fbedc0002105411f2104200d450d8301200710010c83010b20062104200521070c070b2002210620090d0d0c0e0b42e807210b410f2102410f100022040d780b200241011019000b4100210620022005460d090340200341d8036a2002460d082002200341d8036a412010fa02450d092005200241206a2202470d000c0a0b0b2004210620090d090c0a0b2004210620090d080c090b200710002204450d4e0b200420026a2009360000200341b8016a41086a22054200370300200342003703b8012004200241046a220a200341b8016a1002200341d8036a41086a2005290300370300200320032903b8013703d803410021020240200341d8036a41104188f0c100410041001004417f460d00200342103702fc052003200341d8036a3602f805200341f0046a200341f8056a103620032802f0042206450d4d200341f0046a41086a280200210520032802f404210220032902f4042108200341b8016a41086a220c4200370300200342003703b8012004200a200341b8016a1002200341c8016a41086a200c290300370300200320032903b8013703c801200341c8016a411010082008422088a7210a2008a7210c2007450d660c650b41012106410021054100210c4100210a20070d640c650b2007210e0c010b20021000220e450d4e0b200e200641057422056a220220032903b802370000200241186a2004290300370000200241106a200341b8026a41106a290300370000200241086a200341b8026a41086a290300370000200341003602f804200342013703f004200641016a2202200341f0046a101b024002402002450d00200541206a210a4100200341f0046a41086a28020022046b210620032802f004210920032802f4042107200e210c0340200c21020240200720066a411f4b0d00200441206a22052004490d87012007410174220c20052005200c491b22054100480d870120051000210c024002402007450d00200c450d41200c200920052007200720054b1b10f8021a200910010c010b200c450d400b200c2109200521070b200241206a210c200920046a22052002290000370000200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a290000370000200641606a2106200441206a2104200a41606a220a0d000b200341f8046a2004360200200320073602f404200320093602f0040c010b200341f0046a41086a280200210420032802f404210720032802f00421090b200341c8016a41086a22024200370300200342003703c80141e7d0c0004112200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a411020092004100302402007450d00200910010b200d450d70200e10010c700b200341d8036a210620090d020c030b200221060b2009450d010b200c450d00200a10010b02402006450d0041e3eec0002105412221040c4c0b200341c8066a200341f0066a10b201200341f0046a41186a2205200341d8036a41186a290300370300200341f0046a41106a2207200341d8036a41106a290300370300200341f0046a41086a2204200341d8036a41086a290300370300200320032903d8033703f004024020032802d006220220032802cc06470d00200241016a22062002490d7f20024101742209200620062009491b220aad4205862208422088a70d7f2008a722064100480d7f024002402002450d0020032802c806210c200610002209450d492009200c20062002410574220d200d20064b1b10f8021a200c10010c010b200610002209450d480b2003200a3602cc06200320093602c8060b200341c8066a41086a2206200241016a36020020032802c80620024105746a220220032903f004370000200241086a2004290300370000200241106a2007290300370000200241186a200529030037000020042006280200360200200320032903c8063703f004200341f0066a200341f0046a10c901411210002202450d42200342123702f404200320023602f004200341f0046a4185efc00041121025200341f8056a41086a220220032802f804360200200320032903f0043703f805200341d8036a200341f8056a101e2002280200210420032802fc05210520032802f8052102200341c8016a41086a22074200370300200342003703c80120022004200341c8016a1002200341b8016a41086a2007290300370300200320032903c8013703b801200341b8016a4110200341f0066a4120100302402005450d00200210010b410f10002202450d432003420f3702f404200320023602f004200341f0046a41ddd2c000410f1025200341f8056a41086a220220032802f804360200200320032903f0043703f805200341d8036a200341f8056a101e2002280200210420032802fc05210520032802f80521022003427f3703f004200341c8016a41086a22074200370300200342003703c80120022004200341c8016a1002200341b8016a41086a2007290300370300200320032903c8013703b801200341b8016a4110200341f0046a410810032005450d6b200210010c6b0b41eac4c10041331042000b41b0cdc200104f000b41c0e6c200104f000b41d881c300104f000b4198cdc200104f000b41c4d5c200104f000b4180cdc200104f000b41b0acc200104f000b41b8b0c300104f000b41fcabc200104f000b4198e8c200104f000b41eac4c10041331042000b41eac4c10041331042000b20034184056a4101360200200341fc046a4101360200200341033602f406200341ecf1c1003602f006200341e0c3c1003602f804200341023602f4042003418882c3003602f0042003200341f0066a36028005200341f0046a419882c3001071000b41f081c300104f000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b200541011019000b411241011019000b412041011019000b41eac4c10041331042000b411541011019000b411941011019000b41eac4c10041331042000b41eac4c10041331042000b2019450d00200610010b41eac4c10041331042000b200341c8066a41186a200341f0066a41186a290000370300200341c8066a41106a200341f0066a41106a290000370300200341c8066a41086a200341f0066a41086a290000370300200320032900f0063703c80641eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b411241011019000b411241011019000b411741011019000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b411a41011019000b200341c8066a41186a200341f0066a41186a290000370300200341c8066a41106a200341f0066a41106a290000370300200341c8066a41086a200341f0066a41086a290000370300200320032900f0063703c8060b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b200741011019000b200741011019000b200741011019000b200741041019000b41eac4c10041331042000b411941011019000b412041011019000b411541011019000b412041011019000b200741011019000b200541011019000b411041011019000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b411c41011019000b200641011019000b201041081019000b200e41011019000b41eac4c10041331042000b411241011019000b411341011019000b411241011019000b410f41011019000b41eac4c10041331042000b200741011019000b200641011019000b410f41011019000b200241011019000b4105211d0c400b4105211d0c3f0b4105211d0c3e0b4105211d0c3d0b4106211d0c3c0b4106211d0c3b0b4106211d0c3a0b4106211d0c390b4106211d0c380b4107211d0c370b4108211d0c360b410a211d0c350b410c211d0c340b412c211d0c330b410c211d0c320b412c211d0c310b410c211d0c300b412c211d0c2f0b410c211d0c2e0b200410010b200341f0046a41186a2204200341f0066a41186a290300370300200341f0046a41106a2207200341f0066a41106a290300370300200341f0046a41086a220d200341f0066a41086a290300370300200320032903f0063703f004024002400240200a200c470d0020022005470d00200241016a220a2002490d232002410174220c200a200a200c491b2217ad4205862208422088a70d232008a7220a4100480d232002450d01200a1000221a450d0a201a2006200a200241057422022002200a4b1b10f8021a200610010c020b2006211a200221170c010b200a1000221a450d080b201a20054105746a220220032903f004370000200241186a2004290300370000200241106a2007290300370000200241086a200d290300370000411310002202450d06200342133702f404200320023602f004200341f0046a41e886c1004113102520032802f004211002400240024020032802f404220220032802f80422116b41044f0d00201141046a22042011490d2320024101742207200420042007491b22194100480d232002450d01201910002204450d0b2004201020192002200220194b1b10f802210220101001200221100c020b200221190c010b201910002210450d090b201020116a2009360000200341003602f804200342013703f004200541016a2202200341f0046a101b024002402002450d00200541057441206a210c4100200341f0046a41086a28020022046b210620032802f004210a20032802f4042107201a210d0340200d21020240200720066a411f4b0d00200441206a22052004490d242007410174220d20052005200d491b22054100480d2420051000210d024002402007450d00200d450d09200d200a20052007200720054b1b10f8021a200a10010c010b200d450d080b200d210a200521070b200241206a210d200a20046a22052002290000370000200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a290000370000200641606a2106200441206a2104200c41606a220c0d000b200341f8046a2004360200200320073602f4042003200a3602f0040c010b200341f8046a280200210420032802f404210720032802f004210a0b200341b8016a41086a22024200370300200342003703b8012010201141046a200341b8016a1002200341c8016a41086a2002290300370300200320032903b8013703c801200341c8016a4110200a2004100302402007450d00200a10010b02402019450d00201010010b2017450d00201a10010b200341fc046a200341f0066a41086a29030037020020034184056a200341f0066a41106a2903003702002003418c056a20034188076a290300370200200320093602f004200320032903f0063702f404411010002202450d03200342103702dc03200320023602d803200341d8036a41fb86c10041101025200341f8056a41086a220220032802e003360200200320032903d8033703f805200341f0046a200341f8056a1097022002280200210520032802fc05210720032802f8052104410110002202450d042002200e3a0000200341b8016a41086a22064200370300200342003703b80120042005200341b8016a1002200341d8036a41086a2006290300370300200320032903b8013703d803200341d8036a4110200241011003200210012007450d00200410010b4101210241012107200f4102460d070b200f4105470d070c080b200541011019000b411041011019000b410141011019000b411341011019000b200a41011019000b201941011019000b20020d010b410021060c030b200910a00120091001410021060c020b2003420f3702fc05200320043602f805200341f8056a41ddd2c00020021025200341c8066a41086a2202200328028006360200200320032903f8053703c806200341f0046a200341c8066a101e2002280200210420032802cc06210520032802c80621022003200b20087c3703f805200341c8016a41086a22074200370300200342003703c80120022004200341c8016a1002200341b8016a41086a2007290300370300200320032903c8013703b801200341b8016a4110200341f8056a410810032005450d00200210010b410021050c070b410121094101210a4101210d4101210c4101210e4101210f41002105024020012802002202410b4d0d00412c211d0c1e0b410c211d0c1d0b200341b8016a41086a22024200370300200342003703b80141feefc000411c200341b8016a1002200341d8036a41086a22092002290300370300200320032903b8013703d8034100210702400240024002400240024002400240200341d8036a41104188f0c100410041001004417f460d00200342003703f804200342003703f004200341d8036a4110200341f0046a411041001004220a417f460d02200a410f4d0d02200341f8046a290300210b20032903f00421130c010b420021134200210b0b20024200370300200342003703b801419af0c0004115200341b8016a100220092002290300370300200320032903b8013703d80302400240200341d8036a41104188f0c100410041001004417f460d00200341003602f004200341d8036a4110200341f0046a41044100100441016a41044d0d0120032802f00421070b200341e8006a201520142007ad420010fc02200341d8006a2003290368200341e8006a41086a29030042c0843d420010fb02200341f8006a200341f0066a2013200329035822122012201354200341d8006a41086a2903002212200b542012200b511b22021b2213200b201220021b220b10d20202402003280278450d0041c5f0c0002105411a21040c0c0b200341b8016a41086a22024200370300200342003703b80141aff0c0004116200341b8016a1002200341d8036a41086a2002290300370300200320032903b8013703d803410021070240200341d8036a41104188f0c100410041001004417f460d00200341003602f004200341d8036a4110200341f0046a41044100100441016a41044d0d0320032802f00421070b2003200741016a3602f004200341b8016a41086a22024200370300200342003703b80141aff0c0004116200341b8016a1002200341d8036a41086a2002290300370300200320032903b8013703d803200341d8036a4110200341f0046a41041003200341cf056a20084220883c0000200341cb056a20083e0000200341f0046a41186a200b370300200341c7056a200e360000200341c3056a200f360000200341bb056a2016370000200341b7056a2004360000200341b3056a2005360000200341a8056a200341f0066a41186a290300370300200341a0056a200341f0066a41106a29030037030020034198056a200341f0066a41086a290300370300200320063b01b005200341b2056a20064110763a0000200320143703f804200320153703f0042003201337038005200320032903f00637039005411210002202450d03200342123702dc03200320023602d803200341d8036a4197e5c0004112102520032802d803210202400240024020032802dc03220420032802e00322056b41044f0d00200541046a22062005490d1a20044101742209200620062009491b220a4100480d1a2004450d01200a10002206450d0720062002200a20042004200a4b1b10f802210420021001200421020c020b2004210a0c010b200a10002202450d050b200220056a2007360000200341003602e003200342013703d80320034190056a200341d8036a101e200341f8046a290300210820032903f004210b024002400240024020032802dc03220920032802e00322046b41104f0d00200441106a22062004490d1b2009410174220c20062006200c491b220c4100480d1b2009450d0120032802d803210d200c10002206450d092006200d200c20092009200c4b1b10f8021a200d10010c020b20032802d80321060c020b200c10002206450d070b2003200c3602dc03200320063602d8030b200620046a220620083700082006200b370000200341e0036a2206200441106a360200200341b0056a200341d8036a101e20034188056a2903002108200341f0046a41106a290300210b024002400240024020032802dc03220c200628020022066b41104f0d00200641106a22042006490d1b200c4101742209200420042009491b22094100480d1b200c450d0120032802d803210d200910002204450d0a2004200d2009200c200c20094b1b10f8021a200d10010c020b20032802d8032104200c21090c020b200910002204450d080b200320093602dc03200320043602d8030b200420066a220c2008370008200c200b370000200341b8016a41086a220c4200370300200342003703b8012002200541046a200341b8016a1002200341d8036a41086a200c290300370300200320032903b8013703d803200341d8036a41102004200641106a100302402009450d00200410010b0240200a450d00200210010b200341fc046a200736020041002105200341f8046a41003a0000200341093a00f004200341f0046a10b4010c0a0b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b411241011019000b200a41011019000b200c41011019000b200941011019000b41002106410121074106211d0c1b0b200320083e00f303200341f7036a20084220883c0000200320093600ef032003200a3600eb032003200b3700e3032003200c3600df03200320063600db03200320073b01d803200320074110763a00da03024002400240411410002202450d00200342143702f404200320023602f004200341f0046a41eeefc10041141025200341c8066a41086a220220032802f804360200200320032903f0043703c806200341f8056a200341c8066a101e2002280200210420032802cc06210520032802c8062102200341c8016a41086a22074200370300200342003703c80120022004200341c8016a1002200341b8016a41086a2007290300370300200320032903c8013703b8014100210402400240200341b8016a41104188f0c100410041001004417f460d00200342003703f804200342003703f004200341b8016a4110200341f0046a4110410010042204417f460d012004410f4d0d01200341f8046a290300211e20032903f004211f410121042005450d040c030b20050d020c030b41eac4c10041331042000b411441011019000b200210010b024002400240411410002202450d00200342143702f404200320023602f004200341f0046a41eeefc10041141025200341c8066a41086a220220032802f804360200200320032903f0043703c806200341d8036a200341c8066a101e2002280200210520032802cc06210720032802c806210242002108200341c8016a41086a22064200370300200342003703c80120022005200341c8016a1002200341b8016a41086a2006290300370300200320032903c8013703b80102400240200341b8016a41104188f0c100410041001004417f460d00200342003703f804200342003703f004200341b8016a4110200341f0046a4110410010042205417f460d012005410f4d0d01200341f8046a290300211520032903f00421082007450d040c030b4200211520070d020c030b41eac4c10041331042000b411441011019000b200210010b4200210b200341c8016a41086a22024200370300200342003703c80141e7f5c10041fbf5c10020082015845022051b4114200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b80102400240024002400240200341b8016a41104188f0c100410041001004417f460d00200342003703f804200342003703f004200341b8016a4110200341f0046a4110410010042202417f460d022002410f4d0d02200341f8046a290300211620032903f004210b0c010b420021160b02402013200b7c22202013542202201220167c2002ad7c221420125420142012511b450d0041f58bc2002105412821040c060b0240201f420020041b221f20207d2221201f56201e420020041b221e20147d201f202054ad7d2214201e562014201e511b4101470d00419d8cc2002105411d21040c060b2005450d02200341c8016a41086a22024200370300200342003703c80141bef0c100411b200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d02200342003703f804200342003703f004200341b8016a4110200341f0046a4110410010042202417f460d012002410f4d0d01201320032903f004542012200341f8046a29030022205420122020511b450d0241ba8cc2002105411f21040c050b41eac4c10041331042000b41eac4c10041331042000b200341106a200341f8056a10ca01024020032802102205450d00200328021421040c030b0240200820137c22202008542202201520127c2002ad7c220820155420082015511b450d0041d98cc2002105412d21040c030b200341f8056a200341d8036a412010fa02450d00200341f8056a2021201410aa0142002114200341c8016a41086a22024200370300200342003703c80141d9f0c1004116200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801024002400240200341b8016a41104188f0c100410041001004417f460d00200342003703f804200342003703f004200341b8016a4110200341f0046a4110410010042202417f460d022002410f4d0d02200341f8046a290300211520032903f00421140c010b420021150b02402014200b7d221e201456201520167d2014200b54ad7d221420155620142015511b0d002003201e3703f004200320143703f804200341c8016a41086a22024200370300200342003703c80141d9f0c1004116200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a4110200341f0046a411010030b200341d8036a2020200810c2021a200341f0046a41086a41023a0000200341f9046a20032903f80537000020034181056a200341f8056a41086a29030037000020034189056a200341f8056a41106a29030037000020034191056a200341f8056a41186a29030037000020034199056a20032903d803370000200341a1056a200341d8036a41086a290300370000200341a9056a200341d8036a41106a290300370000200341b1056a200341d8036a41186a290300370000200341013a00f004200341d8056a2016370300200341d0056a200b370300200341c8056a2012370300200341c0056a2013370300200341f0046a10b4010c010b41eac4c10041331042000b410021050b0b410121074105211d0c170b410121070b41012106410121094101210a4101210d4101210c4101210e4101210f024020012802002202410b4d0d00412c211d0c160b410c211d0c150b200e10010b4101210920024102470d020c030b200a10010b02402006450d00200c10010b4100210920024102460d010b20024103470d012009450d0102402006450d00200c10010b2007450d01200a10010c010b2009200d45720d00200e10010b4100210e4101210741012106410121094101210a4101210d4101210c410b211d0c0e0b200210010b0240024002400240024002402006450d002003200c3602b803200f2017470d012006200a4105746a210920062102410021050340200920026b41ff004d0d03200341f8056a2002460d0420052002200341f8056a412010fa0222044100476a21052004450d04200241206a2204200341f8056a460d0420052004200341f8056a412010fa0222044100476a21052004450d04200241c0006a2204200341f8056a460d0420052004200341f8056a412010fa0222044100476a21052004450d04200241e0006a2204200341f8056a460d0420024180016a210220052004200341f8056a412010fa0222044100476a210520040d000c040b0b41ecc0c000210541132104200d4102460d0e0c0f0b41ffc0c0002105411021042019450d0b0c0a0b20022009460d012006200a4105746a21090340200341f8056a2002460d0120052002200341f8056a412010fa0222044100476a21052004450d014100210f2009200241206a2202470d000c030b0b4101210f0c010b4100210f0b200c20114105746a210e200c210241002104024002400240024002400240024002400240024002400240024002400240024002400340200e20026b41ff004d0d01200341f8056a2002460d0220042002200341f8056a412010fa0222094100476a21042009450d02200241206a2209200341f8056a460d0220042009200341f8056a412010fa0222094100476a21042009450d02200241c0006a2209200341f8056a460d0220042009200341f8056a412010fa0222094100476a21042009450d02200241e0006a2209200341f8056a460d0220024180016a210220042009200341f8056a412010fa0222094100476a210420090d000c020b0b2002200e460d020340200341f8056a2002460d0120042002200341f8056a412010fa0222094100476a21042009450d0141002109200e200241206a2202470d000c020b0b410121090b201041ff0171450d010c020b41002109201041ff01710d010b20090d01200341f0046a41186a2204200341f8056a41186a290300370300200341f0046a41106a2209200341f8056a41106a290300370300200341f0046a41086a221b200341f8056a41086a290300370300200320032903f8053703f0040240024002400240024002402011201a470d00201a41016a2202201a490d12201a410174220e20022002200e491b2222ad4205862208422088a70d122008a7220e4100480d12201a450d01200e10002202450d042002200c200e201a410574221a201a200e4b1b10f8021a200c10010c020b200c2102201a21220c020b200e10002202450d020b200320023602b803200220114105746a210e0b200e20032903f004370000200e41186a2004290300370000200e41106a2009290300370000200e41086a201b290300370000201141016a21110240200f450d00200a20054d0d022006200a417f6a220a4105746a220429000021082004290008210b20042900102112200620054105746a220541186a200441186a290000370000200520123700102005200b370008200520083700000b2002210c2006211b2019211c2022211a0c040b200e41011019000b41c8acc2002005200a104e000b200f0d00200341f0046a41186a2205200341f8056a41186a290300370300200341f0046a41106a220e200341f8056a41106a290300370300200341f0046a41086a220f200341f8056a41086a290300370300200320032903f8053703f004024002400240200a2019470d00201941016a22022019490d0e2019410174221b20022002201b491b221cad4205862208422088a70d0e2008a722024100480d0e2019450d0120021000221b450d05201b2006200220194105742219201920024b1b10f8021a200610010c020b2006211b2019211c0c010b20021000221b450d030b201b200a4105746a220220032903f004370000200241186a2005290300370000200241106a200e290300370000200241086a200f290300370000200a41016a210a2009450d01201120044d0d03200c2011417f6a22114105746a220229000021082002290008210b20022900102112200c20044105746a220441186a200241186a290000370000200420123700102004200b370008200420083700000c010b418fc1c00021054116210420190d100c110b20034195056a20032903c806370000200341fd046a200341f8056a41086a29030037000020034185056a200341f8056a41106a2903003700002003418d056a200341f8056a41186a2903003700002003419d056a200341c8066a41086a290300370000200341a5056a200341c8066a41106a290300370000200341ad056a200341c8066a41186a290300370000200341013a00f404200341073a00f004200320032903f8053700f504200341bc056a2011360200200341b8056a200a360200200341b5056a20103a0000200341f0046a10b401200341f0046a109e02200341f0046a41086a2802002104024020032802f0042202450d0020032802f404450d00200210010b02400240200a20184f22050d0041002004410020021b220220116b2204200420024b1b2018490d002003418c056a201136020020034188056a201a36020020034180056a200a360200200341fc046a201c3602002003200c360284052003201b3602f804200320183602f404200320173602f004411510002202450d01200342153702f406200320023602f006200341f0066a41c3c0c00041151025200341e0036a220220032802f806360200200320032903f0063703d803200341c8066a200341d8036a101e20032802dc03210420032802d80322052002280200200341f0046a10a3022004450d0820051001201c0d090c0a0b024002402005450d00200341fd046a200341c8066a41086a29030037000020034185056a200341c8066a41106a2903003700002003418d056a200341e0066a290300370000200341023a00f404200341073a00f004200320032903c8063700f504200341f0046a10b401411910002202450d05200342193702f404200320023602f004200341f0046a41dfbfc00041191025200341f0066a41086a220220032802f804360200200320032903f0043703f006200341c8066a200341f0066a101e2002280200210420032802f406210520032802f0062102200341c8016a41086a22064200370300200342003703c80120022004200341c8016a1002200341b8016a41086a2006290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d01200342103702b4042003200341b8016a3602b004200341f0046a200341b0046a103820032802f0042206410d460d06200341f0066a200341f0046a410472220941cc0010f8021a200341f0046a41086a220a4200370300200342003703f00420022004200341f0046a1002200341b0046a41086a200a290300370300200320032903f0043703b004200341b0046a41101008200341d8036a200341f0066a41cc0010f8021a200341f0066a200341d8036a41cc0010f8021a02402005450d00200210010b200320063602f0042009200341f0066a41cc0010f8021a200341013a00d803200320183602dc03200341d0006a200341f0046a200341d8036a10cc0220034195056a2003280250453a0000200341fd046a200341c8066a41086a29030037000020034185056a200341c8066a41106a2903003700002003418d056a200341e0066a290300370000200341043a00f404200341073a00f004200320032903c8063700f504200341f0046a10b401411521024115100022040d080c110b200341fd046a200341d0066a29030037000020034185056a200341d8066a2903003700002003418d056a200341e0066a290300370000200341033a00f404200341073a00f004200320032903c8063700f504200341f0046a10b4010c060b200341d8036a200341f0066a41cc0010f8021a2005450d0520021001411521024115100022040d060c0f0b411541011019000b200241011019000b41c8acc20020042011104e000b411941011019000b41eac4c10041331042000b41152102411510002204450d090b200342153702f404200320043602f004200341f0046a41c3c0c00020021025200341f0066a41086a220220032802f804360200200320032903f0043703f006200341c8066a200341f0066a101e2002280200210520032802f406210620032802f0062104200341c8016a41086a22024200370300200342003703c80120042005200341c8016a1002200341b8016a41086a22052002290300370300200320032903c8013703b801200341b8016a4110100802402006450d00200410010b20024200370300200342003703c80141abc0c0004118200341c8016a100220052002290300370300200320032903c8013703b80141002106024002400240200341b8016a41104188f0c100410041001004417f460d00200342103702f4062003200341b8016a3602f006200341f0046a200341f0066a103620032802f0042202450d0a410021112002410120021b210f20032802f40421192002452117200341f0046a41086a280200410020021b2206450d02200341c8066a200f6b21104100210a200f210e41002111410021020340024002402011450d00200241057421040340200220064f0d0b20102004460d02200f20046a2205200341c8066a412010fa02450d02200a20026a220920064f0d0d200e20046a22092005290000370000200941186a200541186a290000370000200941106a200541106a290000370000200941086a200541086a290000370000200441206a21042006200241016a2202470d000c060b0b200f20024105746a21040340200220064f0d0a200341c8066a2004460d012004200341c8066a412010fa02450d01200441206a21042006200241016a2202470d000c040b0b200e41606a210e200a417f6a210a201141016a2111200241016a22022006470d000c030b0b4101210f410121170b410021110b200341003602f804200342013703f004200620116b2202200341f0046a101b024002402002450d00200641057420114105746b21104100200341f0046a41086a280200220e6b210920032802f004210a20032802f40421064100210203400240200620096a411f4b0d00200e20026a220541206a22042005490d0720064101742205200420042005491b22044100480d07200410002105024002402006450d002005450d0b2005200a20042006200620044b1b10f8021a200a10010c010b2005450d0a0b2005210a200421060b200a200e6a20026a2204200f20026a2205290000370000200441186a200541186a290000370000200441106a200541106a290000370000200441086a200541086a290000370000200941606a21092010200241206a2202470d000b200341f8046a200e20026a2204360200200320063602f4042003200a3602f0040c010b200341f8046a280200210420032802f404210620032802f004210a0b200341c8016a41086a22024200370300200342003703c80141abc0c0004118200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a4110200a2004100302402006450d00200a10010b2017201945720d00200f10010b201c450d010b201b10010b0240201a450d00200c10010b410021050c080b1018000b41b08dc20020022006104e000b200441011019000b41c08dc20020092006104e000b41eac4c10041331042000b200241011019000b200610010b201a450d0020032802b8031001200d4102460d010c020b200d4102470d010b200710a001200710010b4100210d4101210741012106410121094101210a4109211d0c010b200320083703f004200341c8016a41086a22024200370300200342003703c80141a0a5c100410d200341c8016a1002200341b8016a41086a22052002290300370300200320032903c8013703b801200341b8016a4110200341f0046a41081003200341013a00f00420024200370300200342003703c80141f2a1c1004113200341c8016a100220052002290300370300200320032903c8013703b801200341b8016a4110200341f0046a4101100320024200370300200342003703c80141daa3c1004115200341c8016a100220052002290300370300200320032903c8013703b8010240024002400240200341b8016a41104188f0c100410041001004417f460d00200342003703f004200341b8016a4110200341f0046a41084100100441016a41084d0d0220032903f004210b0c010b4205210b0b200341c8016a41086a22024200370300200342003703c80141cbbac1004112200341c8016a1002200341b8016a41086a22062002290300370300200320032903c8013703b8014100210541012107024002400240200341b8016a41104188f0c100410041001004417f460d00200342003703f004200341b8016a4110200341f0046a41084100100441016a41084d0d0220032903f0042112410021090c010b410121090b200320083703f00420024200370300200342003703c80141cbbac1004112200341c8016a100220062002290300370300200320032903c8013703b801200341b8016a4110200341f0046a41081003024002400240024002402012500d00024020090d00427f200b200b7c22132013200b541b220b4200510d042008200b8022082012200b80220b580d0302402008200b42017c2212510d00200341c8016a41086a22024200370300200342003703c80141c8f2c0004112200341c8016a1002200341b8016a41086a2002290300370300200320032903c8013703b801200341b8016a41104188f0c100410041001004417f460d06200342103702f4062003200341b8016a3602f006200341f0046a200341f0066a103620032802f0042211450d032011450d06200341f8046a280200220c450d062011410120111b211020032802f404211a2012a7200c70210f2008200b427f857ca722022002200c6e220e200c6c6b210d024002400240200c20024d0d00200e41016a220e450d0c41002102200f210541002107410041ff017122064101470d010c020b41002106200f21094100210a410021050340200521072006210520092102024002400240024002400240024002400240200a41ff017122064101460d0020064102470d012005200f490d040c050b2002200c4f0d054101210a200241016a21090c010b2002200c4f0d01200241016a21094100210a0b20052106200741016a2105200e2007200d496a2207450d060c050b2005200f4f0d030b200541016a21064102210a2002210920052102200741016a2105200e2007200d496a2207450d040c030b4102211d0c100b4102211d0c0f0b4102211d0c0e0b0240200c20024d0d00200341f0046a41186a201020024105746a220241186a290000370300200341f0046a41106a200241106a290000370300200341f0046a41086a200241086a290000370300200320022900003703f004200341f0046a200710ad010c010b0b4131211d0c0c0b4133211d0c0b0b4138211d0c0a0b4105211d0c090b4105211d0c080b4105211d0c070b41eac4c10041331042000b41e484c300104f000b41cc84c300104f000b418c85c300104f000b41eac4c10041331042000b41eac4c10041331042000b41002106417f2105200f210741002102024002400240024002400340024002400240200241ff017122024101460d0020024102470d012006200f490d020c040b2007200c4f0d0441012102200741016a2107200541016a2205200d490d020c060b02402007200c4f0d00200741016a210741002102200541016a2205200d490d020c070b2006200f4f0d040b200641016a210641022102200541016a2205200d490d000b4102211d0c050b4102211d0c040b4102211d0c030b4102211d0c020b4102211d0c010b4102211d0b03400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240201d0e3a050a3637380b0c0d0e0f101112171318192e2f30311a1b292a2b2c222324141516252627281c1d1e1f2d20213233343500390102040607030809090b200c20024d0d704132211d0c720b200741016a2107200341f0046a41186a201020024105746a220241186a290000370300200341f0046a41106a200241106a290000370300200341f0046a41086a200241086a290000370300200320022900003703f004200341f0046a200e10ad012009210520062102200a41ff017122064101460d384133211d0c710b20064102470d6f4137211d0c700b2002200f490d3b0c3c0b2005200c4f0d394100211d0c6e0b200541016a21094100210a0c370b2002200f4f0d3b4136211d0c6c0b200241016a21064102210a200521092007200d490d330c340b2005200c4f0d384139211d0c6a0b4101210a200541016a21094101211d0c690b20022106200521022007200d490d380c390b410121064106211d0c670b410121094107211d0c660b4101210a4108211d0c650b4101210d4109211d0c640b4101210c410a211d0c630b4101210e410b211d0c620b4101210f20012802002202410b4b0d36410c211d0c610b024020020e0c003700000038393a3b3c003d000b410e211d0c600b2000200436020420002005360200200341e0076a24000f0b200a450d48411f211d0c5e0b200141086a2d00004102470d484120211d0c5d0b2001410c6a22012802001028200128020010010c480b200e450d38410f211d0c5b0b200141086a2d000022024102490d384110211d0c5a0b20024102470d544115211d0c590b200141306a280200450d374116211d0c580b2001412c6a28020010010c370b2006450d474126211d0c560b200141086a2d000022024105460d524127211d0c550b20024102470d464128211d0c540b2001410c6a22012802001028200128020010010c460b2007450d47412b211d0c520b200141086a10290c470b200d450d37411c211d0c500b20012d00044102470d37411d211d0c4f0b2001410c6a22012802001028200128020010010c370b2009450d3a4122211d0c4d0b200141086a2802004102470d3a4123211d0c4c0b200141106a280200450d3a4124211d0c4b0b2001410c6a28020010010c3a0b200c450d2c4118211d0c490b20012802044102490d2c4119211d0c480b2001410c6a280200450d2c411a211d0c470b200141086a28020010010c2c0b2001410c6a22012802001028200128020010010c390b200141106a280200450d404112211d0c440b2001410c6a28020010014113211d0c430b2001411c6a280200450d234114211d0c420b200141186a28020010010c230b200f450d37412d211d0c400b20012d00044102470d37412e211d0c3f0b2001410c6a280200450d37412f211d0c3e0b200141086a28020010010c370b41002105410121072011450d0e4103211d0c3c0b201a450d0e4104211d0c3b0b201010010c0e0b41fc84c3002002200c104e000b4138211d0c380b4130211d0c370b4102211d0c360b4101211d0c350b4135211d0c340b4136211d0c330b4102211d0c320b4102211d0c310b4102211d0c300b4130211d0c2f0b4102211d0c2e0b4105211d0c2d0b4105211d0c2c0b4105211d0c2b0b412c211d0c2a0b412a211d0c290b4125211d0c280b4121211d0c270b411e211d0c260b411b211d0c250b4117211d0c240b410d211d0c230b410e211d0c220b410e211d0c210b410e211d0c200b410e211d0c1f0b410e211d0c1e0b410e211d0c1d0b410e211d0c1c0b410e211d0c1b0b410e211d0c1a0b410e211d0c190b410e211d0c180b410e211d0c170b410e211d0c160b410e211d0c150b410e211d0c140b410e211d0c130b410e211d0c120b410e211d0c110b410e211d0c100b410e211d0c0f0b410e211d0c0e0b410e211d0c0d0b410e211d0c0c0b410e211d0c0b0b410e211d0c0a0b410e211d0c090b410e211d0c080b410e211d0c070b410e211d0c060b410e211d0c050b4111211d0c040b4113211d0c030b4129211d0c020b4131211d0c010b4134211d0c000b0bf710010a7f230041d0006b2203240002402001280200417e6a220441054b0d000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020040e06000402030105000b200241096a2800002104200241056a2800002105200141086a280200210620022d0001210720022d0000210820012802042109200341cc006a41026a220a200241046a2d00003a0000200341106a41086a220b200241156a290000370300200341106a410d6a220c2002411a6a2900003700002003200241026a2f01003b014c20032002410d6a29000037031020080d07200341c8006a41026a200a2d00003a0000200341306a41086a200b290300370300200341306a410d6a200c290000370000200320032f014c3b01482003200329031037033041012108200741ff01714101470d07200341106a41026a200341c8006a41026a2d00003a0000200341236a200341386a290300370000200341286a2003413d6a2900003700002003200436001720032005360013200320032f01483b01102003200329033037001b02402006450d00200910010b4100210a41012106410121090c0c0b41002108200141086a28020021042001280204210a41efeec10041efeec1004100410320022d000120022d00001b41ff017122021b20024103461b2207450d07410121062004450d04200a10010c040b200241096a2800002104200241056a2800002105200141086a280200210a20022d0001210720022d0000210820012802042106200341cc006a41026a2209200241046a2d00003a0000200341106a41086a220b200241156a290000370300200341106a410d6a220c2002411a6a2900003700002003200241026a2f01003b014c20032002410d6a29000037031020080d04200341c8006a41026a20092d00003a0000200341306a41086a200b290300370300200341306a410d6a200c290000370000200320032f014c3b01482003200329031037033041012108200741ff01714101470d04200341106a41026a200341c8006a41026a2d00003a0000200341236a200341386a290300370000200341286a2003413d6a2900003700002003200436001720032005360013200320032f01483b01102003200329033037001b0240200a450d00200610010b41002109410121064101210a0c0a0b410121064101210841efeec10041efeec1004100410320022d000120022d00001b41ff017122021b20024103461b22070d02200341106a200141086a2903001088014184c4c100410a200328021022022003280218100302402003280214450d00200210010b410021074101210841012106410121094101210a0c0a0b4100210741c1efc100410041c1efc100410320022d000120022d00001b41ff017122024102461b20024103461b2202450d05412d21044101210841012106410121094101210a200221070c090b2001410c6a2802002108200141086a28020021092001280204210a41efeec10041efeec1004100410320022d000120022d00001b41ff017122021b20024103461b2207450d0502402008450d00200841186c2104200a210203400240200241046a280200450d00200228020010010b0240200241106a280200450d002002410c6a28020010010b200241186a2102200441686a22040d000b0b41012108410021062009450d00200a10010b412821042001280200417e6a220241054b0d08024020020e0600100d090e0f000b200141086a280200450d0f200128020410010c0f0b412a210441002109410121084197efc10021070240200a450d00200610010b410121064101210a0c060b412a21044100210a410121084197efc100210702402006450d00200910010b41012106410121090c050b41d9c1c1004105200a2001410c6a28020010034101210802402004450d00200a10010b410021060c020b200341086a10f00141012108024020032802084101470d0041012106410121094101210a200328020c4101460d040b200341246a41013602002003411c6a410136020020034103360234200341dcc3c100360230200341e0c3c10036021820034102360214200341a08ac3003602102003200341306a360220200341106a41b08ac3001071000b02402008450d00200a200841186c6a2104200a210203402002280200200241086a2802002002410c6a280200200241146a2802001003200241186a22022004470d000b2008450d00200841186c2104200a210203400240200241046a280200450d00200228020010010b0240200241106a280200450d002002410c6a28020010010b200241186a2102200441686a22040d000b0b4101210602402009450d00200a10010b410021080b410121094101210a0b410021070b2001280200417e6a220241054b0d00024020020e06000802010304000b200a450d07200141086a280200450d07200128020410010c070b200110290c060b2009450d05200141086a280200450d05200128020410010c050b2006450d04200141086a280200450d04200128020410010c040b2008450d0302402001410c6a2802002208450d0020012802042102200841186c210803400240200241046a280200450d00200228020010010b0240200241106a280200450d002002410c6a28020010010b200241186a2102200841686a22080d000b0b200141086a280200450d03200141046a28020010010c030b200141086a280200450d02200128020410010c020b2008450d01200141086a280200450d01200128020410010c010b2006450d0002402001410c6a2802002208450d0020012802042102200841186c210803400240200241046a280200450d00200228020010010b0240200241106a280200450d002002410c6a28020010010b200241186a2102200841686a22080d000b0b200141086a280200450d00200141046a28020010010b2000200436020420002007360200200341d0006a24000f0b41888ac300104f000b9d0301077f230041306b22022400024002400240024002400240411010002203450d002002421037022420022003360220200241206a41c785c2004110102520022802202103024002400240024020022802242204200228022822056b41044f0d00200541046a22062005490d0520044101742207200620062007491b22074100480d052004450d01200710002208450d072008200320072004200420074b1b10f802210420031001200421030c020b200541046a21060c020b200710002203450d050b200721040b200320056a2001360000200241206a41086a220542003703002002420037032020032006200241206a1002200241086a2005290300370300200220022903203703000240200241104188f0c100410041001004417f460d002002421037021420022002360210200241206a200241106a103620022802202205450d0320002002290224370204200020053602002004450d060c050b200041003602082000420137020020040d040c050b411041011019000b1018000b41eac4c10041331042000b200741011019000b200310010b200241306a24000b960201097f230041106b220124002001109e0220012802002202410820021b2203200141086a280200410020021b220441286c6a21052001280204210620032107024002400340200520076b419f014d0d014101210820072000460d0220072000412010fa02450d02200741286a22092000460d0220092000412010fa02450d02200741d0006a22092000460d0220092000412010fa02450d02200741f8006a22092000460d02200741a0016a210720092000412010fa020d000c020b0b024020052007460d002003200441286c6a210903404101210820002007460d0220072000412010fa02450d022009200741286a2207470d000b0b410021080b02402002450d002006450d00200310010b200141106a240020080b82b901090b7f047e047f017e037f027e047f027e0f7f230041e0036b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280200417e6a220441084b0d0002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020040e09000502030106070408000b2001410c6a2802002105200141086a2802002106200141106a280200210720012802042108200241096a2800002104200241056a280000210920022d0001210a20022d00002101200341f0026a41026a220b200241046a2d00003a0000200341c8016a41086a220c200241156a290000370300200341c8016a410d6a220d2002411a6a2900003700002003200241026a2f01003b01f00220032002410d6a2900003703c80120010d0f20034198036a41026a200b2d00003a0000200341b8026a41086a200c290300370300200341b8026a410d6a200d290000370000200320032f01f0023b019803200320032903c8013703b802200a41ff01714101470d0f200341db016a200341b8026a41086a290300220e370000200341e0016a200341b8026a410d6a290000220f370000200341d8026a41026a20034198036a41026a2d000022013a0000200341f0026a41086a200e370300200341f0026a410d6a200f370000200320043600cf01200320093600cb01200320032f01980322023b01c801200320032903b802220e3700d301200320023b01d8022003200e3703f002200320013a00ca01410021010c100b200141386a2903002110200141306a2903002111200141286a2802002112200341a4016a41026a200141076a2d00003a000020034188016a41086a200141186a29020037030020034188016a410d6a2001411d6a290000370000200320012f00053b01a4012003200141106a29020037038801200141086a28020021092001410c6a280200210820012d0004210b200241096a2800002104200241056a280000210620022d0001210c20022d0000210a200341b8036a41026a220d200241046a2d00003a0000200341c8016a41086a2207200241156a290000370300200341c8016a410d6a22052002411a6a2900003700002003200241026a2f01003b01b80320032002410d6a2900003703c801200a0d0820034198036a41026a200d2d00003a0000200341a8016a41086a2007290300370300200341a8016a410d6a2005290000370000200320032f01b8033b019803200320032903c8013703a801200c41ff01714101470d08200341db016a200341a8016a41086a290300220e370000200341e0016a200341a8016a410d6a290000220f370000200341d8026a41026a20034198036a41026a2d000022023a0000200341b8036a41086a200e370300200341b8036a410d6a200f370000200320043600cf01200320063600cb01200320032f019803220a3b01c801200320032903a801220e3700d3012003200a3b01d8022003200e3703b803200320023a00ca01410021020c090b2001280204210d200241096a2800002104200241056a280000210620022d0001210820022d00002109200341f0026a41026a220a200241046a2d00003a0000200341c8016a41086a220b200241156a290000370300200341c8016a410d6a220c2002411a6a2900003700002003200241026a2f01003b01f00220032002410d6a2900003703c80120090d0920034198036a41026a200a2d00003a0000200341b8026a41086a200b290300370300200341b8026a410d6a200c290000370000200320032f01f0023b019803200320032903c8013703b802200841ff01714101470d09200341db016a200341b8026a41086a290300220e370000200341e0016a200341b8026a410d6a290000220f370000200341d8026a41026a20034198036a41026a2d000022023a0000200341f0026a41086a200e370300200341f0026a410d6a200f370000200320043600cf01200320063600cb01200320032f01980322093b01c801200320032903b802220e3700d301200320093b01d8022003200e3703f002200320023a00ca01410021020c0a0b20012802042108200241096a2800002104200241056a280000210620022d0001210a20022d00002109200341f0026a41026a220b200241046a2d00003a0000200341c8016a41086a220c200241156a290000370300200341c8016a410d6a220d2002411a6a2900003700002003200241026a2f01003b01f00220032002410d6a2900003703c80120090d0a20034198036a41026a200b2d00003a0000200341b8026a41086a200c290300370300200341b8026a410d6a200d290000370000200320032f01f0023b019803200320032903c8013703b802200a41ff01714101470d0a200341db016a200341b8026a41086a290300220e370000200341e0016a200341b8026a410d6a290000220f370000200341d8026a41026a20034198036a41026a2d000022023a0000200341f0026a41086a200e370300200341f0026a410d6a200f370000200320043600cf01200320063600cb01200320032f01980322093b01c801200320032903b802220e3700d301200320093b01d8022003200e3703f002200320023a00ca01410021020c0b0b4100210641efeec10041efeec1004100410320022d000120022d00001b41ff017122021b20024103461b22090d042003200141086a2903003703b803200341c8016a41086a22024200370300200342003703c801419ac7c100411c200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802200341b8026a4110200341b8036a410810030c6b0b200141306a28020021122001412c6a280200211320012802042114200341a4016a41026a2001410b6a2d00003a000020034188016a41086a2001411c6a29020037030020034188016a410d6a200141216a290000370000200320012f00093b01a4012003200141146a29020037038801200141086a2d0000210b2001410c6a2802002109200141106a2802002108200241096a2800002104200241056a280000210620022d0001210c20022d0000210a200341b8036a41026a220d200241046a2d00003a0000200341c8016a41086a2207200241156a290000370300200341c8016a410d6a22052002411a6a2900003700002003200241026a2f01003b01b80320032002410d6a2900003703c801200a0d0c20034198036a41026a200d2d00003a0000200341a8016a41086a2007290300370300200341a8016a410d6a2005290000370000200320032f01b8033b019803200320032903c8013703a801200c41ff01714101470d0c200341db016a200341a8016a41086a290300220e370000200341e0016a200341a8016a410d6a290000220f370000200341d8026a41026a20034198036a41026a2d000022023a0000200341b8036a41086a200e370300200341b8036a410d6a200f370000200320043600cf01200320063600cb01200320032f019803220a3b01c801200320032903a801220e3700d3012003200a3b01d8022003200e3703b803200320023a00ca01410021020c0d0b4100210641efeec10041efeec1004100410320022d000120022d00001b41ff017122021b20024103461b22090d02200320012802043602b803200341c8016a41086a22024200370300200342003703c80141c9c6c1004114200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802200341b8026a4110200341b8036a410410030c690b200341d4026a41026a2208200141076a2d00003a0000200341d8026a41086a220a200141186a290200370300200341d8026a410d6a220b2001411d6a290000370000200320012f00053b01d4022003200141106a2902003703d80241efeec10041efeec1004100410320022d000120022d00001b41ff017122021b20024103461b22090d012001410c6a2802002104200141086a280200210620012d0004210220034188016a41026a20082d00003a0000200341b8026a41086a200a290300370300200341b8026a410d6a200b290000370000200320032f01d4023b018801200320032903d8023703b802200241ff01714101470d12200341c8016a200641067610ce0220032802d0012006413f7122024d0d17200341b4036a41026a220920032802c801220b20024105746a220241026a2d00003a000020034198036a41086a2208200241136a29000037030020034198036a410d6a220a200241186a290000370000200320022f00003b01b4032003200229000b370398032002280007210420022800032106024020032802cc01450d00200b10010b200341c8016a41136a2008290300220e370000200341c8016a41186a200a290000220f37000020034194036a41026a20092d000022023a0000200341b8036a41086a200e370300200341b8036a410d6a200f370000200320043600cf01200320063600cb01200320023a00ca01200320032f01b40322023b01c8012003200329039803220e3700d301200320023b0194032003200e3703b803410021020c180b4100210641efeec10041efeec1004100410320022d000120022d00001b41ff017122021b20024103461b2209450d0b0b412821040c6b0b41012102412a21044197efc10021060b200341b4036a41026a220a200341d8026a41026a2d00003a0000200341b8026a41086a220c200341b8036a41086a290300370300200341b8026a41106a200341b8036a41106a290300370300200320032f01d8023b01b403200320032903b8033703b80220020d5f200341f0026a41136a200c290300370000200341f0026a41186a200341b8026a410d6a2202290000370000200320032f01b4033b01f002200320043600f702200320063600f302200320032903b8023700fb022003200a2d00003a00f20220034194036a41026a200341a4016a41026a2d00003a0000200341d8026a41086a20034188016a41086a290300370300200341d8026a410d6a220420034188016a410d6a290000370000200320032f01a4013b01940320032003290388013703d802200b41ff01714101470d09200341c8016a200941067610ce0220032802d0012009413f7122024d0d0f200341b4036a41026a220420032802c801220b20024105746a220241026a2d00003a000020034198036a41086a2206200241136a29000037030020034198036a410d6a220a200241186a290000370000200320022f00003b01b4032003200229000b370398032002280007210820022800032109024020032802cc01450d00200b10010b200341c8016a41136a2006290300220e370000200341c8016a41186a200a290000220f370000200341d4026a41026a20042d000022023a0000200341b8026a41086a200e370300200341b8026a410d6a200f370000200320083600cf01200320093600cb01200320023a00ca01200320032f01b40322023b01c8012003200329039803220e3700d301200320023b01d4022003200e3703b802410021020c100b410121024197efc1002106412a21040b200341c4016a41026a2209200341d8026a41026a2d00003a0000200341a8016a41086a2208200341f0026a41086a290300370300200341a8016a41106a200341f0026a41106a290300370300200320032f01d8023b01c401200320032903f0023703a80120020d5d200341cb036a2008290300370000200341d0036a200341b5016a290000370000200320032f01c4013b01b803200320043600bf03200320063600bb03200320032903a8013700c303200320092d00003a00ba03200341c8016a41086a22024200370300200342003703c80141f2c6c1004114200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802200341b8026a4110100e450d0941dceac10021060c640b410121024197efc1002106412a21040b200341c4016a41026a2209200341d8026a41026a2d00003a0000200341a8016a41086a220a200341f0026a41086a290300370300200341a8016a41106a200341f0026a41106a290300370300200320032f01d8023b01c401200320032903f0023703a80120020d5b200341cb036a200a290300370000200341d0036a200341b5016a290000370000200320032f01c4013b01b803200320043600bf03200320063600bb03200320032903a8013700c303200320092d00003a00ba03411610002202450d2f200342163702cc01200320023602c801200341c8016a4181c8c10041161025200341f0026a41086a220220032802d001360200200320032903c8013703f002200341b8036a200341f0026a101e2002280200210420032802f402210620032802f0022102200341c8016a41086a22094200370300200342003703c80120022004200341c8016a1002200341b8026a41086a2009290300370300200320032903c8013703b802200341b8026a4110100e210402402006450d00200210010b2004450d0941c3ebc10021060c620b410121014197efc1002109412a21040b200341c4016a41026a2202200341d8026a41026a2d00003a0000200341a8016a41086a220a200341f0026a41086a290300370300200341a8016a41106a200341f0026a41106a290300370300200320032f01d8023b01c401200320032903f0023703a801024020010d00200341cb036a200a290300370000200341d0036a200341b5016a290000370000200320032f01c4013b01b803200320043600bf03200320093600bb03200320032903a8013700c303200320022d00003a00ba03200341c8016a41086a22014200370300200342003703c80141f2c6c1004114200341c8016a1002200341b8026a41086a2001290300370300200320032903c8013703b802200341b8026a4110100e450d074186e8c1002109412e21040b2006450d630c5f0b410121024197efc1002106412a21040b200341b4036a41026a220a200341d8026a41026a2d00003a0000200341b8026a41086a220c200341b8036a41086a290300370300200341b8026a41106a200341b8036a41106a290300370300200320032f01d8023b01b403200320032903b8033703b80220020d57200341f0026a41136a200c290300370000200341f0026a41186a200341b8026a410d6a2202290000370000200320032f01b4033b01f002200320043600f702200320063600f302200320032903b8023700fb022003200a2d00003a00f20220034194036a41026a200341a4016a41026a2d00003a0000200341d8026a41086a20034188016a41086a290300370300200341d8026a410d6a220420034188016a410d6a290000370000200320032f01a4013b01940320032003290388013703d802200b41ff01714101470d02200341c8016a200941067610ce0220032802d0012009413f7122024d0d09200341b4036a41026a220420032802c801220b20024105746a220241026a2d00003a000020034198036a41086a2206200241136a29000037030020034198036a410d6a220a200241186a290000370000200320022f00003b01b4032003200229000b370398032002280007210820022800032109024020032802cc01450d00200b10010b200341c8016a41136a2006290300220e370000200341c8016a41186a200a290000220f370000200341d4026a41026a20042d000022023a0000200341b8026a41086a200e370300200341b8026a410d6a200f370000200320083600cf01200320093600cb01200320023a00ca01200320032f01b40322023b01c8012003200329039803220e3700d301200320023b01d4022003200e3703b802410021020c0a0b2003200141086a2903003703b803200341c8016a41086a22024200370300200342003703c8014186c7c1004114200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802200341b8026a4110200341b8036a410810030c5b0b200341c8016a41026a20034194036a41026a2d000022063a0000200341c8016a41136a200341d8026a41086a290300220e370000200341c8016a41186a2004290000220f370000200341d4026a41026a20063a0000200341b8026a41086a200e3703002002200f370000200320083600cf01200320093600cb01200320032f01940322023b01c801200320032903d802220e3700d301200320023b01d4022003200e3703b802410021020c060b200341c8016a41026a20034194036a41026a2d000022063a0000200341c8016a41136a200341d8026a41086a290300220e370000200341c8016a41186a2004290000220f370000200341d4026a41026a20063a0000200341b8026a41086a200e3703002002200f370000200320083600cf01200320093600cb01200320032f01940322023b01c801200320032903d802220e3700d301200320023b01d4022003200e3703b802410021020c070b411410002202450d2c200342143702cc01200320023602c801200341c8016a41c8e8c10041141025200341f0026a41086a220220032802d001360200200320032903c8013703f002200341b8036a200341f0026a101e2002280200210420032802f402210620032802f0022102200341c8016a41086a22094200370300200342003703c80120022004200341c8016a1002200341b8026a41086a2009290300370300200320032903c8013703b802200341b8026a4110100e210402402006450d00200210010b2004450d0a200341c8016a41086a22024200370300200342003703c80141b6c7c100410e200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802200341b8026a41104188f0c100410041001004417f460d12200342103702f4022003200341b8026a3602f002200341c8016a200341f0026a103620032802c8012202450d35200341d0016a280200210420032802cc0121060c130b200341c8016a41086a22014200370300200342003703c80141bfc8c1004111200341c8016a1002200341b8026a41086a2001290300370300200320032903c8013703b802410021010240200341b8026a41104188f0c100410041001004417f460d00200341003602c801200341b8026a4110200341c8016a41044100100441016a41044d0d2520032802c80121010b20072001470d08411410002201450d31200342143702cc01200320013602c801200341c8016a41c8e8c10041141025200341f0026a41086a220120032802d001360200200320032903c8013703f002200341b8036a200341f0026a101e2001280200210220032802f402210420032802f0022101200341c8016a41086a22094200370300200342003703c80120012002200341c8016a1002200341b8026a41086a2009290300370300200320032903c8013703b802200341b8026a4110100e210202402004450d00200110010b2002450d130c530b200341c8016a41086a22044200370300200342003703c80141a9c8c1004116200341c8016a1002200341b8026a41086a22062004290300370300200320032903c8013703b802410021024100210d0240200341b8026a41104188f0c100410041001004417f460d00200341003602c801200341b8026a4110200341c8016a41044100100441016a41044d0d2520032802c801210d0b20044200370300200342003703c8014197c8c1004112200341c8016a100220062004290300370300200320032903c8013703b802200341b8026a41104188f0c100410041001004417f460d09200342103702f4022003200341b8026a3602f002200341c8016a200341f0026a103620032802c8012202450d2d200341d0016a280200210420032802cc0121060c0a0b200341c8016a41026a20034188016a41026a2d000022023a0000200341db016a200341b8026a41086a290300220e370000200341e0016a200341b8026a410d6a290000220f37000020034194036a41026a20023a0000200341b8036a41086a200e370300200341b8036a410d6a200f370000200320043600cf01200320063600cb01200320032f01880122023b01c801200320032903b802220e3700d301200320023b0194032003200e3703b803410021020c050b024020032802cc01450d0020032802c80110010b4101210241152108418987c20021090b200341c4016a41026a2204200341d4026a41026a2d00003a0000200341a8016a41086a2206200341b8026a41086a220a290300370300200341a8016a41106a200341b8026a41106a290300370300200320032f01d4023b01c401200320032903b8023703a80102402002450d00200821042009210620012802004102460d570c580b200341cb036a2006290300370000200341d0036a200341b5016a290000370000200320032f01c4013b01b803200320083600bf03200320093600bb03200320032903a8013700c303200320042d00003a00ba03200341c8016a41086a22024200370300200342003703c8014111210441bfc8c1004111200341c8016a1002200a2002290300370300200320032903c8013703b802410021020240200341b8026a41104188f0c100410041001004417f460d00200341003602c801200341b8026a4110200341c8016a41044100100441016a41044d0d2020032802c80121020b4195ecc100210620122002470d4e200341c8016a41086a22024200370300200342003703c80141f2c6c1004114200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802200341b8026a41104188f0c100410041001004417f460d0a2003200341b8026a3602a801200341103602ac01200342003703c80120034100200341b8026a4110200341c8016a41084100100422022002417f461b22024108200241084922041b22023602b00120040d26200341003602c801200341b0016a4100200341b8026a4110200341c8016a41042002100422042004417f461b22044104200441044922041b20026a36020020040d26200341c8016a200341a8016a103620032802c8012215450d2620032902cc012116200341c8016a41086a22144200370300200342003703c80141c4c7c1004118200341c8016a1002200341b8026a41086a22132014290300370300200320032903c8013703b802200341b8026a41104188f0c100410041001004417f460d10200342103702ac012003200341b8026a3602a80120034180016a200341a8016a1035200328028001450d1e200328028401220bad220e421c88a70d3a200e420486a72202417f4c0d3a2002450d142002100022080d15200241081019000b024020032802cc01450d0020032802c80110010b41012102418987c2002109411521080b200341c4016a41026a2204200341d4026a41026a2d00003a0000200341a8016a41086a2206200341b8026a41086a220a290300370300200341a8016a41106a200341b8026a41106a290300370300200320032f01d4023b01c401200320032903b8023703a80102402002450d00200821042009210620012802004102460d550c560b200341cb036a2006290300370000200341d0036a200341b5016a290000370000200320032f01c4013b01b803200320083600bf03200320093600bb03200320032903a8013700c303200320042d00003a00ba03200341c8016a41086a22024200370300200342003703c80141f2c6c1004114200341c8016a1002200a2002290300370300200320032903c8013703b8020240200341b8026a4110100e450d004181e9c10021064126210420012802004102460d550c560b411410002202450d2c200342143702cc01200320023602c801200341c8016a41c8e8c10041141025200341b8026a41086a220220032802d001360200200320032903c8013703b802200341f0026a200341b8026a101e2002280200210620032802bc02210920032802b8022104200341c8016a41086a22084200370300200342003703c80120042006200341c8016a100220022008290300370300200320032903c8013703b802410021020240200341b8026a41104188f0c100410041001004417f460d00200341003602c80141012102200341b8026a4110200341c8016a41044100100441016a41044d0d240b02402009450d00200410010b2002450d09411410002202450d31200342143702cc01200320023602c801200341c8016a41c8e8c10041141025200341b8026a41086a220220032802d001360200200320032903c8013703b802200341b8036a200341b8026a101e2002280200210620032802bc02210920032802b8022104200341c8016a41086a22084200370300200342003703c80120042006200341c8016a100220022008290300370300200320032903c8013703b80241002102200341b8026a41104188f0c100410041001004417f460d15200341003602c80141012102200341b8026a4110200341c8016a41044100100441016a41044d0d2620032802c80121082009450d4a0c490b024020032802cc01450d0020032802c80110010b4101210241152104418987c20021060b200341c4016a41026a220920034194036a41026a2d00003a0000200341a8016a41086a2208200341b8036a41086a290300370300200341a8016a41106a200341b8036a41106a290300370300200320032f0194033b01c401200320032903b8033703a80120020d4a20034183036a2008290300370000200341f0026a41186a200341b5016a290000370000200320032f01c4013b01f002200320043600f702200320063600f302200320032903a8013700fb02200320092d00003a00f202200341c8016a109e024100210420032802cc01410020032802c80122021b21152002410820021b21050240200341c8016a41086a280200410020021b41286c2206450d000340200341c8016a41206a200520046a220241206a290300370300200341c8016a41186a200241186a290300370300200341c8016a41106a200241106a290300370300200341c8016a41086a200241086a290300370300200320022903003703c801200341c8016a200341f0026a412010fa020d062006200441286a2204470d000b0b4100210c410821072015450d05200510014100210d0c0f0b41b4e8c10021094114210420060d4f0c530b41faeac10021060c060b0b2006410020021b21072004410020021b21092002410120021b210202402008200d470d0020082009460d380b41e1ebc100210641162104200820094f0d38200341e0016a4200370300200341d8016a4200370300200341d0016a4200370300200342003703c801200220084105746a220a200341c8016a460d37200a200341c8016a412010fa020d380c370b200341b8036a41206a2209200341c8016a41206a290300370300200341b8036a41186a2208200341c8016a41186a290300370300200341b8036a41106a220a200341c8016a41106a290300370300200341b8036a41086a220b200341c8016a41086a290300370300200320032903c8013703b803412810002207450d28200720032903b803370300200741206a2009290300370300200741186a2008290300370300200741106a200a290300370300200741086a200b290300370300200641586a2004460d08200241286a2102200620046b41b07f6a21064101210c4101210d0340200341c8016a41206a2209200241206a290300370300200341c8016a41186a2208200241186a290300370300200341c8016a41106a220a200241106a290300370300200341c8016a41086a220b200241086a290300370300200320022903003703c80102400240024002400240200341c8016a200341f0026a412010fa02450d00200341b8036a41206a22042009290300370300200341b8036a41186a22122008290300370300200341b8036a41106a2214200a290300370300200341b8036a41086a2213200b290300370300200320032903c8013703b8032009200429030037030020082012290300370300200a2014290300370300200b2013290300370300200320032903b8033703c801200d200c470d03200c41016a2204200c490d3f200c4101742212200420042012491b2212ad42287e220e422088a70d3f200ea722044100480d3f200c450d01200410002214450d21201420072004200c41286c220c200c20044b1b10f802210420071001200421070c020b20060d030c0e0b200410002207450d1f0b2012210c0b2007200d41286c6a220420032903c801370300200441206a2009290300370300200441186a2008290300370300200441106a200a290300370300200441086a200b290300370300200d41016a210d2006450d0b0b200241286a2102200641586a21060c000b0b4100210d0c090b41a6ecc1002106412d210420012802004102460d4b0c4c0b41a7e9c10021060b4118210420012802004102460d490c4a0b410021020b2006410020021b21082002410120021b2109024002400240200d2004410020021b22024f0d002009200d4105746a2204200341b8036a460d022004200341b8036a412010fa02450d0241aaebc10021064119210420080d010c420b4192ebc1002106411821042008450d410b2009100120012802004102460d480c490b200320023602d001200320083602cc01200320093602c801200341b8036a200d200341c8016a10ef024200210e200341c8016a41086a22024200370300200342003703c80141dce8c1004112200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b80241002106200341b8026a41104188f0c100410041001004417f460d09200342003703d001200342003703c801200341b8026a4110200341c8016a4110410010042202417f460d252002410f4d0d25200341d0016a290300210f20032903c801210e0c0a0b4200210e200341c8016a41086a22014200370300200342003703c80141dce8c1004112200341c8016a1002200341b8026a41086a2001290300370300200320032903c8013703b802200341b8026a41104188f0c100410041001004417f460d0a200342003703d001200342003703c801200341b8026a4110200341c8016a4110410010042201417f460d252001410f4d0d25200341d0016a290300210f20032903c801210e0c0b0b410021084100211741002118410021194100210a0c050b4101210c4101210d0b2015450d00200510010b2003200d3602d0012003200c3602cc01200320073602c801200341c8016a10a1020240200c450d00200710010b410021060c3a0b410821080b02400240200b450d00200341a8016a41086a220c280200210420032802ac01210d20032802a801210741002106200b2102410021090340200342003703d001200342003703c801200c41002007200d200341c8016a411020041004220a200a417f461b220a4110200a411049220a1b20046a2204360200200a0d0a200341c8016a41086a290300210e20032903c801210f024020092002470d00200241016a220a2002490d3020024101742205200a200a2005491b2205ad420486221a422088a70d30201aa7220a4100480d30024002402002450d00200a10002212450d1320122008200a200241047422022002200a4b1b10f802210220081001200221080c010b200a10002208450d120b200521020b200820066a220a200e370308200a200f370300200641106a2106200941016a2209200b490d000c020b0b41002102410021090b2008450d082008211720082118200821192008210a0b20144200370300200342003703c80141b6c7c100410e200341c8016a100220132014290300370300200320032903c8013703b80202400240200341b8026a41104188f0c100410041001004417f460d00200342103702ac012003200341b8026a3602a801200341c8016a200341a8016a103620032802c8012204450d1d200341d0016a280200210620032802cc01210c0c010b410021040b4200210e200341c8016a41086a220b4200370300200342003703c80141aeeec100411c200341c8016a1002200341b8026a41086a200b290300370300200320032903c8013703b80202400240200341b8026a41104188f0c100410041001004417f460d00200342003703d001200342003703c801200341b8026a4110200341c8016a411041001004220b417f460d16200b410f4d0d16200341d0016a290300210e20032903c801210f0c010b4201210f0b4200211a200341f0006a200f200e2006410020041b2214ad420010fc02411410002206450d18200341f0006a41086a290300210e2003290370211b200342143702cc01200320063602c801200341c8016a41eeefc10041141025200341b8026a41086a220620032802d001360200200320032903c8013703b802200341f0026a200341b8026a101e2006280200210d20032802bc02210720032802b802210b200341c8016a41086a22054200370300200342003703c801200b200d200341c8016a100220062005290300370300200320032903c8013703b8020240200341b8026a41104188f0c100410041001004417f460d00200342003703d001200342003703c801200341b8026a4110200341c8016a4110410010042206417f460d162006410f4d0d16200341d0016a290300210f20032903c801211a410121062007450d230c220b4200210f4101210620070d210c220b20090d330c340b4200210f0b200341b8036a200e200f10e1020c390b4200210f0b2003200341b8036a200e200f10d202024020032802002209450d002003280204210420060d390c3d0b200341c8016a41086a22014200370300200342003703c80141b6c7c100410e200341c8016a1002200341b8026a41086a2001290300370300200320032903c8013703b80202400240200341b8026a41104188f0c100410041001004417f460d00200342103702f4022003200341b8026a3602f002200341c8016a200341f0026a103620032802c8012202450d1c200341d0016a280200210920032802cc01210a0c010b410021020b200341c8016a41186a220b200341b8036a41186a290300370300200341c8016a41106a200341b8036a41106a2903003703002001200341b8036a41086a290300370300200320032903b8033703c8012002410120021b21040240024002402009410020021b2201200a410020021b2214470d00200141016a22022001490d2920014101742209200220022009491b2214ad420586220e422088a70d29200ea722024100480d292001450d01200210002212450d1e20122004200220014105742209200920024b1b10f8021a200410010c020b200421120c010b200210002212450d1c0b2012200141057422046a220220032903c801370000200241186a200b290300370000200241106a200341c8016a41106a290300370000200241086a200341c8016a41086a2202290300370000200341003602d001200342013703c801200141016a2201200341c8016a101b024002402001450d00200441206a210c4100200228020022026b210a20032802c801210b20032802cc0121092012210d0340200d210102402009200a6a411f4b0d00200241206a22042002490d2a2009410174220d20042004200d491b22044100480d2a20041000210d024002402009450d00200d450d13200d200b20042009200920044b1b10f8021a200b10010c010b200d450d120b200d210b200421090b200141206a210d200b20026a22042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a290000370000200a41606a210a200241206a2102200c41606a220c0d000b200341d0016a2002360200200320093602cc012003200b3602c8010c010b2002280200210220032802cc01210920032802c801210b0b200341c8016a41086a22014200370300200342003703c80141b6c7c100410e200341c8016a1002200341b8026a41086a2001290300370300200320032903c8013703b802200341b8026a4110200b2002100302402009450d00200b10010b2014450d3320121001411421014114100022020d340c350b41e89fc300104f000b2002450d00200810010b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b411641011019000b200a41081019000b200441081019000b41eac4c10041331042000b41eac4c10041331042000b411441011019000b41eac4c10041331042000b200441011019000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b411441011019000b411441011019000b411441011019000b41eac4c10041331042000b412841081019000b41eac4c10041331042000b411441011019000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b200241011019000b200b10010b20024100200a1b210d200c410020041b21072004200620041b210502400240024002400240024002400240201a201b54200f200e54200f200e511b450d0041d3ecc1002106412e210420070d010c020b200341c8016a41086a22024200370300200342003703c80141eec7c1004113200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802024002400240024002400240200341b8026a41104188f0c100410041001004417f460d00200342103702ac012003200341b8026a3602a801200341c8016a200341a8016a103e20032802c8012212450d0b200341c8016a41086a280200221c450d0a20032802cc01211d41e8edc10021064123210420112012290300562010201241086a290300220f562010200f511b450d0520094100200a1b211e20194108200a1b211920184108200a1b211f20174108200a1b2118200341c8016a109e0220032802cc01410020032802c80122021b21132002410820021b220c200341c8016a41086a280200410020021b221741286c6a210b200c2102410021060340200b20026b419f014d0d022002200341b8036a460d0320062002200341b8036a412010fa0222094100476a21062009450d03200241286a2209200341b8036a460d0320062009200341b8036a412010fa0222094100476a21062009450d03200241d0006a2209200341b8036a460d0320062009200341b8036a412010fa0222094100476a21062009450d03200241f8006a2209200341b8036a460d03200241a0016a210220062009200341b8036a412010fa0222094100476a210620090d000c030b0b4181edc10021064131210420070d050c060b200b2002460d01200c201741286c6a210b0340200341b8036a2002460d0120062002200341b8036a412010fa0222094100476a21062009450d01200b200241286a2202470d000c020b0b20062016422088a74f0d010b02402013450d00200c10010b200341c8016a200341b8036a10eb02418beec100210620032802c8014101470d01200341d0016a280200211320032802cc012117200341e8006a20192019201e4104746a102e200328026c2003280268220a6b41047622022014201420024b1b2214450d04200521024100210642002120420021210340411410002204450d09200342143702cc01200320043602c801200341c8016a41c8e8c10041141025200341b8026a41086a2209200341c8016a41086a2204280200360200200320032903c8013703b8022002200341b8026a101e2009280200210b20032802bc02210c20032802b802210820044200370300200342003703c8012008200b200341c8016a100220092004290300370300200320032903c8013703b802410021090240200341b8026a41104188f0c100410041001004417f460d00200341003602c801200341b8026a4110200341c8016a41044100100441016a41044d0d0c20032802c801210b410121090b0240200c450d00200810010b200641016a210602402009450d00200b2017490d00200341c8016a200210f0024200210f4200211a0240200428020020134d0d00200a41086a290300420020032802c80120136a2d000022041b211a200a290300420020041b210f0b024020032802cc01450d0020032802c80110010b201a20217c200f20207c2220200f54ad7c21210b200241206a2102200a41106a210a20062014490d000c060b0b41b2edc1002106413621042013450d00200c10010b0240201d450d00201210010b2007450d010b200510010b0240200d450d0020084108200a1b10010b2016a7450d190c090b42002120420021210b2012201c41306c6a210620122102024002400240024002400240024002400240024002400240024002400340200620026b41bf014d0d01200241106a2204200341b8036a460d022004200341b8036a412010fa02450d02200241c0006a2204200341b8036a460d022004200341b8036a412010fa02450d02200241f0006a2204200341b8036a460d022004200341b8036a412010fa02450d02200241a0016a2204200341b8036a460d02200241c0016a21022004200341b8036a412010fa020d000c020b0b024020022006460d000340200241106a2202200341b8036a460d022002200341b8036a412010fa02450d02200241206a22022006470d000b0b20112020852010202185844200520d01200341b8036a41086a290300210e200341b8036a41106a290300210f200341b8036a41186a290300211a20032903b803211b2012201037030820122011370300200341c8016a41186a201a370300200341c8016a41106a200f370300200341c8016a41086a200e3703002012201b370310201241186a200e370300201241206a200f370300201241286a201a3703002003201b3703c801201c41144b0d02201c41014d0d03201c417f6a210b0340201c200b2202417f6a220b490d0b0240201c200b6b220a4102490d002012200241306c6a22042903002012200b41306c6a220929030022105a200441086a2202290300220f200941086a2206290300220e5a200f200e511b0d00200341c8016a41186a2217200941286a2208290300370300200341c8016a41106a2218200941206a220c290300370300200341c8016a41086a2219200941186a2214290300370300200320092903103703c8012009200429030037030020062002290300370300200941106a200441106a2903003703002014200441186a290300370300200c200441206a2903003703002008200441286a290300370300410121130240200a4103490d00410321064102210c410121130340200c2208200a4f0d102009200841306c6a220229030020105a200241086a220c290300220f200e5a200f200e511b0d012008417f6a2204200a4f0d0f2009200441306c6a22042002290300370300200441286a200241286a290300370300200441206a200241206a290300370300200441186a200241186a290300370300200441106a200241106a290300370300200441086a200c29030037030002402006200a4f0d002006210c200641016a220420064921142004210620082113200221042014450d010c020b0b20082113200221040b200420103703002004200e3703082009201341306c6a220241286a2017290300370300200241206a2018290300370300200241186a2019290300370300200220032903c8013703100b200b0d000c040b0b200341386a200341f0026a201b200e10ae014116210441caeec1002106201d450d120c110b200341d0006a200341f0026a201b200e10ae01410f210441e0eec1002106201d0d100c110b201c4101762222ad42307e220e422088a70d0d200ea72202417f4c0d0d024002402002450d00200210002223450d082023210c0c010b410821234108210c0b201241506a2124201241f07e6a2125410421184100212641002127201c21280340202821144100212841012106024002400240024002400240024002400240024002402014417f6a2209450d0002400240024002402012200941306c6a22022903002012201441306c220b6a220441a07f6a290300220f54200241086a2903002210200441a87f6a290300220e542010200e511b450d002025200b6a2102034020094101460d02200f20022903002211542104200e200241086a2903002210512106200e2010542108200241506a21022009417f6a21092011210f2010210e2004200820061b0d000c030b0b2014417e6a210a2025200b6a210241002128410021040340200a2004460d0c200f200229030022115a2106200e200241086a2903002210512109200e20105a2108200241506a2102200441016a21042011210f2010210e2006200820091b0d000b200441016a2106201420046b417f6a22090d020c0a0b410021090b20142009490d042014201c4b0d070240201420096b22064101762208450d002024200b6a21022012200941306c6a21040340200341c8016a41286a220a200441286a220b290300370300200341c8016a41206a2213200441206a2217290300370300200341c8016a41186a2219200441186a221e290300370300200341c8016a41106a2229200441106a2228290300370300200341c8016a41086a222a200441086a222b290300370300200320042903003703c801200241086a222c290300210e200241106a222d290300210f200241186a222e2903002110200241206a222f29030021112002290300211a200b200241286a223029030037030020172011370300201e20103703002028200f370300202b200e3703002004201a3703002030200a290300370300202f2013290300370300202e2019290300370300202d2029290300370300202c202a290300370300200220032903c801370300200441306a2104200241506a21022008417f6a22080d000b0b2009450d080b0240200641094d0d002009212820272026470d0b0c0a0b2014201c4b0d04034020142009417f6a2228490d060240201420286b22064102490d002012200941306c6a22042903002012202841306c6a220829030022105a200441086a2202290300220f200841086a2209290300220e5a200f200e511b0d00200341c8016a41186a2219200841286a220a290300370300200341c8016a41106a221e200841206a220b290300370300200341c8016a41086a2229200841186a2213290300370300200320082903103703c8012008200429030037030020092002290300370300200841106a200441106a2903003703002013200441186a290300370300200b200441206a290300370300200a200441286a29030037030041012117024020064103490d00410321094102210b410121170340200b220a20064f0d052008200a41306c6a220229030020105a200241086a220b290300220f200e5a200f200e511b0d01200a417f6a220420064f0d062008200441306c6a22042002290300370300200441286a200241286a290300370300200441206a200241206a290300370300200441186a200241186a290300370300200441106a200241106a290300370300200441086a200b2903003703000240200920064f0d002009210b200941016a2204200949211320042109200a2117200221042013450d010c020b0b200a2117200221040b200420103703002004200e3703082008201741306c6a220241286a2019290300370300200241206a201e290300370300200241186a2029290300370300200220032903c8013703100b2028450d01202821092006410a490d000b0b20272026470d090c080b41d08ac300200a2006104e000b41e08ac30020042006104e000b20092014107a000b20142009417f6a22284f0d010b20282014107a000b2014201c1076000b2009212820272026460d010c020b2014210620272026470d010b202641016a22022026490d1720264101742204200220022004491b2204ad420386220e422088a70d17200ea722024100480d17024002402026450d00200210002209450d0920092018200220264103742208200820024b1b10f802210220181001200221180c010b200210002218450d080b200421260b201820274103746a22022006360204200220283602000240202741016a22274102490d00024003400240024002400240201820272213417f6a22274103746a2202280200450d00201820134103746a220841746a2802002209200228020422044d0d00201341024d0d0520182013417d6a22024103746a2802042206200420096a4d0d01201341034d0d05200841646a280200200620096a4d0d010c050b20134103490d012002280204210420182013417d6a22024103746a28020421060b20062004490d010b2013417e6a21020b2013200241016a222a4d0d05201320024d0d06201820024103746a2219280204222b20192802006a22022018202a4103746a221e2802002229490d072002201c4b0d08201941046a212c2012202941306c6a2214201e280204221741306c22046a2109200241306c210602400240024002400240200220296b220a20176b220220174f0d0020232009200241306c220410f8021a200c20046a210820174101480d0120024101480d01202420066a21062009210203402006200241506a2209200841506a220a200a290300200929030054200841586a290300220e200241586a290300220f54200e200f511b220b1b2204290300370300200641286a200441286a290300370300200641206a200441206a290300370300200641186a200441186a290300370300200641106a200441106a290300370300200641086a200441086a2903003703002008200a200b1b2108201420092002200b1b22024f0d04200641506a2106200c2104200c2008490d000c050b0b20232014200410f8021a200c20046a210820174101480d01200a20174c0d01201220066a210b200c21042014210203402002200920042009290300200429030054200941086a290300220e200441086a290300220f54200e200f511b220a1b2206290300370300200241286a200641286a290300370300200241206a200641206a290300370300200241186a200641186a290300370300200241106a200641106a290300370300200241086a200641086a2903003703002004200441306a200a1b2104200241306a2102200941306a2009200a1b2209200b4f0d04200820044b0d000c040b0b200921020c010b201421020b200c21040b20022004200820046b220620064130706b10f8021a202c202b20176a36020020192029360200201e201e41086a2013202a417f736a41037410f9021a202741014b0d000c020b0b201321270b20280d000b02402026450d00201810010b2022450d00202310010b2003201c3602d0012003201d3602cc01200320123602c801200341c8016a10a2020240201d450d00201210010b02402007450d00200510010b0240200d450d00201f10010b410021062016a7450d25201510010c250b41c08ac300202a2013104e000b41c08ac30020022013104e000b20292002107a000b2002201c1076000b200241041019000b200241081019000b200b201c107a000b41e08ac3002004200a104e000b41d08ac3002008200a104e000b41888bc30041004100104e000b41eac4c10041331042000b411441011019000b102c000b41eac4c10041331042000b201210010b02402007450d00200510010b0240200d450d00201810010b2016a7450d100b2015100120012802004102460d170c180b4200210e200341c8016a41086a22044200370300200342003703c80141d0c8c1004115200341c8016a1002200341b8026a41086a2004290300370300200320032903c8013703b80202400240200341b8026a41104188f0c100410041001004417f460d00200342003703d001200342003703c801200341b8026a4110200341c8016a4110410010042204417f460d062004410f4d0d06200341d0016a290300210e20032903c801210f0c010b4209210f0b200341306a200341b8036a200f200e10d2022003280230450d0141f7ebc1002106411e21040b2007450d0d2002100120012802004102460d150c160b200341c8016a41086a22044200370300200342003703c80141bfc8c1004111200341c8016a1002200341b8026a41086a2004290300370300200320032903c8013703b802410021040240200341b8026a41104188f0c100410041001004417f460d00200341003602c801200341b8026a4110200341c8016a41044100100441016a41044d0d0420032802c80121040b411610002206450d04200342163702cc01200320063602c801200341c8016a4181c8c10041161025200341f0026a41086a220620032802d001360200200320032903c8013703f002200341b8036a200341f0026a101e2006280200210b20032802f402210c20032802f002210a410410002206450d0520062004360000410810002204450d06200420062800003600002006100120042008360004200341c8016a41086a22064200370300200342003703c801200a200b200341c8016a1002200341b8026a41086a2006290300370300200320032903c8013703b802200341b8026a4110200441081003200410010240200c450d00200a10010b0240024002400240024020082009470d00200341c8016a41186a2204200341b8036a41186a290300370300200341c8016a41106a2206200341b8036a41106a290300370300200341c8016a41086a2209200341b8036a41086a290300370300200320032903b8033703c80120082007470d01200841016a220a2008490d052008410174220b200a200a200b491b2207ad420586220e422088a70d05200ea7220a4100480d052008450d02200a10002205450d0d20052002200a2008410574220b200b200a4b1b10f8021a200210010c030b200341c8016a41186a2206200341b8036a41186a290300370300200341c8016a41106a220a200341b8036a41106a290300370300200341c8016a41086a220b200341b8036a41086a290300370300200320032903b8033703c801200920084d0d0b200220084105746a220420032903c801370000200441186a2006290300370000200441106a200a290300370000200441086a200b290300370000200221050c030b200221050c010b200a10002205450d0a0b200520084105746a220220032903c801370000200241186a2004290300370000200241106a2006290300370000200241086a2009290300370000200841016a21090b200341003602d001200342013703c8012009200341c8016a101b024002402009450d002009410574210b4100200341c8016a41086a28020022046b210820032802c801210a20032802cc0121092005210c0340200c21020240200920086a411f4b0d00200441206a22062004490d042009410174220c20062006200c491b22064100480d0420061000210c024002402009450d00200c450d07200c200a20062009200920064b1b10f8021a200a10010c010b200c450d060b200c210a200621090b200241206a210c200a20046a22062002290000370000200641186a200241186a290000370000200641106a200241106a290000370000200641086a200241086a290000370000200841606a2108200441206a2104200b41606a220b0d000b200341d0016a2004360200200320093602cc012003200a3602c8010c010b200341d0016a280200210420032802cc01210920032802c801210a0b200341c8016a41086a22024200370300200342003703c8014197c8c1004112200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802200341b8026a4110200a2004100302402009450d00200a10010b02402007450d00200510010b2003200d41016a3602f002200341c8016a41086a22024200370300200342003703c80141a9c8c1004116200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802200341b8026a4110200341f0026a410410030c0b0b1018000b200641011019000b41eac4c10041331042000b41eac4c10041331042000b411641011019000b410441011019000b410841011019000b41b08bc30020082009104e000b200a41011019000b200410010b02400240024002400240024002402002450d00200341c8016a41086a22024200370300200342003703c80141bfc8c1004111200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802410021020240200341b8026a41104188f0c100410041001004417f460d00200341003602c801200341b8026a4110200341c8016a41044100100441016a41044d0d0520032802c80121020b20122002470d01200341c8016a41086a22024200370300200342003703c801419feac100411b200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802200341b8026a41104188f0c100410041001004417f460d02200341003602c801200341b8026a4110200341c8016a41044100100441016a41044d0d052008201220032802c8016b4f0d030c060b41f3e9c1002106412c210420012802004102460d0f0c100b41bfe9c10021064116210420012802004102460d0e0c0f0b2008201241016b490d030b41d5e9c10021060c0b0b41eac4c10041331042000b41eac4c10041331042000b200341c8016a41086a22024200370300200342003703c80141b6c7c100410e200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b8020240024002400240024002400240024002400240200341b8026a41104188f0c100410041001004417f460d00200342103702ac012003200341b8026a3602a801200341c8016a200341a8016a103620032802c8012202450d02200341d0016a280200210a20032802cc0121040c010b410021020b2004410020021b210b2002410120021b210941caeac100210641122104024002402014200a410020021b220c4f0d000240200920144105746a2202200341f0026a460d002002200341f0026a412010fa020d010b41baeac1002106411021042013200c4f0d00200920134105746a2202200341b8036a460d012002200341b8036a412010fa02450d010b200b450d0a2009100120012802004102460d120c130b20034198036a200341b8036a10f00220032802a00321022003280298032106200341c8016a41086a22044200370300200342003703c8014197c8c1004112200341c8016a1002200341b8026a41086a2004290300370300200320032903c8013703b8024100211202400240200341b8026a41104188f0c100410041001004417f460d00200342103702ac012003200341b8026a3602a801200341c8016a200341a8016a103620032802c8012215450d03200341d0016a280200210420032802cc0121180c010b410021150b2015410120151b211702402004410020151b22042002200220044b1b220a450d0041002104200341e0016a210d200341d8016a2107200341d0016a21052017210203400240200620046a2d0000450d00200d42003703002007420037030020054200370300200342003703c801200341c8016a2002460d002002200341c8016a412010fa02450d00200341c8016a200210eb024101211220032802c8014101470d0020032802cc0120084d0d020b200241206a2102200441016a2204200a490d000b410021120b02402015450d002018450d00201710010b0240200328029c03450d00200610010b2003200c3602d0012003200b3602cc01200320093602c801200341f0026a200341b8036a20121b2014201320121b200341c8016a10ef024200210e200341c8016a41086a22024200370300200342003703c80141dce8c1004112200341c8016a1002200341b8026a41086a2002290300370300200320032903c8013703b802200341b8026a41104188f0c1004100410010042102024002400240024002402012450d002002417f460d01200342003703d001200342003703c801200341b8026a4110200341c8016a4110410010042202417f460d072002410f4d0d07200341d0016a290300210e20032903c801210f0c020b2002417f460d02200342003703d001200342003703c801200341b8026a4110200341c8016a4110410010042202417f460d072002410f4d0d07200341d0016a290300211120032903c801210e0c030b4200210f4200210e0b200341086a200341f0026a200f200e10d402200341d5016a200341f8026a290300370000200341dd016a20034180036a290300370000200341e5016a20034188036a290300370000200341013a00cc01200341053a00c801200320032903f0023700cd01200341c8016a10b4010c0a0b420021110b200341206a200341f0026a10b001024002402003290320200341286a29030084500d00411810002202450d07200342183702cc01200320023602c801200341c8016a4193f1c10041181025200341b8026a41086a220220032802d001360200200320032903c8013703b802200341b8036a200341b8026a101e2002280200210620032802bc02210920032802b80221044200210f200341c8016a41086a22084200370300200342003703c80120042006200341c8016a100220022008290300370300200320032903c8013703b802200341b8026a41104188f0c100410041001004417f460d01200342003703d001200342003703c801200341b8026a4110200341c8016a4110410010042202417f460d062002410f4d0d06200341d0016a290300211020032903c801210f2009450d090c080b41fb84c20021064122210420012802004102460d120c130b4200211020090d060c070b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b411841011019000b200410010b0240411410002202450d00200342143702cc01200320023602c801200341c8016a41eeefc10041141025200341b8026a41086a220220032802d001360200200320032903c8013703b802200341f0026a200341b8026a101e2002280200210620032802bc02210920032802b80221044200211a200341c8016a41086a22084200370300200342003703c80120042006200341c8016a100220022008290300370300200320032903c8013703b802024002400240200341b8026a41104188f0c100410041001004417f460d00200342003703d001200342003703c801200341b8026a4110200341c8016a4110410010042202417f460d022002410f4d0d02200341d0016a290300211620032903c801211a0c010b420021160b20112010200f200e56201020115620102011511b22021b2111200e200f20021b210e02402009450d00200410010b200341f0026a201a200e7c221b201620117c201b201a54ad7c10aa01200341b8036a200f200e7d201020117d200f200e54ad7d10d302200341d5016a200341b8036a41086a290300370000200341dd016a200341b8036a41106a290300370000200341e5016a200341b8036a41186a290300370000200341ed016a20032903f002370000200341f5016a200341f0026a41086a290300370000200341fd016a200341f0026a41106a29030037000020034185026a200341f0026a41186a29030037000041002106200341003a00cc01200341053a00c801200320032903b8033700cd01200341c8016a10b4010c080b41eac4c10041331042000b411441011019000b410021060c050b20012802004102460d070c080b41142101411410002202450d010b200342143702cc01200320023602c801200341c8016a41c8e8c10020011025200341f0026a41086a220120032802d001360200200320032903c8013703f002200341b8036a200341f0026a101e2001280200210220032802f402210420032802f0022101200320073602f002200341c8016a41086a22094200370300200342003703c80120012002200341c8016a1002200341b8026a41086a2009290300370300200320032903c8013703b802200341b8026a4110200341f0026a4104100302402004450d00200110010b411310002201450d01200342133702cc01200320013602c801200341c8016a41eee8c10041131025200341f0026a41086a220120032802d001360200200320032903c8013703f002200341b8036a200341f0026a101e2001280200210420032802f402210920032802f0022101200341003602d001200342013703c80120082005200341c8016a108d0120032802cc01210a20032802d001210b20032802c8012102200341c8016a41086a220c4200370300200342003703c80120012004200341c8016a1002200341b8026a41086a200c290300370300200320032903c8013703b802200341b8026a41102002200b10030240200a450d00200210010b02402009450d00200110010b02402006450d00200810010b410021090c070b200141011019000b411341011019000b20012802004102460d020c030b200810010c030b411e210420012802004102470d010b200141086a280200450d00200128020410010b200621090b2000200436020420002009360200200341e0036a24000bd57205087f027e057f027e0f7f230041a0026b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00002204417e6a220541044b0d00024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e050005020301000b200141046a2802002106200241096a2800002105200241056a280000210720022d0001210820022d00002101200341d8016a41026a2204200241046a2d00003a0000200341d8006a41086a2209200241156a290000370300200341d8006a410d6a220a2002411a6a2900003700002003200241026a2f01003b01d80120032002410d6a29000037035820010d07200341086a41026a20042d00003a000020034180026a41086a200929030037030020034180026a410d6a200a290000370000200320032f01d8013b01082003200329035837038002200841ff01714101470d07200341eb006a20034180026a41086a290300220b370000200341f0006a20034180026a410d6a290000220c370000200341c8016a41026a200341086a41026a2d000022023a0000200341d8016a41086a200b370300200341d8016a410d6a200c3700002003200536005f2003200736005b200320032f010822013b01582003200329038002220b370063200320013b01c8012003200b3703d801200320023a005a410021010c080b4100210841efeec10041efeec1004100410320022d000120022d00001b41ff017122021b20024103461b22070d022003200141086a290300370358200341286a41086a220242003703002003420037032841e9b0c100411a200341286a1002200341c8016a41086a2002290300370300200320032903283703c801200341c8016a4110200341d8006a4108100320044102470d3a0c390b200341206a200141196a290000370300200341186a200141116a290000370300200341086a41086a200141096a29000037030020032001290001370308200241096a2800002105200241056a280000210820022d0001210920022d00002107200341d8016a41026a220a200241046a2d00003a0000200341d8006a41086a220d200241156a290000370300200341d8006a410d6a220e2002411a6a2900003700002003200241026a2f01003b01d80120032002410d6a29000037035820070d03200341c8016a41026a200a2d00003a000020034180026a41086a200d29030037030020034180026a410d6a200e290000370000200320032f01d8013b01c8012003200329035837038002200941ff01714101470d03200341eb006a20034180026a41086a290300220b370000200341f0006a20034180026a410d6a290000220c370000200341c8006a41026a200341c8016a41026a2d000022023a0000200341d8016a41086a200b370300200341d8016a410d6a200c3700002003200536005f2003200836005b200320032f01c80122073b01582003200329038002220b370063200320073b01482003200b3703d801200320023a005a410021020c040b4100210841efeec10041efeec1004100410320022d000120022d00001b41ff017122021b20024103461b2207450d080b412821050c380b200141216a2d0000210f200341c0016a200141196a290000370300200341b8016a200141116a290000370300200341a8016a41086a200141096a290000370300200320012900013703a801200241096a2800002105200241056a280000210820022d0001210920022d00002107200341d8016a41026a220a200241046a2d00003a0000200341d8006a41086a220d200241156a290000370300200341d8006a410d6a220e2002411a6a2900003700002003200241026a2f01003b01d80120032002410d6a29000037035820070d04200341c8016a41026a200a2d00003a0000200341086a41086a200d290300370300200341086a410d6a200e290000370000200320032f01d8013b01c80120032003290358370308200941ff01714101470d04200341eb006a200341086a41086a290300220b370000200341f0006a200341086a410d6a290000220c370000200341c8006a41026a200341c8016a41026a2d000022023a0000200341d8016a41086a200b370300200341d8016a410d6a200c3700002003200536005f2003200836005b200320032f01c80122073b015820032003290308220b370063200320073b01482003200b3703d801200320023a005a410021020c050b41012102412a21054197efc10021080b200341c4006a41026a2207200341c8006a41026a2d00003a0000200341286a41086a2209200341d8016a41086a290300370300200341286a41106a200341d8016a41106a290300370300200320032f01483b0144200320032903d80137032820020d32200341bb016a2009290300370000200341c0016a200341356a290000370000200320032f01443b01a801200320053600af01200320083600ab01200320032903283700b301200320072d00003a00aa01200341a8016a10cf02450d05411c10002202450d162003421c37025c20032002360258200341d8006a41d4b1c100411c1025200341d8016a41086a22022003280260360200200320032903583703d801200341086a200341d8016a101e2002280200210520032802dc01210720032802d8012102200341286a41086a220842003703002003420037032820022005200341286a1002200341c8016a41086a2008290300370300200320032903283703c801200341c8016a4110100e210502402007450d00200210010b2005450d09200341d8006a200341086a10df0220032802602209450d0f2003290264220b422088220ca7220a450d100c210b410121014197efc1002107412a21050b200341c4006a41026a2208200341c8016a41026a2d00003a0000200341286a41086a2202200341d8016a41086a290300370300200341286a41106a200341d8016a41106a290300370300200320032f01c8013b0144200320032903d80137032820010d1c200341bb016a2002290300370000200341c0016a200341286a410d6a290000370000200320032f01443b01a801200320053600af01200320073600ab01200320032903283700b301200320082d00003a00aa01200242003703002003420037032841f0f1c100410d200341286a1002200341c8016a41086a2002290300370300200320032903283703c8014200210b0240200341c8016a41104188f0c100410041001004417f460d0020034200370358200341c8016a4110200341d8006a41084100100441016a41084d0d1b2003290358210b0b200341286a41086a220242003703002003420037032841e9b0c100411a200341286a1002200341c8016a41086a2002290300370300200320032903283703c801200341c8016a41104188f0c100410041001004417f460d0520034200370358200341c8016a4110200341d8006a41084100100441016a41084d0d192003290358210c0c060b410121024197efc1002108412a21050b200341c4006a41026a2207200341c8006a41026a2d00003a0000200341286a41086a2209200341d8016a41086a290300370300200341286a41106a200341d8016a41106a290300370300200320032f01483b0144200320032903d80137032820020d2e20034193026a200929030037000020034180026a41186a2202200341356a290000370000200320032f01443b018002200320053600870220032008360083022003200329032837008b02200320072d00003a00820220034180026a10cf02450d02200341d8006a41186a200341a8016a41186a290300370300200341d8006a41106a200341a8016a41106a290300370300200341d8006a41086a200341a8016a41086a29030037030020034180016a20034180026a41086a29030037030020034188016a20034180026a41106a29030037030020034190016a2002290300370300200320032903a8013703582003200329038002370378411b10002202450d112003421b3702dc01200320023602d801200341d8016a419faec100411b1025200341086a41086a220220032802e001360200200320032903d801370308200341d8006a200341086a10af0220022802002105200328020c210720032802082102200341286a41086a220842003703002003420037032820022005200341286a1002200341c8016a41086a2008290300370300200320032903283703c801200341c8016a41104188f0c100410041001004417f460d06200341003a00d801200341c8016a4110200341d8016a41014100100441016a41014d0d0f20032d00d80121052007450d1c0c1b0b2003200141086a290300370358200341286a41086a220242003703002003420037032841e9b2c100411b200341286a1002200341c8016a41086a2002290300370300200320032903283703c801200341c8016a4110200341d8006a4108100320044102460d2e0c2f0b419eb2c1002108412b210520044102460d2d0c2e0b41f0b1c1002108412e210520044102460d2c0c2d0b4203210c0b200341d8006a109e0220032802582207410820071b2208200341d8006a41086a280200410020071b220941286c6a2105200c200b7c210b200328025c2104200821020340200520026b419f014d0d032002200341a8016a460d042002200341a8016a412010fa02450d04200241286a2201200341a8016a460d052001200341a8016a412010fa02450d05200241d0006a2201200341a8016a460d052001200341a8016a412010fa02450d05200241f8006a2201200341a8016a460d05200241a0016a21022001200341a8016a412010fa020d000c050b0b41c9b2c10021084120210520044102460d290c2a0b4102210520070d140c150b4102210120052002460d022008200941286c6a21050340200341a8016a2002460d012002200341a8016a412010fa02450d012005200241286a2202470d000c030b0b200221010b200141206a290300200b5621010b2001410247200171210202402007450d002004450d00200810010b024002402002450d0020034100360260200342013703582006200341d8006a101c200328025c21082003280260210420032802582107200341d8006a41186a22024200370300200341d8006a41106a22014200370300200341d8006a41086a220542003703002003420037035820072004200341d8006a100d20034180026a41186a2204200229030037030020034180026a41106a2209200129030037030020034180026a41086a220a2005290300370300200320032903583703800202402008450d00200710010b20022004290300370300200120092903003703002005200a2903003703002003200329038002370358411810002202450d07200342183702dc01200320023602d801200341d8016a4188a3c10041181025200341086a41086a220220032802e001360200200320032903d801370308200341d8006a200341086a101e20022802002101200328020c210520032802082102200341286a41086a220742003703002003420037032820022001200341286a1002200341c8016a41086a2007290300370300200320032903283703c801200341c8016a4110100e210102402005450d00200210010b2001450d0141a3b1c1002107411f21050c110b4183b1c1002107412021050c100b200341d8006a20034180026a10df02024020032802602202450d0020032802642101200329035821124200210c200341286a41086a220542003703002003420037032841f0f1c100410d200341286a1002200341c8016a41086a2005290300370300200320032903283703c8010240200341c8016a41104188f0c100410041001004417f460d00200342003703d801200341c8016a4110200341d8016a41084100100441016a41084d0d0a20032903d801210c0b02402001450d00200210010b200c20125a0d0041c2b1c1002107411221050c100b200341d8006a109f022003280258450d02200341c8006a41086a200341d8006a41086a280200220436020020032003290358370348200328024c21020c030b4200210b410121094200422088220ca7220a0d110b200341d8006a41186a200341a8016a41186a290300370300200341d8006a41106a200341a8016a41106a290300370300200341d8006a41086a200341a8016a41086a290300370300200320032903a80137035841002107200341d8006a21050c110b410021022003410036025020034208370348410021040b200341d8006a41186a220120034180026a41186a290300370300200341d8006a41106a220520034180026a41106a290300370300200341d8006a41086a220720034180026a41086a290300370300200320032903800237035802400240024020042002470d00200241016a22082002490d1920024101742209200820082009491b220aad42287e220c422088a70d19200ca722084100480d19024002402002450d002003280248210d200810002209450d032009200d2008200241286c2202200220084b1b10f8021a200d10010c010b200810002209450d020b2003200a36024c200320093602480b200341c8006a41086a200441016a221836020020032802482219200441286c6a2202200b37030020022003290358370308200241106a2007290300370300200241186a2005290300370300200241206a2001290300370300024002400240201841144b0d0020184102490d010340201820042202417f6a2204490d0b0240201820046b22084102490d002019200241286c6a22012903002019200441286c6a2209290300220b5a0d00200341d8006a41186a220f200941206a2202290300370300200341d8006a41106a2211200941186a2205290300370300200341d8006a41086a2216200941106a22072903003703002003200929030837035820092001290300370300200941086a200141086a2903003703002007200141106a2903003703002005200141186a2903003703002002200141206a2903003703004101210e024020084103490d00410321054102210a4101210e0340200a220720084f0d102009200741286c6a2202290300200b5a0d012007417f6a220120084f0d0f2009200141286c6a22012002290300370300200141206a200241206a290300370300200141186a200241186a290300370300200141106a200241106a290300370300200141086a200241086a2903003703000240200520084f0d002005210a200541016a2201200549210d200121052007210e20022101200d450d010c020b0b2007210e200221010b2001200b3703002009200e41286c6a22022003290358370308200241206a200f290300370300200241186a2011290300370300200241106a20162903003703000b20040d000c020b0b2018410176221aad42287e220b422088a70d03200ba72202417f4c0d03024002402002450d0020021000221b450d03201b210a0c010b4108211b4108210a0b201941586a211c201941887f6a211d410421114100211e4100211720182115024003402015210d41002115410121050240024002400240024002400240024002400240024002400240200d417f6a2207450d0002400240024002402019200741286c6a2903002019200d41286c22046a41b07f6a290300220b5a0d00201d20046a2102034020074101460d022007417f6a2107200b2002290300220c542101200241586a2102200c210b20010d000c030b0b200d417e6a2107201d20046a21014100211541002102034020072002460d0c200241016a2102200b2001290300220c5a2105200141586a2101200c210b20050d000b200241016a2105200d20026b417f6a22070d020c0a0b410021070b200d2007490d04200d20184b0d070240200d20076b22054101762208450d002019200741286c6a2102201c20046a21010340200341d8016a41206a2204200241206a2209290300370300200341d8016a41186a220e200241186a220f290300370300200341d8016a41106a2216200241106a2210290300370300200341d8016a41086a2214200241086a2215290300370300200320022903003703d801200141086a221f290300210b200141106a2220290300210c200141186a22212903002112200129030021132009200141206a2222290300370300200f20123703002010200c3703002015200b37030020022013370300202220042903003703002021200e29030037030020202016290300370300201f2014290300370300200120032903d801370300200241286a2102200141586a21012008417f6a22080d000b0b2007450d080b0240200541094d0d00200721152017201e470d0b0c0a0b200d20184b0d040340200d2007417f6a2215490d060240200d20156b22054102490d002019200741286c6a22012903002019201541286c6a2204290300220b5a0d00200341d8006a41186a2216200441206a2202290300370300200341d8006a41106a2210200441186a2207290300370300200341d8006a41086a2214200441106a22082903003703002003200429030837035820042001290300370300200441086a200141086a2903003703002008200141106a2903003703002007200141186a2903003703002002200141206a2903003703004101210f024020054103490d0041032107410221094101210f03402009220820054f0d052004200841286c6a2202290300200b5a0d012008417f6a220120054f0d062004200141286c6a22012002290300370300200141206a200241206a290300370300200141186a200241186a290300370300200141106a200241106a290300370300200141086a200241086a2903003703000240200720054f0d0020072109200741016a2201200749210e200121072008210f20022101200e450d010c020b0b2008210f200221010b2001200b3703002004200f41286c6a22022003290358370308200241206a2016290300370300200241186a2010290300370300200241106a20142903003703000b2015450d01201521072005410a490d000b0b2017201e470d090c080b41d08ac30020082005104e000b41e08ac30020012005104e000b2007200d107a000b200d2007417f6a22154f0d010b2015200d107a000b200d20181076000b200721152017201e460d010c020b200d21052017201e470d010b201e41016a2202201e490d1f201e4101742201200220022001491b2201ad420386220b422088a70d1f200ba722024100480d1f02400240201e450d00200210002207450d03200720112002201e4103742208200820024b1b10f802210220111001200221110c010b200210002211450d020b2001211e0b201120174103746a220220053602042002201536020002400240024002400240201741016a22174102490d000340024002400240024020112017220e417f6a22174103746a2202280200450d002011200e4103746a220841746a2802002207200228020422014d0d00200e41024d0d0b2011200e417d6a22024103746a2802042205200120076a4d0d01200e41034d0d0b200841646a280200200520076a4d0d010c0b0b200e4103490d01200228020421012011200e417d6a22024103746a28020421050b20052001490d010b200e417e6a21020b200e200241016a221f4d0d02200e20024d0d03201120024103746a2216280204222020162802006a22022011201f4103746a22102802002214490d04200220184b0d05201641046a21212019201441286c6a220d2010280204220f41286c22016a2107200241286c210502400240024002400240200220146b2204200f6b2202200f4f0d00201b2007200241286c220110f8021a200a20016a2108200f4101480d0120024101480d01201c20056a21052007210203402005200241586a2207200841586a2204200429030020072903005422091b2201290300370300200541206a200141206a290300370300200541186a200141186a290300370300200541106a200141106a290300370300200541086a200141086a2903003703002008200420091b2108200d2007200220091b22024f0d04200541586a2105200a2101200a2008490d000c050b0b201b200d200110f8021a200a20016a2108200f4101480d012004200f4c0d01201920056a2109200a2101200d21020340200220072001200729030020012903005422041b2205290300370300200241206a200541206a290300370300200241186a200541186a290300370300200241106a200541106a290300370300200241086a200541086a2903003703002001200141286a20041b2101200241286a2102200741286a200720041b220720094f0d04200820014b0d000c040b0b200721020c010b200d21020b200a21010b20022001200820016b220520054128706b10f8021a20212020200f6a360200201620143602002010201041086a200e201f417f736a41037410f9021a201741014b0d000b0b20150d060c070b41c08ac300201f200e104e000b41c08ac3002002200e104e000b20142002107a000b200220181076000b200241041019000b200e211720150d000b0b0240201e450d00201110010b201a450d00201b10010b200341c8006a10a502200341d8016a41186a20034180026a41186a290300370300200341d8016a41106a20034180026a41106a290300370300200341d8016a41086a20034180026a41086a29030037030020032003290380023703d801200341d8006a200641d00010f8021a02400240024002400240411810002202450d002003421837020c20032002360208200341086a4188a3c10041181025200341286a41086a2202200328021036020020032003290308370328200341d8016a200341286a101e20022802002107200328022c2108200328022821012003410036021020034201370308200341d8006a200341086a101c200328020c21042003280210210920032802082105200242003703002003420037032820012007200341286a1002200341c8016a41086a2002290300370300200320032903283703c801200341c8016a411020052009100302402004450d00200510010b02402008450d00200110010b200341d8006a10a001200341d8006a41186a20034180026a41186a290300370300200341d8006a41106a20034180026a41106a290300370300200341d8006a41086a20034180026a41086a2903003703002003200329038002370358412010002202450d01200341a8016a41086a290300210b200341a8016a41106a290300210c20032903a8012112200241186a200341a8016a41186a290300370000200241106a200c370000200241086a200b37000020022012370000411c10002201450d022003421c3702dc01200320013602d801200341d8016a41d4b1c100411c1025200341086a41086a220120032802e001360200200320032903d801370308200341d8006a200341086a101e2001280200210a200328020c210d20032802082104200341003602e001200342013703d8014101200341d8016a101b20032802d801210902400240024020032802dc01220820032802e00122076b411f4b0d00200741206a22012007490d2120084101742205200120012005491b22054100480d212005100021012008450d012001450d072001200920052008200820054b1b10f8021a200910010c020b20092101200821050c010b2001450d050b200120076a22082002290000370000200341d8016a41086a200741206a2207360200200841186a200241186a290000370000200841106a200241106a290000370000200841086a200241086a290000370000200320053602dc01200320013602d801200341286a41086a22084200370300200342003703282004200a200341286a1002200341c8016a41086a2008290300370300200320032903283703c801200341c8016a411020012007100302402005450d00200110010b0240200d450d00200410010b20021001200341d8006a41186a20034180026a41186a290300370300200341d8006a41106a20034180026a41106a290300370300200341d8006a41086a20034180026a41086a29030037030020034180016a200341a8016a41086a29030037030020034188016a200341a8016a41106a29030037030020034190016a200341a8016a41186a2903003703002003200329038002370358200320032903a801370378200341013a0044411b10002202450d032003421b3702dc01200320023602d801200341d8016a419faec100411b1025200341086a41086a220220032802e001360200200320032903d801370308200341d8006a200341086a10af0220022802002101200328020c210520032802082102200341286a41086a220742003703002003420037032820022001200341286a1002200341c8016a41086a2007290300370300200320032903283703c801200341c8016a4110200341c4006a4101100302402005450d00200210010b0240200328024c450d00200328024810010b20061001410021070c2a0b411841011019000b412041011019000b411c41011019000b411b41011019000b200541011019000b200241081019000b200841081019000b102c000b41eac4c10041331042000b411841011019000b411b41011019000b411c41011019000b41eac4c10041331042000b20042018107a000b41e08ac30020012008104e000b41d08ac30020072008104e000b41eac4c10041331042000b41eac4c10041331042000b41c082c300104f000b200610a001200610010c160b200210010b02400240024002400240200541ff01714102470d00200341d8016a41186a200341a8016a41186a290300370300200341d8016a41106a200341a8016a41106a290300370300200341d8016a41086a200341a8016a41086a290300370300200320032903a8013703d8010240024002400240411c10002202450d002003421c37025c20032002360258200341d8006a41d4b1c100411c1025200341086a41086a2202200328026036020020032003290358370308200341d8016a200341086a101e20022802002105200328020c210920032802082107200341c8016a41086a22024200370300200342003703c80120072005200341c8016a1002200341d8006a41086a2002290300370300200320032903c801370358410021020240200341d8006a41104188f0c100410041001004417f460d002003421037022c2003200341d8006a360228200341086a200341286a103620032802082208450d02200329020c210b200341c8016a41086a22024200370300200342003703c80120072005200341c8016a1002200341286a41086a2002290300370300200320032903c801370328200341286a41101008200b422088a72105200ba721022009450d040c030b410121084100210520090d020c030b411c41011019000b41eac4c10041331042000b200710010b200341d8006a41186a220720034180026a41186a290300370300200341d8006a41106a220920034180026a41106a290300370300200341d8006a41086a220a20034180026a41086a290300370300200320032903800237035802400240024020052002470d00200241016a220d2002490d102002410174220e200d200d200e491b2210ad420586220b422088a70d10200ba7220d4100480d102002450d01200d10002211450d0720112008200d200241057422022002200d4b1b10f8021a200810010c020b20082111200221100c010b200d10002211450d050b201120054105746a22022003290358370000200241186a2007290300370000200241106a2009290300370000200241086a200a290300370000411c10002202450d032003421c37025c20032002360258200341d8006a41d4b1c100411c1025200341086a41086a2202200328026036020020032003290358370308200341d8016a200341086a101e20022802002114200328020c2115200328020821162003410036026020034201370358200541016a2202200341d8006a101b024002402002450d00200541057441206a210d4100200341d8006a41086a28020022056b21092003280258210a200328025c21082011210e0340200e21020240200820096a411f4b0d00200541206a22072005490d112008410174220e20072007200e491b22074100480d1120071000210e024002402008450d00200e450d07200e200a20072008200820074b1b10f8021a200a10010c010b200e450d060b200e210a200721080b200241206a210e200a20056a22072002290000370000200741186a200241186a290000370000200741106a200241106a290000370000200741086a200241086a290000370000200941606a2109200541206a2105200d41606a220d0d000b200341e0006a20053602002003200836025c2003200a3602580c010b200341d8006a41086a2802002105200328025c21082003280258210a0b200341286a41086a220242003703002003420037032820162014200341286a1002200341c8016a41086a2002290300370300200320032903283703c801200341c8016a4110200a2005100302402008450d00200a10010b02402015450d00201610010b2010450d00201110010b200341d8006a41186a200341a8016a41186a290300370300200341d8006a41106a200341a8016a41106a290300370300200341d8006a41086a200341a8016a41086a29030037030020034180016a20034180026a41086a29030037030020034188016a20034180026a41106a29030037030020034190016a20034180026a41186a290300370300200320032903a80137035820032003290380023703782003200f3a0048411b10002202450d012003421b3702dc01200320023602d801200341d8016a419faec100411b1025200341086a41086a220220032802e001360200200320032903d801370308200341d8006a200341086a10af0220022802002105200328020c210720032802082102200341286a41086a220842003703002003420037032820022005200341286a1002200341c8016a41086a2008290300370300200320032903283703c801200341c8016a4110200341c8006a410110032007450d14200210010c140b200741011019000b411b41011019000b411c41011019000b200d41011019000b410021020240200a4101460d0041002102200a210503402005410176220720026a22082002200920084105746a200341a8016a412010fa024101481b2102200520076b220541014b0d000b0b200920024105746a200341a8016a412010fa022207450d01200341d8006a41186a200341a8016a41186a290300370300200341d8006a41106a200341a8016a41106a290300370300200341d8006a41086a200341a8016a41086a290300370300200320032903a801370358200341d8006a210520022007411f766a2207200a4d0d0041e88ec200104f000b0240200a200ba7470d00200a41016a2202200a490d07200ca7220d4101742208200220022008491bad22124205862213422088a70d072013a722024100480d07200a450d0220021000220f450d05200f20092002200d410574220820022008491b10f8021a200910010c030b2009210f0c030b4184b3c1002108412a2105200ba7450d0e2009100120044102460d0f0c100b20021000220f450d020b200b42808080807083201284210b0b200f20074105746a220241206a2002200a20076b41057410f9021a200241186a200541186a290000370000200241106a200541106a290000370000200241086a200541086a29000037000020022005290000370000200341286a41086a220242003703002003420037032841f0f1c100410d200341286a1002200341c8016a41086a22052002290300370300200320032903283703c80142002112024002400240200341c8016a41104188f0c100410041001004417f460d0020034200370358200341c8016a4110200341d8006a41084100100441016a41084d0d01200329035821120b200242003703002003420037032841e9b2c100411b200341286a100220052002290300370300200320032903283703c80102400240200341c8016a41104188f0c100410041001004417f460d0020034200370358200341c8016a4110200341d8006a41084100100441016a41084d0d032003290358211341012105411c2102411c10002207450d010c050b42e807211341012105411c2102411c100022070d040b200220051019000b41eac4c10041331042000b41eac4c10041331042000b200241011019000b2003421c37025c20032007360258200341d8006a41a0a3c10020021025200341d8016a41086a22022003280260360200200320032903583703d801200341086a200341d8016a101e2002280200211620032802dc01211020032802d80121112003410036026020034201370358410810002202450d042002201320127c37000020034288808080800137025c20032002360258200ca7220720056a2202200341d8006a101b024002402002450d00200741057441206a210d4100200341d8006a41086a28020022056b21092003280258210a200328025c2108200f210e0340200e21020240200820096a411f4b0d00200541206a22072005490d042008410174220e20072007200e491b22074100480d0420071000210e024002402008450d00200e450d08200e200a20072008200820074b1b10f8021a200a10010c010b200e450d070b200e210a200721080b200241206a210e200a20056a22072002290000370000200741186a200241186a290000370000200741106a200241106a290000370000200741086a200241086a290000370000200941606a2109200541206a2105200d41606a220d0d000b200341e0006a20053602002003200836025c2003200a3602580c010b200341e0006a2802002105200328025c21082003280258210a0b200341286a41086a220242003703002003420037032820112016200341286a1002200341c8016a41086a2002290300370300200320032903283703c801200341c8016a4110200a2005100302402008450d00200a10010b200ba7210202402010450d00201110010b02402002450d00200f10010b200341d8006a109f0241002107200328025c4100200328025822051b21172005410820051b2111024002400240200341d8006a41086a2202280200410020051b41286c2208450d000340200341d8006a41206a201120076a220541206a290300370300200341d8006a41186a200541186a290300370300200341d8006a41106a200541106a2903003703002002200541086a2903003703002003200529030037035820034180026a41186a200241186a29000037030020034180026a41106a200241106a29000037030020034180026a41086a200241086a290000370300200320022900003703800220034180026a200341086a412010fa020d022008200741286a2207470d000b0b200341003602602003420837035802402017450d00201110010b200341d8006a10a5020c010b200341d8016a41206a2202200341d8006a41206a290300370300200341d8016a41186a2209200341d8006a41186a290300370300200341d8016a41106a220a200341d8006a41106a290300370300200341d8016a41086a220d200341d8006a41086a290300370300200320032903583703d801412810002216450d08201620032903d801370300201641206a2002290300370300201641186a2009290300370300201641106a200a290300370300201641086a200d29030037030002400240200841586a2007460d00200541286a2102200820076b41b07f6a2108200341d8006a41086a21054101210f4101210e0340200341d8006a41206a2209200241206a290300370300200341d8006a41186a220a200241186a290300370300200341d8006a41106a220d200241106a2903003703002005200241086a2903003703002003200229030037035820034180026a41186a200541186a29000037030020034180026a41106a200541106a29000037030020034180026a41086a200541086a29000037030020032005290000370380020240024002400240024020034180026a200341086a412010fa02450d00200341d8016a41206a22072009290300370300200341d8016a41186a2210200a290300370300200341d8016a41106a2214200d290300370300200341d8016a41086a22152005290300370300200320032903583703d80120092007290300370300200a2010290300370300200d201429030037030020052015290300370300200320032903d801370358200e200f470d03200f41016a2207200f490d09200f4101742210200720072010491b2210ad42287e220b422088a70d09200ba722074100480d09200f450d01200710002214450d0c201420162007200f41286c220f200f20074b1b10f802210720161001200721160c020b20080d030c060b200710002216450d0a0b2010210f0b2016200e41286c6a22072003290358370300200741206a2009290300370300200741186a200a290300370300200741106a200d290300370300200741086a2005290300370300200e41016a210e2008450d030b200241286a2102200841586a21080c000b0b4101210f4101210e0b02402017450d00201110010b2003200e3602602003200f36025c20032016360258200341d8006a10a502200f450d00201610010b200341d8006a41186a200341086a41186a290300370300200341d8006a41106a200341086a41106a290300370300200341d8006a41086a200341086a41086a29030037030020032003290308370358411c10002202450d052003421c3702dc01200320023602d801200341d8016a41d4b1c100411c102520034180026a41086a220220032802e001360200200320032903d80137038002200341d8006a20034180026a101e2002280200210520032802840221072003280280022102200341286a41086a220842003703002003420037032820022005200341286a1002200341c8016a41086a2008290300370300200320032903283703c801200341c8016a4110100802402007450d00200210010b200341d8006a41186a200341086a41186a290300370300200341d8006a41106a200341086a41106a290300370300200341d8006a41086a200341086a41086a29030037030020032003290308370358411810002202450d06200342183702dc01200320023602d801200341d8016a4188a3c1004118102520034180026a41086a220220032802e001360200200320032903d80137038002200341d8006a20034180026a101e2002280200210520032802840221072003280280022102200341286a41086a220842003703002003420037032820022005200341286a1002200341c8016a41086a2008290300370300200320032903283703c801200341c8016a4110100802402007450d00200210010b200341d8006a109e022003280258220f4108200f1b2111200328025c21160240200341d8006a41086a220e2802004100200f1b2202450d00200241286c2108200341f8006a210520112102034020052002290000370000200341d8006a41186a200341086a41186a290300370300200341d8006a41106a200341086a41106a290300370300200e200341086a41086a290300370300200541086a200241086a290000370000200541106a200241106a290000370000200541186a200241186a29000037000020032003290308370358411b10002207450d032003421b3702dc01200320073602d801200341d8016a419faec100411b102520034180026a41086a2207200341d8016a41086a280200360200200320032903d80137038002200341d8006a20034180026a10af0220072802002109200328028402210a2003280280022107200341286a41086a220d42003703002003420037032820072009200341286a1002200341c8016a41086a200d290300370300200320032903283703c801200341c8016a411010080240200a450d00200710010b200241286a2102200841586a22080d000b0b200f450d082016450d08201110014100210820044102460d0a0c0b0b1018000b411b41011019000b200741011019000b200741081019000b410841011019000b411c41011019000b411841011019000b412841081019000b410021080b20044102470d010b41000d00200141046a280200220210a001200210010b200821070b2000200536020420002007360200200341a0026a24000be90506057f017e017f027e017f027e230041306b22042400024002400240411410002205450d002004421437022420042005360220200441206a41eeefc10041141025200441106a41086a22052004280228360200200420042903203703102001200441106a101e20052802002106200428021421072004280210210842002109200441206a41086a220a42003703002004420037032020082006200441206a10022005200a2903003703002004200429032037031002400240200441106a41104188f0c100410041001004417f460d002004420037032820044200370320200441106a4110200441206a4110410010042205417f460d012005410f4d0d01200441286a290300210b200429032021092007450d040c030b4200210b20070d020c030b41eac4c10041331042000b411441011019000b200810010b0240024020092002542208200b200354200b2003511b450d00419e87c2002105411521010c010b200441086a200110ca01024020042802082205450d00200428020c21010c010b024002400240411810002205450d002004421837022420042005360220200441206a4193f1c10041181025200441106a41086a22052004280228360200200420042903203703102001200441106a101e200528020021072004280214210a200428021021064200210c200441206a41086a220d42003703002004420037032020062007200441206a10022005200d2903003703002004200429032037031002400240200441106a41104188f0c100410041001004417f460d002004420037032820044200370320200441106a4110200441206a4110410010042205417f460d012005410f4d0d01200441286a290300210e2004290320210c200a450d040c030b4200210e200a0d020c030b41eac4c10041331042000b411841011019000b200610010b2001200c20027c220f200e20037c200f200c54ad7c10d3022001200920027d200b20037d2008ad7d10aa01410021050b2000200136020420002005360200200441306a24000bbf0b06017f017e017f017e037f017e230041306b2203240042002104200341106a41086a220542003703002003420037031041bef0c100411b200341106a1002200341086a2005290300370300200320032903103703000240024002400240200341104188f0c100410041001004417f460d00200342003703282003420037032020034110200341206a4110410010042205417f460d022005410f4d0d02200341286a29030021062003290320210441182105411810002207450d010c030b42002106411821054118100022070d020b200541011019000b41eac4c10041331042000b2003421837022420032007360220200341206a4193f1c10020051025200341106a41086a22052003280228360200200320032903203703102000200341106a101e2005280200210820032802142109200328021021072003200237032820032001370320200542003703002003420037031020072008200341106a1002200341086a20052903003703002003200329031037030020034110200341206a4110100302402009450d00200710010b02402004200158200620025820062002511b0d00024002400240411810002205450d002003421837022420032005360220200341206a4193f1c10041181025200341106a41086a22052003280228360200200320032903203703102000200341106a101e20052802002108200328021421092003280210210742002106200542003703002003420037031020072008200341106a1002200341086a20052903003703002003200329031037030002400240200341104188f0c100410041001004417f460d00200342003703282003420037032020034110200341206a4110410010042205417f460d012005410f4d0d01200341286a2903002104200329032021062009450d040c030b4200210420090d020c030b41eac4c10041331042000b411841011019000b200710010b42002102200341106a41086a220542003703002003420037031041d9f0c1004116200341106a1002200341086a20052903003703002003200329031037030002400240024002400240024002400240200341104188f0c100410041001004417f460d00200342003703282003420037032020034110200341206a4110410010042205417f460d022005410f4d0d02200341286a2903002101200329032021020c010b420021010b0240200220067d220a200256200120047d2002200654ad7d220220015620022001511b0d002003200a37032020032002370328200341106a41086a220542003703002003420037031041d9f0c1004116200341106a1002200341086a20052903003703002003200329031037030020034110200341206a411010030b411810002205450d022003421837022420032005360220200341206a4193f1c10041181025200341106a41086a22052003280228360200200320032903203703102000200341106a101e200528020021082003280214210920032802102107200542003703002003420037031020072008200341106a1002200341086a20052903003703002003200329031037030020034110100802402009450d00200710010b411410002205450d032003421437022420032005360220200341206a41eeefc10041141025200341106a41086a22052003280228360200200320032903203703102000200341106a101e200528020021082003280214210920032802102107200542003703002003420037031020072008200341106a1002200341086a2005290300370300200320032903103703000240200341104188f0c100410041001004417f460d00200342003703282003420037032020034110200341206a4110410010042205417f460d022005410f4d0d02200341286a290300210220032903202101410021052009450d060c050b4101210520090d040c050b41eac4c10041331042000b41eac4c10041331042000b411841011019000b411441011019000b200710010b20012002844200522005410173710d00200010f1020b200341306a24000bd50504057f017e017f067e230041306b22042400024002400240411810002205450d002004421837022420042005360220200441206a4193f1c10041181025200441106a41086a22052004280228360200200420042903203703102001200441106a101e20052802002106200428021421072004280210210842002109200441206a41086a220a42003703002004420037032020082006200441206a10022005200a2903003703002004200429032037031002400240200441106a41104188f0c100410041001004417f460d002004420037032820044200370320200441106a4110200441206a4110410010042205417f460d012005410f4d0d01200441286a290300210b200429032021092007450d040c030b4200210b20070d020c030b41eac4c10041331042000b411841011019000b200810010b20012009200220092009200256200b200356200b20035122051b22081b220c7d200b2003200b20081b220d7d2009200c54ad7d10d3024200210e200441206a41086a220142003703002004420037032041d9f0c1004116200441206a1002200441106a41086a200129030037030020042004290320370310024002400240200441106a41104188f0c100410041001004417f460d002004420037032820044200370320200441106a4110200441206a4110410010042201417f460d022001410f4d0d02200441286a290300210f2004290320210e0c010b4200210f0b0240200e200c7d2210200e56200f200d7d200e200c54ad7d220e200f56200e200f511b0d00200420103703002004200e370308200441206a41086a220142003703002004420037032041d9f0c1004116200441206a1002200441106a41086a200129030037030020042004290320370310200441106a41102004411010030b20002002200c7d370308200041106a2003200d7d2002200c54ad7d37030020002009200254200b20035420051bad370300200441306a24000f0b41eac4c10041331042000b885f05057f037e057f047e067f230041c0076b22022400200241003a00a006200241a0066a2001280200220320012802042204410047220510f8021a02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020042005490d00200141046a200420056b22063602002001200320056a2205360200024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402004450d0020022d00a0062204410c4b0d0a024020040e0d00090607030a0c080e050d0204000b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d8101200141046a200620046b3602002001200520046a3602002006450dbe0120022d00a006450d0f0cbe010b2000410d360200200241c0076a24000f0b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d8001200141046a200620046b22033602002001200520046a22043602002006450d7c20022d00a0062205450d0e20054101470d7c200241a8056a200110960120022802a805450d7c200241b8056a290300210720022903b005210820024198056a2001109701200228029805450d7c20022903a005210920024190056a2001103a200228029005450d7c2002280294052204417f4c0d8c012004450d68200410002205450daa0120054100200410f7021a0c690b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d8001200141046a200620046b22033602002001200520046a220a3602002006450d4e20022d00a006220b41094b0d4e4102210c0240200b0e0a4e004547434a4b484d444e0b200241a0016a2001103a20022802a001450d4e20022802a4012204410876210d4103210c0c480b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d800141042103200141046a200620046b220e3602002001200520046a22043602002006450d1820022d00a0062205450d0d20054101470d18200241a0066a200e4120200e41204922061b22056a41004100412020056b2005411f4b1b10f7021a200241a0066a2004200510f8021a41042103200141046a200e20056b3602002001200420056a36020020060d17200220022f00a1063b01ce0520022d00a006210120022800a306210420022900a706210920022900af06210720022800b706210520022800bb06210620022d00bf06210e200220022f01ce0522033b01a006200220033b01cc05200220033b01ca05410321030cb7010b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d8001200141046a200620046b3602002001200520046a3602002006450db80120022d00a006450d090cb8010b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d8001200141046a200620046b3602002001200520046a3602002006450d0e20022d00a0062204450d0c20044101470d0e200241a0066a200110a20120022d00a00622044102460d0e20022d00a306210520022f00a106210e200241ac066a2902002109200241bc066a2902002107200241b8066a2802002106200241b4066a280200210320022902a4062108200241f8006a20011096012002280278450d0e200241f8006a41106a290300210f2002290380012110200241e0006a20011096012002280260450d0e200e2005411074722101200241f0006a290300211141032105200229036821120c0d0b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d8001200141046a200620046b22033602002001200520046a22043602002006450d3220022d00a0062205450d1120054101460d1020054102470d32200241003a00a006200241a0066a20042003410047220510f8021a20032005490d8d0141042106200141046a200320056b3602002001200420056a3602002003450d3220022d00a00641017121010c120b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d8001200141046a200620046b22033602002001200520046a22043602002006450d1b20022d00a006220541044b0d1b024020050e05001d171916000b200241a0066a200110d50220022802a0062101200241f0066a200241a0066a41047241cc0010f8021a2001410d460d1b200241d0056a200241f0066a41cc0010f8021a41d00010002204450d9b0120042001360200200441046a200241d0056a41cc0010f8021a410221050c1a0b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d8001200141046a200620046b22033602002001200520046a22053602002006450d7020022d00a006220641054b0d704103210e024020060e06005d2627242a000b200241186a2001103a2002280218450d70200228021c2205417f4c0d85012005450d58200510002204450da00120044100200510f7021a0c590b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d8001200141046a200620046b22033602002001200520046a22043602002006450d4b20022d00a006220541054b0d4b024020050e06002a2728242b000b200241a0066a200110d50220022802a0062105200241f0066a200241a0066a41047241cc0010f8021a2005410d460d4b200241d0056a200241f0066a41cc0010f8021a41d00010002204450d9c0120042005360200200441046a200241d0056a41cc0010f8021a20024188026a2001109601200229038802a7450d4a20024198026a29030021072002290390022109410221060c2b0b2000410d360200200241c0076a24000f0b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d7f200141046a200620046b3602002001200520046a3602002006450da80120022d00a006220441084b0da801024020040e09003431323035373338000b200241c0026a2001103a20022802c002450da80120022802c4022213417f4c0d82012013450d60201310002206450da2012013ad2109200141046a210341002114034020032802002104200241003a00a006200241a0066a2001280200220e2004410047220510f8021a20042005490d85012003200420056b3602002001200e20056a3602002004450d6320022d00a006210e02402009422088a72009a72204470d00200441016a22052004490d850120044101742215200520052015491b22054100480d8501024002402004450d00200510002215450d8901201520062005200420052004491b10f802210420061001200421060c010b200510002206450d88010b2009428080808070832005ad8421090b20062009422088a76a200e4101713a000020094280808080107c2109201441016a22142013490d000c620b0b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d7f200141046a200620046b22033602002001200520046a22043602002006450d1e20022d00a006220541044b0d1e024020050e05001c1a1b13000b200241f0036a200110960120022802f003450d1e20024180046a290300210920022903f8032107200241a0066a200110a2014102210520022d00a00622044102460d1e200241bc066a2902002108200241b4066a290200210f20022f00a106210120022d00a306210620022902a40621102002200241ac066a2902003703f806200220103703f0062002200f37038007200120064110747221010c1d0b200241003a00a006200241a0066a20052006410047220410f8021a20062004490d7f200141046a200620046b22033602002001200520046a22043602002006450d0820022d00a0062205450d0720054101470d08200241a0066a200341202003412049220e1b22056a41004100412020056b2005411f4b1b10f7021a200241a0066a2004200510f8021a41042106200141046a200320056b3602002001200420056a360200200e0d17200220022f00a1063b01f00620022d00a006210320022800a306210420022900af06210920022800b706210e20022800bb06211420022d00bf06211320022900a7062107200220022f01f00622053b01a006200220053b01cc05200241e0036a2001103a20022802e003450da90120022802e4032105200141046a22162802002106200241003a00a006200241a0066a200128020022172006410047221510f8021a20062015490d8e012016200620156b3602002001201720156a3602002006450d4e2007422088a721152007a7210120022d00a0062116200220022f01cc053b01ce05410321060caa010b200241e8036a2001103a20022802e803450dae0120022802ec032204417f4c0d7f2004450d4320041000220e450d8b01200e4100200410f7021a0c440b200241086a20011097012002290308a7450dae012002290310210920004100360200200041106a2009370300200041086a4202370300200241c0076a24000f0b200241a0066a20034120200341204922061b22056a41004100412020056b2005411f4b1b10f7021a200241a0066a2004200510f8021a4104210e200141046a200320056b3602002001200420056a36020020060d09200220022f00a1063b01f00620022d00a006210620022800a306210520022900a706211120022900af06211220022800b706210320022800bb06211420022d00bf062113200220022f01f00622043b01a006200220043b01cc05200241f0046a200110960120022802f004450d6020024180056a290300210f20022903f8042109200241e0046a200110970120022802e004450d6020022903e8042110200241d8046a2001103a20022802d804450d6020022802dc042204417f4c0d7d2004450d5e200410002217450d9e0120174100200410f7021a0c5f0b200241c0056a2001103a4100210420022802c005450d2520022802c4052205417f4c0d7c2005450d47200510002213450d890120134100200510f7021a0c480b200241a0066a200110a2014102210520022d00a00622044102460d0120022d00a306210e20022f00a1062114200241ac066a2902002109200241bc066a2902002107200241b8066a2802002106200241b4066a280200210320022902a4062108200241c8006a20011096012002280248450d012014200e411074722101200241c8006a41106a290300210f200229035021100b200020013b000d200041023602002000410f6a20014110763a0000200041c8006a2011370200200041c0006a2012370200200041386a200f370200200041306a2010370200200041186a2009370000200041106a2008370000200041286a2007370000200041246a2006360000200041206a20033600002000410c6a20043a0000200041086a2005360200200241c0076a24000f0b2000410d360200200241c0076a24000f0b200241d8036a2001103a20022802d803450d0020022802dc032104200241a0066a200110d50220022802a0062105200241f0066a200241a0066a41047241cc0010f8021a2005410d470d240b200220022f01ce053b01a0060ca5010b20024190016a2001109701200229039001a7450d212002290398012209422088a7210e2009a72114410321060c010b200241a0066a20034120200341204922061b22056a41004100412020056b2005411f4b1b10f7021a200241a0066a2004200510f8021a200141046a200320056b3602002001200420056a36020020060d1f200220022f00a1063b01f00620022d00a006210120022800a306211320022900af06210920022800b706210320022800bb06210520022d00bf06210420022900a7062107200220022f01f00622063b01a006200220063b01cc05200220063b01ce05200220022f01ce0522063b01d005200220063b01ca052007422088a7210e2007a72114410221060b200220022f01ca0522153b01a006200220153b01c805200020013a0009200041086a20063a000020004103360200200041286a20043a0000200041246a2005360200200041206a2003360200200041186a2009370200200041146a200e360200200041106a20143602002000410c6a2013360200200020022f01c8053b000a200241c0076a24000f0b200220022f01f0063b01a0060c630b200220022f01ce053b01a0060b0c9e010b200241c8036a200110970120022903c803a7450d0520022903d0032209422088a721012009a72106410621050c030b200241a0066a200341202003412049220e1b22066a41004100412020066b2006411f4b1b10f7021a200241a0066a2004200610f8021a41042105200141046a200320066b3602002001200420066a360200200e0d37200220022f00a1063b01f00620022d00a006210320022800a306210420022900af06210920022800b706210e20022800bb06211420022d00bf06211320022900a7062107200220022f01f00622013b01a006200220013b01cc05200220013b01ce052007422088a721012007a721060c480b200241d0046a2001103a20022802d004450d0b20022802d40422044108762101410621050c090b200241b8036a200110970120022903b803a7450d0220022903c0032209422088a721012009a72106410521050b0b200220022f01ce053b01a0060c460b200220022f01ce053b01a0060c96010b200241a0066a200341202003412049220e1b22056a41004100412020056b2005411f4b1b10f7021a200241a0066a2004200510f8021a200141046a200320056b22063602002001200420056a2205360200200e0d32200220022f00a1063b01f00620022d00a006210320022800a306210420022900a706210720022900af06210920022800b706210e20022800bb06211420022d00bf062113200220022f01f00622153b01a006200220153b01d005200241003a00a006200241a0066a20052006410047221510f8021a20062015490d7f200141046a200620156b3602002001200520156a3602002006450d4120022d00a0062101200220022f01d0053b01ce05200141017121152007422088a721012007a72106410321050c430b200220022f01f0063b01a0060c91010b200241003602a006200241a0066a200420034104200341044922061b220510f8021a200141046a200320056b3602002001200420056a36020020060d0420022802a0062104200241b0046a200110960120022802b004450d04200241c0046a290300210920022903b8042107200241a0046a200110970120022802a004450d0420022903a8042108200241003602a00641042105200241a0066a2001280200220e200141046a221428020022064104200641044922131b220310f8021a2014200620036b3602002001200e20036a36020020130d0420022802a006210120024180076a2009370300200220073703f806200220013602f006200441087621010c030b200241c8046a2001103a20022802c804450d0320022802cc0422044108762101410521050c010b20024188046a2001109601200229038804a7450d0220024198046a290300210920022002290390043703f006200220093703f806410321050b0b200241a0066a41106a200241f0066a41106a290300220f370300200241a0066a41086a200241f0066a41086a2903002210370300200241d0056a41086a22062010370300200241d0056a41106a2203200f370300200220022903f006220f3703d0052002200f3703a006200041386a2009370200200041306a20073702002000410c6a2001410874200441ff017172360200200041086a20053602002000410a360200200041286a2008370200200041106a20022903d005370200200041186a2006290300370200200041206a2003290300370200200241c0076a24000f0b200241a0066a41106a200241f0066a41106a290300370300200241a0066a41086a200241f0066a41086a290300370300200220022903f0063703a0062000410d360200200241c0076a24000f0b200241286a2001103a2002280228450d4c200228022c2205417f4c0d612005450d30200510002204450d7d20044100200510f7021a0c310b200241b0026a2001103a20022802b002450d274106210620022802b40221040c070b200241206a2001103a2002280220450d4a20022802242205417f4c0d5f2005450d30200510002204450d7c20044100200510f7021a0c310b200242003703a006200241a0066a200520034108200341084922061b220410f8021a200141046a200320046b3602002001200520046a36020020060d4920022903a00621094105210e0c350b200241a8026a2001103a20022802a802450d2420022802ac022104200141046a22032802002105200241003a00a006200241a0066a2001280200220e2005410047220610f8021a20052006490d6e2003200520066b3602002001200e20066a3602002005450d2420022d00a0062105410421060c050b200241a0066a200110d50220022802a0062105200241f0066a200241a0066a41047241cc0010f8021a2005410d460d23200241d0056a200241f0066a41cc0010f8021a41d00010002204450d7520042005360200200441046a200241d0056a41cc0010f8021a200141046a22032802002105200241003a00a006200241a0066a2001280200220e2005410047220610f8021a20052006490d762003200520066b22143602002001200e20066a22063602002005450d2220022d00a006220541034f0d2242002107200242003703a006200241a0066a2006201441082014410849220e1b220310f8021a200141046a201420036b3602002001200620036a360200200e0d2220022903a0062109410521060c040b200241c0006a2001103a2002280240450d4620022802442217ad220942187e2207422088a70d5b2007a72205417f4c0d5b2005450d302005100022040d31200541041019000b200241a0026a2001103a20022802a002450d214103210620022802a40221040c010b200242003703a006200241a0066a2004200341082003410849220e1b220510f8021a200141046a2214200320056b22063602002001200420056a2204360200200e0d2020022903a0062109200241003602a006200241a0066a20042006410420064104491b220510f8021a2014200620056b3602002001200420056a360200200641034d0d2020022802a006210442002107410721060b0b200220022f01ce0522013b01a006200220013b01cc05200041186a2007370200200041106a2009370200200020053a0009200041086a20063a0000200041053602002000410c6a2004360200200020022f01cc053b000a200241c0076a24000f0b0c230b200220022f01f0063b01a006200220022f01ce053b01d0050b200220022f01ca053b01a0062000410d360200200241c0076a24000f0b200241d0056a200241f0066a41cc0010f8021a41d00010002201450d6220012005360200200141046a200241d0056a41cc0010f8021a200220022f01ce053b01a006410221060c7e0b200241a0066a200110a20120022d00a00622064102460d7820022d00a306210420022f00a106210e200241ac066a290200210f200241bc066a2902002109200241b8066a2802002105200241b4066a280200210320022902a4062110200241f8026a200110960120022802f802450d78200241f8026a41106a29030021072002290380032108200241f0026a2001103a20022802f002450d78200e2004411074722101200f422088a72114200fa7211320022802f40221162010420888210f2010a72104410621150c7a0b200241e0026a2001103a20022802e002450d7720022802e40222064108762101410421150c040b200241e8026a2001103a20022802e802450d7620022802ec0222064108762101410521150c030b20024198036a2001109701200229039803a7450d7520022903a0032209420888210f2009a72104410921150c050b200241d8026a2001103a20022802d802450d7420022802dc022106200241a0066a200110a20120022d00a00622044102460d74200241ac066a2902002109200241bc066a2902002107200241b4066a2802002105200220022902a40622083700f306200241fb066a2009370000200220022d00a3063a00f206200220022f00a1063b01f0062002200241b8066a2802003602d005200220073702d405200241d0026a2001103a20022802d002450d7420022802d402210e200241c8026a2001103a20022802c802450d742007422088a721162008422088a721132009422088a721032009a721142006410876210120023502f00620023301f40620023100f6064210868442208684210f20022903d005210920022802cc02ad210842002107410321150c760b20024190036a2001103a200228029003450d7320022802940322064108762101410721150b0c730b200241a0066a200110a20120022d00a00622064102460d7120022902a4062207420888210f20022f00a10620022d00a306411074722101200241ac066a2902002208422088a72114200241b4066a2802002103200241b8066a2802002105200241bc066a29020021092007a721042008a72113410821150c730b200241a8036a200110970120022903a803a7450d7020022903b0032209420888210f2009a72104410a21150b0c700b200241d0016a2001103a20022802d001450d0b20022802d4012104200241c8016a2001103a20022802c801450d0b20022802cc012105200241b0016a200110960120022903b001a7450d0b200241c0016a29030021092004410876210d20022903b8012207a721174106210c0c020b20024180026a2001103a200228028002450d0a2002280284022204410876210d410b210c0c040b200241a0066a200110a20120022d00a00622044102460d09200241ac066a290200210920022f00a10620022d00a30641107472210d200241bc066a2902002207422088a721132007421088a721142007420888a72115200241b4066a2802002105200241b8066a28020021062007a7210e20022902a4062207a721174104210c0b2007422088a721160c070b200241a8016a2001103a20022802a801450d0720022802ac012204410876210d4105210c0c010b200241f8016a2001103a20022802f801450d0620022802fc012204410876210d4109210c0b0c040b200241d8016a200110970120022903d801a7450d0420022903e0012209422088a721162009a721174107210c0c010b200241e8016a200110970120022903e801a7450d0320022903f0012209422088a721162009a721174108210c0b0c010b200241003a00a006200241a0066a200a2003410047220410f8021a20032004490d4e200141046a200320046b3602002001200a20046a3602002003450d0120022d00a0064101712118410a210c0b200220022f01f00622013b01a006200220013b01d005200020183a0009200041086a200c3a0000200041043602002000412c6a2013360200200020143b012a200020153a0029200041286a200e3a0000200041246a2006360200200041206a2005360200200041186a2009370200200041146a2016360200200041106a20173602002000410c6a200d410874200441ff017172360200200020022f01d0053b000a200241c0076a24000f0b200220022f01f0063b01a0062000410d360200200241c0076a24000f0b4101210e0b200e2001280200200141046a22062802002203200420032004491b220510f802210e200628020022142005490d412006201420056b3602002001200128020020056a3602000240200320044f0d00200e10010c6a0b200e450d6920004289808080203703002000410c6a2004ad2209422086200984370200200041086a200e360200200241c0076a24000f0b200410a001200410010b200220022f01ce053b01a0062000410d360200200241c0076a24000f0b200220022f01f0063b01a0060c010b200220022f01f0063b01a0060b410721050c0f0b410121130b20132001280200200141046a220e2802002214200520142005491b220610f8022113200e28020022152006490d3b2005ad22094220862009842109200e201520066b3602002001200128020020066a3602000240201420054f0d00201310010c010b02402013450d0041022103201321040c610b201321040b0c5f0b410421060c5a0b410121040b20042001280200200141046a2203280200220e2005200e2005491b220610f8022113200328020022142006490d412003201420066b3602002001200128020020066a360200200e2005490d192013450d1a2005ad220942208620098421094106210e0c060b410121040b20042001280200200141046a2203280200220e2005200e2005491b220610f8022113200328020022142006490d402003201420066b3602002001200128020020066a360200200e2005490d172013450d182005ad220942208620098421094104210e0c040b410121040b20042001280200200141046a2203280200220e2005200e2005491b220610f8022113200328020022142006490d3f2003201420066b3602002001200128020020066a360200200e2005490d152013450d162005ad220942208620098421094102210e0c020b410421040b02402017450d00200141046a2106410021150340200241386a2001103a2002280238450d14200228023c2205417f4c0d2b024002402005450d00200510002214450d3620144100200510f7021a0c010b410121140b201420012802002006280200220e2005200e2005491b220310f8022114200628020022132003490d2f2006201320036b3602002001200128020020036a360200200e2005490d132014450d142005ad22074220862007842107200241306a2001103a2002280230450d1220022802342205417f4c0d2b024002402005450d00200510002213450d3720134100200510f7021a0c010b410121130b201320012802002006280200220e2005200e2005491b220310f8022113200628020022162003490d302006201620036b3602002001200128020020036a360200200e2005490d112013450d1202402009422088a722032009a7470d00200341016a220e2003490d2d20034101742216200e200e2016491bad220842187e220f422088a70d2d200fa7220e4100480d2d024002402003450d00200e10002216450d3920162004200e200341186c22032003200e4b1b10f802210320041001200321040c010b200e10002204450d380b20094280808080708320088421090b20042009422088a741186c6a2203201336020c2003200737020420032014360200200341106a2005ad220742208620078437020020094280808080107c2109201541016a22152017490d000b0b2004450d144107210e0b20004101360200200041106a20093702002000410c6a2004360200200041086a200e360200200241c0076a24000f0b410721050b0b200220022f01ce053b01a00620054107460d510b200220022f01a0063b01ca05200020033a0009200041086a20053a000020004107360200200020153a0029200041286a20133a0000200041246a2014360200200041206a200e360200200041186a2009370200200041146a2001360200200041106a20063602002000410c6a2004360200200020022f01ca053b000a200241c0076a24000f0b410121050b20052001280200200141046a2203280200220e2004200e2004491b220610f8022114200328020022132006490d392003201320066b3602002001200128020020066a360200200e2004490d112014450d122004ad220f422086200f84211120024188056a2001103a200228028805450d10200228028c052204417f4c0d222004450d0e200410002213450d4520134100200410f7021a0c0f0b42002109410121060b2006450d46200241b8026a2001103a20022802b802450d0520022802bc0221132009420888210f200641087621012009a72104410221150c470b2009a7450d450c440b410121170b20172001280200200141046a22152802002216200420162004491b220e10f802211720152802002218200e490d3c20152018200e6b36020020012001280200200e6a36020002400240201620044f0d00201710010c010b2017450d00200220022f01cc053b01d0052004ad2207422086200784220742088842088620074238862017ad4218868422084238888421072013ad42ff018320084208868421084102210e0c020b4104210e0b0b200220022f01d0053b01a006200e4104460d0c0c3f0b2009a70d3f0c400b201310010b2007a7450d010b201410010b02402009422088a72201450d00200141186c21052004210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141186a2101200541686a22050d000b0b2009a7450d010b200410010b2000410d360200200241c0076a24000f0b410121130b20132001280200200141046a2203280200220e2004200e2004491b220610f8022113200328020022152006490d342003201520066b3602002001200128020020066a3602000240200e20044f0d00201310010c010b2013450d00200220022f01d0053b01a0062004ad220f422086200f84220f4220862013ad842112200f422088a721034103210e0c360b2011a7450d010b201410010b200220022f01d0053b01a0060b2000410d360200200241c0076a24000f0b20052004107a000b20042006107a000b20042006107a000b20042006107a000b20042006107a000b20042006107a000b20042006107a000b20042006107a000b20042006107a000b20042006107a000b20042006107a000b20042006107a000b20042006107a000b20042006107a000b102c000b1018000b20052004107a000b200541011019000b20032013107a000b20032016107a000b20052003107a000b20052014107a000b20062015107a000b200541011019000b200541011019000b200e41041019000b200441011019000b200541011019000b20152006107a000b41d00041081019000b20042003107a000b20062005107a000b20062014107a000b20062014107a000b20062014107a000b41d00041081019000b20152006107a000b20062013107a000b41d00041081019000b41d00041081019000b20062005107a000b200541011019000b200541011019000b200541011019000b200441011019000b200e2018107a000b201341011019000b200441011019000b20062015107a000b200441011019000b200220022f01a0063b01ce05200041c0006a200f370000200041386a2009370000200041306a2007370000200041286a2008370000200020063a0009200041086a200e3a00002000410b360200200041c8006a2010370000200041246a2014360000200041206a2003360000200041186a2012370000200041106a20113700002000410c6a2005360000200020022f01ce053b000a200241c0076a24000f0b200610010b2000410d360200200241c0076a24000f0b0b20004106360200200041c0006a2007370200200041386a2008370200200041346a200e360200200041306a2016360200200041286a2009370200200041246a2005360200200041206a20033602002000411c6a2014360200200041186a2013360200200041086a20153602002000410c6a2001410874200641ff017172360200200041106a200f4208862004ad42ff018384370200200241c0076a24000f0b0b200220022f01ce053b01a00620064104460d030b200220022f01a0063b01ca05200020033a0005200020063a000420004108360200200041286a2005360200200020163a0025200041246a20133a0000200041206a20143602002000411c6a200e360200200041146a2009370200200041106a20153602002000410c6a2001360200200041086a2004360200200020022f01ca053b0006200241c0076a24000f0b2000410d360200200241c0076a24000f0b200241a0066a41026a2214200241f0066a41026a2d00003a0000200220022f01ca053b01ce05200220022f00f0063b01a006024020034104470d002000410d360200200241c0076a24000f0b200241d0056a41026a221320142d00003a0000200220022f01ce053b01c805200220022f01a0063b01d005200020013a0005200020033a00042000410c360200200041246a200e3a0000200041206a20063600002000411c6a2005360000200041146a20073700002000410c6a2009370000200041086a2004360000200020022f01c8053b0006200020022f01d0053b0025200041276a20132d00003a0000200241c0076a24000f0b2000410d360200200241c0076a24000f0b2000410d360200200241c0076a24000f0b2000410d360200200241c0076a24000b851108067f017e017f027e087f017e037f037e230041d0006b22022400024002400240024002400240024002400240024002400240024002400240024002400240024020012d00002203450d0020034101470d01200041003a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a29000037000020030d024101450d120c110b200241336a2001410c6a280000360000200041013a00002002200141046a29000037002b20002002290028370001200041086a2002412f6a29000037000020030d0141000d100c110b20034103470d0520022001410c6a280200220436021c2002200141046a2802002205360218200241003a0028200241286a20052004410047220610f8021a20042006490d072002200420066b220736021c2002200520066a22063602182004450d050240024002400240024020022d00282204450d00024020044101460d0020044102470d0b200241003a0028200241286a20062007410047220410f8021a20072004490d0f2002200720046b220536021c2002200620046a22043602182007450d0b20022d00280d0b20024200370328200241286a200420054108200541084922061b220710f8021a2002200520076b36021c2002200420076a36021820060d0b20022903282108200241086a200241186a103a2002280208450d0b200228020c2209ad220a42287e220b422088a70d0e200ba72207417f4c0d0e2007450d0220071000220c450d1420090d030c040b200241003a0028200241286a20062007410047220410f8021a20072004490d0f2002200720046b36021c2002200620046a3602182007450d0a20022d00280d0a200241286a200241186a103920022802282207450d0a200229022c2108200241146a41026a200241286a41026a2d00003a0000200220022f00283b0114410121060c040b200241003a0028200241286a20062007410047220510f8021a20072005490d0f2002200720056b220436021c2002200620056a22053602182007450d1120022d00280d1141002106200241286a2004412020044120491b22076a41004100412020076b2007411f4b1b10f7021a200241286a2005200710f8021a2002200420076b36021c2002200520076a3602182004411f4d0d10200241cc006a41026a220d200241286a41026a22052d00003a0000200220022f00283b014c200228002b2107200229002f21082002280037210c200229003b210a200228004321042002310047210b2005200d2d0000220d3a0000200241246a41026a220e200d3a0000200220022f014c220d3b01242002200d3b0128200241c8006a41026a220d200e2d00003a0000200220022f01243b01482005200d2d0000220d3a0000200241146a41026a200d3a0000200220022f014822053b0114200220053b01280c030b4108210c2009450d010b20022802182105200228021c21042002412b6a210f200241376a21102002413b6a2111200241c3006a21124100210d0340200241286a2004412020044120491b22076a41004100412020076b2007411f4b1b10f7021a200241286a2005200710f8021a2002200420076b220636021c2002200520076a22073602182004411f4d0d06200241cc006a41026a2204200241286a41026a22052d00003a0000200220022f00283b014c200f280000210e200241286a41076a290000210b201028000021132011290000211420122800002115200241286a411f6a2d00002116200520042d000022043a0000200241246a41026a221720043a0000200220022f014c22043b0124200220043b012820024200370328200241286a20072006410820064108491b220510f8021a2002200620056b220436021c2002200720056a2205360218200641074d0d0720022903282118200220172d00003a004a200220022f01243b0148200220022d004a3a002a200220022f01483b01280240200a422088a7200aa72207470d00200741016a22062007490d0620074101742217200620062017491bad221942287e221a422088a70d06201aa722064100480d06024002402007450d00200610002217450d0c2017200c2006200741286c2207200720064b1b10f8022107200c10012007210c0c010b20061000220c450d0b0b200a42808080807083201984210a0b200c200a422088a741286c6a220720022f01283b010020022d002a210620072018370320200720163a001f2007201536001b200720143700132007201336000f2007200b3700072007200e360003200741026a20063a0000200a4280808080107c210a200d41016a220d2009490d000b0b200c450d0641022106200241146a41026a200241286a41026a2d00003a0000200220022f00283b01140b200241286a41026a2205200241146a41026a2d00003a0000200220022f01143b0128200020063a0000200041206a200b3700002000411c6a2004360000200041146a200a370000200041106a200c360000200041086a2008370000200041046a2007360000200020022f01283b0001200041036a20052d00003a00002003450d010b2003417f6a4102490d0f024020030d00200141086a280200450d10200141046a2802001001200241d0006a24000f0b200141086a280200450d0f200141046a2802001001200241d0006a24000f0b41010d0d0c0e0b1018000b200241286a41026a200241cc006a41026a2d00003a0000200220022f004c3b01280b200aa7450d00200c10010b41a79ec100411e1042000b200641081019000b20062004107a000b102c000b20042007107a000b20042007107a000b20052007107a000b200241286a41026a200241cc006a41026a2d00003a0000200220022f004c3b01280b200241286a41026a200241c8006a41026a2d00003a0000200220022f00483b012841a79ec100411e1042000b200741081019000b200141086a280200450d00200141046a2802001001200241d0006a24000f0b200241d0006a24000bd806010a7f230041106b22022400200241003602082002420137030020012802002103200128020822012002101b0240024002400240024002402001450d00200320014105746a210403402003280200200341086a2802002002108e012003410c6a280200200341146a2802002002108e01200241086a2205280200210120022802042106024002400240024002400240024002400240024002400240024002400240200341186a2802004101470d0020062001470d01200141016a22062001490d1120014101742207200620062007491b22064100480d112001450d0320022802002107200610002208450d122008200720062001200120064b1b10f8021a200710010c040b20062001470d01200141016a22062001490d1020014101742207200620062007491b22064100480d102001450d0520022802002107200610002208450d122008200720062001200120064b1b10f8021a200710010c060b200228020021080c030b200228020021080c050b200610002208450d0e0b20022006360204200220083602000b2005200141016a2207360200200820016a41023a00002003411c6a28020021090240200620076b41034b0d00200741046a220a2007490d0c2006410174220b200a200a200b491b220b4100480d0c200b1000210a2006450d04200a450d0f200a2008200b20062006200b4b1b10f8021a200810010c050b2008210a0c050b200610002208450d0c0b20022006360204200220083602000b2005200141016a2207360200200820016a41013a00002003411c6a28020021090240200620076b41044f0d00200741046a220a2007490d0920064101742201200a200a2001491b220b4100480d09200b100021012006450d042001450d0d20012008200b20062006200b4b1b10f8021a200810010c050b200141056a210a200821010c050b200a450d0a0b2002200b3602042002200a3602000b2005200141056a360200200a20076a2009360000200341206a22032004470d030c040b2001450d080b2002200b360204200220013602000b2005200a360200200120076a2009360000200341206a22032004470d000b0b20002002290300370200200041086a200241086a280200360200200241106a24000f0b1018000b200641011019000b200641011019000b200b41011019000b200b41011019000bcb0401057f230041106b22022400200241003a0008200241086a2001280200220320012802042204410047220510f8021a024020042005490d00200141046a200420056b22063602002001200320056a22053602000240024002400240024002400240024002402004450d0020022d0008417f6a220441034b0d04024020040e0400030204000b20024100360208200241086a20052006410420064104491b220410f8021a200141046a200620046b3602002001200520046a360200200641034d0d052000200228020836020420004100360200200241106a24000f0b20004104360200200241106a24000f0b20024100360208200241086a20052006410420064104491b220410f8021a200141046a200620046b3602002001200520046a360200200641034d0d042000200228020836020420004102360200200241106a24000f0b20024200370308200241086a20052006410820064108491b220410f8021a200141046a200620046b3602002001200520046a360200200641074d0d04200041086a200229030837030020004101360200200241106a24000f0b20024200370308200241086a20052006410820064108491b220410f8021a200141046a200620046b3602002001200520046a360200200641074d0d04200041086a200229030837030020004103360200200241106a24000f0b20004104360200200241106a24000f0b20004104360200200241106a24000f0b20004104360200200241106a24000f0b20004104360200200241106a24000f0b20004104360200200241106a24000f0b20052004107a000b6e01017f024002400240200028020022024101460d0020024102460d0120024103470d02200141041024200041086a290300200110230f0b200141021024200041086a290300200110230f0b200141031024200028020420011089010f0b200141011024200028020420011089010b3400200041efa3c10036020420004100360200200041146a4103360200200041106a41ecf6c200360200200041086a42093702000b4b00200041ddf5c10036020420004100360200200041206a41013602002000411c6a41b8f8c200360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000b340020004185a9c10036020420004100360200200041146a4108360200200041106a41c0f9c200360200200041086a420d3702000b4b00200041ddf5c10036020420004100360200200041206a41053602002000411c6a41a8fdc200360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000b1300200041023602042000419080c3003602000b970302057f017e230041c0006b220224000240411c10002203450d002002421c37023420022003360230200241306a41a0a3c100411c1025200241086a220320022802383602002002200229033037030020012002101e200328020021042002280204210520022802002101200241306a41086a220642003703002002420037033020012004200241306a100220032006290300370300200220022903303703004100210302400240200241104188f0c100410041001004417f460d002002200236021020024110360214200242003703302002410020024110200241306a41084100100422032003417f461b2203410820034108491b360218200341074d0d0120022903302107200241306a200241106a103620022802302203450d0120022002290234370320200241306a41086a2204200241206a41086a28020036020020022002290320370330200020073703002000200229033037020c200041146a20042802003602000b2000200336020802402005450d00200110010b200241c0006a24000f0b41eac4c10041331042000b411c41011019000bae0603077f017e017f230041d0006b22012400200141286a41086a22024200370300200142003703284190f3c100410d200141286a1002200141086a41086a2002290300370300200120012903283703080240024002400240200141086a41104188f0c100410041001004417f460d002001421037021c2001200141086a360218200141286a200141186a10ea0220012802282203450d02200141306a2802002104200128022c21050c010b410021030b200141286a41206a2206200041206a290300370300200141286a41186a2207200041186a290300370300200141286a41106a200041106a2903003703002002200041086a290300370300200120002903003703282003410820031b210202400240024002402004410020031b22002005410020031b2205470d00200041016a22032000490d0320004101742204200320032004491b2205ad42287e2208422088a70d032008a722034100480d032000450d01200310002204450d05200420022003200041286c2209200920034b1b10f8021a200210010c020b200221040c010b200310002204450d030b2004200041286c6a22032001290328370300200341206a2006290300370300200341186a2007290300370300200341106a200141286a41106a290300370300200341086a200141286a41086a22032903003703002001200041016a22063602202001200536021c200120043602182001410036023020014201370328200141286a200141186a101f200128022c2107200128023021092001280228210220034200370300200142003703284190f3c100410d200141286a1002200141086a41086a200329030037030020012001290328370308200141086a411020022009100302402007450d00200210010b02402006450d00200041286c41286a2103200421000340024020002d00002202450d00024020024101470d00200041086a280200450d01200041046a2802001001200041286a2100200341586a22030d020c030b200041146a280200450d00200041106a28020010010b200041286a2100200341586a22030d000b0b02402005450d00200410010b200141d0006a24000f0b1018000b41eac4c10041331042000b200341081019000b930504057f017e017f047e230041206b22032400024002400240411810002204450d002003421837021420032004360210200341106a4193f1c10041181025200341086a220420032802183602002003200329031037030020002003101e20042802002105200328020421062003280200210742002108200341106a41086a220942003703002003420037031020072005200341106a1002200420092903003703002003200329031037030002400240200341104188f0c100410041001004417f460d00200342003703182003420037031020034110200341106a4110410010042204417f460d012004410f4d0d01200341186a290300210a200329031021082006450d040c030b4200210a20060d020c030b41eac4c10041331042000b411841011019000b200710010b0240411410002204450d002003421437021420032004360210200341106a41eeefc10041141025200341086a220420032802183602002003200329031037030020002003101e2004280200210520032802042106200328020021074200210b200341106a41086a220942003703002003420037031020072005200341106a10022004200929030037030020032003290310370300024002400240200341104188f0c100410041001004417f460d00200342003703182003420037031020034110200341106a4110410010042204417f460d022004410f4d0d02200341186a290300210c2003290310210b0c010b4200210c0b2002200a2008200156200a200256200a2002511b22041b210d2001200820041b210202402006450d00200710010b2000200b20027c2201200c200d7c2001200b54ad7c10aa012000200820027d200a200d7d2008200254ad7d10d302200341206a24000f0b41eac4c10041331042000b411441011019000bccaf0109027f027e057f017e0e7f017e027f027e147f230041f0026b2201240020014180016a41086a22024200370300200142003703800141b5c6c100411420014180016a100220014198026a41086a20022903003703002001200129038001370398020240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020014198026a41104188f0c100410041001004417f460d00200142003703800120014198026a411020014180016a41084100100441016a41084d0d0220012903800122034200510d044200210420002003824200520d1f0c010b42002104200042e807824200520d1e0b20014180016a41086a22022004370300200120043703800141c9c6c100411420014180016a100220014198026a41086a200229030037030020012001290380013703980220014198026a41104188f0c100410041001004417f460d1d200141003602800120014198026a411020014180016a41044100100441016a41044d0d012001280280012205450d1d20014180016a109e0220014180016a41086a22062802002107200128028401210820012802800121024200210320064200370300200142003703800141f2c6c100411420014180016a100220014198026a41086a220920062903003703002001200129038001370398022007410020021b2107024020014198026a41104188f0c100410041001004417f460d00200120014198026a3602c802200141103602cc0220014200370380012001410020014198026a411020014180016a41084100100422062006417f461b2206410820064108491b22093602d002200641074d0d0520012903800121032001410036028001200141d0026a410020014198026a411020014180016a41042009100422062006417f461b2206410420064104491b20096a360200200641034d0d05200128028001210620014180016a200141c8026a10362001280280012209450d052006200129028401220a422088a76b20076a210b0240200aa7450d00200910010b2002410820021b2109200b2005490d070c060b20064200370300200142003703800141f0f1c100410d20014180016a100220092006290300370300200120012903800137039802024020014198026a41104188f0c100410041001004417f460d00200142003703800120014198026a411020014180016a41084100100441016a41084d0d0420012903800121030b410021062002410820021b2109200720054f0d050c060b41eac4c10041331042000b41eac4c10041331042000b41f08ac300104f000b41eac4c10041331042000b41eac4c10041331042000b0240200620054f0d002007200620056b6a220620074f0d052009200641286c6a29032021030c010b20014180016a41086a2206420037030020014200370380014186c7c100411420014180016a100220014198026a41086a2006290300370300200120012903800137039802024020014198026a41104188f0c100410041001004417f460d00200142003703800120014198026a411020014180016a41084100100441016a41084d0d0220012903800120037c21030c010b420520037c21030b20014180016a41086a22064200370300200142003703800141b5c6c100411420014180016a100220014198026a41086a200629030037030020012001290380013703980202400240024002400240024020014198026a41104188f0c100410041001004417f460d00200142003703800120014198026a411020014180016a41084100100441016a41084d0d02200129038001220a4200520d0141988bc300104f000b42e807210a0b2003200a7c427f7c22032003200a827d210302402002450d002008450d00200910010b20032000520d1a20014180016a109e0220014180016a41086a22022802002106200128028401210c200128028001210d4200210320024200370300200142003703800141c9c6c100411420014180016a100220014198026a41086a220520022903003703002001200129038001370398024100210e024020014198026a41104188f0c100410041001004417f460d00200141003602800120014198026a411020014180016a41044100100441016a41044d0d04200128028001210e0b20024200370300200142003703800141f0f1c100410d20014180016a100220052002290300370300200120012903800137039802024020014198026a41104188f0c100410041001004417f460d00200142003703800120014198026a411020014180016a41084100100441016a41084d0d0220012903800121030b200d4108200d1b210f0240024020064100200d1b221041286c450d00200f41206a2903002003520d00200141f0016a41186a2206200f41186a290000370300200141f0016a41106a2205200f41106a290000370300200141f0016a41086a2207200f41086a2900003703002001200f2900003703f001412010002211450d0d200f41286a2102201120012903f001370000201141186a2006290300370000201141106a2005290300370000201141086a2007290300370000412021074101211241012105201041286c41586a2209450d010340200241206a2903002003520d02200141c8026a41186a200241186a2206290000370300200141c8026a41106a200241106a2208290000370300200141c8026a41086a200241086a220b290000370300200120022900003703c80220014180016a41186a2213200629000037030020014180016a41106a2214200829000037030020014180016a41086a2208200b2900003703002001200229000037038001024020052012470d00201241016a22062012490d162012410174220b20062006200b491b220bad420586220a422088a70d17200aa722064100480d1802402012450d00200610002215450d0b20152011200620124105742212201220064b1b10f80221062011100120062111200b21120c010b200b2112200610002211450d0a0b200241286a2102201120076a2206200129038001370000200641186a2013290300370000200641106a2014290300370000200641086a2008290300370000200741206a2107200541016a2105200941586a22090d000c020b0b4101211141002105410021120b024002400240201020056b200e4f0d0020014180016a41086a220242003703002001420037038001419ac7c100411c20014180016a100220014198026a41086a200229030037030020012001290380013703980220014198026a41104188f0c100410041001004417f460d01200142003703800120014198026a411020014180016a41084100100441016a41084d0d08200129038001210a0c020b2012450d1a20111001200d0d1b0c1c0b42e807210a0b20014100360288012001420137038001410810002202450d082001428880808080013702840120012002360280012002200a20037c370000411010002206450d09200620022900003700002002100120014290808080c001370284012006200520106b200e6a220e3600082001200636028001200520014180016a101b024002402005450d002005410574210b410020014180016a41086a221328020022066b210720012802840121052011210203400240024002400240200520076a41204f0d00200641206a22092006490d1c20054101742208200920092008491b22084100480d1d2005450d012001280280012114200810002209450d092009201420082005200520084b1b10f8021a201410010c020b20012802800121090c020b200810002209450d070b20012008360284012001200936028001200821050b2013200641206a2208360200200920066a220641086a200241086a290000370000200641106a200241106a290000370000200641186a200241186a29000037000020062002290000370000200741606a210720082106200241206a2102200b41606a220b0d000c020b0b20014188016a2802002108200128028401210520012802800121090b20014180016a41086a22024200370300200142003703800141f2c6c100411420014180016a100220014198026a41086a200229030037030020012001290380013703980220014198026a411020092008100302402005450d00200910010b02402012450d00201110010b4108211120014180016a41086a22024200370300200142003703800141b6c7c100410e20014180016a100220014198026a41086a2002290300370300200120012903800137039802410021140240024020014198026a41104188f0c100410041001004417f460d00200142103702cc02200120014198026a3602c80220014180016a200141c8026a10362001280280012213450d0e20014188016a280200210220012802840121100c010b410021130b200141106a2013410120131b221520152002410020131b4105746a102e024020012802142207200128021022066b4105762202450d002002410474220510002211450d0e200221140b02400240024020062007460d0041002105200141086a21092011210203402001200610b001200129030021032002200929030037030820022003370300200541016a2105200241106a21022007200641206a2206470d000b2005413f4d0d012005418080014f0d0241022102410210002209450d11200920054102744101723b00000c1a0b410021050b41012102410110002209450d0b200920054102743a00000c180b024020054180808080044f0d0041042102410410002209450d10200920054102744102723600000c180b410110002206450d10200641033a000041052102410510002209450d11200920062d00003a000020061001200920053600010c170b41eac4c10041331042000b41eac4c10041331042000b200841011019000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b200641011019000b41888bc30020062007104e000b410841011019000b411041011019000b410141011019000b412041011019000b41eac4c10041331042000b200541081019000b410241011019000b410441011019000b410141011019000b410541011019000b410921220c160b410921220c150b410921220c140b410921220c130b410921220c120b024002402011201120054104746a220b460d00410020026b210720022105201121060340200641086a29030021032006290300210a0240200520076a410f4b0d00200241106a22082002490d0f20054101742212200820082012491b22084100480d10024002402005450d00200810002212450d092012200920082005200520084b1b10f802210520091001200521090c010b200810002209450d080b200821050b200920026a220820033700082008200a370000200741706a2107200241106a2102200b200641106a2206470d000c020b0b410121050b20014180016a41086a22064200370300200142003703800141c4c7c100411820014180016a100220014198026a41086a200629030037030020012001290380013703980220014198026a411020092002100302402005450d00200910010b02402014450d00201110010b20014180016a41086a22024200370300200142003703800141dcc7c100411220014180016a100220014198026a41086a220620022903003703002001200129038001370398020240024020014198026a41104188f0c100410041001004417f460d00200141003602800120014198026a411020014180016a41044100100441016a41044d0d0920012802800121020c010b410221020b200141c0026a4200370300200141b8026a4200370300200141b0026a420037030020014198026a41106a42003703002006420037030020014200370398022002200e6a2205ad42307e2203422088a70d0d2003a72202417f4c0d0e024002402002450d00200210002212450d0a201221020c010b41082112410821020b20014180016a41286a220720014198026a41286a29030037030020014180016a41206a220920014198026a41206a29030037030020014180016a41186a220820014198026a41186a29030037030020014180016a41106a220b20014198026a41106a29030037030020014180016a41086a20014198026a41086a29030037030020012001290398023703800102400240024020054102490d004101210603402002200129038001370300200241286a2007290300370300200241206a2009290300370300200241186a2008290300370300200241106a200b290300370300200241086a20014180016a41086a290300370300200241306a2102200641016a22062005490d000b2006417f6a21060c010b410021062005450d010b2002200129038001370300200241286a20014180016a41286a290300370300200241206a20014180016a41206a290300370300200241186a20014180016a41186a290300370300200241106a20014180016a41106a290300370300200241086a20014180016a41086a290300370300200641016a21060b20012006360288012001200536028401200120123602800120014180016a10a20202402005450d00201210010b20014188016a200e360200200141023a008401200141053a00800120014180016a10b4012013450d002010450d00201510010b200d450d010b200c450d00200f10010b20014180016a41086a22022004370300200120043703800141f2c6c100411420014180016a100220014198026a41086a200229030037030020012001290380013703980220014198026a41104188f0c100410041001004417f460d0d200120014198026a3602c802200141103602cc0220014200370380012001410020014198026a411020014180016a41084100100422022002417f461b2202410820024108491b22063602d0020240024002400240200241074d0d0020012903800121042001410036028001200141d0026a410020014198026a411020014180016a41042006100422022002417f461b22024104200241044922021b20066a36020020020d0020014180016a200141c8026a10362001280280012216450d00200128028401211720042000520d1020014180016a41086a22024200370300200142003703800141c4c7c100411820014180016a100220014198026a41086a2206200229030037030020012001290380013703980220014198026a4110100820064200370300200142003703980241f2c6c100411420014198026a10022002200629030037030020012001290398023703800102400240024020014180016a41104188f0c100410041001004417f460d00200120014180016a3602f001200141103602f40120014200370398022001410020014180016a411020014198026a41084100100422022002417f461b2202410820024108491b22063602f801200241074d0d0620012903980221042001410036029802200141f8016a410020014180016a411020014198026a41042006100422022002417f461b2202410420024104491b20066a360200200241034d0d06200128029802210220014198026a200141f0016a10362001280298022218450d06200120023602d002200120043703c802200129029c02211920012802d002211a4108211b4200211c20014198026a41086a22024200370300200142003703980241f2c6c100411420014198026a100220014180016a41086a2206200229030037030020012001290398023703800120014180016a4110100820024200370300200142003703980241eec7c100411320014198026a100220062002290300370300200120012903980237038001024020014180016a41104188f0c100410041001004417f460d00200142103702cc02200120014180016a3602c80220014198026a200141c8026a103e200128029802221b450d0a200129029c02211c20014198026a41086a22024200370300200142003703980241eec7c100411320014198026a100220014180016a41086a200229030037030020012001290398023703800120014180016a411010080b20014180016a41086a22024200370300200142003703800141f0f1c100410d20014180016a100220014198026a41086a2206200229030037030020012001290380013703980242002104024020014198026a41104188f0c100410041001004417f460d00200142003703800120014198026a411020014180016a41084100100441016a41084d0d0520012903800121040b2002420037030020014200370380014186c7c100411420014180016a10022006200229030037030020012001290380013703980220014198026a41104188f0c100410041001004417f460d01200142003703800120014198026a411020014180016a41084100100441016a41084d0d0520012903800121000c020b02402017450d00201610010b419ac9c100410f100641e5c8c10041351006200141f0026a24000f0b420521000b2001200020047c3703184200210a20014180016a41086a22024200370300200142003703800141d0c8c100411520014180016a100220014198026a41086a20022903003703002001200129038001370398020240024020014198026a41104188f0c100410041001004417f460d002001420037038801200142003703800120014198026a411020014180016a4110410010042202417f460d072002410f4d0d0720014188016a290300210a200129038001211d0c010b4209211d0b201b201c422088a7221e41306c6a211102400240024002400240201a450d00201a417f6a210741002106201b2011460d01201b201e41306c6a220241506a2211290300200241586a29030084500d03200141b0026a200241786a290000370300200141a8026a200241706a290000370300200141a0026a200241686a2900003703002001200241606a29000037039802410121060c020b4100211341002107410021060c030b201b21110b410021130c010b410121130b20014189016a20014198026a41086a29030037000020014191016a20014198026a41106a29030037000020014199016a20014198026a41186a290300370000200120063a0080012001200129039802370081014101211f20014180016a410172210202402006450d002002201d200a10e102200141f0016a41186a200241186a290000370300200141f0016a41106a200241106a290000370300200141f0016a41086a200241086a290000370300200120022900003703f00141201000221f450d08201f20012903f001370000201f41186a200141f0016a41186a290300370000201f41106a200141f0016a41106a290300370000201f41086a200141f0016a41086a29030037000020014180016a410172210241202105410121204101212120070d0c0c0b0b200141f0016a41186a200241186a290000370300200141f0016a41106a200241106a290000370300200141f0016a41086a200241086a290000370300200120022900003703f0014100212141002120410f21220c120b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b41eac4c10041331042000b200841011019000b41eac4c10041331042000b41eac4c10041331042000b412041011019000b41eac4c10041331042000b200241081019000b410521220c070b410021220c060b410921220c050b410921220c040b412721220c030b412721220c020b41d60021220c010b41d80021220b03400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020220ead0209101100080f01020393020405069a02071213141517181d1e1f2021253738393a3ba701a801a901aa01ab01ad01ae01a002af01b001b301b701b801b901ba01bb01bc01bd01be01c201d401d501d601d701d801d901da01db01dc01dd01de01ec01ed01ee01ef01f401f501f601f701f8018002810283028402850286028702880289028b028c028d028e028f02900291029202a1028a02f901fa01fb01fc01fd01ff019b02fe018202e801e901ea01eb01f001df01e001f101e101e201f201e301e401f301e501e601e7019c02c301c501c601c701c801d301c901ca01cb01cc01cd01ab02ce01cf01d001d101d201bf01c001c101c401b401b501b601b101b201a902ac01262728292a3c3d3e3f404151525354555762636768696a608401a201a301a401a501a601850186018b018e018f0196029001970291019201930199019f01a001a1019a019b019c019d0194019e019501960197019801990298028c018d01870158880189018a017c7d7e7f800181018301a30282016b6c6d6e797b7a6f70777871729402737495027576a602a502a702616465665a5b5c5d5e5fa40259ac0256424344455046474e4f48499d024a4b9e024c4d9f022b2c362d2e2f3031323335a20234aa02191a1b1c242322a802160a0b0c0e0d0d0b20014180016a41186a2212200929030037030020014180016a41106a2209200829030037030020014180016a41086a2208200b290300370300200120012903c8023703800120212020470db502410621220c9d040b202041016a22062020490db502410721220c9c040b2020410174220b20062006200b491b220bad4205862204422088a70db502410821220c9b040b2004a722064100480db702410a21220c9a040b2020450dbe02410b21220c99040b200610002214450dbe02410c21220c98040b2014201f20062020410574220d200d20064b1b10f8022106201f10012006211f200b21200cad020b200b212020061000221f450dad02410421220c96040b201f20056a2206200129038001370000200641186a2012290300370000200641106a2009290300370000200641086a2008290300370000200541206a2105202141016a21212007450da402410021220c95040b2007417f6a2107201341ff01710da70241a80221220c94040b2011201b460d910441a90221220c93040b201141506a2209290300201141586a290300844200510d910441aa0221220c92040b201141606a2900002104201141686a2900002100201141706a290000210320014198026a41186a2206201141786a29000037030020014198026a41106a2208200337030020014198026a41086a220b200037030020012004370398022002200129039802370000200241086a200b290300370000200241106a2008290300370000200241186a200629030037000041012106200141013a0080012002201d200a10e10241002113200921110ca3020b41002113201b21110ca0020b41012113200921110ca0020b41002107410121220c8e040b2002200129039802370000200241086a20014198026a41086a290300370000200241106a20014198026a41106a290300370000200241186a20014198026a41186a29030037000041002106200141003a008001410221220c8d040b200141c8026a41186a2209200241186a290000370300200141c8026a41106a2208200241106a290000370300200141c8026a41086a220b200241086a290000370300200120022900003703c80220060da1020ca0020b20014180016a109e024100212320012802840121062019422088a7221220014180016a41086a280200410020012802800122021b221341286c220541286e2207200720124b1b2224450db202411021220c8b040b202441057422074100480da802411121220c8a040b200710002225450db102411221220c89040b2006410020021b21142002410820021b221120056a210b20120db2020cb1020b41012125410021242006410020021b21142002410820021b221120056a210b2012450db202411321220c87040b41002123201121022012210520252106411421220c86040b200b20026b419f014d0db302419f0221220c85040b20014180016a41186a200241186a220729000037030020014180016a41106a200241106a220929000037030020014180016a41086a200241086a22082900003703002001200229000037038001200829000021042009290000210020022900002103200641186a2007290000370000200641106a2000370000200641086a20043700002006200337000020054101460dff0341a00221220c84040b200241306a2900002104200241386a290000210020022900282103200641386a200241c0006a290000370000200641306a2000370000200641286a20043700002006200337002020054102460dff0341a10221220c83040b200241d8006a2900002104200241e0006a290000210020022900502103200641d8006a200241e8006a290000370000200641d0006a2000370000200641c8006a20043700002006200337004020054103460dff0341a20221220c82040b20024180016a290000210420024188016a290000210020022900782103200641f8006a20024190016a290000370000200641f0006a2000370000200641e8006a200437000020062003370060202341046a212320064180016a2106200241a0016a21022005417c6a22050dae020cad020b200b2002460daf02411621220c80040b2011201341286c6a210d41012107411721220cff030b20014180016a41186a200241186a220929000037030020014180016a41106a200241106a220829000037030020014180016a41086a200241086a22132900003703002001200229000037038001201329000021042008290000210020022900002103200641186a2009290000370000200641106a2000370000200641086a200437000020062003370000200520072209460daf02411821220cfe030b200941016a2107200641206a2106200d200241286a2202470dad02411921220cfd030b202320096a21230cae020b202341017221230caf020b202341027221230cad020b20234103722123411a21220cf9030b2001201f3602840220014188026a2202201f20214105746a360200200141003a00900220012012360280022001200b3602fc01200120113602f801200120143602f401200120113602f0012001418c026a200141186a36020020014180016a200141f0016a10472001290380014201520dad0241920121220cf8030b417f417f4100200141fc016a280200200141f0016a41086a2802006b41286d220620014180026a2802006b2205200520064b1b220620022802002001280284026b4105766a220220022006491b220241016a220620062002491b2226ad42287e2204422088a70db90241930121220cf7030b2004a72202417f4c0db90241940121220cf6030b410821272002450d900341950121220cf5030b200210002227450d900341960121220cf4030b202720014180016a41086a2202290300370300202741206a200241206a290300370300202741186a200241186a290300370300202741106a200241106a290300370300202741086a200241086a290300370300200141c8026a41206a200141f0016a41206a280200360200200141c8026a41186a2211200141f0016a41186a290300370300200141c8026a41106a2213200141f0016a41106a290300370300200141c8026a41086a200141f0016a41086a290300370300200120012903f0013703c80220014180016a200141c8026a10472001290380014201520d900341910221220cf3030b20014180016a41086a2102200141d4026a2114200141dc026a210d412821054101212841920221220cf2030b20014198026a41206a2207200241206a29030037030020014198026a41186a2209200241186a29030037030020014198026a41106a2208200241106a29030037030020014198026a41086a220b200241086a290300370300200120022903003703980220282026470de60341940221220cf1030b417f417f41002014280200200141c8026a41086a2802006b41286d220620132802006b2212201220064b1b22062011280200200d2802006b4105766a221220122006491b220641016a221220122006491b2206450de60341950221220cf0030b202620066a22062026490d8e0241960221220cef030b20264101742212200620062012491b2212ad42287e2204422088a70d8e0241970221220cee030b2004a722064100480d8e0241980221220ced030b2026450de30341990221220cec030b20061000220f450de303419a0221220ceb030b200f20272006202641286c220e200e20064b1b10f802210620271001200621270ce3030b200610002227450de303419b0221220ce9030b2012212641930221220ce8030b202720056a2206200129039802370300200641206a2007290300370300200641186a2009290300370300200641106a2008290300370300200641086a200b290300370300200541286a2105202841016a212820014180016a200141c8026a10472001290380014201510d85030c86030b200141f8016a22062802002202200141fc016a2802002205460d9c02411c21220ce6030b20062002200520026b41586a41286e41286c6a41286a360200411d21220ce5030b20012802f401450d9b02411e21220ce4030b20012802f0011001411f21220ce3030b4100212641082127410021280c9a020b4101212841980121220ce1030b200141d0026a22062802002202200141d4026a2802002205460d800341990121220ce0030b20062002200520026b41586a41286e41286c6a41286a360200419a0121220cdf030b20012802cc02450dff02419b0121220cde030b20012802c8021001419c0121220cdd030b202841144b0dfe0241ff0121220cdc030b202841014d0d940241800221220cdb030b2028417f6a210941810221220cda030b202820092202417f6a2209490dc40341820221220cd9030b202820096b22074102490dc40341840221220cd8030b2027200241286c6a220b41206a22022903002027200941286c6a220841206a220629030022045a0dc40341850221220cd7030b20014180016a41186a2211200841186a220529030037030020014180016a41106a2213200841106a221229030037030020014180016a41086a2214200841086a220d29030037030020012008290300370380012008200b290300370300200d200b41086a2903003703002012200b41106a2903003703002005200b41186a2903003703002006200229030037030020074103490dc50341880221220cd6030b410321054102210641890221220cd5030b200620074f0dc703418b0221220cd4030b2008200641286c6a220241206a221229030020045a0dc103418c0221220cd3030b2006417f6a220620074f0dc603418e0221220cd2030b2008200641286c6a22062002290300370300200641206a2012290300370300200641186a200241186a290300370300200641106a200241106a290300370300200641086a200241086a290300370300200520074f0dc303418f0221220cd1030b20052106200541016a220b2005492112200b21052002210b2012450dc1030cc0030b200b210241870221220ccf030b2002200129038001370300200241186a2011290300370300200241106a2013290300370300200241086a20142903003703002002200437032041830221220cce030b20090d88020c87020b20284101762229ad42287e2204422088a70d9002419e0121220ccc030b2004a72202417f4c0d9002419f0121220ccb030b2002450ded0241a00121220cca030b20021000222a450ded0241a10121220cc9030b202a210b0ced020b4108212a4108210b41a20121220cc7030b202741586a212b202741a87f6a212c4104210d4100212d4100210c202821100cec020b2013210c20100dee020ced020b4100210741f50121220cc4030b20112007490dab0341f60121220cc3030b201120284b0da60341f70121220cc2030b201120076b22054101762209450daa0341f80121220cc1030b202b20086a21022027200741286c6a210641f90121220cc0030b20014180016a41206a2208200641206a221229030037030020014180016a41186a2213200641186a221429030037030020014180016a41106a220f200641106a220e29030037030020014180016a41086a2215200641086a22102903003703002001200629030037038001200241086a222e2903002104200241106a222f2903002100200241186a223029030021032002290300210a2012200241206a223129030037030020142003370300200e2000370300201020043703002006200a3703002031200829030037030020302013290300370300202f200f290300370300202e20152903003703002002200129038001370300200241586a2102200641286a21062009417f6a22090da90341fa0121220cbf030b20070dec0241a90121220cbe030b20072110200c202d460df1020cf2020b20112105200c202d460dee020cef020b2010211141002110410121052011417f6a2207450de50241a40121220cbb030b2027200741286c6a41206a2903002027201141286c22026a41506a29030022045a0de50241f20121220cba030b202c201141056c41037422086a210241f30121220cb9030b20074101460d9f0341f40121220cb8030b2007417f6a2107200420022903002200542106200241586a21022000210420060d9c030c9d030b2011417e6a2107202c20026a2106410021104100210241a60121220cb6030b20072002460de20241a70121220cb5030b200241016a21022004200629030022005a2105200641586a21062000210420050de00241a80121220cb4030b200241016a2105201120026b417f6a2207450de20241db0121220cb3030b200541094b0de20241dc0121220cb2030b201120284b0d880341dd0121220cb1030b20112007417f6a2210490d880341de0121220cb0030b201120106b22054102490d880341e20121220caf030b2027200741286c6a220841206a22022903002027201041286c6a220941206a220629030022045a0d880341e30121220cae030b20014180016a41186a2213200941186a220729030037030020014180016a41106a2214200941106a221229030037030020014180016a41086a220f200941086a220e290300370300200120092903003703800120092008290300370300200e200841086a2903003703002012200841106a2903003703002007200841186a2903003703002006200229030037030020054103490d8a0341e60121220cad030b410321074102210641e70121220cac030b200620054f0d8c0341e90121220cab030b2009200641286c6a220241206a221229030020045a0d860341ea0121220caa030b2006417f6a220620054f0d8b0341ec0121220ca9030b2009200641286c6a22062002290300370300200641206a2012290300370300200641186a200241186a290300370300200641106a200241106a290300370300200641086a200241086a290300370300200720054f0d880341ed0121220ca8030b20072106200741016a2208200749211220082107200221082012450d86030c85030b2008210241e50121220ca6030b2002200129038001370300200241186a2013290300370300200241106a2014290300370300200241086a200f2903003703002002200437032041df0121220ca5030b2010450dff0241e10121220ca4030b201021072005410a490df90241e00121220ca3030b200c202d470dd30241d20121220ca2030b202d41016a2202202d490dc50141d30121220ca1030b202d4101742206200220022006491b2206ad4203862204422088a70dc30141d40121220ca0030b2004a722024100480dc10141d50121220c9f030b202d450df00241d60121220c9e030b200210002207450df00241d70121220c9d030b2007200d2002202d4103742209200920024b1b10f8022102200d10012002210d0cf0020b20021000220d450df00241d80121220c9b030b2006212d41aa0121220c9a030b200d200c4103746a2202200536020420022010360200200c41016a220c4102490dcf0241b00121220c99030b200d200c2213417f6a220c4103746a2202280200450dd10241b10121220c98030b200d20134103746a220941746a2802002207200228020422064d0dd10241cd0121220c97030b201341024d0de60241cf0121220c96030b200d2013417d6a22024103746a2802042205200620076a4d0de40241d00121220c95030b201341034d0de50241d10121220c94030b200941646a280200200520076a4d0de1020ce0020b20134103490dcd0241cb0121220c92030b20022802042106200d2013417d6a22024103746a280204210541cc0121220c91030b20052006490dcc0241b30121220c90030b2013417e6a210241b40121220c8f030b2013200241016a222e4d0dcb0241b60121220c8e030b201320024d0dcb0241b80121220c8d030b200d20024103746a220f280204222f200f2802006a2202200d202e4103746a220e2802002215490dcb0241b90121220c8c030b200220284b0dcb0241ba0121220c8b030b200f41046a21302027201541286c6a2211200e280204221441286c22066a2109200241286c2105200220156b220820146b220220144f0dcb0241c30121220c8a030b202a2009200241286c220610f8021a200b20066a210720144101480dd40241c50121220c89030b20024101480dd40241c60121220c88030b202b20056a21052009210241c70121220c87030b2005200241586a2208200741586a2212200741786a290300200241786a2903005422091b2206290300370300200541206a200641206a290300370300200541186a200641186a290300370300200541106a200641106a290300370300200541086a200641086a2903003703002007201220091b210720112008200220091b22024f0dca0241c80121220c86030b200541586a2105200b2106200b2007490dcd020cce020b202a2011200610f8021a200b20066a210720144101480dc60241bf0121220c84030b200820144c0dc60241c00121220c83030b202720056a2112200b21062011210241c10121220c82030b200220092006200941206a290300200641206a2903005422081b2205290300370300200241206a200541206a290300370300200241186a200541186a290300370300200241106a200541106a290300370300200241086a200541086a2903003703002006200641286a20081b2106200241286a2102200941286a200920081b220920124f0dcb0241c20121220c81030b200720064b0dc6020cc7020b200921020cc4020b2011210241bd0121220cfe020b200b210641be0121220cfd020b20022006200720066b220520054128706b10f8021a2030202f20146a360200200f2015360200200e200e41086a2013202e417f736a41037410f9021a200c41014b0db30241ab0121220cfc020b20100da20241ac0121220cfb020b202d450db20241ad0121220cfa020b200d100141ae0121220cf9020b2029450db40141af0121220cf8020b202a1001412021220cf7020b20012028360288012001202636028401200120273602800120014180016a10a1022026450db301412121220cf6020b20271001412221220cf5020b20014180016a41086a2202420037030020014200370380014197c8c100411220014180016a100220014198026a41086a2206200229030037030020012001290380013703980220014198026a41104188f0c100410041001004417f460db201412321220cf4020b200142103702cc02200120014198026a3602c80220014180016a200141c8026a1036200128028001220e450db201412421220cf3020b20014188016a280200210220012802840121300cb2010b4100210e412521220cf1020b200141b0026a420037030020014198026a41106a420037030020064200370300200142003703980220024100200e1b2212ad2204421b88a70db101412621220cf0020b2004420586a72202417f4c0db501412821220cef020b2002450db501412921220cee020b2002100022130db501418e0121220ced020b200241011019000b41012113412a21220ceb020b20014180016a41186a220520014198026a41186a29030037030020014180016a41106a220720014198026a41106a29030037030020014180016a41086a220920014198026a41086a29030037030020012001290398023703800120124102490db301418b0121220cea020b2013210241012106418c0121220ce9020b2002200129038001370000200241186a2005290300370000200241106a2007290300370000200241086a2009290300370000200241206a2102200641016a22062012490d8202418d0121220ce8020b2006417f6a210d0cb2010b4100210d201321022012450db001412c21220ce6020b2002200129038001370000200241186a20014180016a41186a290300370000200241106a20014180016a41106a290300370000200241086a20014180016a41086a290300370000200d41016a210d412d21220ce5020b201b201e41306c6a2102201a450db001412e21220ce4020b2002201b460db001412f21220ce3020b201e41306c2106201a417f732108200141f0016a41186a2105200141f0016a41106a2107200141f0016a41086a2109413021220ce2020b201b20066a220241586a2903002104200241506a29030021002005200241786a2903003703002007200241706a2903003703002009200241686a2903003703002001200241606a2903003703f00120002004844200510db101413121220ce1020b20014198026a41186a220b200529030037030020014198026a41106a2211200729030037030020014198026a41086a22142009290300370300200120012903f00137039802200141c8026a41186a220f200b290300370300200141c8026a41106a220b2011290300370300200141c8026a41086a2211201429030037030020012001290398023703c80220014180016a41186a200f29030037030020014180016a41106a200b29030037030020014180016a41086a2011290300370300200120012903c80237038001200841016a2208450db101413221220ce0020b200641506a22060dae010cad010b2002201b460db00141880121220cde020b20014198026a41086a2206200241686a220529030037030020014198026a41106a2209200241706a220829030037030020014198026a41186a220b200241786a22112903003703002001200241606a221429030037039802200241586a2903002104200241506a2207290300210020014180016a41186a201129030037030020014180016a41106a200829030037030020014180016a41086a20052903003703002001201429030037038001200141f0016a41186a2202200b290300370300200141f0016a41106a22052009290300370300200141f0016a41086a2209200629030037030020012001290398023703f0012000200484500df60141890121220cdd020b200141e0006a41186a2002290300370300200141e0006a41106a2005290300370300200141e0006a41086a2009290300370300200120012903f0013703604100212f41002127420150450de4010ce5010b4100212741012102201ca70db0010caf010b200141e0006a41186a20014180016a41186a290300370300200141e0006a41106a20014180016a41106a290300370300200141e0006a41086a20014180016a41086a2903003703002001200129038001370360200241506a21074100212f0ce0010b4101212f410021274200500de00141f70021220cd9020b4100212741f80021220cd8020b20072102202f211441f90021220cd7020b200141c0006a41186a2206200141e0006a41186a2210290300370300200141c0006a41106a2205200141e0006a41106a220c290300370300200141c0006a41086a2207200141e0006a41086a222e2903003703002001200129036037034020014198026a41186a2209200629030037030020014198026a41106a2208200529030037030020014198026a41086a220b20072903003703002001200129034037039802200141f0016a20014198026a10eb0220014180016a41186a2211200629030037030020014180016a41106a2206200529030037030020014180016a41086a22052007290300370300200120012903403703800120012802f0014101460de70141fa0021220cd6020b201441ff01710de70141fc0021220cd5020b201b2002460de70141fd0021220cd4020b200241586a2903002104200241506a220729030021002009200241786a22142903003703002008200241706a220f290300370300200b200241686a22152903003703002001200241606a220229030037039802201120142903003703002006200f290300370300200520152903003703002001200229030037038001200141f0016a41186a22022009290300370300200141f0016a41106a22062008290300370300200141f0016a41086a2205200b29030037030020012001290398023703f0012000200484500de90141fe0021220cd3020b20102002290300370300200c2006290300370300202e2005290300370300200120012903f001370360410021142007210242014200520de1010ce2010b4101212f410121142007210242004200520dde010cdf010b200141c8026a41086a220f2005290300370300200141c8026a41106a22152006290300370300200141c8026a41186a2228201129030037030020012001290380013703c802200141f0016a41086a22142802002107200141206a41186a22312028290300370300200141206a41106a22282015290300370300200141206a41086a2215200f290300370300200120012903c8023703202011203129030037030020062028290300370300200520152903003703002001200129032037038001200d20074d0de70141820121220cd0020b201320074105746a2207200129038001370000200741186a2011290300370000200741106a2006290300370000200741086a2005290300370000202741016a2127202f41ff01710de30141830121220ccf020b201b2002460de30141840121220cce020b200241586a2903002104200241506a220729030021002009200241786a220f2903003703002008200241706a2215290300370300200b200241686a222f2903003703002001200241606a2202290300370398022011200f290300370300200620152903003703002005202f2903003703002001200229030037038001200141f0016a41186a22022009290300370300200141f0016a41106a220620082903003703002014200b29030037030020012001290398023703f0012000200484500de50141850121220ccd020b20102002290300370300200c2006290300370300202e2014290300370300200120012903f0013703604100212f42014200520dd6010cd7010b4101212f42004200520dd70141fb0021220ccb020b41012102201ca7450d9d01413421220cca020b201b1001413521220cc9020b200e2002200e1b210f200d20122012200d4b1b2208450d9e01413621220cc8020b41002105200f210220132106413721220cc7020b20022006460d9e01413821220cc6020b20022006412010fa02450d9e01413921220cc5020b411610002207450d9e01413a21220cc4020b2001421637028401200120073602800120014180016a4181c8c1004116102520014198026a41086a220720014180016a41086a2209280200360200200120012903800137039802200220014198026a101e20072802002111200128029c022114200128029802210b200942003703002001420037038001200b201120014180016a10022007200929030037030020012001290380013703980220014198026a411010082014450d9e01413b21220cc3020b200b1001413c21220cc2020b200241206a2102200641206a2106200541016a22052008490d9801413d21220cc1020b20014198016a210620014190016a210520014188016a21072013200d4105746a22112102200d2109413e21220cc0020b200220136b41ff004d0d9d0141e90021220cbf020b2006420037030020054200370300200742003703002001420037038001200241606a220820014180016a460dbe0141ea0021220cbe020b200820014180016a412010fa020dbe0141ec0021220cbd020b2006420037030020054200370300200742003703002001420037038001200241406a220820014180016a460dbe0141ed0021220cbc020b200820014180016a412010fa020dbe0141ef0021220cbb020b2006420037030020054200370300200742003703002001420037038001200241a07f6a220820014180016a460dbe0141f00021220cba020b200820014180016a412010fa020dbe0141f20021220cb9020b20064200370300200542003703002007420037030020014200370380012009417c6a2109200241807f6a220220014180016a460d950141f30021220cb8020b200220014180016a412010fa02450d930141f40021220cb7020b41012107200941016a2202200d4f0d9a0141e40021220cb6020b200d210541e50021220cb5020b200220076a22062002490db30141e60021220cb4020b2005417f6a2105200621022006200d490db10141e70021220cb3020b201320054105746a21110c9e010b20132002460d900141c00021220cb1020b20014180016a41206a210520014198016a210720014190016a210820014188016a210b4101210641c10021220cb0020b2007420037030020084200370300200b4200370300200142003703800120052002460d910141c20021220caf020b200241606a20014180016a412010fa020d910141e80021220cae020b200641016a21062013200241606a2202470d8e010c8d010b410121072009417f6a41016a2202200d490d92010c93010b410121072009417e6a41016a2202200d490d93010c94010b410121072009417d6a41016a2202200d490d94010c95010b41012107200920066b41016a2202200d490d8e0141c40021220ca9020b200d210541c50021220ca8020b2001419c016a202336020020014180016a41186a202436020020014194016a202536020020014180016a41106a20213602002001418c016a202036020020014180016a41086a2202201f360200200141033a008401200141053a00800120014180016a10b40120014100360288012001420137038001200520014180016a101b2005450d940141c60021220ca7020b4100200228020022066b2109200128028001210820012802840121072013210241c70021220ca6020b20022102200720096a411f4b0d940141db0021220ca5020b200641206a22052006490d3f41dc0021220ca4020b2007410174220b20052005200b491b22054100480d3f41dd0021220ca3020b20051000210b2007450d9c0141de0021220ca2020b200b450d9c0141df0021220ca1020b200b200820052007200720054b1b10f8021a200810010c9d010b200b450d9b0141e00021220c9f020b200b21082005210741c80021220c9e020b200820066a22052002290000370000200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a290000370000200941606a2109200641206a21062011200241206a2202470d8b0141c90021220c9d020b20014188016a2006360200200120073602840120012008360280010c8c010b200228020021062001280284012107200128028001210841ca0021220c9b020b20014180016a41086a2202420037030020014200370380014197c8c100411220014180016a100220014198026a41086a200229030037030020012001290380013703980220014198026a41102008200610032007450d8b0141cb0021220c9a020b2008100141cc0021220c99020b2012450d8a0141cd0021220c98020b2013100141ce0021220c97020b200120273602c80220014180016a41086a22024200370300200142003703800141a9c8c100411620014180016a100220014198026a41086a2206200229030037030020012001290380013703980220014198026a4110200141c8026a4104100320024200370300200142003703800141bfc8c100411120014180016a10022006200229030037030020012001290380013703980220014198026a41104188f0c100410041001004417f460d890141cf0021220c96020b200141003602800120014198026a411020014180016a41044100100441016a41044d0d890141d00021220c95020b20012802800141016a21020c89010b4101210241d10021220c93020b200120023602c80220014180016a41086a22024200370300200142003703800141bfc8c100411120014180016a100220014198026a41086a200229030037030020012001290380013703980220014198026a4110200141c8026a41041003200e450d880141d20021220c92020b2030450d880141d30021220c91020b200f100141d40021220c90020b2019a7450d870141d50021220c8f020b2018100141d60021220c8e020b2017450d860141d70021220c8d020b2016100141d80021220c8c020b200141f0026a24000f0b1018000b41d08ac30020062005104e000b41e08ac30020062005104e000b41c08ac300202e2013104e000b41c08ac30020022013104e000b20152002107a000b200220281076000b200641011019000b200541011019000b411641011019000b41d08ac30020062007104e000b41e08ac30020062007104e000b20092028107a000b102c000b41eac4c10041331042000b200641081019000b200241041019000b20072011107a000b20112007417f6a22104f0ddb0141ee0121220cf8010b20102011107a000b201120281076000b200741011019000b41eac4c10041331042000b200241081019000b41b08bc3002007200d104e000b200241081019000b410521220cf0010b410121220cef010b410121220cee010b410221220ced010b410121220cec010b410f21220ceb010b410321220cea010b410421220ce9010b410d21220ce8010b410421220ce7010b410921220ce6010b410921220ce5010b410921220ce4010b410921220ce3010b410921220ce2010b410921220ce1010b410921220ce0010b410921220cdf010b410921220cde010b410921220cdd010b410921220cdc010b410921220cdb010b410e21220cda010b410d21220cd9010b41a70221220cd8010b41a60221220cd7010b411a21220cd6010b411321220cd5010b411a21220cd4010b411a21220cd3010b411421220cd2010b411521220cd1010b411a21220cd0010b411721220ccf010b411921220cce010b411a21220ccd010b411a21220ccc010b411a21220ccb010b411b21220cca010b411d21220cc9010b411f21220cc8010b412021220cc7010b412021220cc6010b412021220cc5010b41810221220cc4010b412021220cc3010b412221220cc2010b41910121220cc1010b41900121220cc0010b412521220cbf010b412721220cbe010b412721220cbd010b412721220cbc010b412721220cbb010b412721220cba010b412721220cb9010b418f0121220cb8010b412a21220cb7010b412b21220cb6010b412d21220cb5010b412c21220cb4010b41870121220cb3010b413321220cb2010b413321220cb1010b413021220cb0010b413321220caf010b41f60021220cae010b413321220cad010b413521220cac010b413521220cab010b413421220caa010b413d21220ca9010b413721220ca8010b413c21220ca7010b413c21220ca6010b41f50021220ca5010b413c21220ca4010b413e21220ca3010b413e21220ca2010b413f21220ca1010b41c40021220ca0010b41c40021220c9f010b41c10021220c9e010b41e80021220c9d010b41c30021220c9c010b41c40021220c9b010b41e40021220c9a010b41e40021220c99010b41c40021220c98010b41e40021220c97010b41c40021220c96010b41e40021220c95010b41c40021220c94010b41c50021220c93010b41e30021220c92010b41c70021220c91010b41c80021220c90010b41ca0021220c8f010b41cc0021220c8e010b41ce0021220c8d010b41da0021220c8c010b41d90021220c8b010b41d10021220c8a010b41d40021220c89010b41d40021220c88010b41d60021220c87010b41d80021220c86010b41e20021220c85010b41e10021220c84010b41e10021220c83010b41e00021220c82010b41e50021220c81010b41e70021220c80010b41ec0021220c7f0b41eb0021220c7e0b41ef0021220c7d0b41ee0021220c7c0b41f20021220c7b0b41f10021220c7a0b41f70021220c790b41fb0021220c780b41f70021220c770b41fb0021220c760b41f80021220c750b41fb0021220c740b41f80021220c730b41f90021220c720b41fb0021220c710b41f90021220c700b41fb0021220c6f0b41800121220c6e0b41fb0021220c6d0b41fb0021220c6c0b41fb0021220c6b0b41fb0021220c6a0b41ff0021220c690b41810121220c680b41860121220c670b418a0121220c660b418c0121220c650b41960121220c640b419e0221220c630b41970121220c620b41920221220c610b41980121220c600b419a0121220c5f0b419c0121220c5e0b419d0121220c5d0b41fe0121220c5c0b41fd0121220c5b0b41a20121220c5a0b41a30121220c590b41a30121220c580b41ac0121220c570b41a30121220c560b41e00121220c550b41a50121220c540b41a60121220c530b41f10121220c520b41db0121220c510b41a90121220c500b41a90121220c4f0b41aa0121220c4e0b41d20121220c4d0b41aa0121220c4c0b41d20121220c4b0b41aa0121220c4a0b41ab0121220c490b41b00121220c480b41ae0121220c470b41b20121220c460b41b20121220c450b41b30121220c440b41b40121220c430b41b50121220c420b41b70121220c410b41ca0121220c400b41c90121220c3f0b41bb0121220c3e0b41bc0121220c3d0b41bc0121220c3c0b41bd0121220c3b0b41bd0121220c3a0b41c10121220c390b41be0121220c380b41c70121220c370b41be0121220c360b41be0121220c350b41c40121220c340b41c40121220c330b41ce0121220c320b41cc0121220c310b41cc0121220c300b41ce0121220c2f0b41ce0121220c2e0b41da0121220c2d0b41d90121220c2c0b41d80121220c2b0b41d90121220c2a0b41dd0121220c290b41ef0121220c280b41ee0121220c270b41df0121220c260b41df0121220c250b41e00121220c240b41e40121220c230b41e40121220c220b41e50121220c210b41e70121220c200b41e50121220c1f0b41e80121220c1e0b41eb0121220c1d0b41f00121220c1c0b41f00121220c1b0b41f30121220c1a0b41f50121220c190b41fc0121220c180b41fb0121220c170b41fa0121220c160b41f90121220c150b41900221220c140b41830221220c130b41830221220c120b41860221220c110b41860221220c100b41870221220c0f0b41890221220c0e0b41870221220c0d0b418a0221220c0c0b418d0221220c0b0b41930221220c0a0b41930221220c090b419d0221220c080b419c0221220c070b419b0221220c060b419c0221220c050b41a50221220c040b41a40221220c030b41a30221220c020b41ac0221220c010b41ab0221220c000b0b821103037f067e067f230041e0016b2208240002400240024002400240200728020022094100480d00200941ffffffff07460d002007200941016a36020002400240200741046a220a200410de012209450d002009280200450d00200941106a290300210b200941086a290300210c0c010b200841306a20072802102004200741146a280200280214110400200841386a290300210b2008290330210c0b20072007280200417f6a36020020072802282109024002402002450d00200941c0006a21090c010b0240200c200b84500d00200941e0006a21090c010b200941d0006a21090b2001290310220d200141186a290300220e844200510d01200841206a2009290300200941086a290300200d200e10fb02200142002001290308220e20082903207d220d200d200e56200d507222091b370308024002402009450d0041a3b9c1002101412221070c010b200728020022014100480d01200141ffffffff07460d012007200141016a36020002400240200a200310de012201450d002001280200450d00200141106a290300210d200141086a290300210e0c010b200841106a20072802102003200741146a280200280214110400200841186a290300210d2008290310210e0b20072007280200417f6a3602000240200e20057d220f200e56200d20067d200e200554ad7d220e200d56200e200d511b4101470d00419d8cc2002101411d21070c010b0240200c200b8450450d00200741286a2802002201290330200556200141386a290300220d200656200d2006511b450d0041ba8cc2002101411f21070c010b200841086a200310ca01024020082802082201450d00200828020c21070c010b0240200c20057c2210200c542201200b20067c2001ad7c220d200b54200d200b511b450d0041d98cc2002101412d21070c010b41002101024020032004460d0020032004412010fa02450d0020072802000d042007417f360200200841f8006a41186a2201200341186a290000370300200841f8006a41106a2209200341106a290000370300200841f8006a41086a2202200341086a29000037030020082003290000370378200841c0006a200a200841f8006a10df010240024020082802404101470d00200841c0006a41086a2802002101200841c0006a41106a2802002109200842003702b401200841e8bdc0003602b0012001200941306c6a41e8026a2101200841f8006a200841b0016a10cb01200841f8006a10cc010c010b200841a8016a200841f4006a280200360200200841f8006a41286a200841ec006a29020037030020084198016a200841e4006a2902003703002001200841dc006a2902003703002009200841d4006a2902003703002002200841cc006a29020037030020082008290244370378200841b0016a41186a4100360200200841b0016a41106a4200370300200841b0016a41086a4200370300200841b0016a41286a4200370300200842003703b001200841e8bdc0003602d401200841f8006a200841b0016a10e20121010b2001200f37030820014201370300200141106a200e3703002007200728020041016a220136020020010d042007417f360200200841f8006a41186a2201200441186a290000370300200841f8006a41106a200441106a290000370300200841f8006a41086a2209200441086a29000037030020082004290000370378200841c0006a200a200841f8006a10df010240024020082802404101470d00200841c0006a41086a2802002101200841d0006a2802002109200842003702b401200841e8bdc0003602b0012001200941306c6a41e8026a2101200841f8006a200841b0016a10cb01200841f8006a10cc010c010b200841a8016a200841f4006a280200360200200841f8006a41286a200841ec006a29020037030020084198016a200841e4006a2902003703002001200841dc006a290200370300200841f8006a41106a200841d4006a2902003703002009200841cc006a29020037030020082008290244370378200841b0016a41186a4100360200200841b0016a41106a4200370300200841b0016a41086a4200370300200841b0016a41286a4200370300200842003703b001200841e8bdc0003602d401200841f8006a200841b0016a10e20121010b2001201037030820014201370300200141106a200d3703002007200728020041016a360200200841c0006a41186a2202200341186a290000370300200841c0006a41106a220a200341106a290000370300200841c0006a41086a2211200341086a290000370300200841f8006a41086a2212200441086a290000370300200841f8006a41106a2213200441106a290000370300200841f8006a41186a2214200441186a29000037030020082003290000370340200820042900003703780240200741246a22092802002201200741206a280200470d00200141016a22042001490d0620014101742203200420042003491b2215ad42d8007e220d422088a70d06200da722044100480d06024002402001450d002007411c6a2802002116200410002203450d09200320162004200141d8006c2201200120044b1b10f8021a201610010c010b200410002203450d080b200741206a20153602002007411c6a2003360200200741246a28020021010b2007411c6a280200200141d8006c6a2207200829034037000141002101200741003a000020072008290378370021200741096a2011290300370000200741116a200a290300370000200741196a2002290300370000200741296a2012290300370000200741316a2013290300370000200741396a2014290300370000200741d0006a200637030020072005370348200741c7006a200841b6016a2d00003a0000200741c5006a200841b4016a2f00003b0000200720082800b0013600412009200928020041016a3602000b0b2000200736020420002001360200200841e0016a24000f0b10c602000b41b8c7c200104f000b108402000b1018000b200441081019000ba46704097f017e167f017e230041c0036b2208240020084200370254200841e8bdc00036025002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240410310002209450d00200941026a41002d008680413a0000200941002f008480413b000020084283808080303702940320082009360290030240410110002209450d00200941003a0000200841f0026a41e0083b0100200841e8026a428180808010370300200841f2026a20082f01c8023b0100200820093602e402200841113602e002200841e0006a200841d0006a20084190036a200841e0026a10e101024020082d00714105460d002008280268450d00200828026410010b0240410f10002209450d00200941076a410029008e80413700002009410029008780413700002008428f808080f0013702940320082009360290030240410410002209450d0020094100360000200841f0026a41e0083b0100200841e8026a4284808080c000370300200841f2026a20082f01c8023b0100200820093602e402200841123602e002200841f8006a200841d0006a20084190036a200841e0026a10e101024020082d0089014105460d00200828028001450d00200828027c10010b0240410f10002209450d00200941076a410029009d80413700002009410029009680413700002008428f808080f0013702940320082009360290030240410110002209450d00200941003a0000200841f0026a41e0003b0100200841e0026a41086a428180808010370300200841f2026a20082f01c8023b0100200820093602e402200841133602e00220084190016a200841d0006a20084190036a200841e0026a10e101024020082d00a1014105460d00200828029801450d0020082802940110010b0240410810002209450d00200942e5f0d1fbb5ac98b6ec003700002008428880808080013702940320082009360290030240410710002209450d0020094100360003200941013a0002200941003b0000200841f0026a41e0003b0100200841e8026a4287808080f000370300200841f2026a20082f01c8023b0100200820093602e402200841143602e002200841a8016a200841d0006a20084190036a200841e0026a10e101024020082d00b9014105460d0020082802b001450d0020082802ac0110010b0240410a10002209450d00200941086a41002f00ad80413b0000200941002900a580413700002008428a808080a0013702940320082009360290030240410710002209450d0020094100360003200941013a0002200941003b0000200841f0026a41e0003b0100200841e0026a41086a4287808080f000370300200841f2026a20082f01c8023b0100200820093602e402200841153602e002200841c0016a200841d0006a20084190036a200841e0026a10e101024020082d00d1014105460d0020082802c801450d0020082802c40110010b0240410a10002209450d00200941086a41002f00b780413b0000200941002900af80413700002008428a808080a0013702940320082009360290030240410210002209450d00200941003b0000200841f0026a41e0083b0100200841e0026a41086a428280808020370300200841f2026a20082f01c8023b0100200820093602e402200841163602e002200841d8016a200841d0006a20084190036a200841e0026a10e101024020082d00e9014105460d0020082802e001450d0020082802dc0110010b0240410a10002209450d00200941086a41002f00c180413b0000200941002900b980413700002008428a808080a001370294032008200936029003200841f0026a41e0083b0100200841ec026a4100360200200842013702e402200841173602e002200841f0016a200841d0006a20084190036a200841e0026a10e101024020082d0081024105460d0020082802f801450d0020082802f40110010b0240410e10002209450d00200941066a41002900c98041370000200941002900c380413700002008428e808080e001370294032008200936029003200841f0026a41e0003b0100200841ec026a4100360200200842013702e402200841183602e00220084188026a200841d0006a20084190036a200841e0026a10e101024020082d0099024105460d00200828029002450d00200828028c0210010b0240410e10002209450d00200941066a41002900d78041370000200941002900d180413700002008428e808080e0013702940320082009360290030240410310002209450d00200941003a0002200941003b0000200841e0026a41106a41e0083b0100200841e8026a428380808030370300200841f2026a20082f01c8023b0100200820093602e402200841193602e002200841a0026a200841d0006a20084190036a200841e0026a10e101024020082d00b1024105460d0020082802a802450d0020082802a40210010b0240411010002209450d00200941086a41002900e78041370000200941002900df8041370000200842908080808002370294032008200936029003200841e0026a41106a41e0003b0100200841ec026a4100360200200842013702e4022008411a3602e002200841c8026a200841d0006a20084190036a200841e0026a10e101024020082d00d9024105460d0020082802d002450d0020082802cc0210010b0240411010002209450d00200941086a41002900f78041370000200941002900ef80413700002008429080808080023702bc02200820093602b8020240410310002209450d00200941003a0002200941003b0000200841f0026a41e0083b0100200841e0026a41086a428380808030370300200841f2026a20082f0190033b0100200820093602e4022008411b3602e00220084190036a200841d0006a200841b8026a200841e0026a10e101024020082d00a1034105460d00200828029803450d0020082802940310010b200841c0006a41086a200841d0006a41086a280200360200200820082903503703404100210a200841003602d002200820003602c802200820013602cc020240200141044f0d00200841013a008802200841f4026a4101360200200841ec026a41013602002008410f3602a402200841e0c3c1003602e802200841013602e402200841b08fc2003602e002200820084188026a3602a0022008200841a0026a3602f00220084190036a200841e0026a104d200828029403210b200828029003210c0c2b0b200841c8026a41086a41043602000240024020002800004180c2cdeb06470d002001417c714104470d01200841013a008802200841f4026a4101360200200841ec026a41013602002008410f3602a402200841e0c3c1003602e802200841013602e402200841b08fc2003602e002200820084188026a3602a0022008200841a0026a3602f00220084190036a200841e0026a104d200828029403210b200828029003210c4100210a0c2c0b410121010c290b0240200141074d0d00200841c8026a41086a41083602000240024002400240024002402000280004220c4101470d00200841e0026a200841c8026a10ba0220082802e002220e4101470d01410021004104210f4100211020082d00e4020d020c1a0b410221010c2f0b200841e0026a410572210b4104210f200841e0026a412c6a211220084184036a211320084180036a2114200841fc026a2115200841f8026a2116200841f4026a2117200841f0026a2118200841ec026a2119200841e8026a211a4128210d41002100410021104100210a0340200841a0026a41026a221b200b41026a2d00003a00002008200b2f00003b01a0022012280200211c20084188036a280200211d2013280200211e2014280200211f2015280200212020162802002121201728020021222018280200212320192802002124201a2802002125024020082d00e402220c417e6a220941ff0171410b4f0d0002400240024002400240024002400240024002400240024002400240024002400240024002402009410a4b22260d00024020090e0b00070405020809060b030a000b200a41ff0171222741014d0d0c0c0b0b200a41ff0171222741004b0d0a0c0b0b200a41ff0171222741054d0d0a0c090b200a41ff01712227410a4d0d090c080b200a41ff0171222741034d0d080c070b200a41ff0171222741044d0d070c060b200a41ff0171222741084d0d060c050b200a41ff0171222741024d0d050c040b200a41ff0171222741064d0d040c030b200a41ff0171222741074d0d030c020b200a41ff01712227410b4d0d020c010b200a41ff0171222741094d0d010b41132101200c410d4b0d010c020b02400240024002400240024002400240024002400240024020260d00024020090e0b00070405020809060b030a000b20274101470d110c0b0b20274100460d0a0c100b20274105470d0f0c090b2027410a470d0e0c080b20274103470d0d0c070b20274104470d0c0c060b20274108470d0b0c050b20274102470d0a0c040b20274106470d090c030b20274107470d080c020b2027410b470d070c010b20274109470d060b41142101200c410d4d0d010b02402024450d00202510010b02402021450d002020450d00202110010b201d450d01201e1001200c4105460d020c030b02400240024002400240024002400240024002400240024002400240200c0e0e0d0405010d0d0d08030e070002060d0b2023450d0c2025202341186c6a21232025210b03400240200b41046a280200450d00200b28020010010b0240200b41146a280200220d450d00200b28020c2109200d410474210d0340024020092d00004109470d00200941086a28020041ffffffff0371450d00200941046a28020010010b200941106a2109200d41706a220d0d000b0b200b41186a21090240200b41106a280200450d00200b410c6a28020010010b2009210b20092023470d000c0d0b0b2023450d0b202341286c210d2025210903400240200941046a280200450d00200928020010010b0240200941106a280200450d002009410c6a28020010010b200941286a2109200d41586a220d0d000c0c0b0b2023450d0a20252023411c6c6a21232025210b03400240200b410c6a280200220d450d00200b2802042109200d410474210d0340024020092d00004109470d00200941086a28020041ffffffff0371450d00200941046a28020010010b200941106a2109200d41706a220d0d000b0b0240200b41086a280200450d00200b41046a28020010010b200b411c6a21090240200b41146a280200450d00200b28021010010b2009210b20092023470d000c0b0b0b2023450d09202341146c210d2025210903400240200941046a280200450d00200928020010010b200941146a2109200d416c6a220d0d000c0a0b0b02402024450d00202510010b2021450d0920221001200c4105460d0a0c0b0b2023450d072023410474210d2025210903400240200941046a280200450d00200928020010010b200941106a2109200d41706a220d0d000c080b0b202541ff017122094102460d0320094101460d0220090d052023450d0720241001200c4105460d080c090b2023450d0520252023411c6c6a21232025210b03400240200b410c6a280200220d450d00200b2802042109200d410474210d0340024020092d00004109470d00200941086a28020041ffffffff0371450d00200941046a28020010010b200941106a2109200d41706a220d0d000b0b0240200b41086a280200450d00200b41046a28020010010b200b411c6a21090240200b41146a280200450d00200b28021010010b2009210b20092023470d000c060b0b2023450d04202520234104746a21232025210b03400240200b280208220d450d00200b2802002109200d410474210d0340024020092d00004109470d00200941086a28020041ffffffff0371450d00200941046a28020010010b200941106a2109200d41706a220d0d000b0b200b41106a21090240200b41046a280200450d00200b28020010010b2009210b20092023470d000c050b0b2021450d012021410c6c210d20232109034002402009280200220b450d00200941046a280200450d00200b10010b2009410c6a2109200d41746a220d0d000c020b0b2021450d00202320214104746a21202023211d0340201d222141106a211d024020212802042209450d0002402021410c6a280200220d450d00200d410c6c210d034002402009280200220b450d00200941046a280200450d00200b10010b2009410c6a2109200d41746a220d0d000b0b202141086a280200450d00202141046a28020010010b201d2020470d000b0b2022450d0220231001200c4105460d030c040b2023450d01202410010c010b2024450d0020251001200c4105460d010c020b200c4105470d010b200e450d002024450d00202510010b200f21092010450d050c040b0240024002400240024002400240024002400240024020260d00024020090e0b00070405020809060b030a000b4101210a0c0b0b4100210a0c0a0b4105210a0c090b410a210a0c080b4103210a0c070b4104210a0c060b4108210a0c050b4102210a0c040b4106210a0c030b4107210a0c020b410b210a0c010b4109210a0b20084190036a41026a2226201b2d00003a0000200820082f01a0023b019003024020102000470d00200041016a22092000490d1b2000410174221b20092009201b491b221bad422c7e2211422088a70d1b2011a722094100480d1b024002402000450d0020091000220e450d07200e200f20092000412c6c2200200020094b1b10f8022109200f10012009210f0c010b20091000220f450d060b201b21000b200f200d6a220941586a200c3a00002009201c3602002009417c6a201d360200200941786a201e360200200941746a201f360200200941706a20203602002009416c6a2021360200200941686a2022360200200941646a2023360200200941606a20243602002009415c6a20253602002009415b6a20262d00003a0000200941596a20082f0190033b0000200d412c6a210d201041016a2110200841e0026a200841c8026a10ba0220082802e002220e4101470d000b20082d00e402450d180b20082902e4022211422088a7210c2011421088a7210d2011420888a7210a200841ec026a280200210b2011a72101200f21092010450d010b2010412c6c211003402009102a2009412c6a2109201041546a22100d000b0b2000450d2d200f10010c2d0b200941041019000b410820011076000b410341011019000b411041011019000b411041011019000b410341011019000b410e41011019000b410e41011019000b410a41011019000b410241011019000b410a41011019000b410741011019000b410a41011019000b410741011019000b410841011019000b410141011019000b410f41011019000b410441011019000b410f41011019000b410141011019000b410341011019000b2010412c6c2109200f41606a210a2010ad4220862000ad8421110240024003402009450d01200941546a2109200a41206a210d200a412c6a220b210a200d2d0000410b470d000b200b280200210c0c010b4100210c0b2010412c6c2109200f41586a210a0240024003402009450d01200941546a2109200a41286a210d200a412c6a220b210a200d2d00004104470d000b200841386a200b1049200c200828023c460d010c150b200c4100470d140b02400240024002400240024002400240024002400240200841d0026a2802002001470d00200f450d022011a72110200f2011422088a7220d412c6c6a210a200f21090340200a2009460d0220092d000021012009412c6a2200210920014106470d000b200841306a200041586a10492008280234450d01410221090c1c0b200841003a008802200841f4026a4101360200200841ec026a41013602002008410f3602a402200841e0c3c1003602e802200841013602e402200841b08fc2003602e002200820084188026a3602a0022008200841a0026a3602f00220084190036a200841e0026a104d200828029403210b200828029003210c02402011422088a72209450d002009412c6c2101200f210903402009102a2009412c6a2109200141546a22010d000b0b410521012011a7450d22200f10010c220b200841e0026a41086a22014200370300200841e8bdc0003602e402200820062903003e02f002200820062903083e02e002200841e0026a4104722209410d10602009410c10602009410710602009410f1060200841d8026a20082802f002360200200841c8026a41086a2001290300370300200820082903e0023703c802200f450d0120084190036a410c6a20113702002008200f3602980320084280c2cdeb1637039003200841e0026a20084190036a200841c8026a105a024020082802e0024101470d00200841f0026a2802002100200841ec026a280200210a0240200841f4026a2802002209450d002009412c6c2101200a210903402009102a2009412c6a2109200141546a22010d000b0b02402000450d00200a10010b200841c8026a41047210ce01410321090c230b200841f0026a2903002111200841e0026a410c6a280200210920082902e4022128200841c8026a41047210ce012009450d0220084190036a410c6a201137020020082009360298032008202837039003200841e0026a20084190036a20062802281048024020082802e0024101470d000240200841e8026a280200450d0020082802e40210010b410421090c230b200841ec026a280200220f450d0320082902e4022128200841f0026a2903002211a72110200f2011422088a7220d412c6c6a210a200f2109024002400340200a2009460d0120092d000021012009412c6a2200210920014102470d000b200841286a200041586a104920082802282109200828022c21010c010b410021090b2001410020091b211d20094188f0c10020091b2120200f200d412c6c6a210a200f2109024002400340200a2009460d0120092d000021012009412c6a2200210920014103470d000b200841206a200041586a104920082802202109200828022421010c010b410021090b20094188f0c10020091b22212001410020091b41286c6a21004100210c0240034020212000460d0120212101034041062109200141086a2802004103470d1d02402001280200220a4196b9c100460d00200a4196b9c100410310fa020d1e0b024002400240200141186a2d0000220a4102460d00200a0d010c020b2001411c6a210c0b200141286a22012000470d010c030b0b20202001411c6a280200220a4104746a4100201d200a4b1b221c450d1c201c200b201c1b211e200141286a2121200141146a280200210a2001410c6a280200211b200828024021012008280244210b200841c0006a21240340200841e0026a41086a221f2024360200200820013602e4022008200b3602e002200841186a200841e0026a10a10120082802182201200828021c410c6c6a2123417f2125418901210b024002400240034020012023460d012001450d0102400240201b2001280200200141086a2802002224200a200a20244b1b10fa022222450d00200b41146a210b417f410120224100481b22240d010c050b200b41146a210b4100417f4101200a2024491b200a2024461b2224450d040b2001410c6a2101202541016a212520244101460d000b20082802e00222010d010c200b200841106a200841e0026a10a1012008280214212520082802e0022201450d1f0b201f28020021242001417f6a210b20082802e40220254102746a41e8026a28020021010c010b0b20082802e402200b6a22224111460d1c2022417f6a2d0000201e2d000c470d1c2022417b6a2802002224201e280208470d1c202241736a2802002125201e28020021234100210102400340200120244f0d01202320016a210a202520016a210b200141016a2101200b2d0000200a2d0000460d000c1e0b0b20222d0000220a4104462224201e410d6a2d00002201410447460d1c201c210b200a2001460d00201c210b20240d00201c210b20014104460d000c1c0b0b024002400240024002400240200c450d0041072109200c280204220a450d20200c2802002200200c28020822014b0d202001200628022c4b0d2020002001417f200a1b10102201417f460d20410c1000221c450d0d201c2001360208201c428180808010370200200f0d010c1f0b4100410010102209417f460d01410c1000221c450d0a201c2009360208201c428180808010370200200f450d1e0b200841003602a802200842013703a002410410002209450d08200841043602a402200841a8026a22012001280200220a41046a360200200820093602a0022009200a6a20283e0000024020082802a402220a200128020022096b41044f0d00200941046a22012009490d0e200a4101742209200120012009491b22094100480d0e200a450d0220082802a0022100200910002201450d0b200120002009200a200a20094b1b10f8021a200010010c030b20082802a00221010c030b41072109200f0d1e0c250b200910002201450d080b200820093602a402200820013602a002200841a8026a28020021090b200841a0026a41086a200941046a360200200120096a2028422088a7360000200f2011422088a72209412c6c22016a21002011a7211f024002400240024002402009450d00200141546a2123200841e0026a4101722101200841e0026a412a6a210d200841e0026a41286a2110200841e0026a41206a210b200841e0026a41186a210c200841e0026a41106a2124200841e0026a41086a2125200f2109034020092d0000210a200d2009412b6a2d00003a00002010200941296a2f00003b0100200b200941216a290000370300200c200941196a2900003703002024200941116a2900003703002025200941096a2900003703002008200941016a2900003703e002200a410f460d0220084190036a412a6a2221200d2d00003a000020084190036a41286a222220102f01003b010020084190036a41206a221d200b29030037030020084190036a41186a2220200c29030037030020084190036a41106a221e202429030037030020084190036a41086a221b2025290300370300200820082903e002370390032001200829039003370000200141086a201b290300370000200141106a201e290300370000200141186a2020290300370000200141206a201d290300370000200141286a20222f01003b00002001412a6a20212d00003a00002008200a3a00e002200841c8026a200841e0026a200841a0026a10b30220082d00c802220a411a470d05202341546a21232009412c6a22092000470d000b200022092000470d020c030b200f22092000470d010c020b2009412c6a22092000460d010b200841e0026a4101722101200841e0026a412a6a210d200841e0026a41286a2110200841e0026a41206a210b200841e0026a41186a210c200841e0026a41106a2124200841e0026a41086a2125034020092d0000210a200d2009412b6a2d00003a00002010200941296a2f00003b0100200b200941216a290000370300200c200941196a2900003703002024200941116a2900003703002025200941096a2900003703002008200941016a2900003703e002200a410f460d0120084190036a412a6a2223200d2d00003a000020084190036a41286a222120102f01003b010020084190036a41206a2222200b29030037030020084190036a41186a221d200c29030037030020084190036a41106a2220202429030037030020084190036a41086a221e2025290300370300200820082903e002370390032001200829039003370000200141086a201e290300370000200141106a2020290300370000200141186a201d290300370000200141206a2022290300370000200141286a20212f01003b00002001412a6a20232d00003a00002008200a3a00e002200841e0026a102a2009412c6a22092000470d000b0b201f450d09200f10010c090b20082d00cb02212620082f00c902210e200841c8026a41086a280200211220082802cc02211302402023450d002009412c6a2109200841e0026a4101722101200841e0026a412a6a2110200841e0026a41286a210b200841e0026a41206a210c200841e0026a41186a2124200841e0026a41106a2125200841e0026a41086a2123034020092d0000210d20102009412b6a2d00003a0000200b200941296a2f00003b0100200c200941216a2900003703002024200941196a2900003703002025200941116a2900003703002023200941096a2900003703002008200941016a2900003703e002200d410f460d0120084190036a412a6a222120102d00003a000020084190036a41286a2222200b2f01003b010020084190036a41206a221d200c29030037030020084190036a41186a2220202429030037030020084190036a41106a221e202529030037030020084190036a41086a221b2023290300370300200820082903e002370390032001200829039003370000200141086a201b290300370000200141106a201e290300370000200141186a2020290300370000200141206a201d290300370000200141286a20222f01003b00002001412a6a20212d00003a00002008200d3a00e002200841e0026a102a2009412c6a22092000470d000b0b0240201f450d00200f10010b200a411a460d08200e202641107472410874200a722109024020082802a402450d0020082802a00210010b0240200941ff01714105470d002012450d00201310010b201c201c280200417f6a22013602004100210920010d22201c2802081011201c201c280204417f6a220136020420010d22201c10010c220b4188a1c10041341042000b41bca1c10041361042000b41bca1c10041361042000b41bca1c10041361042000b410441011019000b410c41041019000b200941011019000b410c41041019000b200841a0026a41086a280200212120082802a402212220082802a0022123200841a0036a420037030020084280808080c00037039803200842043703900320082802442110200841e0026a41086a220020082802402201360200200841e0026a410c6a220d200841c0006a360200200820103602e40220082010410047220c3602e002024002402010450d002010417f6a2109200841e0026a410472210b2001210a03402000200a2802e802220a360200200d200841c0006a360200200820093602e402200820094100473602e0022009417f6a2209417f470d000c020b0b200841e0026a410472210b0b200841a0026a41086a200b41086a2802003602002008200b2902003703a002200841e0026a41086a220a2001360200200841ec026a2200200841c0006a360200200820103602e4022008200c3602e00202402010450d002010417f6a21090340200a200120012f01064102746a41e8026a28020022013602002000200841c0006a360200200820093602e402200820094100473602e0022009417f6a2209417f470d000b0b200841ec026a2802002109200841e0026a41086a2201280200220a2f0106210020082802e402210d200841c8026a41086a2210200841a0026a41086a280200360200200820082903a0023703c8022008280248210b200841e0026a411c6a2000360200200841f8026a2009360200200841e0026a41146a200a360200200120102802003602002008200b360280032008200d3602f002200841003602ec02200820082903c8023703e002200841086a200841e0026a10d301024020082802082209450d00200828020c210120084190036a41086a210003402001280200210d200928020821012009280200211041031000220a450d03200a41026a41002d0098b9413a0000200a41002f0096b9413b00002001417f4c0d04024002402001450d002001100022090d010c070b410121090b20092010200110f8022110024020002802002209200828029403470d00200941016a220b2009490d032009410174220c200b200b200c491b220fad4205862211422088a70d032011a7220b4100480d03024002402009450d002008280290032124200b1000220c450d09200c2024200b200941057422252025200b4b1b10f8021a202410010c010b200b1000220c450d080b2008200f360294032008200c360290030b20082802900320094105746a220941003602182009201036020c20094283808080303702042009200a3602002009411c6a200d360200200941146a2001360200200941106a20013602002000200028020041016a3602002008200841e0026a10d30120082802042101200828020022090d000b0b201c280200220941016a220141014d0d05201c20013602002009417e460d05201c200941026a3602000240200841a4036a22012802002209200841a0036a280200470d00200941016a220a2009490d0120094101742200200a200a2000491b220dad4202862211422088a70d012011a7220a4100480d01024002402009450d002008419c036a2802002110200a10002200450d0b20002010200a2009410274220b200b200a4b1b10f8021a201010010c010b200a10002200450d0a0b200841a0036a200d3602002008419c036a20003602000b2008419c036a28020020094102746a201c3602002001200128020041016a360200201c280208210d410310002201450d06200141026a41002d0098b9413a0000200141002f0096b9413b000041061000220a450d07200a41046a41002f009db9413b0000200a4100280099b941360000024020084198036a22002802002209200828029403470d00200941016a22102009490d012009410174220b20102010200b491b220cad4205862211422088a70d012011a722104100480d01024002402009450d00200828029003210f20101000220b450d0c200b200f201020094105742224202420104b1b10f8021a200f10010c010b20101000220b450d0b0b2008200c360294032008200b360290030b20082802900320094105746a220941013602182009200a36020c2009428380808030370204200920013602002009411c6a200d360200200941106a4286808080e0003702002000200028020041016a360200201c201c280200417f6a2209360200024020090d00201c41086a2802001011201c201c280204417f6a220936020420090d00201c10010b41002109200841f8026a4100360200200841e8026a2003360200200841003a00880320082007360284032008201c36028003200820063602fc02200842013703f002200820043602ec02200820023602e402200820053602e002200841a0026a20084190036a10d70202400240411c2023202120082802a002220120082802a802200841e0026a1012220d417f460d00200d417d470d01410221090b024020082802a402450d00200110010b024020094102470d0020084188036a2d0000210120084180036a28020021090240200841f4026a280200450d00200841f0026a28020010010b20092009280200417f6a220a3602000240200a0d002009280208101120092009280204417f6a220a360204200a0d00200910010b4108410520011b210941002124410121250c110b0240200841f4026a280200450d00200841f0026a28020010010b20084180036a220928020022012001280200417f6a3602000240200928020022012802000d0020012802081011200928020022012001280204417f6a360204200928020022092802040d00200910010b024020084198036a2802002201450d0020082802900321092001410574210103400240200941046a280200450d00200928020010010b0240200941106a280200450d002009410c6a28020010010b200941206a2109200141606a22010d000b0b0240200828029403450d0020082802900310010b0240200841a4036a2802002201450d002008419c036a28020021092001410274210103402009280200220a200a280200417f6a36020002402009280200220a2802000d00200a28020810112009280200220a200a280204417f6a3602042009280200220a2802040d00200a10010b200941046a21092001417c6a22010d000b0b0240200841a0036a280200450d002008419c036a28020010010b02402022450d00202310010b200841c0006a10d201200841c0036a240041060f0b200841c8026a20084190036a410c6a102d20082802d002211020082802cc02210c20082802c802210b024020082802a402450d00200110010b200841ac026a2010360200200841a0026a41086a200c3602002008200b3602a4022008200d3602a002200841003602d002200842083703c802200841c8026a4188f0c1004100102620082802cc02210020082802c802210a20082802d0022109200841003602d002200842013703c8022009200841c8026a101b02402009450d0020094104742101200a210903402009200841c8026a10d902200941106a2109200141706a22010d000b0b200841c8026a41086a280200210f20082802cc02212420082802c802210102402000450d00200a10010b410a10002209450d0a20094200370000200941086a41003b000041012100200d419fb9c10041042001200f2009410a200841e0026a1013220a417d460d0c200a0d0b2008410936028c022008200941016a360288020240024020092d0000220a4101460d00200a0d01410021000c0e0b200841c8026a20084188026a10d80220082802c802220a4104460d0041002100200a4105470d0d0b2009100102402024450d00200110010b20084180036a2802002101200841f4026a280200210a200841f0026a280200210f20084188036a2d00004521090c0d0b1018000b410341011019000b102c000b200141011019000b200b41041019000b00000b410341011019000b410641011019000b200a41041019000b201041041019000b410a41011019000b41d889c300104f000b2009100102402024450d00200110010b20084180036a2802002101200841f4026a280200210a200841f0026a280200210f20084188036a2d0000212402402000450d0020244521090c010b410821092024450d0141acd6c200104f000b4105410820091b21090b0240200a450d00200f10010b20012001280200417f6a220a3602000240200a0d002001280208101120012001280204417f6a220a360204200a0d00200110010b200d101402402010450d002010410274210a200b21010340200128020022002000280200417f6a3602000240200128020022002802000d0020002802081011200128020022002000280204417f6a360204200128020022002802040d00200010010b200141046a2101200a417c6a220a0d000b0b4101212441002125200c450d00200b10010b2008280290032100024020084198036a2802002201450d002001410574210a2000210103400240200141046a280200450d00200128020010010b0240200141106a280200450d002001410c6a28020010010b200141206a2101200a41606a220a0d000b0b0240200828029403450d00200010010b2008419c036a280200210f0240200841a4036a2802002201450d002001410274210a200f21010340200128020022002000280200417f6a3602000240200128020022002802000d0020002802081011200128020022002000280204417f6a360204200128020022002802040d00200010010b200141046a2101200a417c6a220a0d000b0b0240200841a0036a280200450d00200f10010b02402022450d00202310010b200841c0006a10d20120242025410047720d0a200d101402402010450d002010410274210a200b21010340200128020022002000280200417f6a3602000240200128020022002802000d0020002802081011200128020022002000280204417f6a360204200128020022002802040d00200010010b200141046a2101200a417c6a220a0d000b0b200c450d0a200b1001200841c0036a240020090f0b41bca1c10041361042000b200f450d070b0240200d450d00200d412c6c210a200f210103402001102a2001412c6a2101200a41546a220a0d000b0b2010450d06200f10010c060b02402010450d002010412c6c2101200f210903402009102a2009412c6a2109200141546a22010d000b0b411921012000450d00200f10010b0b0c010b410521014100210d0b200d411074200a41ff017141087472200141ff01717221010b41012109200141ff01714105470d00200b450d00200c10010b200841c0006a10d2010b200841c0036a240020090bf70604027f017e067f027e230041d0006b220424002004200136021c200420004188f0c10020011b360218200441106a200441186a103a024002400240024002400240024002402004280210450d0020042802142205ad2206421c88a70d022006420486a72201417f4c0d02024002400240024002402001450d00200110002200450d0820050d010c020b410821002005450d010b200441306a4104722107410021080340200441306a200441186a10d802200441c0006a41086a2201200741086a28020036020020042007290200370340200428023022094104460d03200441206a41086a220a20012802003602002004200429034037032002402006422088a722012006a7470d00200141016a220b2001490d032001410174220c200b200b200c491bad220d420486220e422088a70d03200ea7220b4100480d03024002402001450d00200b1000220c450d08200c2000200b20014104742201200b2001491b10f802210120001001200121000c010b200b10002200450d070b200642808080807083200d8421060b20002006422088a74104746a220120093602002001410c6a200a2802003602002001200429032037020420064280808080107c2106200841016a22082005490d000b0b2000450d022004200637022420042000360220200441086a200441206a1049200441306a20022004280208200428020c20031105002004410036024820044201370340200428023021004101100021010240024020004105470d002001450d08200141013a000020044281808080103702442004200136024042012106200121000c010b2001450d08200141003a0000200442818080801037024420042001360240024020004104470d00410210002200450d0a200020012d00003a000020011001200041003a0001200442828080802037024420042000360240420221060c010b410210002200450d0a200020012d00003a000020011001200041013a0001200442828080802037024420042000360240200441306a200441c0006a10d902200441c8006a3502002106200428024021000b2000ad422086200684210602402004280224450d00200428022010010b200441d0006a240020060f0b1018000b2006a7450d00200010010b41dec1c10041f0001042000b200b41081019000b102c000b200141081019000b410141011019000b410141011019000b410241011019000b410241011019000b4501017f230041c0006b22012400200141386a2000410c6a28020036020020012000290204370330200141086a200141306a10cf01200141086a10d001200141c0006a24000b4b00200041ddf5c10036020420004100360200200041206a41003602002000411c6a4188f0c100360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000b3400200041f9bdc10036020420004100360200200041146a4101360200200041106a41bc85c300360200200041086a42093702000b4b00200041ddf5c10036020420004100360200200041206a41063602002000411c6a41f885c300360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000b871a0a027f027e107f027e017f027e047f017e077f017e230041d0026b22022400200241086a200110350240024002400240024002402002280208450d00200228020c2203ad220442287e2205422088a70d032005a72206417f4c0d03024002400240024002402006450d00200610002207450d0920030d010c020b410821072003450d010b200241c7016a2108200241f8006a41116a2109200241b8016a41106a2106200241b8016a410172210a200241106a410172210b200141046a210c200141086a210d200241f0016a210e20024180026a210f410021100340200241003a00b8012001280200200c280200200241b8016a4101200d28020010042111200d200d280200201141016a221141014b6a221236020002400240024002400240024002400240024002400240024020114102490d004104211320022d00b801221141034b0d0b024020110e0400040203000b2002200110352002280200450d0b20022802042211417f4c0d132011450d08201110002212450d1520124100201110f7021a0c090b410421130c0a0b200241b8016a41186a2214420037030020064200370300200241b8016a41086a22114200370300200242003703b801200d41002001280200200c280200200241b8016a41202012100422122012417f461b2212412020124120491b200d2802006a3602002012411f4d0d04200241c0026a41026a20022d00ba013a000020024188026a41086a200841086a29000037030020024188026a41106a200841106a2d00003a0000200220022f01b8013b01c002200220082900003703880220022800bb01211520022900bf012116410121120c050b200242003703b801200d41002001280200200c280200200241b8016a41082012100422112011417f461b2211410820114108491b200d2802006a2212360200201141074d0d0120022903b8012117200e4200370300200241b8016a41306a4200370300200241b8016a41286a4200370300200241b8016a41206a4200370300200241b8016a41186a420037030020064200370300200241b8016a41086a4200370300200242003703b801200d41002001280200200c280200200241b8016a41c0002012100422112011417f461b221141c000201141c000491b200d2802006a3602002011413f4d0d0120024188026a41086a200841086a29000037030020024188026a41106a200841106a29000037030020024188026a41186a200841186a29000037030020024188026a41206a200841206a29000037030020024188026a41286a200841286a29000037030020024188026a41306a200841306a2d00003a0000200220022d00ba013a00c202200220022f01b8013b01c002200220082900003703880220022800bb01211820022900bf012119410121112017211a0c020b200241b8016a2001103420022802b8012211450d0720022902bc012105200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a2006290300370300200241f8006a41186a200241b8016a41186a290300370300200241f8006a41206a200241b8016a41206a290300370300200241f8006a41286a200241b8016a41286a290300370300200241f8006a41306a200241b8016a41306a290300370300200220024188026a41026a2d00003a00b201200220022f0088023b01b001200220022903b801370378410021132011211b0c060b410021110b200241b8016a41086a221220024188026a41086a290300370300200620024188026a41106a290300370300200241b8016a41186a221420024188026a41186a290300370300200241b8016a41206a221c20024188026a41206a290300370300200241b8016a41286a221d20024188026a41286a290300370300200241b8016a41306a221e20024188026a41306a2d00003a0000200220022d00c2023a00ca02200220022f01c0023b01c80220022002290388023703b8012011450d05200241f8006a41086a2012290300370300200241f8006a41106a2006290300370300200241f8006a41186a2014290300370300200241f8006a41206a201c290300370300200241f8006a41286a201d290300370300200241f8006a41306a201e2d00003a0000200220022d00ca023a00b201200220022f01c8023b01b001200220022903b801370378410221132018211b20192105201a211f0c050b410021120b200241c8026a41026a221c200241c0026a41026a2d00003a0000201120024188026a41086a290300370300200620024188026a41106a2d00003a0000200220022f01c0023b01c80220022002290388023703b8012012450d03200241f8006a41086a2011290300370300200241f8006a41106a20062d00003a0000200220022f01c8023b01b001200220022903b8013703782002201c2d00003a00b2012009411f6a200241b8016a411f6a290000370000200941186a2014290000370000200941106a2006290000370000200941086a2011290000370000200920022900b801370000410121132015211b201621050c020b410121120b200d201141002001280200200c28020020122011200d280200100422142014417f461b2214201420114b1b200d2802006a3602000240201120144d0d00201210010c020b2012450d012011ad22054220862005842105200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a2006290300370300200241f8006a41186a200241b8016a41186a290300370300200241f8006a41206a200241b8016a41206a290300370300200241f8006a41286a200241b8016a41286a290300370300200241f8006a41306a200241b8016a41306a290300370300200220022f0088023b01b001200220022903b801370378200220024188026a41026a2d00003a00b201410321132012211b0b0b20024188026a41026a221e20022d00b2013a0000200241b8016a41086a2211200241f8006a41086a22142903003703002006200241f8006a41106a221c290300370300200241b8016a41186a2212200241f8006a41186a221d290300370300200241b8016a41206a2220200241f8006a41206a290300370300200241b8016a41286a2221200241f8006a41286a290300370300200241b8016a41306a2222200241f8006a41306a290300370300200220022f01b0013b018802200220022903783703b80120134104460d02200241f4006a41026a2223201e2d00003a0000200241386a41086a221e2011290300370300200241386a41106a22242006290300370300200241386a41186a22252012290300370300200241386a41206a22262020290300370300200241386a41286a22202021290300370300200241386a41306a22212022290300370300200220022f0188023b0174200220022903b80137033820112005370300200a20022f01743b0000200a41026a20232d00003a000020062002290338370000200641086a201e290300370000200641106a2024290300370000200641186a2025290300370000200641206a2026290300370000200641286a2020290300370000200641306a2021290300370000200220133a00b8012002201b3602bc01200f201f370300200241106a200241b8016a10d60220022d00102113200241b8016a411f6a221e200b411f6a2900003700002012200b41186a2900003703002006200b41106a2900003703002011200b41086a2900003703002002200b2900003703b80120134103460d03200241f8006a411f6a2220201e290000370000201d2012290300370300201c200629030037030020142011290300370300200220022903b80137037802402004422088a722112004a7470d00201141016a22122011490d062011410174221e20122012201e491bad221742287e2227422088a70d062027a722124100480d06024002402011450d0020121000221e450d09201e20072012201141286c2211201120124b1b10f802211120071001201121070c010b201210002207450d080b20044280808080708320178421040b20072004422088a741286c6a221120133a0000201141206a2020290000370000201141196a201d290300370000201141116a201c290300370000201141096a20142903003700002011200229037837000120044280808080107c2104201041016a22102003490d000b0b2007450d022000200437020420002007360200200241d0026a24000f0b200241033a0010200241b8016a411f6a200b411f6a290000370000200241b8016a41186a200b41186a290000370300200241b8016a41106a200b41106a290000370300200241b8016a41086a200b41086a2900003703002002200b2900003703b8010b02402004422088a72206450d00200641286c2111200721060340024020062d0000220b450d000240200b4101470d00200641086a280200450d01200641046a2802001001200641286a2106201141586a22110d020c030b200641146a280200450d00200641106a28020010010b200641286a2106201141586a22110d000b0b2004a7450d00200710010b20004100360200200241d0026a24000f0b1018000b201241081019000b102c000b200641081019000b201141011019000bcc0201057f230041206b22022400024002400240411610002203450d002002421637021420022003360210200241106a4181c8c10041161025200241086a220320022802183602002002200229031037030020012002101e200328020021042002280204210520022802002101200241106a41086a220642003703002002420037031020012004200241106a1002200320062903003703002002200229031037030002400240200241104188f0c100410041001004417f460d002002410036021020024110200241106a41044100100441016a41044d0d01200228021021032002410036021020024110200241106a41044104100441016a41044d0d01200041086a200228021036020020002003360204200041013602002005450d040c030b2000410036020020050d020c030b41eac4c10041331042000b411641011019000b200110010b200241206a24000b3400200041a9cbc10036020420004100360200200041146a4114360200200041106a41c08bc300360200200041086a42073702000b4b00200041ddf5c10036020420004100360200200041206a41093602002000411c6a419896c300360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000b130020004104360204200041d89dc3003602000ba80703057f037e047f230041206b220324000240024002402002280208220420014d0d00200241086a2004417f6a22053602002002280200220620054105746a22072900002108200729000821092007290010210a200620014105746a220141186a200741186a2900003700002001200a37001020012009370008200120083700002002280204210b20034100360218200342013703102005200341106a101b02400240024002402005450d00200441057441606a210c200341106a41086a280200210120032802102104200328021421072006210d0340200d210202400240024002402007200122056b41204f0d00200541206a22012005490d072007410174220d20012001200d491b220d4100480d07200d1000210e2007450d01200e450d08200e2004200d20072007200d4b1b10f8021a200410010c020b200541206a21010c020b200e450d060b200e2104200d21070b200241206a210d200420056a22052002290000370000200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a290000370000200c41606a220c0d000b200341186a200136020020032007360214200320043602100c010b200341106a41086a280200210120032802142107200328021021040b200341106a41086a220242003703002003420037031041b6c7c100410e200341106a1002200341086a2002290300370300200320032903103703002003411020042001100302402007450d00200410010b0240200b450d00200610010b411310002202450d032003421337021420032002360210200341106a41eee8c10041131025200341086a220220032802183602002003200329031037030020002003101e200228020021072003280204210120032802002105200341106a41086a220442003703002003420037031020052007200341106a1002200220042903003703002003200329031037030020034110100802402001450d00200510010b411410002202450d042003421437021420032002360210200341106a41c8e8c10041141025200341086a220220032802183602002003200329031037030020002003101e200228020021072003280204210120032802002105200341106a41086a220442003703002003420037031020052007200341106a1002200220042903003703002003200329031037030020034110100802402001450d00200510010b200341206a24000f0b1018000b200d41011019000b41b08bc30020012004104e000b411341011019000b411441011019000baa0201057f230041306b220224000240024002400240411310002203450d002002421337022420022003360220200241206a41eee8c10041131025200241086a220320022802283602002002200229032037030020012002101e200328020021042002280204210520022802002101200241206a41086a220642003703002002420037032020012004200241206a100220032006290300370300200220022903203703000240200241104188f0c100410041001004417f460d002002421037021420022002360210200241206a200241106a103d20022802202203450d0220002002290224370204200020033602002005450d040c030b200041003602082000420137020020050d020c030b411341011019000b41eac4c10041331042000b200110010b200241306a24000b940201067f23004180016b220124000240411310002202450d002001421337020420012002360200200141abf1c10041131025200141f0006a41086a22022001280208360200200120012903003703702000200141f0006a101e200228020021032001280274210420012802702105200141086a220642003703002001420037030020052003200110022002200629030037030020012001290300370370200141f0006a4110100802402004450d00200510010b200641013a0000200141096a2000290000370000200141116a200041086a290000370000200141196a200041106a290000370000200141216a200041186a290000370000200141013a0000200110b40120014180016a24000f0b411341011019000b3400200041b1f3c10036020420004100360200200041146a410a360200200041106a4198a0c300360200200041086a42063702000b34002000418ff6c10036020420004100360200200041146a410b360200200041106a41f8a4c300360200200041086a42083702000baf05010c7f230041206b2202240002400240411010002203450d002002421037021420022003360210200241106a41c785c20041101025200228021021040240024002400240024020022802142205200228021822036b41044f0d00200341046a22062003490d0320054101742207200620062007491b22084100480d032005450d01200810002207450d062007200420082005200520084b1b10f802210520041001200521040c020b200341046a2106200521080c010b200810002204450d040b200420036a200036000020024100360218200242013703102001280200210920012802082203200241106a101b024002402003450d002003410574210a200241106a41086a28020021072002280210210b200228021421002009210c0340200c210302400240024002402000200722056b41204f0d00200541206a22072005490d072000410174220c20072007200c491b220c4100480d07200c1000210d2000450d01200d450d08200d200b200c20002000200c4b1b10f8021a200b10010c020b200541206a21070c020b200d450d060b200d210b200c21000b200341206a210c200b20056a22052003290000370000200541186a200341186a290000370000200541106a200341106a290000370000200541086a200341086a290000370000200a41606a220a0d000b200241186a2007360200200220003602142002200b3602100c010b200241186a2802002107200228021421002002280210210b0b200241106a41086a220342003703002002420037031020042006200241106a1002200241086a20032903003703002002200229031037030020024110200b2007100302402000450d00200b10010b02402008450d00200410010b0240200141046a280200450d00200910010b200241206a24000f0b1018000b200c41011019000b411041011019000b200841011019000b4b00200041ddf5c10036020420004100360200200041206a41023602002000411c6a41bcacc300360200200041146a4204370200200041106a41e3f5c100360200200041086a42063702000b130020004103360204200041dcaec3003602000b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f02400240200120004f0d002002450d012001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000c020b0b2002450d00200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000b0b20000b4401037f024002402002450d00410021030340200020036a2d00002204200120036a2d00002205470d02200341016a22032002490d000b41000f0b41000f0b200420056b0b3e01017f230041106b22052400200520012002200320044100108003200529030021012000200541086a29030037030820002001370300200541106a24000b7501027e200020034220882205200142208822067e200320027e7c200420017e7c200342ffffffff0f832203200142ffffffff0f8322017e2204422088200320067e7c22034220887c200342ffffffff0f83200520017e7c22034220887c37030820002003422086200442ffffffff0f83843703000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a108003200529031021012000200529031837030820002001370300200541206a24000b5701017e02400240200341c000710d002003450d012001410020036b413f71ad8820022003413f71ad220486842102200120048621010c010b20012003413f71ad862102420021010b20002001370300200020023703080b5701017e02400240200341c000710d002003450d0120012003413f71ad2204882002410020036b413f71ad86842101200220048821020c010b20022003413f71ad882101420021020b20002001370300200020023703080bd80502037f067e230041306b220624000240024002400240024002400240024002400240024002400240024002400240024020024200510d002003500d012004500d03200479a7200279a76b2207413f4b0d0241ff0020076b2108200741016a21070c0c0b200450450d012005450d0520034200510d0c20054200370308200520012003823703000c060b2004500d0b20014200510d032004427f7c2209200483500d07200479a7200279a76b2207413e4d0d090b2005450d012005200137030020052002370308420021010c070b2003427f7c2209200383500d044100200379a741c1006a200279a76b22076b21080c080b420021010c050b02402005450d0020054200370300200520022004823703080b200220048021010c040b20034200510d060b200120038021010c020b02402005450d0020054200370308200520092001833703000b20034201510d07200641206a2001200220037aa710ff02200641286a2903002102200629032021010c070b02402005450d0020052001370300200520092002833703080b200220047a423f838821010b420021020c050b41ff0020076b2108200741016a21070b200620012002200841ff007110fe02200641106a20012002200741ff007110ff02200641086a2903002102200641106a41086a290300210a200629030021012006290310210902402007450d004200210b4200210c0340200a4201862009423f8884220d200d427f8520047c20094201862002423f88842209427f85220d20037c200d54ad7c423f87220d2004837d2009200d200383220e54ad7d210a2009200e7d2109420020024201862001423f8884842102200c2001420186842101200d420183220d210c2007417f6a22070d000b2005450d030c020b4200210d4200210b20050d010c020b00000b200520093703002005200a3703080b200b20024201862001423f8884842102200d20014201868421010b2000200137030020002002370308200641306a24000b0bdeb0030200418080c0000ba98d022f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962616c6c6f632f7665632e727366756e635f737461636b5f636f7374732069736e27742079657420636f6d70757465643b0a0909090944696420796f752063616c6c2060636f6d707574655f737461636b5f636f737473603f546869732073686f756c64206265206120696e646578206f66206120646566696e65642066756e6374696f6e44756520746f2076616c69646174696f6e20636f64652073656374696f6e2073686f756c642065786973747346756e6374696f6e20626f6479206973206f7574206f6620626f756e647343616c6c20746f2066756e6374696f6e2074686174206f75742d6f662d626f756e64733a200000000000002f686f6d652f6261737469616e2f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e332e312f7372632f737461636b5f6865696768742f6d6f642e727366756e6374696f6e20696d706f727420636f756e74206973206e6f74207a65726f3b20696d706f72742073656374696f6e206d757374206578697374733b2071656466756e635f696478206973206c657373207468616e2066756e6374696f6e20696d706f72747320636f756e743b0a090909096e74682066756e6374696f6e20696d706f7274206d7573742062652060536f6d65603b0a090909097165645369676e61747572652020287370656369666965642062792066756e6320292069736e277420646566696e656446756e6374696f6e20617420696e64657820206973206e6f7420646566696e65640000000000000000000000002f686f6d652f6261737469616e2f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e332e312f7372632f6761732e72737372632f6c6962616c6c6f632f7665632e7273617373657274696f6e206661696c65643a20656e64203c3d206c656e617373657274696f6e206661696c65643a20696e646578203c3d206c656e4e6f2066756e6374696f6e2073656374696f6e4e6f20636f64652073656374696f6e4e6f20747970652073656374696f6e46756e6374696f6e206973206e6f7420666f756e6420696e2066756e632073656374696f6e46756e6374696f6e20626f647920666f722074686520696e6465782069736e277420666f756e64737461636b206d757374206265206e6f6e2d656d707479737461636b206f766572666c6f774172697479206f6620616c6c206a756d702d74617267657473206d75737420626520657175616c54797065206e6f7420666f756e6400002f686f6d652f6261737469616e2f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e332e312f7372632f737461636b5f6865696768742f6d61785f6865696768742e7273747279696e6720746f20706f70206d6f72652076616c756573207468616e20707573686564737461636b20756e646572666c6f77636f6e74726f6c20737461636b20697320656d707479636f6e74726f6c20737461636b206f75742d6f662d626f756e6473000000000000000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f736c6963652f6d6f642e72736066756e635f696478602073686f756c6420636f6d652066726f6d20606e6565645f7468756e6b73603b0a09090909606e6565645f7468756e6b736020697320706f70756c617465642077697468207468652073616d65206974656d73207468617420696e20607265706c6163656d656e745f6d6170603b0a090909097165644174207468697320706f696e7420616e20696e646578206d7573742062652061737369676e656420746f2065616368207468756e6b66756e6374696f6e207769746820696478202069736e277420666f756e64547261696c696e6744617461556e6578706563746564456f66496e76616c696444617461492f4f204572726f723a204578706c69636974207265706f7274696e67206e6f7420616c6c6f77656445787472696e7369635375636365737345787472696e7369634661696c656420416e2065787472696e736963206661696c65642e20416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e48617368206e6f7420657175616c00617474656d707420746f20646976696465206279207a65726f000000000000002f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f636f72652f73722d7072696d6974697665732f7372632f67656e657269632f6572612e727352756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e676361706163697479206f766572666c6f776120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f72000000000000000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f666d742f6d6f642e727301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202020202020202020202020202020202020202020202020202020202020303030303030303030303030303030304040404040000000000000000000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e646578206973203030303130323033303430353036303730383039313031313132313331343135313631373138313932303231323232333234323532363237323832393330333133323333333433353336333733383339343034313432343334343435343634373438343935303531353235333534353535363537353835393630363136323633363436353636363736383639373037313732373337343735373637373738373938303831383238333834383538363837383838393930393139323933393439353936393739383939696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820736c69636520696e64657820737461727473206174202062757420656e6473206174206030785b2e2e2e5d000100000000000000200000000000000003000000000000000300000000000000030000000100000001000000200000000000000003000000000000000300000000000000030000000100000002000000200000000000000003000000000000000300000000000000030000000100000003000000200000000000000003000000000000000300000000000000030000000100000000000000200000000000000003000000000000000300000000000000030000000100000001000000200000000000000003000000000000000300000000000000030000000100000002000000200000000000000003000000000000000300000000000000030000000100000003000000200000000000000003000000000000000300000000000000030000000100000004000000200000000000000003000000000000000300000000000000030000007372632f6c6962636f72652f7374722f6d6f642e72736279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f6620600000007372632f6c6962636f72652f666d742f6d6f642e72732e2e00000000000000007372632f6c6962636f72652f756e69636f64652f626f6f6c5f747269652e72730000c0fbef3e00000000000e0000000000000000000000000000f8fffbffffff0700000000000014fe21fe000c00000002000000000000501e2080000c00004006000000000000108639020000002300be2100000c0000fc02000000000000d01e20c0000c0000000400000000000040012080000000000011000000000000c0c13d60000c0000000200000000000090443060000c00000003000000000000581e2080000c00000000845c8000000000000000000000f207807f000000000000000000000000f21b003f000000000000000000030000a002000000000000fe7fdfe0fffeffffff1f40000000000000000000000000e0fd66000000c301001e006420002000000000000000e00000000000001c0000001c0000000c0000000c00000000000000b03f40fe0f200000000000380000000000006000000000020000000000008701040e00008009000000000000407fe51ff89f000000000000ff7f0f0000000000d0170400000000f80f00030000003c3b00000000000040a303000000000000f0cf000000f7fffd211003fffffffffffffffb00100000000000000000ffffffff01000000000000800300000000000000008000000000ffffffff0000000000fc00000000000600000000000000000080f73f000000c0000000000000000000000300440800006000000030000000ffff038000000000c03f000080ff030000000000070000000000c813000000002000000000000000007e660008100000000000100000000000009dc1020000000030400000000000202100000000004000000000ffff0000ffff00000000000000000001000000020003000000000000000000000000000000000000000000000000000004000005000000000000000006000000000000000007000008090a000b0c0d0e0f000010111200001314151600001718191a1b001c0000001d000000000000001e1f20000000000021002200232425000000002600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027280000000000000000000000000000000000290000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000002b2c00002d0000000000000000000000000000000000000000000000000000000000002e2f300000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000000000320033000000000000000000000000000000000000000000000000000034350000353535360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000001000000000000000000c0076ef0000000000087000000006000000000000000f0000000c0ff01000000000002000000000000ff7f0000000000008003000000000078060700000080ef1f000000000000000800030000000000c07f001e000000000000000000000080d34000000080f8070000030000000000005801008000c01f1f0000000000000000ff5c00004000000000000000000000f9a50d000000000000000000000000803cb00100003000000000000000000000f8a70100000000000000000000000028bf00000000e0bc0f0000000000000080ff06fe0700000000f87980007e0e0000000000fc7f03000000000000000000007fbf0000fcfffffc6d000000000000007eb4bf000000000000000000a3000000000000000000000018000000000000001f000000000000007f000080070000000000000000600000000000000000a0c307f8e70f0000003c00001c00000000000000ffffffffffff7ff8ffffffffff1f2000100000f8feff00007ffffff9db07000000007f0000000000f00700000000000000000000ffffffffffffffffffffffffffffffffffff000000010305050606030706080809110a1c0b190c140d120e160f0410031212130916011705180219031a071c021d011f1620032b062c022d0b2e01300331023202a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f0040d1145496465808184b2bcbebfd5d7f0f1838586898b8c98a0a4a6a8a9acbabebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f74759697c9ff2f5f262e2fa7afb7bfc7cfd7df9a409798308f1fffceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab351e1580e003190801042f043404070301070607110a500f1207550802041c0a090308030703020303030c0405030b06010e15053a0311070605100856070207150d500443032d03010411060f0c3a041d250d064c206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a061f414c042d0374083c030f033c0738082a0682ff1118082f112d032010210f808c048297190b158894052f053b07020e180980af31740c80d61a0c0580ff0580b605240c9bc60ad23010848d033709815c1480b80880ba3d35040a06380846080c06740b1e035a0459098083181c0a1609460a808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b0210011104120513111402150217021a021c051d0824016a036b02bc02d102d40cd509d602d702da01e005e802ee20f004f9040c273b3e4e4f8f9e9e9f060709363d3e56f3d0d104141836375657bd35cecfe01287898e9e040d0e11122931343a4546494a4e4f64655a5cb6b71b1c848509379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a2225c5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d03f71727b5e227b0503042d036504012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a81261f808128082a80a64e041e0f430e19070a0647092709750b3f412a063b050a0651060105100305808b5f2148080a80a65e22450b0a060d1338080a362c041080c03c64530c0181004808531d398107460a1d03474937030e080a0639070a8136198107839a66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b65450b2f101140021e97f20e82f3a50d811f51818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b87d580d7294b050a0402831144814b3c06010455051b3402810e2c04640c560a0d035c043d391d0d2c040907020e06809a83d50b0d030a06740c59270c0438080a0628081e520c046703290d0a06030d30600e859263616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c75657372632f6c6962636f72652f6f7074696f6e2e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f662060426f72726f774572726f72426f72726f774d75744572726f724572726f72547269656420746f20736872696e6b20746f2061206c61726765722063617061636974797372632f6c6962616c6c6f632f7261775f7665632e7273626164206f726967696e3a20657870656374656420746f2062652061207468726573686f6c64206e756d626572206f6620636f756e63696c206d656d62657273436f6e747261637420436f64654f66436f6e7472616374204761735370656e74436f6e747261637420426c6f636b4761734c696d6974637265617465204372656174652061206e657720636f6e74726163742c206f7074696f6e616c6c79207472616e73666572696e6720736f6d652062616c616e636520746f207468652063726561746564206163636f756e742e204372656174696f6e20697320657865637574656420617320666f6c6c6f77733a202d207468652064657374696e6174696f6e206164647265737320697320636f6d7075746564206261736564206f6e207468652073656e64657220616e642068617368206f662074686520636f64652e202d206163636f756e7420697320637265617465642061742074686520636f6d707574656420616464726573732e202d20746865206063746f725f636f64656020697320657865637574656420696e2074686520636f6e74657874206f6620746865206e65776c792063726561746564206163636f756e742e204275666665722072657475726e656420202061667465722074686520657865637574696f6e206973207361766564206173207468652060636f646560206f6620746865206163636f756e742e205468617420636f64652077696c6c20626520696e766f6b656420202075706f6e20616e79206d6573736167652072656365697665642062792074686973206163636f756e742e656e646f776d656e746761735f6c696d69743c543a3a47617320617320486173436f6d706163743e3a3a5479706563746f725f636f646564617461204d616b6520612063616c6c20746f206120737065636966696564206163636f756e742c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e436f6e7472616374204761735072696365566563203c2054203a3a2048617368203e3c2054206173205472616974203e203a3a2050726f706f73616c566f74696e67282050726f706f73616c496e646578202c20753332202c20566563203c2054203a3a204163636f756e744964203e202c20566563203c2054203a3a204163636f756e744964203e20292050726f706f73616c7320736f206661722e20566f74657320666f72206120676976656e2070726f706f73616c3a202872657175697265645f7965735f766f7465732c207965735f766f746572732c206e6f5f766f74657273292e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e205468652028686173686573206f662920746865206163746976652070726f706f73616c732e426f783c3c542061732054726169743e3a3a50726f706f73616c3e4372656174656420436f6e7472616374206465706c6f7965642062792061646472657373206174207468652073706563696669656420616464726573732e205472616e736665722068617070656e6564206066726f6d60202d3e2060746f60207769746820676976656e206076616c7565602061732070617274206f66206120606d6573736167652d63616c6c60206f722060637265617465602e2f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f636f6e74726163742f7372632f6c69622e7273566f746564417070726f766564446973617070726f7665642041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e206173207533327320726573706563746976656c79292e2041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20753332292e2f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f636f756e63696c2f7372632f6d6f74696f6e732e72730000000000000000000000000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b2071656450726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b20716564000000000000000000000000000000000000000000436f6e74726163742043757272656e745363686564756c65436f6e7472616374204d61784465707468436f6e747261637420436f6e7472616374466565436f6e74726163742043616c6c42617365466565436f6e74726163742043726561746542617365466565436f756e63696c4d6f74696f6e732050726f706f73616c4f6670726f706f736572206e6f74206f6e20636f756e63696c436f756e63696c4d6f74696f6e732050726f706f73616c436f756e74436f756e63696c4d6f74696f6e732050726f706f73616c73436f756e63696c4d6f74696f6e7320566f74696e67766f746572206e6f74206f6e20636f756e63696c70726f706f73616c206d7573742065786973746d69736d61746368656420696e6465786475706c696361746520766f74652069676e6f72656400000000000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f736c6963652f6d6f642e7273626c6f636b20676173206c696d697420697320726561636865646f766572666c6f77206d756c7469706c79696e6720676173206c696d69742062792070726963655472656173757279205370656e64506572696f64547265617375727920506f74547265617375727920417070726f76616c735472656173757279204275726e0000000000000000617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f6f70732f61726974682e727356616c696461746f72436f756e744d696e696d756d56616c696461746f72436f756e7453657373696f6e7350657245726153657373696f6e52657761726450657262696c6c4f66666c696e65536c6173684f66666c696e65536c6173684772616365426f6e64696e674475726174696f6e43757272656e7445726156616c696461746f72507265666572656e63657356616c696461746f725072656673203c2054203a3a2042616c616e6365203e496e74656e74696f6e734e6f6d696e6174696e674e6f6d696e61746f7273466f7243757272656e744e6f6d696e61746f7273466f7243757272656e7453657373696f6e52657761726443757272656e744f66666c696e65536c6173684e65787453657373696f6e735065724572614c6173744572614c656e6774684368616e67655374616b6552616e6765506169724f66203c2054203a3a2042616c616e6365203e536c617368436f756e74466f7263696e674e6577457261282020292057652061726520666f7263696e672061206e6577206572612e20546865206e756d626572206f662074696d6573206120676976656e2076616c696461746f7220686173206265656e207265706f72746564206f66666c696e652e205468697320676574732064656372656d656e746564206279206f6e652065616368206572612074686174207061737365732e2054686520626c6f636b20617420776869636820746865206077686f6027732066756e6473206265636f6d6520656e746972656c79206c69717569642e20546865206869676865737420616e64206c6f77657374207374616b65642076616c696461746f7220736c61736861626c652062616c616e6365732e205468652073657373696f6e20696e6465782061742077686963682074686520657261206c656e677468206c617374206368616e6765642e20546865206e6578742076616c7565206f662073657373696f6e7320706572206572612e204e6f6d696e61746f727320666f72206120706172746963756c6172206163636f756e74207468617420697320696e20616374696f6e207269676874206e6f772e204e6f6d696e61746f727320666f72206120706172746963756c6172206163636f756e742e20416c6c206e6f6d696e61746f72202d3e206e6f6d696e65652072656c6174696f6e73686970732e20416c6c20746865206163636f756e7473207769746820612064657369726520746f207374616b652e20507265666572656e636573207468617420612076616c696461746f72206861732e205468652063757272656e742065726120696e6465782e20546865206c656e677468206f662074686520626f6e64696e67206475726174696f6e20696e20626c6f636b732e204e756d626572206f6620696e7374616e636573206f66206f66666c696e65207265706f727473206265666f726520736c617368696e6720626567696e7320666f722076616c696461746f72732e20536c6173682c207065722076616c696461746f7220746861742069732074616b656e20666f72207468652066697273742074696d6520746865792061726520666f756e6420746f206265206f66666c696e652e204d6178696d756d207265776172642c207065722076616c696461746f722c20746861742069732070726f7669646564207065722061636365707461626c652073657373696f6e2e20546865206c656e677468206f662061207374616b696e672065726120696e2073657373696f6e732e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e5374616b696e6720536c617368436f756e745374616b696e67204f66666c696e65536c61736847726163655374616b696e672043757272656e744f66666c696e65536c617368736c61736820636f756e74206e6f206c6f6e67657220696e6372656d656e746564206166746572206f766572666c6f773b207072696f7220636865636b206f6e6c79206661696c73207769746820696e7374616e636573203e3d20313b207468757320696e7374616e636573202d203120616c7761797320776f726b7320616e6420697320612076616c696420616d6f756e74206f6620626974733b207165645374616b696e6720496e74656e74696f6e735374616b696e67204d696e696d756d56616c696461746f72436f756e745374616b696e672056616c696461746f72507265666572656e636573706f73206465726976656420636f72726563746c792066726f6d2053656c663a3a696e74656e74696f6e7328293b206170706c795f756e7374616b652063616e206f6e6c79206661696c20696620706f732077726f6e673b2053656c663a3a696e74656e74696f6e73282920646f65736e2774206368616e67653b207165645374616b696e6720466f7263696e674e65774572615374616b696e6720426f6e64696e674475726174696f6e5374616b696e6720426f6e64616765496e76616c696420696e646578000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f736c6963652f6d6f642e72735374616b696e67204e6f6d696e61746f7273466f725374616b696e672043757272656e744e6f6d696e61746f7273466f727374616b65756e7374616b656e6f6d696e617465756e6e6f6d696e61746572656769737465725f707265666572656e6365737365745f73657373696f6e735f7065725f6572617365745f626f6e64696e675f6475726174696f6e7365745f76616c696461746f725f636f756e74666f7263655f6e65775f6572617365745f6f66666c696e655f736c6173685f67726163652053657420746865206f66666c696e6520736c61736820677261636520706572696f642e20466f72636520746865726520746f2062652061206e6577206572612e205468697320616c736f20666f726365732061206e65772073657373696f6e20696d6d6564696174656c792061667465722e20606170706c795f72657761726473602073686f756c64206265207472756520666f722076616c696461746f727320746f20676574207468652073657373696f6e207265776172642e2054686520696465616c206e756d626572206f662076616c696461746f72732e20546865206c656e677468206f662074686520626f6e64696e67206475726174696f6e20696e20657261732e2053657420746865206e756d626572206f662073657373696f6e7320696e20616e206572612e205365742074686520676976656e206163636f756e74277320707265666572656e636520666f7220736c617368696e67206265686176696f75722073686f756c64207468657920626520612076616c696461746f722e20416e206572726f7220286e6f2d6f7029206966206053656c663a3a696e74656e74696f6e7328295b696e74656e74696f6e735f696e6465785d20213d206f726967696e602e696e74656e74696f6e735f696e646578707265667356616c696461746f7250726566733c543a3a42616c616e63653e2057696c6c2070616e69632069662063616c6c6564207768656e20736f757263652069736e27742063757272656e746c79206e6f6d696e6174696e67207461726765742e2055706461746573204e6f6d696e6174696e672c204e6f6d696e61746f7273466f7220616e64204e6f6d696e6174696f6e42616c616e63652e7461726765745f696e6465787461726765742052657472616374207468652064657369726520746f207374616b6520666f7220746865207472616e736163746f722e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e204465636c617265207468652064657369726520746f207374616b6520666f7220746865207472616e736163746f722e50726f706f73616c426f6e645065726d696c6c50726f706f73616c426f6e644d696e696d756d5370656e64506572696f644275726e506f7450726f706f73616c436f756e7450726f706f73616c496e64657850726f706f73616c203c2054203a3a204163636f756e744964202c2054203a3a2042616c616e6365203e417070726f76616c73566563203c2050726f706f73616c496e646578203e2050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e20546f74616c2066756e647320617661696c61626c6520746f2074686973206d6f64756c6520666f72207370656e64696e672e2050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e2050726f706f7274696f6e206f662066756e647320746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c61636520612070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f65736e27742e70726f706f73655f7370656e647365745f706f74636f6e66696775726572656a6563745f70726f706f73616c617070726f76655f70726f706f73616c20417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e2052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e70726f706f73616c5f6964436f6d706163743c50726f706f73616c496e6465783e202852652d29636f6e6669677572652074686973206d6f64756c652e70726f706f73616c5f626f6e6470726f706f73616c5f626f6e645f6d696e696d756d7370656e645f706572696f646275726e20536574207468652062616c616e6365206f662066756e647320617661696c61626c6520746f207370656e642e6e65775f706f742050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e62656e656669636961727954726561737572792050726f706f73616c734b657975706772616465543a3a4163636f756e74496400617474656d707420746f20646976696465206279207a65726f55706772616465644b65794368616e67656420416e2075706772616465206a7573742068617070656e65643b206f6c64206b657920697320737570706c69656420617320616e20617267756d656e742e20416e2075706772616465206a7573742068617070656e65642e5265776172644f66666c696e655761726e696e67204f6e652076616c696461746f722028616e64207468656972206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e204f6e652076616c696461746f722028616e64207468656972206e6f6d696e61746f72732920686173206265656e20676976656e2061206f66666c696e652d7761726e696e67202874686579277265207374696c6c2077697468696e207468656972206772616365292e205468652061636372756564206e756d626572206f6620736c6173686573206973207265636f726465642c20746f6f2e20416c6c2076616c696461746f72732068617665206265656e2072657761726465642062792074686520676976656e2062616c616e63652e50726f706f7365645370656e64696e67417761726465644275726e74526f6c6c6f766572205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e204e65772070726f706f73616c2e2f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f7374616b696e672f7372632f6c69622e72732f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f74726561737572792f7372632f6c69622e72732f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f757067726164652d6b65792f7372632f6c69622e72735374616b696e672043757272656e7453657373696f6e5265776172645374616b696e67205374616b6552616e67655374616b696e67204c6173744572614c656e6774684368616e67655374616b696e672053657373696f6e735065724572615374616b696e672043757272656e744572615374616b696e67204e65787453657373696f6e735065724572615374616b696e672056616c696461746f72436f756e745374616b696e67204f66666c696e65536c6173685374616b696e672053657373696f6e52657761726443616e6e6f74207374616b6520696620616c7265616479207374616b65642e43616e6e6f74207374616b6520696620616c7265616479206e6f6d696e6174696e672e43616e6e6f74206e6f6d696e61746520696620616c7265616479206e6f6d696e6174696e672e43616e6e6f74206e6f6d696e61746520696620616c7265616479207374616b65642e5374616b696e67204e6f6d696e6174696e674163636f756e74206d757374206265206e6f6d696e6174696e67496e76616c69642074617267657420696e64657863616e6e6f7420756e7374616b65207768656e2074686572652061726520746f6f20666577207374616b6564207061727469636970616e747354726561737572792050726f706f73616c426f6e644d696e696d756d54726561737572792050726f706f73616c426f6e6454726561737572792050726f706f73616c436f756e7450726f706f73657227732062616c616e636520746f6f206c6f774e6f2070726f706f73616c206174207468617420696e646578557067726164654b6579204b65796f6e6c79207468652063757272656e742075706772616465206b65792063616e207573652074686520757067726164655f6b6579206d6f64756c6553657373696f6e204c6173744c656e6774684368616e676553657373696f6e2053657373696f6e4c656e67746853657373696f6e20466f7263696e674e657753657373696f6e53657373696f6e2043757272656e74537461727453657373696f6e2043757272656e74496e64657853657373696f6e204e65787453657373696f6e4c656e67746853657373696f6e2056616c696461746f727353657373696f6e204e6578744b6579466f7200000000617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f6f70732f61726974682e727356616c696461746f727353657373696f6e4c656e67746843757272656e74496e64657843757272656e745374617274466f7263696e674e657753657373696f6e4c6173744c656e6774684368616e67654e6578744b6579466f7254203a3a2053657373696f6e4b65794e65787453657373696f6e4c656e67746820546865206e6578742073657373696f6e206c656e6774682e20546865206e657874206b657920666f72206120676976656e2076616c696461746f722e20426c6f636b206174207768696368207468652073657373696f6e206c656e677468206c617374206368616e6765642e204e65772073657373696f6e206973206265696e6720666f72636564206973207468697320656e747279206578697374733b20696e20776869636820636173652c2074686520626f6f6c65616e2076616c7565206973207768657468657220746865206e65772073657373696f6e2073686f756c6420626520636f6e736964657265642061206e6f726d616c20726f746174696f6e202872657761726461626c6529206f7220657863657074696f6e616c2028736c61736861626c65292e2054696d657374616d70207768656e2063757272656e742073657373696f6e20737461727465642e2043757272656e7420696e646578206f66207468652073657373696f6e2e2043757272656e74206c656e677468206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e7365745f6b65797365745f6c656e677468666f7263655f6e65775f73657373696f6e20466f726365732061206e65772073657373696f6e2e6170706c795f72657761726473205365742061206e65772073657373696f6e206c656e6774682e20576f6e2774206b69636b20696e20756e74696c20746865206e6578742073657373696f6e206368616e6765202861742063757272656e74206c656e677468292e2053657473207468652073657373696f6e206b6579206f6620605f76616c696461746f726020746f20605f6b6579602e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e6b6579543a3a53657373696f6e4b657900000000000000000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f736c6963652f736f72742e7273617373657274696f6e206661696c65643a206d6964203c3d206c656e00000000000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f736c6963652f6d6f642e72734e657753657373696f6e204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e426c6f636b4e756d6265722f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f73657373696f6e2f7372632f6c69622e72737372632f6c69622e727342616420696e70757420646174612070726f766964656420746f20657865637574655f626c6f636b696e697469616c6973655f626c6f636b6170706c795f65787472696e736963696e686572656e745f65787472696e73696373636865636b5f696e686572656e747376616c69646174655f7472616e73616374696f6e6772616e6470615f70656e64696e675f6368616e67652f686f6d652f6261737469616e2f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d636f6465632d322e312e352f7372632f636f6465632e72732f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f636f6e74726163742f7372632f766d2f72756e74696d652e72736761736578745f7365745f73746f726167656578745f6765745f73746f726167656578745f6372656174656578745f72657475726e6578745f63616c6c65726578745f696e7075745f73697a656578745f696e7075745f636f70796578745f736372617463685f73697a656578745f736372617463685f636f7079707265636f6e646974696f6e3a20616c6c20696d706f7274732073686f756c6420626520636865636b656420616761696e737420746865207369676e617475726573206f6620636f72726573706f6e64696e670a09090909090966756e6374696f6e7320646566696e65642062792060646566696e655f656e762160206d6163726f206279207468652075736572206f6620746865206d6163726f3b0a0909090909097369676e617475726573206f662074686573652066756e6374696f6e7320646566696e6564206279206024706172616d73603b0a09090909090963616c6c7320616c77617973206d616465207769746820617267756d656e7473207479706573206f662077686963682061726520646566696e65642062792074686520636f72726573706f6e64696e6720696d706f7274733b0a09090909090974687573207479706573206f6620617267756d656e74732073686f756c6420626520657175616c20746f2074797065206c69737420696e206024706172616d736020616e640a0909090909096c656e677468206f6620617267756d656e74206c69737420616e642024706172616d732073686f756c6420626520657175616c3b0a0909090909097468757320746869732063616e206e6576657220626520604e6f6e65603b0a0909090909097165643b0a09090909090944656d6f637261637920426f6e6461676563616e6e6f74207472616e7366657220696c6c69717569642066756e647344656d6f6372616379204c61756e6368506572696f6444656d6f6372616379205075626c696350726f707344656d6f6372616379204465706f7369744f6644656d6f637261637920566f74696e67506572696f6444656d6f6372616379205075626c696344656c617944656d6f6372616379204e65787454616c6c7944656d6f6372616379205265666572656e64756d436f756e7444656d6f6372616379204469737061746368517565756544656d6f6372616379205265666572656e64756d496e666f4f6644656d6f637261637920566f74657273466f7244656d6f637261637920566f74654f660000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f6f70732f61726974682e727343616e6e6f7420696e6a6563742061207265666572656e64756d207468617420656e6473206561726c696572207468616e2070726563656564696e67207265666572656e64756d002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f736c6963652f6d6f642e72730000000000000000617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f5075626c696350726f70436f756e7450726f70496e6465785075626c696350726f7073566563203c20282050726f70496e646578202c2054203a3a2050726f706f73616c202c2054203a3a204163636f756e7449642029203e4465706f7369744f66282054203a3a2042616c616e6365202c20566563203c2054203a3a204163636f756e744964203e20294c61756e6368506572696f644d696e696d756d4465706f7369745075626c696344656c61794d61784c6f636b506572696f64734c6f636b506572696f64735265666572656e64756d436f756e745265666572656e64756d496e6465784e65787454616c6c795265666572656e64756d496e666f4f6628205265666572656e64756d496e666f203c2054203a3a20426c6f636b4e756d626572202c2054203a3a2050726f706f73616c203e202944697370617463685175657565566563203c204f7074696f6e203c20282054203a3a2050726f706f73616c202c205265666572656e64756d496e6465782029203e203e426f6e64616765566f74657273466f72566f74654f6628205265666572656e64756d496e646578202c2054203a3a204163636f756e7449642029566f7465204765742074686520766f746520696e206120676976656e207265666572656e64756d206f66206120706172746963756c617220766f7465722e2054686520726573756c74206973206d65616e696e6766756c206f6e6c792069662060766f746572735f666f726020696e636c756465732074686520766f746572207768656e2063616c6c6564207769746820746865207265666572656e64756d2028796f75276c6c20676574207468652064656661756c742060566f7465602076616c7565206f7468657277697365292e20496620796f7520646f6e27742077616e7420746f20636865636b2060766f746572735f666f72602c207468656e20796f752063616e20616c736f20636865636b20666f722073696d706c65206578697374656e636520776974682060566f74654f663a3a657869737473602066697273742e204765742074686520766f7465727320666f72207468652063757272656e742070726f706f73616c2e2054686520626c6f636b20617420776869636820746865206077686f6027732066756e6473206265636f6d65206c69717569642e205175657565206f66207375636365737366756c207265666572656e646120746f20626520646973706174636865642e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e20546865206e657874207265666572656e64756d20696e64657820746861742073686f756c642062652074616c6c6965642e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e64756d73207374617274656420736f206661722e20546865206d6178696d756d206e756d626572206f66206164646974696f6e616c206c6f636b20706572696f6473206120766f746572206d6179206f6666657220746f20737472656e677468656e20746865697220766f74652e204d756c7469706c6573206f6620605075626c696344656c6179602e205468652064656c6179206265666f726520656e6163746d656e7420666f7220616c6c207075626c6963207265666572656e64612e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e7365636f6e6473746172745f7265666572656e64756d63616e63656c5f7265666572656e64756d63616e63656c5f7175657565642043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e7768656e543a3a426c6f636b4e756d62657277686963682052656d6f76652061207265666572656e64756d2e7265665f696e646578436f6d706163743c5265666572656e64756d496e6465783e2053746172742061207265666572656e64756d2e7468726573686f6c64566f74655468726573686f6c6464656c617920566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e436f6d706163743c50726f70496e6465783e2050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e5461626c6564537461727465645061737365644e6f7450617373656443616e63656c6c656445786563757465642f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f64656d6f63726163792f7372632f6c69622e727344656d6f6372616379204d696e696d756d4465706f73697476616c756520746f6f206c6f7744656d6f6372616379205075626c696350726f70436f756e7470726f706f73657227732062616c616e636520746f6f206c6f7763616e206f6e6c79207365636f6e6420616e206578697374696e672070726f706f73616c7365636f6e64657227732062616c616e636520746f6f206c6f7744656d6f6372616379204d61784c6f636b506572696f6473766f74652068617320746f6f206772656174206120737472656e677468766f746520676976656e20666f7220696e76616c6964207265666572656e64756d2e7472616e736163746f72206d75737420686176652062616c616e636520746f207369676e616c20617070726f76616c2e746f6f206d616e7920696e737472756374696f6e733a6772616e6470613a617574683a4772616e64706146696e616c6974792050656e64696e674368616e67654772616e64706146696e616c69747950656e64696e674368616e676553746f72656450656e64696e674368616e6765203c2054203a3a20426c6f636b4e756d626572202c2054203a3a2053657373696f6e4b6579203e4e6577417574686f726974696573204e657720617574686f726974792073657420686173206265656e206170706c6965642e5665633c2853657373696f6e4b65792c20753634293e2f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f6772616e6470612f7372632f6c69622e72736e616d65616c7265616479206d757461626c7920626f72726f776564616c726561647920626f72726f776564636f6e3a73746f3a4469676573744974656d206e6f7420657175616c6e6f7420616c6c6f77656420746f206661696c20696e2072756e74696d656e6f64657375627374726174652d6e6f646500df6acb689907609b0100000037e397fc7c91f5e40100000040fe3ad401f8959a01000000d2bc9897eed08f1501000000ed99c5acb25eedf501000000dd718d5cc53262d4010000004576656e7474696d657374616d70636f6e73656e73757362616c616e63657353657373696f6e73657373696f6e5374616b696e677374616b696e6744656d6f637261637964656d6f6372616379636f756e63696c636f756e63696c5f766f74696e67436f756e63696c4d6f74696f6e73636f756e63696c5f6d6f74696f6e734772616e6470616772616e64706154726561737572797472656173757279436f6e7472616374636f6e7472616374557067726164654b6579757067726164655f6b657973797374656d617572614e6f2076616c69642074696d657374616d7020696e20626c6f636b2e4f6e20656e74727920746f207468652066756e6374696f6e20606d6f64756c65602063616e2774206265204e6f6e653b207165644f6e20656e74727920746f207468652066756e6374696f6e20606d6f64756c65602063616e277420626520604e6f6e65603b2071656454696d657374616d702044696455706461746554696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b2f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f74696d657374616d702f7372632f6c69622e7273436f756e63696c566f74696e672050726f706f73616c73436f756e63696c566f74696e672050726f706f73616c4f66436f756e63696c566f74696e67205665746f656450726f706f73616c436f756e63696c566f74696e6720456e61637444656c6179506572696f6454696d657374616d7020426c6f636b506572696f6454696d657374616d704e6f7754203a3a204d6f6d656e74426c6f636b506572696f64446964557064617465626f6f6c20446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f20546865206d696e696d756d2028616e6420616476697365642920706572696f64206265747765656e20626c6f636b732e2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e54696d657374616d70204e6f7773657420536574207468652063757272656e742074696d652e2045787472696e736963207769746820746869732063616c6c2073686f756c6420626520706c616365642061742074686520737065636966696320706f736974696f6e20696e20746865206561636820626c6f636b2028737065636966696564206279207468652054726169743a3a54494d455354414d505f5345545f504f534954494f4e29207479706963616c6c7920617420746865207374617274206f6620746865206561636820626c6f636b2e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e74207370656369666965642062792060626c6f636b5f706572696f64602e6e6f773c543a3a4d6f6d656e7420617320486173436f6d706163743e3a3a54797065436f756e63696c566f74696e67436f6f6c6f6666506572696f64456e61637444656c6179506572696f6450726f706f73616c73566563203c20282054203a3a20426c6f636b4e756d626572202c2054203a3a20486173682029203e50726f706f73616c4f6654203a3a2050726f706f73616c50726f706f73616c566f74657273436f756e63696c566f74654f66282054203a3a2048617368202c2054203a3a204163636f756e74496420295665746f656450726f706f73616c282054203a3a20426c6f636b4e756d626572202c20566563203c2054203a3a204163636f756e744964203e2029204e756d626572206f6620626c6f636b7320627920776869636820746f2064656c617920656e6163746d656e74206f66207375636365737366756c2c206e6f6e2d756e616e696d6f75732d636f756e63696c2d696e7374696761746564207265666572656e64756d2070726f706f73616c732e70726f706f7365766f74657665746f7365745f636f6f6c6f66665f706572696f647365745f766f74696e675f706572696f64626c6f636b7370726f706f73616c5f68617368543a3a4861736870726f706f73616c617070726f7665426f783c543a3a50726f706f73616c3e7372632f6c6962636f72652f736c6963652f6d6f642e727354616c6c7943616e63656c6174696f6e54616c6c795265666572656e64756d204120766f74696e672074616c6c79206861732068617070656e656420666f722061207265666572656e64756d20766f74652e204c61737420746872656520617265207965732c206e6f2c206162737461696e20636f756e74732e204120766f74696e672074616c6c79206861732068617070656e656420666f722061207265666572656e64756d2063616e63656c6c6174696f6e20766f74652e48617368436f756e63696c566f74696e6720436f756e63696c566f74654f662f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f636f756e63696c2f7372632f766f74696e672e727354696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c426c6f636b506572696f643e206265747765656e2073657175656e7469616c20626c6f636b7354696d657374616d702065787472696e736963206d75737420626520617420706f736974696f6e2054696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b4e6f2076616c69642074696d657374616d7020696e686572656e7420696e20626c6f636b54696d657374616d7020746f6f2066617220696e2066757475726520746f20616363657074436f756e63696c566f74696e6720566f74696e67506572696f6470726f706f73657220776f756c64206e6f74206265206f6e20636f756e63696c6475706c69636174652070726f706f73616c73206e6f7420616c6c6f77656470726f706f73616c206973207665746f6564436f756e63696c566f74696e672050726f706f73616c566f746572736f6e6c7920636f756e63696c6c6f7273206d617920766f7465206f6e20636f756e63696c2070726f706f73616c736f6e6c7920636f756e63696c6c6f7273206d6179207665746f20636f756e63696c2070726f706f73616c7370726f706f73616c206d75737420657869737420746f206265207665746f6564436f756e63696c566f74696e6720436f6f6c6f6666506572696f646120636f756e63696c6c6f72206d6179206e6f74207665746f20612070726f706f73616c207477696365000001000000000000002000000000000000030000000000000003000000000000000300000001000000010000002000000000000000030000000000000003000000000000000300000001000000020000002000000000000000030000000000000003000000000000000300000053746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e2f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f6578656375746976652f7372632f6c69622e7273446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a204e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e436f6e73656e737573204f726967696e616c417574686f7269746965736c656e3a617574683a416c6c2065787472696e736963732073686f756c642062652070726f7065726c79207369676e6564416c6c2065787472696e736963732073686f756c6420686176652073656e6465722061626c6520746f207061792074686569722066656573416c6c2065787472696e736963732073686f756c6420686176652074686520636f7272656374206e6f6e6365626164207369676e617475726520696e2065787472696e7369635472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642e506172656e7420686173682073686f756c642062652076616c69642e72656163686564206d6178696d756d2064657074682c2063616e6e6f74206d616b6520612063616c6c6e6f7420656e6f7567682067617320746f2070617920626173652063616c6c20666565766d20657865637574652072657475726e6564206572726f72207768696c652063616c6c656e766d656d6f727963616c6c6e6f7420656e6f7567682067617320746f20706179207472616e736665722066656572656163686564206d6178696d756d2064657074682c2063616e6e6f74206372656174656e6f7420656e6f7567682067617320746f2070617920626173652063726561746520666565636f6e747261637420616c726561647920657869737473766d20657865637574652072657475726e6564206572726f72207768696c652063726561746541757261204c61737454696d657374616d70000000617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f000000000000002f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f617572612f7372632f6c69622e7273000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f736c6963652f6d6f642e72734f6e6c79206f6e6520626c6f636b206d617920626520617574686f7265642070657220736c6f742e2f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f617572612f7372632f6c69622e72734175726120736c6f74206475726174696f6e2063616e6e6f74206265207a65726f2e74696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c00617474656d707420746f20646976696465206279207a65726f436f6e73656e7375734f726967696e616c417574686f726974696573566563203c2054203a3a2053657373696f6e4b6579203e7265706f72745f6d69736265686176696f726e6f74655f6f66666c696e6572656d61726b7365745f686561705f70616765737365745f636f64657365745f73746f726167652053657420736f6d65206974656d73206f662073746f726167652e6974656d735665633c4b657956616c75653e2053657420746865206e657720636f64652e6e65775665633c75383e2053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e7061676573753634204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b204e6f7465207468652070726576696f757320626c6f636b27732076616c696461746f72206d6973736564207468656972206f70706f7274756e69747920746f2070726f706f7365206120626c6f636b2e6f66666c696e653c543a3a496e686572656e744f66666c696e655265706f727420617320496e686572656e744f66666c696e655265706f72743e3a3a496e686572656e74205265706f727420736f6d65206d69736265686176696f75722e5f7265706f72743a636f646573657269616c697a656420617267732073686f756c642062652070726f7669646564206279207468652072756e74696d653b0a090909636f72726563746c792073657269616c697a656420646174612073686f756c6420626520646573657269616c697a61626c653b0a0909097165642f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f636f72652f73722d73616e64626f782f7372632f2e2e2f776974686f75745f7374642e72732f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f636f6e73656e7375732f7372632f6c69622e7273010000000100000000000000200000000000000003000000000000000300000000000000030000003a6865617070616765736e6f74655f6f66666c696e652065787472696e736963206d75737420626520617420706f736974696f6e2020696e2074686520626c6f636b52657475726e207479706573206c656e6774682073686f756c642062652030206f72203173746f72616765206973206e6f74206e756c6c2c207468657265666f7265206d75737420626520612076616c696420747970650000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f736c6963652f6d6f642e727300000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962616c6c6f632f736c6963652e7273436f756e63696c20566f74696e67506572696f64436f756e63696c20446573697265645365617473436f756e63696c20416374697665436f756e63696c436f756e63696c204e65787446696e616c697365436f756e63696c205465726d4475726174696f6e436f756e63696c2050726573656e746174696f6e4475726174696f6e436f756e63696c20566f74657273436f756e63696c20536e617073686f7465645374616b6573436f756e63696c204361727279436f756e74436f756e63696c204c6561646572626f617264436f756e63696c205265676973746572496e666f4f66436f756e63696c2043616e64696461746573436f756e63696c2043616e646964617465436f756e74436f756e63696c20566f7465436f756e74436f756e63696c2043616e646964616379426f6e6466696e616c6973652063616e206f6e6c792062652063616c6c656420616674657220612074616c6c7920697320737461727465642e47757275206d656469746174696f6e000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f736c6963652f6d6f642e72730000000000000000617474656d707420746f20646976696465206279207a65726f000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f6f70732f61726974682e72730000000000000000617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f436f756e63696c43616e646964616379426f6e64566f74696e67426f6e6450726573656e74536c617368506572566f7465724361727279436f756e7450726573656e746174696f6e4475726174696f6e496e6163746976654772616365506572696f64566f7465496e646578566f74696e67506572696f645465726d4475726174696f6e446573697265645365617473416374697665436f756e63696c566563203c20282054203a3a204163636f756e744964202c2054203a3a20426c6f636b4e756d6265722029203e566f7465436f756e74417070726f76616c734f66566563203c20626f6f6c203e5265676973746572496e666f4f662820566f7465496e646578202c2075333220294c6173744163746976654f66566f7465727343616e6469646174657343616e646964617465436f756e744e65787446696e616c697365282054203a3a20426c6f636b4e756d626572202c20753332202c20566563203c2054203a3a204163636f756e744964203e2029536e617073686f7465645374616b6573566563203c2054203a3a2042616c616e6365203e4c6561646572626f617264566563203c20282054203a3a2042616c616e6365202c2054203a3a204163636f756e7449642029203e2047657420746865206c6561646572626f6172642069662077653b726520696e207468652070726573656e746174696f6e2070686173652e20546865207374616b6573206173207468657920776572652061742074686520706f696e7420746861742074686520766f746520656e6465642e20546865206163636f756e747320686f6c64696e672074686520736561747320746861742077696c6c206265636f6d652066726565206f6e20746865206e6578742074616c6c792e205468652070726573656e742063616e646964617465206c6973742e205468652070726573656e7420766f746572206c6973742e2054686520766f746520696e64657820616e64206c69737420736c6f742074686174207468652063616e646964617465206077686f60207761732072656769737465726564206f7220604e6f6e6560206966207468657920617265206e6f742063757272656e746c7920726567697374657265642e20546865206c61737420636c656172656420766f746520696e6465782074686174207468697320766f74657220776173206c617374206163746976652061742e2054686520746f74616c206e756d626572206f6620766f746573207468617420686176652068617070656e6564206f722061726520696e2070726f67726573732e205468652063757272656e7420636f756e63696c2e205768656e2074686572652773206120766f746520676f696e67206f6e2c20746869732073686f756c64207374696c6c206265207573656420666f7220657865637574697665206d6174746572732e204e756d626572206f66206163636f756e747320746861742073686f756c642062652073697474696e67206f6e2074686520636f756e63696c2e20486f77206c6f6e67206561636820706f736974696f6e2069732061637469766520666f722e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206d616e7920766f746573206e65656420746f20676f206279206166746572206120766f7465722773206c61737420766f7465206265666f726520746865792063616e2062652072656170656420696620746865697220617070726f76616c7320617265206d6f6f742e20486f77206c6f6e6720746f2067697665206561636820746f702063616e64696461746520746f2070726573656e74207468656d73656c7665732061667465722074686520766f746520656e64732e20486f77206d616e792072756e6e6572732d75702073686f756c64206861766520746865697220617070726f76616c73207065727369737420756e74696c20746865206e65787420766f74652e205468652070756e6973686d656e742c2070657220766f7465722c20696620796f752070726f7669646520616e20696e76616c69642070726573656e746174696f6e2e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f2062652061626c6520746f207375626d697420766f7465732e20486f77206d7563682073686f756c64206265206c6f636b656420757020696e206f7264657220746f207375626d6974206f6e6527732063616e6469646163792e7365745f617070726f76616c73726561705f696e6163746976655f766f746572726574726163745f766f7465727375626d69745f63616e64696461637970726573656e745f77696e6e65727365745f646573697265645f736561747372656d6f76655f6d656d6265727365745f70726573656e746174696f6e5f6475726174696f6e7365745f7465726d5f6475726174696f6e20536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e74206120766f7465206265696e672070726573656e74656420666f722c2077696c6c20696e766f6b65206066696e616c6973655f766f7465602e20536574207468652070726573656e746174696f6e206475726174696f6e2e2049662074686572652069732063757272656e746c79206120766f7465206265696e672070726573656e74656420666f722c2077696c6c636f756e743c543a3a426c6f636b4e756d62657220617320486173436f6d706163743e3a3a547970652052656d6f7665206120706172746963756c6172206d656d6265722e20412074616c6c792077696c6c2068617070656e20696e7374616e746c7920286966206e6f7420616c726561647920696e20612070726573656e746174696f6e20706572696f642920746f2066696c6c2074686520736561742069662072656d6f76616c206d65616e732074686174207468652064657369726564206d656d6265727320617265206e6f74206d65742e20546869732069732065666665637469766520696d6d6564696174656c792e416464726573733c543a3a4163636f756e7449642c20543a3a4163636f756e74496e6465783e20536574207468652064657369726564206d656d62657220636f756e743b206966206c6f776572207468616e207468652063757272656e7420636f756e742c207468656e2073656174732077696c6c206e6f7420626520757020656c656374696f6e207768656e2074686579206578706972652e204966206d6f72652c207468656e2061206e657720766f74652077696c6c2062652073746172746564206966206f6e65206973206e6f7420616c726561647920696e2070726f67726573732e436f6d706163743c7533323e20436c61696d207468617420607369676e656460206973206f6e65206f662074686520746f702053656c663a3a63617272795f636f756e742829202b2063757272656e745f766f746528292e312063616e646964617465732e204f6e6c7920776f726b73206966207468652060626c6f636b5f6e756d626572203e3d2063757272656e745f766f746528292e306020616e6420603c2063757272656e745f766f746528292e30202b2070726573656e746174696f6e5f6475726174696f6e2829606020607369676e6564602073686f756c642068617665206174206c6561737463616e646964617465746f74616c696e646578436f6d706163743c566f7465496e6465783e205375626d6974206f6e6573656c6620666f722063616e6469646163792e204163636f756e74206d757374206861766520656e6f756768207472616e736665727261626c652066756e647320696e20697420746f207061792074686520626f6e642e736c6f742052656d6f7665206120766f7465722e20416c6c20766f746573206172652063616e63656c6c656420616e642074686520766f746572206465706f7369742069732072657475726e65642e2052656d6f7665206120766f7465722e20466f72206974206e6f7420746f206265206120626f6e642d636f6e73756d696e67206e6f2d6f702c20616c6c20617070726f7665642063616e64696461746520696e6469636573206d757374206e6f772062652065697468657220756e72656769737465726564206f72207265676973746572656420746f20612063616e646964617465207468617420726567697374657265642074686520736c6f742061667465722074686520766f7465722067617665207468656972206c61737420617070726f76616c207365742e204d61792062652063616c6c656420627920616e796f6e652e2052657475726e732074686520766f746572206465706f73697420746f20607369676e6564602e7265706f727465725f696e64657877686f5f696e646578617373756d65645f766f74655f696e646578205365742063616e64696461746520617070726f76616c732e20417070726f76616c20736c6f747320737461792076616c6964206173206c6f6e672061732063616e6469646174657320696e2074686f736520736c6f74732061726520726567697374657265642e766f7465735665633c626f6f6c3e566f746572526561706564426164526561706572536c617368656454616c6c795374617274656454616c6c7946696e616c6973656420412074616c6c792028666f7220617070726f76616c20766f746573206f6620636f756e63696c2073656174287329292068617320656e646564202877697468206f6e65206f72206d6f7265206e6577206d656d62657273292e5665633c4163636f756e7449643e20412074616c6c792028666f7220617070726f76616c20766f746573206f6620636f756e63696c2073656174287329292068617320737461727465642e20736c6173686564207265617065722072656170656420766f7465722c207265617065722f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f636f756e63696c2f7372632f73656174732e72736e6f20617070726f76616c206368616e67657320647572696e672070726573656e746174696f6e20706572696f64696e636f727265637420766f746520696e646578436f756e63696c204c6173744163746976654f66436f756e63696c20566f74696e67426f6e64436f756e63696c20417070726f76616c734f6663616e6e6f74207265617020647572696e672070726573656e746174696f6e20706572696f647265706f72746572206d757374206265206120766f746572766f746520696e646578206e6f742063757272656e7463616e6e6f74207265617020647572696e6720677261636520706572696474617267657420666f7220696e616374697669747920636c65616e7570206d75737420626520616374697665436f756e63696c20496e6163746976654772616365506572696f646261642074617267657420696e646578626164207265706f7274657220696e64657863616e6e6f742072657472616374207768656e2070726573656e74696e6763616e6e6f742072657472616374206e6f6e2d766f74657272657472616374696f6e20696e64657820696e76616c696472657472616374696f6e20696e646578206d69736d617463686475706c69636174652063616e646964617465207375626d697373696f6e696e76616c69642063616e64696461746520736c6f7463616e64696461746520686173206e6f7420656e6f7567682066756e6473696e646578206e6f742063757272656e7463616e6e6f742070726573656e74206f757473696465206f662070726573656e746174696f6e20706572696f6470726573656e746572206d75737420686176652073756666696369656e7420736c61736861626c652066756e64736c6561646572626f617264206d757374206578697374207768696c652070726573656e742070686173652061637469766563616e646964617465206d757374206e6f7420666f726d2061206475706c696361746564206d656d62657220696620656c656374656463616e646964617465206e6f7420776f72746879206f66206c6561646572626f61726470726573656e7465642063616e646964617465206d7573742062652063757272656e74436f756e63696c2050726573656e74536c617368506572566f7465726475706c69636174652070726573656e746174696f6e696e636f727265637420746f74616c626164206f726967696e3a20657870656374656420746f206265206120726f6f74206f726967696e626164206f726967696e3a20657870656374656420746f2062652061207369676e6564206f726967696e626164206f726967696e3a20657870656374656420746f20626520616e20696e686572656e74206f726967696e42616c616e636573204672656542616c616e636500000000000042616c616e636573205472616e73616374696f6e4261736546656542616c616e636573205472616e73616374696f6e4279746546656542616c616e636573204578697374656e7469616c4465706f73697442616c616e63657320546f74616c49737375616e63656e6f7420656e6f7567682066756e647320666f72207472616e73616374696f6e2066656542616c616e63657320526573657276656442616c616e636553797374656d204163636f756e744e6f6e63653a65787472696e7369635f696e64657853797374656d204576656e747353797374656d20426c6f636b48617368000000000053797374656d204e756d62657253797374656d20506172656e744861736853797374656d2045787472696e73696373526f6f7453797374656d2052616e646f6d53656564426c6f636b206e756d626572206d6179206e65766572206265207a65726f2f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f73797374656d2f7372632f6c69622e727353797374656d2044696765737453797374656d2045787472696e7369634461746153797374656d4163636f756e744e6f6e636554203a3a204163636f756e74496454203a3a20496e64657845787472696e736963436f756e74753332426c6f636b4861736854203a3a20426c6f636b4e756d62657254203a3a204861736845787472696e73696344617461566563203c207538203e52616e646f6d536565644e756d626572506172656e744861736845787472696e73696373526f6f7444696765737454203a3a204469676573744576656e7473566563203c204576656e745265636f7264203c2054203a3a204576656e74203e203e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e53797374656d2045787472696e736963436f756e744d6f64756c6543616c6c42616c616e636573204372656174696f6e46656542616c616e636573205472616e7366657246656542616c616e636573546f74616c49737375616e636554203a3a2042616c616e63654578697374656e7469616c4465706f7369745265636c61696d5265626174655472616e736665724665654372656174696f6e4665654e657874456e756d53657454203a3a204163636f756e74496e646578456e756d536574566563203c2054203a3a204163636f756e744964203e4672656542616c616e6365526573657276656442616c616e63655472616e73616374696f6e426173654665655472616e73616374696f6e42797465466565205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b2074686520626173652e2054686520616d6f756e74206f66207468652062616c616e6365206f66206120676976656e206163636f756e7420746861742069732065787465726e616c6c792072657365727665643b20746869732063616e207374696c6c2067657420736c61736865642c20627574206765747320736c6173686564206c617374206f6620616c6c2e20546869732062616c616e63652069732061202772657365727665272062616c616e63652074686174206f746865722073756273797374656d732075736520696e206f7264657220746f2073657420617369646520746f6b656e73207468617420617265207374696c6c20276f776e65642720627920746865206163636f756e7420686f6c6465722c20627574207768696368206172652073757370656e6461626c652e20285468697320697320646966666572656e7420616e642077686f6c6c7920756e72656c6174656420746f207468652060426f6e64616765602073797374656d207573656420696e20746865207374616b696e67206d6f64756c652e29205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e2074686973202772657365727665206163636f756e74272069732064656c657465643a207370656369666963616c6c792c2060526573657276656442616c616e6365602e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c6574656420696620604672656542616c616e63656020697320616c736f207a65726f2028697420616c736f206765747320636f6c6c617073656420746f207a65726f2069662069742065766572206265636f6d6573206c657373207468616e20604578697374656e7469616c4465706f736974602e20546865202766726565272062616c616e6365206f66206120676976656e206163636f756e742e205468697320697320746865206f6e6c792062616c616e63652074686174206d61747465727320696e207465726d73206f66206d6f7374206f7065726174696f6e73206f6e20746f6b656e732e20497420697320616c6f6e65207573656420746f2064657465726d696e65207468652062616c616e6365207768656e20696e2074686520636f6e747261637420657865637574696f6e20656e7669726f6e6d656e742e205768656e20746869732062616c616e63652066616c6c732062656c6f77207468652076616c7565206f6620604578697374656e7469616c4465706f736974602c207468656e20746865202763757272656e74206163636f756e74272069732064656c657465643a207370656369666963616c6c7920604672656542616c616e6365602e20467572746865726d6f72652c20604f6e4672656542616c616e63655a65726f602063616c6c6261636b20697320696e766f6b65642c20676976696e672061206368616e636520746f2065787465726e616c206d6f64756c657320746f20636c65616e75702064617461206173736f6369617465642077697468207468652064656c65746564206163636f756e742e206073797374656d3a3a4163636f756e744e6f6e63656020697320616c736f2064656c657465642069662060526573657276656442616c616e63656020697320616c736f207a65726f2028697420616c736f20676574732054686520656e756d65726174696f6e20736574732e20546865206e657874206672656520656e756d65726174696f6e207365742e205468652066656520726571756972656420746f2063726561746520616e206163636f756e742e204174206c6561737420617320626967206173205265636c61696d5265626174652e205468652066656520726571756972656420746f206d616b652061207472616e736665722e2054686520616d6f756e7420637265646974656420746f20612064657374696e6174696f6e2773206163636f756e742077686f736520696e64657820776173207265636c61696d65642e20546865206d696e696d756d20616d6f756e7420616c6c6f77656420746f206b65657020616e206163636f756e74206f70656e2e2054686520746f74616c20616d6f756e74206f66207374616b65206f6e207468652073797374656d2e62656e6566696369617279206163636f756e74206d757374207072652d657869737442616c616e636573204e657874456e756d53657442616c616e636573205265636c61696d52656261746542616c616e63657320456e756d536574000000000000000000617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f000000000000002f72757374632f313439393764353661353530663461613939666537333735393363643237353832323761666335362f7372632f6c6962636f72652f6f70732f61726974682e72730000000000000000617474656d707420746f20646976696465206279207a65726f696e76616c6964206163636f756e7420696e6465786e6f7420656e6f75676820667265652066756e64737472616e736665727365745f62616c616e636520536574207468652062616c616e636573206f66206120676976656e206163636f756e742e77686f526177416464726573733c543a3a4163636f756e7449642c20543a3a4163636f756e74496e6465783e667265653c543a3a42616c616e636520617320486173436f6d706163743e3a3a547970657265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572207374616b65722e6465737476616c75650000000100000000000000200000000000000003000000000000000300000000000000030000000100000001000000200000000000000003000000000000000300000000000000030000007372632f6c6962636f72652f726573756c742e72733a20696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64652f686f6d652f6261737469616e2f70726f6a656374732f7061726974792f7375627374726174652f73726d6c2f62616c616e6365732f7372632f6c69622e72734e65774163636f756e745265617065644163636f756e745472616e73666572205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c75652c2066656573292e4163636f756e74496442616c616e636520416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e4163636f756e74496e6465784e65774163636f756e744f7574636f6d65676f74206f766572666c6f7720616674657220616464696e6720612066656520746f2076616c756562616c616e636520746f6f206c6f7720746f2073656e642076616c756576616c756520746f6f206c6f7720746f20637265617465206163636f756e7464657374696e6174696f6e2062616c616e636520746f6f206869676820746f20726563656976652076616c75655f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e0041b08dc2000ba0a30100001000430000005e0a0000250000000000100043000000640a00002c000000e3841000280000004e6110004d0000008700000009000000e3841000280000004e6110004d00000090000000090000003001100067000000220100001700000005011000250000006302100012000000750210000f000000360210000a0000004002100014000000540210000f000000900210005a0000008800000016000000fd0210001c000000ea021000130000005f04000009000000190310001e000000ea021000130000005603000009000000100410006e000000c800000011000000f0041000480000009f0900000a000000ed05100012000000ff0510000c0000002f0610000b000000000000005806100010000000000000000878100000000000000000000000000010881000010000000000000000000000680610000f00000000000000087810000000000000000000000000001888100001000000000000008c061000250000007706100015000000c006100019000000e00610004d00000052000000220000004f07100011000000ea17100017000000f502000005000000a00710004600000081010000130000001d00000004000000040000001e0000001f00000020000000e608100020000000060910001200000021000000000000000100000022000000e009100006000000e60910002200000049561000180000002d09000005000000080a1000160000001e0a10000d000000495610001800000033090000050000008e0b10000b00000092171000160000002b0a100001000000780b1000160000002c08000009000000701710000e0000007e1710000400000082171000100000002b0a100001000000780b1000160000003008000005000000301710002b0000005b1710001500000063010000150000008e0b10000b000000990b100026000000bf0b100008000000c70b1000060000002b0a100001000000780b1000160000003d080000050000000878100000000000e60b100002000000d00b1000160000005604000011000000d00b1000160000004a04000028000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000f8030000000000000000000000000000000000000000000000000000000000000000feffffffffbfb6000000000000000000ff070000000000f8ffff0000010000000000000000000000c09f9f3d0000000002000000ffffff0700000000000000000000c0ff01000000000000f80f20100c10004a000000600e100000020000601010003700000000010203040506070809080a0b0c0d0e0f10111213140215161718191a1b1c1d1e1f2002020202020202020202210202020202020202020202020202222324252602270228020202292a2b022c2d2e2f300202310202023202020202020202023302023402020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023502360237020202020202020238023902020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202023a3b3c020202023d02023e3f4041424344454602020247020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202024802020202020202020202024902020202023b0200010202020203020202020402050602020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202070202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202f00b1000200000003100000019000000f00b1000200000003200000020000000f00b1000200000003400000019000000f00b1000200000003500000018000000f00b100020000000360000002000000008781000000000005b17100015000000f003000005000000c617100024000000ea171000170000004b02000009000000000000009f5c1000040000000000000088901000040000000000000000000000e890100002000000000000000000000000000000771810000600000000000000f89010000400000000000000000000005891100009000000000000000100000000000000788410000400000000000000b33210000c000000000000007c84100005000000000000001b8410002000000000000000571a10000900000000000000601a10001c00000000000000851a10000400000000000000b35f100007000000891a10004a000000891a10004a000000000000004e1a100009000000000000001b8410002000000000000000571a10000900000000000000601a10001c000000000000007c1a10000900000000000000b35f10000700000000000000851a10000400000000000000b35f1000070000007d181000530000000878100000000000d0181000210000000878100000000000f118100050000000411910002e0000006f1910005b000000ca19100057000000211a10002d00000000000000af541000090000000000000000000000e41a100011000000000000000000000000000000000000009092100001000000000000000100000000000000e05410000a0000000100000000000000057a10000900000000000000f51a10001a0000000000000098921000010000000000000000000000000000000f1b1000060000000100000000000000057a10000900000000000000151b10004900000000000000a092100001000000000000000000000000000000e12d10000d0000000000000000000000e97910000300000000000000000000000000000000000000a8921000010000000000000001000000ec1b100026000000b91b100033000000701b1000490000005e1b10001200000000000000de5510000700000000000000109310000200000000000000000000000878100000000000000000000000000000000000e55510000400000000000000409310000300000000000000000000000878100000000000000000000100000000000000664b100009000000000000004a6f10000c000000000000002a5610000800000000000000121c10001b000000000000002a56100008000000000000002356100007000000000000004470100005000000000000004731100016000000000000003256100007000000000000001a5210000400000000000000628510000800000000000000e0931000030000000000000000000000f89310000100000000000000000000002d1c1000070000000000000088cf1000020000000000000000000000009410000100000000000000968510000900000096851000090000009f851000070000006b1c10005d000000341c100037000000e384100028000000c81c100040000000930000000100000000000000743410000800000000000000fc9410000400000000000000000000001c951000010000000000000000000000081d10000500000000000000249510000500000000000000000000004c9510000200000000000000000000000d1d100008000000000000005c95100001000000000000000000000064951000010000000000000000000000151d10000b000000000000005c9510000100000000000000000000006c9510000100000000000000000000005c4c10000800000000000000749510000200000000000000000000008495100001000000000000009685100009000000ee2d10000d0000001b57100004000000e979100003000000461e10005900000096851000090000001b571000040000001a52100004000000e979100003000000e979100003000000c71d100042000000091e10003d0000001b57100004000000961d100031000000611d1000350000001b571000040000001a52100004000000201d100041000000e3841000280000009f1e10004300000044000000010000002d1f100036000000603f10005d000000fb00000005000000f01e10003d000000603f10005d00000002010000050000002d1f100036000000603f10005d0000001001000005000000603f10005d00000017010000050000008686100023000000c81c10004000000093000000010000002100000000000000010000002300000024000000250000002600000086861000230000009f1e1000430000004400000001000000b020100048000000a50900000e0000008021100039000000c0211000480000001a0200002d00000000000000082210000e0000000000000000000000e979100003000000000000000000000000000000000000005c9b10000100000000000000010000000000000016221000150000000000000000000000e97910000300000000000000000000000000000000000000649b1000010000000000000001000000000000002b2210000e0000000000000000000000f579100010000000000000000000000000000000000000006c9b100001000000000000000100000000000000392210000d0000000000000000000000462210000700000000000000000000000000000000000000749b1000010000000000000001000000000000004d2210000c00000000000000000000004622100007000000000000000000000000000000000000007c9b10000100000000000000010000000000000059221000110000000000000000000000e97910000300000000000000000000000000000000000000849b1000010000000000000001000000000000006a2210000f0000000000000000000000f579100010000000000000000000000000000000000000008c9b100001000000000000000100000000000000792210000a0000000000000000000000f57910001000000000000000000000000000000000000000949b10000100000000000000010000000000000083221000140000000100000000000000c37910000e00000000000000972210001f000000000000009c9b100001000000000000000100000000000000b62210000a0000000000000000000000887b10001600000000000000000000000000000000000000a49b100001000000000000000100000000000000c02210000a0000000100000000000000c37910000e00000000000000c37910000e00000000000000ac9b100001000000000000000000000000000000ca2210000d0000000100000000000000c37910000e00000000000000887b10001600000000000000b49b100001000000000000000100000000000000d7221000140000000100000000000000c37910000e00000000000000887b10001600000000000000bc9b100001000000000000000100000000000000eb221000140000000000000000000000247b10000c00000000000000000000000000000000000000749b100001000000000000000100000000000000ff221000130000000000000000000000247b10000c000000000000000000000000000000000000007c9b10000100000000000000010000000000000012231000120000000000000000000000f57910001000000000000000000000000000000000000000c49b10000100000000000000000000000000000024231000130000000000000000000000f57910001000000000000000000000000000000000000000cc9b100001000000000000000100000000000000372310000a0000000000000000000000412310001700000000000000000000000000000000000000d49b10000100000000000000010000000000000043461000070000000100000000000000c37910000e00000000000000f57910001000000000000000dc9b100001000000000000000100000000000000582310000a0000000100000000000000c37910000e00000000000000e97910000300000000000000e49b100001000000000000000100000000000000622310000d00000000000000000000006f2310000400000000000000000000000000000000000000ec9b1000010000000000000000000000572710002a0000000727100050000000de2610002900000096261000480000004226100054000000f42510004e000000c62510002e000000af251000170000008d2510002200000064251000290000003c251000280000001725100025000000d624100041000000b2241000240000007a241000380000003e2410003c000000012410003d0000008d23100074000000732310001a00000000000000f9291000050000000000000008781000000000000000000000000000d49d100003000000000000000000000000000000fe2910000700000000000000ec9d1000010000000000000000000000049e100003000000000000000100000000000000052a100008000000000000001c9e100001000000000000000000000008781000000000000000000002000000000000000d2a10000a00000000000000349e10000100000000000000000000004c9e100002000000000000000300000000000000172a100014000000000000005c9e10000200000000000000000000008c9e1000030000000000000004000000000000002b2a10001400000000000000c0a91000010000000000000000000000a49e1000010000000000000005000000000000003f2a10001400000000000000c0a91000010000000000000000000000ac9e100001000000000000000600000000000000532a10001300000000000000b49e1000010000000000000000000000cc9e100001000000000000000700000000000000662a10000d00000000000000e0a91000010000000000000000000000d49e100002000000000000000800000000000000732a10001700000000000000b49e1000010000000000000000000000e49e1000010000000000000009000000792d1000300000000878100000000000422d10003700000000000000542c100010000000000000004a6f10000c000000122d1000300000000878100000000000422d100037000000000000000c2d10000600000000000000646e10002600000000000000002d10000c000000000000004a6f10000c000000832c100044000000c72c10003900000000000000542c100010000000000000004a6f10000c00000000000000642c10000500000000000000692c10001a000000b82b10005600000008781000000000000e2c100046000000922b100026000000662b10002c00000000000000b05f100003000000000000004a6f10000c000000462b100020000000ae2a10004f000000fd2a1000490000008a2a10002400000000000000a92d10000c0000000000000000000000b52d10000700000000000000000000000000000000000000cca0100002000000000000000100000000000000bc2d1000130000000000000000000000247b10000c00000000000000000000000000000000000000dca0100001000000000000000100000000000000cf2d10000b0000000000000000000000f57910001000000000000000000000000000000000000000e4a0100001000000000000000100000000000000da2d1000040000000000000000000000b52d10000700000000000000000000000000000000000000eca0100001000000000000000100000000000000de2d1000030000000000000000000000247b10000c00000000000000000000000000000000000000f4a0100001000000000000000100000000000000e12d10000d0000000000000000000000ee2d10000d00000000000000000000000000000000000000fca0100001000000000000000100000000000000af541000090000000100000000000000ee2d10000d00000000000000fb2d10002a0000000000000004a1100001000000000000000000000000000000252e10000900000000000000000000002e2e100015000000000000000000000000000000000000000ca11000010000000000000001000000b42f1000540000000830100037000000622f100052000000402f100022000000fc2e100044000000c92e100033000000a02e100029000000812e10001f000000432e10003e000000000000003f3010000d0000000000000004a2100002000000000000000000000034a21000030000000000000000000000000000004c30100007000000000000004ca2100001000000000000000000000064a21000010000000000000001000000000000005330100009000000000000006ca21000040000000000000000000000cca21000010000000000000002000000000000005c3010000f00000000000000d4a21000010000000000000000000000eca21000010000000000000003000000000000006b3010001000000000000000d4a21000010000000000000000000000f4a21000020000000000000004000000000000007c84100005000000000000001b84100020000000000000008c3210000b00000000000000646e100026000000df3110004b0000002a3210004d000000773210001500000000000000d831100007000000000000001b84100020000000ab3110002d00000000000000793110000d00000000000000b52d100007000000000000008631100015000000000000001b84100020000000000000009b3110000c00000000000000756d10002400000000000000a73110000400000000000000b52d1000070000005d3110001c000000000000003c3110000b000000000000004731100016000000fd3010003f0000007b30100057000000d23010002b00000000000000a9321000030000000000000000000000c37910000e000000000000000000000000000000000000000878100000000000000000000100000000000000ac321000070000000000000098c410000100000000000000000000000878100000000000000000000000000000000000213c10000700000000000000a0a310000100000000000000000000000878100000000000000000000100000000000000b05f10000300000000000000b33210000c000000c032100019000000c021100048000000c50100002d00000000000000d932100008000000000000000878100000000000000000000000000028a41000010000000000000000000000e13210000a0000000000000000d8100001000000000000000000000030a410000100000000000000293310001a000000eb3210003e00000000000000433310000600000000000000bca41000010000000000000000000000c4a41000010000000000000000000000493310000e00000000000000cca41000020000000000000000000000dca410000200000000000000000000004d2210000c00000000000000eca41000020000000000000000000000fca4100001000000000000009f851000070000003c341000380000009685100009000000e979100003000000a233100055000000f73310004500000096851000090000009f85100007000000573310004b00000000000000743410000800000000000000e0a51000010000000000000000000000e8a510000100000000000000000000007c3410000800000000000000bca41000010000000000000000000000f0a51000010000000000000000000000843410000700000000000000f8a5100003000000000000000000000010a610000100000000000000000000008b3410000500000000000000bca4100001000000000000000000000018a61000010000000000000000000000903410000800000000000000bca4100001000000000000000000000020a610000100000000000000ee2d10000d000000613510000e000000273510003a000000ee2d10000d0000009f8510000700000096851000090000000735100020000000e434100023000000983410004c000000e3841000280000006f3510003f0000006500000001000000e384100028000000ae351000400000004400000001000000e384100028000000ee351000430000002e0000000100000080291000480000009f0900000a00000086861000230000006f3510003f00000065000000010000008686100023000000ae3510004000000044000000010000008686100023000000ee351000430000002e000000010000007039100039000000b0391000480000001a0200002d00000000000000f83910000a0000000000000000000000887b10001600000000000000000000000000000000000000c0a8100001000000000000000100000000000000023a10000d0000000000000000000000f57910001000000000000000000000000000000000000000c8a81000010000000000000001000000000000000f3a10000c0000000000000000000000f57910001000000000000000000000000000000000000000d0a81000010000000000000001000000000000001b3a10000c0000000000000000000000fb5110000b00000000000000000000000000000000000000d8a8100001000000000000000100000000000000273a10001100000000000000000000001a5210000400000000000000000000000000000000000000e0a8100002000000000000000000000000000000383a1000100000000000000000000000f57910001000000000000000000000000000000000000000f0a8100001000000000000000000000000000000483a10000a0000000100000000000000c37910000e00000000000000523a10000f00000000000000f8a8100001000000000000000000000000000000613a1000110000000000000000000000f5791000100000000000000000000000000000000000000000a91000010000000000000000000000023c10001f000000e33b10001f000000c53b10001e0000009d3b100028000000df3a10005e0000003d3b100060000000af3a1000300000008b3a100024000000723a10001900000000000000213c1000070000000000000098a91000010000000000000000000000b0a9100002000000000000000000000000000000283c10000a00000000000000c0a91000010000000000000000000000d8a9100001000000000000000100000000000000323c10001100000000000000e0a91000010000000000000000000000f8a9100001000000000000000200000000000000223d10000300000000000000253d10000d000000c13c100058000000193d10000900000000000000b05f10000300000000000000756d100024000000663c10005b00000000000000593c10000d000000000000001a52100004000000433c100016000000b03d100048000000bb01000023000000b03d100048000000bc01000023000000893d10001c0000004956100018000000ee0300000d000000403d100049000000910200001d000000403d100049000000a70000003a000000403d100049000000ae0000003000000000000000f83d10000a0000000000000094aa10000100000000000000000000009caa10000200000000000000793e10000b000000023e100055000000573e100022000000e384100028000000843e10003f0000005a000000010000008686100023000000843e10003f0000005a00000001000000e83e10000d000000cd3e10001b000000c33e10000a0000000301000001000000f53e100010000000053f10000f000000143f100013000000273f10000f000000363f1000140000004a3f100016000000e384100028000000bd3f1000470000005a000000080000009044100039000000b0431000480000001a0200002d0000004044100048000000a50900000e0000009043100019000000b043100048000000c50100002d00000000000000c94410000f0000000000000000000000d8441000090000000000000000000000000000000000000008af100001000000000000000100000000000000e14410000b0000000000000000000000ec441000360000000000000000000000000000000000000010af10000100000000000000010000000000000022451000090000000100000000000000d844100009000000000000002b451000290000000000000018af100001000000000000000000000000000000544510000c0000000000000000000000f5791000100000000000000000000000000000000000000020af100001000000000000000100000000000000604510000e0000000000000000000000247b10000c0000000000000000000000000000000000000028af1000010000000000000001000000000000006e4510000b0000000000000000000000f5791000100000000000000000000000000000000000000030af100001000000000000000100000000000000794510000e0000000000000000000000874510000b0000000000000000000000000000000000000038af100001000000000000000100000000000000156610000c0000000000000000000000f57910001000000000000000000000000000000000000000a8ca100001000000000000000100000000000000924510000f0000000000000000000000a14510000f0000000000000000000000000000000000000040af100001000000000000000100000000000000b0451000090000000000000000000000a14510000f0000000000000000000000000000000000000048af100001000000000000000100000000000000b9451000100000000100000000000000a14510000f00000000000000c9451000370000000000000050af100001000000000000000000000000000000004610000d0000000100000000000000f579100010000000000000000d461000360000000000000058af10000100000000000000010000000000000043461000070000000100000000000000c37910000e00000000000000f5791000100000000000000060af1000010000000000000001000000000000004a461000090000000100000000000000a14510000f00000000000000887b1000160000000000000068af100001000000000000000100000000000000534610000600000001000000000000005946100024000000000000007d461000040000000000000070af10000300000000000000010000006c4a10003d0000004c4a1000200000002b4a100021000000f249100039000000a54910004d0000007049100035000000fa48100076000000ac4810004e0000007a481000320000004d4810002d0000001d48100030000000e947100034000000c0471000290000008146100075000000f646100072000000684710005800000000000000de5510000700000000000000a8b01000020000000000000000000000d8b0100001000000000000000000000000000000a94a10000600000000000000e0b01000010000000000000000000000d8b0100001000000000000000100000000000000e55510000400000000000000f8b0100002000000000000000000000028b1100002000000000000000200000000000000af4a1000100000000000000038b1100003000000000000000000000080b1100001000000000000000300000000000000bf4a1000110000000000000088b11000010000000000000000000000a0b1100001000000000000000400000000000000d04a10000d00000000000000a8b11000020000000000000000000000d8b11000010000000000000005000000000000002a56100008000000000000003956100010000000000000007c84100005000000000000001b841000200000000f4c100028000000000000002a5610000800000000000000fd4b10001200000000000000314b100009000000000000003a4b10001800000000000000e555100004000000000000007d46100004000000814b10004d000000ce4b10002f000000000000002a5610000800000000000000395610001000000000000000664b100009000000000000006f4b10000d000000000000007c4b10000500000000000000094b10000e000000524b10001400000000000000314b100009000000000000003a4b1000180000001c4b10001500000000000000054b10000400000000000000094b10000e00000000000000174b10000500000000000000e979100003000000dd4a10002800000000000000374c10000600000000000000e8b21000030000000000000000000000087810000000000000000000000000003d4c1000070000000000000000b3100002000000000000000000000008781000000000000000000000000000444c1000060000000000000010b31000010000000000000000000000087810000000000000000000000000004a4c1000090000000000000010b3100001000000000000000000000008781000000000000000000000000000534c1000090000000000000010b31000010000000000000000000000087810000000000000000000000000005c4c1000080000000000000018b31000020000000000000000000000087810000000000000000000d8441000090000009f85100007000000567310000e000000a14510000f0000006f4b10000d000000a14510000f000000a14510000f0000001a52100004000000e384100028000000644c10004100000058000000010000008686100023000000644c100041000000580000000100000000000000114e10000d00000000000000000000001e4e10003a0000000000000000000000000000000000000008781000000000000000000000000000000000002c5f1000120000000000000018c4100001000000000000000000000030c4100001000000000000000000000000000000584e10000e00000000000000f0b31000010000000000000000000000f8b3100001000000000000008a4e100016000000664e100024000000e384100028000000a04e10003f000000b1000000010000008686100023000000a04e10003f000000b100000001000000625010000600000027000000b74f10000800000028000000c64f10000700000029000000d44f1000070000002a000000e44f1000090000002b000000ed4f1000070000002c000000f44f10000e0000002d000000105010000f0000002e00000026501000070000002f000000355010000800000030000000455010000800000031000000575010000b00000032000000000000006250100006000000000000003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000068501000040000000000000033000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000a54f1000090000000000000035000000000000000000000000000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000ae4f1000090000000000000037000000000000000000000000000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000b74f1000080000000000000039000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000c64f100007000000000000003b000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000d44f100007000000000000003d000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000e44f100009000000000000003f000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000ed4f1000070000000000000041000000000000000000000000000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000f44f10000e0000000000000043000000000000000000000000000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000105010000f00000000000000450000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000002650100007000000000000004700000000000000000000000000000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000000000035501000080000000000000049000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a000000000000000000000000000000000000000000000000000000000000004550100008000000000000004b000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000575010000b000000000000004c000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d00000000000000000000000000000000000000000000000000000000000000ef5110000900000000000000a54f1000090000000000000000000000f95e10000900000000000000ae4f10000900000001000000000000000f7b10000800000000000000b74f1000080000000200000000000000bf4f10000700000000000000c64f1000070000000300000000000000cd4f10000700000000000000d44f1000070000000400000000000000db4f10000900000000000000e44f1000090000000500000000000000a96510000700000000000000ed4f1000070000000600000000000000855410000d00000000000000f44f10000e0000000700000000000000025010000e00000000000000105010000f00000008000000000000001f5010000700000000000000265010000700000009000000000000002d501000080000000000000035501000080000000a000000000000003d501000080000000000000045501000080000000b000000000000004d5010000a00000000000000575010000b0000000c000000055110002b0000003051100041000000760000000400000000000000f8511000030000000000000000000000fb5110000b0000000000000000000000000000000000000020bc100001000000000000000100000000000000065210000b0000000000000000000000fb5110000b0000000000000000000000000000000000000028bc100001000000000000000100000000000000115210000900000000000000000000001a521000040000000000000000000000000000000000000030bc10000100000000000000010000007c521000240000004b521000310000001e5210002d00000000000000ad521000030000000000000068bc100001000000000000000000000080bc100008000000000000000000000000000000635410000300000000000000665410001f000000b0521000160000000878100000000000c6521000550000001b5310005b000000765310005d000000d35310002f0000000878100000000000025410006100000000000000925410000d0000000000000000000000f579100010000000000000000000000000000000000000000878100000000000000000000100000000000000156610000c0000000000000000000000f5791000100000000000000000000000000000000000000008781000000000000000000001000000000000009f541000100000000000000000000000f57910001000000000000000000000000000000000000000a0be100001000000000000000100000000000000af541000090000000000000000000000b854100028000000000000000000000000000000000000000878100000000000000000000100000000000000e05410000a0000000100000000000000057a10000900000000000000ea5410000d000000000000000878100000000000000000000000000000000000f75410000e0000000100000000000000057a10000900000000000000887b100016000000000000000878100000000000000000000100000000000000055510000d0000000100000000000000125510001e000000000000001a52100004000000000000000878100000000000000000000000000000000000305510000e0000000100000000000000057a100009000000000000003e5510002d00000000000000087810000000000000000000000000006b5510007300000000000000de551000070000000000000098bf10000100000000000000000000000878100000000000000000000000000000000000e55510000400000000000000b0bf10000200000000000000000000000878100000000000000000000100000000000000e95510000400000000000000e0bf10000100000000000000000000000878100000000000000000000200000000000000ed5510001200000000000000f8bf10000100000000000000000000000878100000000000000000000300000000000000ff5510001100000000000000f8bf100001000000000000000000000008781000000000000000000004000000000000002a56100008000000000000003956100010000000000000002a56100008000000000000002356100007000000000000003256100007000000000000001a5210000400000000000000165610000d00000000000000235610000700000000000000105610000600000000000000756d1000240000000000000061561000100000000000000068c0100004000000000000000000000088c01000020000000000000000000000715610000f0000000000000068c0100004000000000000000000000098c0100002000000000000001b57100004000000e979100003000000e979100003000000e979100003000000db56100040000000b3561000280000008056100033000000b356100028000000e38410002800000030511000410000005700000001000000e3841000280000003a571000420000002200000001000000868610002300000030511000410000005700000001000000f05710003000000030511000410000006500000004000000c857100028000000396210000d000000305110004100000066000000040000007c5710004c00000030511000410000006b0000000400000086861000230000003a5710004200000022000000010000000a5c10001c000000445a1000410000006400000003000000e65b100024000000445a1000410000006c00000003000000a05b10002c000000445a100041000000a60000004c000000685b100038000000445a100041000000a40000002a000000405b100028000000445a100041000000a500000032000000e85a100032000000ac5a10002d000000d95a10000c000000e55a100003000000445a100041000000cc00000003000000855a100027000000445a100041000000d4000000040000001c5a100028000000445a100041000000da000000030000004e00000018000000040000004f0000005000000051000000520000008c5e100022000000505e10003c0000009e00000003000000285e100028000000505e10003c000000a400000003000000e05d1000480000009f0900000a000000605d100039000000a05d10003c0000006500000014000000e05e100019000000a05d10003c0000008d0000001e00000000000000025f1000130000000000000000000000155f1000170000000000000000000000000000000000000008781000000000000000000000000000000000002c5f1000120000000000000018c4100001000000000000000000000030c41000010000000000000000000000000000003e5f10000c0000000000000038c4100001000000000000000000000050c41000010000000000000001000000000000004a5f1000060000000000000058c4100001000000000000000000000070c4100001000000000000000200000000000000505f10000e0000000000000078c4100001000000000000000000000090c41000010000000000000003000000000000005e5f1000080000000000000098c41000010000000000000000000000b0c4100001000000000000000400000000000000665f10000b00000000000000b8c41000010000000000000000000000d0c4100001000000000000000500000000000000d26010000700000000000000b35f100007000000b86010001a000000000000007460100007000000000000007b6010003d0000002360100051000000000000001c6010000700000000000000b35f100007000000016010001b00000000000000f95f10000500000000000000fe5f100003000000ba5f10003f00000000000000b05f10000300000000000000b35f1000070000009e5f100012000000000000008c5f10000500000000000000915f10000d000000715f10001b000000e3841000280000004e6110004d0000003701000009000000e3841000280000009b61100041000000c20000000100000086861000230000009b61100041000000c2000000010000000e6210002b000000396210000d0000009b61100041000000ce00000004000000a0621000480000009f0900000a000000f062100045000000cb0200001e000000f062100045000000ce02000036000000706510003900000020651000480000001a0200002d000000b0641000480000009f0900000a00000000651000190000002065100048000000c50100002d000000b064100048000000a50900000e00000000000000b06510000d0000000000000000000000247b10000c0000000000000000000000000000000000000070ca100001000000000000000100000000000000bd6510000a0000000000000000000000247b10000c0000000000000000000000000000000000000078ca100001000000000000000100000000000000c7651000140000000000000000000000247b10000c0000000000000000000000000000000000000080ca100001000000000000000100000000000000db6510000a0000000000000000000000e9791000030000000000000000000000000000000000000088ca100001000000000000000100000000000000e5651000140000000000000000000000f5791000100000000000000000000000000000000000000090ca100001000000000000000100000000000000f96510001300000000000000000000000c661000090000000000000000000000000000000000000098ca100002000000000000000100000000000000156610000c0000000000000000000000f57910001000000000000000000000000000000000000000a8ca100001000000000000000100000000000000216610000c0000000000000000000000f57910001000000000000000000000000000000000000000b0ca1000010000000000000001000000000000002d6610000c0000000000000000000000e97910000300000000000000000000000000000000000000b8ca100001000000000000000100000000000000396610000d0000000000000000000000466610002d00000000000000000000000000000000000000c0ca100002000000000000000100000000000000736610000900000000000000000000000c6610000900000000000000000000000000000000000000d0ca1000010000000000000001000000000000007c6610000b0000000100000000000000c37910000e00000000000000876610000c00000000000000d8ca100001000000000000000100000000000000936610000e0000000100000000000000c37910000e00000000000000a16610001300000000000000e0ca100002000000000000000000000000000000b46610000c0000000100000000000000c37910000e000000000000000c6610000900000000000000d8ca100001000000000000000000000000000000c0661000060000000000000000000000887b10001600000000000000000000000000000000000000f0ca100001000000000000000100000000000000c66610000a0000000000000000000000887b10001600000000000000000000000000000000000000f8ca100001000000000000000100000000000000d06610000e0000000000000000000000e979100003000000000000000000000000000000000000000878100000000000000000000100000000000000de6610000c0000000000000000000000ea661000330000000000000000000000000000000000000000cb1000010000000000000000000000000000001d6710001000000000000000000000002d671000140000000000000000000000000000000000000008cb100001000000000000000100000000000000416710000b00000000000000000000004c671000290000000000000000000000000000000000000010cb1000010000000000000000000000da6b100041000000986b100042000000556b100043000000086b10004d000000b96a10004f0000004b6a10005a000000a56a1000140000001d6a10002e000000f769100026000000bd6910003a000000596910005b000000b4691000090000001869100041000000d868100040000000636810005f000000c2681000160000004b681000180000002f6810001c000000e767100048000000ad6710003a0000007567100038000000000000001b6c10000d00000000000000c8cc1000020000000000000000000000f8cc100002000000000000000000000000000000286c1000130000000000000008cd100004000000000000000000000068cd1000050000000000000001000000000000003b6c10000d0000000000000090cd1000010000000000000000000000a8cd100001000000000000000200000000000000486c10001000000000000000b0cd1000010000000000000000000000c8cd100003000000000000000300000000000000586c10000e00000000000000e0cd100003000000000000000000000028ce100003000000000000000400000000000000666c1000110000000000000040ce100001000000000000000000000058ce100003000000000000000500000000000000776c10000d0000000000000070ce100001000000000000000000000088ce100003000000000000000600000000000000846c10001900000000000000a0ce1000010000000000000000000000b8ce1000020000000000000007000000000000009d6c10001100000000000000a0ce1000010000000000000000000000c8ce100002000000000000000800000000000000b97210000500000000000000be721000090000000000000044701000050000000000000049701000120000005172100058000000a97210001000000000000000287210000e000000000000004a6f10000c00000000000000eb8310000300000000000000646e100026000000000000003672100009000000000000004a6f10000c000000000000003f721000120000000000000049701000120000000c71100058000000647110005c000000c0711000280000000878100000000000e871100040000000000000004470100005000000000000004a6f10000c000000c17010004b00000000000000bd70100004000000000000004a6f10000c0000005b7010001e0000000878100000000000797010004400000000000000367010000900000000000000646e100026000000000000003f70100005000000000000001b84100020000000000000004470100005000000000000004970100012000000566f100059000000af6f100069000000187010001e00000000000000706d100005000000000000004a6f10000c0000008a6e100059000000e36e10005a0000003d6f10000d00000000000000eb8310000300000000000000646e100026000000996d10005c000000f56d100050000000456e10001f00000000000000706d10000500000000000000756d1000240000001a6d100056000000026d100018000000ae6c100054000000026d10001800000000000000c77210000b0000000000000088cf100002000000000000000000000098cf1000010000000000000000000000d2721000100000000000000000d81000010000000000000000000000a0cf1000010000000000000000000000e27210000c00000000000000a8cf1000010000000000000000000000b0cf1000010000000000000000000000ee7210000e00000000000000b8cf1000020000000000000000000000c8cf1000010000000000000096851000090000009685100009000000b073100015000000a17310000f000000e979100003000000647310003d000000567310000e000000567310000e000000fc7210005a000000e384100028000000c57310004100000058000000010000008686100023000000c5731000410000005800000001000000347910001e000000527910003e000000370100000300000000000000b77910000c0000000100000000000000c37910000e00000000000000d17910000a000000000000000878100000000000000000000100000000000000db7910000e0000000000000000000000e979100003000000000000000000000000000000000000000878100000000000000000000000000000000000ec791000090000000100000000000000f57910001000000000000000057a1000090000000000000008781000000000000000000001000000000000000e7a10000d0000000100000000000000e979100003000000000000001b7a10000a000000000000000878100000000000000000000100000000000000257a10000a0000000000000000000000057a1000090000000000000000000000000000000000000008781000000000000000000001000000000000002f7a1000060000000000000000000000f5791000100000000000000000000000000000000000000070d2100001000000000000000100000000000000357a10000a0000000000000000000000057a1000090000000000000000000000000000000000000008781000000000000000000001000000000000003f7a10000e0000000000000000000000057a1000090000000000000000000000000000000000000008781000000000000000000001000000000000004d7a1000060000000000000000000000537a10000b0000000000000000000000000000000000000008781000000000000000000001000000000000005e7a1000060000000000000000000000647a1000220000000000000000000000000000000000000008781000000000000000000001000000867a10004200000000000000177b10000d0000000000000000000000247b10000c000000000000000000000000000000000000000cd5100001000000000000000100000000000000307b1000120000000000000000000000247b10000c0000000000000000000000000000000000000014d5100001000000000000000100000000000000427b10000d0000000000000000000000247b10000c000000000000000000000000000000000000001cd51000010000000000000001000000000000004f7b10000b0000000000000000000000247b10000c0000000000000000000000000000000000000024d51000010000000000000001000000000000005a7b10000b0000000000000000000000247b10000c000000000000000000000000000000000000002cd5100001000000000000000100000000000000657b10000b0000000000000000000000707b1000110000000000000000000000000000000000000034d5100001000000000000000100000000000000817b1000070000000100000000000000707b10001100000000000000887b100016000000000000003cd51000010000000000000001000000000000009e7b10000b0000000100000000000000c37910000e00000000000000247b10000c0000000000000044d510000b000000000000000100000000000000a97b10000f0000000100000000000000c37910000e00000000000000247b10000c000000000000009cd510000c000000000000000100000000000000b87b1000120000000000000000000000247b10000c00000000000000000000000000000000000000fcd5100001000000000000000100000000000000ca7b1000120000000000000000000000247b10000c0000000000000000000000000000000000000004d6100001000000000000000100000052821000290000001e82100034000000d48110004a000000af811000250000006681100049000000478110001f0000003181100016000000fd7e1000270000000878100000000000247f100053000000777f10005a000000d17f100055000000268010004f0000007580100050000000c5801000150000000878100000000000da80100057000000b87e100045000000567c10005d000000b37c1000270000000878100000000000da7c10005b000000357d10005c000000917d10004a0000000878100000000000db7d10005d000000387e10002d0000000878100000000000657e100053000000b87e1000450000001f7c100037000000dc7b10004300000070831000190000002083100048000000c50100002d000000e08210003900000020831000480000001a0200002d00000000000000b383100008000000000000009cd61000020000000000000000000000ccd6100001000000000000000000000000000000bb8310000b00000000000000d4d610000300000000000000000000001cd7100001000000000000000100000000000000788410000400000000000000ee83100029000000000000007c84100005000000000000001b84100020000000438410003500000000000000eb8310000300000000000000ee83100029000000000000001784100004000000000000001b84100020000000000000003b84100008000000000000001b84100020000000c6831000250000000878100000000000e184100002000000cc84100015000000f103000005000000e3841000280000000b851000400000008900000001000000000000004b8510000a00000000000000e0d71000030000000000000000000000f8d71000010000000000000000000000558510000d0000000000000000d8100001000000000000000000000008d8100001000000000000000000000062851000080000000000000010d8100004000000000000000000000030d8100001000000000000009685100009000000d88510000c000000e485100011000000bd8510001b0000009685100009000000a685100017000000968510000900000096851000090000009f851000070000009f851000070000006a8510002c00000086861000230000000b8510004000000089000000010000000084e201046e616d6501fbe1018103000a6578745f6d616c6c6f6301086578745f66726565020c6578745f74776f785f313238030f6578745f7365745f73746f7261676504146578745f6765745f73746f726167655f696e746f05236578745f626c616b65325f3235365f656e756d6572617465645f747269655f726f6f74060e6578745f7072696e745f75746638070d6578745f7072696e745f6e756d08116578745f636c6561725f73746f72616765090d6578745f7072696e745f6865780a106578745f73746f726167655f726f6f740b166578745f73616e64626f785f6d656d6f72795f6765740c166578745f73616e64626f785f6d656d6f72795f7365740d0e6578745f626c616b65325f3235360e126578745f6578697374735f73746f726167650f126578745f656432353531395f76657269667910166578745f73616e64626f785f6d656d6f72795f6e6577111b6578745f73616e64626f785f6d656d6f72795f74656172646f776e12176578745f73616e64626f785f696e7374616e746961746513126578745f73616e64626f785f696e766f6b65141d6578745f73616e64626f785f696e7374616e63655f74656172646f776e15106578745f636c6561725f70726566697816186578745f73746f726167655f6368616e6765735f726f6f74176a3c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c20616c6c6f633a3a7665633a3a496e746f497465723c543e3e3e3a3a737065635f657874656e643a3a68306236623466366461346538373665631834616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68336266363834353061623434666161391908727573745f6f6f6d1a3d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68333232646334366162613238303934351b603c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c7533323e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68663764353631653136666139653166371c513c6e6f64655f72756e74696d653a3a43616c6c206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68333266306464303361323264616431321d3d7061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68663331653466613238626138666331611e397061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a68626330623333363063626331633430311f347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a6838313566653232633763303662643265204d3c6e6f64655f72756e74696d653a3a4c6f67206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a683365336666643831633034316465613021347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a686538303962323333366637303837366322347061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573683a3a686561363435613332326264363635656323397061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a683662393231623537643563663264353024397061726974795f636f6465633a3a636f6465633a3a4f75747075743a3a707573685f627974653a3a6862306432656639343134396639366136253a3c616c6c6f633a3a7665633a3a5665633c543e3e3a3a657874656e645f66726f6d5f736c6963653a3a6830323330353563303066343835343636263a3c616c6c6f633a3a7665633a3a5665633c543e3e3a3a657874656e645f66726f6d5f736c6963653a3a6832323737303332306462633063333738272f3c616c6c6f633a3a7665633a3a5665633c543e3e3a3a726573697a653a3a68393831313962643838303862306137312830636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68326362393663383734366439366336362930636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68393330333832623738643031336533392a30636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68366630356264663035333564626666662b443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68343337313931343437326333616538352c4b3c616c6c6f633a3a7261775f7665633a3a5261775665633c542c20413e3e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303066373734353263343130626335312d443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68656332623639623565643637376538352e39636f72653a3a697465723a3a6974657261746f723a3a4974657261746f723a3a636c6f6e65643a3a68303564333339363765643661616339632f443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6866353535383361663936313938643335304b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6830633235656638373134636437386334314b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6835623338303962633463643635623665324b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6864316339616133376634623565326263334b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6864326436396238363534643134643438344e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830353336303362626136386532326439355d3c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c7533323e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6839623836353935616334643136626331364e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830653465623535316339376364376436374e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6833623866346264663934663066393133384e3c6e6f64655f72756e74696d653a3a43616c6c206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830373866616633333065346264303636394e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68343966303734326533666661323764393a5d3c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c7533323e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68613632383439356235353134656533643b4e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68346437643432393932393332366438303c4e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68376136383132626538363435363039313d4e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68376564376339343431633737323433623e4e3c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68666431393930366365666134663066363f543c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c20493e3e3a3a737065635f657874656e643a3a683130663732383666316236313061346140523c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c20493e3e3a3a66726f6d5f697465723a3a683635646439663430383036383430313941523c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c20493e3e3a3a66726f6d5f697465723a3a6836373832316538346664396365336665422e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a683866326530643464626366323339633543523c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c20493e3e3a3a66726f6d5f697465723a3a683764653066333130376433393631366144523c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c20493e3e3a3a66726f6d5f697465723a3a683862386137373466383033333365316445523c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c20493e3e3a3a66726f6d5f697465723a3a686464313165353565613236313832313946523c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c20493e3e3a3a66726f6d5f697465723a3a686534653766613332613464396438313847543c636f72653a3a697465723a3a436861696e3c412c20423e20617320636f72653a3a697465723a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6833353030383335356135613263613835483c707761736d5f7574696c733a3a737461636b5f6865696768743a3a696e6a6563745f6c696d697465723a3a683261643237386561316332623064623849467061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a436f646553656374696f6e3a3a626f646965733a3a68316136653363323564383336373233644a41707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a636f6d707574653a3a68363434643937666330363536356434314b543c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c20493e3e3a3a737065635f657874656e643a3a68653936363766393466336235373162334c323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68613863393464383765633333643361374d25616c6c6f633a3a666d743a3a666f726d61743a3a68333765643964643530643432616162624e36636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a68646337663865393837366163363963384f29636f72653a3a70616e69636b696e673a3a70616e69633a3a683263643034333836326363366463346150383c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c26276120543e3e3a3a636c6f6e65643a3a686331343935643766333563343963363551457061726974795f7761736d3a3a656c656d656e74733a3a7365676d656e743a3a446174615365676d656e743a3a76616c75653a3a6862636335663864373331653538336662523f707761736d5f7574696c733a3a737461636b5f6865696768743a3a7265736f6c76655f66756e635f747970653a3a6864343738623366396237386236383230533c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a66726f6d5f6d6f64756c653a3a6835393865633632333536353431363035546a3c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c20616c6c6f633a3a7665633a3a496e746f497465723c543e3e3e3a3a737065635f657874656e643a3a686361633363666436356638643535623155523c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3e3a3a707573685f66756e6374696f6e3a3a686431366332313437333330613765643656a9017061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c6553636166666f6c643e20666f72207061726974795f7761736d3a3a656c656d656e74733a3a6d6f64756c653a3a4d6f64756c653e3a3a66726f6d3a3a683366303436613061343264323161363957623c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c20563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68663635363339666532633165313536325849636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a686565646333383036343831626262633959463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68333833383262313738653434303735325a37707761736d5f7574696c733a3a6761733a3a696e6a6563745f6761735f636f756e7465723a3a68643262613033653738303061376331655b553c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3e3a3a7265736f6c76655f747970655f7265663a3a68623839356231303738323632376631345c3a707761736d5f7574696c733a3a72756c65733a3a496e737472756374696f6e547970653a3a6f703a3a68343863613134303834333430326664355d2f3c616c6c6f633a3a7665633a3a5665633c543e3e3a3a696e736572743a3a68333539373733353834333136663030315e46707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a6672616d653a3a68326330323632633333303139613332355f4b707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a706f705f76616c7565733a3a6862646437383034646434356133393261604b3c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c20563e3e3a3a696e736572743a3a686537656636316331393830633337666561443c7061726974795f7761736d3a3a696f3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839633664336463383130373636656361622f73726d6c5f73797374656d3a3a4576656e743a3a6d657461646174613a3a683561383362396331656164663132306663423c5b545d206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a686632333334306337393366306235336264463c26276120737472206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683631356438343866656333653937303265603c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c7533323e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683231613463376265306233326466626466633c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c204f3e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683234343236303735393762306331383467633c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c204f3e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a686337343634626366353666356366376468633c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c204f3e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683637636433383538373036353063396469633c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c204f3e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68306331616461616436393462336238636a633c73726d6c5f6d657461646174613a3a4465636f6465446966666572656e743c422c204f3e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68643437396462633833396663333931386b6c3c73725f7072696d6974697665733a3a7472616974733a3a426c616b6554776f3235362061732073725f7072696d6974697665733a3a7472616974733a3a486173683e3a3a656e756d6572617465645f747269655f726f6f743a3a68323465386134343735663630383061366c11727573745f626567696e5f756e77696e646d23636f72653a3a666d743a3a77726974653a3a68323836633239633038353338343136396e2e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a68656239323632633139373462656135616f3e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686239323837373837626265313963613770323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6834316166646162613931333239383738712d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a68633834626633393031633130393564347230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6832346331386664653835663366373632735f3c636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a416461707465723c275f2c20543e20617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a683837316261373134643738393836653174603c636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a416461707465723c275f2c20543e20617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6866396462383536633866663432626231755f3c636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a416461707465723c275f2c20543e20617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68393536396133623130303866626231327634636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68386532623636346463343035623830377735636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a686236326537356361336165303436363378353c5420617320636f72653a3a616e793a3a416e793e3a3a6765745f747970655f69643a3a68613466646438383262613662313861357942636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a7b7b636c6f737572657d7d3a3a68353130346139663834616235313537617a36636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a68353232386663346466303130353434637b49636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207536343e3a3a666d743a3a68613863353265323134646138636561337c2c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a68356339313832616130316666633536647d2e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a68323763313936373563306565323131647e4a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68363464653066663265643266393233627f323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683764616234323839613436626363366580013d636f72653a3a756e69636f64653a3a626f6f6c5f747269653a3a426f6f6c547269653a3a6c6f6f6b75703a3a6862366564333062666338363062313136810149636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a6832656366663232333562343761393362820134636f72653a3a666d743a3a417267756d656e7456313a3a73686f775f7573697a653a3a68356161383436616430316232656133358301453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68656130353130613364653965643665378401483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683437623235613431633630363735383485018001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a6830636661376366316536666563313033860127636f72653a3a7374723a3a66726f6d5f757466383a3a68626562396238633766356234356565378701483c636f72653a3a666d743a3a417267756d656e74733c275f3e20617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68636332343431303363366536356336358801367061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68323739306136636564323436346331348901397061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a68373139393933303635356130376363318a01373c73726d6c5f636f6e74726163743a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a68623935393333373637633964633066628b01453c73726d6c5f636f756e63696c3a3a6d6f74696f6e733a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a68306338303661333233353230323931318c013f3c73726d6c5f636f756e63696c3a3a6d6f74696f6e733a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a68313031366636633137616263343134398d01423c5b545d206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68306233643262313830396162386237668e01433c5b75385d206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68306332373562376365643566323031658f014a3c73726d6c5f636f6e74726163743a3a5261774576656e743c42616c616e63652c204163636f756e7449643e3e3a3a6d657461646174613a3a683966626661383533393633663765653790014f3c73726d6c5f636f756e63696c3a3a6d6f74696f6e733a3a5261774576656e743c486173682c204163636f756e7449643e3e3a3a6d657461646174613a3a68633061653865363666666463626663629101443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68663938313366393061613331306132619201493c73726d6c5f636f6e73656e7375733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68346665313962363661376161336632329301493c73726d6c5f64656d6f63726163793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a683164363364373931666661323633336494014e3c73726d6c5f636f756e63696c3a3a73656174733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686664393363313738366239376330333395014f3c73726d6c5f636f756e63696c3a3a766f74696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686364373231613938653835306238376196015e3c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c753132383e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686137366664636563336333343161333597015d3c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c7536343e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683030613839386163303465323232333298015e3c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c753132383e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683337373131393139396365326136643599015d3c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c7536343e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a68613465306430383765643731326665369a01613c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c753132383e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68633865393931666464643566636664359b01303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68386130313238303039326432393730359c01603c7061726974795f636f6465633a3a636f6465633a3a436f6d706163743c7536343e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68613339336330636531353265623364309d01303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68376439306261303436613632623133619e01363c73726d6c5f636f6e74726163743a3a436f6e6669673c543e3e3a3a7072656c6f61643a3a68393937303235633635323831363538619f0130636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6833376236326364343237633463656636a00135636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68326362393663383734366439366336362e31323431a1015b3c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4e6f64655265663c426f72726f77547970652c204b2c20562c20547970653e3e3a3a6b6579733a3a6831646239333437393336306636333732a201743c73726d6c5f62616c616e6365733a3a616464726573733a3a416464726573733c4163636f756e7449642c204163636f756e74496e6465783e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830646662656136393365323133636539a301743c73726d6c5f62616c616e6365733a3a616464726573733a3a416464726573733c4163636f756e7449642c204163636f756e74496e6465783e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6835333136323465613033306632656537a401773c73726d6c5f62616c616e6365733a3a616464726573733a3a416464726573733c4163636f756e7449642c204163636f756e74496e6465783e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6862303636616463666236313762336636a501b00173725f7072696d6974697665733a3a67656e657269633a3a626c6f636b3a3a5f494d504c5f4445434f44455f464f525f426c6f636b3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f722073725f7072696d6974697665733a3a67656e657269633a3a626c6f636b3a3a426c6f636b3c4865616465722c2045787472696e7369633e3e3a3a6465636f64653a3a6865636438316533663130343539353838a6017c3c73725f7072696d6974697665733a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c20486173682c204469676573744974656d3e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6830343537376133623865326163383738a701a9013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f6d6f7274616c5f65787472696e7369633a3a556e636865636b65644d6f7274616c45787472696e7369633c416464726573732c20496e6465782c2043616c6c2c205369676e61747572653e206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6831356465643265656137326131353662a8013873726d6c5f636f6e74726163743a3a6761733a3a726566756e645f756e757365645f6761733a3a6833373134396362616136616636633162a9013b3c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a667265655f62616c616e63653a3a6838303062636339356161613637333134aa013f3c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a7365745f667265655f62616c616e63653a3a6863626432656439346637613736393331ab012e73726d6c5f636f6e74726163743a3a6761733a3a6275795f6761733a3a6831303232653939303062616365396234ac013c3c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a6831316534333733383239666331353131ad01423c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3e3a3a6f6e5f6f66666c696e655f76616c696461746f723a3a6864356136393932383334313061323636ae01343c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a736c6173683a3a6835653538646433353831643334303361af01443c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3e3a3a63757272656e745f6e6f6d696e61746f72735f666f723a3a6863336334643436336236383133653738b0013c3c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a746f74616c5f62616c616e63653a3a6862336334306462383563333964666336b1016c3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a6765743a3a6830623763613830346636646533386265b2013c3c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3e3a3a6e6f6d696e61746f72735f666f723a3a6866623831353634373839353864313962b3013b3c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3e3a3a6170706c795f756e7374616b653a3a6832633939323665393233386233656566b4013a3c73726d6c5f73797374656d3a3a4d6f64756c653c543e3e3a3a6465706f7369745f6576656e743a3a6862343734646130376166366536366438b5012e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a6861633261623134356234393732323433b601363c73726d6c5f7374616b696e673a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a6839323933393432346562653736313466b7013d3c73726d6c5f74726561737572793a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a6832633266636164393165333939653362b801373c73726d6c5f74726561737572793a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a6834373665353665323830326232346633b901383c73726d6c5f74726561737572793a3a4d6f64756c653c543e3e3a3a70726f706f73616c733a3a6861643362306236666439383333396266ba01303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834393532613038613939323965383633bb01303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865626333366332396363363537323363bc01403c73726d6c5f757067726164655f6b65793a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a6863303135666437323630666161303239bd013a3c73726d6c5f757067726164655f6b65793a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a6866633530626636643739656261396264be01443c73726d6c5f757067726164655f6b65793a3a5261774576656e743c4163636f756e7449643e3e3a3a6d657461646174613a3a6865393766633835366539643338386137bf01493c73726d6c5f7374616b696e673a3a5261774576656e743c42616c616e63652c204163636f756e7449643e3e3a3a6d657461646174613a3a6863613133623565666433366561656463c0014a3c73726d6c5f74726561737572793a3a5261774576656e743c42616c616e63652c204163636f756e7449643e3e3a3a6d657461646174613a3a6830346662333038343338316633353765c101523c28522c2053292061732073726d6c5f73657373696f6e3a3a4f6e53657373696f6e4368616e67653c543e3e3a3a6f6e5f73657373696f6e5f6368616e67653a3a6833653732666563353137306139323734c201353c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a7265776172643a3a6861613962356462353732646235393335c3012d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6833353530623132396438626231303735c4014273726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765745f6f725f64656661756c743a3a6830626565353732343035303538353232c501493c73726d6c5f636f6e73656e7375733a3a4d6f64756c653c543e3e3a3a736176655f6f726967696e616c5f617574686f7269746965733a3a6866636361623530613230356463333762c6013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a7075743a3a6866623635326161363138366430393936c7016c3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a6765743a3a6839646661323065316233393634303236c801b1013c73726d6c5f7374616b696e673a3a4e6f6d696e6174696e673c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c203c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6765743a3a6833623036303232343530383239383134c901493c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c20563e3e3a3a696e736572743a3a6839326464313363636332313132323666ca01633c28582c2059292061732073726d6c5f62616c616e6365733a3a456e737572654163636f756e744c69717569643c4163636f756e7449643e3e3a3a656e737572655f6163636f756e745f6c69717569643a3a6830386635373761376661353238623863cb01723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c20563e20617320636f72653a3a697465723a3a7472616974733a3a496e746f4974657261746f723e3a3a696e746f5f697465723a3a6837343439366133643330373264363931cc01623c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c20563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6837623162656661326536313466666233cd016b3c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c20563e20617320636f72653a3a697465723a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6836313965643733383235376533616633ce01623c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c20563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6833316330393134323734613736313661cf01723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c20563e20617320636f72653a3a697465723a3a7472616974733a3a496e746f4974657261746f723e3a3a696e746f5f697465723a3a6837653539333535313365366665376462d001623c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c20563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6832376663373765616664633733303332d1016b3c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c20563e20617320636f72653a3a697465723a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6835333036313866666431646566313763d201623c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c20563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6864643935663531666461643330633639d3016b3c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a497465723c27612c204b2c20563e20617320636f72653a3a697465723a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6866306530346461343465333164623665d4013c3c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a6830383430343761316634313063326166d501363c73726d6c5f73657373696f6e3a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a6833366562346533363238653537633531d6012d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6862626266343535396430343433396232d70134636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6836326662316266316161386165306163d8012e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6839643432336261616534613463393638d9013c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6863616261623933353263383063306335da0134636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6834353430636134616534636663316235db012e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6831363061616235383861636335663964dc013c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6834633166383564353063336663373139dd01423c73726d6c5f73657373696f6e3a3a5261774576656e743c426c6f636b4e756d6265723e3e3a3a6d657461646174613a3a6862323737303539366135616663363838de01483c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c20563e3e3a3a6765743a3a6863373164353762303432626564643630df014a3c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c20563e3e3a3a656e7472793a3a6863323361343266333338396237646136e0014b3c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c20563e3e3a3a696e736572743a3a6835613661303530353265373665663466e1014b3c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c20563e3e3a3a696e736572743a3a6866396266666365323833356636333732e201523c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c27612c204b2c20563e3e3a3a696e736572743a3a6832393331373330363962333132323237e3010c436f72655f76657273696f6ee40110436f72655f617574686f726974696573e50112436f72655f657865637574655f626c6f636be601373c73726d6c5f73797374656d3a3a4d6f64756c653c543e3e3a3a696e697469616c6973653a3a6865393230626439393539353037666466e701373c73726d6c5f73797374656d3a3a4d6f64756c653c543e3e3a3a626c6f636b5f686173683a3a6834663965323232626163636631326633e8014173725f7072696d6974697665733a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6866636335613135613362356166326231e9017f3c73726d6c5f6578656375746976653a3a4578656375746976653c53797374656d2c20426c6f636b2c20436f6e746578742c205061796d656e742c2046696e616c69736174696f6e3e3e3a3a6170706c795f65787472696e7369635f6e6f5f6e6f74655f776974685f6c656e3a3a6836353039373764323930323766646637ea01453c73726d6c5f73797374656d3a3a4d6f64756c653c543e3e3a3a6e6f74655f66696e69736865645f65787472696e736963733a3a6835333731373337353834366535303430eb01793c284d2c204e2c204f2c20502c20512c20522c20532c20542c20552c20562c20572c20582c20592c205a292061732073725f7072696d6974697665733a3a7472616974733a3a4f6e46696e616c6973653c4e756d6265723e3e3a3a6f6e5f66696e616c6973653a3a6836636363373037333335386134663338ec01353c73726d6c5f73797374656d3a3a4d6f64756c653c543e3e3a3a66696e616c6973653a3a6864326563653865613532386264333564ed0115436f72655f696e697469616c6973655f626c6f636bee01114d657461646174615f6d65746164617461ef011c426c6f636b4275696c6465725f6170706c795f65787472696e736963f0013773726d6c5f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830646461376533323666653731616434f1011b426c6f636b4275696c6465725f66696e616c6973655f626c6f636bf20120426c6f636b4275696c6465725f696e686572656e745f65787472696e73696373f3011c426c6f636b4275696c6465725f636865636b5f696e686572656e7473f40118426c6f636b4275696c6465725f72616e646f6d5f73656564f501367061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6832383635396130656337653835376332f6012b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6ef701b6013c73725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f6d6f7274616c5f65787472696e7369633a3a556e636865636b65644d6f7274616c45787472696e7369633c416464726573732c20496e6465782c2043616c6c2c205369676e61747572653e2061732073725f7072696d6974697665733a3a7472616974733a3a436865636b61626c653c436f6e746578743e3e3a3a636865636b3a3a6836313365393335646531646666323334f80187013c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a4d616b655061796d656e743c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6d616b655f7061796d656e743a3a6838613861383233626131663862663036f9013a3c73726d6c5f73797374656d3a3a4d6f64756c653c543e3e3a3a6163636f756e745f6e6f6e63653a3a6836383134666135323539323437306161fa0135636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a68326362393663383734366439366336362e31393735fb01367061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6835333233643861613261333635316638fc01214772616e6470614170695f6772616e6470615f70656e64696e675f6368616e6765fd01a70173725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a5f494d504c5f4445434f44455f464f525f4469676573743a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f722073725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573743c4974656d3e3e3a3a6465636f64653a3a6862343662306434373639623933346639fe011e4772616e6470614170695f6772616e6470615f617574686f726974696573ff01bd043c6e6f64655f72756e74696d653a3a52756e74696d65206173207375627374726174655f66696e616c6974795f6772616e6470615f7072696d6974697665733a3a72756e74696d655f6465636c5f666f725f4772616e6470614170693a3a4772616e6470614170693c73725f7072696d6974697665733a3a67656e657269633a3a626c6f636b3a3a426c6f636b3c73725f7072696d6974697665733a3a67656e657269633a3a6865616465723a3a4865616465723c7536342c2073725f7072696d6974697665733a3a7472616974733a3a426c616b6554776f3235362c206e6f64655f72756e74696d653a3a4c6f673e2c2073725f7072696d6974697665733a3a67656e657269633a3a756e636865636b65645f6d6f7274616c5f65787472696e7369633a3a556e636865636b65644d6f7274616c45787472696e7369633c73726d6c5f62616c616e6365733a3a616464726573733a3a416464726573733c3c6e6f64655f72756e74696d653a3a52756e74696d652061732073726d6c5f73797374656d3a3a54726169743e3a3a4163636f756e7449642c203c6e6f64655f72756e74696d653a3a52756e74696d652061732073726d6c5f62616c616e6365733a3a54726169743e3a3a4163636f756e74496e6465783e2c207536342c206e6f64655f72756e74696d653a3a43616c6c2c2073725f7072696d6974697665733a3a456432353531395369676e61747572653e3e3e3e3a3a6772616e6470615f617574686f7269746965733a3a6865623435363935346339353965353935800215417572614170695f736c6f745f6475726174696f6e81023c73726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6761733a3a683238396237303561346234633163333782024873726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f7365745f73746f726167653a3a683435663461623039343062326663356483024273726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a726561645f73616e64626f785f6d656d6f72793a3a683334346231326362313665336666633484022e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a683737386461623134373131656335343785024873726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f6765745f73746f726167653a3a683634666661333530333739656139656686027f3c73726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c27612c20543e2061732073726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a683633653937326232356535653532623687024173726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f63616c6c3a3a68616537653366613137623532613763648802473c73726d6c5f636f6e74726163743a3a657865633a3a457865637574696f6e436f6e746578743c27612c20543e3e3a3a63616c6c3a3a686461643235643432633630333339653189024373726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f6372656174653a3a68336534346430326238353463386462368a02493c73726d6c5f636f6e74726163743a3a657865633a3a457865637574696f6e436f6e746578743c27612c20543e3e3a3a6372656174653a3a68383866343836623232643138303062378b024373726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f72657475726e3a3a68313861653766386332653764383434318c024373726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f63616c6c65723a3a68386638306665626230636435666630658d024773726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f696e7075745f73697a653a3a68646261323139336461323733353238648e024773726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f696e7075745f636f70793a3a68656536303930663731666361303132328f024973726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f736372617463685f73697a653a3a686233613130346163626331336230373890024973726d6c5f636f6e74726163743a3a766d3a3a72756e74696d653a3a696e69745f656e763a3a6578745f736372617463685f636f70793a3a686633323061623135303433636461663191023a3c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3e3a3a6465706f7369745f6f663a3a68343336383836326634666636626362379202413c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3e3a3a696e6a6563745f7265666572656e64756d3a3a683061353835316365623064633364333493023f3c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3e3a3a7265666572656e64756d5f696e666f3a3a68303261653534343131633764386439389402e9013c73726d6c5f64656d6f63726163793a3a446973706174636851756575653c543e2061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167654d61703c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265722c20616c6c6f633a3a7665633a3a5665633c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c283c542061732073726d6c5f64656d6f63726163793a3a54726169743e3a3a50726f706f73616c2c20753332293e3e3e3e3a3a74616b653a3a686634383839376638626132643564653495023a3c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3e3a3a766f746572735f666f723a3a68343461303266366561333837396664639602403c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3e3a3a636c6561725f7265666572656e64756d3a3a68376235626639303235643238303332629702727061726974795f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f7220284a2c204b293e3a3a656e636f64655f746f3a3a683235376132613066306335666561666598023e3c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a68646434356265396639346530376636379902373c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3e3a3a766f74655f6f663a3a68303336346263313136343264303363619a02383c73726d6c5f64656d6f63726163793a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a68376332393636623835643234313861339b024b3c73726d6c5f64656d6f63726163793a3a5261774576656e743c42616c616e63652c204163636f756e7449643e3e3a3a6d657461646174613a3a68313164363831363466336166336166309c02493c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68663938313366393061613331306132612e313436369d02493c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c20563e3e3a3a696e736572743a3a68666535633437323034373034333737669e026c3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a6765743a3a68303433353637313533343234373162649f026c3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a6765743a3a6832643863363566616662393464396536a0026c3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a7075743a3a6835323133303237303034626139616337a1026c3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a7075743a3a6838373662616436636563306661346562a2026c3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a7075743a3a6839616631663634376662663236653136a3026c3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a7075743a3a6839626232333030643233323066326165a4026c3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a7075743a3a6863643534386539326433633163373162a5026c3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a7075743a3a6866653631616136636232346430633765a6026d3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a74616b653a3a6861616530343533613936633463643665a7026d3c73726d6c5f737570706f72743a3a73746f726167653a3a52756e74696d6553746f726167652061732073726d6c5f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a53746f726167653e3a3a74616b653a3a6864343464653666653266303433306630a802683c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6863303663313033303063636362623437a9026b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6863393838626262313539386631396161aa026c3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6866303361333864326430363865653335ab026f3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6835383065373330353663333636313862ac02743c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a56617255696e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6838376534656166386634343034373236ad02793c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973743c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6839376665636665373065613933353838ae026b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6861353538643563343832383333343033af02727061726974795f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f7220284a2c204b293e3a3a656e636f64655f746f3a3a6865316264306330643338396233396239b0023c3c73726d6c5f6772616e6470613a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a6862653263633736653733626466313766b102363c73726d6c5f6772616e6470613a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a6830636539643766613166373737333539b202413c73726d6c5f6772616e6470613a3a5261774576656e743c53657373696f6e4b65793e3e3a3a6d657461646174613a3a6839386331636239346433313365306261b3026b3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6839643738353062383133333332646534b4026f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a56617255696e7437206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6832663035333535316234323234666133b502713c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a437573746f6d53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6838663965323261626663626339393766b60282017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a73657269616c697a653a3a6865646666623637303635636139653365b702693c7061726974795f7761736d3a3a656c656d656e74733a3a66756e633a3a46756e63426f6479206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6865616439393631303834633130383332b802713c7061726974795f7761736d3a3a656c656d656e74733a3a696e6465785f6d61703a3a496e6465784d61703c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6830323839373530613264333436396665b90282017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a73657269616c697a653a3a6866303639336538353738303237373461ba026f3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6862393537323437643166393663343761bb02457061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e5265616465723a3a6e65773a3a6837643066373138633638393464653633bc0286017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a646573657269616c697a653a3a6863653139643461363761373862613738bd027c3c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6838613238383864306263373061626463be02773c73726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6833346564366333323837393832323131bf02773c73726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6833353335376465333835653731306164c0023673726d6c5f636f6e74726163743a3a646f75626c655f6d61703a3a66756c6c5f6b65793a3a6831643235623335313333316634396231c102723c73726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6863643832396465313835323130373030c202483c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a7365745f667265655f62616c616e63655f6372656174696e673a3a6830653965623035396634663535353761c302743c73726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732073726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64653a3a6862323935633932646464393530343737c402563c73726d6c5f636f6e73656e7375733a3a43616c6c3c543e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6834373966653533653633613130303061c5027f3c73726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c27612c20543e2061732073726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6866656163613164313130353137626162c6022e636f72653a3a726573756c743a3a756e777261705f6661696c65643a3a6835306461613337623235623032376538c7027a3c73726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c27612c20543e2061732073726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6836313832626335376361623233313564c8027c3c73726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c27612c20543e2061732073726d6c5f636f6e74726163743a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64653a3a6862663138633132366638333462626534c902373c636f72653a3a736c6963653a3a497465723c27612c20543e3e3a3a61735f736c6963653a3a6839626234323536303932396635363035ca0280013c73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573744974656d5265663c27612c20486173682c20417574686f7269747949643e206173207061726974795f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6864333935323333376132646263386431cb027b6e6f64655f72756e74696d653a3a5f494d504c5f4445434f44455f464f525f4576656e743a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a4576656e743e3a3a6465636f64653a3a6865663334386465393162656266363764cc02593c6e6f64655f72756e74696d653a3a43616c6c2061732073726d6c5f737570706f72743a3a64697370617463683a3a446973706174636861626c653e3a3a64697370617463683a3a6865356334326533383465643635346265cd025e3c73726d6c5f636f6e73656e7375733a3a43616c6c3c543e2061732073726d6c5f737570706f72743a3a64697370617463683a3a446973706174636861626c653e3a3a64697370617463683a3a6866633439373238323161356437323639ce02373c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a656e756d5f7365743a3a6865646161633831303465396633383037cf02433c73726d6c5f636f756e63696c3a3a766f74696e673a3a4d6f64756c653c543e3e3a3a69735f636f756e63696c6c6f723a3a6862353636316638326430656239386565d002633c73726d6c5f636f756e63696c3a3a73656174733a3a43616c6c3c543e2061732073726d6c5f737570706f72743a3a64697370617463683a3a446973706174636861626c653e3a3a64697370617463683a3a6831333133346662663266313462663062d102643c73726d6c5f636f756e63696c3a3a766f74696e673a3a43616c6c3c543e2061732073726d6c5f737570706f72743a3a64697370617463683a3a446973706174636861626c653e3a3a64697370617463683a3a6834363863383266353462333230623761d202363c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a726573657276653a3a6839346664646565623736313266333231d302433c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a7365745f72657365727665645f62616c616e63653a3a6832366433393933313533376638336135d4023d3c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a736c6173685f72657365727665643a3a6865343364613863393535636230353335d5024e3c6e6f64655f72756e74696d653a3a43616c6c206173207061726974795f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6863393663336264393333356162343834d602c2013c6e6f64655f72756e74696d653a3a4c6f6720617320636f72653a3a636f6e766572743a3a46726f6d3c73725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c7375627374726174655f7072696d6974697665733a3a686173683a3a483235362c207375627374726174655f7072696d6974697665733a3a617574686f726974795f69643a3a417574686f7269747949643e3e3e3a3a66726f6d3a3a6838316466343634633964346230373964d702367061726974795f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6861383331323439346564646233333334d802a7017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f4445434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a6465636f64653a3a6866393566653334333861633532303566d902aa017375627374726174655f7072696d6974697665733a3a73616e64626f783a3a5f494d504c5f454e434f44455f464f525f547970656456616c75653a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a456e636f646520666f72207375627374726174655f7072696d6974697665733a3a73616e64626f783a3a547970656456616c75653e3a3a656e636f64655f746f3a3a6836346639666566626233363864666434da023e3c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a6838353762306366393236653834363830db02383c73726d6c5f74696d657374616d703a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a6864623231643531336436313533316633dc02443c73726d6c5f636f756e63696c3a3a766f74696e673a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a6837333165613734336231333938633061dd023e3c73726d6c5f636f756e63696c3a3a766f74696e673a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a6832623338353665663164616662346433de02433c73726d6c5f636f756e63696c3a3a766f74696e673a3a5261774576656e743c486173683e3e3a3a6d657461646174613a3a6839343236383031343265393531346431df023d3c73726d6c5f636f756e63696c3a3a766f74696e673a3a4d6f64756c653c543e3e3a3a7665746f5f6f663a3a6830613436396435386435386163306662e002383c73726d6c5f73797374656d3a3a4d6f64756c653c543e3e3a3a6465706f7369745f6c6f673a3a6832666663636136363437613462346337e102383c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a756e726573657276653a3a6866333762376136396438636139333664e2028d013c73726d6c5f636f756e63696c3a3a73656174733a3a4d6f64756c653c543e2061732073725f7072696d6974697665733a3a7472616974733a3a4f6e46696e616c6973653c3c542061732073726d6c5f73797374656d3a3a54726169743e3a3a426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c6973653a3a6861613362383536643032303461653763e3023073726d6c5f636f6e74726163743a3a657865633a3a7472616e736665723a3a6831623965666434326138336233653237e4022d73726d6c5f636f6e74726163743a3a766d3a3a657865637574653a3a6866316632613064376261343333656233e5023273725f73616e64626f783a3a696d703a3a64697370617463685f7468756e6b3a3a6862353232626663363062663532336232e60230636f72653a3a7074723a3a7265616c5f64726f705f696e5f706c6163653a3a6864313463666633313830626361663065e702333c73726d6c5f617572613a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a6832363736343037663036323432336632e8023e3c73726d6c5f636f6e73656e7375733a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a6866393666333064653139343333666665e902383c73726d6c5f636f6e73656e7375733a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a6838646135303462663035663936303838ea02a70173725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a5f494d504c5f4445434f44455f464f525f4469676573743a3a3c696d706c207061726974795f636f6465633a3a636f6465633a3a4465636f646520666f722073725f7072696d6974697665733a3a67656e657269633a3a6469676573743a3a4469676573743c4974656d3e3e3a3a6465636f64653a3a6835653165653665636239383335626662eb02473c73726d6c5f636f756e63696c3a3a73656174733a3a4d6f64756c653c543e3e3a3a63616e6469646174655f7265675f696e666f3a3a6831333730623136366362643830363134ec02433c73726d6c5f636f756e63696c3a3a73656174733a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a6865666233616438393038653261313766ed023d3c73726d6c5f636f756e63696c3a3a73656174733a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a6863643436626661393930383534346466ee02473c73726d6c5f636f756e63696c3a3a73656174733a3a5261774576656e743c4163636f756e7449643e3e3a3a6d657461646174613a3a6835333338356464656533646239323264ef02413c73726d6c5f636f756e63696c3a3a73656174733a3a4d6f64756c653c543e3e3a3a72656d6f76655f766f7465723a3a6830333234633666623632626461396437f002413c73726d6c5f636f756e63696c3a3a73656174733a3a4d6f64756c653c543e3e3a3a617070726f76616c735f6f663a3a6865383436353866313332616662326338f1023b3c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a726561705f6163636f756e743a3a6832356534336238663665323165663830f2023b3c73726d6c5f73797374656d3a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a6864663130353166623036333361356330f3023d3c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a73746f72655f6d657461646174613a3a6863616236336139363839373665386334f402493c552061732073726d6c5f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c20563e3e3a3a696e736572743a3a6837643863306239343539356234343663f502373c73726d6c5f62616c616e6365733a3a4d6f64756c653c543e3e3a3a6d657461646174613a3a6830396531613439646237316238663233f602583c73726d6c5f62616c616e6365733a3a5261774576656e743c4163636f756e7449642c204163636f756e74496e6465782c2042616c616e63653e3e3a3a6d657461646174613a3a6861353537333434333632363539343132f702066d656d736574f802066d656d637079f902076d656d6d6f7665fa02066d656d636d70fb02095f5f75646976746933fc02085f5f6d756c746933fd02095f5f756d6f64746933fe023f636f6d70696c65725f6275696c74696e733a3a696e743a3a73686966743a3a727573745f693132385f73686c3a3a6838616661636336353330643766396236ff023f636f6d70696c65725f6275696c74696e733a3a696e743a3a73686966743a3a727573745f753132385f7368723a3a686533646132363863336233396232393480030c5f5f756469766d6f6474693400590970726f64756365727302086c616e677561676501045275737404323031350c70726f6365737365642d62790105727573746325312e33322e302d6e696768746c79202831343939376435366120323031382d31322d303529", + "0x3a6772616e6470613a617574683a03000000": "0x8101764f45778d4980dadaceee6e8af2517d3ab91ac9bec9cd1714fa5994081c0100000000000000", + "0x3a6772616e6470613a617574683a6c656e": "0x04000000", + "0xf718f07ec955fb94f1b3069713461089": "0x0010a5d4e80000000000000000000000", + "0x4664fb5d4e16f894df23cadb3faaa9a6": "0x04000000", + "0x472b8f236d06a2ff7f1e9b2e848ef1d5": "0x0080e03779c311000000000000000000", + "0x78f4ad73d6b7279f8d06f359e363c829": "0x0000a0dec5adc9353600000000000000", + "0x7935e46f94f24b82716c0142e2271de9": "0x8070000000000000", + "0x90d5871cf3f4d0a3642cf2043a7d8eda": "0x0010a5d4e80000000000000000000000", + "0x500603c2af44c475f017a2bbd8d08cbf": "0x04f295940fa750df68a686fcf4abd4111c8a9c5a5a5a83c4c8639c451a94a7adfd", + "0x2dce29f1a768624dc5343063cb77f77d": "0x07000000", + "0x579ab55d37b1220812be3c3df29d4858": "0x0000000000000000", + "0x24b2518f9a9ee24ab0b62346d83d90b0": "0x11080000", + "0xdd9b01f8462dc19488279cb351a6d861": "0x20a10700", + "0x62f532424b7b1c52f522857315040f27": "0x00407a10f35a00000000000000000000", + "0x799192c17c5cc562d709af11ace92e6a": "0x00040000", + "0xa361c08e2d7768113505020abde19e30": "0x00000000", + "0xb7b6ec0f25eb1ed8b91d05f697d7a874": "0x0c00000000000000", + "0x637414312dac3b280120bf15b4f66cee": "0x00000000", + "0x1f3cb74fca639d825d2f0a0955afbf4a": "0xf295940fa750df68a686fcf4abd4111c8a9c5a5a5a83c4c8639c451a94a7adfd", + "0x90e2849b965314409e8bc00011f3004f": "0x04000000", + "0x329586a7b97f2ac15f6c26a02c3c5621": "0x1082c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf54de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7063d7787ebca768b7445dfebe7d62cbb1625ff4dba288ea34488da266dd6dca58101764f45778d4980dadaceee6e8af2517d3ab91ac9bec9cd1714fa5994081c", + "0x52c9048efbfc40fd1e312b7bed451dee": "0x06000000", + "0x0e4944cfd98d6f4cc374d16f5a4e3f9c": "0x0000000000000000", + "0xfb4fdd0ab2d85118e220e2e7473cd3b5": "0x0000a0dec5adc9353600000000000000", + "0x2b89d3b6f46fc8a3aee48c9cb06d7670": "0x0010a5d4e80000000000000000000000", + "0x59b17352bea17cb7dec6dde697de7db4": "0x6400000000000000", + "0x4a8b1a5c7681353a6a320553abbbca49": "0x4038000000000000", + "0x99e2aba8a2b7c8ccba2d740fb86adb0c": "0x00", + "0x717a2ee9c64ad3424e10e4461ec08296": "0x010000000000000001000000000000000100000000000000010000000000000001000000000000000000010010000000", + "0x0b21b3456b23e90d061941ab416f5ea2": "0x00000000000000000000000000000000", + "0xfe7030fd433199728c516e4392091aa5": "0x0080c6a47e8d03000000000000000000", + "0x53d1471b684c8a776c80353e5981c960": "0x00407a10f35a00000000000000000000", + "0xdee5bbb035d9ebc2c9338b5aedf744d7": "0x4038000000000000", + "0x2ec6e5652282d579398fb8fdfa531ef6": "0x0000000000000000", + "0x6e45a8645fa8f905c49fecfef3d06c67": "0x01000000", + "0x9651d20f401bfac47731a01d6eba33b4": "0x00000000", + "0xf4039aa8ae697861be900c58239e96f7": "0x0010a5d4e80000000000000000000000", + "0xdade128e67a5ed110063f56a01ab6bbf": "0x0000000000000000", + "0xb553f17a95cb65012a4326bbaae97035": "0x0010a5d4e80000000000000000000000", + "0x3a617574683a00000000": "0x82c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf5", + "0x74d5dca6735bab024bc25136daaab7c0": "0x06", + "0x934302c5ec4cb4f73a395e2184ab0aa6": "0x00e40b54020000000000000000000000", + "0xe026dd082e3158e72eb7c985fc8bac4f": "0x4038000000000000", + "0xa36baa0f89eff09b2facf282f27a11ba": "0x50c30000", + "0xf14d23a9d4492a1efc9194e257b3c3d9": "0x00000000", + "0xdfaac108e0d4bc78fc9419a7fcfa84dc": "0x1082c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf54de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7063d7787ebca768b7445dfebe7d62cbb1625ff4dba288ea34488da266dd6dca58101764f45778d4980dadaceee6e8af2517d3ab91ac9bec9cd1714fa5994081c", + "0xd437fe93b0bd0a5d67d30d85d010edc2": "0x40420f00", + "0x3a6772616e6470613a617574683a00000000": "0x82c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf50100000000000000", + "0x3a617574683a01000000": "0x4de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7", + "0x3a617574683a02000000": "0x063d7787ebca768b7445dfebe7d62cbb1625ff4dba288ea34488da266dd6dca5", + "0xb9b861cab4bbce870c811515bd5f33d7": "0x00", + "0x125dc846383907f5846f72ce53ca0e4b": "0x00ca9a3b000000000000000000000000", + "0x3a617574683a6c656e": "0x04000000" + } + } +} diff --git a/node/cli/src/chain_spec.rs b/node/cli/src/chain_spec.rs index 5058f0de60c2715ad015debb095a0dc5389bf5dd..78e6d923410a66a65a1692275f6656a23a7c1949 100644 --- a/node/cli/src/chain_spec.rs +++ b/node/cli/src/chain_spec.rs @@ -16,20 +16,24 @@ //! Substrate chain configurations. -use primitives::{AuthorityId, ed25519}; +use primitives::{Ed25519AuthorityId, ed25519}; use node_primitives::AccountId; -use node_runtime::{GenesisConfig, ConsensusConfig, CouncilSeatsConfig, CouncilVotingConfig, DemocracyConfig, - SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, TreasuryConfig, UpgradeKeyConfig, - ContractConfig, Permill, Perbill}; +use node_runtime::{ConsensusConfig, CouncilSeatsConfig, CouncilVotingConfig, DemocracyConfig, + SessionConfig, StakingConfig, TimestampConfig, BalancesConfig, TreasuryConfig, + SudoConfig, ContractConfig, GrandpaConfig, IndicesConfig, Permill, Perbill}; +pub use node_runtime::GenesisConfig; use substrate_service; +use substrate_keystore::pad_seed; + const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; /// Specialised `ChainSpec`. pub type ChainSpec = substrate_service::ChainSpec; -pub fn bbq_birch_config() -> Result { - ChainSpec::from_embedded(include_bytes!("../res/bbq-birch.json")) +/// Charred Cherry testnet generator +pub fn charred_cherry_config() -> Result { + ChainSpec::from_embedded(include_bytes!("../res/charred-cherry.json")) } fn staging_testnet_config_genesis() -> GenesisConfig { @@ -43,32 +47,34 @@ fn staging_testnet_config_genesis() -> GenesisConfig { hex!["f295940fa750df68a686fcf4abd4111c8a9c5a5a5a83c4c8639c451a94a7adfd"].into(), ]; const MILLICENTS: u128 = 1_000_000_000; - const CENTS: u128 = 1_000 * MILLICENTS; // assume this is worth about a cent. + const CENTS: u128 = 1_000 * MILLICENTS; // assume this is worth about a cent. const DOLLARS: u128 = 100 * CENTS; - const SECS_PER_BLOCK: u64 = 4; + const SECS_PER_BLOCK: u64 = 6; const MINUTES: u64 = 60 / SECS_PER_BLOCK; const HOURS: u64 = MINUTES * 60; const DAYS: u64 = HOURS * 24; GenesisConfig { consensus: Some(ConsensusConfig { - code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm").to_vec(), // TODO change + code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm").to_vec(), // TODO change authorities: initial_authorities.clone(), }), system: None, balances: Some(BalancesConfig { - balances: endowed_accounts.iter().map(|&k|(k, 10_000_000 * DOLLARS)).collect(), + balances: endowed_accounts.iter().map(|&k| (k, 10_000_000 * DOLLARS)).collect(), transaction_base_fee: 1 * CENTS, transaction_byte_fee: 10 * MILLICENTS, existential_deposit: 1 * DOLLARS, transfer_fee: 1 * CENTS, creation_fee: 1 * CENTS, - reclaim_rebate: 1 * CENTS, + }), + indices: Some(IndicesConfig { + ids: endowed_accounts.clone(), }), session: Some(SessionConfig { validators: initial_authorities.iter().cloned().map(Into::into).collect(), - session_length: 5 * MINUTES + session_length: 5 * MINUTES, }), staking: Some(StakingConfig { current_era: 0, @@ -79,14 +85,17 @@ fn staging_testnet_config_genesis() -> GenesisConfig { current_session_reward: 0, validator_count: 7, sessions_per_era: 12, - bonding_duration: 1 * DAYS, + bonding_duration: 60 * MINUTES, offline_slash_grace: 4, minimum_validator_count: 4, + invulnerables: initial_authorities.iter().cloned().map(Into::into).collect(), }), democracy: Some(DemocracyConfig { - launch_period: 5 * MINUTES, // 1 day per public referendum - voting_period: 5 * MINUTES, // 3 days to discuss & vote on an active referendum - minimum_deposit: 50 * DOLLARS, // 12000 as the minimum deposit for a referendum + launch_period: 10 * MINUTES, // 1 day per public referendum + voting_period: 10 * MINUTES, // 3 days to discuss & vote on an active referendum + minimum_deposit: 50 * DOLLARS, // 12000 as the minimum deposit for a referendum + public_delay: 10 * MINUTES, + max_lock_periods: 6, }), council_seats: Some(CouncilSeatsConfig { active_council: vec![], @@ -98,15 +107,15 @@ fn staging_testnet_config_genesis() -> GenesisConfig { approval_voting_period: 2 * DAYS, term_duration: 28 * DAYS, desired_seats: 0, - inactive_grace_period: 1, // one additional vote should go by before an inactive voter can be reaped. - + inactive_grace_period: 1, // one additional vote should go by before an inactive voter can be reaped. }), council_voting: Some(CouncilVotingConfig { cooloff_period: 4 * DAYS, voting_period: 1 * DAYS, + enact_delay_period: 0, }), timestamp: Some(TimestampConfig { - period: SECS_PER_BLOCK, + period: SECS_PER_BLOCK / 2, // due to the nature of aura the slots are 2*period }), treasury: Some(TreasuryConfig { proposal_bond: Permill::from_percent(5), @@ -121,17 +130,20 @@ fn staging_testnet_config_genesis() -> GenesisConfig { gas_price: 1 * MILLICENTS, max_depth: 1024, block_gas_limit: 10_000_000, + current_schedule: Default::default(), }), - upgrade_key: Some(UpgradeKeyConfig { + sudo: Some(SudoConfig { key: endowed_accounts[0].clone(), }), + grandpa: Some(GrandpaConfig { + authorities: initial_authorities.clone().into_iter().map(|k| (k, 1)).collect(), + }) } } /// Staging testnet config. pub fn staging_testnet_config() -> ChainSpec { - let boot_nodes = vec![ - ]; + let boot_nodes = vec![]; ChainSpec::from_genesis( "Staging Testnet", "staging_testnet", @@ -140,32 +152,50 @@ pub fn staging_testnet_config() -> ChainSpec { Some(STAGING_TELEMETRY_URL.into()), None, None, + None, ) } -fn testnet_genesis(initial_authorities: Vec, upgrade_key: AccountId) -> GenesisConfig { - let endowed_accounts = vec![ - ed25519::Pair::from_seed(b"Alice ").public().0.into(), - ed25519::Pair::from_seed(b"Bob ").public().0.into(), - ed25519::Pair::from_seed(b"Charlie ").public().0.into(), - ed25519::Pair::from_seed(b"Dave ").public().0.into(), - ed25519::Pair::from_seed(b"Eve ").public().0.into(), - ed25519::Pair::from_seed(b"Ferdie ").public().0.into(), - ]; +/// Helper function to generate AuthorityID from seed +pub fn get_authority_id_from_seed(seed: &str) -> Ed25519AuthorityId { + let padded_seed = pad_seed(seed); + // NOTE from ed25519 impl: + // prefer pkcs#8 unless security doesn't matter -- this is used primarily for tests. + ed25519::Pair::from_seed(&padded_seed).public().0.into() +} + +/// Helper function to create GenesisConfig for testing +pub fn testnet_genesis( + initial_authorities: Vec, + root_key: AccountId, + endowed_accounts: Option>, +) -> GenesisConfig { + let endowed_accounts = endowed_accounts.unwrap_or_else(|| { + vec![ + get_authority_id_from_seed("Alice"), + get_authority_id_from_seed("Bob"), + get_authority_id_from_seed("Charlie"), + get_authority_id_from_seed("Dave"), + get_authority_id_from_seed("Eve"), + get_authority_id_from_seed("Ferdie"), + ] + }); GenesisConfig { consensus: Some(ConsensusConfig { code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm").to_vec(), authorities: initial_authorities.clone(), }), system: None, + indices: Some(IndicesConfig { + ids: endowed_accounts.iter().map(|x| x.0.into()).collect(), + }), balances: Some(BalancesConfig { transaction_base_fee: 1, transaction_byte_fee: 0, existential_deposit: 500, transfer_fee: 0, creation_fee: 0, - reclaim_rebate: 0, - balances: endowed_accounts.iter().map(|&k|(k, (1 << 60))).collect(), + balances: endowed_accounts.iter().map(|&k| (k.into(), (1 << 60))).collect(), }), session: Some(SessionConfig { validators: initial_authorities.iter().cloned().map(Into::into).collect(), @@ -183,16 +213,19 @@ fn testnet_genesis(initial_authorities: Vec, upgrade_key: AccountId current_offline_slash: 0, current_session_reward: 0, offline_slash_grace: 0, + invulnerables: initial_authorities.iter().cloned().map(Into::into).collect(), }), democracy: Some(DemocracyConfig { launch_period: 9, voting_period: 18, minimum_deposit: 10, + public_delay: 0, + max_lock_periods: 6, }), council_seats: Some(CouncilSeatsConfig { active_council: endowed_accounts.iter() - .filter(|a| initial_authorities.iter().find(|&b| a.as_bytes() == b.0).is_none()) - .map(|a| (a.clone(), 1000000)).collect(), + .filter(|a| initial_authorities.iter().find(|&b| a.0 == b.0).is_none()) + .map(|a| (a.clone().into(), 1000000)).collect(), candidacy_bond: 10, voter_bond: 2, present_slash_per_voter: 1, @@ -206,9 +239,10 @@ fn testnet_genesis(initial_authorities: Vec, upgrade_key: AccountId council_voting: Some(CouncilVotingConfig { cooloff_period: 75, voting_period: 20, + enact_delay_period: 0, }), timestamp: Some(TimestampConfig { - period: 5, // 5 second block time. + period: 2, // 2*2=4 second block time. }), treasury: Some(TreasuryConfig { proposal_bond: Permill::from_percent(5), @@ -223,38 +257,46 @@ fn testnet_genesis(initial_authorities: Vec, upgrade_key: AccountId gas_price: 1, max_depth: 1024, block_gas_limit: 10_000_000, + current_schedule: Default::default(), }), - upgrade_key: Some(UpgradeKeyConfig { - key: upgrade_key, + sudo: Some(SudoConfig { + key: root_key, }), + grandpa: Some(GrandpaConfig { + authorities: initial_authorities.clone().into_iter().map(|k| (k, 1)).collect(), + }) } } fn development_config_genesis() -> GenesisConfig { - testnet_genesis(vec![ - ed25519::Pair::from_seed(b"Alice ").public().into(), - ], - ed25519::Pair::from_seed(b"Alice ").public().0.into() + testnet_genesis( + vec![ + get_authority_id_from_seed("Alice"), + ], + get_authority_id_from_seed("Alice").into(), + None, ) } /// Development config (single validator Alice) pub fn development_config() -> ChainSpec { - ChainSpec::from_genesis("Development", "development", development_config_genesis, vec![], None, None, None) + ChainSpec::from_genesis("Development", "dev", development_config_genesis, vec![], None, None, None, None) } fn local_testnet_genesis() -> GenesisConfig { - testnet_genesis(vec![ - ed25519::Pair::from_seed(b"Alice ").public().into(), - ed25519::Pair::from_seed(b"Bob ").public().into(), - ], - ed25519::Pair::from_seed(b"Alice ").public().0.into() + testnet_genesis( + vec![ + get_authority_id_from_seed("Alice"), + get_authority_id_from_seed("Bob"), + ], + get_authority_id_from_seed("Alice").into(), + None, ) } /// Local testnet config (multivalidator Alice + Bob) pub fn local_testnet_config() -> ChainSpec { - ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None) + ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None, None) } #[cfg(test)] @@ -271,11 +313,11 @@ mod tests { /// Local testnet config (multivalidator Alice + Bob) pub fn integration_test_config() -> ChainSpec { - ChainSpec::from_genesis("Integration Test", "test", local_testnet_genesis_instant, vec![], None, None, None) + ChainSpec::from_genesis("Integration Test", "test", local_testnet_genesis_instant, vec![], None, None, None, None) } #[test] fn test_connectivity() { - service_test::connectivity::(integration_test_config()); + service_test::connectivity::(integration_test_config()); } } diff --git a/node/cli/src/cli.yml b/node/cli/src/cli.yml deleted file mode 100644 index 6c1fe186e793bc4965fd35d06f745008a6a0f05e..0000000000000000000000000000000000000000 --- a/node/cli/src/cli.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: substrate-node -author: "Parity Team " -about: Substrate Node Rust Implementation -args: - - log: - short: l - value_name: LOG_PATTERN - help: Sets a custom logging - takes_value: true -subcommands: - - validator: - about: Run validator node diff --git a/node/cli/src/lib.rs b/node/cli/src/lib.rs index beb47f91ff86812dfffbc6f151ce99db2412fafc..55ab1822ea44ee2718c00aa872756aaede60b04e 100644 --- a/node/cli/src/lib.rs +++ b/node/cli/src/lib.rs @@ -33,21 +33,30 @@ extern crate substrate_transaction_pool as transaction_pool; #[macro_use] extern crate substrate_network as network; extern crate substrate_consensus_aura as consensus; +extern crate substrate_client as client; +extern crate substrate_finality_grandpa as grandpa; extern crate node_primitives; #[macro_use] extern crate substrate_service; extern crate node_executor; +extern crate substrate_keystore; #[macro_use] extern crate log; +extern crate structopt; pub use cli::error; -mod chain_spec; +pub mod chain_spec; mod service; +mod params; +use tokio::prelude::Future; use tokio::runtime::Runtime; pub use cli::{VersionInfo, IntoExit}; use substrate_service::{ServiceFactory, Roles as ServiceRoles}; +use params::{Params as NodeParams}; +use structopt::StructOpt; +use std::ops::Deref; /// The chain specification option. #[derive(Clone, Debug)] @@ -56,8 +65,8 @@ pub enum ChainSpec { Development, /// Whatever the current runtime is, with simple Alice/Bob auths. LocalTestnet, - /// The BBQ Birch testnet. - BbqBirch, + /// The Charred Cherry testnet. + CharredCherry, /// Whatever the current runtime is with the "global testnet" defaults. StagingTestnet, } @@ -66,7 +75,7 @@ pub enum ChainSpec { impl ChainSpec { pub(crate) fn load(self) -> Result { Ok(match self { - ChainSpec::BbqBirch => chain_spec::bbq_birch_config()?, + ChainSpec::CharredCherry => chain_spec::charred_cherry_config()?, ChainSpec::Development => chain_spec::development_config(), ChainSpec::LocalTestnet => chain_spec::local_testnet_config(), ChainSpec::StagingTestnet => chain_spec::staging_testnet_config(), @@ -77,7 +86,7 @@ impl ChainSpec { match s { "dev" => Some(ChainSpec::Development), "local" => Some(ChainSpec::LocalTestnet), - "" | "bbq-birch" => Some(ChainSpec::BbqBirch), + "" | "cherry" | "charred-cherry" => Some(ChainSpec::CharredCherry), "staging" => Some(ChainSpec::StagingTestnet), _ => None, } @@ -97,32 +106,52 @@ pub fn run(args: I, exit: E, version: cli::VersionInfo) -> error::Resul T: Into + Clone, E: IntoExit, { - match cli::prepare_execution::(args, exit, version, load_spec, "substrate-node")? { + let full_version = substrate_service::config::full_version_from_strs( + version.version, + version.commit + ); + + let matches = match NodeParams::clap() + .name(version.executable_name) + .author(version.author) + .about(version.description) + .version(&(full_version + "\n")[..]) + .get_matches_from_safe(args) { + Ok(m) => m, + Err(e) => e.exit(), + }; + + let (spec, config) = cli::parse_matches::( + load_spec, &version, "substrate-node", &matches + )?; + + match cli::execute_default::(spec, exit, &matches, &config)? { cli::Action::ExecutedInternally => (), - cli::Action::RunService((config, exit)) => { - info!("Substrate Node"); + cli::Action::RunService(exit) => { + info!("{}", version.name); info!(" version {}", config.full_version()); - info!(" by Parity Technologies, 2017, 2018"); + info!(" by {}, 2017, 2018", version.author); info!("Chain specification: {}", config.chain_spec.name()); info!("Node name: {}", config.name); info!("Roles: {:?}", config.roles); let mut runtime = Runtime::new()?; let executor = runtime.executor(); match config.roles == ServiceRoles::LIGHT { - true => run_until_exit(&mut runtime, service::Factory::new_light(config, executor)?, exit)?, - false => run_until_exit(&mut runtime, service::Factory::new_full(config, executor)?, exit)?, + true => run_until_exit(runtime, service::Factory::new_light(config, executor)?, exit)?, + false => run_until_exit(runtime, service::Factory::new_full(config, executor)?, exit)?, } } } Ok(()) } -fn run_until_exit( - runtime: &mut Runtime, - service: service::Service, +fn run_until_exit( + mut runtime: Runtime, + service: T, e: E, ) -> error::Result<()> where + T: Deref>, C: substrate_service::Components, E: IntoExit, { @@ -133,5 +162,14 @@ fn run_until_exit( let _ = runtime.block_on(e.into_exit()); exit_send.fire(); + + // 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 + let _telemetry = service.telemetry(); + drop(service); + + // TODO [andre]: timeout this future #1318 + let _ = runtime.shutdown_on_idle().wait(); + Ok(()) } diff --git a/node/cli/src/params.rs b/node/cli/src/params.rs new file mode 100644 index 0000000000000000000000000000000000000000..130c9a4dc54fe7df531567e0d2a5263a2d1cacf7 --- /dev/null +++ b/node/cli/src/params.rs @@ -0,0 +1,25 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 structopt::StructOpt; +use cli::CoreParams; + +/// Extend params for Node +#[derive(Debug, StructOpt)] +pub struct Params { + #[structopt(flatten)] + core: CoreParams +} diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index d02ea48767b19ce900ed3443258faf30fb7115e8..38f34aedf5a0dd3d86a7f0160cd3952ba6258e28 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -19,76 +19,134 @@ //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. use std::sync::Arc; -use transaction_pool::{self, txpool::{Pool as TransactionPool}}; -use node_primitives::Block; -use node_runtime::GenesisConfig; +use std::time::Duration; + +use client; +use consensus::{import_queue, start_aura, AuraImportQueue, SlotDuration, NothingExtra}; +use grandpa; +use node_executor; +use primitives::ed25519::Pair; +use node_primitives::{Block, InherentData}; +use node_runtime::{GenesisConfig, RuntimeApi}; use substrate_service::{ FactoryFullConfiguration, LightComponents, FullComponents, FullBackend, - FullClient, LightClient, LightBackend, FullExecutor, LightExecutor, - Roles, TaskExecutor, + FullClient, LightClient, LightBackend, FullExecutor, LightExecutor, TaskExecutor }; -use node_executor; -use consensus::{import_queue, start_aura, Config as AuraConfig, AuraImportQueue}; - -const AURA_SLOT_DURATION: u64 = 6; +use transaction_pool::{self, txpool::{Pool as TransactionPool}}; construct_simple_protocol! { /// Demo protocol attachment for substrate. pub struct NodeProtocol where Block = Block { } } -construct_simple_service!(Service); +/// Node specific configuration +pub struct NodeConfig { + /// grandpa connection to import block + // FIXME: rather than putting this on the config, let's have an actual intermediate setup state + // https://github.com/paritytech/substrate/issues/1134 + pub grandpa_import_setup: Option<(Arc>, grandpa::LinkHalfForService)>, +} + +impl Default for NodeConfig where F: substrate_service::ServiceFactory { + fn default() -> NodeConfig { + NodeConfig { + grandpa_import_setup: None, + } + } +} construct_service_factory! { struct Factory { Block = Block, + RuntimeApi = RuntimeApi, NetworkProtocol = NodeProtocol { |config| Ok(NodeProtocol::new()) }, RuntimeDispatch = node_executor::Executor, - FullTransactionPoolApi = transaction_pool::ChainApi, FullExecutor, Block> + FullTransactionPoolApi = transaction_pool::ChainApi, FullExecutor, Block, RuntimeApi>, Block> { |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) }, - LightTransactionPoolApi = transaction_pool::ChainApi, LightExecutor, Block> + LightTransactionPoolApi = transaction_pool::ChainApi, LightExecutor, Block, RuntimeApi>, Block> { |config, client| Ok(TransactionPool::new(config, transaction_pool::ChainApi::new(client))) }, Genesis = GenesisConfig, - Configuration = (), - FullService = Service> - { |config: FactoryFullConfiguration, executor: TaskExecutor| { - let is_auth = config.roles == Roles::AUTHORITY; - Service::>::new(config, executor.clone()).map(move |service|{ - if is_auth { - if let Ok(Some(Ok(key))) = service.keystore().contents() - .map(|keys| keys.get(0).map(|k| service.keystore().load(k, ""))) - { - info!("Using authority key {}", key.public()); - let task = start_aura( - AuraConfig { - local_key: Some(Arc::new(key)), - slot_duration: AURA_SLOT_DURATION, - }, - service.client(), - service.proposer(), - service.network(), - ); - - executor.spawn(task); - } - } - - service - }) + Configuration = NodeConfig, + FullService = FullComponents + { |config: FactoryFullConfiguration, executor: TaskExecutor| + FullComponents::::new(config, executor) }, + AuthoritySetup = { + |mut service: Self::FullService, executor: TaskExecutor, local_key: Option>| { + let (block_import, link_half) = service.config.custom.grandpa_import_setup.take() + .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); + + if let Some(ref key) = local_key { + info!("Using authority key {}", key.public()); + let proposer = Arc::new(substrate_basic_authorship::ProposerFactory { + client: service.client(), + transaction_pool: service.transaction_pool(), + }); + + let client = service.client(); + executor.spawn(start_aura( + SlotDuration::get_or_compute(&*client)?, + key.clone(), + client, + block_import.clone(), + proposer, + service.network(), + service.on_exit(), + )); + + info!("Running Grandpa session as Authority {}", key.public()); + } + + executor.spawn(grandpa::run_grandpa( + grandpa::Config { + local_key, + gossip_duration: Duration::new(4, 0), // FIXME: make this available through chainspec? + justification_period: 4096, + name: Some(service.config.name.clone()) + }, + link_half, + grandpa::NetworkBridge::new(service.network()), + service.on_exit(), + )?); + + Ok(service) } }, - LightService = Service> - { |config, executor| Service::>::new(config, executor) }, - FullImportQueue = AuraImportQueue> - { |config, client| Ok(import_queue(AuraConfig { - local_key: None, - slot_duration: 5 - }, client)) }, - LightImportQueue = AuraImportQueue> - { |config, client| Ok(import_queue(AuraConfig { - local_key: None, - slot_duration: 5 - }, client)) }, + LightService = LightComponents + { |config, executor| >::new(config, executor) }, + FullImportQueue = AuraImportQueue< + Self::Block, + grandpa::BlockImportForService, + NothingExtra, + ::consensus::InherentProducingFn, + > + { |config: &mut FactoryFullConfiguration , client: Arc>| { + let slot_duration = SlotDuration::get_or_compute(&*client)?; + let (block_import, link_half) = grandpa::block_import::<_, _, _, RuntimeApi, FullClient>(client.clone(), client)?; + let block_import = Arc::new(block_import); + + config.custom.grandpa_import_setup = Some((block_import.clone(), link_half)); + + Ok(import_queue( + slot_duration, + block_import, + NothingExtra, + ::consensus::make_basic_inherent as _, + )) + }}, + LightImportQueue = AuraImportQueue< + Self::Block, + LightClient, + NothingExtra, + ::consensus::InherentProducingFn, + > + { |ref mut config, client: Arc>| + Ok(import_queue( + SlotDuration::get_or_compute(&*client)?, + client, + NothingExtra, + ::consensus::make_basic_inherent as _, + )) + }, } } @@ -104,7 +162,6 @@ mod tests { 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 offline = Arc::new(RwLock::new(OfflineTracker::new())); let dummy_runtime = ::tokio::runtime::Runtime::new().unwrap(); let block_factory = |service: &::FullService| { let block_id = BlockId::number(service.client().info().unwrap().chain.best_number); @@ -114,7 +171,6 @@ mod tests { client: service.client().clone(), transaction_pool: service.transaction_pool().clone(), network: consensus_net, - offline: offline.clone(), force_delay: 0, handle: dummy_runtime.executor(), }; @@ -122,7 +178,7 @@ mod tests { let block = proposer.propose().expect("Error making test block"); ImportBlock { origin: BlockOrigin::File, - external_justification: Vec::new(), + justification: Vec::new(), internal_justification: Vec::new(), finalized: true, body: Some(block.extrinsics), diff --git a/node/executor/Cargo.toml b/node/executor/Cargo.toml index 6cbbb2f11e4feb333b2011f60e32c891f2003e32..4dcb70d7282d77ac178106263caa3a1064ae0a39 100644 --- a/node/executor/Cargo.toml +++ b/node/executor/Cargo.toml @@ -6,8 +6,8 @@ description = "Substrate node implementation in Rust." [dependencies] hex-literal = "0.1" -trie-root = { git = "https://github.com/paritytech/trie" } -parity-codec = "2.1" +trie-root = "0.9" +parity-codec = "2.2" sr-io = { path = "../../core/sr-io" } substrate-state-machine = { path = "../../core/state-machine" } substrate-executor = { path = "../../core/executor" } @@ -28,4 +28,9 @@ srml-consensus = { path = "../../srml/consensus" } srml-timestamp = { path = "../../srml/timestamp" } srml-treasury = { path = "../../srml/treasury" } srml-contract = { path = "../../srml/contract" } -wabt = "0.4" +srml-grandpa = { path = "../../srml/grandpa" } +srml-indices = { path = "../../srml/indices" } +wabt = "~0.7.4" + +[features] +benchmarks = [] diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index fd68aadd51c0c85ea876661ac3e0d8a8918ad2b7..fecb895fc00672d991b1215d81b70db3bab2dd23 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -17,10 +17,14 @@ //! A `CodeExecutor` specialisation which uses natively compiled runtime when the wasm to be //! executed is equivalent to the natively compiled code. +#![cfg_attr(feature = "benchmarks", feature(test))] + extern crate node_runtime; #[macro_use] extern crate substrate_executor; #[cfg_attr(test, macro_use)] extern crate substrate_primitives as primitives; +#[cfg(feature = "benchmarks")] extern crate test; + #[cfg(test)] extern crate substrate_keyring as keyring; #[cfg(test)] extern crate sr_primitives as runtime_primitives; #[cfg(test)] extern crate srml_support as runtime_support; @@ -32,6 +36,8 @@ extern crate node_runtime; #[cfg(test)] extern crate srml_timestamp as timestamp; #[cfg(test)] extern crate srml_treasury as treasury; #[cfg(test)] extern crate srml_contract as contract; +#[cfg(test)] extern crate srml_grandpa as grandpa; +#[cfg(test)] extern crate srml_indices as indices; #[cfg(test)] extern crate node_primitives; #[cfg(test)] extern crate parity_codec as codec; #[cfg(test)] extern crate sr_io as runtime_io; @@ -52,17 +58,18 @@ mod tests { use keyring::Keyring; use runtime_support::{Hashable, StorageValue, StorageMap}; use state_machine::{CodeExecutor, Externalities, TestExternalities}; - use primitives::{twox_128, Blake2Hasher, ChangesTrieConfiguration, - ed25519::{Public, Pair}}; + use primitives::{ + twox_128, Blake2Hasher, ChangesTrieConfiguration, ed25519::{Public, Pair}, NeverNativeValue + }; use node_primitives::{Hash, BlockNumber, AccountId}; - use runtime_primitives::traits::{Header as HeaderT, Digest as DigestT}; + use runtime_primitives::traits::{Header as HeaderT, Digest as DigestT, Hash as HashT}; use runtime_primitives::{generic, generic::Era, ApplyOutcome, ApplyError, ApplyResult, Perbill}; - use {balances, staking, session, system, consensus, timestamp, treasury, contract}; + use {balances, indices, staking, session, system, consensus, timestamp, treasury, contract}; use contract::ContractAddressFor; use system::{EventRecord, Phase}; use node_runtime::{Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage, GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, System, - SystemConfig, Event, Log}; + SystemConfig, GrandpaConfig, IndicesConfig, Event, Log}; use wabt; const BLOATY_CODE: &[u8] = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.wasm"); @@ -85,11 +92,11 @@ mod tests { match xt.signed { Some((signed, index)) => { let era = Era::mortal(256, 0); - let payload = (index, xt.function, era, GENESIS_HASH); + let payload = (index.into(), xt.function, era, GENESIS_HASH); let pair = Pair::from(Keyring::from_public(Public::from_raw(signed.clone().into())).unwrap()); let signature = pair.sign(&payload.encode()).into(); UncheckedExtrinsic { - signature: Some((balances::address::Address::Id(signed), signature, payload.0, era)), + signature: Some((indices::address::Address::Id(signed), signature, payload.0, era)), function: payload.1, } } @@ -103,7 +110,7 @@ mod tests { fn xt() -> UncheckedExtrinsic { sign(CheckedExtrinsic { signed: Some((alice(), 0)), - function: Call::Balances(balances::Call::transfer::(bob().into(), 69.into())), + function: Call::Balances(balances::Call::transfer::(bob().into(), 69)), }) } @@ -117,7 +124,7 @@ mod tests { #[test] fn panic_execution_with_foreign_code_gives_error() { - let mut t = TestExternalities::::new(map![ + let mut t = TestExternalities::::new_with_code(BLOATY_CODE, map![ twox_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![70u8; 16], @@ -125,20 +132,32 @@ mod tests { twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, 8, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_initialise_block", + &vec![].and(&from_block_number(1u64)), + true, + None, + ).0; assert!(r.is_ok()); - let v = executor().call(&mut t, 8, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap(); - let r = ApplyResult::decode(&mut &v[..]).unwrap(); + let v = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + true, + None, + ).0.unwrap(); + let r = ApplyResult::decode(&mut &v.as_encoded()[..]).unwrap(); assert_eq!(r, Err(ApplyError::CantPay)); } #[test] fn bad_extrinsic_with_native_equivalent_code_gives_error() { - let mut t = TestExternalities::::new(map![ + let mut t = TestExternalities::::new_with_code(COMPACT_CODE, map![ twox_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![70u8; 16], @@ -146,20 +165,32 @@ mod tests { twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, 8, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_initialise_block", + &vec![].and(&from_block_number(1u64)), + true, + None, + ).0; assert!(r.is_ok()); - let v = executor().call(&mut t, 8, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0.unwrap(); - let r = ApplyResult::decode(&mut &v[..]).unwrap(); + let v = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + true, + None, + ).0.unwrap(); + let r = ApplyResult::decode(&mut &v.as_encoded()[..]).unwrap(); assert_eq!(r, Err(ApplyError::CantPay)); } #[test] fn successful_execution_with_native_equivalent_code_gives_ok() { - let mut t = TestExternalities::::new(map![ + let mut t = TestExternalities::::new_with_code(COMPACT_CODE, map![ twox_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], @@ -167,13 +198,25 @@ mod tests { twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, 8, COMPACT_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_initialise_block", + &vec![].and(&from_block_number(1u64)), + true, + None, + ).0; assert!(r.is_ok()); - let r = executor().call(&mut t, 8, COMPACT_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + true, + None, + ).0; assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -184,7 +227,7 @@ mod tests { #[test] fn successful_execution_with_foreign_code_gives_ok() { - let mut t = TestExternalities::::new(map![ + let mut t = TestExternalities::::new_with_code(BLOATY_CODE, map![ twox_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], @@ -192,13 +235,25 @@ mod tests { twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let r = executor().call(&mut t, 8, BLOATY_CODE, "initialise_block", &vec![].and(&from_block_number(1u64)), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_initialise_block", + &vec![].and(&from_block_number(1u64)), + true, + None, + ).0; assert!(r.is_ok()); - let r = executor().call(&mut t, 8, BLOATY_CODE, "apply_extrinsic", &vec![].and(&xt()), true).0; + let r = executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "BlockBuilder_apply_extrinsic", + &vec![].and(&xt()), + true, + None, + ).0; assert!(r.is_ok()); runtime_io::with_externalities(&mut t, || { @@ -207,10 +262,10 @@ mod tests { }); } - fn new_test_ext(support_changes_trie: bool) -> TestExternalities { + fn new_test_ext(code: &[u8], support_changes_trie: bool) -> TestExternalities { use keyring::Keyring::*; let three = [3u8; 32].into(); - TestExternalities::new(GenesisConfig { + TestExternalities::new_with_code(code, GenesisConfig { consensus: Some(Default::default()), system: Some(SystemConfig { changes_trie_config: if support_changes_trie { Some(ChangesTrieConfiguration { @@ -219,6 +274,9 @@ mod tests { }) } else { None }, ..Default::default() }), + indices: Some(IndicesConfig { + ids: vec![alice(), charlie()], + }), balances: Some(BalancesConfig { balances: vec![ (alice(), 111), @@ -229,7 +287,6 @@ mod tests { existential_deposit: 0, transfer_fee: 0, creation_fee: 0, - reclaim_rebate: 0, }), session: Some(SessionConfig { session_length: 2, @@ -247,6 +304,7 @@ mod tests { current_offline_slash: 0, current_session_reward: 0, offline_slash_grace: 0, + invulnerables: vec![alice(), bob(), Charlie.to_raw_public().into()], }), democracy: Some(Default::default()), council_seats: Some(Default::default()), @@ -254,15 +312,26 @@ mod tests { timestamp: Some(Default::default()), treasury: Some(Default::default()), contract: Some(Default::default()), - upgrade_key: Some(Default::default()), + sudo: Some(Default::default()), + grandpa: Some(GrandpaConfig { + authorities: vec![ // set these so no GRANDPA events fire when session changes + (Alice.to_raw_public().into(), 1), + (Bob.to_raw_public().into(), 1), + (Charlie.to_raw_public().into(), 1), + ], + }), }.build_storage().unwrap().0) } + fn changes_trie_log(changes_root: Hash) -> Log { + Log::from(system::RawLog::ChangesTrieRoot::(changes_root)) + } + fn construct_block( number: BlockNumber, parent_hash: Hash, state_root: Hash, - changes_root: Option, + logs: Vec, extrinsics: Vec ) -> (Vec, Hash) { use trie::ordered_trie_root; @@ -274,8 +343,8 @@ mod tests { .into(); let mut digest = generic::Digest::::default(); - if let Some(changes_root) = changes_root { - digest.push(Log::from(system::RawLog::ChangesTrieRoot::(changes_root))); + for item in logs { + digest.push(item); } let header = Header { @@ -295,23 +364,25 @@ mod tests { 1, GENESIS_HASH.into(), if support_changes_trie { - hex!("978a3ff733a86638da39d36a349c693b5cf562bcc8db30fec6c2b6c40f925a9b").into() + hex!("cc63808897a07869d3b9103df5ad92f9be2f865ece506df5de0a87b2a95131d5").into() } else { - hex!("7bbad534e3de3db3c8cda015c4e8ed8ba10dde7e3fca21f4fd4fbc686e6c1410").into() + hex!("fe5275f4d9f8130c8e80d0132f0a718ae0eeea2872c841843192720ad5c3f05a").into() }, if support_changes_trie { - Some(hex!("1f8f44dcae8982350c14dee720d34b147e73279f5a2ce1f9781195a991970978").into()) + vec![changes_trie_log( + hex!("f254b62df0bfef049e010a7a0d6f176d73cc5d9710fa945b4e48f519c8d3a291").into(), + )] } else { - None + vec![] }, vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(42.into())), + function: Call::Timestamp(timestamp::Call::set(42)), }, CheckedExtrinsic { signed: Some((alice(), 0)), - function: Call::Balances(balances::Call::transfer(bob().into(), 69.into())), + function: Call::Balances(balances::Call::transfer(bob().into(), 69)), }, ] ) @@ -321,20 +392,26 @@ mod tests { construct_block( 2, block1(false).1, - hex!("7be30152ee2ee909047cffad5f0a28bf8c2b0a97c124b500aeac112f6917738e").into(), - None, + hex!("45b6655508fb524467b5c24184a7509b9ae07db4f95e16052ed425af182f39a8").into(), + vec![ // session changes here, so we add a grandpa change signal log. + Log::from(::grandpa::RawLog::AuthoritiesChangeSignal(0, vec![ + (Keyring::One.to_raw_public().into(), 1), + (Keyring::Two.to_raw_public().into(), 1), + ([3u8; 32].into(), 1), + ])) + ], vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(52.into())), + function: Call::Timestamp(timestamp::Call::set(52)), }, CheckedExtrinsic { signed: Some((bob(), 0)), - function: Call::Balances(balances::Call::transfer(alice().into(), 5.into())), + function: Call::Balances(balances::Call::transfer(alice().into(), 5)), }, CheckedExtrinsic { signed: Some((alice(), 1)), - function: Call::Balances(balances::Call::transfer(bob().into(), 15.into())), + function: Call::Balances(balances::Call::transfer(bob().into(), 15)), } ] ) @@ -344,12 +421,12 @@ mod tests { construct_block( 1, GENESIS_HASH.into(), - hex!("325a73726dc640af41becb42938e7152e218f130219c0695aae35b6a156f93f3").into(), - None, + hex!("ec00658cc2826d3499dde2954e399f0a0b2596eec1b0da9b76bc72394161dc99").into(), + vec![], vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(42.into())), + function: Call::Timestamp(timestamp::Call::set(42)), }, CheckedExtrinsic { signed: Some((alice(), 0)), @@ -361,9 +438,15 @@ mod tests { #[test] fn full_native_block_import_works() { - let mut t = new_test_ext(false); + let mut t = new_test_ext(COMPACT_CODE, false); - executor().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1(false).0, true).0.unwrap(); + executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_execute_block", + &block1(false).0, + true, + None, + ).0.unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 41); @@ -375,7 +458,14 @@ mod tests { }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::balances(balances::RawEvent::NewAccount(bob(), 2, balances::NewAccountOutcome::NoHint)) + event: Event::indices(indices::RawEvent::NewAccountIndex(bob(), 2)) + }, + EventRecord { + phase: Phase::ApplyExtrinsic(1), + event: Event::balances(balances::RawEvent::NewAccount( + hex!["d7568e5f0a7eda67a82691ff379ac4bba4f9c9b859fe779b5d46363b61ad2db9"].into(), + 69 + )) }, EventRecord { phase: Phase::ApplyExtrinsic(1), @@ -405,7 +495,13 @@ mod tests { ]); }); - executor().call(&mut t, 8, COMPACT_CODE, "execute_block", &block2().0, true).0.unwrap(); + executor().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_execute_block", + &block2().0, + true, + None, + ).0.unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 30); @@ -453,6 +549,14 @@ mod tests { phase: Phase::Finalization, event: Event::staking(staking::RawEvent::Reward(0)) }, + EventRecord { + phase: Phase::Finalization, + event: Event::grandpa(::grandpa::RawEvent::NewAuthorities(vec![ + (Keyring::One.to_raw_public().into(), 1), + (Keyring::Two.to_raw_public().into(), 1), + ([3u8; 32].into(), 1), + ])), + }, EventRecord { phase: Phase::Finalization, event: Event::treasury(treasury::RawEvent::Spending(0)) @@ -471,16 +575,16 @@ mod tests { #[test] fn full_wasm_block_import_works() { - let mut t = new_test_ext(false); + let mut t = new_test_ext(COMPACT_CODE, false); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1(false).0).unwrap(); + WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1(false).0).unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 41); assert_eq!(Balances::total_balance(&bob()), 69); }); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block2().0).unwrap(); + WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block2().0).unwrap(); runtime_io::with_externalities(&mut t, || { assert_eq!(Balances::total_balance(&alice()), 30); @@ -503,6 +607,8 @@ mod tests { (import "env" "ext_input_size" (func $ext_input_size (result i32))) (import "env" "ext_input_copy" (func $ext_input_copy (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) + (func (export "deploy") + ) (func (export "call") (block $fail ;; fail if ext_input_size != 4 @@ -570,55 +676,15 @@ mod tests { ) "#; - /// Convert a byte slice to a string with hex values. - /// Convert a byte slice to a string with hex values. - /// - /// Each value is preceeded with a `\` character. - fn escaped_bytestring(bytes: &[u8]) -> String { - use std::fmt::Write; - let mut result = String::new(); - for b in bytes { - write!(result, "\\{:02x}", b).unwrap(); - } - result - } - - /// Create a constructor for the specified code. - /// - /// When constructor is executed, it will call `ext_return` with code that - /// specified in `child_bytecode`. - fn code_ctor(child_bytecode: &[u8]) -> String { - format!( - r#" - (module - ;; ext_return(data_ptr: u32, data_len: u32) -> ! - (import "env" "ext_return" (func $ext_return (param i32 i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (call $ext_return - (i32.const 4) - (i32.const {code_len}) - ) - ;; ext_return is diverging, i.e. doesn't return. - unreachable - ) - (data (i32.const 4) "{escaped_bytecode}") - ) - "#, - escaped_bytecode = escaped_bytestring(child_bytecode), - code_len = child_bytecode.len(), - ) - } - #[test] fn deploying_wasm_contract_should_work() { - let mut t = new_test_ext(false); + let mut t = new_test_ext(COMPACT_CODE, false); - let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap(); - let code_ctor_transfer = wabt::wat2wasm(&code_ctor(&code_transfer)).unwrap(); + let transfer_code = wabt::wat2wasm(CODE_TRANSFER).unwrap(); + let transfer_ch = ::Hashing::hash(&transfer_code); let addr = ::DetermineContractAddress::contract_address_for( - &code_ctor_transfer, + &transfer_ch, &[], &charlie(), ); @@ -626,63 +692,89 @@ mod tests { let b = construct_block( 1, GENESIS_HASH.into(), - hex!("cf0fee74c87ecff646804984bbdf85832a788b3ca2a2aa33e20da61fa7182b37").into(), - None, + hex!("6a4da4ed61c4d9eba0477aa67024d573693df781176dfe7fe903d1088b38b266").into(), + vec![], vec![ CheckedExtrinsic { signed: None, - function: Call::Timestamp(timestamp::Call::set(42.into())), + function: Call::Timestamp(timestamp::Call::set(42)), }, CheckedExtrinsic { signed: Some((charlie(), 0)), function: Call::Contract( - contract::Call::create::(10.into(), 10_000.into(), code_ctor_transfer, Vec::new()) + contract::Call::put_code::(10_000, transfer_code) ), }, CheckedExtrinsic { signed: Some((charlie(), 1)), function: Call::Contract( - contract::Call::call::(addr, 10.into(), 10_000.into(), vec![0x00, 0x01, 0x02, 0x03]) + contract::Call::create::(10, 10_000, transfer_ch, Vec::new()) + ), + }, + CheckedExtrinsic { + signed: Some((charlie(), 2)), + function: Call::Contract( + contract::Call::call::(indices::address::Address::Id(addr), 10, 10_000, vec![0x00, 0x01, 0x02, 0x03]) ), }, ] ); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &b.0).unwrap(); + WasmExecutor::new().call(&mut t, 8, COMPACT_CODE,"Core_execute_block", &b.0).unwrap(); runtime_io::with_externalities(&mut t, || { // Verify that the contract constructor worked well and code of TRANSFER contract is actually deployed. - assert_eq!(&contract::CodeOf::::get(addr), &code_transfer); + assert_eq!(&contract::CodeHashOf::::get(addr).unwrap(), &transfer_ch); }); } #[test] fn wasm_big_block_import_fails() { - let mut t = new_test_ext(false); - - let r = WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0); - assert!(!r.is_ok()); + let mut t = new_test_ext(COMPACT_CODE, false); + + assert!( + WasmExecutor::new().call( + &mut t, + 8, + COMPACT_CODE, + "Core_execute_block", + &block1big().0 + ).is_err() + ); } #[test] fn native_big_block_import_succeeds() { - let mut t = new_test_ext(false); + let mut t = new_test_ext(COMPACT_CODE, false); - let r = Executor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0, true).0; - assert!(r.is_ok()); + Executor::new().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_execute_block", + &block1big().0, + true, + None, + ).0.unwrap(); } #[test] fn native_big_block_import_fails_on_fallback() { - let mut t = new_test_ext(false); - - let r = Executor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1big().0, false).0; - assert!(!r.is_ok()); + let mut t = new_test_ext(COMPACT_CODE, false); + + assert!( + Executor::new().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_execute_block", + &block1big().0, + false, + None, + ).0.is_err() + ); } #[test] fn panic_execution_gives_error() { - let mut t = TestExternalities::::new(map![ + let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.wasm"); + let mut t = TestExternalities::::new_with_code(foreign_code, map![ twox_128(&>::key_for(alice())).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![69u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![70u8; 16], @@ -690,21 +782,21 @@ mod tests { twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.wasm"); - let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64))); + let r = WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_initialise_block", &vec![].and(&from_block_number(1u64))); assert!(r.is_ok()); - let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap(); + let r = WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).unwrap(); let r = ApplyResult::decode(&mut &r[..]).unwrap(); assert_eq!(r, Err(ApplyError::CantPay)); } #[test] fn successful_execution_gives_ok() { - let mut t = TestExternalities::::new(map![ + let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm"); + let mut t = TestExternalities::::new_with_code(foreign_code, map![ twox_128(&>::key_for(alice())).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], twox_128(>::key()).to_vec() => vec![0u8; 16], @@ -712,14 +804,13 @@ mod tests { twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(>::key()).to_vec() => vec![0u8; 16], - twox_128(>::key()).to_vec() => vec![0u8; 16], + twox_128(>::key()).to_vec() => vec![0u8; 16], twox_128(&>::key_for(0)).to_vec() => vec![0u8; 32] ]); - let foreign_code = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm"); - let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "initialise_block", &vec![].and(&from_block_number(1u64))); + let r = WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_initialise_block", &vec![].and(&from_block_number(1u64))); assert!(r.is_ok()); - let r = WasmExecutor::new().call(&mut t, 8, &foreign_code[..], "apply_extrinsic", &vec![].and(&xt())).unwrap(); + let r = WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "BlockBuilder_apply_extrinsic", &vec![].and(&xt())).unwrap(); let r = ApplyResult::decode(&mut &r[..]).unwrap(); assert_eq!(r, Ok(ApplyOutcome::Success)); @@ -731,17 +822,38 @@ mod tests { #[test] fn full_native_block_import_works_with_changes_trie() { - let mut t = new_test_ext(true); - Executor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1(true).0, true).0.unwrap(); + let mut t = new_test_ext(COMPACT_CODE, true); + Executor::new().call::<_, NeverNativeValue, fn() -> NeverNativeValue>( + &mut t, + "Core_execute_block", + &block1(true).0, + true, + None, + ).0.unwrap(); - assert!(t.storage_changes_root(1).is_some()); + assert!(t.storage_changes_root(Default::default(), 0).is_some()); } #[test] fn full_wasm_block_import_works_with_changes_trie() { - let mut t = new_test_ext(true); - WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "execute_block", &block1(true).0).unwrap(); + let mut t = new_test_ext(COMPACT_CODE, true); + WasmExecutor::new().call(&mut t, 8, COMPACT_CODE, "Core_execute_block", &block1(true).0).unwrap(); - assert!(t.storage_changes_root(1).is_some()); + assert!(t.storage_changes_root(Default::default(), 0).is_some()); + } + + #[cfg(feature = "benchmarks")] + mod benches { + use super::*; + use test::Bencher; + + #[bench] + fn wasm_execute_block(b: &mut Bencher) { + b.iter(|| { + let mut t = new_test_ext(COMPACT_CODE, false); + WasmExecutor::new().call(&mut t, "Core_execute_block", &block1(false).0).unwrap(); + WasmExecutor::new().call(&mut t, "Core_execute_block", &block2().0).unwrap(); + }); + } } } diff --git a/node/primitives/Cargo.toml b/node/primitives/Cargo.toml index a28714f6ee040dee93235b8462a3512e741f56c7..bb9921f704741f8e5336625470606886f2c157f0 100644 --- a/node/primitives/Cargo.toml +++ b/node/primitives/Cargo.toml @@ -6,7 +6,7 @@ authors = ["Parity Technologies "] [dependencies] serde = { version = "1.0", default-features = false } serde_derive = { version = "1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index 2e436e31de55aad988c16f71fcba68f181531fcb..504ac5db953dc9a59741a800b175c2607b0ae221 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -22,21 +22,18 @@ #![cfg_attr(not(feature = "std"), feature(alloc))] #[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; +extern crate serde; -#[macro_use] -extern crate parity_codec_derive; +extern crate parity_codec as codec; extern crate sr_std as rstd; extern crate sr_primitives as runtime_primitives; extern crate substrate_primitives as primitives; -use rstd::prelude::*; use runtime_primitives::generic; -#[cfg(feature = "std")] -use primitives::bytes; -use runtime_primitives::traits::{BlakeTwo256, self}; +use runtime_primitives::{OpaqueExtrinsic, traits::BlakeTwo256}; + +pub use runtime_primitives::BasicInherentData as InherentData; /// An index to a block. pub type BlockNumber = u64; @@ -54,7 +51,7 @@ pub type Balance = u128; /// The Ed25519 pub key of an session that belongs to an authority of the chain. This is /// exactly equivalent to what the substrate calls an "authority". -pub type SessionKey = primitives::AuthorityId; +pub type SessionKey = primitives::Ed25519AuthorityId; /// Index of a transaction in the chain. pub type Index = u64; @@ -76,12 +73,4 @@ pub type Block = generic::Block; pub type BlockId = generic::BlockId; /// Opaque, encoded, unchecked extrinsic. -#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -pub struct UncheckedExtrinsic(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); - -impl traits::Extrinsic for UncheckedExtrinsic { - fn is_signed(&self) -> Option { - None - } -} +pub type UncheckedExtrinsic = OpaqueExtrinsic; diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index 6c86355b255ebb6acea9699e0b9b0bfeb782865f..ad644fa3a37eb6b02f7a21053c9f6fe4be3af6ad 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -4,41 +4,46 @@ version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -rustc-hex = "1.0" -hex-literal = "0.1.0" -serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } +integer-sqrt = { version = "0.1.2" } safe-mix = { version = "1.0", default-features = false } -parity-codec = "2.1" -parity-codec-derive = "2.1" -sr-api = { path = "../../core/sr-api", default-features = false } -sr-std = { path = "../../core/sr-std" } -srml-support = { path = "../../srml/support" } -substrate-primitives = { path = "../../core/primitives" } -substrate-keyring = { path = "../../core/keyring" } -srml-balances = { path = "../../srml/balances" } -srml-consensus = { path = "../../srml/consensus" } -srml-contract = { path = "../../srml/contract" } -srml-council = { path = "../../srml/council" } -srml-democracy = { path = "../../srml/democracy" } -srml-executive = { path = "../../srml/executive" } -sr-primitives = { path = "../../core/sr-primitives" } -srml-session = { path = "../../srml/session" } -srml-staking = { path = "../../srml/staking" } -srml-system = { path = "../../srml/system" } -srml-timestamp = { path = "../../srml/timestamp" } -srml-treasury = { path = "../../srml/treasury" } -srml-upgrade-key = { path = "../../srml/upgrade-key" } -sr-version = { path = "../../core/sr-version" } -node-primitives = { path = "../primitives" } +parity-codec-derive = { version = "2.1" } +parity-codec = { version = "2.2", default-features = false } +substrate-primitives = { path = "../../core/primitives", default-features = false } +substrate-client = { path = "../../core/client", default-features = false } +sr-std = { path = "../../core/sr-std", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +sr-version = { path = "../../core/sr-version", default-features = false } +srml-support = { path = "../../srml/support", default-features = false } +srml-aura = { path = "../../srml/aura", default-features = false } +srml-balances = { path = "../../srml/balances", default-features = false } +srml-consensus = { path = "../../srml/consensus", default-features = false } +srml-contract = { path = "../../srml/contract", default-features = false } +srml-council = { path = "../../srml/council", default-features = false } +srml-democracy = { path = "../../srml/democracy", default-features = false } +srml-executive = { path = "../../srml/executive", default-features = false } +srml-grandpa = { path = "../../srml/grandpa", default-features = false } +srml-indices = { path = "../../srml/indices", default-features = false } +srml-session = { path = "../../srml/session", default-features = false } +srml-staking = { path = "../../srml/staking", default-features = false } +srml-system = { path = "../../srml/system", default-features = false } +srml-timestamp = { path = "../../srml/timestamp", default-features = false } +srml-treasury = { path = "../../srml/treasury", default-features = false } +srml-sudo = { path = "../../srml/sudo", default-features = false } +srml-upgrade-key = { path = "../../srml/upgrade-key", default-features = false } +node-primitives = { path = "../primitives", default-features = false } +substrate-consensus-aura-primitives = { path = "../../core/consensus/aura/primitives", default-features = false } +rustc-hex = { version = "1.0", optional = true } +hex-literal = { version = "0.1.0", optional = true } +serde = { version = "1.0", optional = true } +substrate-keyring = { path = "../../core/keyring", optional = true } [features] default = ["std"] std = [ "parity-codec/std", "substrate-primitives/std", - "sr-api/std", "sr-std/std", + "sr-primitives/std", "srml-support/std", "srml-balances/std", "srml-consensus/std", @@ -46,16 +51,23 @@ std = [ "srml-council/std", "srml-democracy/std", "srml-executive/std", - "sr-primitives/std", + "srml-grandpa/std", + "srml-indices/std", "srml-session/std", "srml-staking/std", "srml-system/std", "srml-timestamp/std", "srml-treasury/std", + "srml-sudo/std", "srml-upgrade-key/std", "sr-version/std", "node-primitives/std", - "serde_derive", "serde/std", - "safe-mix/std" + "safe-mix/std", + "substrate-client/std", + "substrate-consensus-aura-primitives/std", + "rustc-hex", + "hex-literal", + "serde", + "substrate-keyring", ] diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index d1afc82c4408ac3a8dce2969025bcb015d51f927..ed8bae6968ab847a322b984c063f870eb1e81fa8 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -20,58 +20,67 @@ // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit="256"] -#[macro_use] -extern crate sr_api as runtime_api; - #[macro_use] extern crate srml_support; #[macro_use] extern crate sr_primitives as runtime_primitives; -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - extern crate substrate_primitives; +#[macro_use] +extern crate substrate_client as client; + #[macro_use] extern crate parity_codec_derive; +extern crate parity_codec as codec; + extern crate sr_std as rstd; +extern crate srml_aura as aura; extern crate srml_balances as balances; extern crate srml_consensus as consensus; extern crate srml_contract as contract; extern crate srml_council as council; extern crate srml_democracy as democracy; extern crate srml_executive as executive; +extern crate srml_grandpa as grandpa; +extern crate srml_indices as indices; extern crate srml_session as session; extern crate srml_staking as staking; +extern crate srml_sudo as sudo; extern crate srml_system as system; extern crate srml_timestamp as timestamp; extern crate srml_treasury as treasury; -extern crate srml_upgrade_key as upgrade_key; #[macro_use] extern crate sr_version as version; extern crate node_primitives; +extern crate substrate_consensus_aura_primitives as consensus_aura; use rstd::prelude::*; use substrate_primitives::u32_trait::{_2, _4}; use node_primitives::{ - AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, - SessionKey, Signature + AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, SessionKey, Signature }; -use runtime_api::{runtime::*, id::*}; -use runtime_primitives::ApplyResult; +use grandpa::fg_primitives::{self, ScheduledChange}; +use client::{ + block_builder::api as block_builder_api, runtime_api as client_api +}; +use runtime_primitives::{ApplyResult, CheckInherentError, BasicInherentData}; use runtime_primitives::transaction_validity::TransactionValidity; use runtime_primitives::generic; -use runtime_primitives::traits::{Convert, BlakeTwo256, Block as BlockT}; +use runtime_primitives::traits::{ + Convert, BlakeTwo256, Block as BlockT, DigestFor, NumberFor, ProvideInherent, + StaticLookup +}; use version::RuntimeVersion; use council::{motions as council_motions, voting as council_voting}; #[cfg(feature = "std")] use council::seats as council_seats; #[cfg(any(feature = "std", test))] use version::NativeVersion; +use substrate_primitives::OpaqueMetadata; +use consensus_aura::api as aura_api; #[cfg(any(feature = "std", test))] pub use runtime_primitives::BuildStorage; @@ -79,7 +88,6 @@ pub use consensus::Call as ConsensusCall; pub use timestamp::Call as TimestampCall; pub use balances::Call as BalancesCall; pub use runtime_primitives::{Permill, Perbill}; -pub use timestamp::BlockPeriod; pub use srml_support::{StorageValue, RuntimeMetadata}; const TIMESTAMP_SET_POSITION: u32 = 0; @@ -87,16 +95,12 @@ const NOTE_OFFLINE_POSITION: u32 = 1; /// Runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: ver_str!("node"), - impl_name: ver_str!("substrate-node"), - authoring_version: 1, - spec_version: 1, - impl_version: 0, - apis: apis_vec!([ - (BLOCK_BUILDER, 1), - (TAGGED_TRANSACTION_QUEUE, 1), - (METADATA, 1) - ]), + spec_name: create_runtime_str!("node"), + impl_name: create_runtime_str!("substrate-node"), + authoring_version: 10, + spec_version: 16, + impl_version: 16, + apis: RUNTIME_API_VERSIONS, }; /// Native version. @@ -116,16 +120,28 @@ impl system::Trait for Runtime { type Hashing = BlakeTwo256; type Digest = generic::Digest; type AccountId = AccountId; + type Lookup = Indices; type Header = generic::Header; type Event = Event; type Log = Log; } +impl aura::Trait for Runtime { + type HandleReport = aura::StakingSlasher; +} + +impl indices::Trait for Runtime { + type AccountIndex = AccountIndex; + type IsDeadAccount = Balances; + type ResolveHint = indices::SimpleResolveHint; + type Event = Event; +} + impl balances::Trait for Runtime { type Balance = Balance; - type AccountIndex = AccountIndex; - type OnFreeBalanceZero = (Staking, Contract); - type EnsureAccountLiquid = Staking; + type OnFreeBalanceZero = ((Staking, Contract), Democracy); + type OnNewAccount = Indices; + type EnsureAccountLiquid = (Staking, Democracy); type Event = Event; } @@ -133,12 +149,16 @@ impl consensus::Trait for Runtime { const NOTE_OFFLINE_POSITION: u32 = NOTE_OFFLINE_POSITION; type Log = Log; type SessionKey = SessionKey; - type OnOfflineValidator = Staking; + + // the aura module handles offline-reports internally + // rather than using an explicit report system. + type InherentOfflineReport = (); } impl timestamp::Trait for Runtime { const TIMESTAMP_SET_POSITION: u32 = TIMESTAMP_SET_POSITION; type Moment = u64; + type OnTimestampSet = Aura; } /// Session key conversion. @@ -151,7 +171,7 @@ impl Convert for SessionKeyConversion { impl session::Trait for Runtime { type ConvertAccountIdToSessionKey = SessionKeyConversion; - type OnSessionChange = Staking; + type OnSessionChange = (Staking, grandpa::SyncedAuthorities); type Event = Event; } @@ -186,23 +206,35 @@ impl treasury::Trait for Runtime { } impl contract::Trait for Runtime { + type Call = Call; + type Event = Event; type Gas = u64; type DetermineContractAddress = contract::SimpleAddressDeterminator; + type ComputeDispatchFee = contract::DefaultDispatchFeeComputor; +} + +impl sudo::Trait for Runtime { type Event = Event; + type Proposal = Call; } -impl upgrade_key::Trait for Runtime { +impl grandpa::Trait for Runtime { + type SessionKey = SessionKey; + type Log = Log; type Event = Event; } construct_runtime!( pub enum Runtime with Log(InternalLog: DigestItem) where Block = Block, - UncheckedExtrinsic = UncheckedExtrinsic + NodeBlock = node_primitives::Block, + InherentData = BasicInherentData { System: system::{default, Log(ChangesTrieRoot)}, + Aura: aura::{Module}, Timestamp: timestamp::{Module, Call, Storage, Config, Inherent}, Consensus: consensus::{Module, Call, Storage, Config, Log(AuthoritiesChange), Inherent}, + Indices: indices, Balances: balances, Session: session, Staking: staking, @@ -211,33 +243,32 @@ construct_runtime!( CouncilVoting: council_voting, CouncilMotions: council_motions::{Module, Call, Storage, Event, Origin}, CouncilSeats: council_seats::{Config}, + Grandpa: grandpa::{Module, Call, Storage, Config, Log(), Event}, Treasury: treasury, Contract: contract::{Module, Call, Config, Event}, - UpgradeKey: upgrade_key, + Sudo: sudo, } ); /// The address format for describing accounts. -pub use balances::address::Address as RawAddress; -/// The address format for describing accounts. -pub type Address = balances::Address; +pub type Address = ::Source; /// Block header type as expected by this runtime. pub type Header = generic::Header; /// Block type as expected by this runtime. pub type Block = generic::Block; /// A Block signed with a Justification -pub type SignedBlock = generic::SignedBlock; +pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; /// Unchecked extrinsic type as expected by this runtime. -pub type UncheckedExtrinsic = generic::UncheckedMortalExtrinsic; +pub type UncheckedExtrinsic = generic::UncheckedMortalCompactExtrinsic; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. -pub type Executive = executive::Executive, Balances, AllModules>; +pub type Executive = executive::Executive, Balances, AllModules>; -impl_apis! { - impl Core for Runtime { +impl_runtime_apis! { + impl client_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION } @@ -249,19 +280,19 @@ impl_apis! { fn execute_block(block: Block) { Executive::execute_block(block) } - } - impl Metadata for Runtime { - fn metadata() -> RuntimeMetadata { - Runtime::metadata() + fn initialise_block(header: &::Header) { + Executive::initialise_block(header) } } - impl BlockBuilder for Runtime { - fn initialise_block(header: ::Header) { - Executive::initialise_block(&header) + impl client_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + Runtime::metadata().into() } + } + impl block_builder_api::BlockBuilder for Runtime { fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyResult { Executive::apply_extrinsic(extrinsic) } @@ -270,12 +301,46 @@ impl_apis! { Executive::finalise_block() } - fn inherent_extrinsics(data: InherentData) -> Vec { - data.create_inherent_extrinsics() + fn inherent_extrinsics(data: BasicInherentData) -> Vec<::Extrinsic> { + let mut inherent = Vec::new(); + + inherent.extend( + Timestamp::create_inherent_extrinsics(data.timestamp) + .into_iter() + .map(|v| (v.0, UncheckedExtrinsic::new_unsigned(Call::Timestamp(v.1)))) + ); + + inherent.extend( + Consensus::create_inherent_extrinsics(data.consensus) + .into_iter() + .map(|v| (v.0, UncheckedExtrinsic::new_unsigned(Call::Consensus(v.1)))) + ); + + inherent.as_mut_slice().sort_unstable_by_key(|v| v.0); + inherent.into_iter().map(|v| v.1).collect() } - fn check_inherents(block: Block, data: InherentData) -> Result<(), InherentError> { - data.check_inherents(block) + fn check_inherents(block: Block, data: BasicInherentData) -> Result<(), CheckInherentError> { + let expected_slot = data.aura_expected_slot; + + // draw timestamp out from extrinsics. + let set_timestamp = block.extrinsics() + .get(TIMESTAMP_SET_POSITION as usize) + .and_then(|xt: &UncheckedExtrinsic| match xt.function { + Call::Timestamp(TimestampCall::set(ref t)) => Some(t.clone()), + _ => None, + }) + .ok_or_else(|| CheckInherentError::Other("No valid timestamp in block.".into()))?; + + // take the "worse" result of normal verification and the timestamp vs. seal + // check. + CheckInherentError::combine_results( + Runtime::check_inherents(block, data), + || { + Aura::verify_inherent(set_timestamp.into(), expected_slot) + .map_err(|s| CheckInherentError::Other(s.into())) + }, + ) } fn random_seed() -> ::Hash { @@ -283,9 +348,35 @@ impl_apis! { } } - impl TaggedTransactionQueue for Runtime { + impl client_api::TaggedTransactionQueue for Runtime { fn validate_transaction(tx: ::Extrinsic) -> TransactionValidity { Executive::validate_transaction(tx) } } + + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_pending_change(digest: &DigestFor) + -> Option>> + { + for log in digest.logs.iter().filter_map(|l| match l { + Log(InternalLog::grandpa(grandpa_signal)) => Some(grandpa_signal), + _=> None + }) { + if let Some(change) = Grandpa::scrape_digest_change(log) { + return Some(change); + } + } + None + } + + fn grandpa_authorities() -> Vec<(SessionKey, u64)> { + Grandpa::grandpa_authorities() + } + } + + impl aura_api::AuraApi for Runtime { + fn slot_duration() -> u64 { + Aura::slot_duration() + } + } } diff --git a/node/runtime/wasm/Cargo.lock b/node/runtime/wasm/Cargo.lock index 0a1450a40733134fde86d65514a797fdf3c1e706..a373a8d7d1e4f9907de6edab35273c83136d9795 100644 --- a/node/runtime/wasm/Cargo.lock +++ b/node/runtime/wasm/Cargo.lock @@ -1,9 +1,30 @@ [[package]] name = "arrayvec" -version = "0.4.7" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -21,19 +42,43 @@ name = "blake2-rfc" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "byteorder" -version = "1.2.6" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bytes" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cc" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" -version = "0.1.5" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "chrono" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "cloudabi" @@ -48,35 +93,39 @@ name = "constant_time_eq" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "crossbeam" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "crossbeam-deque" -version = "0.2.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-epoch" -version = "0.3.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-utils" -version = "0.2.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -102,19 +151,45 @@ name = "environmental" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "error-chain" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fixed-hash" -version = "0.3.0-beta.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fnv" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -130,19 +205,19 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "gcc" -version = "0.3.54" +name = "futures" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hash-db" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" [[package]] name = "hash256-std-hasher" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" dependencies = [ "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -172,11 +247,75 @@ dependencies = [ "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "httparse" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "idna" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "impl-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "impl-serde" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "integer-sqrt" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "iovec" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "itoa" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kvdb" +version = "0.1.0" +source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" +dependencies = [ + "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", +] + [[package]] name = "lazy_static" version = "0.2.11" @@ -184,51 +323,67 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "1.1.0" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazycell" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "libc" -version = "0.2.43" +version = "0.2.44" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lock_api" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "mashup" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "mashup-impl 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mashup-impl 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "mashup-impl" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "matches" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "memoffset" version = "0.2.1" @@ -237,7 +392,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memory-db" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" dependencies = [ "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -249,18 +404,73 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "nan-preserving-float" -version = "0.1.0" +name = "mio" +version = "0.6.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-extras" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-uds" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "net2" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "node-primitives" version = "0.1.0" dependencies = [ - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 0.1.0", "sr-std 0.1.0", "substrate-primitives 0.1.0", @@ -270,35 +480,59 @@ dependencies = [ name = "node-runtime" version = "0.1.0" dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 0.1.0", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-api 0.1.0", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-primitives 0.1.0", "sr-std 0.1.0", "sr-version 0.1.0", + "srml-aura 0.1.0", "srml-balances 0.1.0", "srml-consensus 0.1.0", "srml-contract 0.1.0", "srml-council 0.1.0", "srml-democracy 0.1.0", "srml-executive 0.1.0", + "srml-grandpa 0.1.0", + "srml-indices 0.1.0", "srml-session 0.1.0", "srml-staking 0.1.0", + "srml-sudo 0.1.0", "srml-support 0.1.0", "srml-system 0.1.0", "srml-timestamp 0.1.0", "srml-treasury 0.1.0", "srml-upgrade-key 0.1.0", + "substrate-client 0.1.0", + "substrate-consensus-aura-primitives 0.1.0", + "substrate-keyring 0.1.0", "substrate-primitives 0.1.0", ] +[[package]] +name = "node-runtime-wasm" +version = "0.1.0" +dependencies = [ + "node-runtime 0.1.0", +] + [[package]] name = "nodrop" -version = "0.1.12" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num-integer" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "num-traits" @@ -310,24 +544,58 @@ name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "once_cell" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "openssl" +version = "0.10.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "openssl-sys" +version = "0.9.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "owning_ref" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parity-bytes" +version = "0.1.0" +source = "git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d#b0317f649ab2c665b7987b8475878fc4d2e1f81d" + [[package]] name = "parity-codec" -version = "2.1.5" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -335,8 +603,8 @@ name = "parity-codec-derive" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -345,29 +613,73 @@ name = "parity-wasm" version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parking_lot" -version = "0.4.8" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parking_lot_core" -version = "0.2.14" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "percent-encoding" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pkg-config" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "primitive-types" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro-hack" version = "0.4.1" @@ -383,7 +695,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "proc-macro2" -version = "0.4.19" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -391,20 +703,20 @@ dependencies = [ [[package]] name = "pwasm-utils" -version = "0.3.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quote" -version = "0.6.8" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -413,7 +725,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -424,117 +736,241 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rand_core" -version = "0.2.1" +name = "rand" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "rayon" -version = "0.8.2" +name = "rand_chacha" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rayon-core" -version = "1.4.1" +name = "rand_core" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "ring" -version = "0.12.1" +name = "rand_core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand_hc" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rustc-hex" -version = "2.0.1" +name = "rand_isaac" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "rustc_version" -version = "0.2.3" +name = "rand_pcg" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "safe-mix" -version = "1.0.0" +name = "rand_xorshift" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "scopeguard" -version = "0.3.3" +name = "redox_syscall" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "semver" -version = "0.9.0" +name = "ring" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "semver-parser" -version = "0.7.0" +name = "rustc-demangle" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "serde" -version = "1.0.79" +name = "rustc-hex" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "serde_derive" -version = "1.0.79" +name = "rustc-hex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ryu" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "safe-mix" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "semver" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.6 (registry+https://github.com/rust-lang/crates.io-index)", + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde_derive" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slab" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slog" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slog-async" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "slog-json" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "slog-scope" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "smallvec" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "sr-api" +name = "sr-api-macros" version = "0.1.0" dependencies = [ - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sr-primitives 0.1.0", - "sr-std 0.1.0", - "sr-version 0.1.0", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -543,7 +979,7 @@ version = "0.1.0" dependencies = [ "environmental 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 0.1.0", "substrate-primitives 0.1.0", @@ -556,12 +992,12 @@ name = "sr-primitives" version = "0.1.0" dependencies = [ "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-std 0.1.0", "substrate-primitives 0.1.0", @@ -571,11 +1007,11 @@ dependencies = [ name = "sr-sandbox" version = "0.1.0" dependencies = [ - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 0.1.0", "substrate-primitives 0.1.0", - "wasmi 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -589,12 +1025,32 @@ dependencies = [ name = "sr-version" version = "0.1.0" dependencies = [ - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "sr-std 0.1.0", +] + +[[package]] +name = "srml-aura" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", + "srml-consensus 0.1.0", + "srml-staking 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "srml-timestamp 0.1.0", + "substrate-primitives 0.1.0", ] [[package]] @@ -602,11 +1058,10 @@ name = "srml-balances" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", @@ -621,10 +1076,9 @@ name = "srml-consensus" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", @@ -637,12 +1091,11 @@ dependencies = [ name = "srml-contract" version = "0.1.0" dependencies = [ - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", - "pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-sandbox 0.1.0", @@ -658,11 +1111,10 @@ name = "srml-council" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", @@ -678,11 +1130,10 @@ name = "srml-democracy" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", @@ -697,15 +1148,63 @@ name = "srml-executive" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", +] + +[[package]] +name = "srml-grandpa" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-session 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "substrate-finality-grandpa-primitives 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-indices" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", "srml-support 0.1.0", "srml-system 0.1.0", + "substrate-keyring 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-metadata" +version = "0.1.0" +dependencies = [ + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 0.1.0", + "substrate-primitives 0.1.0", ] [[package]] @@ -713,11 +1212,10 @@ name = "srml-session" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", @@ -733,11 +1231,10 @@ name = "srml-staking" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", @@ -751,19 +1248,68 @@ dependencies = [ "substrate-primitives 0.1.0", ] +[[package]] +name = "srml-sudo" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-support 0.1.0", + "srml-support-procedural 0.1.0", + "srml-system 0.1.0", + "substrate-primitives 0.1.0", +] + [[package]] name = "srml-support" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mashup 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", - "substrate-metadata 0.1.0", + "srml-metadata 0.1.0", + "srml-support-procedural 0.1.0", +] + +[[package]] +name = "srml-support-procedural" +version = "0.1.0" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-api-macros 0.1.0", + "srml-support-procedural-tools 0.1.0", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "srml-support-procedural-tools" +version = "0.1.0" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "srml-support-procedural-tools-derive 0.1.0", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "srml-support-procedural-tools-derive" +version = "0.1.0" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -771,11 +1317,10 @@ name = "srml-system" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", @@ -788,10 +1333,8 @@ name = "srml-timestamp" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", @@ -806,10 +1349,9 @@ name = "srml-treasury" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", @@ -824,15 +1366,15 @@ name = "srml-upgrade-key" version = "0.1.0" dependencies = [ "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-io 0.1.0", "sr-primitives 0.1.0", "sr-std 0.1.0", "srml-consensus 0.1.0", "srml-support 0.1.0", + "srml-support-procedural 0.1.0", "srml-system 0.1.0", "substrate-primitives 0.1.0", ] @@ -848,22 +1390,103 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "substrate-keyring" +name = "substrate-client" version = "0.1.0" dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-api-macros 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "sr-version 0.1.0", + "substrate-consensus-common 0.1.0", + "substrate-executor 0.1.0", + "substrate-keyring 0.1.0", "substrate-primitives 0.1.0", + "substrate-state-machine 0.1.0", + "substrate-telemetry 0.3.0", + "substrate-trie 0.4.0", ] [[package]] -name = "substrate-metadata" +name = "substrate-consensus-aura-primitives" version = "0.1.0" dependencies = [ - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-version 0.1.0", + "srml-support 0.1.0", + "substrate-client 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "substrate-consensus-common" +version = "0.1.0" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "sr-version 0.1.0", + "substrate-primitives 0.1.0", + "tokio 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-executor" +version = "0.1.0" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-version 0.1.0", + "substrate-primitives 0.1.0", + "substrate-serializer 0.1.0", + "substrate-state-machine 0.1.0", + "substrate-trie 0.4.0", + "wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-finality-grandpa-primitives" +version = "0.1.0" +dependencies = [ + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "substrate-client 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "substrate-keyring" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-primitives 0.1.0", ] [[package]] @@ -872,23 +1495,30 @@ version = "0.1.0" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fixed-hash 0.3.0-beta.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", "hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)", "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", "sr-std 0.1.0", - "twox-hash 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.5.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "twox-hash 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-serializer" +version = "0.1.0" +dependencies = [ + "serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -898,22 +1528,36 @@ dependencies = [ "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-primitives 0.1.0", "substrate-trie 0.4.0", "trie-db 0.9.0 (git+https://github.com/paritytech/trie)", "trie-root 0.9.0 (git+https://github.com/paritytech/trie)", ] +[[package]] +name = "substrate-telemetry" +version = "0.3.0" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-scope 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "substrate-trie" version = "0.4.0" dependencies = [ "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", "memory-db 0.9.0 (git+https://github.com/paritytech/trie)", - "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "trie-db 0.9.0 (git+https://github.com/paritytech/trie)", "trie-root 0.9.0 (git+https://github.com/paritytech/trie)", ] @@ -923,25 +1567,203 @@ name = "syn" version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syn" -version = "0.15.6" +version = "0.15.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "time" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-fs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-current-thread" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-executor" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-fs" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-io" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-reactor" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-tcp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-timer" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-udp" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-uds" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "trie-db" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" dependencies = [ "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", @@ -952,29 +1774,43 @@ dependencies = [ [[package]] name = "trie-root" version = "0.9.0" -source = "git+https://github.com/paritytech/trie#b476c9e64b5d6ab38251b87bd10d6795e5f15a1b" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" dependencies = [ "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", ] [[package]] name = "twox-hash" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "uint" -version = "0.5.0-beta.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.1.0" @@ -990,12 +1826,22 @@ dependencies = [ [[package]] name = "untrusted" -version = "0.5.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "version_check" -version = "0.1.5" +name = "url" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "vcpkg" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1005,15 +1851,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasmi" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" version = "0.3.6" @@ -1023,6 +1873,11 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -1033,86 +1888,186 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ws" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [metadata] -"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" +"checksum arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f405cc4c21cd8b784f6c8fc2adf9bc00f59558f0049b5ec21517f875963040cc" +"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" +"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" -"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" +"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" +"checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" +"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" +"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" +"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" -"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" -"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" +"checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" +"checksum crossbeam-deque 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fe1b6f945f824c7a25afe44f62e25d714c0cc523f8e99d8db5cd1026e1269d3" +"checksum crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2449aaa4ec7ef96e5fb24db16024b935df718e9ae1cec0a1e68feeca2efca7b8" +"checksum crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e07fc155212827475223f0bcfae57e945e694fc90950ddf3f6695bbfd5555c72" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2" "checksum elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88d4851b005ef16de812ea9acdb7bece2f0a40dd86c07b85631d7dafa54537bb" "checksum environmental 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db746025e3ea695bfa0ae744dbacd5fcfc8db51b9760cf8bd0ab69708bb93c49" -"checksum fixed-hash 0.3.0-beta.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e71c99c903a9fe54baed1bc701b43daba8c6dc6d4aec89a32f667ab6b3094c4" +"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" +"checksum fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a557e80084b05c32b455963ff565a9de6f2866da023d6671705c6aff6f65e01c" +"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" +"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" "checksum hash-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" "checksum hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4da5f0e01bd8a71a224a4eedecaacfcabda388dbb7a80faf04d3514287572d95" "checksum hex-literal-impl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d340b6514f232f6db1bd16db65302a5278a04fef9ce867cb932e7e5fa21130a" +"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" +"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum impl-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c88568d828291c50eed30cd7fb9f8e688ad0013620186fa3e777b9f206c79f2" +"checksum impl-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5158079de9d4158e0ce1de3ae0bd7be03904efc40b3d7dd8b8c301cbf6b52b56" "checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" +"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" +"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" +"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" +"checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311" +"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" -"checksum mashup 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d886e371548f5c66258a99df9ec03366bff02cc96ea3d3f8f346b5d2d6836de7" -"checksum mashup-impl 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8d426741e35fab52542d84dfee615f442c2b37247bee8b1ed5c25ca723487580" +"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f2d82b34c7fb11bb41719465c060589e291d505ca4735ea30016a91f6fc79c3b" +"checksum mashup-impl 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "aa607bfb674b4efb310512527d64266b065de3f894fc52f84efcbf7eaa5965fb" +"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum memory-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" -"checksum nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d4f00fcc2f4c9efa8cc971db0da9e28290e28e97af47585e48691ef10ff31f" -"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" +"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" +"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" +"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" +"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" -"checksum parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dca389ea5e1632c89b2ce54f7e2b4a8a8c9d278042222a91e0bf95451218cb4c" +"checksum once_cell 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d7ce3535d54560c937c1652ba4a0da66bfc63e0f8e07bed127483afb6e5ee925" +"checksum openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ec7bd7ca4cce6dbdc77e7c1230682740d307d1218a87fb0349a571272be749f9" +"checksum openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)" = "1bb974e77de925ef426b6bc82fce15fd45bdcbeb5728bffcfc7cdeeb7ce1c2d6" +"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" +"checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=b0317f649ab2c665b7987b8475878fc4d2e1f81d)" = "" +"checksum parity-codec 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7b6a1290fe78aa6bbb5f3338ecede3062687a98b9e40cd1dbcaa47261d44097" "checksum parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa42c2cb493b60b12c75b26e8c94cb734af4df4d7f2cc229dc04c1953dac189" "checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" -"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" -"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" +"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" +"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" +"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" +"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" +"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" +"checksum primitive-types 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f47c18b4601125931d69fcf7b000c2c16a304e4f84d58218d6470b4502e00b58" "checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8" "checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a" -"checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901" -"checksum pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd695333cfae6e9dbe2703a6d040e252b57a6fc3b9a65c712615ac042b2e0c5" -"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" +"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" +"checksum pwasm-utils 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e9135bed7b452e20dbb395a2d519abaf0c46d60e7ecc02daeeab447d29bada1" +"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" -"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" -"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" -"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" -"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" +"checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a" +"checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a" +"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" +"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" +"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" +"checksum rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3" +"checksum redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "679da7508e9a6390aeaf7fbd02a800fdc64b73fe2204dd2c8ae66d22d9d5ad5d" +"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" +"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" +"checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" "checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9" -"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe" -"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" +"checksum serde 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)" = "c91eb5b0190ae87b4e2e39cbba6e3bed3ac6186935fe265f0426156c4c49961b" +"checksum serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)" = "477b13b646f5b5b56fc95bedfc3b550d12141ce84f466f6c44b9a17589923885" +"checksum serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)" = "c37ccd6be3ed1fdf419ee848f7c758eb31b054d7cd3ae3600e3bae0adf569811" +"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" +"checksum slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1a2eec401952cd7b12a84ea120e2d57281329940c3f93c2bf04f462539508e" +"checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f" +"checksum slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a" +"checksum slog-scope 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "053344c94c0e2b22da6305efddb698d7c485809427cf40555dc936085f67a9df" +"checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum syn 0.15.6 (registry+https://github.com/rust-lang/crates.io-index)" = "854b08a640fc8f54728fb95321e3ec485b365a97fe47609797c671addd1dde69" +"checksum syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)" = "ae8b29eb5210bc5cf63ed6149cbf9adfc82ac0be023d8735c176ee74a2db4da7" +"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" +"checksum tokio 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "a7817d4c98cc5be21360b3b37d6036fe9b7aefa5b7a201b7b16ff33423822f7d" +"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" +"checksum tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "331c8acc267855ec06eb0c94618dcbbfea45bed2d20b77252940095273fb58f6" +"checksum tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c117b6cf86bb730aab4834f10df96e4dd586eff2c3c27d3781348da49e255bde" +"checksum tokio-fs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "60ae25f6b17d25116d2cba342083abe5255d3c2c79cb21ea11aa049c53bf7c75" +"checksum tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7392fe0a70d5ce0c882c4778116c519bd5dbaa8a7c3ae3d04578b3afafdcda21" +"checksum tokio-reactor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "502b625acb4ee13cbb3b90b8ca80e0addd263ddacf6931666ef751e610b07fb5" +"checksum tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ad235e9dadd126b2d47f6736f65aa1fdcd6420e66ca63f44177bc78df89f912" +"checksum tokio-threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "56c5556262383032878afad66943926a1d1f0967f17e94bd7764ceceb3b70e7f" +"checksum tokio-timer 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4f37f0111d76cc5da132fe9bc0590b9b9cfd079bc7e75ac3846278430a299ff8" +"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" +"checksum tokio-uds 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "99ce87382f6c1a24b513a72c048b2c8efe66cb5161c9061d00bee510f08dc168" "checksum trie-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" "checksum trie-root 0.9.0 (git+https://github.com/paritytech/trie)" = "" -"checksum twox-hash 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f85be565a110ed72ed7048cf56570db04ce0a592c98aa59b7dacde3e5718750" -"checksum uint 0.5.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4630460173a57c0af94b8306091e018025d988473f641a4af754b6cde980e1e3" +"checksum twox-hash 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "555cd4909480122bbbf21e34faac4cb08a171f324775670447ed116726c474af" +"checksum uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "082df6964410f6aa929a61ddfafc997e4f32c62c22490e439ac351cec827f436" +"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" +"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" +"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum wasmi 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d184c4b7081f30316f74f8d73c197314dcb56ea7af9323522b42a2fa9cb19453" +"checksum wasmi 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21ef487a11df1ed468cf613c78798c26282da5c30e9d49f824872d4c77b47d1d" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "329d3e6dd450a9c5c73024e1047f0be7e24121a68484eb0b5368977bee3cf8c3" +"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/node/runtime/wasm/Cargo.toml b/node/runtime/wasm/Cargo.toml index 17ae789bdfc64df4eb14c3bdb12569600a0e3aec..ea95bd115264740fdf68bc6350214ba6644208b8 100644 --- a/node/runtime/wasm/Cargo.toml +++ b/node/runtime/wasm/Cargo.toml @@ -1,60 +1,19 @@ [package] -name = "node-runtime" +name = "node-runtime-wasm" version = "0.1.0" authors = ["Parity Technologies "] [lib] +name = "node_runtime" crate-type = ["cdylib"] [dependencies] -integer-sqrt = { version = "0.1.2" } -safe-mix = { version = "1.0", default-features = false} -parity-codec-derive = { version = "2.1" } -parity-codec = { version = "2.1", default-features = false } -substrate-primitives = { path = "../../../core/primitives", default-features = false } -sr-api = { path = "../../../core/sr-api", default-features = false } -sr-std = { path = "../../../core/sr-std", default-features = false } -srml-support = { path = "../../../srml/support", default-features = false } -srml-balances = { path = "../../../srml/balances", default-features = false } -srml-consensus = { path = "../../../srml/consensus", default-features = false } -srml-contract = { path = "../../../srml/contract", default-features = false } -srml-council = { path = "../../../srml/council", default-features = false } -srml-democracy = { path = "../../../srml/democracy", default-features = false } -srml-executive = { path = "../../../srml/executive", default-features = false } -sr-primitives = { path = "../../../core/sr-primitives", default-features = false } -srml-session = { path = "../../../srml/session", default-features = false } -srml-staking = { path = "../../../srml/staking", default-features = false } -srml-system = { path = "../../../srml/system", default-features = false } -srml-timestamp = { path = "../../../srml/timestamp", default-features = false } -srml-treasury = { path = "../../../srml/treasury", default-features = false } -srml-upgrade-key = { path = "../../../srml/upgrade-key", default-features = false } -sr-version = { path = "../../../core/sr-version", default-features = false } -node-primitives = { path = "../../primitives", default-features = false } +node-runtime = { path = "..", default-features = false } [features] default = [] std = [ - "safe-mix/std", - "parity-codec/std", - "substrate-primitives/std", - "sr-api/std", - "sr-std/std", - "srml-support/std", - "srml-balances/std", - "srml-consensus/std", - "srml-contract/std", - "srml-council/std", - "srml-democracy/std", - "srml-executive/std", - "sr-primitives/std", - "srml-session/std", - "srml-staking/std", - "srml-system/std", - "srml-timestamp/std", - "srml-treasury/std", - "srml-upgrade-key/std", - "sr-version/std", - "node-primitives/std", + "node-runtime/std", ] [profile.release] diff --git a/node/runtime/wasm/src b/node/runtime/wasm/src deleted file mode 120000 index 5cd551cf2693e4b4f65d7954ec621454c2b20326..0000000000000000000000000000000000000000 --- a/node/runtime/wasm/src +++ /dev/null @@ -1 +0,0 @@ -../src \ No newline at end of file diff --git a/node/runtime/wasm/src/lib.rs b/node/runtime/wasm/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..05d27009c7d040d97271bc3b54cd3ce621bbb776 --- /dev/null +++ b/node/runtime/wasm/src/lib.rs @@ -0,0 +1,22 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 Substrate runtime reexported for WebAssembly compile. + +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate node_runtime; +pub use node_runtime::*; diff --git a/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm b/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm index 4fbcc974d009df0e7d334462296e80ed16a01032..e39414434f6c8c614101f39a5771e9410bec6f1a 100644 Binary files a/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm and b/node/runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm differ diff --git a/node/src/main.rs b/node/src/main.rs index bf5717042e55449974aa99a055c8e061d6b31016..fdc51cdc1e114e959a0b3eca34c6f75e85b30e8c 100644 --- a/node/src/main.rs +++ b/node/src/main.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Substrate CLI +//! Substrate Node CLI #![warn(missing_docs)] @@ -54,10 +54,11 @@ quick_main!(run); fn run() -> cli::error::Result<()> { let version = VersionInfo { + name: "Substrate Node", commit: env!("VERGEN_SHA_SHORT"), version: env!("CARGO_PKG_VERSION"), executable_name: "substrate", - author: "Parity Team ", + author: "Parity Technologies ", description: "Generic substrate node", }; cli::run(::std::env::args(), Exit, version) diff --git a/scripts/docker/Dockerfile b/scripts/docker/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..3511ef2b7d5ada3b25d7bd2293177d5d57adce31 --- /dev/null +++ b/scripts/docker/Dockerfile @@ -0,0 +1,29 @@ +FROM ubuntu:xenial +LABEL maintainer "devops-team@parity.io" +LABEL description="Substrate: The platform for blockchain innovators" + +RUN apt-get update && \ + apt-get upgrade -y && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + libssl1.0.0 \ + ca-certificates \ + curl && \ + apt-get autoremove -y && \ + apt-get clean + +RUN find /var/lib/apt/lists/ -type f -not -name lock -delete + +COPY ./substrate /usr/local/bin + + + +RUN useradd -m -u 1000 -U -s /bin/sh -d /substrate substrate +USER substrate + +ENV RUST_BACKTRACE 1 + +EXPOSE 30333 9933 9944 +VOLUME ["/substrate"] + +ENTRYPOINT ["/usr/local/bin/substrate"] + diff --git a/srml/README.adoc b/srml/README.adoc index 616c12568a07649a796e8acf097c6d5f2af643ef..81b4f216e67e433466ec68292a31cff4ddd734ac 100644 --- a/srml/README.adoc +++ b/srml/README.adoc @@ -2,5 +2,3 @@ = Runtime Set of libs for the substrate runtime. - -TODO: Add READMEs to packages. diff --git a/srml/assets/Cargo.toml b/srml/assets/Cargo.toml index 58d84fb9bb4c60df9ca0194f81747246141a5471..8ff2b4ff98e8779e6b4d85208f763187f55f3344 100644 --- a/srml/assets/Cargo.toml +++ b/srml/assets/Cargo.toml @@ -6,8 +6,7 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } @@ -20,7 +19,6 @@ srml-system = { path = "../system", default-features = false } default = ["std"] std = [ "serde/std", - "serde_derive", "parity-codec/std", "parity-codec-derive/std", "substrate-primitives/std", diff --git a/srml/assets/src/lib.rs b/srml/assets/src/lib.rs index e266a00bdd86648e17d26366de2f18ed7990582e..01a8c13cf078f2f36f96f05edc1749f299e78cd9 100644 --- a/srml/assets/src/lib.rs +++ b/srml/assets/src/lib.rs @@ -30,13 +30,6 @@ extern crate sr_io as runtime_io; #[cfg(test)] extern crate substrate_primitives; -// Needed for deriving `Serialize` and `Deserialize` for various types. -// We only implement the serde traits for std builds - they're unneeded -// in the wasm runtime. -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - // Needed for deriving `Encode` and `Decode` for `RawEvent`. #[macro_use] extern crate parity_codec_derive; @@ -52,8 +45,8 @@ extern crate sr_primitives as primitives; // depend on it being around. extern crate srml_system as system; -use runtime_support::{StorageValue, StorageMap, dispatch::Result, Parameter}; -use primitives::traits::{Member, SimpleArithmetic, Zero}; +use runtime_support::{StorageValue, StorageMap, Parameter}; +use primitives::traits::{Member, SimpleArithmetic, Zero, StaticLookup}; use system::ensure_signed; pub trait Trait: system::Trait { @@ -69,46 +62,48 @@ type AssetId = u32; decl_module! { // Simple declaration of the `Module` type. Lets the macro know what its working on. pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Issue a new class of fungible assets. There are, and will only ever be, `total` /// such assets and they'll all belong to the `origin` initially. It will have an /// identifier `AssetId` instance: this will be specified in the `Issued` event. - fn issue(origin, total: T::Balance) -> Result { + fn issue(origin, #[compact] total: T::Balance) { let origin = ensure_signed(origin)?; let id = Self::next_asset_id(); >::mutate(|id| *id += 1); >::insert((id, origin.clone()), total); + >::insert(id, total); Self::deposit_event(RawEvent::Issued(id, origin, total)); - Ok(()) } /// Move some assets from one holder to another. - fn transfer(origin, id: AssetId, target: T::AccountId, amount: T::Balance) -> Result { + fn transfer(origin, + #[compact] id: AssetId, + target: ::Source, + #[compact] amount: T::Balance + ) { let origin = ensure_signed(origin)?; let origin_account = (id, origin.clone()); let origin_balance = >::get(&origin_account); - ensure!(origin_balance >= amount, "origin account balance must be greater than amount"); + let target = T::Lookup::lookup(target)?; + ensure!(!amount.is_zero(), "transfer amount should be non-zero"); + ensure!(origin_balance >= amount, "origin account balance must be greater than or equal to the transfer amount"); - Self::deposit_event(RawEvent::Transfered(id, origin, target.clone(), amount)); + Self::deposit_event(RawEvent::Transferred(id, origin, target.clone(), amount)); >::insert(origin_account, origin_balance - amount); >::mutate((id, target), |balance| *balance += amount); - - Ok(()) } /// Destroy any assets of `id` owned by `origin`. - fn destroy(origin, id: AssetId) -> Result { + fn destroy(origin, #[compact] id: AssetId) { let origin = ensure_signed(origin)?; - let balance = >::take((id, origin.clone())); ensure!(!balance.is_zero(), "origin balance should be non-zero"); + >::mutate(id, |total_supply| *total_supply -= balance); Self::deposit_event(RawEvent::Destroyed(id, origin, balance)); - - Ok(()) } } } @@ -120,8 +115,8 @@ decl_event!( pub enum Event where ::AccountId, ::Balance { /// Some assets were issued. Issued(AssetId, AccountId, Balance), - /// Some assets were transfered. - Transfered(AssetId, AccountId, AccountId, Balance), + /// Some assets were transferred. + Transferred(AssetId, AccountId, AccountId, Balance), /// Some assets were destroyed. Destroyed(AssetId, AccountId, Balance), } @@ -133,6 +128,8 @@ decl_storage! { Balances: map (AssetId, T::AccountId) => T::Balance; /// The next asset identifier up for grabs. NextAssetId get(next_asset_id): AssetId; + /// The total unit supply of an asset + TotalSupply: map AssetId => T::Balance; } } @@ -144,6 +141,11 @@ impl Module { pub fn balance(id: AssetId, who: T::AccountId) -> T::Balance { >::get((id, who)) } + + // Get the total supply of an asset `id` + pub fn total_supply(id: AssetId) -> T::Balance { + >::get(id) + } } #[cfg(test)] @@ -153,8 +155,12 @@ mod tests { use runtime_io::with_externalities; use substrate_primitives::{H256, Blake2Hasher}; // 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 requried. - use primitives::{BuildStorage, traits::{BlakeTwo256}, testing::{Digest, DigestItem, Header}}; + // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. + use primitives::{ + BuildStorage, + traits::{BlakeTwo256, IdentityLookup}, + testing::{Digest, DigestItem, Header} + }; impl_outer_origin! { pub enum Origin for Test {} @@ -173,6 +179,7 @@ mod tests { type Hashing = BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = (); type Log = DigestItem; @@ -190,16 +197,88 @@ mod tests { } #[test] - fn it_works() { + fn issuing_asset_units_to_issuer_should_work() { + with_externalities(&mut new_test_ext(), || { + assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_eq!(Assets::balance(0, 1), 100); + }); + } + + #[test] + fn querying_total_supply_should_work() { + with_externalities(&mut new_test_ext(), || { + assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_eq!(Assets::balance(0, 1), 100); + assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); + assert_eq!(Assets::balance(0, 1), 50); + assert_eq!(Assets::balance(0, 2), 50); + assert_ok!(Assets::transfer(Origin::signed(2), 0, 3, 31)); + assert_eq!(Assets::balance(0, 1), 50); + assert_eq!(Assets::balance(0, 2), 19); + assert_eq!(Assets::balance(0, 3), 31); + assert_ok!(Assets::destroy(Origin::signed(3), 0)); + assert_eq!(Assets::total_supply(0), 69); + }); + } + + #[test] + fn transferring_amount_above_available_balance_should_work() { + with_externalities(&mut new_test_ext(), || { + assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_eq!(Assets::balance(0, 1), 100); + assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); + assert_eq!(Assets::balance(0, 1), 50); + assert_eq!(Assets::balance(0, 2), 50); + }); + } + + #[test] + fn transferring_amount_less_than_available_balance_should_not_work() { with_externalities(&mut new_test_ext(), || { assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50)); assert_eq!(Assets::balance(0, 1), 50); assert_eq!(Assets::balance(0, 2), 50); - assert_ok!(Assets::destroy(Origin::signed(2), 0)); + assert_ok!(Assets::destroy(Origin::signed(1), 0)); + assert_eq!(Assets::balance(0, 1), 0); + assert_noop!(Assets::transfer(Origin::signed(1), 0, 1, 50), "origin account balance must be greater than or equal to the transfer amount"); + }); + } + + #[test] + fn transferring_less_than_one_unit_should_not_work() { + with_externalities(&mut new_test_ext(), || { + assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_eq!(Assets::balance(0, 1), 100); + assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 0), "transfer amount should be non-zero"); + }); + } + + #[test] + fn transferring_more_units_than_total_supply_should_not_work() { + with_externalities(&mut new_test_ext(), || { + assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_eq!(Assets::balance(0, 1), 100); + assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 101), "origin account balance must be greater than or equal to the transfer amount"); + }); + } + + #[test] + fn destroying_asset_balance_with_positive_balance_should_work() { + with_externalities(&mut new_test_ext(), || { + assert_ok!(Assets::issue(Origin::signed(1), 100)); + assert_eq!(Assets::balance(0, 1), 100); + assert_ok!(Assets::destroy(Origin::signed(1), 0)); + }); + } + + #[test] + fn destroying_asset_balance_with_zero_balance_should_not_work() { + with_externalities(&mut new_test_ext(), || { + assert_ok!(Assets::issue(Origin::signed(1), 100)); assert_eq!(Assets::balance(0, 2), 0); - assert_noop!(Assets::transfer(Origin::signed(2), 0, 1, 50), "origin account balance must be greater than amount"); + assert_noop!(Assets::destroy(Origin::signed(2), 0), "origin balance should be non-zero"); }); } } diff --git a/srml/aura/Cargo.toml b/srml/aura/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..480548e9d7cfa37a6256e6d44950da3865f27f39 --- /dev/null +++ b/srml/aura/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "srml-aura" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +hex-literal = "0.1.0" +parity-codec = { version = "2.2", default-features = false } +parity-codec-derive = { version = "2.1", default-features = false } +serde = { version = "1.0", default-features = false } +substrate-primitives = { path = "../../core/primitives", default-features = false } +sr-std = { path = "../../core/sr-std", default-features = false } +sr-io = { path = "../../core/sr-io", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +srml-support = { path = "../support", default-features = false } +srml-system = { path = "../system", default-features = false } +srml-consensus = { path = "../consensus", default-features = false } +srml-timestamp = { path = "../timestamp", default-features = false } +srml-staking = { path = "../staking", default-features = false } + +[dev-dependencies] +lazy_static = "1.0" +parking_lot = "0.7.1" + +[features] +default = ["std"] +std = [ + "serde/std", + "parity-codec/std", + "parity-codec-derive/std", + "substrate-primitives/std", + "sr-std/std", + "sr-io/std", + "srml-support/std", + "sr-primitives/std", + "srml-system/std", + "srml-consensus/std", + "srml-timestamp/std", + "srml-staking/std", +] diff --git a/srml/aura/src/lib.rs b/srml/aura/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..b0bc50d69bc54593e2666300f489f9c877ea29e6 --- /dev/null +++ b/srml/aura/src/lib.rs @@ -0,0 +1,199 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Consensus extension module for Aura consensus. This manages offline reporting. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[allow(unused_imports)] +#[macro_use] +extern crate sr_std as rstd; + +#[macro_use] +extern crate parity_codec_derive; +extern crate parity_codec; + +#[macro_use] +extern crate srml_support as runtime_support; + +extern crate sr_primitives as primitives; +extern crate srml_system as system; +extern crate srml_timestamp as timestamp; +extern crate srml_staking as staking; +extern crate substrate_primitives; + +#[cfg(test)] +extern crate srml_consensus as consensus; + +#[cfg(test)] +extern crate sr_io as runtime_io; + +#[cfg(test)] +#[macro_use] +extern crate lazy_static; + +#[cfg(test)] +extern crate parking_lot; + +use rstd::prelude::*; +use runtime_support::storage::StorageValue; +use runtime_support::dispatch::Result; +use primitives::traits::{As, Zero}; +use timestamp::OnTimestampSet; + +mod mock; +mod tests; + +/// Something which can handle Aura consensus reports. +pub trait HandleReport { + fn handle_report(report: AuraReport); +} + +impl HandleReport for () { + fn handle_report(_report: AuraReport) { } +} + +pub trait Trait: timestamp::Trait { + /// The logic for handling reports. + type HandleReport: HandleReport; +} + +decl_storage! { + trait Store for Module as Aura { + // The last timestamp. + LastTimestamp get(last) build(|_| T::Moment::sa(0)): T::Moment; + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { } +} + +/// A report of skipped authorities in aura. +#[derive(Clone, Encode, Decode, PartialEq, Eq)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct AuraReport { + // The first skipped slot. + start_slot: usize, + // The number of times authorities were skipped. + skipped: usize, +} + +impl AuraReport { + /// Call the closure with (validator_indices, punishment_count) for each + /// validator to punish. + pub fn punish(&self, validator_count: usize, mut punish_with: F) + where F: FnMut(usize, usize) + { + let start_slot = self.start_slot % validator_count; + + // the number of times everyone was skipped. + let skipped_all = self.skipped / validator_count; + // the number of validators who were skipped once after that. + let skipped_after = self.skipped % validator_count; + + let iter = (start_slot..validator_count).into_iter() + .chain(0..start_slot) + .enumerate(); + + for (rel_index, actual_index) in iter { + let slash_count = skipped_all + if rel_index < skipped_after { + 1 + } else { + // avoid iterating over all authorities when skipping a couple. + if skipped_all == 0 { break } + 0 + }; + + if slash_count > 0 { + punish_with(actual_index, slash_count); + } + } + } +} + +impl Module { + /// Determine the Aura slot-duration based on the timestamp module configuration. + pub fn slot_duration() -> u64 { + // we double the minimum block-period so each author can always propose within + // the majority of their slot. + >::block_period().as_().saturating_mul(2) + } + + /// Verify an inherent slot that is used in a block seal against a timestamp + /// extracted from the block. + // TODO: ensure `ProvideInherent` can deal with dependencies like this. + // https://github.com/paritytech/substrate/issues/1228 + pub fn verify_inherent(timestamp: T::Moment, seal_slot: u64) -> Result { + let timestamp_based_slot = timestamp.as_() / Self::slot_duration(); + + if timestamp_based_slot == seal_slot { + Ok(()) + } else { + Err("timestamp set in block doesn't match slot in seal".into()) + } + } + + fn on_timestamp_set(now: T::Moment, slot_duration: T::Moment) { + let last = Self::last(); + ::LastTimestamp::put(now.clone()); + + if last == T::Moment::zero() { + return; + } + + assert!(slot_duration > T::Moment::zero(), "Aura slot duration cannot be zero."); + + let last_slot = last / slot_duration.clone(); + let first_skipped = last_slot.clone() + T::Moment::sa(1); + let cur_slot = now / slot_duration; + + assert!(last_slot < cur_slot, "Only one block may be authored per slot."); + if cur_slot == first_skipped { return } + + let slot_to_usize = |slot: T::Moment| { slot.as_() as usize }; + + let skipped_slots = cur_slot - last_slot - T::Moment::sa(1); + + H::handle_report(AuraReport { + start_slot: slot_to_usize(first_skipped), + skipped: slot_to_usize(skipped_slots), + }) + } +} + +impl OnTimestampSet for Module { + fn on_timestamp_set(moment: T::Moment) { + Self::on_timestamp_set::(moment, T::Moment::sa(Self::slot_duration())) + } +} + +/// A type for performing slashing based on aura reports. +pub struct StakingSlasher(::rstd::marker::PhantomData); + +impl HandleReport for StakingSlasher { + fn handle_report(report: AuraReport) { + let validators = staking::Module::::validators(); + + report.punish( + validators.len(), + |idx, slash_count| { + let v = validators[idx].clone(); + staking::Module::::on_offline_validator(v, slash_count); + } + ); + } +} diff --git a/srml/aura/src/mock.rs b/srml/aura/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..6ff33e6c51ccd82237fe11cb8d57ac8916512e35 --- /dev/null +++ b/srml/aura/src/mock.rs @@ -0,0 +1,79 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Test utilities + +#![cfg(test)] + +use primitives::{BuildStorage, traits::IdentityLookup, testing::{Digest, DigestItem, Header, UintAuthorityId}}; +use runtime_io; +use substrate_primitives::{H256, Blake2Hasher}; +use {Trait, Module, consensus, system, timestamp}; + +impl_outer_origin!{ + pub enum Origin for Test {} +} + +// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Test; + +impl consensus::Trait for Test { + const NOTE_OFFLINE_POSITION: u32 = 1; + type Log = DigestItem; + type SessionKey = UintAuthorityId; + type InherentOfflineReport = (); +} + +impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = ::primitives::traits::BlakeTwo256; + type Digest = Digest; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type Log = DigestItem; +} + +impl timestamp::Trait for Test { + const TIMESTAMP_SET_POSITION: u32 = 0; + + type Moment = u64; + type OnTimestampSet = Aura; +} + +impl Trait for Test { + type HandleReport = (); +} + +pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities { + let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + t.extend(consensus::GenesisConfig::{ + code: vec![], + authorities: authorities.into_iter().map(|a| UintAuthorityId(a)).collect(), + }.build_storage().unwrap().0); + t.extend(timestamp::GenesisConfig::{ + period: 1, + }.build_storage().unwrap().0); + t.into() +} + +pub type System = system::Module; +pub type Aura = Module; diff --git a/srml/aura/src/tests.rs b/srml/aura/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..6f215b8fe25e74c2743fb6e1746e9292fa9cd4fe --- /dev/null +++ b/srml/aura/src/tests.rs @@ -0,0 +1,79 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Tests for the module. + +#![cfg(test)] + +use mock::{System, Aura, new_test_ext}; +use primitives::traits::Header; +use runtime_io::with_externalities; +use parking_lot::Mutex; +use {AuraReport, HandleReport}; + +#[test] +fn aura_report_gets_skipped_correctly() { + let mut report = AuraReport { + start_slot: 0, + skipped: 30, + }; + + let mut validators = vec![0; 10]; + report.punish(10, |idx, count| validators[idx] += count); + + assert_eq!(validators, vec![3; 10]); + + let mut validators = vec![0; 4]; + report.punish(4, |idx, count| validators[idx] += count); + assert_eq!(validators, vec![8, 8, 7, 7]); + + report.start_slot = 2; + report.punish(4, |idx, count| validators[idx] += count); + assert_eq!(validators, vec![15, 15, 15, 15]); +} + +#[test] +fn aura_reports_offline() { + lazy_static! { + static ref SLASH_COUNTS: Mutex> = Mutex::new(vec![0; 4]); + } + + struct HandleTestReport; + impl HandleReport for HandleTestReport { + fn handle_report(report: AuraReport) { + let mut counts = SLASH_COUNTS.lock(); + report.punish(counts.len(), |idx, count| counts[idx] += count); + } + } + + with_externalities(&mut new_test_ext(vec![0, 1, 2, 3]), || { + System::initialise(&1, &Default::default(), &Default::default()); + let slot_duration = Aura::slot_duration(); + + Aura::on_timestamp_set::(5 * slot_duration, slot_duration); + let header = System::finalise(); + + // no slashing when last step was 0. + assert_eq!(SLASH_COUNTS.lock().as_slice(), &[0, 0, 0, 0]); + + System::initialise(&2, &header.hash(), &Default::default()); + Aura::on_timestamp_set::(8 * slot_duration, slot_duration); + let _header = System::finalise(); + + // Steps 6 and 7 were skipped. + assert_eq!(SLASH_COUNTS.lock().as_slice(), &[0, 0, 1, 1]); + }); +} diff --git a/srml/balances/Cargo.toml b/srml/balances/Cargo.toml index 769e801ca9a84a3390f4cebff7b6435fe8028d88..477e11eefb2ea71353c62040355e2044f0351463 100644 --- a/srml/balances/Cargo.toml +++ b/srml/balances/Cargo.toml @@ -6,9 +6,8 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } safe-mix = { version = "1.0", default-features = false} -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-keyring = { path = "../../core/keyring", optional = true } substrate-primitives = { path = "../../core/primitives", default-features = false } @@ -22,7 +21,6 @@ srml-system = { path = "../system", default-features = false } default = ["std"] std = [ "serde/std", - "serde_derive", "safe-mix/std", "substrate-keyring", "parity-codec/std", diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs index cf2f9bc4da917876e935f3870bd7b0067f17dc5a..88404cbc38ad9797ca8ee41fc4fa0f4f97133446 100644 --- a/srml/balances/src/lib.rs +++ b/srml/balances/src/lib.rs @@ -14,14 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Balances: Handles balances. +//! Balances: Handles setting and retrieval of free balance, +//! retrieving total balance, reserve and unreserve balance, +//! repatriating a reserved balance to a beneficiary account that exists, +//! transfering a balance between accounts (when not reserved), +//! slashing an account balance, account removal, rewards, +//! lookup of an index to reclaim an account (when not balance not reserved), +//! increasing total stake. #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - #[macro_use] extern crate srml_support as runtime_support; @@ -41,27 +43,16 @@ extern crate substrate_primitives; use rstd::prelude::*; use rstd::{cmp, result}; -use codec::{Encode, Decode, Codec, Input, Output, HasCompact}; +use codec::Codec; use runtime_support::{StorageValue, StorageMap, Parameter}; use runtime_support::dispatch::Result; -use primitives::traits::{Zero, One, SimpleArithmetic, MakePayment, - As, Lookup, Member, CheckedAdd, CheckedSub, CurrentHeight, BlockNumberToHash}; -use address::Address as RawAddress; -use system::ensure_signed; +use primitives::traits::{Zero, SimpleArithmetic, MakePayment, + As, StaticLookup, Member, CheckedAdd, CheckedSub}; +use system::{IsDeadAccount, OnNewAccount, ensure_signed}; mod mock; - -pub mod address; mod tests; -/// Number of account IDs stored per enum set. -const ENUM_SET_SIZE: usize = 64; - -/// The byte to identify intention to reclaim an existing account index. -const RECLAIM_INDEX_MAGIC: usize = 0x69; - -pub type Address = RawAddress<::AccountId, ::AccountIndex>; - /// The account with the given id was killed. pub trait OnFreeBalanceZero { /// The account was the given id was killed. @@ -99,23 +90,33 @@ pub trait EnsureAccountLiquid { /// with the reason why not otherwise. fn ensure_account_liquid(who: &AccountId) -> Result; } - +impl< + AccountId, + X: EnsureAccountLiquid, + Y: EnsureAccountLiquid, +> EnsureAccountLiquid for (X, Y) { + fn ensure_account_liquid(who: &AccountId) -> Result { + X::ensure_account_liquid(who)?; + Y::ensure_account_liquid(who) + } +} impl EnsureAccountLiquid for () { fn ensure_account_liquid(_who: &AccountId) -> Result { Ok(()) } } pub trait Trait: system::Trait { /// The balance of an account. - type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + As + As + As; - /// Type used for storing an account's index; implies the maximum number of accounts the system - /// can hold. - type AccountIndex: Parameter + Member + Codec + Default + SimpleArithmetic + As + As + As + As + As + Copy; + type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + As + As; + /// A function which is invoked when the free-balance has fallen below the existential deposit and /// has been reduced to zero. /// /// Gives a chance to clean up resources associated with the given account. type OnFreeBalanceZero: OnFreeBalanceZero; + /// Handler for when a new account is created. + type OnNewAccount: OnNewAccount; + /// A function that returns true iff a given account can transfer its funds to another account. type EnsureAccountLiquid: EnsureAccountLiquid; @@ -125,18 +126,17 @@ pub trait Trait: system::Trait { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Transfer some liquid free balance to another staker. pub fn transfer( origin, - dest: RawAddress, - value: ::Type - ) -> Result { + dest: ::Source, + #[compact] value: T::Balance + ) { let transactor = ensure_signed(origin)?; - let dest = Self::lookup(dest)?; - let value = value.into(); + let dest = T::Lookup::lookup(dest)?; let from_balance = Self::free_balance(&transactor); let to_balance = Self::free_balance(&dest); let would_create = to_balance.is_zero(); @@ -168,20 +168,17 @@ decl_module! { Self::set_free_balance_creating(&dest, new_to_balance); Self::deposit_event(RawEvent::Transfer(transactor, dest, value, fee)); } - - Ok(()) } /// Set the balances of a given account. fn set_balance( - who: RawAddress, - free: ::Type, - reserved: ::Type - ) -> Result { - let who = Self::lookup(who)?; - Self::set_free_balance(&who, free.into()); - Self::set_reserved_balance(&who, reserved.into()); - Ok(()) + who: ::Source, + #[compact] free: T::Balance, + #[compact] reserved: T::Balance + ) { + let who = T::Lookup::lookup(who)?; + Self::set_free_balance(&who, free); + Self::set_reserved_balance(&who, reserved); } } } @@ -189,11 +186,10 @@ decl_module! { decl_event!( pub enum Event where ::AccountId, - ::AccountIndex, ::Balance { /// A new account was created. - NewAccount(AccountId, AccountIndex, NewAccountOutcome), + NewAccount(AccountId, Balance), /// An account was reaped. ReapedAccount(AccountId), /// Transfer succeeded (from, to, value, fees). @@ -209,20 +205,11 @@ decl_storage! { }): T::Balance; /// The minimum amount allowed to keep an account open. pub ExistentialDeposit get(existential_deposit) config(): T::Balance; - /// The amount credited to a destination's account whose index was reclaimed. - pub ReclaimRebate get(reclaim_rebate) config(): T::Balance; /// The fee required to make a transfer. pub TransferFee get(transfer_fee) config(): T::Balance; /// The fee required to create an account. At least as big as ReclaimRebate. pub CreationFee get(creation_fee) config(): T::Balance; - /// The next free enumeration set. - pub NextEnumSet get(next_enum_set) build(|config: &GenesisConfig| { - T::AccountIndex::sa(config.balances.len() / ENUM_SET_SIZE) - }): T::AccountIndex; - /// The enumeration sets. - pub EnumSet get(enum_set): map T::AccountIndex => Vec; - /// The 'free' balance of a given account. /// /// This is the only balance that matters in terms of most operations on tokens. It is @@ -260,25 +247,9 @@ decl_storage! { } add_extra_genesis { config(balances): Vec<(T::AccountId, T::Balance)>; - build(|storage: &mut primitives::StorageMap, _: &mut primitives::ChildrenStorageMap, config: &GenesisConfig| { - let ids: Vec<_> = config.balances.iter().map(|x| x.0.clone()).collect(); - for i in 0..(ids.len() + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE { - storage.insert(GenesisConfig::::hash(&>::key_for(T::AccountIndex::sa(i))).to_vec(), - ids[i * ENUM_SET_SIZE..ids.len().min((i + 1) * ENUM_SET_SIZE)].to_owned().encode()); - } - }); } } -/// Whatever happened about the hint given when creating the new account. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] -#[derive(Encode, Decode, PartialEq, Eq, Clone, Copy)] -pub enum NewAccountOutcome { - NoHint, - GoodHint, - BadHint, -} - /// Outcome of a balance update. pub enum UpdateBalanceOutcome { /// Account balance was simply updated. @@ -311,30 +282,6 @@ impl Module { } } - /// Lookup an T::AccountIndex to get an Id, if there's one there. - pub fn lookup_index(index: T::AccountIndex) -> Option { - let enum_set_size = Self::enum_set_size(); - let set = Self::enum_set(index / enum_set_size); - let i: usize = (index % enum_set_size).as_(); - set.get(i).map(|x| x.clone()) - } - - /// `true` if the account `index` is ready for reclaim. - pub fn can_reclaim(try_index: T::AccountIndex) -> bool { - let enum_set_size = Self::enum_set_size(); - let try_set = Self::enum_set(try_index / enum_set_size); - let i = (try_index % enum_set_size).as_(); - i < try_set.len() && Self::total_balance(&try_set[i]).is_zero() - } - - /// Lookup an address to get an Id, if there's one there. - pub fn lookup_address(a: address::Address) -> Option { - match a { - address::Address::Id(i) => Some(i), - address::Address::Index(i) => Self::lookup_index(i), - } - } - //PUBLIC MUTABLES (DANGEROUS) /// Set the free balance of an account to some new value. @@ -391,22 +338,14 @@ impl Module { // account is reaped). // NOTE: This is orthogonal to the `Bondage` value that an account has, a high // value of which makes even the `free_balance` unspendable. - // TODO: enforce this for the other balance-altering functions. if balance < ed { Self::set_free_balance(who, balance); UpdateBalanceOutcome::AccountKilled } else { if !>::exists(who) { - let outcome = Self::new_account(&who, balance); - let credit = match outcome { - NewAccountOutcome::GoodHint => balance + >::reclaim_rebate(), - _ => balance, - }; - Self::set_free_balance(who, credit); - Self::increase_total_stake_by(credit - balance); - } else { - Self::set_free_balance(who, balance); + Self::new_account(&who, balance); } + Self::set_free_balance(who, balance); UpdateBalanceOutcome::Updated } @@ -542,82 +481,10 @@ impl Module { } } - fn enum_set_size() -> T::AccountIndex { - T::AccountIndex::sa(ENUM_SET_SIZE) - } - /// Register a new account (with existential balance). - fn new_account(who: &T::AccountId, balance: T::Balance) -> NewAccountOutcome { - let enum_set_size = Self::enum_set_size(); - let next_set_index = Self::next_enum_set(); - let reclaim_index_magic = T::AccountIndex::sa(RECLAIM_INDEX_MAGIC); - let reclaim_index_modulus = T::AccountIndex::sa(256usize); - let quantization = T::AccountIndex::sa(256usize); - - // A little easter-egg for reclaiming dead indexes.. - let ret = { - // we quantise the number of accounts so it stays constant over a reasonable - // period of time. - let quantized_account_count: T::AccountIndex = (next_set_index * enum_set_size / quantization + One::one()) * quantization; - // then modify the starting balance to be modulo this to allow it to potentially - // identify an account index for reuse. - let maybe_try_index = balance % >::sa(quantized_account_count * reclaim_index_modulus); - let maybe_try_index = As::::as_(maybe_try_index); - - // this identifier must end with magic byte 0x69 to trigger this check (a minor - // optimisation to ensure we don't check most unintended account creations). - if maybe_try_index % reclaim_index_modulus == reclaim_index_magic { - // reuse is probably intended. first, remove magic byte. - let try_index = maybe_try_index / reclaim_index_modulus; - - // then check to see if this balance identifies a dead account index. - let set_index = try_index / enum_set_size; - let mut try_set = Self::enum_set(set_index); - let item_index = (try_index % enum_set_size).as_(); - if item_index < try_set.len() { - if Self::total_balance(&try_set[item_index]).is_zero() { - // yup - this index refers to a dead account. can be reused. - try_set[item_index] = who.clone(); - >::insert(set_index, try_set); - - Self::deposit_event(RawEvent::NewAccount(who.clone(), try_index, NewAccountOutcome::GoodHint)); - - return NewAccountOutcome::GoodHint - } - } - NewAccountOutcome::BadHint - } else { - NewAccountOutcome::NoHint - } - }; - - // insert normally as a back up - let mut set_index = next_set_index; - // defensive only: this loop should never iterate since we keep NextEnumSet up to date later. - let mut set = loop { - let set = Self::enum_set(set_index); - if set.len() < ENUM_SET_SIZE { - break set; - } - set_index += One::one(); - }; - - let index = T::AccountIndex::sa(set_index.as_() * ENUM_SET_SIZE + set.len()); - - // update set. - set.push(who.clone()); - - // keep NextEnumSet up to date - if set.len() == ENUM_SET_SIZE { - >::put(set_index + One::one()); - } - - // write set. - >::insert(set_index, set); - - Self::deposit_event(RawEvent::NewAccount(who.clone(), index, ret)); - - ret + fn new_account(who: &T::AccountId, balance: T::Balance) { + T::OnNewAccount::on_new_account(&who); + Self::deposit_event(RawEvent::NewAccount(who.clone(), balance.clone())); } fn reap_account(who: &T::AccountId) { @@ -659,43 +526,6 @@ impl Module { >::put(v); } } - - pub fn lookup(a: address::Address) -> result::Result { - match a { - address::Address::Id(i) => Ok(i), - address::Address::Index(i) => >::lookup_index(i).ok_or("invalid account index"), - } - } -} - -pub struct ChainContext(::rstd::marker::PhantomData); -impl Default for ChainContext { - fn default() -> Self { - ChainContext(::rstd::marker::PhantomData) - } -} - -impl Lookup for ChainContext { - type Source = address::Address; - type Target = T::AccountId; - fn lookup(&self, a: Self::Source) -> result::Result { - >::lookup(a) - } -} - -impl CurrentHeight for ChainContext { - type BlockNumber = T::BlockNumber; - fn current_height(&self) -> Self::BlockNumber { - >::block_number() - } -} - -impl BlockNumberToHash for ChainContext { - type BlockNumber = T::BlockNumber; - type Hash = T::Hash; - fn block_number_to_hash(&self, n: Self::BlockNumber) -> Option { - Some(>::block_hash(n)) - } } impl MakePayment for Module { @@ -710,3 +540,9 @@ impl MakePayment for Module { Ok(()) } } + +impl IsDeadAccount for Module { + fn is_dead_account(who: &T::AccountId) -> bool { + Self::total_balance(who).is_zero() + } +} diff --git a/srml/balances/src/mock.rs b/srml/balances/src/mock.rs index d2e62cb83d678b7fe3c9eff21841fd8cda34c32f..1ff7a03073549a567473714027718ce8bf0176fb 100644 --- a/srml/balances/src/mock.rs +++ b/srml/balances/src/mock.rs @@ -19,7 +19,7 @@ #![cfg(test)] use primitives::BuildStorage; -use primitives::testing::{Digest, DigestItem, Header}; +use primitives::{traits::{IdentityLookup}, testing::{Digest, DigestItem, Header}}; use substrate_primitives::{H256, Blake2Hasher}; use runtime_io; use {GenesisConfig, Module, Trait, system}; @@ -29,7 +29,7 @@ impl_outer_origin!{ } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. -#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[derive(Clone, PartialEq, Eq, Debug)] pub struct Runtime; impl system::Trait for Runtime { type Origin = Origin; @@ -39,14 +39,15 @@ impl system::Trait for Runtime { type Hashing = ::primitives::traits::BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = (); type Log = DigestItem; } impl Trait for Runtime { type Balance = u64; - type AccountIndex = u64; type OnFreeBalanceZero = (); + type OnNewAccount = (); type EnsureAccountLiquid = (); type Event = (); } @@ -72,6 +73,7 @@ impl ExtBuilder { self.existential_deposit = existential_deposit; self } + #[allow(dead_code)] pub fn transfer_fee(mut self, transfer_fee: u64) -> Self { self.transfer_fee = transfer_fee; self @@ -102,7 +104,6 @@ impl ExtBuilder { existential_deposit: self.existential_deposit, transfer_fee: self.transfer_fee, creation_fee: self.creation_fee, - reclaim_rebate: 0, }.build_storage().unwrap().0); t.into() } diff --git a/srml/balances/src/tests.rs b/srml/balances/src/tests.rs index 9ad100fe6179c0e86552a9c1c9c768f8193e2569..781366bf38aee7e38d6ead0e54156757b74fc627 100644 --- a/srml/balances/src/tests.rs +++ b/srml/balances/src/tests.rs @@ -22,67 +22,6 @@ use super::*; use mock::{Balances, ExtBuilder, Runtime, System}; use runtime_io::with_externalities; -#[test] -fn reward_should_work() { - with_externalities(&mut ExtBuilder::default().monied(true).build(), || { - assert_eq!(Balances::total_balance(&1), 10); - assert_ok!(Balances::reward(&1, 10)); - assert_eq!(Balances::total_balance(&1), 20); - assert_eq!(>::get(), 110); - }); -} - -#[test] -fn indexing_lookup_should_work() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .build(), - || { - assert_eq!(Balances::lookup_index(0), Some(1)); - assert_eq!(Balances::lookup_index(1), Some(2)); - assert_eq!(Balances::lookup_index(2), Some(3)); - assert_eq!(Balances::lookup_index(3), Some(4)); - assert_eq!(Balances::lookup_index(4), None); - }, - ); -} - -#[test] -fn default_indexing_on_new_accounts_should_work() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .build(), - || { - assert_eq!(Balances::lookup_index(4), None); - assert_ok!(Balances::transfer(Some(1).into(), 5.into(), 10.into())); - assert_eq!(Balances::lookup_index(4), Some(5)); - }, - ); -} - -#[test] -fn default_indexing_on_new_accounts_should_work2() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(10) - .creation_fee(50) - .monied(true) - .build(), - || { - assert_eq!(Balances::lookup_index(4), None); - // account 1 has 256 * 10 = 2560, account 5 is not exist, ext_deposit is 10, value is 10 - assert_ok!(Balances::transfer(Some(1).into(), 5.into(), 10.into())); - assert_eq!(Balances::lookup_index(4), Some(5)); - - assert_eq!(Balances::free_balance(&1), 256 * 10 - 10 - 50); // 10 is value, 50 is creation_free - }, - ); -} - #[test] fn default_indexing_on_new_accounts_should_not_work2() { with_externalities( @@ -92,166 +31,100 @@ fn default_indexing_on_new_accounts_should_not_work2() { .monied(true) .build(), || { - assert_eq!(Balances::lookup_index(4), None); + assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist // account 1 has 256 * 10 = 2560, account 5 is not exist, ext_deposit is 10, value is 9, not satisfies for ext_deposit assert_noop!( - Balances::transfer(Some(1).into(), 5.into(), 9.into()), + Balances::transfer(Some(1).into(), 5, 9), "value too low to create account" ); - assert_eq!(Balances::lookup_index(4), None); // account 5 should not exist + assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist assert_eq!(Balances::free_balance(&1), 256 * 10); }, ); } #[test] -fn dust_account_removal_should_work() { +fn reserved_balance_should_prevent_reclaim_count() { with_externalities( &mut ExtBuilder::default() - .existential_deposit(256 * 10) + .existential_deposit(256 * 1) .monied(true) .build(), || { System::inc_account_nonce(&2); - assert_eq!(System::account_nonce(&2), 1); + assert_eq!(Balances::is_dead_account(&2), false); + assert_eq!(Balances::is_dead_account(&5), true); assert_eq!(Balances::total_balance(&2), 256 * 20); - assert_ok!(Balances::transfer(Some(2).into(), 5.into(), (256 * 10 + 1).into())); // index 1 (account 2) becomes zombie - assert_eq!(Balances::total_balance(&2), 0); - assert_eq!(Balances::total_balance(&5), 256 * 10 + 1); - assert_eq!(System::account_nonce(&2), 0); - }, - ); -} - -#[test] -fn dust_account_removal_should_work2() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(256 * 10) - .creation_fee(50) - .monied(true) - .build(), - || { - System::inc_account_nonce(&2); + assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved + assert_eq!(Balances::free_balance(&2), 0); // "free" account deleted." + assert_eq!(Balances::total_balance(&2), 256 * 19 + 1); // reserve still exists. + assert_eq!(Balances::is_dead_account(&2), false); assert_eq!(System::account_nonce(&2), 1); - assert_eq!(Balances::total_balance(&2), 256 * 20); - assert_ok!(Balances::transfer(Some(2).into(), 5.into(), (256 * 10).into())); // index 1 (account 2) becomes zombie for 256*10 + 50(fee) < 256 * 10 (ext_deposit) - assert_eq!(Balances::total_balance(&2), 0); - assert_eq!(Balances::total_balance(&5), 256 * 10); - assert_eq!(System::account_nonce(&2), 0); - }, - ); -} -#[test] -fn reclaim_indexing_on_new_accounts_should_work() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(256 * 1) - .monied(true) - .build(), - || { - assert_eq!(Balances::lookup_index(1), Some(2)); - assert_eq!(Balances::lookup_index(4), None); - assert_eq!(Balances::total_balance(&2), 256 * 20); + assert_ok!(Balances::transfer(Some(4).into(), 5, 256 * 1 + 0x69)); // account 4 tries to take index 1 for account 5. + assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); + assert_eq!(Balances::is_dead_account(&5), false); - assert_ok!(Balances::transfer(Some(2).into(), 5.into(), (256 * 20).into())); // account 2 becomes zombie freeing index 1 for reclaim) - assert_eq!(Balances::total_balance(&2), 0); + assert_eq!(Balances::slash(&2, 256 * 18 + 2), None); // account 2 gets slashed + assert_eq!(Balances::total_balance(&2), 0); // "reserve" account reduced to 255 (below ED) so account deleted + assert_eq!(System::account_nonce(&2), 0); // nonce zero + assert_eq!(Balances::is_dead_account(&2), true); - assert_ok!(Balances::transfer(Some(5).into(), 6.into(), (256 * 1 + 0x69).into())); // account 6 takes index 1. + assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69)); // account 4 tries to take index 1 again for account 6. assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); - assert_eq!(Balances::lookup_index(1), Some(6)); + assert_eq!(Balances::is_dead_account(&6), false); }, ); } -#[test] -fn reclaim_indexing_on_new_accounts_should_work2() { - with_externalities( - &mut ExtBuilder::default() - .existential_deposit(256 * 1) - .monied(true) - .build(), - || { - assert_eq!(Balances::lookup_index(1), Some(2)); - assert_eq!(Balances::lookup_index(4), None); - assert_eq!(Balances::total_balance(&2), 256 * 20); - assert_ok!(Balances::transfer(Some(2).into(), 5.into(), (256 * 20 - 50).into())); // account 2 becomes zombie freeing index 1 for reclaim) 50 is creation fee - assert_eq!(Balances::total_balance(&2), 0); - - assert_ok!(Balances::transfer(Some(5).into(), 6.into(), (256 * 1 + 0x69).into())); // account 6 takes index 1. - assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); - assert_eq!(Balances::lookup_index(1), Some(6)); - }, - ); +#[test] +fn reward_should_work() { + with_externalities(&mut ExtBuilder::default().monied(true).build(), || { + assert_eq!(Balances::total_balance(&1), 10); + assert_ok!(Balances::reward(&1, 10)); + assert_eq!(Balances::total_balance(&1), 20); + assert_eq!(>::get(), 110); + }); } #[test] -fn reserved_balance_should_prevent_reclaim_count() { +fn dust_account_removal_should_work() { with_externalities( &mut ExtBuilder::default() - .existential_deposit(256 * 1) + .existential_deposit(256 * 10) .monied(true) .build(), || { System::inc_account_nonce(&2); - assert_eq!(Balances::lookup_index(1), Some(2)); - assert_eq!(Balances::lookup_index(4), None); - assert_eq!(Balances::total_balance(&2), 256 * 20); - - assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved - assert_eq!(Balances::free_balance(&2), 0); // "free" account deleted." - assert_eq!(Balances::total_balance(&2), 256 * 19 + 1); // reserve still exists. - assert_eq!(System::account_nonce(&2), 1); - - assert_ok!(Balances::transfer(Some(4).into(), 5.into(), (256 * 1 + 0x69).into())); // account 4 tries to take index 1 for account 5. - assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); - assert_eq!(Balances::lookup_index(1), Some(2)); // but fails. assert_eq!(System::account_nonce(&2), 1); + assert_eq!(Balances::total_balance(&2), 256 * 20); - assert_eq!(Balances::slash(&2, 256 * 18 + 2), None); // account 2 gets slashed - assert_eq!(Balances::total_balance(&2), 0); // "free" account deleted." + assert_ok!(Balances::transfer(Some(2).into(), 5, 256 * 10 + 1)); // index 1 (account 2) becomes zombie + assert_eq!(Balances::total_balance(&2), 0); + assert_eq!(Balances::total_balance(&5), 256 * 10 + 1); assert_eq!(System::account_nonce(&2), 0); - - assert_ok!(Balances::transfer(Some(4).into(), 6.into(), (256 * 1 + 0x69).into())); // account 4 tries to take index 1 again for account 6. - assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); - assert_eq!(Balances::lookup_index(1), Some(6)); // and succeeds. }, ); } #[test] -fn reserved_balance_should_prevent_reclaim_count2() { +fn dust_account_removal_should_work2() { with_externalities( &mut ExtBuilder::default() - .existential_deposit(256 * 1) + .existential_deposit(256 * 10) + .creation_fee(50) .monied(true) .build(), || { System::inc_account_nonce(&2); - assert_eq!(Balances::lookup_index(1), Some(2)); - assert_eq!(Balances::lookup_index(4), None); - assert_eq!(Balances::total_balance(&2), 256 * 20); - - assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved - assert_eq!(Balances::free_balance(&2), 0); // "free" account deleted." - assert_eq!(Balances::total_balance(&2), 256 * 19 + 1); // reserve still exists. - assert_eq!(System::account_nonce(&2), 1); - - assert_ok!(Balances::transfer(Some(4).into(), 5.into(), (256 * 1 + 0x69).into())); // account 4 tries to take index 1 for account 5. - assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); - assert_eq!(Balances::lookup_index(1), Some(2)); // but fails. assert_eq!(System::account_nonce(&2), 1); - - assert_eq!(Balances::slash(&2, 256 * 18 + 2), None); // account 2 gets slashed - assert_eq!(Balances::total_balance(&2), 0); // "free" account deleted." + assert_eq!(Balances::total_balance(&2), 256 * 20); + assert_ok!(Balances::transfer(Some(2).into(), 5, 256 * 10)); // index 1 (account 2) becomes zombie for 256*10 + 50(fee) < 256 * 10 (ext_deposit) + assert_eq!(Balances::total_balance(&2), 0); + assert_eq!(Balances::total_balance(&5), 256 * 10); assert_eq!(System::account_nonce(&2), 0); - - assert_ok!(Balances::transfer(Some(4).into(), 6.into(), (256 * 1 + 0x69).into())); // account 4 tries to take index 1 again for account 6. - assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); - assert_eq!(Balances::lookup_index(1), Some(6)); // and succeeds. }, ); } @@ -274,7 +147,7 @@ fn balance_transfer_works() { with_externalities(&mut ExtBuilder::default().build(), || { Balances::set_free_balance(&1, 111); Balances::increase_total_stake_by(111); - assert_ok!(Balances::transfer(Some(1).into(), 2.into(), 69.into())); + assert_ok!(Balances::transfer(Some(1).into(), 2, 69)); assert_eq!(Balances::total_balance(&1), 42); assert_eq!(Balances::total_balance(&2), 69); }); @@ -313,7 +186,7 @@ fn balance_transfer_when_reserved_should_not_work() { with_externalities(&mut ExtBuilder::default().build(), || { Balances::set_free_balance(&1, 111); assert_ok!(Balances::reserve(&1, 69)); - assert_noop!(Balances::transfer(Some(1).into(), 2.into(), 69.into()), "balance too low to send value"); + assert_noop!(Balances::transfer(Some(1).into(), 2, 69), "balance too low to send value"); }); } @@ -444,7 +317,7 @@ fn transferring_too_high_value_should_not_panic() { >::insert(2, 1); assert_err!( - Balances::transfer(Some(1).into(), 2.into(), u64::max_value().into()), + Balances::transfer(Some(1).into(), 2, u64::max_value()), "destination balance too high to receive value" ); @@ -472,7 +345,7 @@ fn account_removal_on_free_too_low() { // Transfer funds from account 1 of such amount that after this transfer // the balance of account 1 will be below the exsistential threshold. // This should lead to the removal of all balance of this account. - assert_ok!(Balances::transfer(Some(1).into(), 2.into(), 20.into())); + assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); // Verify free balance removal of account 1. assert_eq!(Balances::free_balance(&1), 0); @@ -492,7 +365,7 @@ fn transfer_overflow_isnt_exploitable() { let evil_value = u64::max_value() - 49; assert_err!( - Balances::transfer(Some(1).into(), 5.into(), evil_value.into()), + Balances::transfer(Some(1).into(), 5, evil_value), "got overflow after adding a fee to value" ); } diff --git a/srml/consensus/Cargo.toml b/srml/consensus/Cargo.toml index c7bbfe03f6c318d5c47fa4752b1aef98d3832207..9bc03d85eed470ed611edac07918e216b09d721b 100644 --- a/srml/consensus/Cargo.toml +++ b/srml/consensus/Cargo.toml @@ -6,8 +6,7 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } @@ -20,7 +19,6 @@ srml-system = { path = "../system", default-features = false } default = ["std"] std = [ "serde/std", - "serde_derive", "parity-codec/std", "substrate-primitives/std", "sr-std/std", diff --git a/srml/consensus/src/lib.rs b/srml/consensus/src/lib.rs index 0d2bd7f27932502d8568e796092aeb112e806727..e8ef08e4b9ccbf2d79c9fa68f7bc1e3c471c854e 100644 --- a/srml/consensus/src/lib.rs +++ b/srml/consensus/src/lib.rs @@ -25,10 +25,6 @@ extern crate sr_std as rstd; #[macro_use] extern crate srml_support as runtime_support; -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - extern crate parity_codec; #[macro_use] extern crate parity_codec_derive; @@ -45,16 +41,18 @@ use rstd::prelude::*; use rstd::result; use parity_codec::Encode; use runtime_support::{storage, Parameter}; -use runtime_support::dispatch::Result; use runtime_support::storage::StorageValue; use runtime_support::storage::unhashed::StorageVec; -use primitives::RuntimeString; +use primitives::CheckInherentError; use primitives::traits::{ MaybeSerializeDebug, Member, ProvideInherent, Block as BlockT }; use substrate_primitives::storage::well_known_keys; use system::{ensure_signed, ensure_inherent}; +#[cfg(any(feature = "std", test))] +use substrate_primitives::Ed25519AuthorityId; + mod mock; mod tests; @@ -66,12 +64,63 @@ impl StorageVec for AuthorityStorageVec { pub type KeyValue = (Vec, Vec); -pub trait OnOfflineValidator { - fn on_offline_validator(validator_index: usize); +/// Handling offline validator reports in a generic way. +pub trait OnOfflineReport { + fn handle_report(offline: Offline); +} + +impl OnOfflineReport for () { + fn handle_report(_: T) {} } -impl OnOfflineValidator for () { - fn on_offline_validator(_validator_index: usize) {} +/// Describes the offline-reporting extrinsic. +pub trait InherentOfflineReport { + /// The report data type passed to the runtime during block authorship. + type Inherent: codec::Codec + Parameter; + + /// Whether an inherent is empty and doesn't need to be included. + fn is_empty(inherent: &Self::Inherent) -> bool; + + /// Handle the report. + fn handle_report(report: Self::Inherent); + + /// Whether two reports are compatible. + fn check_inherent(contained: &Self::Inherent, expected: &Self::Inherent) -> Result<(), &'static str>; +} + +impl InherentOfflineReport for () { + type Inherent = (); + + fn is_empty(_inherent: &()) -> bool { true } + fn handle_report(_: ()) { } + fn check_inherent(_: &(), _: &()) -> Result<(), &'static str> { + Err("Explicit reporting not allowed") + } +} + +/// A variant of the `OfflineReport` which is useful for instant-finality blocks. +/// +/// This assumes blocks are only finalized +pub struct InstantFinalityReportVec(::rstd::marker::PhantomData); + +impl>> InherentOfflineReport for InstantFinalityReportVec { + type Inherent = Vec; + + fn is_empty(inherent: &Self::Inherent) -> bool { inherent.is_empty() } + + fn handle_report(report: Vec) { + T::handle_report(report) + } + + fn check_inherent(contained: &Self::Inherent, expected: &Self::Inherent) -> Result<(), &'static str> { + contained.iter().try_for_each(|n| + if !expected.contains(n) { + Err("Node we believe online marked offline") + } else { + Ok(()) + } + ) + } } pub type Log = RawLog< @@ -79,7 +128,7 @@ pub type Log = RawLog< >; /// A logs in this module. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +#[cfg_attr(feature = "std", derive(Serialize, Debug))] #[derive(Encode, Decode, PartialEq, Eq, Clone)] pub enum RawLog { /// Authorities set has been changed. Contains the new set of authorities. @@ -97,12 +146,12 @@ impl RawLog { // Implementation for tests outside of this crate. #[cfg(any(feature = "std", test))] -impl From> for primitives::testing::DigestItem where N: Into { +impl From> for primitives::testing::DigestItem where N: Into { fn from(log: RawLog) -> primitives::testing::DigestItem { match log { RawLog::AuthoritiesChange(authorities) => - primitives::generic::DigestItem::AuthoritiesChange - ::(authorities.into_iter() + primitives::generic::DigestItem::AuthoritiesChange( + authorities.into_iter() .map(Into::into).collect()), } } @@ -116,7 +165,9 @@ pub trait Trait: system::Trait { type Log: From> + Into>; type SessionKey: Parameter + Default + MaybeSerializeDebug; - type OnOfflineValidator: OnOfflineValidator; + /// Defines the offline-report type of the trait. + /// Set to `()` if offline-reports aren't needed for this runtime. + type InherentOfflineReport: InherentOfflineReport; } decl_storage! { @@ -146,54 +197,44 @@ decl_storage! { decl_module! { pub struct Module for enum Call where origin: T::Origin { /// Report some misbehaviour. - fn report_misbehavior(origin, _report: Vec) -> Result { + fn report_misbehavior(origin, _report: Vec) { ensure_signed(origin)?; - // TODO. - Ok(()) + // TODO: requires extension trait. } /// Note the previous block's validator missed their opportunity to propose a block. - /// This only comes in if 2/3+1 of the validators agree that no proposal was submitted. - /// It's only relevant for the previous block. - fn note_offline(origin, offline_val_indices: Vec) -> Result { + fn note_offline(origin, offline: ::Inherent) { ensure_inherent(origin)?; + assert!( >::extrinsic_index() == Some(T::NOTE_OFFLINE_POSITION), "note_offline extrinsic must be at position {} in the block", T::NOTE_OFFLINE_POSITION ); - for validator_index in offline_val_indices.into_iter() { - T::OnOfflineValidator::on_offline_validator(validator_index as usize); - } - - Ok(()) + T::InherentOfflineReport::handle_report(offline); } /// Make some on-chain remark. - fn remark(origin, _remark: Vec) -> Result { + fn remark(origin, _remark: Vec) { ensure_signed(origin)?; - Ok(()) } /// Set the number of pages in the WebAssembly environment's heap. - fn set_heap_pages(pages: u64) -> Result { + fn set_heap_pages(pages: u64) { storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode()); - Ok(()) } /// Set the new code. - pub fn set_code(new: Vec) -> Result { + pub fn set_code(new: Vec) { storage::unhashed::put_raw(well_known_keys::CODE, &new); - Ok(()) } /// Set some items of storage. - fn set_storage(items: Vec) -> Result { + fn set_storage(items: Vec) { for i in &items { storage::unhashed::put_raw(&i.0, &i.1); } - Ok(()) } fn on_finalise() { @@ -251,30 +292,34 @@ impl Module { } impl ProvideInherent for Module { - type Inherent = Vec; + type Inherent = ::Inherent; type Call = Call; - type Error = RuntimeString; fn create_inherent_extrinsics(data: Self::Inherent) -> Vec<(u32, Self::Call)> { - vec![(T::NOTE_OFFLINE_POSITION, Call::note_offline(data))] + if ::is_empty(&data) { + vec![] + } else { + vec![(T::NOTE_OFFLINE_POSITION, Call::note_offline(data))] + } } fn check_inherent Option<&Self::Call>>( - block: &Block, data: Self::Inherent, extract_function: &F - ) -> result::Result<(), Self::Error> { + block: &Block, expected: Self::Inherent, extract_function: &F + ) -> result::Result<(), CheckInherentError> { let noted_offline = block - .extrinsics().get(T::NOTE_OFFLINE_POSITION as usize) + .extrinsics() + .get(T::NOTE_OFFLINE_POSITION as usize) .and_then(|xt| match extract_function(&xt) { - Some(Call::note_offline(ref x)) => Some(&x[..]), + Some(Call::note_offline(ref x)) => Some(x), _ => None, - }).unwrap_or(&[]); + }); - noted_offline.iter().try_for_each(|n| - if !data.contains(n) { - Err("Online node marked offline".into()) - } else { - Ok(()) - } - ) + // REVIEW: perhaps we should be passing a `None` to check_inherent. + if let Some(noted_offline) = noted_offline { + ::check_inherent(¬ed_offline, &expected) + .map_err(|e| CheckInherentError::Other(e.into()))?; + } + + Ok(()) } } diff --git a/srml/consensus/src/mock.rs b/srml/consensus/src/mock.rs index e3a13d45973f87285b54baad0d669dcda718f411..9bf81cd327db5c2c51b4b0b5cd149efed33ecbb9 100644 --- a/srml/consensus/src/mock.rs +++ b/srml/consensus/src/mock.rs @@ -18,7 +18,7 @@ #![cfg(test)] -use primitives::{BuildStorage, testing::{Digest, DigestItem, Header}}; +use primitives::{BuildStorage, traits::IdentityLookup, testing::{Digest, DigestItem, Header, UintAuthorityId}}; use runtime_io; use substrate_primitives::{H256, Blake2Hasher}; use {GenesisConfig, Trait, Module, system}; @@ -28,13 +28,13 @@ impl_outer_origin!{ } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. -#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[derive(Clone, PartialEq, Eq, Debug)] pub struct Test; impl Trait for Test { const NOTE_OFFLINE_POSITION: u32 = 1; type Log = DigestItem; - type SessionKey = u64; - type OnOfflineValidator = (); + type SessionKey = UintAuthorityId; + type InherentOfflineReport = ::InstantFinalityReportVec<()>; } impl system::Trait for Test { type Origin = Origin; @@ -44,6 +44,7 @@ impl system::Trait for Test { type Hashing = ::primitives::traits::BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = (); type Log = DigestItem; @@ -53,7 +54,7 @@ pub fn new_test_ext(authorities: Vec) -> runtime_io::TestExternalities::default().build_storage().unwrap().0; t.extend(GenesisConfig::{ code: vec![], - authorities, + authorities: authorities.into_iter().map(|a| UintAuthorityId(a)).collect(), }.build_storage().unwrap().0); t.into() } diff --git a/srml/consensus/src/tests.rs b/srml/consensus/src/tests.rs index b823367c15458f792d254f824f85a2fe4dfa76dc..9dc65136fbc28221f6dd114d7f41d07404b94879 100644 --- a/srml/consensus/src/tests.rs +++ b/srml/consensus/src/tests.rs @@ -18,21 +18,20 @@ #![cfg(test)] -use primitives::{generic, testing, traits::OnFinalise}; +use primitives::{generic, testing::{self, UintAuthorityId}, traits::{OnFinalise, ProvideInherent}}; use runtime_io::with_externalities; -use substrate_primitives::H256; use mock::{Consensus, System, new_test_ext}; #[test] fn authorities_change_logged() { with_externalities(&mut new_test_ext(vec![1, 2, 3]), || { System::initialise(&1, &Default::default(), &Default::default()); - Consensus::set_authorities(&[4, 5, 6]); + Consensus::set_authorities(&[UintAuthorityId(4), UintAuthorityId(5), UintAuthorityId(6)]); Consensus::on_finalise(1); let header = System::finalise(); assert_eq!(header.digest, testing::Digest { logs: vec![ - generic::DigestItem::AuthoritiesChange::(vec![4, 5, 6]), + generic::DigestItem::AuthoritiesChange(vec![UintAuthorityId(4).into(), UintAuthorityId(5).into(), UintAuthorityId(6).into()]), ], }); }); @@ -54,8 +53,8 @@ fn authorities_change_is_not_logged_when_not_changed() { fn authorities_change_is_not_logged_when_changed_back_to_original() { with_externalities(&mut new_test_ext(vec![1, 2, 3]), || { System::initialise(&1, &Default::default(), &Default::default()); - Consensus::set_authorities(&[4, 5, 6]); - Consensus::set_authorities(&[1, 2, 3]); + Consensus::set_authorities(&[UintAuthorityId(4), UintAuthorityId(5), UintAuthorityId(6)]); + Consensus::set_authorities(&[UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); Consensus::on_finalise(1); let header = System::finalise(); assert_eq!(header.digest, testing::Digest { @@ -63,3 +62,12 @@ fn authorities_change_is_not_logged_when_changed_back_to_original() { }); }); } + +#[test] +fn offline_report_can_be_excluded() { + with_externalities(&mut new_test_ext(vec![1, 2, 3]), || { + System::initialise(&1, &Default::default(), &Default::default()); + assert!(Consensus::create_inherent_extrinsics(Vec::new()).is_empty()); + assert_eq!(Consensus::create_inherent_extrinsics(vec![0]).len(), 1); + }); +} diff --git a/srml/contract/COMPLEXITY.md b/srml/contract/COMPLEXITY.md index f805eb45f04682476f2a61dd0fa0ec995937666c..511f4e258fbdc5dbff21f5c101ae54d5e545c09f 100644 --- a/srml/contract/COMPLEXITY.md +++ b/srml/contract/COMPLEXITY.md @@ -1,3 +1,5 @@ +# Complexity + This analysis is on the computing and memory complexity of specific procedures. It provides a rough estimate of operations performed in general and especially focusing on DB reads and writes. It is also an attempt to estimate the memory consumption at its peak. 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. @@ -132,53 +134,48 @@ Consists of dropping (in the Rust sense) of the `AccountDb`. This function performs the following steps: 1. Querying source and destination balances from an overlay (see `get_balance`), -2. Querying fee for the case. (This hits DB unless pre-loaded) -2. Querying `existential_deposit`. (This hits DB unless pre-loaded) +2. Querying `existential_deposit`. 3. Executing `ensure_account_liquid` hook. 4. Updating source and destination balance in the overlay (see `set_balance`). **Note** that the complexity of executing `ensure_account_liquid` hook should be considered separately. -In the course of the execution this function can perform up to 4 DB reads: 2x `get_balance`, fee and `existential_deposit`. The last two can be pre-loaded pushing the cost of loading to a higher level and making it a one time. It can also induce up to 2 DB writes via `set_balance` if flushed to the storage. +In the course of the execution this function can perform up to 2 DB reads to `get_balance` of source and destination accounts. It can also induce up to 2 DB writes via `set_balance` if flushed to the storage. Moreover, if the source balance goes below `existential_deposit` then the account will be deleted along with all its storage which requires time proportional to the number of storage entries of that account. Assuming marshaled size of a balance value is of the constant size we can neglect its effect on the performance. -**complexity**: up to 4 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. For the current `AccountDb` implementation computing complexity also depends on the depth of the `AccountDb` cascade. Memorywise it can be assumed to be constant. ## Call This function receives input data for the contract execution. The execution consists of the following steps: -1. Querying `MaxDepth` and `call_base_fee`. (These hit DB unless pre-loaded) -2. Loading code from the DB. -3. `transfer`-ing funds between the caller and the destination account. -4. Executing the code of the destination account. -5. Committing overlayed changed to the underlying `AccountDb`. +1. Loading code from the DB. +2. `transfer`-ing funds between the caller and the destination account. +3. Executing the code of the destination account. +4. Committing overlayed changed to the underlying `AccountDb`. **Note** that the complexity of executing the contract code should be considered separately. -The execution of this function will involve 2 DB reads for querying `MaxDepth` and `MaxDepth` constants. These values can be pre-loaded pushing the cost of loading to a higher level and making it a one time. - Loading code most probably will trigger a DB read, since the code is immutable and therefore will not get into the cache (unless a suicide removes it). -Also, `transfer` can make up to 4 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. +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. -**complexity**: Up to 7 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. +**complexity**: Up to 3 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. ## Create This function takes the code of the constructor and input data. Creation of a contract consists of the following steps: -1. Querying `MaxDepth` and `create_base_fee`. (These hit DB unless pre-loaded) -2. Calling `DetermineContractAddress` hook to determine an address for the contract, -3. `transfer`-ing funds between self and the newly created contract. -4. Executing the constructor code. This will yield the final code of the code. -5. Storing the code for the newly created contract in the overlay. -6. Committing overlayed changed to the underlying `AccountDb`. +1. Calling `DetermineContractAddress` hook to determine an address for the contract, +2. `transfer`-ing funds between self and the newly created contract. +3. Executing the constructor code. This will yield the final code of the code. +4. Storing the code for the newly created contract in the overlay. +5. Committing overlayed changed to the underlying `AccountDb`. **Note** that the complexity of executing the constructor code should be considered separately. @@ -186,15 +183,13 @@ This function takes the code of the constructor and input data. Creation of a co **Note** that the constructor returns code in the owned form and it's obtained via return facilities, which should have take fee for the return value. -The execution of this function involves 2 DB reads for querying `create_base_fee` and `MaxDepth` constants. These values can be pre-loaded pushing the cost of loading to a higher level and making it a one time. - -Also, `transfer` can make up to 4 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. +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. 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. -**complexity**: Up to 6 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. +**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 @@ -280,6 +275,12 @@ 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_input_size **complexity**: This function is of constant complexity. diff --git a/srml/contract/Cargo.toml b/srml/contract/Cargo.toml index 51a0b172db3f2ac0175220aace20530448c82e43..2a265cb0fac53f143165518b1120599453ae862e 100644 --- a/srml/contract/Cargo.toml +++ b/srml/contract/Cargo.toml @@ -5,9 +5,8 @@ authors = ["Parity Technologies "] [dependencies] serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } -pwasm-utils = { version = "0.3", default-features = false } -parity-codec = { version = "2.1", default-features = false } +pwasm-utils = { version = "0.6.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } parity-wasm = { version = "0.31", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } @@ -20,13 +19,13 @@ srml-system = { path = "../system", default-features = false } srml-balances = { path = "../balances", default-features = false } [dev-dependencies] -wabt = "0.4" +wabt = "~0.7.4" assert_matches = "1.1" +hex-literal = "0.1.0" [features] default = ["std"] std = [ - "serde_derive", "serde/std", "parity-codec/std", "parity-codec-derive/std", diff --git a/srml/contract/src/account_db.rs b/srml/contract/src/account_db.rs index d7ff094003c97e52d014773220a63ea0cd644eea..6142abcbe22236cd669026e60822ce2fb59a2c1a 100644 --- a/srml/contract/src/account_db.rs +++ b/srml/contract/src/account_db.rs @@ -16,17 +16,17 @@ //! Auxilliaries to help with managing partial changes to accounts state. -use super::{CodeOf, StorageOf, Trait}; -use double_map::StorageDoubleMap; +use super::{CodeHash, CodeHashOf, StorageOf, Trait}; use rstd::cell::RefCell; use rstd::collections::btree_map::{BTreeMap, Entry}; use rstd::prelude::*; -use runtime_support::StorageMap; +use runtime_support::{StorageMap, StorageDoubleMap}; use {balances, system}; pub struct ChangeEntry { balance: Option, - code: Option>, + /// In the case the outer option is None, the code_hash remains untouched, while providing `Some(None)` signifies a removing of the code in question + code: Option>>, storage: BTreeMap, Option>>, } @@ -45,7 +45,7 @@ pub type ChangeSet = BTreeMap<::AccountId, ChangeEntry pub trait AccountDb { fn get_storage(&self, account: &T::AccountId, location: &[u8]) -> Option>; - fn get_code(&self, account: &T::AccountId) -> Vec; + fn get_code(&self, account: &T::AccountId) -> Option>; fn get_balance(&self, account: &T::AccountId) -> T::Balance; fn commit(&mut self, change_set: ChangeSet); @@ -56,8 +56,8 @@ impl AccountDb for DirectAccountDb { fn get_storage(&self, account: &T::AccountId, location: &[u8]) -> Option> { >::get(account.clone(), location.to_vec()) } - fn get_code(&self, account: &T::AccountId) -> Vec { - >::get(account) + fn get_code(&self, account: &T::AccountId) -> Option> { + >::get(account) } fn get_balance(&self, account: &T::AccountId) -> T::Balance { balances::Module::::free_balance(account) @@ -69,13 +69,17 @@ impl AccountDb for DirectAccountDb { balances::Module::::set_free_balance_creating(&address, balance) { // Account killed. This will ultimately lead to calling `OnFreeBalanceZero` callback - // which will make removal of CodeOf and StorageOf for this account. + // which will make removal of CodeHashOf and StorageOf for this account. // In order to avoid writing over the deleted properties we `continue` here. continue; } } if let Some(code) = changed.code { - >::insert(&address, &code); + if let Some(code) = code { + >::insert(&address, code); + } else { + >::remove(&address); + } } for (k, v) in changed.storage.into_iter() { if let Some(value) = v { @@ -117,7 +121,7 @@ impl<'a, T: Trait> OverlayAccountDb<'a, T> { .storage .insert(location, value); } - pub fn set_code(&mut self, account: &T::AccountId, code: Vec) { + pub fn set_code(&mut self, account: &T::AccountId, code: Option>) { self.local .borrow_mut() .entry(account.clone()) @@ -142,7 +146,7 @@ impl<'a, T: Trait> AccountDb for OverlayAccountDb<'a, T> { .cloned() .unwrap_or_else(|| self.underlying.get_storage(account, location)) } - fn get_code(&self, account: &T::AccountId) -> Vec { + fn get_code(&self, account: &T::AccountId) -> Option> { self.local .borrow() .get(account) diff --git a/srml/contract/src/exec.rs b/srml/contract/src/exec.rs index cc74142947a86838234573e89cbb27a3767743b7..af900081d3e7c330f4f807336aa22e6a9c4acfc2 100644 --- a/srml/contract/src/exec.rs +++ b/srml/contract/src/exec.rs @@ -14,68 +14,284 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use super::{MaxDepth, ContractAddressFor, Module, Trait, Event, RawEvent}; -use account_db::{AccountDb, OverlayAccountDb}; -use gas::GasMeter; -use vm; +use super::{CodeHash, Config, ContractAddressFor, Event, RawEvent, Trait}; +use account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}; +use gas::{GasMeter, Token, approx_gas_for_balance}; -use rstd::prelude::*; -use runtime_primitives::traits::{Zero, CheckedAdd, CheckedSub}; -use runtime_support::StorageValue; use balances::{self, EnsureAccountLiquid}; +use rstd::prelude::*; +use runtime_primitives::traits::{CheckedAdd, CheckedSub, Zero}; + +pub type BalanceOf = ::Balance; +pub type AccountIdOf = ::AccountId; +pub type CallOf = ::Call; + +#[cfg_attr(test, derive(Debug))] +pub struct InstantiateReceipt { + pub address: AccountId, +} + +#[cfg_attr(test, derive(Debug))] +pub struct CallReceipt { + /// Output data received as a result of a call. + pub output_data: Vec, +} + +/// An interface that provides access to the external environment in which the +/// smart-contract is executed. +/// +/// This interface is specialised to an account of the executing code, so all +/// operations are implicitly performed on that account. +pub trait Ext { + type T: Trait; + + /// Returns the storage entry of the executing account by the given `key`. + /// + /// Returns `None` if the `key` wasn't previously set by `set_storage` or + /// was deleted. + fn get_storage(&self, key: &[u8]) -> Option>; + + /// Sets the storage entry by the given key to the specified value. + /// + /// If `value` is `None` then the storage entry is deleted. + fn set_storage(&mut self, key: &[u8], value: Option>); + + /// Instantiate a contract from the given code. + /// + /// The newly created account will be associated with `code`. `value` specifies the amount of value + /// transfered from this to the newly created account (also known as endowment). + fn instantiate( + &mut self, + code: &CodeHash, + value: BalanceOf, + gas_meter: &mut GasMeter, + input_data: &[u8], + ) -> Result>, &'static str>; + + /// Call (possibly transfering some amount of funds) into the specified account. + fn call( + &mut self, + to: &AccountIdOf, + value: BalanceOf, + gas_meter: &mut GasMeter, + input_data: &[u8], + empty_output_buf: EmptyOutputBuf, + ) -> Result; + + /// Notes a call dispatch. + fn note_dispatch_call(&mut self, call: CallOf); -// TODO: Add logs -pub struct CreateReceipt { - pub address: T::AccountId, + /// Returns a reference to the account id of the caller. + fn caller(&self) -> &AccountIdOf; + + /// Returns a reference to the account id of the current contract. + fn address(&self) -> &AccountIdOf; + + + /// Returns the balance of the current contract. + /// + /// The `value_transferred` is already added. + fn balance(&self) -> BalanceOf; + + /// Returns the value transfered along with this call or as endowment. + fn value_transferred(&self) -> BalanceOf; +} + +/// Loader is a companion of the `Vm` trait. It loads an appropriate abstract +/// executable to be executed by an accompanying `Vm` implementation. +pub trait Loader { + type Executable; + + /// Load the initializer portion of the code specified by the `code_hash`. This + /// executable is called upon instantiation. + fn load_init(&self, code_hash: &CodeHash) -> Result; + /// Load the main portion of the code specified by the `code_hash`. This executable + /// is called for each call to a contract. + fn load_main(&self, code_hash: &CodeHash) -> Result; +} + +/// An `EmptyOutputBuf` is used as an optimization for reusing empty vectors when +/// available. +/// +/// You can create this structure from a spare vector if you have any and then +/// you can fill it (only once), converting it to `OutputBuf`. +pub struct EmptyOutputBuf(Vec); + +impl EmptyOutputBuf { + /// Create an output buffer from a spare vector which is not longer needed. + /// + /// All contents are discarded, but capacity is preserved. + pub fn from_spare_vec(mut v: Vec) -> Self { + v.clear(); + EmptyOutputBuf(v) + } + + /// Create an output buffer ready for receiving a result. + /// + /// Use this function to create output buffer if you don't have a spare + /// vector. Otherwise, use `from_spare_vec`. + pub fn new() -> Self { + EmptyOutputBuf(Vec::new()) + } + + /// Write to the buffer result of the specified size. + /// + /// Calls closure with the buffer of the requested size. + pub fn fill Result<(), E>>(mut self, size: usize, f: F) -> Result { + assert!(self.0.len() == 0, "the vector is always cleared; it's written only once"); + self.0.resize(size, 0); + f(&mut self.0).map(|()| OutputBuf(self.0)) + } } -// TODO: Add logs. -pub struct CallReceipt; +/// `OutputBuf` is the end result of filling an `EmptyOutputBuf`. +pub struct OutputBuf(Vec); -pub struct ExecutionContext<'a, T: Trait + 'a> { - // typically should be dest +#[must_use] +pub enum VmExecResult { + Ok, + Returned(OutputBuf), + /// A program executed some forbidden operation. + /// + /// This can include, e.g.: division by 0, OOB access or failure to satisfy some precondition + /// of a system call. + /// + /// Contains some vm-specific description of an trap. + Trap(&'static str), +} + +impl VmExecResult { + pub fn into_result(self) -> Result, &'static str> { + match self { + VmExecResult::Ok => Ok(Vec::new()), + VmExecResult::Returned(buf) => Ok(buf.0), + VmExecResult::Trap(description) => Err(description), + } + } +} + +/// A trait that represent a virtual machine. +/// +/// You can view a virtual machine as something that takes code, an input data buffer, +/// queries it and/or performs actions on the given `Ext` and optionally +/// returns an output data buffer. The type of code depends on the particular virtual machine. +/// +/// Execution of code can end by either implicit termination (that is, reached the end of +/// executable), explicit termination via returning a buffer or termination due to a trap. +/// +/// You can optionally provide a vector for collecting output if a spare is available. If you don't have +/// it will be created anyway. +pub trait Vm { + type Executable; + + fn execute>( + &self, + exec: &Self::Executable, + ext: &mut E, + input_data: &[u8], + empty_output_buf: EmptyOutputBuf, + gas_meter: &mut GasMeter, + ) -> VmExecResult; +} + +#[cfg_attr(test, derive(Debug, PartialEq, Eq))] +#[derive(Copy, Clone)] +pub enum ExecFeeToken { + /// Base fee charged for a call. + Call, + /// Base fee charged for a instantiate. + Instantiate, +} + +impl Token for ExecFeeToken { + type Metadata = Config; + #[inline] + fn calculate_amount(&self, metadata: &Config) -> T::Gas { + match *self { + ExecFeeToken::Call => metadata.call_base_fee, + ExecFeeToken::Instantiate => metadata.instantiate_base_fee, + } + } +} + +pub struct ExecutionContext<'a, T: Trait + 'a, V, L> { pub self_account: T::AccountId, pub overlay: OverlayAccountDb<'a, T>, pub depth: usize, pub events: Vec>, + pub calls: Vec<(T::AccountId, T::Call)>, + pub config: &'a Config, + pub vm: &'a V, + pub loader: &'a L, } -impl<'a, T: Trait> ExecutionContext<'a, T> { - /// Make a call to the specified address. +impl<'a, T, E, V, L> ExecutionContext<'a, T, V, L> +where + T: Trait, + L: Loader, + V: Vm, +{ + /// Create the top level execution context. + /// + /// The specified `origin` address will be used as `sender` for + pub fn top_level(origin: T::AccountId, cfg: &'a Config, vm: &'a V, loader: &'a L) -> Self { + let overlay = OverlayAccountDb::::new(&DirectAccountDb); + ExecutionContext { + self_account: origin, + depth: 0, + overlay, + events: Vec::new(), + calls: Vec::new(), + config: &cfg, + vm: &vm, + loader: &loader, + } + } + + fn nested(&self, overlay: OverlayAccountDb<'a, T>, dest: T::AccountId) -> Self { + ExecutionContext { + overlay: overlay, + self_account: dest, + depth: self.depth + 1, + events: Vec::new(), + calls: Vec::new(), + config: self.config, + vm: self.vm, + loader: self.loader, + } + } + + /// Make a call to the specified address, optionally transfering some funds. pub fn call( &mut self, - caller: T::AccountId, dest: T::AccountId, value: T::Balance, gas_meter: &mut GasMeter, - data: &[u8], - output_data: &mut Vec, + input_data: &[u8], + empty_output_buf: EmptyOutputBuf, ) -> Result { - if self.depth == >::get() as usize { + if self.depth == self.config.max_depth as usize { return Err("reached maximum depth, cannot make a call"); } - let call_base_fee = >::call_base_fee(); - if gas_meter.charge(call_base_fee).is_out_of_gas() { + if gas_meter + .charge(self.config, ExecFeeToken::Call) + .is_out_of_gas() + { return Err("not enough gas to pay base call fee"); } - let dest_code = self.overlay.get_code(&dest); + let dest_code_hash = self.overlay.get_code(&dest); + let mut output_data = Vec::new(); - let (change_set, events) = { + let (change_set, events, calls) = { let mut overlay = OverlayAccountDb::new(&self.overlay); - - let mut nested = ExecutionContext { - overlay: overlay, - self_account: dest.clone(), - depth: self.depth + 1, - events: Vec::new(), - }; + let mut nested = self.nested(overlay, dest.clone()); if value > T::Balance::zero() { transfer( gas_meter, - false, + TransferCause::Call, &self.self_account, &dest, value, @@ -83,108 +299,151 @@ impl<'a, T: Trait> ExecutionContext<'a, T> { )?; } - if !dest_code.is_empty() { - vm::execute( - &dest_code, - data, - output_data, - &mut CallContext { - ctx: &mut nested, - _caller: caller, - }, - &::vm::Config::default(), - gas_meter, - ).map_err(|_| "vm execute returned error while call")?; + if let Some(dest_code_hash) = dest_code_hash { + let executable = self.loader.load_main(&dest_code_hash)?; + output_data = self + .vm + .execute( + &executable, + &mut CallContext { + ctx: &mut nested, + caller: self.self_account.clone(), + value_transferred: value, + }, + input_data, + empty_output_buf, + gas_meter, + ) + .into_result()?; } - (nested.overlay.into_change_set(), nested.events) + (nested.overlay.into_change_set(), nested.events, nested.calls) }; self.overlay.commit(change_set); self.events.extend(events); + self.calls.extend(calls); - Ok(CallReceipt) + Ok(CallReceipt { output_data }) } - pub fn create( + pub fn instantiate( &mut self, - caller: T::AccountId, endowment: T::Balance, gas_meter: &mut GasMeter, - init_code: &[u8], - data: &[u8], - ) -> Result, &'static str> { - if self.depth == >::get() as usize { + code_hash: &CodeHash, + input_data: &[u8], + ) -> Result, &'static str> { + if self.depth == self.config.max_depth as usize { return Err("reached maximum depth, cannot create"); } - let create_base_fee = >::create_base_fee(); - if gas_meter.charge(create_base_fee).is_out_of_gas() { - return Err("not enough gas to pay base create fee"); + if gas_meter + .charge(self.config, ExecFeeToken::Instantiate) + .is_out_of_gas() + { + return Err("not enough gas to pay base instantiate fee"); } - let dest = T::DetermineContractAddress::contract_address_for(init_code, data, &self.self_account); + let dest = T::DetermineContractAddress::contract_address_for( + code_hash, + input_data, + &self.self_account, + ); - if !self.overlay.get_code(&dest).is_empty() { + if self.overlay.get_code(&dest).is_some() { // It should be enough to check only the code. return Err("contract already exists"); } - let (change_set, events) = { + let (change_set, events, calls) = { let mut overlay = OverlayAccountDb::new(&self.overlay); + overlay.set_code(&dest, Some(code_hash.clone())); + let mut nested = self.nested(overlay, dest.clone()); - let mut nested = ExecutionContext { - overlay: overlay, - self_account: dest.clone(), - depth: self.depth + 1, - events: Vec::new(), - }; + // Send funds unconditionally here. If the `endowment` is below existential_deposit + // then error will be returned here. + transfer( + gas_meter, + TransferCause::Instantiate, + &self.self_account, + &dest, + endowment, + &mut nested, + )?; - if endowment > T::Balance::zero() { - transfer( + let executable = self.loader.load_init(&code_hash)?; + self.vm + .execute( + &executable, + &mut CallContext { + ctx: &mut nested, + caller: self.self_account.clone(), + value_transferred: endowment, + }, + input_data, + EmptyOutputBuf::new(), gas_meter, - true, - &self.self_account, - &dest, - endowment, - &mut nested, - )?; - } + ) + .into_result()?; - let mut contract_code = Vec::new(); - vm::execute( - init_code, - data, - &mut contract_code, - &mut CallContext { - ctx: &mut nested, - _caller: caller, - }, - &::vm::Config::default(), - gas_meter, - ).map_err(|_| "vm execute returned error while create")?; + // Deposit an instantiation event. + nested.events.push(RawEvent::Instantiated(self.self_account.clone(), dest.clone())); - nested.overlay.set_code(&dest, contract_code); - (nested.overlay.into_change_set(), nested.events) + (nested.overlay.into_change_set(), nested.events, nested.calls) }; self.overlay.commit(change_set); self.events.extend(events); + self.calls.extend(calls); + + Ok(InstantiateReceipt { address: dest }) + } +} + +#[cfg_attr(test, derive(Debug, PartialEq, Eq))] +#[derive(Copy, Clone)] +pub enum TransferFeeKind { + ContractInstantiate, + AccountCreate, + Transfer, +} + +#[cfg_attr(test, derive(Debug, PartialEq, Eq))] +#[derive(Copy, Clone)] +pub struct TransferFeeToken { + kind: TransferFeeKind, + gas_price: Balance, +} - Ok(CreateReceipt { - address: dest, - }) +impl Token for TransferFeeToken { + type Metadata = Config; + + #[inline] + fn calculate_amount(&self, metadata: &Config) -> T::Gas { + let balance_fee = match self.kind { + TransferFeeKind::ContractInstantiate => metadata.contract_account_instantiate_fee, + TransferFeeKind::AccountCreate => metadata.account_create_fee, + TransferFeeKind::Transfer => metadata.transfer_fee, + }; + approx_gas_for_balance::(self.gas_price, balance_fee) } } +/// Describes possible transfer causes. +enum TransferCause { + Call, + Instantiate, +} + /// Transfer some funds from `transactor` to `dest`. /// /// All balance changes are performed in the `overlay`. /// /// This function also handles charging the fee. The fee depends -/// on whether the transfer happening because of contract creation -/// (transfering endowment), specified by `contract_create` flag, -/// or because of a transfer via `call`. +/// on whether the transfer happening because of contract instantiation +/// (transfering endowment) or because of a transfer via `call`. This +/// is specified using the `cause` parameter. /// /// NOTE: that the fee is denominated in `T::Balance` units, but /// charged in `T::Gas` from the provided `gas_meter`. This means @@ -193,37 +452,47 @@ impl<'a, T: Trait> ExecutionContext<'a, T> { /// NOTE: that we allow for draining all funds of the contract so it /// can go below existential deposit, essentially giving a contract /// the chance to give up it's life. -fn transfer<'a, T: Trait>( +fn transfer<'a, T: Trait, V: Vm, L: Loader>( gas_meter: &mut GasMeter, - contract_create: bool, + cause: TransferCause, transactor: &T::AccountId, dest: &T::AccountId, value: T::Balance, - ctx: &mut ExecutionContext<'a, T>, + ctx: &mut ExecutionContext<'a, T, V, L>, ) -> Result<(), &'static str> { + use self::TransferCause::*; + use self::TransferFeeKind::*; + let to_balance = ctx.overlay.get_balance(dest); - // This flag is totally distinct from `contract_create`, which shows if this function - // is called from `CREATE` procedure. - // // `would_create` indicates whether the account will be created if this transfer gets executed. - // For example, we can create a contract at the address which already has some funds. In this - // case `contract_create` will be `true` but `would_create` will be `false`. Another example would - // be when this function is called from `CALL`, but `dest` doesn't exist yet. In this case - // `contract_create` will be `false` but `would_create` will be `true`. + // This flag is orthogonal to `cause. + // For example, we can instantiate a contract at the address which already has some funds. In this + // `would_create` will be `false`. Another example would be when this function is called from `call`, + // and account with the address `dest` doesn't exist yet `would_create` will be `true`. let would_create = to_balance.is_zero(); - let fee: T::Balance = if contract_create { - >::contract_fee() - } else { - if would_create { - >::creation_fee() - } else { - >::transfer_fee() + let token = { + let kind: TransferFeeKind = match cause { + // If this function is called from `Instantiate` routine, then we always + // charge contract account creation fee. + Instantiate => ContractInstantiate, + + // Otherwise the fee depends on whether we create a new account or transfer + // to an existing one. + Call => if would_create { + TransferFeeKind::AccountCreate + } else { + TransferFeeKind::Transfer + }, + }; + TransferFeeToken { + kind, + gas_price: gas_meter.gas_price(), } }; - if gas_meter.charge_by_balance(fee).is_out_of_gas() { + if gas_meter.charge(ctx.config, token).is_out_of_gas() { return Err("not enough gas to pay transfer fee"); } @@ -233,7 +502,7 @@ fn transfer<'a, T: Trait>( Some(b) => b, None => return Err("balance too low to send value"), }; - if would_create && value < >::existential_deposit() { + if would_create && value < ctx.config.existential_deposit { return Err("value too low to create account"); } ::EnsureAccountLiquid::ensure_account_liquid(transactor)?; @@ -246,18 +515,25 @@ fn transfer<'a, T: Trait>( if transactor != dest { ctx.overlay.set_balance(transactor, new_from_balance); ctx.overlay.set_balance(dest, new_to_balance); - ctx.events.push(RawEvent::Transfer(transactor.clone(), dest.clone(), value)); + ctx.events + .push(RawEvent::Transfer(transactor.clone(), dest.clone(), value)); } Ok(()) } -struct CallContext<'a, 'b: 'a, T: Trait + 'b> { - ctx: &'a mut ExecutionContext<'b, T>, - _caller: T::AccountId, +struct CallContext<'a, 'b: 'a, T: Trait + 'b, V: Vm + 'b, L: Loader> { + ctx: &'a mut ExecutionContext<'b, T, V, L>, + caller: T::AccountId, + value_transferred: T::Balance, } -impl<'a, 'b: 'a, T: Trait + 'b> vm::Ext for CallContext<'a, 'b, T> { +impl<'a, 'b: 'a, T, E, V, L> Ext for CallContext<'a, 'b, T, V, L> +where + T: Trait + 'b, + V: Vm, + L: Loader, +{ type T = T; fn get_storage(&self, key: &[u8]) -> Option> { @@ -270,17 +546,14 @@ impl<'a, 'b: 'a, T: Trait + 'b> vm::Ext for CallContext<'a, 'b, T> { .set_storage(&self.ctx.self_account, key.to_vec(), value) } - fn create( + fn instantiate( &mut self, - code: &[u8], + code_hash: &CodeHash, endowment: T::Balance, gas_meter: &mut GasMeter, - data: &[u8], - ) -> Result, ()> { - let caller = self.ctx.self_account.clone(); - self.ctx - .create(caller, endowment, gas_meter, code, &data) - .map_err(|_| ()) + input_data: &[u8], + ) -> Result>, &'static str> { + self.ctx.instantiate(endowment, gas_meter, code_hash, input_data) } fn call( @@ -288,13 +561,756 @@ impl<'a, 'b: 'a, T: Trait + 'b> vm::Ext for CallContext<'a, 'b, T> { to: &T::AccountId, value: T::Balance, gas_meter: &mut GasMeter, - data: &[u8], - output_data: &mut Vec, - ) -> Result<(), ()> { - let caller = self.ctx.self_account.clone(); + input_data: &[u8], + empty_output_buf: EmptyOutputBuf, + ) -> Result { self.ctx - .call(caller, to.clone(), value, gas_meter, data, output_data) - .map_err(|_| ()) - .map(|_| ()) + .call(to.clone(), value, gas_meter, input_data, empty_output_buf) + } + + /// Notes a call dispatch. + fn note_dispatch_call(&mut self, call: CallOf) { + self.ctx.calls.push( + (self.ctx.self_account.clone(), call) + ); + } + + fn address(&self) -> &T::AccountId { + &self.ctx.self_account + } + + fn caller(&self) -> &T::AccountId { + &self.caller + } + + fn balance(&self) -> T::Balance { + self.ctx.overlay.get_balance(&self.ctx.self_account) + } + + fn value_transferred(&self) -> T::Balance { + self.value_transferred + } +} + +/// These tests exercise the executive layer. +/// +/// 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::{ + ExecFeeToken, ExecutionContext, Ext, Loader, EmptyOutputBuf, TransferFeeKind, TransferFeeToken, + Vm, VmExecResult, InstantiateReceipt, RawEvent, + }; + use account_db::AccountDb; + use gas::GasMeter; + use runtime_io::with_externalities; + use std::cell::RefCell; + use std::collections::HashMap; + use std::marker::PhantomData; + use std::rc::Rc; + use tests::{ExtBuilder, Test}; + use {CodeHash, Config}; + + const ALICE: u64 = 1; + const BOB: u64 = 2; + const CHARLIE: u64 = 3; + + struct MockCtx<'a> { + ext: &'a mut dyn Ext, + input_data: &'a [u8], + empty_output_buf: Option, + gas_meter: &'a mut GasMeter, + } + + #[derive(Clone)] + struct MockExecutable<'a>(Rc VmExecResult + 'a>); + + impl<'a> MockExecutable<'a> { + fn new(f: impl Fn(MockCtx) -> VmExecResult + 'a) -> Self { + MockExecutable(Rc::new(f)) + } + } + + struct MockLoader<'a> { + map: HashMap, MockExecutable<'a>>, + counter: u64, + } + + impl<'a> MockLoader<'a> { + fn empty() -> Self { + MockLoader { + map: HashMap::new(), + counter: 0, + } + } + + fn insert(&mut self, f: impl Fn(MockCtx) -> VmExecResult + 'a) -> CodeHash { + // Generate code hashes as monotonically increasing values. + let code_hash = self.counter.into(); + + self.counter += 1; + self.map.insert(code_hash, MockExecutable::new(f)); + code_hash + } + } + + struct MockVm<'a> { + _marker: PhantomData<&'a ()>, + } + + impl<'a> MockVm<'a> { + fn new() -> Self { + MockVm { _marker: PhantomData } + } + } + + impl<'a> Loader for MockLoader<'a> { + type Executable = MockExecutable<'a>; + + fn load_init(&self, code_hash: &CodeHash) -> Result { + self.map + .get(code_hash) + .cloned() + .ok_or_else(|| "code not found") + } + fn load_main(&self, code_hash: &CodeHash) -> Result { + self.map + .get(code_hash) + .cloned() + .ok_or_else(|| "code not found") + } + } + + impl<'a> Vm for MockVm<'a> { + type Executable = MockExecutable<'a>; + + fn execute>( + &self, + exec: &MockExecutable, + ext: &mut E, + input_data: &[u8], + empty_output_buf: EmptyOutputBuf, + gas_meter: &mut GasMeter, + ) -> VmExecResult { + (exec.0)(MockCtx { + ext, + input_data, + empty_output_buf: Some(empty_output_buf), + gas_meter, + }) + } + } + + #[test] + fn it_works() { + let value = Default::default(); + let mut gas_meter = GasMeter::::with_limit(10000, 1); + let data = vec![]; + + let vm = MockVm::new(); + + let test_data = Rc::new(RefCell::new(vec![0usize])); + + let mut loader = MockLoader::empty(); + let exec_ch = loader.insert(|_ctx| { + test_data.borrow_mut().push(1); + VmExecResult::Ok + }); + + with_externalities(&mut ExtBuilder::default().build(), || { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_code(&BOB, Some(exec_ch)); + + assert_matches!( + ctx.call(BOB, value, &mut gas_meter, &data, EmptyOutputBuf::new()), + Ok(_) + ); + }); + + assert_eq!(&*test_data.borrow(), &vec![0, 1]); + } + + #[test] + fn base_fees() { + let origin = ALICE; + let dest = BOB; + + // This test verifies that base fee for call is taken. + with_externalities(&mut ExtBuilder::default().build(), || { + let vm = MockVm::new(); + 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); + + let mut gas_meter = GasMeter::::with_limit(1000, 1); + + let result = ctx.call(dest, 0, &mut gas_meter, &[], EmptyOutputBuf::new()); + assert_matches!(result, Ok(_)); + + let mut toks = gas_meter.tokens().iter(); + match_tokens!(toks, ExecFeeToken::Call,); + }); + + // This test verifies that base fee for instantiation is taken. + with_externalities(&mut ExtBuilder::default().build(), || { + let mut loader = MockLoader::empty(); + let code = loader.insert(|_| VmExecResult::Ok); + + let vm = MockVm::new(); + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + + ctx.overlay.set_balance(&origin, 100); + + let mut gas_meter = GasMeter::::with_limit(1000, 1); + + let result = ctx.instantiate(0, &mut gas_meter, &code, &[]); + assert_matches!(result, Ok(_)); + + let mut toks = gas_meter.tokens().iter(); + match_tokens!(toks, ExecFeeToken::Instantiate,); + }); + } + + #[test] + fn transfer_works() { + // This test verifies that a contract is able to transfer + // some funds to another account. + let origin = ALICE; + let dest = BOB; + + let vm = MockVm::new(); + let loader = MockLoader::empty(); + + with_externalities(&mut ExtBuilder::default().build(), || { + 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); + + let result = ctx.call( + dest, + 55, + &mut GasMeter::::with_limit(1000, 1), + &[], + EmptyOutputBuf::new(), + ); + assert_matches!(result, Ok(_)); + assert_eq!(ctx.overlay.get_balance(&origin), 45); + assert_eq!(ctx.overlay.get_balance(&dest), 55); + }); + } + + #[test] + fn transfer_fees() { + let origin = ALICE; + let dest = BOB; + + // This test sends 50 units of currency to a non-existent account. + // This should create lead to creation of a new account thus + // a fee should be charged. + with_externalities( + &mut ExtBuilder::default().existential_deposit(15).build(), + || { + let vm = MockVm::new(); + 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); + + let mut gas_meter = GasMeter::::with_limit(1000, 1); + + let result = ctx.call(dest, 50, &mut gas_meter, &[], EmptyOutputBuf::new()); + assert_matches!(result, Ok(_)); + + let mut toks = gas_meter.tokens().iter(); + match_tokens!( + toks, + ExecFeeToken::Call, + TransferFeeToken { + kind: TransferFeeKind::AccountCreate, + gas_price: 1u64 + }, + ); + }, + ); + + // This one is similar to the previous one but transfer to an existing account. + // In this test we expect that a regular transfer fee is charged. + with_externalities( + &mut ExtBuilder::default().existential_deposit(15).build(), + || { + let vm = MockVm::new(); + 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); + + let mut gas_meter = GasMeter::::with_limit(1000, 1); + + let result = ctx.call(dest, 50, &mut gas_meter, &[], EmptyOutputBuf::new()); + assert_matches!(result, Ok(_)); + + let mut toks = gas_meter.tokens().iter(); + match_tokens!( + toks, + ExecFeeToken::Call, + TransferFeeToken { + kind: TransferFeeKind::Transfer, + gas_price: 1u64 + }, + ); + }, + ); + + // This test sends 50 units of currency as an endownment to a newly + // created contract. + with_externalities( + &mut ExtBuilder::default().existential_deposit(15).build(), + || { + let mut loader = MockLoader::empty(); + let code = loader.insert(|_| VmExecResult::Ok); + + let vm = MockVm::new(); + 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); + + let mut gas_meter = GasMeter::::with_limit(1000, 1); + + let result = ctx.instantiate(50, &mut gas_meter, &code, &[]); + assert_matches!(result, Ok(_)); + + let mut toks = gas_meter.tokens().iter(); + match_tokens!( + toks, + ExecFeeToken::Instantiate, + TransferFeeToken { + kind: TransferFeeKind::ContractInstantiate, + gas_price: 1u64 + }, + ); + }, + ); + } + + #[test] + fn balance_too_low() { + // This test verifies that a contract can't send value if it's + // balance is too low. + let origin = ALICE; + let dest = BOB; + + let vm = MockVm::new(); + let loader = MockLoader::empty(); + + with_externalities(&mut ExtBuilder::default().build(), || { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + ctx.overlay.set_balance(&origin, 0); + + let result = ctx.call( + dest, + 100, + &mut GasMeter::::with_limit(1000, 1), + &[], + EmptyOutputBuf::new(), + ); + + assert_matches!(result, Err("balance too low to send value")); + assert_eq!(ctx.overlay.get_balance(&origin), 0); + assert_eq!(ctx.overlay.get_balance(&dest), 0); + }); + } + + #[test] + fn output_is_returned() { + // Verifies that if a contract returns data, this data + // is returned from the execution context. + let origin = ALICE; + let dest = BOB; + + let vm = MockVm::new(); + let mut loader = MockLoader::empty(); + let return_ch = loader.insert(|mut ctx| { + #[derive(Debug)] + enum Void {} + let empty_output_buf = ctx.empty_output_buf.take().unwrap(); + let output_buf = + empty_output_buf.fill::(4, |data| { + data.copy_from_slice(&[1, 2, 3, 4]); + Ok(()) + }) + .expect("Ok is always returned"); + VmExecResult::Returned(output_buf) + }); + + with_externalities(&mut ExtBuilder::default().build(), || { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + ctx.overlay.set_code(&BOB, Some(return_ch)); + + let result = ctx.call( + dest, + 0, + &mut GasMeter::::with_limit(1000, 1), + &[], + EmptyOutputBuf::new(), + ); + + let output_data = result.unwrap().output_data; + assert_eq!(&output_data, &[1, 2, 3, 4]); + }); + } + + #[test] + fn input_data() { + let vm = MockVm::new(); + let mut loader = MockLoader::empty(); + let input_data_ch = loader.insert(|ctx| { + assert_eq!(ctx.input_data, &[1, 2, 3, 4]); + VmExecResult::Ok + }); + + // This one tests passing the input data into a contract via call. + with_externalities(&mut ExtBuilder::default().build(), || { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_code(&BOB, Some(input_data_ch)); + + let result = ctx.call( + BOB, + 0, + &mut GasMeter::::with_limit(10000, 1), + &[1, 2, 3, 4], + EmptyOutputBuf::new(), + ); + assert_matches!(result, Ok(_)); + }); + + // This one tests passing the input data into a contract via call. + with_externalities(&mut ExtBuilder::default().build(), || { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + + let result = ctx.instantiate( + 0, + &mut GasMeter::::with_limit(10000, 1), + &input_data_ch, + &[1, 2, 3, 4], + ); + assert_matches!(result, Ok(_)); + }); + } + + #[test] + fn max_depth() { + // This test verifies that when we reach the maximal depth creation of an + // yet another context fails. + let value = Default::default(); + let reached_bottom = RefCell::new(false); + + let vm = MockVm::new(); + let mut loader = MockLoader::empty(); + let recurse_ch = loader.insert(|ctx| { + // Try to call into yourself. + let r = ctx + .ext + .call(&BOB, 0, ctx.gas_meter, &[], EmptyOutputBuf::new()); + + let mut reached_bottom = reached_bottom.borrow_mut(); + 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!(r, Err("reached maximum depth, cannot make a call")); + *reached_bottom = true; + } else { + // We just unwinding stack here. + assert_matches!(r, Ok(_)); + } + + VmExecResult::Ok + }); + + with_externalities(&mut ExtBuilder::default().build(), || { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_code(&BOB, Some(recurse_ch)); + + let result = ctx.call( + BOB, + value, + &mut GasMeter::::with_limit(100000, 1), + &[], + EmptyOutputBuf::new(), + ); + + assert_matches!(result, Ok(_)); + }); + } + + #[test] + fn caller_returns_proper_values() { + let origin = ALICE; + let dest = BOB; + + let vm = MockVm::new(); + + let witnessed_caller_bob = RefCell::new(None::); + let witnessed_caller_charlie = RefCell::new(None::); + + let mut loader = MockLoader::empty(); + let bob_ch = loader.insert(|ctx| { + // Record the caller for bob. + *witnessed_caller_bob.borrow_mut() = Some(*ctx.ext.caller()); + + // Call into CHARLIE contract. + assert_matches!( + ctx.ext + .call(&CHARLIE, 0, ctx.gas_meter, &[], EmptyOutputBuf::new()), + Ok(_) + ); + VmExecResult::Ok + }); + let charlie_ch = loader.insert(|ctx| { + // Record the caller for charlie. + *witnessed_caller_charlie.borrow_mut() = Some(*ctx.ext.caller()); + VmExecResult::Ok + }); + + with_externalities(&mut ExtBuilder::default().build(), || { + let cfg = Config::preload(); + + let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + ctx.overlay.set_code(&dest, Some(bob_ch)); + ctx.overlay.set_code(&CHARLIE, Some(charlie_ch)); + + let result = ctx.call( + dest, + 0, + &mut GasMeter::::with_limit(10000, 1), + &[], + EmptyOutputBuf::new(), + ); + + assert_matches!(result, Ok(_)); + }); + + assert_eq!(&*witnessed_caller_bob.borrow(), &Some(origin)); + assert_eq!(&*witnessed_caller_charlie.borrow(), &Some(dest)); + } + + #[test] + fn address_returns_proper_values() { + let vm = MockVm::new(); + + let mut loader = MockLoader::empty(); + let bob_ch = loader.insert(|ctx| { + // Verify that address matches BOB. + assert_eq!(*ctx.ext.address(), BOB); + + // Call into charlie contract. + assert_matches!( + ctx.ext + .call(&CHARLIE, 0, ctx.gas_meter, &[], EmptyOutputBuf::new()), + Ok(_) + ); + VmExecResult::Ok + }); + let charlie_ch = loader.insert(|ctx| { + assert_eq!(*ctx.ext.address(), CHARLIE); + VmExecResult::Ok + }); + + with_externalities(&mut ExtBuilder::default().build(), || { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_code(&BOB, Some(bob_ch)); + ctx.overlay.set_code(&CHARLIE, Some(charlie_ch)); + + let result = ctx.call( + BOB, + 0, + &mut GasMeter::::with_limit(10000, 1), + &[], + EmptyOutputBuf::new(), + ); + + assert_matches!(result, Ok(_)); + }); + } + + #[test] + fn refuse_instantiate_with_value_below_existential_deposit() { + let vm = MockVm::new(); + + let mut loader = MockLoader::empty(); + let dummy_ch = loader.insert(|_| VmExecResult::Ok); + + with_externalities( + &mut ExtBuilder::default().existential_deposit(15).build(), + || { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + + assert_matches!( + ctx.instantiate( + 0, // <- zero endowment + &mut GasMeter::::with_limit(10000, 1), + &dummy_ch, + &[], + ), + Err(_) + ); + } + ); + } + + #[test] + fn instantiation() { + let vm = MockVm::new(); + + let mut loader = MockLoader::empty(); + let dummy_ch = loader.insert(|_| VmExecResult::Ok); + + with_externalities( + &mut ExtBuilder::default().existential_deposit(15).build(), + || { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1000); + + let created_contract_address = assert_matches!( + ctx.instantiate( + 100, + &mut GasMeter::::with_limit(10000, 1), + &dummy_ch, + &[], + ), + Ok(InstantiateReceipt { address }) => address + ); + + // Check that the newly created account has the expected code hash and + // there are instantiation event. + assert_eq!(ctx.overlay.get_code(&created_contract_address).unwrap(), dummy_ch); + assert_eq!(&ctx.events, &[ + RawEvent::Transfer(ALICE, created_contract_address, 100), + RawEvent::Instantiated(ALICE, created_contract_address), + ]); + } + ); + } + + #[test] + fn instantiation_from_contract() { + let vm = MockVm::new(); + + let mut loader = MockLoader::empty(); + let dummy_ch = loader.insert(|_| VmExecResult::Ok); + let created_contract_address = Rc::new(RefCell::new(None::)); + let creator_ch = loader.insert({ + let dummy_ch = dummy_ch.clone(); + let created_contract_address = Rc::clone(&created_contract_address); + move |ctx| { + // Instantiate a contract and save it's address in `created_contract_address`. + *created_contract_address.borrow_mut() = + ctx.ext.instantiate( + &dummy_ch, + 15u64, + ctx.gas_meter, + &[] + ) + .unwrap() + .address.into(); + + VmExecResult::Ok + } + }); + + with_externalities( + &mut ExtBuilder::default().existential_deposit(15).build(), + || { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1000); + ctx.overlay.set_code(&BOB, Some(creator_ch)); + + assert_matches!( + ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), &[], EmptyOutputBuf::new()), + Ok(_) + ); + + let created_contract_address = created_contract_address.borrow().as_ref().unwrap().clone(); + + // Check that the newly created account has the expected code hash and + // there are instantiation event. + assert_eq!(ctx.overlay.get_code(&created_contract_address).unwrap(), dummy_ch); + assert_eq!(&ctx.events, &[ + RawEvent::Transfer(ALICE, BOB, 20), + RawEvent::Transfer(BOB, created_contract_address, 15), + RawEvent::Instantiated(BOB, created_contract_address), + ]); + } + ); + } + + #[test] + fn instantiation_fails() { + let vm = MockVm::new(); + + let mut loader = MockLoader::empty(); + let dummy_ch = loader.insert(|_| VmExecResult::Trap("It's a trap!")); + let creator_ch = loader.insert({ + let dummy_ch = dummy_ch.clone(); + move |ctx| { + // Instantiate a contract and save it's address in `created_contract_address`. + assert_matches!( + ctx.ext.instantiate( + &dummy_ch, + 15u64, + ctx.gas_meter, + &[] + ), + Err("It's a trap!") + ); + + VmExecResult::Ok + } + }); + + with_externalities( + &mut ExtBuilder::default().existential_deposit(15).build(), + || { + let cfg = Config::preload(); + let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1000); + ctx.overlay.set_code(&BOB, Some(creator_ch)); + + assert_matches!( + ctx.call(BOB, 20, &mut GasMeter::::with_limit(1000, 1), &[], EmptyOutputBuf::new()), + Ok(_) + ); + + // The contract wasn't created so we don't expect to see an instantiation + // event here. + assert_eq!(&ctx.events, &[ + RawEvent::Transfer(ALICE, BOB, 20), + ]); + } + ); } } diff --git a/srml/contract/src/gas.rs b/srml/contract/src/gas.rs index 9d1978f7a527cdf79289824ab9b242ea6cc919d2..61e915672d91cedfd86957ed125a8a598a3d3e53 100644 --- a/srml/contract/src/gas.rs +++ b/srml/contract/src/gas.rs @@ -14,10 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use {Trait, Module, GasSpent}; +use balances; use runtime_primitives::traits::{As, CheckedMul, CheckedSub, Zero}; use runtime_support::StorageValue; -use balances; +use {GasSpent, Module, Trait}; + +#[cfg(test)] +use std::{any::Any, fmt::Debug}; #[must_use] #[derive(Debug, PartialEq, Eq)] @@ -35,11 +38,54 @@ impl GasMeterResult { } } +#[cfg(not(test))] +pub trait TestAuxiliaries {} +#[cfg(not(test))] +impl TestAuxiliaries for T {} + +#[cfg(test)] +pub trait TestAuxiliaries: Any + Debug + PartialEq + Eq {} +#[cfg(test)] +impl TestAuxiliaries for T {} + +/// This trait represents a token that can be used for charging `GasMeter`. +/// There is no other way of charging it. +/// +/// Implementing type is expected to be super lightweight hence `Copy` (`Clone` is added +/// for consistency). If inlined there should be no observable difference compared +/// to a hand-written code. +pub trait Token: Copy + Clone + TestAuxiliaries { + /// Metadata type, which the token can require for calculating the amount + /// of gas to charge. Can be a some configuration type or + /// just the `()`. + type Metadata; + + /// Calculate amount of gas that should be taken by this token. + /// + /// This function should be really lightweight and must not fail. It is not + /// expected that implementors will query the storage or do any kinds of heavy operations. + /// + /// That said, implementors of this function still can run into overflows + /// while calculating the amount. In this case it is ok to use saturating operations + /// since on overflow they will return `max_value` which should consume all gas. + fn calculate_amount(&self, metadata: &Self::Metadata) -> T::Gas; +} + +/// A wrapper around a type-erased trait object of what used to be a `Token`. +#[cfg(test)] +pub struct ErasedToken { + pub description: String, + pub token: Box, +} + pub struct GasMeter { limit: T::Gas, /// Amount of gas left from initial gas limit. Can reach zero. gas_left: T::Gas, gas_price: T::Balance, + + #[cfg(test)] + tokens: Vec, } impl GasMeter { #[cfg(test)] @@ -48,17 +94,37 @@ impl GasMeter { limit: gas_limit, gas_left: gas_limit, gas_price, + #[cfg(test)] + tokens: Vec::new(), } } /// Account for used gas. /// + /// Amount is calculated by the given `token`. + /// /// Returns `OutOfGas` if there is not enough gas or addition of the specified /// amount of gas has lead to overflow. On success returns `Proceed`. /// - /// NOTE that `amount` is always consumed, i.e. if there is not enough gas + /// NOTE that amount is always consumed, i.e. if there is not enough gas /// then the counter will be set to zero. - pub fn charge(&mut self, amount: T::Gas) -> GasMeterResult { + #[inline] + pub fn charge>( + &mut self, + metadata: &Tok::Metadata, + token: Tok, + ) -> GasMeterResult { + #[cfg(test)] + { + // Unconditionally add the token to the storage. + let erased_tok = ErasedToken { + description: format!("{:?}", token), + token: Box::new(token), + }; + self.tokens.push(erased_tok); + } + + let amount = token.calculate_amount(metadata); let new_value = match self.gas_left.checked_sub(&amount) { None => None, Some(val) if val.is_zero() => None, @@ -74,18 +140,6 @@ impl GasMeter { } } - /// Account for used gas expressed in balance units. - /// - /// Same as [`charge`], but amount to be charged is converted from units of balance to - /// units of gas. - /// - /// [`charge`]: #method.charge - pub fn charge_by_balance(&mut self, amount: T::Balance) -> GasMeterResult { - let amount_in_gas: T::Balance = amount / self.gas_price; - let amount_in_gas: T::Gas = >::sa(amount_in_gas); - self.charge(amount_in_gas) - } - /// Allocate some amount of gas and perform some work with /// a newly created nested gas meter. /// @@ -108,6 +162,8 @@ impl GasMeter { limit: amount, gas_left: amount, gas_price: self.gas_price, + #[cfg(test)] + tokens: Vec::new(), }; let r = f(Some(&mut nested)); @@ -118,6 +174,10 @@ impl GasMeter { } } + pub fn gas_price(&self) -> T::Balance { + self.gas_price + } + /// Returns how much gas left from the initial budget. pub fn gas_left(&self) -> T::Gas { self.gas_left @@ -127,6 +187,11 @@ impl GasMeter { fn spent(&self) -> T::Gas { self.limit - self.gas_left } + + #[cfg(test)] + pub fn tokens(&self) -> &[ErasedToken] { + &self.tokens + } } /// Buy the given amount of gas. @@ -150,15 +215,20 @@ pub fn buy_gas( let cost = >::as_(gas_limit.clone()) .checked_mul(&gas_price) .ok_or("overflow multiplying gas limit by price")?; - if b < cost + >::existential_deposit() { + + let new_balance = b.checked_sub(&cost); + if new_balance < Some(>::existential_deposit()) { return Err("not enough funds for transaction fee"); } + >::set_free_balance(transactor, b - cost); >::decrease_total_stake_by(cost); Ok(GasMeter { limit: gas_limit, gas_left: gas_limit, gas_price, + #[cfg(test)] + tokens: Vec::new(), }) } @@ -176,3 +246,108 @@ pub fn refund_unused_gas(transactor: &T::AccountId, gas_meter: GasMete >::set_free_balance(transactor, b + refund); >::increase_total_stake_by(refund); } + +/// A little handy utility for converting a value in balance units into approximitate value in gas units +/// at the given gas price. +pub fn approx_gas_for_balance(gas_price: T::Balance, balance: T::Balance) -> T::Gas { + let amount_in_gas: T::Balance = balance / gas_price; + >::sa(amount_in_gas) +} + +/// A simple utility macro that helps to match against a +/// list of tokens. +#[macro_export] +macro_rules! match_tokens { + ($tokens_iter:ident,) => { + }; + ($tokens_iter:ident, $x:expr, $($rest:tt)*) => { + { + let next = ($tokens_iter).next().unwrap(); + let pattern = $x; + + // Note that we don't specify the type name directly in this macro, + // we only have some expression $x of some type. At the same time, we + // have an iterator of Box and to downcast we need to specify + // the type which we want downcast to. + // + // So what we do is we assign `_pattern_typed_next_ref` to the a variable which has + // the required type. + // + // Then we make `_pattern_typed_next_ref = token.downcast_ref()`. This makes + // rustc infer the type `T` (in `downcast_ref`) to be the same as in $x. + + let mut _pattern_typed_next_ref = &pattern; + _pattern_typed_next_ref = match next.token.downcast_ref() { + Some(p) => { + assert_eq!(p, &pattern); + p + } + None => { + panic!("expected type {} got {}", stringify!($x), next.description); + } + }; + } + + match_tokens!($tokens_iter, $($rest)*); + }; +} + +#[cfg(test)] +mod tests { + use super::{GasMeter, Token}; + use tests::Test; + + /// A trivial token that charges 1 unit of gas. + #[derive(Copy, Clone, PartialEq, Eq, Debug)] + struct UnitToken; + impl Token for UnitToken { + type Metadata = (); + fn calculate_amount(&self, _metadata: &()) -> u64 { 1 } + } + + struct DoubleTokenMetadata { + multiplier: u64, + } + /// A simple token that charges for the given amount multipled to + /// a multiplier taken from a given metadata. + #[derive(Copy, Clone, PartialEq, Eq, Debug)] + struct DoubleToken(u64); + + impl Token for DoubleToken { + type Metadata = DoubleTokenMetadata; + fn calculate_amount(&self, metadata: &DoubleTokenMetadata) -> u64 { + // Probably you want to use saturating mul in producation code. + self.0 * metadata.multiplier + } + } + + #[test] + fn it_works() { + let gas_meter = GasMeter::::with_limit(50000, 10); + assert_eq!(gas_meter.gas_left(), 50000); + } + + #[test] + fn simple() { + let mut gas_meter = GasMeter::::with_limit(50000, 10); + + let result = gas_meter.charge(&DoubleTokenMetadata { multiplier: 3 }, DoubleToken(10)); + assert!(!result.is_out_of_gas()); + + assert_eq!(gas_meter.gas_left(), 49_970); + assert_eq!(gas_meter.spent(), 30); + assert_eq!(gas_meter.gas_price(), 10); + } + + #[test] + fn tracing() { + let mut gas_meter = GasMeter::::with_limit(50000, 10); + assert!(!gas_meter.charge(&(), UnitToken).is_out_of_gas()); + assert!(!gas_meter + .charge(&DoubleTokenMetadata { multiplier: 3 }, DoubleToken(10)) + .is_out_of_gas()); + + let mut tokens = gas_meter.tokens()[0..2].iter(); + match_tokens!(tokens, UnitToken, DoubleToken(10),); + } +} diff --git a/srml/contract/src/lib.rs b/srml/contract/src/lib.rs index 5e3722bb04040e31fe002491fe1ddfa7e21ad486..38b2aa3e7514713b449b9483191857a9366bc387 100644 --- a/srml/contract/src/lib.rs +++ b/srml/contract/src/lib.rs @@ -39,7 +39,7 @@ //! This module requires performing some finalization steps at the end of the block. If not performed //! the module will have incorrect behavior. //! -//! Call [`Module::execute`] at the end of the block. The order in relation to +//! Thus [`Module::on_finalise`] must be called at the end of the block. The order in relation to //! the other module doesn't matter. //! //! ## Account killing @@ -48,14 +48,10 @@ //! exsistential deposit) then it reaps the account. That will lead to deletion of the associated //! code and storage of the account. //! -//! [`Module::execute`]: struct.Module.html#impl-OnFinalise +//! [`Module::on_finalise`]: struct.Module.html#impl-OnFinalise #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - #[macro_use] extern crate parity_codec_derive; @@ -87,40 +83,62 @@ extern crate assert_matches; #[cfg(test)] extern crate wabt; +#[cfg(test)] +#[macro_use] +extern crate hex_literal; + +#[macro_use] +mod gas; + mod account_db; -mod double_map; mod exec; -mod vm; -mod gas; +mod wasm; #[cfg(test)] mod tests; use exec::ExecutionContext; -use account_db::{AccountDb, OverlayAccountDb}; -use double_map::StorageDoubleMap; +use account_db::AccountDb; use rstd::prelude::*; use rstd::marker::PhantomData; -use codec::{Codec, HasCompact}; -use runtime_primitives::traits::{Hash, As, SimpleArithmetic}; -use runtime_support::dispatch::Result; -use runtime_support::{Parameter, StorageMap, StorageValue}; -use system::ensure_signed; +use codec::Codec; +use runtime_primitives::traits::{Hash, As, SimpleArithmetic,Bounded, StaticLookup}; +use runtime_support::dispatch::{Result, Dispatchable}; +use runtime_support::{Parameter, StorageMap, StorageValue, StorageDoubleMap}; +use system::{ensure_signed, RawOrigin}; +use runtime_io::{blake2_256, twox_128}; + +pub type CodeHash = ::Hash; + +/// A function that generates an `AccountId` for a contract upon instantiation. +pub trait ContractAddressFor { + fn contract_address_for(code_hash: &CodeHash, data: &[u8], origin: &AccountId) -> AccountId; +} -pub trait Trait: balances::Trait { - /// Function type to get the contract address given the creator. - type DetermineContractAddress: ContractAddressFor; +/// A function that returns the fee for dispatching a `Call`. +pub trait ComputeDispatchFee { + fn compute_dispatch_fee(call: &Call) -> Balance; +} - // As is needed for wasm-utils - type Gas: Parameter + Default + Codec + SimpleArithmetic + Copy + As + As + As; +pub trait Trait: balances::Trait { + /// The outer call dispatch type. + type Call: Parameter + Dispatchable::Origin>; /// The overarching event type. type Event: From> + Into<::Event>; -} -pub trait ContractAddressFor { - fn contract_address_for(code: &[u8], data: &[u8], origin: &AccountId) -> AccountId; + // As is needed for wasm-utils + type Gas: Parameter + Default + Codec + SimpleArithmetic + Bounded + Copy + As + As + As; + + /// A function type to get the contract address given the creator. + type DetermineContractAddress: ContractAddressFor, Self::AccountId>; + + /// A function type that computes the fee for dispatching the given `Call`. + /// + /// It is recommended (though not required) for this function to return a fee that would be taken + /// by executive module for regular dispatch. + type ComputeDispatchFee: ComputeDispatchFee::Balance>; } /// Simple contract address determintator. @@ -130,13 +148,11 @@ pub trait ContractAddressFor { /// /// Formula: `blake2_256(blake2_256(code) + blake2_256(data) + origin)` pub struct SimpleAddressDeterminator(PhantomData); - -impl ContractAddressFor for SimpleAddressDeterminator +impl ContractAddressFor, T::AccountId> for SimpleAddressDeterminator where T::AccountId: From + AsRef<[u8]> { - fn contract_address_for(code: &[u8], data: &[u8], origin: &T::AccountId) -> T::AccountId { - let code_hash = T::Hashing::hash(code); + fn contract_address_for(code_hash: &CodeHash, data: &[u8], origin: &T::AccountId) -> T::AccountId { let data_hash = T::Hashing::hash(data); let mut buf = Vec::new(); @@ -148,23 +164,68 @@ where } } +/// The default dispatch fee computor computes the fee in the same way that +/// implementation of `MakePayment` for balances module does. +pub struct DefaultDispatchFeeComputor(PhantomData); +impl ComputeDispatchFee for DefaultDispatchFeeComputor { + fn compute_dispatch_fee(call: &T::Call) -> T::Balance { + let encoded_len = codec::Encode::encode(&call).len(); + let base_fee = >::transaction_base_fee(); + let byte_fee = >::transaction_byte_fee(); + base_fee + byte_fee * >::sa(encoded_len as u64) + } +} + decl_module! { /// Contracts module. - pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; - // TODO: Change AccountId to staking::Address - /// Make a call to a specified account, optionally transferring some balance. + pub struct Module for enum Call where origin: ::Origin { + fn deposit_event() = default; + + /// Updates the schedule for metering contracts. + /// + /// The schedule must have a greater version than the stored schedule. + fn update_schedule(schedule: Schedule) -> Result { + if >::current_schedule().version >= schedule.version { + return Err("new schedule must have a greater version than current"); + } + + Self::deposit_event(RawEvent::ScheduleUpdated(schedule.version)); + >::put(schedule); + + Ok(()) + } + + /// Stores code in the storage. You can instantiate contracts only with stored code. + fn put_code( + origin, + #[compact] gas_limit: T::Gas, + code: Vec + ) -> Result { + let origin = ensure_signed(origin)?; + let schedule = >::current_schedule(); + + let mut gas_meter = gas::buy_gas::(&origin, gas_limit)?; + + let result = wasm::save_code::(code, &mut gas_meter, &schedule); + if let Ok(code_hash) = result { + Self::deposit_event(RawEvent::CodeStored(code_hash)); + } + + gas::refund_unused_gas::(&origin, gas_meter); + + result.map(|_| ()) + } + /// Make a call to a specified account, optionally transferring some balance. fn call( origin, - dest: T::AccountId, - value: ::Type, - gas_limit: ::Type, + dest: ::Source, + #[compact] value: T::Balance, + #[compact] gas_limit: T::Gas, data: Vec ) -> Result { let origin = ensure_signed(origin)?; - let value = value.into(); - let gas_limit = gas_limit.into(); + let dest = T::Lookup::lookup(dest)?; // Pay for the gas upfront. // @@ -172,15 +233,12 @@ decl_module! { // paying for the gas. let mut gas_meter = gas::buy_gas::(&origin, gas_limit)?; - let mut ctx = ExecutionContext { - self_account: origin.clone(), - depth: 0, - overlay: OverlayAccountDb::::new(&account_db::DirectAccountDb), - events: Vec::new(), - }; + let cfg = Config::preload(); + let vm = ::wasm::WasmVm::new(&cfg.schedule); + let loader = ::wasm::WasmLoader::new(&cfg.schedule); + let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); - let mut output_data = Vec::new(); - let result = ctx.call(origin.clone(), dest, value, &mut gas_meter, &data, &mut output_data); + let result = ctx.call(dest, value, &mut gas_meter, &data, exec::EmptyOutputBuf::new()); if let Ok(_) = result { // Commit all changes that made it thus far into the persistant storage. @@ -196,6 +254,12 @@ decl_module! { // can alter the balance of the caller. gas::refund_unused_gas::(&origin, gas_meter); + // Dispatch every recorded call with an appropriate origin. + ctx.calls.into_iter().for_each(|(who, call)| { + let result = call.dispatch(RawOrigin::Signed(who.clone()).into()); + Self::deposit_event(RawEvent::Dispatched(who, result.is_ok())); + }); + result.map(|_| ()) } @@ -210,14 +274,12 @@ decl_module! { /// upon any message received by this account. fn create( origin, - endowment: ::Type, - gas_limit: ::Type, - ctor_code: Vec, + #[compact] endowment: T::Balance, + #[compact] gas_limit: T::Gas, + code_hash: CodeHash, data: Vec ) -> Result { let origin = ensure_signed(origin)?; - let endowment = endowment.into(); - let gas_limit = gas_limit.into(); // Pay for the gas upfront. // @@ -225,22 +287,18 @@ decl_module! { // paying for the gas. let mut gas_meter = gas::buy_gas::(&origin, gas_limit)?; - let mut ctx = ExecutionContext { - self_account: origin.clone(), - depth: 0, - overlay: OverlayAccountDb::::new(&account_db::DirectAccountDb), - events: Vec::new(), - }; - let result = ctx.create(origin.clone(), endowment, &mut gas_meter, &ctor_code, &data); + let cfg = Config::preload(); + let vm = ::wasm::WasmVm::new(&cfg.schedule); + let loader = ::wasm::WasmLoader::new(&cfg.schedule); + let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); + let result = ctx.instantiate(endowment, &mut gas_meter, &code_hash, &data); - if let Ok(ref r) = result { + if let Ok(_) = result { // Commit all changes that made it thus far into the persistant storage. account_db::DirectAccountDb.commit(ctx.overlay.into_change_set()); // Then deposit all events produced. ctx.events.into_iter().for_each(Self::deposit_event); - - Self::deposit_event(RawEvent::Created(origin.clone(), r.address.clone())); } // Refund cost of the unused gas. @@ -249,6 +307,12 @@ decl_module! { // can alter the balance of the caller. gas::refund_unused_gas::(&origin, gas_meter); + // Dispatch every recorded call with an appropriate origin. + ctx.calls.into_iter().for_each(|(who, call)| { + let result = call.dispatch(RawOrigin::Signed(who.clone()).into()); + Self::deposit_event(RawEvent::Dispatched(who, result.is_ok())); + }); + result.map(|_| ()) } @@ -262,13 +326,24 @@ decl_event! { pub enum Event where ::Balance, - ::AccountId + ::AccountId, + ::Hash { /// Transfer happened `from` -> `to` with given `value` as part of a `message-call` or `create`. Transfer(AccountId, AccountId, Balance), /// Contract deployed by address at the specified address. - Created(AccountId, AccountId), + Instantiated(AccountId, AccountId), + + /// Code with the specified hash has been stored. + CodeStored(Hash), + + /// 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), } } @@ -288,9 +363,14 @@ decl_storage! { BlockGasLimit get(block_gas_limit) config(): T::Gas = T::Gas::sa(1_000_000); /// Gas spent so far in this block. GasSpent get(gas_spent): T::Gas; - - /// The code associated with an account. - pub CodeOf: map T::AccountId => Vec; // TODO Vec values should be optimised to not do a length prefix. + /// Current cost schedule for contracts. + CurrentSchedule get(current_schedule) config(): Schedule = Schedule::default(); + /// The code associated with a given account. + pub CodeHashOf: map T::AccountId => Option>; + /// A mapping from an original code hash to the original code, untouched by instrumentation. + pub PristineCode: map CodeHash => Option>; + /// A mapping between an original code hash and instrumented wasm code, ready for the execution. + pub CodeStorage: map CodeHash => Option; } } @@ -301,16 +381,109 @@ decl_storage! { /// /// TODO: keys should also be able to take AsRef to ensure Vecs can be passed as &[u8] pub(crate) struct StorageOf(::rstd::marker::PhantomData); -impl double_map::StorageDoubleMap for StorageOf { +impl StorageDoubleMap for StorageOf { const PREFIX: &'static [u8] = b"con:sto:"; type Key1 = T::AccountId; type Key2 = Vec; type Value = Vec; + + /// Hashed by XX + fn derive_key1(key1_data: Vec) -> Vec { + twox_128(&key1_data).to_vec() + } + + /// Blake2 is used for `Key2` is because it will be used as a key for contract's storage and + /// thus will be susceptible for a untrusted input. + fn derive_key2(key2_data: Vec) -> Vec { + blake2_256(&key2_data).to_vec() + } } impl balances::OnFreeBalanceZero for Module { fn on_free_balance_zero(who: &T::AccountId) { - >::remove(who); + >::remove(who); >::remove_prefix(who.clone()); } } + +/// In-memory cache of configuration values. +/// +/// We assume that these values can't be changed in the +/// course of transaction execution. +pub struct Config { + pub schedule: Schedule, + pub existential_deposit: T::Balance, + pub max_depth: u32, + pub contract_account_instantiate_fee: T::Balance, + pub account_create_fee: T::Balance, + pub transfer_fee: T::Balance, + pub call_base_fee: T::Gas, + pub instantiate_base_fee: T::Gas, +} + +impl Config { + fn preload() -> Config { + Config { + schedule: >::current_schedule(), + existential_deposit: >::existential_deposit(), + max_depth: >::max_depth(), + contract_account_instantiate_fee: >::contract_fee(), + account_create_fee: >::creation_fee(), + transfer_fee: >::transfer_fee(), + call_base_fee: >::call_base_fee(), + instantiate_base_fee: >::create_base_fee(), + } + } +} + +/// Definition of the cost schedule and other parameterizations for wasm vm. +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +#[derive(Clone, Encode, Decode, PartialEq, Eq)] +pub struct Schedule { + /// Version of the schedule. + pub version: u32, + + /// Cost of putting a byte of code into the storage. + pub put_code_per_byte_cost: Gas, + + /// Gas cost of a growing memory by single page. + pub grow_mem_cost: Gas, + + /// Gas cost of a regular operation. + pub regular_op_cost: Gas, + + /// Gas cost per one byte returned. + pub return_data_per_byte_cost: Gas, + + /// Gas cost per one byte read from the sandbox memory. + pub sandbox_data_read_cost: Gas, + + /// Gas cost per one byte written to the sandbox memory. + pub sandbox_data_write_cost: Gas, + + /// How tall the stack is allowed to grow? + /// + /// See https://wiki.parity.io/WebAssembly-StackHeight to find out + /// how the stack frame cost is calculated. + pub max_stack_height: u32, + + /// What is the maximal memory pages amount is allowed to have for + /// a contract. + pub max_memory_pages: u32, +} + +impl> Default for Schedule { + fn default() -> Schedule { + Schedule { + version: 0, + put_code_per_byte_cost: Gas::sa(1), + grow_mem_cost: Gas::sa(1), + regular_op_cost: Gas::sa(1), + return_data_per_byte_cost: Gas::sa(1), + sandbox_data_read_cost: Gas::sa(1), + sandbox_data_write_cost: Gas::sa(1), + max_stack_height: 64 * 1024, + max_memory_pages: 16, + } + } +} diff --git a/srml/contract/src/tests.rs b/srml/contract/src/tests.rs index 62683e0a95b1e1e8204ea7ffdc76f1231d42086c..d843c993c338a7090c16d4f7c42287f223501df4 100644 --- a/srml/contract/src/tests.rs +++ b/srml/contract/src/tests.rs @@ -14,25 +14,28 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use double_map::StorageDoubleMap; +// TODO: #1417 Add more integration tests +// also remove the #![allow(unused)] below. + +#![allow(unused)] + use runtime_io::with_externalities; use runtime_primitives::testing::{Digest, DigestItem, H256, Header}; -use runtime_primitives::traits::{BlakeTwo256}; +use runtime_primitives::traits::{BlakeTwo256, IdentityLookup}; use runtime_primitives::BuildStorage; -use runtime_support::StorageMap; +use runtime_support::{StorageMap, StorageDoubleMap}; use substrate_primitives::{Blake2Hasher}; -use system::{Phase, EventRecord}; +use system::{ensure_signed, Phase, EventRecord}; use wabt; use { - runtime_io, balances, system, CodeOf, ContractAddressFor, - GenesisConfig, Module, StorageOf, Trait, RawEvent, + balances, runtime_io, system, ComputeDispatchFee, ContractAddressFor, GenesisConfig, Module, RawEvent, StorageOf, + Trait }; -impl_outer_origin! { - pub enum Origin for Test {} -} - mod contract { + // Re-export contents of the root. This basically + // needs to give a name for the current crate. + // This hack is required for `impl_outer_event!`. pub use super::super::*; } impl_outer_event! { @@ -40,6 +43,15 @@ impl_outer_event! { balances, contract, } } +impl_outer_origin! { + pub enum Origin for Test { } +} +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + balances::Balances, + contract::Contract, + } +} #[derive(Clone, Eq, PartialEq)] pub struct Test; @@ -51,21 +63,24 @@ impl system::Trait for Test { type Hashing = BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = MetaEvent; type Log = DigestItem; } impl balances::Trait for Test { type Balance = u64; - type AccountIndex = u64; type OnFreeBalanceZero = Contract; + type OnNewAccount = (); type EnsureAccountLiquid = (); type Event = MetaEvent; } impl Trait for Test { + type Call = Call; type Gas = u64; type DetermineContractAddress = DummyContractAddressFor; type Event = MetaEvent; + type ComputeDispatchFee = DummyComputeDispatchFee; } type Balances = balances::Module; @@ -73,13 +88,24 @@ type Contract = Module; type System = system::Module; pub struct DummyContractAddressFor; -impl ContractAddressFor for DummyContractAddressFor { - fn contract_address_for(_code: &[u8], _data: &[u8], origin: &u64) -> u64 { - origin + 1 +impl ContractAddressFor for DummyContractAddressFor { + fn contract_address_for(_code_hash: &H256, _data: &[u8], origin: &u64) -> u64 { + *origin + 1 } } -struct ExtBuilder { +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; + +pub struct ExtBuilder { existential_deposit: u64, gas_price: u64, block_gas_limit: u64, @@ -98,30 +124,31 @@ impl Default for ExtBuilder { } } impl ExtBuilder { - fn existential_deposit(mut self, existential_deposit: u64) -> Self { + pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { self.existential_deposit = existential_deposit; self } - fn gas_price(mut self, gas_price: u64) -> Self { + pub fn gas_price(mut self, gas_price: u64) -> Self { self.gas_price = gas_price; self } - fn block_gas_limit(mut self, block_gas_limit: u64) -> Self { + pub fn block_gas_limit(mut self, block_gas_limit: u64) -> Self { self.block_gas_limit = block_gas_limit; self } - fn transfer_fee(mut self, transfer_fee: u64) -> Self { + pub fn transfer_fee(mut self, transfer_fee: u64) -> Self { self.transfer_fee = transfer_fee; self } - fn creation_fee(mut self, creation_fee: u64) -> Self { + pub fn creation_fee(mut self, creation_fee: u64) -> Self { self.creation_fee = creation_fee; self } - fn build(self) -> runtime_io::TestExternalities { + pub fn build(self) -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::::default() .build_storage() - .unwrap().0; + .unwrap() + .0; t.extend( balances::GenesisConfig:: { balances: vec![], @@ -130,9 +157,10 @@ impl ExtBuilder { existential_deposit: self.existential_deposit, transfer_fee: self.transfer_fee, creation_fee: self.creation_fee, - reclaim_rebate: 0, - }.build_storage() - .unwrap().0, + } + .build_storage() + .unwrap() + .0, ); t.extend( GenesisConfig:: { @@ -142,546 +170,34 @@ impl ExtBuilder { gas_price: self.gas_price, max_depth: 100, block_gas_limit: self.block_gas_limit, - }.build_storage() - .unwrap().0, + current_schedule: Default::default(), + } + .build_storage() + .unwrap() + .0, ); runtime_io::TestExternalities::new(t) } } -const CODE_TRANSFER: &str = r#" -(module - ;; ext_call( - ;; callee_ptr: u32, - ;; callee_len: u32, - ;; gas: u64, - ;; value_ptr: u32, - ;; value_len: u32, - ;; input_data_ptr: u32, - ;; input_data_len: u32 - ;; ) -> u32 - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (drop - (call $ext_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. - (i32.const 12) ;; 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 - ) - ) - ) - ;; Destination AccountId to transfer the funds. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\09\00\00\00\00\00\00\00") - ;; Amount of value to transfer. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 12) "\06\00\00\00\00\00\00\00") -) -"#; - -#[test] -fn contract_transfer() { - const CONTRACT_SHOULD_TRANSFER_VALUE: u64 = 6; - const CONTRACT_SHOULD_TRANSFER_TO: u64 = 9; - - let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap(); - - with_externalities(&mut ExtBuilder::default().build(), || { - >::insert(1, code_transfer.to_vec()); - - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - Balances::set_free_balance(&1, 11); - Balances::increase_total_stake_by(11); - - assert_ok!(Contract::call(Origin::signed(0), 1, 3.into(), 100_000.into(), Vec::new())); - - assert_eq!( - Balances::free_balance(&0), - // 3 - value sent with the transaction - // 2 * 26 - gas used by the contract (26) multiplied by gas price (2) - // 2 * 135 - base gas fee for call (by transaction) - // 2 * 135 - base gas fee for call (by the contract) - 100_000_000 - 3 - (2 * 26) - (2 * 135) - (2 * 135), - ); - assert_eq!( - Balances::free_balance(&1), - 11 + 3 - CONTRACT_SHOULD_TRANSFER_VALUE, - ); - assert_eq!( - Balances::free_balance(&CONTRACT_SHOULD_TRANSFER_TO), - CONTRACT_SHOULD_TRANSFER_VALUE, - ); - - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::NewAccount( - CONTRACT_SHOULD_TRANSFER_TO, - 0, - balances::NewAccountOutcome::NoHint - ) - ), - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(0, 1, 3)), - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(1, CONTRACT_SHOULD_TRANSFER_TO, 6)), - }, - ]); - }); -} - -#[test] -fn contract_transfer_to_death() { - const CONTRACT_SHOULD_TRANSFER_VALUE: u64 = 6; - - let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap(); - - with_externalities(&mut ExtBuilder::default().existential_deposit(5).build(), || { - >::insert(1, code_transfer.to_vec()); - - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - - Balances::set_free_balance(&1, 6); - Balances::increase_total_stake_by(6); - >::insert(1, b"foo".to_vec(), b"1".to_vec()); - - assert_ok!(Contract::call(Origin::signed(0), 1, 0.into(), 100_000.into(), Vec::new())); - - assert_eq!( - Balances::free_balance(&0), - // 2 * 26 - gas used by the contract (26) multiplied by gas price (2) - // 2 * 135 - base gas fee for call (by transaction) - // 2 * 135 - base gas fee for call (by the contract) - 100_000_000 - (2 * 26) - (2 * 135) - (2 * 135), - ); - - assert!(!>::exists(1)); - assert!(!>::exists(1, b"foo".to_vec())); - assert_eq!(Balances::free_balance(&1), 0); - - assert_eq!(Balances::free_balance(&9), CONTRACT_SHOULD_TRANSFER_VALUE); - }); -} - -#[test] -fn contract_transfer_takes_creation_fee() { - const CONTRACT_SHOULD_TRANSFER_VALUE: u64 = 6; - const CONTRACT_SHOULD_TRANSFER_TO: u64 = 9; - - let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap(); - - with_externalities(&mut ExtBuilder::default().creation_fee(105).build(), || { - >::insert(1, code_transfer.to_vec()); - - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - Balances::set_free_balance(&1, 11); - Balances::increase_total_stake_by(11); - - assert_ok!(Contract::call(Origin::signed(0), 1, 3.into(), 100_000.into(), Vec::new())); - - assert_eq!( - Balances::free_balance(&0), - // 3 - value sent with the transaction - // 2 * 26 - gas used by the contract (26) multiplied by gas price (2) - // 2 * 135 - base gas fee for call (by transaction) - // 2 * 135 - base gas fee for call (by the contract) - // 104 - (rounded) fee per creation (by the contract) - 100_000_000 - 3 - (2 * 26) - (2 * 135) - (2 * 135) - 104, - ); - assert_eq!( - Balances::free_balance(&1), - 11 + 3 - CONTRACT_SHOULD_TRANSFER_VALUE, - ); - assert_eq!( - Balances::free_balance(&CONTRACT_SHOULD_TRANSFER_TO), - CONTRACT_SHOULD_TRANSFER_VALUE, - ); - }); -} - -#[test] -fn contract_transfer_takes_transfer_fee() { - const CONTRACT_SHOULD_TRANSFER_VALUE: u64 = 6; - const CONTRACT_SHOULD_TRANSFER_TO: u64 = 9; - - let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap(); - - with_externalities(&mut ExtBuilder::default().creation_fee(105).transfer_fee(45).build(), || { - >::insert(1, code_transfer.to_vec()); - - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - Balances::set_free_balance(&1, 11); - Balances::increase_total_stake_by(11); - - // Create destination account here so we can check that transfer fee - // is charged (and creation fee is not). - Balances::set_free_balance(&CONTRACT_SHOULD_TRANSFER_TO, 25); - - assert_ok!(Contract::call(Origin::signed(0), 1, 3.into(), 100_000.into(), Vec::new())); - - assert_eq!( - Balances::free_balance(&0), - // 3 - value sent with the transaction - // 2 * 26 - gas used by the contract (26) multiplied by gas price (2) - // 2 * 135 - base gas fee for call (by transaction) - // 44 - (rounded from 45) fee per transfer (by transaction) - // 2 * 135 - base gas fee for call (by the contract) - // 44 - (rounded from 45) fee per transfer (by the contract) - 100_000_000 - 3 - (2 * 26) - (2 * 135) - 44 - (2 * 135) - 44, - ); - assert_eq!( - Balances::free_balance(&1), - 11 + 3 - CONTRACT_SHOULD_TRANSFER_VALUE, - ); - assert_eq!( - Balances::free_balance(&CONTRACT_SHOULD_TRANSFER_TO), - 25 + CONTRACT_SHOULD_TRANSFER_VALUE, - ); - }); -} - -#[test] -fn contract_transfer_oog() { - const CONTRACT_SHOULD_TRANSFER_TO: u64 = 9; - - let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap(); - - with_externalities(&mut ExtBuilder::default().build(), || { - >::insert(1, code_transfer.to_vec()); - - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - Balances::set_free_balance(&1, 11); - Balances::increase_total_stake_by(11); - - assert_ok!(Contract::call(Origin::signed(0), 1, 3.into(), (135 + 135 + 7).into(), Vec::new())); - - assert_eq!( - Balances::free_balance(&0), - // 3 - value sent with the transaction - // 2 * 7 - gas used by the contract (7) multiplied by gas price (2) - // 2 * 135 - base gas fee for call (by transaction) - // 2 * 135 - base gas fee for call (by contract) - 100_000_000 - 3 - (2 * 7) - (2 * 135) - (2 * 135), - ); - - // Transaction level transfer should succeed. - assert_eq!(Balances::free_balance(&1), 14); - // But `ext_call` should not. - assert_eq!(Balances::free_balance(&CONTRACT_SHOULD_TRANSFER_TO), 0); - - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(0, 1, 3)), - }, - ]); - }); -} - -#[test] -fn contract_transfer_max_depth() { - const CONTRACT_SHOULD_TRANSFER_TO: u64 = 9; - - let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap(); - - with_externalities(&mut ExtBuilder::default().build(), || { - >::insert(CONTRACT_SHOULD_TRANSFER_TO, code_transfer.to_vec()); - - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - Balances::set_free_balance(&CONTRACT_SHOULD_TRANSFER_TO, 11); - Balances::increase_total_stake_by(11); - - assert_ok!(Contract::call(Origin::signed(0), CONTRACT_SHOULD_TRANSFER_TO, 3.into(), 100_000.into(), Vec::new())); - - assert_eq!( - Balances::free_balance(&0), - // 3 - value sent with the transaction - // 2 * 26 * 100 - gas used by the contract (26) multiplied by gas price (2) - // multiplied by max depth (100). - // 2 * 135 * 100 - base gas fee for call (by transaction) multiplied by max depth (100). - 100_000_000 - 3 - (2 * 26 * 100) - (2 * 135 * 100), - ); - assert_eq!(Balances::free_balance(&CONTRACT_SHOULD_TRANSFER_TO), 14); - }); -} - -/// Convert a byte slice to a string with hex values. -/// -/// Each value is preceeded with a `\` character. -fn escaped_bytestring(bytes: &[u8]) -> String { - use std::fmt::Write; - let mut result = String::new(); - for b in bytes { - write!(result, "\\{:02x}", b).unwrap(); - } - result -} - -/// Create a constructor for the specified code. -/// -/// When constructor is executed, it will call `ext_return` with code that -/// specified in `child_bytecode`. -fn code_ctor(child_bytecode: &[u8]) -> String { - format!( - r#" -(module - ;; ext_return(data_ptr: u32, data_len: u32) -> ! - (import "env" "ext_return" (func $ext_return (param i32 i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (call $ext_return - (i32.const 4) - (i32.const {code_len}) - ) - ;; ext_return is diverging, i.e. doesn't return. - unreachable - ) - (data (i32.const 4) "{escaped_bytecode}") -) -"#, - escaped_bytecode = escaped_bytestring(child_bytecode), - code_len = child_bytecode.len(), - ) -} - -/// Returns code that uses `ext_create` runtime call. -/// -/// Takes bytecode of the contract that needs to be deployed. -fn code_create(constructor: &[u8]) -> String { - format!( - r#" -(module - ;; ext_create( - ;; code_ptr: u32, - ;; code_len: u32, - ;; gas: u64, - ;; value_ptr: u32, - ;; value_len: u32, - ;; input_data_ptr: u32, - ;; input_data_len: u32, - ;; ) -> u32 - (import "env" "ext_create" (func $ext_create (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (drop - (call $ext_create - (i32.const 12) ;; Pointer to `code` - (i32.const {code_len}) ;; Length of `code` - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 4) ;; 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 - ) - ) - ) - ;; Amount of value to transfer. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\03\00\00\00\00\00\00\00") - ;; Embedded wasm code. - (data (i32.const 12) "{escaped_constructor}") -) -"#, - escaped_constructor = escaped_bytestring(constructor), - code_len = constructor.len(), - ) -} - #[test] -fn contract_create() { - let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap(); - let code_ctor_transfer = wabt::wat2wasm(&code_ctor(&code_transfer)).unwrap(); - let code_create = wabt::wat2wasm(&code_create(&code_ctor_transfer)).unwrap(); - +fn refunds_unused_gas() { with_externalities(&mut ExtBuilder::default().build(), || { Balances::set_free_balance(&0, 100_000_000); Balances::increase_total_stake_by(100_000_000); - Balances::set_free_balance(&1, 0); - Balances::set_free_balance(&9, 30); - Balances::increase_total_stake_by(30); - - >::insert(1, code_create.to_vec()); - - // When invoked, the contract at address `1` must create a contract with 'transfer' code. - assert_ok!(Contract::call(Origin::signed(0), 1, 11.into(), 100_000.into(), Vec::new())); - - let derived_address = ::DetermineContractAddress::contract_address_for( - &code_ctor_transfer, - &[], - &1, - ); - - // 11 - value sent with the transaction - // 2 * 362 - gas spent by the deployer contract (362) multiplied by gas price (2) - // 2 * 135 - base gas fee for call (top level) - // 2 * 175 - base gas fee for create (by contract) - // ((21 / 2) * 2) - price per account creation - let expected_gas_after_create = - 100_000_000 - 11 - (2 * 362) - (2 * 135) - (2 * 175) - ((21 / 2) * 2); - assert_eq!(Balances::free_balance(&0), expected_gas_after_create); - assert_eq!(Balances::free_balance(&1), 8); - assert_eq!(Balances::free_balance(&derived_address), 3); - - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances( - balances::RawEvent::NewAccount( - derived_address, - 0, - balances::NewAccountOutcome::NoHint - ) - ), - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(0, 1, 11)), - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(1, 2, 3)), - }, - ]); - - // Initiate transfer to the newly created contract. - assert_ok!(Contract::call(Origin::signed(0), derived_address, 22.into(), 100_000.into(), Vec::new())); - - assert_eq!( - Balances::free_balance(&0), - // 22 - value sent with the transaction - // (2 * 26) - gas used by the contract - // (2 * 135) - base gas fee for call (top level) - // (2 * 135) - base gas fee for call (by transfer contract) - expected_gas_after_create - 22 - (2 * 26) - (2 * 135) - (2 * 135), - ); - assert_eq!(Balances::free_balance(&derived_address), 22 - 3); - assert_eq!(Balances::free_balance(&9), 36); - }); -} -#[test] -fn top_level_create() { - let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap(); - let code_ctor_transfer = wabt::wat2wasm(&code_ctor(&code_transfer)).unwrap(); - - with_externalities(&mut ExtBuilder::default().gas_price(3).build(), || { - let derived_address = ::DetermineContractAddress::contract_address_for( - &code_ctor_transfer, - &[], - &0, - ); - - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - Balances::set_free_balance(&derived_address, 30); - Balances::increase_total_stake_by(30); - - assert_ok!(Contract::create( + assert_ok!(Contract::call( Origin::signed(0), - 11.into(), - 100_000.into(), - code_ctor_transfer.clone(), - Vec::new(), + 1, + 0, + 100_000, + Vec::new() )); - // 11 - value sent with the transaction - // (3 * 129) - gas spent by the init_code. - // (3 * 175) - base gas fee for create (175) (top level) multipled by gas price (3) - // ((21 / 3) * 3) - price for contract creation - assert_eq!( - Balances::free_balance(&0), - 100_000_000 - 11 - (3 * 129) - (3 * 175) - ((21 / 3) * 3) - ); - assert_eq!(Balances::free_balance(&derived_address), 30 + 11); - - assert_eq!(>::get(&derived_address), code_transfer); - - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(0, derived_address, 11)), - }, - EventRecord { - phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Created(0, 1)), - }, - ]); - }); -} - -const CODE_NOP: &'static str = r#" -(module - (func (export "call") - nop - ) -) -"#; - -#[test] -fn refunds_unused_gas() { - let code_nop = wabt::wat2wasm(CODE_NOP).unwrap(); - - with_externalities(&mut ExtBuilder::default().build(), || { - >::insert(1, code_nop.to_vec()); - - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - - assert_ok!(Contract::call(Origin::signed(0), 1, 0.into(), 100_000.into(), Vec::new())); - - assert_eq!(Balances::free_balance(&0), 100_000_000 - 4 - (2 * 135)); - }); -} - -#[test] -fn call_with_zero_value() { - with_externalities(&mut ExtBuilder::default().build(), || { - >::insert(1, vec![]); - - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - - assert_ok!(Contract::call(Origin::signed(0), 1, 0.into(), 100_000.into(), Vec::new())); - assert_eq!(Balances::free_balance(&0), 100_000_000 - (2 * 135)); }); } -#[test] -fn create_with_zero_endowment() { - let code_nop = wabt::wat2wasm(CODE_NOP).unwrap(); - - with_externalities(&mut ExtBuilder::default().build(), || { - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - - assert_ok!(Contract::create(Origin::signed(0), 0.into(), 100_000.into(), code_nop, Vec::new())); - - assert_eq!( - Balances::free_balance(&0), - // 4 - for the gas spent by the constructor - // 2 * 175 - base gas fee for create (175) multiplied by gas price (2) (top level) - 100_000_000 - 4 - (2 * 175), - ); - }); -} - #[test] fn account_removal_removes_storage() { with_externalities( @@ -704,7 +220,7 @@ fn account_removal_removes_storage() { // the balance of account 1 is will be below than exsistential threshold. // // This should lead to the removal of all storage associated with this account. - assert_ok!(Balances::transfer(Origin::signed(1), 2.into(), 20.into())); + assert_ok!(Balances::transfer(Origin::signed(1), 2, 20)); // Verify that all entries from account 1 is removed, while // entries from account 2 is in place. @@ -725,146 +241,182 @@ fn account_removal_removes_storage() { ); } -const CODE_UNREACHABLE: &'static str = r#" +const CODE_RETURN_FROM_START_FN: &str = r#" (module - (func (export "call") - nop - unreachable - ) -) -"#; - -#[test] -fn top_level_call_refunds_even_if_fails() { - let code_unreachable = wabt::wat2wasm(CODE_UNREACHABLE).unwrap(); - with_externalities(&mut ExtBuilder::default().gas_price(4).build(), || { - >::insert(1, code_unreachable.to_vec()); - - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - - assert_err!( - Contract::call(Origin::signed(0), 1, 0.into(), 100_000.into(), Vec::new()), - "vm execute returned error while call" - ); - - assert_eq!(Balances::free_balance(&0), 100_000_000 - (4 * 3) - (4 * 135)); + (import "env" "ext_return" (func $ext_return (param i32 i32))) + (import "env" "memory" (memory 1 1)) - assert_eq!(System::events(), vec![]); - }); -} + (start $start) + (func $start + (call $ext_return + (i32.const 8) + (i32.const 4) + ) + (unreachable) + ) -const CODE_LOOP: &'static str = r#" -(module (func (export "call") - (loop - (br 0) - ) + (unreachable) ) + (func (export "deploy")) + + (data (i32.const 8) "\01\02\03\04") ) "#; +const HASH_RETURN_FROM_START_FN: [u8; 32] = hex!("e6411d12daa2a19e4e9c7d8306c31c7d53a352cb8ed84385c8a1d48fc232e708"); #[test] -fn block_gas_limit() { - let code_loop = wabt::wat2wasm(CODE_LOOP).unwrap(); +fn instantiate_and_call() { + let wasm = wabt::wat2wasm(CODE_RETURN_FROM_START_FN).unwrap(); + with_externalities( - &mut ExtBuilder::default().block_gas_limit(100_000).build(), + &mut ExtBuilder::default().existential_deposit(100).build(), || { - >::insert(1, code_loop.to_vec()); - - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); - - // Spend 50_000 units of gas (OOG). - assert_err!( - Contract::call(Origin::signed(0), 1, 0.into(), 50_000.into(), Vec::new()), - "vm execute returned error while call" - ); - - // Ensure we can't spend more gas than available in block gas limit. - assert_err!( - Contract::call(Origin::signed(0), 1, 0.into(), 50_001.into(), Vec::new()), - "block gas limit is reached" - ); - - // However, we can spend another 50_000 - assert_err!( - Contract::call(Origin::signed(0), 1, 0.into(), 50_000.into(), Vec::new()), - "vm execute returned error while call" - ); + Balances::set_free_balance(&ALICE, 1_000_000); + Balances::increase_total_stake_by(1_000_000); + + assert_ok!(Contract::put_code( + Origin::signed(ALICE), + 100_000, + wasm, + )); + + assert_ok!(Contract::create( + Origin::signed(ALICE), + 100, + 100_000, + HASH_RETURN_FROM_START_FN.into(), + vec![], + )); + + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(HASH_RETURN_FROM_START_FN.into())), + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::NewAccount(BOB, 100) + ) + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)) + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)) + } + ]); }, ); } -const CODE_INPUT_DATA: &'static str = r#" +const CODE_DISPATCH_CALL: &str = r#" (module - (import "env" "ext_input_size" (func $ext_input_size (result i32))) - (import "env" "ext_input_copy" (func $ext_input_copy (param i32 i32 i32))) + (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) (import "env" "memory" (memory 1 1)) (func (export "call") - (block $fail - ;; fail if ext_input_size != 4 - (br_if $fail - (i32.ne - (i32.const 4) - (call $ext_input_size) - ) - ) - - (call $ext_input_copy - (i32.const 0) - (i32.const 0) - (i32.const 4) - ) - - - (br_if $fail - (i32.ne - (i32.load8_u (i32.const 0)) - (i32.const 0) - ) - ) - (br_if $fail - (i32.ne - (i32.load8_u (i32.const 1)) - (i32.const 1) - ) - ) - (br_if $fail - (i32.ne - (i32.load8_u (i32.const 2)) - (i32.const 2) - ) - ) - (br_if $fail - (i32.ne - (i32.load8_u (i32.const 3)) - (i32.const 3) - ) - ) - - (return) + (call $ext_dispatch_call + (i32.const 8) ;; Pointer to the start of encoded call buffer + (i32.const 11) ;; Length of the buffer ) - unreachable ) + (func (export "deploy")) + + (data (i32.const 8) "\00\00\03\00\00\00\00\00\00\00\C8") ) "#; +const HASH_DISPATCH_CALL: [u8; 32] = hex!("49dfdcaf9c1553be10634467e95b8e71a3bc15a4f8bf5563c0312b0902e0afb9"); #[test] -fn input_data() { - let code_input_data = wabt::wat2wasm(CODE_INPUT_DATA).unwrap(); - with_externalities( - &mut ExtBuilder::default().build(), - || { - >::insert(1, code_input_data.to_vec()); +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 = codec::Encode::encode(&Call::Balances(balances::Call::transfer(CHARLIE, 50))); + assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); - Balances::set_free_balance(&0, 100_000_000); - Balances::increase_total_stake_by(100_000_000); + let wasm = wabt::wat2wasm(CODE_DISPATCH_CALL).unwrap(); - assert_ok!(Contract::call(Origin::signed(0), 1, 0.into(), 50_000.into(), vec![0, 1, 2, 3])); - - // all asserts are made within contract code itself. + with_externalities( + &mut ExtBuilder::default().existential_deposit(50).build(), + || { + Balances::set_free_balance(&ALICE, 1_000_000); + Balances::increase_total_stake_by(1_000_000); + + assert_ok!(Contract::put_code( + Origin::signed(ALICE), + 100_000, + 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::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(HASH_DISPATCH_CALL.into())), + }, + ]); + + assert_ok!(Contract::create( + Origin::signed(ALICE), + 100, + 100_000, + HASH_DISPATCH_CALL.into(), + vec![], + )); + + assert_ok!(Contract::call( + Origin::signed(ALICE), + BOB, // newly created account + 0, + 100_000, + vec![], + )); + + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::CodeStored(HASH_DISPATCH_CALL.into())), + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::NewAccount(BOB, 100) + ) + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)) + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)) + }, + + // Dispatching the call. + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::NewAccount(CHARLIE, 50) + ) + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances( + balances::RawEvent::Transfer(BOB, CHARLIE, 50, 0) + ) + }, + + // Event emited as a result of dispatch. + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contract(RawEvent::Dispatched(BOB, true)) + } + ]); }, ); } diff --git a/srml/contract/src/vm/mod.rs b/srml/contract/src/vm/mod.rs deleted file mode 100644 index 63cdc5861d61e203b5913744662dd8e19f03b99d..0000000000000000000000000000000000000000 --- a/srml/contract/src/vm/mod.rs +++ /dev/null @@ -1,580 +0,0 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU 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 provides a means for executing contracts -//! represented in wasm. - -use exec::CreateReceipt; -use gas::GasMeter; -use rstd::prelude::*; -use runtime_primitives::traits::As; -use Trait; -use {balances, sandbox, system}; - -type BalanceOf = ::Balance; -type AccountIdOf = ::AccountId; - -mod prepare; -#[macro_use] -mod env_def; -mod runtime; - -use self::prepare::{prepare_contract, PreparedContract}; -use self::runtime::{to_execution_result, Runtime}; - -/// An interface that provides an access to the external environment in which the -/// smart-contract is executed. -/// -/// This interface is specialised to an account of the executing code, so all -/// operations are implicitly performed on that account. -pub trait Ext { - type T: Trait; - - /// Returns the storage entry of the executing account by the given key. - fn get_storage(&self, key: &[u8]) -> Option>; - - /// Sets the storage entry by the given key to the specified value. - fn set_storage(&mut self, key: &[u8], value: Option>); - - /// Create a new account for a contract. - /// - /// The newly created account will be associated with the `code`. `value` specifies the amount of value - /// transfered from this to the newly created account. - fn create( - &mut self, - code: &[u8], - value: BalanceOf, - gas_meter: &mut GasMeter, - data: &[u8], - ) -> Result, ()>; - - /// Call (possibly transfering some amount of funds) into the specified account. - fn call( - &mut self, - to: &AccountIdOf, - value: BalanceOf, - gas_meter: &mut GasMeter, - data: &[u8], - output_data: &mut Vec, - ) -> Result<(), ()>; -} - -/// Error that can occur while preparing or executing wasm smart-contract. -#[derive(Debug, PartialEq, Eq)] -pub enum Error { - /// Error happened while serializing the module. - Serialization, - - /// Error happened while deserializing the module. - Deserialization, - - /// Internal memory declaration has been found in the module. - InternalMemoryDeclared, - - /// Gas instrumentation failed. - /// - /// This most likely indicates the module isn't valid. - GasInstrumentation, - - /// Stack instrumentation failed. - /// - /// This most likely indicates the module isn't valid. - StackHeightInstrumentation, - - /// Error happened during invocation of the contract's entrypoint. - /// - /// Most likely because of trap. - Invoke, - - /// Error happened during instantiation. - /// - /// This might indicate that `start` function trapped, or module isn't - /// instantiable and/or unlinkable. - Instantiate, - - /// Memory creation error. - /// - /// This might happen when the memory import has invalid descriptor or - /// requested too much resources. - Memory, -} - -/// Execute the given code as a contract. -pub fn execute<'a, E: Ext>( - code: &[u8], - input_data: &[u8], - output_data: &mut Vec, - ext: &'a mut E, - config: &Config, - gas_meter: &mut GasMeter, -) -> Result<(), Error> { - let env = runtime::init_env(); - - let PreparedContract { - instrumented_code, - memory, - } = prepare_contract(code, &config, &env)?; - - let mut imports = sandbox::EnvironmentDefinitionBuilder::new(); - for (func_name, ext_func) in &env.funcs { - imports.add_host_func("env", &func_name[..], ext_func.raw_fn_ptr()); - } - imports.add_memory("env", "memory", memory.clone()); - - let mut runtime = Runtime::new(ext, input_data, output_data, &config, memory, gas_meter); - - // Instantiate the instance from the instrumented module code. - match sandbox::Instance::new(&instrumented_code, &imports, &mut runtime) { - // No errors or traps were generated on instantiation! That - // means we can now invoke the contract entrypoint. - Ok(mut instance) => { - let err = instance.invoke(b"call", &[], &mut runtime).err(); - to_execution_result(runtime, err) - } - // `start` function trapped. Treat it in the same manner as an execution error. - Err(err @ sandbox::Error::Execution) => to_execution_result(runtime, Some(err)), - // Other instantiation errors. - // Return without executing anything. - Err(_) => return Err(Error::Instantiate), - } -} - -// TODO: Extract it to the root of the crate -#[derive(Clone)] -pub struct Config { - /// Gas cost of a growing memory by single page. - grow_mem_cost: T::Gas, - - /// Gas cost of a regular operation. - regular_op_cost: T::Gas, - - /// Gas cost per one byte returned. - return_data_per_byte_cost: T::Gas, - - /// Gas cost per one byte read from the sandbox memory. - sandbox_data_read_cost: T::Gas, - - /// Gas cost per one byte written to the sandbox memory. - sandbox_data_write_cost: T::Gas, - - /// How tall the stack is allowed to grow? - /// - /// See https://wiki.parity.io/WebAssembly-StackHeight to find out - /// how the stack frame cost is calculated. - max_stack_height: u32, - - //// What is the maximal memory pages amount is allowed to have for - /// a contract. - max_memory_pages: u32, -} - -impl Default for Config { - fn default() -> Config { - Config { - grow_mem_cost: T::Gas::sa(1), - regular_op_cost: T::Gas::sa(1), - return_data_per_byte_cost: T::Gas::sa(1), - sandbox_data_read_cost: T::Gas::sa(1), - sandbox_data_write_cost: T::Gas::sa(1), - max_stack_height: 64 * 1024, - max_memory_pages: 16, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use gas::GasMeter; - use std::collections::HashMap; - use tests::Test; - use wabt; - - #[derive(Debug, PartialEq, Eq)] - struct CreateEntry { - code: Vec, - endowment: u64, - data: Vec, - gas_left: u64, - } - #[derive(Debug, PartialEq, Eq)] - struct TransferEntry { - to: u64, - value: u64, - data: Vec, - gas_left: u64, - } - #[derive(Default)] - pub struct MockExt { - storage: HashMap, Vec>, - creates: Vec, - transfers: Vec, - next_account_id: u64, - } - impl Ext for MockExt { - type T = Test; - - fn get_storage(&self, key: &[u8]) -> Option> { - self.storage.get(key).cloned() - } - fn set_storage(&mut self, key: &[u8], value: Option>) { - *self.storage.entry(key.to_vec()).or_insert(Vec::new()) = value.unwrap_or(Vec::new()); - } - fn create( - &mut self, - code: &[u8], - endowment: u64, - gas_meter: &mut GasMeter, - data: &[u8], - ) -> Result, ()> { - self.creates.push(CreateEntry { - code: code.to_vec(), - endowment, - data: data.to_vec(), - gas_left: gas_meter.gas_left(), - }); - let address = self.next_account_id; - self.next_account_id += 1; - - Ok(CreateReceipt { address }) - } - fn call( - &mut self, - to: &u64, - value: u64, - gas_meter: &mut GasMeter, - data: &[u8], - _output_data: &mut Vec, - ) -> Result<(), ()> { - self.transfers.push(TransferEntry { - to: *to, - value, - data: data.to_vec(), - gas_left: gas_meter.gas_left(), - }); - // Assume for now that it was just a plain transfer. - // TODO: Add tests for different call outcomes. - Ok(()) - } - } - - const CODE_TRANSFER: &str = r#" -(module - ;; ext_call( - ;; callee_ptr: u32, - ;; callee_len: u32, - ;; gas: u64, - ;; value_ptr: u32, - ;; value_len: u32, - ;; input_data_ptr: u32, - ;; input_data_len: u32 - ;;) -> u32 - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (drop - (call $ext_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. - (i32.const 12) ;; 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.const 4) ;; Length of input data buffer - ) - ) - ) - ;; Destination AccountId to transfer the funds. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\09\00\00\00\00\00\00\00") - ;; Amount of value to transfer. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 12) "\06\00\00\00\00\00\00\00") - - (data (i32.const 20) "\01\02\03\04") -) -"#; - - #[test] - fn contract_transfer() { - let code_transfer = wabt::wat2wasm(CODE_TRANSFER).unwrap(); - - let mut mock_ext = MockExt::default(); - execute( - &code_transfer, - &[], - &mut Vec::new(), - &mut mock_ext, - &::vm::Config::default(), - &mut GasMeter::with_limit(50_000, 1), - ).unwrap(); - - assert_eq!( - &mock_ext.transfers, - &[TransferEntry { - to: 9, - value: 6, - data: vec![ - 1, 2, 3, 4, - ], - gas_left: 49970, - }] - ); - } - - const CODE_CREATE: &str = r#" -(module - ;; ext_create( - ;; code_ptr: u32, - ;; code_len: u32, - ;; gas: u64, - ;; value_ptr: u32, - ;; value_len: u32, - ;; input_data_ptr: u32, - ;; input_data_len: u32, - ;; ) -> u32 - (import "env" "ext_create" (func $ext_create (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (drop - (call $ext_create - (i32.const 12) ;; Pointer to `code` - (i32.const 8) ;; Length of `code` - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 4) ;; 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.const 4) ;; Length of input data buffer - ) - ) - ) - ;; Amount of value to transfer. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\03\00\00\00\00\00\00\00") - ;; Embedded wasm code. - (data (i32.const 12) "\00\61\73\6d\01\00\00\00") - ;; Input data to pass to the contract being created. - (data (i32.const 20) "\01\02\03\04") -) -"#; - - #[test] - fn contract_create() { - let code_create = wabt::wat2wasm(CODE_CREATE).unwrap(); - - let mut mock_ext = MockExt::default(); - execute( - &code_create, - &[], - &mut Vec::new(), - &mut mock_ext, - &::vm::Config::default(), - &mut GasMeter::with_limit(50_000, 1), - ).unwrap(); - - assert_eq!( - &mock_ext.creates, - &[CreateEntry { - code: vec![0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00], - endowment: 3, - data: vec![ - 1, 2, 3, 4, - ], - gas_left: 49970, - }] - ); - } - - const CODE_MEM: &str = r#" -(module - ;; Internal memory is not allowed. - (memory 1 1) - - (func (export "call") - nop - ) -) -"#; - - #[test] - fn contract_internal_mem() { - let code_mem = wabt::wat2wasm(CODE_MEM).unwrap(); - - let mut mock_ext = MockExt::default(); - - assert_matches!( - execute( - &code_mem, - &[], - &mut Vec::new(), - &mut mock_ext, - &::vm::Config::default(), - &mut GasMeter::with_limit(100_000, 1) - ), - Err(_) - ); - } - - const CODE_TRANSFER_LIMITED_GAS: &str = r#" -(module - ;; ext_call( - ;; callee_ptr: u32, - ;; callee_len: u32, - ;; gas: u64, - ;; value_ptr: u32, - ;; value_len: u32, - ;; input_data_ptr: u32, - ;; input_data_len: u32 - ;;) -> u32 - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - (func (export "call") - (drop - (call $ext_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. - (i32.const 12) ;; 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.const 4) ;; Length of input data buffer - ) - ) - ) - ;; Destination AccountId to transfer the funds. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 4) "\09\00\00\00\00\00\00\00") - ;; Amount of value to transfer. - ;; Represented by u64 (8 bytes long) in little endian. - (data (i32.const 12) "\06\00\00\00\00\00\00\00") - - (data (i32.const 20) "\01\02\03\04") -) -"#; - - #[test] - fn contract_call_limited_gas() { - let code_transfer = wabt::wat2wasm(CODE_TRANSFER_LIMITED_GAS).unwrap(); - - let mut mock_ext = MockExt::default(); - execute( - &code_transfer, - &[], - &mut Vec::new(), - &mut mock_ext, - &::vm::Config::default(), - &mut GasMeter::with_limit(50_000, 1), - ).unwrap(); - - assert_eq!( - &mock_ext.transfers, - &[TransferEntry { - to: 9, - value: 6, - data: vec![ - 1, 2, 3, 4, - ], - gas_left: 228, - }] - ); - } - - 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_copy" (func $ext_scratch_copy (param i32 i32 i32))) - (import "env" "ext_return" (func $ext_return (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - (local $buf_size i32) - - - ;; Load a storage value into the scratch buf. - (call $assert - (i32.eq - (call $ext_get_storage - (i32.const 4) ;; The pointer to the storage key to fetch - ) - - ;; Return value 0 means that the value is found and there were - ;; no errors. - (i32.const 0) - ) - ) - - ;; 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_copy - (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 - ) - ) - - ;; Return the contents of the buffer - (call $ext_return - (i32.const 36) - (get_local $buf_size) - ) - - ;; env:ext_return doesn't return, so this is effectively unreachable. - (unreachable) - ) - - (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() { - let code_get_storage = wabt::wat2wasm(CODE_GET_STORAGE).unwrap(); - - let mut mock_ext = MockExt::default(); - mock_ext.storage.insert([0x11; 32].to_vec(), [0x22; 32].to_vec()); - - let mut return_buf = Vec::new(); - execute( - &code_get_storage, - &[], - &mut return_buf, - &mut mock_ext, - &Config::default(), - &mut GasMeter::with_limit(50_000, 1), - ).unwrap(); - - assert_eq!( - return_buf, - [0x22; 32].to_vec(), - ); - } -} diff --git a/srml/contract/src/vm/prepare.rs b/srml/contract/src/vm/prepare.rs deleted file mode 100644 index b79ce8336ddb5daab5e8b4075c5104b8bad7da94..0000000000000000000000000000000000000000 --- a/srml/contract/src/vm/prepare.rs +++ /dev/null @@ -1,286 +0,0 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Substrate is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU 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 that takes care of loading, checking and preprocessing of a -//! wasm module before execution. - -use super::env_def::HostFunctionSet; -use super::{Config, Error, Ext}; -use rstd::prelude::*; -use parity_wasm::elements::{self, External, MemoryType, Type}; -use pwasm_utils; -use pwasm_utils::rules; -use runtime_primitives::traits::As; -use sandbox; -use Trait; - -struct ContractModule<'a, T: Trait + 'a> { - // An `Option` is used here for loaning (`take()`-ing) the module. - // Invariant: Can't be `None` (i.e. on enter and on exit from the function - // the value *must* be `Some`). - module: Option, - config: &'a Config, -} - -impl<'a, T: Trait> ContractModule<'a, T> { - fn new(original_code: &[u8], config: &'a Config) -> Result, Error> { - let module = - elements::deserialize_buffer(original_code).map_err(|_| Error::Deserialization)?; - Ok(ContractModule { - module: Some(module), - config, - }) - } - - /// Ensures that module doesn't declare internal memories. - /// - /// In this runtime we only allow wasm module to import memory from the environment. - /// Memory section contains declarations of internal linear memories, so if we find one - /// we reject such a module. - fn ensure_no_internal_memory(&self) -> Result<(), Error> { - let module = self - .module - .as_ref() - .expect("On entry to the function `module` can't be None; qed"); - if module - .memory_section() - .map_or(false, |ms| ms.entries().len() > 0) - { - return Err(Error::InternalMemoryDeclared); - } - Ok(()) - } - - fn inject_gas_metering(&mut self) -> Result<(), Error> { - let gas_rules = rules::Set::new(self.config.regular_op_cost.as_(), Default::default()) - .with_grow_cost(self.config.grow_mem_cost.as_()) - .with_forbidden_floats(); - - let module = self - .module - .take() - .expect("On entry to the function `module` can't be `None`; qed"); - - let contract_module = pwasm_utils::inject_gas_counter(module, &gas_rules) - .map_err(|_| Error::GasInstrumentation)?; - - self.module = Some(contract_module); - Ok(()) - } - - fn inject_stack_height_metering(&mut self) -> Result<(), Error> { - let module = self - .module - .take() - .expect("On entry to the function `module` can't be `None`; qed"); - - let contract_module = - pwasm_utils::stack_height::inject_limiter(module, self.config.max_stack_height) - .map_err(|_| Error::StackHeightInstrumentation)?; - - self.module = Some(contract_module); - Ok(()) - } - - /// Scan an import section if any. - /// - /// This accomplishes two tasks: - /// - /// - checks any imported function against defined host functions set, incl. - /// their signatures. - /// - if there is a memory import, returns it's descriptor - fn scan_imports(&self, env: &HostFunctionSet) -> Result, Error> { - let module = self - .module - .as_ref() - .expect("On entry to the function `module` can't be `None`; qed"); - - let types = module.type_section().map(|ts| ts.types()).unwrap_or(&[]); - let import_entries = module - .import_section() - .map(|is| is.entries()) - .unwrap_or(&[]); - - 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(Error::Instantiate); - } - - let type_idx = match import.external() { - &External::Function(ref type_idx) => type_idx, - &External::Memory(ref memory_type) => { - imported_mem_type = Some(memory_type); - continue; - } - _ => continue, - }; - - let Type::Function(ref func_ty) = types - .get(*type_idx as usize) - .ok_or_else(|| Error::Instantiate)?; - - let ext_func = env - .funcs - .get(import.field().as_bytes()) - .ok_or_else(|| Error::Instantiate)?; - if !ext_func.func_type_matches(func_ty) { - return Err(Error::Instantiate); - } - } - Ok(imported_mem_type) - } - - fn into_wasm_code(mut self) -> Result, Error> { - elements::serialize( - self.module - .take() - .expect("On entry to the function `module` can't be `None`; qed"), - ).map_err(|_| Error::Serialization) - } -} - -pub(super) struct PreparedContract { - pub instrumented_code: Vec, - pub memory: sandbox::Memory, -} - -/// Loads the given module given in `original_code`, performs some checks on it and -/// does some preprocessing. -/// -/// The checks are: -/// -/// - module doesn't define an internal memory instance, -/// - imported memory (if any) doesn't reserve more memory than permitted by the `config`, -/// - all imported functions from the external environment matches defined by `env` module, -/// -/// The preprocessing includes injecting code for gas metering and metering the height of stack. -pub(super) fn prepare_contract( - original_code: &[u8], - config: &Config, - env: &HostFunctionSet, -) -> Result { - let mut contract_module = ContractModule::new(original_code, config)?; - contract_module.ensure_no_internal_memory()?; - contract_module.inject_gas_metering()?; - contract_module.inject_stack_height_metering()?; - - let memory = if let Some(memory_type) = contract_module.scan_imports(env)? { - // Inspect the module to extract the initial and maximum page count. - let limits = memory_type.limits(); - match (limits.initial(), limits.maximum()) { - (initial, Some(maximum)) if initial > maximum => { - // Requested initial number of pages should not exceed the requested maximum. - return Err(Error::Memory); - } - (_, Some(maximum)) if maximum > config.max_memory_pages => { - // Maximum number of pages should not exceed the configured maximum. - return Err(Error::Memory); - } - (_, None) => { - // Maximum number of pages should be always declared. - // This isn't a hard requirement and can be treated as a maxiumum set - // to configured maximum. - return Err(Error::Memory); - } - (initial, maximum) => sandbox::Memory::new(initial, maximum), - } - } else { - // If none memory imported then just crate an empty placeholder. - // Any access to it will lead to out of bounds trap. - sandbox::Memory::new(0, Some(0)) - }; - let memory = memory.map_err(|_| Error::Memory)?; - - Ok(PreparedContract { - instrumented_code: contract_module.into_wasm_code()?, - memory, - }) -} - -#[cfg(test)] -mod tests { - use super::*; - use std::fmt; - use tests::Test; - use vm::tests::MockExt; - use wabt; - - impl fmt::Debug for PreparedContract { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "PreparedContract {{ .. }}") - } - } - - fn parse_and_prepare_wat(wat: &str) -> Result { - let wasm = wabt::Wat2Wasm::new().validate(false).convert(wat).unwrap(); - let config = Config::::default(); - let env = ::vm::runtime::init_env(); - prepare_contract::(wasm.as_ref(), &config, &env) - } - - #[test] - fn internal_memory_declaration() { - let r = parse_and_prepare_wat(r#"(module (memory 1 1))"#); - assert_matches!(r, Err(Error::InternalMemoryDeclared)); - } - - #[test] - fn memory() { - // This test assumes that maximum page number is configured to a certain number. - assert_eq!(Config::::default().max_memory_pages, 16); - - let r = parse_and_prepare_wat(r#"(module (import "env" "memory" (memory 1 1)))"#); - assert_matches!(r, Ok(_)); - - // No memory import - let r = parse_and_prepare_wat(r#"(module)"#); - assert_matches!(r, Ok(_)); - - // initial exceed maximum - let r = parse_and_prepare_wat(r#"(module (import "env" "memory" (memory 16 1)))"#); - assert_matches!(r, Err(Error::Memory)); - - // no maximum - let r = parse_and_prepare_wat(r#"(module (import "env" "memory" (memory 1)))"#); - assert_matches!(r, Err(Error::Memory)); - - // requested maximum exceed configured maximum - let r = parse_and_prepare_wat(r#"(module (import "env" "memory" (memory 1 17)))"#); - assert_matches!(r, Err(Error::Memory)); - } - - #[test] - fn imports() { - // nothing can be imported from non-"env" module for now. - let r = parse_and_prepare_wat(r#"(module (import "another_module" "memory" (memory 1 1)))"#); - assert_matches!(r, Err(Error::Instantiate)); - - let r = parse_and_prepare_wat(r#"(module (import "env" "gas" (func (param i32))))"#); - assert_matches!(r, Ok(_)); - - // wrong signature - let r = parse_and_prepare_wat(r#"(module (import "env" "gas" (func (param i64))))"#); - assert_matches!(r, Err(Error::Instantiate)); - - // unknown function name - let r = parse_and_prepare_wat(r#"(module (import "env" "unknown_func" (func)))"#); - assert_matches!(r, Err(Error::Instantiate)); - } -} diff --git a/srml/contract/src/wasm/code_cache.rs b/srml/contract/src/wasm/code_cache.rs new file mode 100644 index 0000000000000000000000000000000000000000..e0c5bd4b97ae4155dc4d34645111570a255b7fb7 --- /dev/null +++ b/srml/contract/src/wasm/code_cache.rs @@ -0,0 +1,106 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! A module that implements instrumented code cache. +//! +//! - In order to run contract code we need to instrument it with gas metering. +//! To do that we need to provide the schedule which will supply exact gas costs values. +//! We cache this code in the storage saving the schedule version. +//! - Before running contract code we check if the cached code has the schedule version that is equal to the current saved schedule. +//! If it is equal then run the code, if it isn't reinstrument with the current schedule. +//! - When we update the schedule we want it to have strictly greater version than the current saved one: +//! this guarantees that every instrumented contract code in cache cannot have the version equal to the current one. +//! Thus, before executing a contract it should be reinstrument with new schedule. + +use gas::{GasMeter, Token}; +use rstd::prelude::*; +use runtime_primitives::traits::{As, CheckedMul, Hash, Bounded}; +use runtime_support::StorageMap; +use wasm::{prepare, runtime::Env, PrefabWasmModule}; +use {CodeHash, CodeStorage, PristineCode, Schedule, Trait}; + +/// Gas metering token that used for charging storing code into the code storage. +/// +/// Specifies the code length in bytes. +#[cfg_attr(test, derive(Debug, PartialEq, Eq))] +#[derive(Copy, Clone)] +pub struct PutCodeToken(u64); + +impl Token for PutCodeToken { + type Metadata = Schedule; + + fn calculate_amount(&self, metadata: &Schedule) -> T::Gas { + let code_len_in_gas = >::sa(self.0); + metadata + .put_code_per_byte_cost + .checked_mul(&code_len_in_gas) + .unwrap_or_else(|| Bounded::max_value()) + } +} + +/// Put code in the storage. The hash of code is used as a key and is returned +/// as a result of this function. +/// +/// This function instruments the given code and caches it in the storage. +pub fn save( + original_code: Vec, + gas_meter: &mut GasMeter, + schedule: &Schedule, +) -> Result, &'static str> { + // The first time instrumentation is on the user. However, consequent reinstrumentation + // due to the schedule changes is on governance system. + if gas_meter + .charge(schedule, PutCodeToken(original_code.len() as u64)) + .is_out_of_gas() + { + return Err("there is not enough gas for storing the code"); + } + + let prefab_module = prepare::prepare_contract::(&original_code, schedule)?; + let code_hash = T::Hashing::hash(&original_code); + + // TODO: #1416 validate the code. If the code is not valid, then don't store it. + + >::insert(code_hash, prefab_module); + >::insert(code_hash, original_code); + + Ok(code_hash) +} + +/// Load code with the given code hash. +/// +/// If the module was instrumented with a lower version of schedule than +/// the current one given as an argument, then this function will perform +/// re-instrumentation and update the cache in the storage. +pub fn load( + code_hash: &CodeHash, + schedule: &Schedule, +) -> Result { + let mut prefab_module = + >::get(code_hash).ok_or_else(|| "code is not found")?; + + if prefab_module.schedule_version < schedule.version { + // The current schedule version is greater than the version of the one cached + // in the storage. + // + // We need to re-instrument the code with the latest schedule here. + let original_code = + >::get(code_hash).ok_or_else(|| "pristine code is not found")?; + prefab_module = prepare::prepare_contract::(&original_code, schedule)?; + >::insert(code_hash, prefab_module.clone()); + } + Ok(prefab_module) +} diff --git a/srml/contract/src/vm/env_def/macros.rs b/srml/contract/src/wasm/env_def/macros.rs similarity index 69% rename from srml/contract/src/vm/env_def/macros.rs rename to srml/contract/src/wasm/env_def/macros.rs index 16ba669dafa5c3d97d8a40f6304b09fb6a36632f..bd123c43604c88b87e4a0a92b289020757142934 100644 --- a/srml/contract/src/vm/env_def/macros.rs +++ b/srml/contract/src/wasm/env_def/macros.rs @@ -17,12 +17,12 @@ //! Definition of macros that hides boilerplate of defining external environment //! for a wasm module. //! -//! Typically you should use `define_env` macro. +//! Most likely you should use `define_env` macro. #[macro_export] macro_rules! convert_args { () => (vec![]); - ( $( $t:ty ),* ) => ( vec![ $( { use $crate::vm::env_def::ConvertibleToWasm; <$t>::VALUE_TYPE }, )* ] ); + ( $( $t:ty ),* ) => ( vec![ $( { use $crate::wasm::env_def::ConvertibleToWasm; <$t>::VALUE_TYPE }, )* ] ); } #[macro_export] @@ -36,19 +36,39 @@ macro_rules! gen_signature { ( ( $( $params: ty ),* ) -> $returns: ty ) => ( { $crate::parity_wasm::elements::FunctionType::new(convert_args!($($params),*), Some({ - use $crate::vm::env_def::ConvertibleToWasm; <$returns>::VALUE_TYPE + use $crate::wasm::env_def::ConvertibleToWasm; <$returns>::VALUE_TYPE })) } ); } +#[macro_export] +macro_rules! gen_signature_dispatch { + ( + $needle_name:ident, + $needle_sig:ident ; + $name:ident + ( $ctx:ident $( , $names:ident : $params:ty )* ) $( -> $returns:ty )* , $($rest:tt)* ) => { + if stringify!($name).as_bytes() == $needle_name { + let signature = gen_signature!( ( $( $params ),* ) $( -> $returns )* ); + if $needle_sig == &signature { + return true; + } + } else { + gen_signature_dispatch!($needle_name, $needle_sig ; $($rest)*); + } + }; + ( $needle_name:ident, $needle_sig:ident ; ) => { + }; +} + /// Unmarshall arguments and then execute `body` expression and return its result. macro_rules! unmarshall_then_body { ( $body:tt, $ctx:ident, $args_iter:ident, $( $names:ident : $params:ty ),* ) => ({ $( - let $names : <$params as $crate::vm::env_def::ConvertibleToWasm>::NativeType = + let $names : <$params as $crate::wasm::env_def::ConvertibleToWasm>::NativeType = $args_iter.next() - .and_then(|v| <$params as $crate::vm::env_def::ConvertibleToWasm> + .and_then(|v| <$params as $crate::wasm::env_def::ConvertibleToWasm> ::from_typed_value(v.clone())) .expect( "precondition: all imports should be checked against the signatures of corresponding @@ -84,16 +104,16 @@ where #[macro_export] macro_rules! unmarshall_then_body_then_marshall { ( $args_iter:ident, $ctx:ident, ( $( $names:ident : $params:ty ),* ) -> $returns:ty => $body:tt ) => ({ - let body = $crate::vm::env_def::macros::constrain_closure::< - <$returns as $crate::vm::env_def::ConvertibleToWasm>::NativeType, _ + let body = $crate::wasm::env_def::macros::constrain_closure::< + <$returns as $crate::wasm::env_def::ConvertibleToWasm>::NativeType, _ >(|| { unmarshall_then_body!($body, $ctx, $args_iter, $( $names : $params ),*) }); let r = body()?; - return Ok($crate::sandbox::ReturnValue::Value({ use $crate::vm::env_def::ConvertibleToWasm; r.to_typed_value() })) + return Ok($crate::sandbox::ReturnValue::Value({ use $crate::wasm::env_def::ConvertibleToWasm; r.to_typed_value() })) }); ( $args_iter:ident, $ctx:ident, ( $( $names:ident : $params:ty ),* ) => $body:tt ) => ({ - let body = $crate::vm::env_def::macros::constrain_closure::<(), _>(|| { + let body = $crate::wasm::env_def::macros::constrain_closure::<(), _>(|| { unmarshall_then_body!($body, $ctx, $args_iter, $( $names : $params ),*) }); body()?; @@ -105,7 +125,7 @@ macro_rules! unmarshall_then_body_then_marshall { 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 >( - $ctx: &mut $crate::vm::Runtime, + $ctx: &mut $crate::wasm::Runtime, args: &[$crate::sandbox::TypedValue], ) -> Result { #[allow(unused)] @@ -120,6 +140,27 @@ macro_rules! define_func { }; } +#[macro_export] +macro_rules! register_func { + ( $reg_cb:ident, < E: $ext_ty:tt > ; ) => {}; + + ( $reg_cb:ident, < E: $ext_ty:tt > ; + $name:ident ( $ctx:ident $( , $names:ident : $params:ty )* ) + $( -> $returns:ty )* => $body:tt $($rest:tt)* + ) => { + $reg_cb( + stringify!($name).as_bytes(), + { + define_func!( + < E: $ext_ty > $name ( $ctx $(, $names : $params )* ) $( -> $returns )* => $body + ); + $name:: + } + ); + register_func!( $reg_cb, < E: $ext_ty > ; $($rest)* ); + }; +} + /// Define a function set that can be imported by executing wasm code. /// /// **NB**: Be advised that all functions defined by this macro @@ -132,25 +173,20 @@ macro_rules! define_env { $( $name:ident ( $ctx:ident $( , $names:ident : $params:ty )* ) $( -> $returns:ty )* => $body:tt , )* ) => { - pub(crate) fn $init_name() -> $crate::vm::env_def::HostFunctionSet { - let mut env = $crate::vm::env_def::HostFunctionSet::new(); - - $( - env.funcs.insert( - stringify!( $name ).into(), - $crate::vm::env_def::HostFunction::new( - gen_signature!( ( $( $params ),* ) $( -> $returns )* ), - { - define_func!( - < E: $ext_ty > $name ( $ctx $(, $names : $params )* ) $( -> $returns )* => $body - ); - $name:: - }, - ), - ); - )* + pub struct $init_name; - env + impl $crate::wasm::env_def::ImportSatisfyCheck for $init_name { + fn can_satisfy(name: &[u8], func_type: &$crate::parity_wasm::elements::FunctionType) -> bool { + gen_signature_dispatch!( name, func_type ; $( $name ( $ctx $(, $names : $params )* ) $( -> $returns )* , )* ); + + return false; + } + } + + 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 )* ); + } } }; } @@ -161,8 +197,9 @@ mod tests { use parity_wasm::elements::ValueType; use runtime_primitives::traits::{As, Zero}; use sandbox::{self, ReturnValue, TypedValue}; - use vm::tests::MockExt; - use vm::{Ext, Runtime}; + use wasm::tests::MockExt; + use wasm::Runtime; + use exec::Ext; use Trait; #[test] @@ -219,7 +256,7 @@ mod tests { #[test] fn macro_define_func() { define_func!( ext_gas (_ctx, amount: u32) => { - let amount = <<::T as Trait>::Gas as As>::sa(amount); + let amount = <::Gas as As>::sa(amount); if !amount.is_zero() { Ok(()) } else { @@ -267,9 +304,11 @@ mod tests { #[test] fn macro_define_env() { - define_env!(init_env, , + use wasm::env_def::ImportSatisfyCheck; + + define_env!(Env, , ext_gas( _ctx, amount: u32 ) => { - let amount = <<::T as Trait>::Gas as As>::sa(amount); + let amount = <::Gas as As>::sa(amount); if !amount.is_zero() { Ok(()) } else { @@ -278,7 +317,7 @@ mod tests { }, ); - let env = init_env::(); - assert!(env.funcs.get(&b"ext_gas"[..]).is_some()); + assert!(Env::can_satisfy(b"ext_gas", &FunctionType::new(vec![ValueType::I32], None))); + assert!(!Env::can_satisfy(b"not_exists", &FunctionType::new(vec![], None))); } } diff --git a/srml/contract/src/vm/env_def/mod.rs b/srml/contract/src/wasm/env_def/mod.rs similarity index 58% rename from srml/contract/src/vm/env_def/mod.rs rename to srml/contract/src/wasm/env_def/mod.rs index d66e1b8961ac8edeed5c8d7ce58d95a784893447..0f4de9186036df81948c802cd532e39abaf13010 100644 --- a/srml/contract/src/vm/env_def/mod.rs +++ b/srml/contract/src/wasm/env_def/mod.rs @@ -14,10 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use super::{Ext, Runtime}; +use super::Runtime; +use exec::Ext; use parity_wasm::elements::{FunctionType, ValueType}; -use rstd::prelude::*; -use rstd::collections::btree_map::BTreeMap; use sandbox::{self, TypedValue}; #[macro_use] @@ -66,45 +65,21 @@ impl ConvertibleToWasm for u64 { } } -/// Represents a set of function that defined in this particular environment and -/// which can be imported and called by the module. -pub(crate) struct HostFunctionSet { - /// Functions which defined in the environment. - pub funcs: BTreeMap, HostFunction>, -} -impl HostFunctionSet { - pub fn new() -> Self { - HostFunctionSet { - funcs: BTreeMap::new(), - } - } -} +pub(crate) type HostFunc = + fn( + &mut Runtime, + &[sandbox::TypedValue] + ) -> Result; -pub(crate) struct HostFunction { - pub(crate) f: fn(&mut Runtime, &[sandbox::TypedValue]) - -> Result, - func_type: FunctionType, +pub(crate) trait FunctionImplProvider { + fn impls)>(f: &mut F); } -impl HostFunction { - /// Create a new instance of a host function. - pub fn new( - func_type: FunctionType, - f: fn(&mut Runtime, &[sandbox::TypedValue]) - -> Result, - ) -> Self { - HostFunction { func_type, f } - } - - /// Returns a function pointer of this host function. - pub fn raw_fn_ptr( - &self, - ) -> fn(&mut Runtime, &[sandbox::TypedValue]) - -> Result { - self.f - } - /// Check if the this function could be invoked with the given function signature. - pub fn func_type_matches(&self, func_type: &FunctionType) -> bool { - &self.func_type == func_type - } +/// This trait can be used to check whether the host environment can satisfy +/// a requested function import. +pub trait ImportSatisfyCheck { + /// Returns `true` if the host environment contains a function with + /// the specified name and its type matches to the given type, or `false` + /// otherwise. + fn can_satisfy(name: &[u8], func_type: &FunctionType) -> bool; } diff --git a/srml/contract/src/wasm/mod.rs b/srml/contract/src/wasm/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..4d75b8a7d1afeafeac9ef86c8031fff5c87e17ac --- /dev/null +++ b/srml/contract/src/wasm/mod.rs @@ -0,0 +1,1031 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 provides a means for executing contracts +//! represented in wasm. + +use codec::Compact; +use exec::{Ext, EmptyOutputBuf, VmExecResult}; +use gas::GasMeter; +use rstd::prelude::*; +use sandbox; +use wasm::env_def::FunctionImplProvider; +use {CodeHash, Schedule, Trait}; + +#[macro_use] +mod env_def; +mod code_cache; +mod prepare; +mod runtime; + +use self::runtime::{to_execution_result, Runtime}; +use self::code_cache::load as load_code; + +pub use self::code_cache::save as save_code; + +/// A prepared wasm module ready for execution. +#[derive(Clone, Encode, Decode)] +pub struct PrefabWasmModule { + /// Version of the schedule with which the code was instrumented. + #[codec(compact)] + schedule_version: u32, + #[codec(compact)] + initial: u32, + #[codec(compact)] + maximum: u32, + /// This field is reserved for future evolution of format. + /// + /// Basically, for now this field will be serialized as `None`. In the future + /// we would be able to extend this structure with. + _reserved: Option<()>, + /// Code instrumented with the latest schedule. + code: Vec, +} + +/// Wasm executable loaded by `WasmLoader` and executed by `WasmVm`. +pub struct WasmExecutable { + entrypoint_name: &'static [u8], + prefab_module: PrefabWasmModule, +} + +/// Loader which fetches `WasmExecutable` from the code cache. +pub struct WasmLoader<'a, T: Trait> { + schedule: &'a Schedule, +} + +impl<'a, T: Trait> WasmLoader<'a, T> { + pub fn new(schedule: &'a Schedule) -> Self { + WasmLoader { schedule } + } +} + +impl<'a, T: Trait> ::exec::Loader for WasmLoader<'a, T> { + type Executable = WasmExecutable; + + fn load_init(&self, code_hash: &CodeHash) -> Result { + let prefab_module = load_code::(code_hash, self.schedule)?; + Ok(WasmExecutable { + entrypoint_name: b"deploy", + prefab_module, + }) + } + fn load_main(&self, code_hash: &CodeHash) -> Result { + let prefab_module = load_code::(code_hash, self.schedule)?; + Ok(WasmExecutable { + entrypoint_name: b"call", + prefab_module, + }) + } +} + +/// Implementation of `Vm` that takes `WasmExecutable` and executes it. +pub struct WasmVm<'a, T: Trait> { + schedule: &'a Schedule, +} + +impl<'a, T: Trait> WasmVm<'a, T> { + pub fn new(schedule: &'a Schedule) -> Self { + WasmVm { schedule } + } +} + +impl<'a, T: Trait> ::exec::Vm for WasmVm<'a, T> { + type Executable = WasmExecutable; + + fn execute>( + &self, + exec: &WasmExecutable, + ext: &mut E, + input_data: &[u8], + empty_output_buf: EmptyOutputBuf, + gas_meter: &mut GasMeter, + ) -> VmExecResult { + let memory = + sandbox::Memory::new(exec.prefab_module.initial, Some(exec.prefab_module.maximum)) + .unwrap_or_else(|_| { + // unlike `.expect`, explicit panic preserves the source location. + // Needed as we can't use `RUST_BACKTRACE` in here. + panic!( + "exec.prefab_module.initial can't be greater than exec.prefab_module.maximum; + thus Memory::new must not fail; + qed" + ) + }); + + let mut imports = sandbox::EnvironmentDefinitionBuilder::new(); + imports.add_memory("env", "memory", memory.clone()); + runtime::Env::impls(&mut |name, func_ptr| { + imports.add_host_func("env", name, func_ptr); + }); + + let mut runtime = Runtime::new( + ext, + input_data, + empty_output_buf, + &self.schedule, + memory, + gas_meter, + ); + + // Instantiate the instance from the instrumented module code. + match sandbox::Instance::new(&exec.prefab_module.code, &imports, &mut runtime) { + // No errors or traps were generated on instantiation! That + // means we can now invoke the contract entrypoint. + Ok(mut instance) => { + let err = instance + .invoke(exec.entrypoint_name, &[], &mut runtime) + .err(); + to_execution_result(runtime, err) + } + // `start` function trapped. Treat it in the same manner as an execution error. + Err(err @ sandbox::Error::Execution) => to_execution_result(runtime, Some(err)), + Err(_err @ sandbox::Error::Module) => { + // `Error::Module` is returned only if instantiation or linking failed (i.e. + // wasm bianry tried to import a function that is not provided by the host). + // This shouldn't happen because validation proccess ought to reject such binaries. + // + // Because panics are really undesirable in the runtime code, we treat this as + // a trap for now. Eventually, we might want to revisit this. + return VmExecResult::Trap("validation error"); + } + // Other instantiation errors. + // Return without executing anything. + Err(_) => return VmExecResult::Trap("during start function"), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::collections::HashMap; + use substrate_primitives::H256; + use exec::{CallReceipt, Ext, InstantiateReceipt, EmptyOutputBuf}; + use balances; + use gas::GasMeter; + use tests::{Test, Call}; + use wabt; + use wasm::prepare::prepare_contract; + use CodeHash; + + #[derive(Debug, PartialEq, Eq)] + struct DispatchEntry(Call); + #[derive(Debug, PartialEq, Eq)] + struct CreateEntry { + code_hash: H256, + endowment: u64, + data: Vec, + gas_left: u64, + } + #[derive(Debug, PartialEq, Eq)] + struct TransferEntry { + to: u64, + value: u64, + data: Vec, + gas_left: u64, + } + #[derive(Default)] + pub struct MockExt { + storage: HashMap, Vec>, + creates: Vec, + transfers: Vec, + dispatches: Vec, + next_account_id: u64, + } + impl Ext for MockExt { + type T = Test; + + fn get_storage(&self, key: &[u8]) -> Option> { + self.storage.get(key).cloned() + } + fn set_storage(&mut self, key: &[u8], value: Option>) { + *self.storage.entry(key.to_vec()).or_insert(Vec::new()) = value.unwrap_or(Vec::new()); + } + fn instantiate( + &mut self, + code_hash: &CodeHash, + endowment: u64, + gas_meter: &mut GasMeter, + data: &[u8], + ) -> Result, &'static str> { + self.creates.push(CreateEntry { + code_hash: code_hash.clone(), + endowment, + data: data.to_vec(), + gas_left: gas_meter.gas_left(), + }); + let address = self.next_account_id; + self.next_account_id += 1; + + Ok(InstantiateReceipt { address }) + } + fn call( + &mut self, + to: &u64, + value: u64, + gas_meter: &mut GasMeter, + data: &[u8], + _output_data: EmptyOutputBuf, + ) -> Result { + self.transfers.push(TransferEntry { + to: *to, + value, + data: data.to_vec(), + gas_left: gas_meter.gas_left(), + }); + // Assume for now that it was just a plain transfer. + // TODO: Add tests for different call outcomes. + Ok(CallReceipt { + output_data: Vec::new(), + }) + } + fn note_dispatch_call(&mut self, call: Call) { + self.dispatches.push(DispatchEntry(call)); + } + fn caller(&self) -> &u64 { + &42 + } + fn address(&self) -> &u64 { + &69 + } + fn balance(&self) -> u64 { + 228 + } + fn value_transferred(&self) -> u64 { + 1337 + } + } + + fn execute( + wat: &str, + input_data: &[u8], + output_data: &mut Vec, + ext: &mut E, + gas_meter: &mut GasMeter, + ) -> Result<(), &'static str> { + use exec::Vm; + + let wasm = wabt::wat2wasm(wat).unwrap(); + let schedule = ::Schedule::::default(); + let prefab_module = + prepare_contract::(&wasm, &schedule).unwrap(); + + let exec = WasmExecutable { + // Use a "call" convention. + entrypoint_name: b"call", + prefab_module, + }; + + let cfg = Default::default(); + let vm = WasmVm::new(&cfg); + + *output_data = vm + .execute(&exec, ext, input_data, EmptyOutputBuf::new(), gas_meter) + .into_result()?; + + Ok(()) + } + + const CODE_TRANSFER: &str = r#" +(module + ;; ext_call( + ;; callee_ptr: u32, + ;; callee_len: u32, + ;; gas: u64, + ;; value_ptr: u32, + ;; value_len: u32, + ;; input_data_ptr: u32, + ;; input_data_len: u32 + ;;) -> u32 + (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + (func (export "call") + (drop + (call $ext_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. + (i32.const 12) ;; 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.const 4) ;; Length of input data buffer + ) + ) + ) + (func (export "deploy")) + + ;; Destination AccountId to transfer the funds. + ;; Represented by u64 (8 bytes long) in little endian. + (data (i32.const 4) "\09\00\00\00\00\00\00\00") + ;; Amount of value to transfer. + ;; Represented by u64 (8 bytes long) in little endian. + (data (i32.const 12) "\06\00\00\00\00\00\00\00") + + (data (i32.const 20) "\01\02\03\04") +) +"#; + + #[test] + fn contract_transfer() { + let mut mock_ext = MockExt::default(); + execute( + CODE_TRANSFER, + &[], + &mut Vec::new(), + &mut mock_ext, + &mut GasMeter::with_limit(50_000, 1), + ) + .unwrap(); + + assert_eq!( + &mock_ext.transfers, + &[TransferEntry { + to: 9, + value: 6, + data: vec![1, 2, 3, 4], + gas_left: 49970, + }] + ); + } + + const CODE_CREATE: &str = r#" +(module + ;; ext_create( + ;; code_ptr: u32, + ;; code_len: u32, + ;; gas: u64, + ;; value_ptr: u32, + ;; value_len: u32, + ;; input_data_ptr: u32, + ;; input_data_len: u32, + ;; ) -> u32 + (import "env" "ext_create" (func $ext_create (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + (func (export "call") + (drop + (call $ext_create + (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. + (i32.const 4) ;; Pointer to the buffer with value to transfer + (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 + ) + ) + ) + (func (export "deploy")) + + ;; Amount of value to transfer. + ;; Represented by u64 (8 bytes long) in little endian. + (data (i32.const 4) "\03\00\00\00\00\00\00\00") + ;; Input data to pass to the contract being created. + (data (i32.const 12) "\01\02\03\04") + ;; Hash of code. + (data (i32.const 16) "\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 contract_create() { + let mut mock_ext = MockExt::default(); + execute( + CODE_CREATE, + &[], + &mut Vec::new(), + &mut mock_ext, + &mut GasMeter::with_limit(50_000, 1), + ) + .unwrap(); + + assert_eq!( + &mock_ext.creates, + &[CreateEntry { + code_hash: [0x11; 32].into(), + endowment: 3, + data: vec![1, 2, 3, 4], + gas_left: 49946, + }] + ); + } + + const CODE_TRANSFER_LIMITED_GAS: &str = r#" +(module + ;; ext_call( + ;; callee_ptr: u32, + ;; callee_len: u32, + ;; gas: u64, + ;; value_ptr: u32, + ;; value_len: u32, + ;; input_data_ptr: u32, + ;; input_data_len: u32 + ;;) -> u32 + (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + (func (export "call") + (drop + (call $ext_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. + (i32.const 12) ;; 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.const 4) ;; Length of input data buffer + ) + ) + ) + (func (export "deploy")) + + ;; Destination AccountId to transfer the funds. + ;; Represented by u64 (8 bytes long) in little endian. + (data (i32.const 4) "\09\00\00\00\00\00\00\00") + ;; Amount of value to transfer. + ;; Represented by u64 (8 bytes long) in little endian. + (data (i32.const 12) "\06\00\00\00\00\00\00\00") + + (data (i32.const 20) "\01\02\03\04") +) +"#; + + #[test] + fn contract_call_limited_gas() { + let mut mock_ext = MockExt::default(); + execute( + &CODE_TRANSFER_LIMITED_GAS, + &[], + &mut Vec::new(), + &mut mock_ext, + &mut GasMeter::with_limit(50_000, 1), + ) + .unwrap(); + + assert_eq!( + &mock_ext.transfers, + &[TransferEntry { + to: 9, + value: 6, + data: vec![1, 2, 3, 4], + gas_left: 228, + }] + ); + } + + 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_copy" (func $ext_scratch_copy (param i32 i32 i32))) + (import "env" "ext_return" (func $ext_return (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "call") + (local $buf_size i32) + + + ;; Load a storage value into the scratch buf. + (call $assert + (i32.eq + (call $ext_get_storage + (i32.const 4) ;; The pointer to the storage key to fetch + ) + + ;; Return value 0 means that the value is found and there were + ;; no errors. + (i32.const 0) + ) + ) + + ;; 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_copy + (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 + ) + ) + + ;; Return the contents of the buffer + (call $ext_return + (i32.const 36) + (get_local $buf_size) + ) + + ;; env:ext_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() { + let mut mock_ext = MockExt::default(); + mock_ext + .storage + .insert([0x11; 32].to_vec(), [0x22; 32].to_vec()); + + let mut return_buf = Vec::new(); + execute( + CODE_GET_STORAGE, + &[], + &mut return_buf, + &mut mock_ext, + &mut GasMeter::with_limit(50_000, 1), + ) + .unwrap(); + + assert_eq!(return_buf, [0x22; 32].to_vec()); + } + + /// calls `ext_caller`, loads the address from the scratch buffer and + /// compares it with the constant 42. + const CODE_CALLER: &'static 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_copy" (func $ext_scratch_copy (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") + ;; fill the scratch buffer with the caller. + (call $ext_caller) + + ;; 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_copy + (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.const 42) + ) + ) + ) + + (func (export "deploy")) +) +"#; + + #[test] + fn caller() { + let mut mock_ext = MockExt::default(); + execute( + CODE_CALLER, + &[], + &mut Vec::new(), + &mut mock_ext, + &mut GasMeter::with_limit(50_000, 1), + ) + .unwrap(); + } + + /// calls `ext_address`, loads the address from the scratch buffer and + /// compares it with the constant 69. + const CODE_ADDRESS: &'static 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_copy" (func $ext_scratch_copy (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") + ;; fill the scratch buffer with the self address. + (call $ext_address) + + ;; 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_copy + (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.const 69) + ) + ) + ) + + (func (export "deploy")) +) +"#; + + #[test] + fn address() { + let mut mock_ext = MockExt::default(); + execute( + CODE_ADDRESS, + &[], + &mut Vec::new(), + &mut mock_ext, + &mut GasMeter::with_limit(50_000, 1), + ) + .unwrap(); + } + + 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_copy" (func $ext_scratch_copy (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") + ;; This stores the balance in the scratch buffer + (call $ext_balance) + + ;; 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_copy + (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.const 228) + ) + ) + ) + (func (export "deploy")) +) +"#; + + #[test] + fn balance() { + let mut mock_ext = MockExt::default(); + let mut gas_meter = GasMeter::with_limit(50_000, 1); + execute( + CODE_BALANCE, + &[], + &mut Vec::new(), + &mut mock_ext, + &mut gas_meter, + ) + .unwrap(); + } + + 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_copy" (func $ext_scratch_copy (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") + ;; This stores the gas price in the scratch buffer + (call $ext_gas_price) + + ;; 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_copy + (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. + (call $assert + (i64.eq + (i64.load + (i32.const 8) + ) + (i64.const 1312) + ) + ) + ) + (func (export "deploy")) +) +"#; + + #[test] + fn gas_price() { + let mut mock_ext = MockExt::default(); + let mut gas_meter = GasMeter::with_limit(50_000, 1312); + execute( + CODE_GAS_PRICE, + &[], + &mut Vec::new(), + &mut mock_ext, + &mut gas_meter, + ) + .unwrap(); + } + + 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_copy" (func $ext_scratch_copy (param i32 i32 i32))) + (import "env" "ext_return" (func $ext_return (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "call") + ;; This stores the gas left in the scratch buffer + (call $ext_gas_left) + + ;; 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_copy + (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) + ) + + (unreachable) + ) + (func (export "deploy")) +) +"#; + + #[test] + fn gas_left() { + let mut mock_ext = MockExt::default(); + let mut gas_meter = GasMeter::with_limit(50_000, 1312); + execute( + CODE_GAS_LEFT, + &[], + &mut Vec::new(), + &mut mock_ext, + &mut gas_meter, + ) + .unwrap(); + } + + 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_copy" (func $ext_scratch_copy (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") + ;; This stores the value transferred in the scratch buffer + (call $ext_value_transferred) + + ;; 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_copy + (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.const 1337) + ) + ) + ) + (func (export "deploy")) +) +"#; + + #[test] + fn value_transferred() { + let mut mock_ext = MockExt::default(); + let mut gas_meter = GasMeter::with_limit(50_000, 1); + execute( + CODE_VALUE_TRANSFERRED, + &[], + &mut Vec::new(), + &mut mock_ext, + &mut gas_meter, + ) + .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(); + execute( + CODE_DISPATCH_CALL, + &[], + &mut Vec::new(), + &mut mock_ext, + &mut GasMeter::with_limit(50_000, 1), + ) + .unwrap(); + + assert_eq!( + &mock_ext.dispatches, + &[DispatchEntry( + Call::Balances(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 "env" "memory" (memory 1 1)) + + (start $start) + (func $start + (call $ext_return + (i32.const 8) + (i32.const 4) + ) + (unreachable) + ) + + (func (export "call") + (unreachable) + ) + (func (export "deploy")) + + (data (i32.const 8) "\01\02\03\04") +) +"#; + + + #[test] + fn return_from_start_fn() { + let mut mock_ext = MockExt::default(); + let mut output_data = Vec::new(); + execute( + CODE_RETURN_FROM_START_FN, + &[], + &mut output_data, + &mut mock_ext, + &mut GasMeter::with_limit(50_000, 1), + ) + .unwrap(); + + assert_eq!(output_data, vec![1, 2, 3, 4]); + } +} diff --git a/srml/contract/src/wasm/prepare.rs b/srml/contract/src/wasm/prepare.rs new file mode 100644 index 0000000000000000000000000000000000000000..9d401a6a7c2cd71dfb964c7063df81d2a86a52bf --- /dev/null +++ b/srml/contract/src/wasm/prepare.rs @@ -0,0 +1,584 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 takes care of loading, checking and preprocessing of a +//! wasm module before execution. It also extracts some essential information +//! from a module. + +use parity_wasm::elements::{self, Internal, External, MemoryType, Type}; +use pwasm_utils; +use pwasm_utils::rules; +use rstd::prelude::*; +use runtime_primitives::traits::As; +use wasm::env_def::ImportSatisfyCheck; +use wasm::PrefabWasmModule; +use {Schedule, Trait}; + +struct ContractModule<'a, Gas: 'a> { + // An `Option` is used here for loaning (`take()`-ing) the module. + // Invariant: Can't be `None` (i.e. on enter and on exit from the function + // the value *must* be `Some`). + module: Option, + schedule: &'a Schedule, +} + +impl<'a, Gas: 'a + As + Clone> ContractModule<'a, Gas> { + fn new( + original_code: &[u8], + schedule: &'a Schedule, + ) -> Result, &'static str> { + let module = + elements::deserialize_buffer(original_code).map_err(|_| "can't decode wasm code")?; + Ok(ContractModule { + module: Some(module), + schedule, + }) + } + + /// Ensures that module doesn't declare internal memories. + /// + /// In this runtime we only allow wasm module to import memory from the environment. + /// Memory section contains declarations of internal linear memories, so if we find one + /// we reject such a module. + fn ensure_no_internal_memory(&self) -> Result<(), &'static str> { + let module = self + .module + .as_ref() + .expect("On entry to the function `module` can't be None; qed"); + if module + .memory_section() + .map_or(false, |ms| ms.entries().len() > 0) + { + return Err("module declares internal memory"); + } + Ok(()) + } + + fn inject_gas_metering(&mut self) -> Result<(), &'static str> { + let gas_rules = + rules::Set::new( + self.schedule.regular_op_cost.clone().as_(), + Default::default(), + ) + .with_grow_cost(self.schedule.grow_mem_cost.clone().as_()) + .with_forbidden_floats(); + + let module = self + .module + .take() + .expect("On entry to the function `module` can't be `None`; qed"); + + let contract_module = pwasm_utils::inject_gas_counter(module, &gas_rules) + .map_err(|_| "gas instrumentation failed")?; + + self.module = Some(contract_module); + Ok(()) + } + + fn inject_stack_height_metering(&mut self) -> Result<(), &'static str> { + let module = self + .module + .take() + .expect("On entry to the function `module` can't be `None`; qed"); + + let contract_module = + pwasm_utils::stack_height::inject_limiter(module, self.schedule.max_stack_height) + .map_err(|_| "stack height instrumentation failed")?; + + self.module = Some(contract_module); + Ok(()) + } + + /// Check that the module has required exported functions. For now + /// these are just entrypoints: + /// + /// - 'call' + /// - 'deploy' + fn scan_exports(&self) -> Result<(), &'static str> { + let mut deploy_found = false; + let mut call_found = false; + + let module = self + .module + .as_ref() + .expect("On entry to the function `module` can't be `None`; qed"); + + let types = module.type_section().map(|ts| ts.types()).unwrap_or(&[]); + let export_entries = module + .export_section() + .map(|is| is.entries()) + .unwrap_or(&[]); + let func_entries = module + .function_section() + .map(|fs| fs.entries()) + .unwrap_or(&[]); + + // Function index space consists of imported function following by + // declared functions. Calculate the total number of imported functions so + // we can use it to convert indexes from function space to declared function space. + let fn_space_offset = module + .import_section() + .map(|is| is.entries()) + .unwrap_or(&[]) + .iter() + .filter(|entry| { + match *entry.external() { + External::Function(_) => true, + _ => false, + } + }) + .count(); + + for export in export_entries { + match export.field() { + "call" => call_found = true, + "deploy" => deploy_found = true, + _ => continue, + } + + // Then check the export kind. "call" and "deploy" are + // functions. + let fn_idx = match export.internal() { + Internal::Function(ref fn_idx) => *fn_idx, + _ => return Err("expected a function"), + }; + + // convert index from function index space to declared index space. + let fn_idx = match fn_idx.checked_sub(fn_space_offset as u32) { + Some(fn_idx) => fn_idx, + None => { + // Underflow here means fn_idx points to imported function which we don't allow! + return Err("entry point points to an imported function"); + } + }; + + // Then check the signature. + // 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(); + let Type::Function(ref func_ty) = types + .get(func_ty_idx as usize) + .ok_or_else(|| "function has a non-existent type")?; + if !(func_ty.params().is_empty() && func_ty.return_type().is_none()) { + return Err("entry point has wrong signature"); + } + } + + if !deploy_found { + return Err("deploy function isn't exported"); + } + if !call_found { + return Err("call function isn't exported"); + } + + Ok(()) + } + + /// Scan an import section if any. + /// + /// This accomplishes two tasks: + /// + /// - checks any imported function against defined host functions set, incl. + /// their signatures. + /// - if there is a memory import, returns it's descriptor + fn scan_imports(&self) -> Result, &'static str> { + let module = self + .module + .as_ref() + .expect("On entry to the function `module` can't be `None`; qed"); + + let types = module.type_section().map(|ts| ts.types()).unwrap_or(&[]); + let import_entries = module + .import_section() + .map(|is| is.entries()) + .unwrap_or(&[]); + + 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::Function(ref type_idx) => type_idx, + &External::Memory(ref memory_type) => { + imported_mem_type = Some(memory_type); + continue; + } + _ => continue, + }; + + let Type::Function(ref func_ty) = types + .get(*type_idx as usize) + .ok_or_else(|| "validation: import entry points to a non-existent type")?; + + // We disallow importing `gas` function here since it is treated as implementation detail. + if import.field().as_bytes() == b"gas" + || !C::can_satisfy(import.field().as_bytes(), func_ty) + { + return Err("module imports a non-existent function"); + } + } + Ok(imported_mem_type) + } + + fn into_wasm_code(mut self) -> Result, &'static str> { + elements::serialize( + self.module + .take() + .expect("On entry to the function `module` can't be `None`; qed"), + ) + .map_err(|_| "error serializing instrumented module") + } +} + +/// Loads the given module given in `original_code`, performs some checks on it and +/// does some preprocessing. +/// +/// The checks are: +/// +/// - module doesn't define an internal memory instance, +/// - imported memory (if any) doesn't reserve more memory than permitted by the `schedule`, +/// - all imported functions from the external environment matches defined by `env` module, +/// +/// The preprocessing includes injecting code for gas metering and metering the height of stack. +pub fn prepare_contract( + original_code: &[u8], + schedule: &Schedule, +) -> Result { + let mut contract_module = ContractModule::new(original_code, schedule)?; + contract_module.scan_exports()?; + contract_module.ensure_no_internal_memory()?; + + struct MemoryDefinition { + initial: u32, + maximum: u32, + } + + let memory_def = if let Some(memory_type) = contract_module.scan_imports::()? { + // Inspect the module to extract the initial and maximum page count. + let limits = memory_type.limits(); + match (limits.initial(), limits.maximum()) { + (initial, Some(maximum)) if initial > maximum => { + return Err( + "Requested initial number of pages should not exceed the requested maximum", + ); + } + (_, Some(maximum)) if maximum > schedule.max_memory_pages => { + return Err("Maximum number of pages should not exceed the configured maximum."); + } + (initial, Some(maximum)) => MemoryDefinition { initial, maximum }, + (_, None) => { + // Maximum number of pages should be always declared. + // This isn't a hard requirement and can be treated as a maxiumum set + // to configured maximum. + return Err("Maximum number of pages should be always declared."); + } + } + } else { + // If none memory imported then just crate an empty placeholder. + // Any access to it will lead to out of bounds trap. + MemoryDefinition { + initial: 0, + maximum: 0, + } + }; + + contract_module.inject_gas_metering()?; + contract_module.inject_stack_height_metering()?; + + Ok(PrefabWasmModule { + schedule_version: schedule.version, + initial: memory_def.initial, + maximum: memory_def.maximum, + _reserved: None, + code: contract_module.into_wasm_code()?, + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::fmt; + use tests::Test; + use exec::Ext; + use wabt; + + impl fmt::Debug for PrefabWasmModule { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "PreparedContract {{ .. }}") + } + } + + // Define test environment for tests. We need ImportSatisfyCheck + // implementation from it. So actual implementations doesn't matter. + define_env!(TestEnv, , + panic(_ctx) => { unreachable!(); }, + + // gas is an implementation defined function and a contract can't import it. + gas(_ctx, _amount: u32) => { unreachable!(); }, + + nop(_ctx, _unused: u64) => { 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 schedule = Schedule::::default(); + let r = prepare_contract::(wasm.as_ref(), &schedule); + assert_matches!(r, $($expected)*); + } + }; + } + + prepare_test!(no_floats, + r#" + (module + (func (export "call") + (drop + (f32.add + (f32.const 0) + (f32.const 1) + ) + ) + ) + (func (export "deploy")) + )"#, + Err("gas instrumentation failed") + ); + + mod memories { + use super::*; + + // Tests below assumes that maximum page number is configured to a certain number. + #[test] + fn assume_memory_size() { + assert_eq!(Schedule::::default().max_memory_pages, 16); + } + + prepare_test!(memory_with_one_page, + r#" + (module + (import "env" "memory" (memory 1 1)) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Ok(_) + ); + + prepare_test!(internal_memory_declaration, + r#" + (module + (memory 1 1) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("module declares internal memory") + ); + + prepare_test!(no_memory_import, + r#" + (module + ;; no memory imported + + (func (export "call")) + (func (export "deploy")) + )"#, + Ok(_) + ); + + prepare_test!(initial_exceeds_maximum, + r#" + (module + (import "env" "memory" (memory 16 1)) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("Requested initial number of pages should not exceed the requested maximum") + ); + + prepare_test!(no_maximum, + r#" + (module + (import "env" "memory" (memory 1)) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("Maximum number of pages should be always declared.") + ); + + prepare_test!(requested_maximum_exceeds_configured_maximum, + r#" + (module + (import "env" "memory" (memory 1 17)) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("Maximum number of pages should not exceed the configured maximum.") + ); + } + + mod imports { + use super::*; + + prepare_test!(can_import_legit_function, + r#" + (module + (import "env" "nop" (func (param i64))) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Ok(_) + ); + + // even though gas is defined the contract can't import it since + // it is an implementation defined. + prepare_test!(can_not_import_gas_function, + r#" + (module + (import "env" "gas" (func (param i32))) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("module imports a non-existent function") + ); + + // nothing can be imported from non-"env" module for now. + prepare_test!(non_env_import, + r#" + (module + (import "another_module" "memory" (memory 1 1)) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("module has imports from a non-'env' namespace") + ); + + // wrong signature + prepare_test!(wrong_signature, + r#" + (module + (import "env" "gas" (func (param i64))) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("module imports a non-existent function") + ); + + prepare_test!(unknown_func_name, + r#" + (module + (import "env" "unknown_func" (func)) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("module imports a non-existent function") + ); + } + + mod entrypoints { + use super::*; + + prepare_test!(it_works, + r#" + (module + (func (export "call")) + (func (export "deploy")) + ) + "#, + Ok(_) + ); + + prepare_test!(omit_deploy, + r#" + (module + (func (export "call")) + ) + "#, + Err("deploy function isn't exported") + ); + + prepare_test!(omit_call, + r#" + (module + (func (export "deploy")) + ) + "#, + Err("call function isn't exported") + ); + + // Try to use imported function as an entry point. + prepare_test!(try_sneak_export_as_entrypoint, + r#" + (module + (import "env" "panic" (func)) + + (func (export "deploy")) + + (export "call" (func 0)) + ) + "#, + Err("entry point points to an imported function") + ); + + // Try to use imported function as an entry point. + prepare_test!(try_sneak_export_as_global, + r#" + (module + (func (export "deploy")) + (global (export "call") i32 (i32.const 0)) + ) + "#, + Err("expected a function") + ); + + prepare_test!(wrong_signature, + r#" + (module + (func (export "deploy")) + (func (export "call") (param i32)) + ) + "#, + Err("entry point has wrong signature") + ); + } +} diff --git a/srml/contract/src/vm/runtime.rs b/srml/contract/src/wasm/runtime.rs similarity index 60% rename from srml/contract/src/vm/runtime.rs rename to srml/contract/src/wasm/runtime.rs index 3bdc9bf12ad3e17b4274dc3a2160452c096f571a..ce1bf89baac522ac57101cf039b361cc5c6ef79a 100644 --- a/srml/contract/src/vm/runtime.rs +++ b/srml/contract/src/wasm/runtime.rs @@ -16,16 +16,16 @@ //! Environment definition of the wasm smart-contract runtime. -use super::{BalanceOf, Config, CreateReceipt, Error, Ext}; +use super::{Schedule}; +use exec::{Ext, BalanceOf, VmExecResult, OutputBuf, EmptyOutputBuf, CallReceipt, InstantiateReceipt}; use rstd::prelude::*; +use rstd::mem; use codec::{Decode, Encode}; -use gas::{GasMeter, GasMeterResult}; -use runtime_primitives::traits::{As, CheckedMul}; +use gas::{GasMeter, Token, GasMeterResult, approx_gas_for_balance}; +use runtime_primitives::traits::{As, CheckedMul, Bounded}; use sandbox; use system; -use Trait; - -type GasOf = <::T as Trait>::Gas; +use {Trait, CodeHash, ComputeDispatchFee}; /// Enumerates all possible *special* trap conditions. /// @@ -33,15 +33,18 @@ type GasOf = <::T as Trait>::Gas; /// to just terminate quickly in some cases. enum SpecialTrap { /// Signals that trap was generated in response to call `ext_return` host function. - Return, + Return(OutputBuf), } +/// Can only be used for one call. pub(crate) struct Runtime<'a, 'data, E: Ext + 'a> { ext: &'a mut E, input_data: &'data [u8], - output_data: &'data mut Vec, + // A VM can return a result only once and only by value. So + // we wrap output buffer to make it possible to take the buffer out. + empty_output_buf: Option, scratch_buf: Vec, - config: &'a Config, + schedule: &'a Schedule<::Gas>, memory: sandbox::Memory, gas_meter: &'a mut GasMeter, special_trap: Option, @@ -50,17 +53,17 @@ impl<'a, 'data, E: Ext + 'a> Runtime<'a, 'data, E> { pub(crate) fn new( ext: &'a mut E, input_data: &'data [u8], - output_data: &'data mut Vec, - config: &'a Config, + empty_output_buf: EmptyOutputBuf, + schedule: &'a Schedule<::Gas>, memory: sandbox::Memory, gas_meter: &'a mut GasMeter, ) -> Self { Runtime { ext, input_data, - output_data, + empty_output_buf: Some(empty_output_buf), scratch_buf: Vec::new(), - config, + schedule, memory, gas_meter, special_trap: None, @@ -75,30 +78,71 @@ impl<'a, 'data, E: Ext + 'a> Runtime<'a, 'data, E> { pub(crate) fn to_execution_result( runtime: Runtime, sandbox_err: Option, -) -> Result<(), Error> { +) -> VmExecResult { // Check the exact type of the error. It could be plain trap or // special runtime trap the we must recognize. match (sandbox_err, runtime.special_trap) { // No traps were generated. Proceed normally. - (None, None) => Ok(()), + (None, None) => VmExecResult::Ok, // Special case. The trap was the result of the execution `return` host function. - (Some(sandbox::Error::Execution), Some(SpecialTrap::Return)) => Ok(()), + (Some(sandbox::Error::Execution), Some(SpecialTrap::Return(buf))) => VmExecResult::Returned(buf), // Any other kind of a trap should result in a failure. - (Some(_), _) => Err(Error::Invoke), + (Some(_), _) => VmExecResult::Trap("during execution"), // Any other case (such as special trap flag without actual trap) signifies // a logic error. _ => unreachable!(), } } -/// Charge the specified amount of gas. +#[cfg_attr(test, derive(Debug, PartialEq, Eq))] +#[derive(Copy, Clone)] +pub enum RuntimeToken { + /// Explicit call to the `gas` function. Charge the gas meter + /// with the value provided. + Explicit(u32), + /// The given number of bytes is read from the sandbox memory. + ReadMemory(u32), + /// The given number of bytes is written to the sandbox memory. + WriteMemory(u32), + /// The given number of bytes is read from the sandbox memory and + /// is returned as the return data buffer of the call. + ReturnData(u32), + /// Dispatch fee calculated by `T::ComputeDispatchFee`. + ComputedDispatchFee(Gas), +} + +impl Token for RuntimeToken { + type Metadata = Schedule; + + fn calculate_amount(&self, metadata: &Schedule) -> T::Gas { + use self::RuntimeToken::*; + let value = match *self { + Explicit(amount) => Some(>::sa(amount)), + ReadMemory(byte_count) => metadata + .sandbox_data_read_cost + .checked_mul(&>::sa(byte_count)), + WriteMemory(byte_count) => metadata + .sandbox_data_write_cost + .checked_mul(&>::sa(byte_count)), + ReturnData(byte_count) => metadata + .return_data_per_byte_cost + .checked_mul(&>::sa(byte_count)), + ComputedDispatchFee(gas) => Some(gas), + }; + + value.unwrap_or_else(|| Bounded::max_value()) + } +} + +/// Charge the gas meter with the specified token. /// -/// Returns `Err` if there is not enough gas. -fn charge_gas( +/// Returns `Err(HostError)` if there is not enough gas. +fn charge_gas>( gas_meter: &mut GasMeter, - amount: T::Gas, + metadata: &Tok::Metadata, + token: Tok, ) -> Result<(), sandbox::HostError> { - match gas_meter.charge(amount) { + match gas_meter.charge(metadata, token) { GasMeterResult::Proceed => Ok(()), GasMeterResult::OutOfGas => Err(sandbox::HostError), } @@ -117,10 +161,7 @@ fn read_sandbox_memory( ptr: u32, len: u32, ) -> Result, sandbox::HostError> { - let price = (ctx.config.sandbox_data_read_cost) - .checked_mul(& as As>::sa(len)) - .ok_or(sandbox::HostError)?; - charge_gas(ctx.gas_meter, price)?; + charge_gas(ctx.gas_meter, ctx.schedule, RuntimeToken::ReadMemory(len))?; let mut buf = Vec::new(); buf.resize(len as usize, 0); @@ -139,16 +180,13 @@ fn read_sandbox_memory( /// - out of gas /// - designated area is not within the bounds of the sandbox memory. fn write_sandbox_memory( - per_byte_cost: T::Gas, + schedule: &Schedule, gas_meter: &mut GasMeter, memory: &sandbox::Memory, ptr: u32, buf: &[u8], ) -> Result<(), sandbox::HostError> { - let price = per_byte_cost - .checked_mul(&>::sa(buf.len() as u32)) - .ok_or(sandbox::HostError)?; - charge_gas(gas_meter, price)?; + charge_gas(gas_meter, schedule, RuntimeToken::WriteMemory(buf.len() as u32))?; memory.set(ptr, buf)?; @@ -163,15 +201,16 @@ fn write_sandbox_memory( // Define a function `fn init_env() -> HostFunctionSet` that returns // a function set which can be imported by an executed contract. -define_env!(init_env, , +define_env!(Env, , // Account for used gas. Traps if gas used is greater than gas limit. // + // NOTE: This is a implementation defined call and is NOT a part of the public API. + // This call is supposed to be called only by instrumentation injected code. + // // - amount: How much gas is used. gas(ctx, amount: u32) => { - let amount = <<::T as Trait>::Gas as As>::sa(amount); - charge_gas(&mut ctx.gas_meter, amount)?; - + charge_gas(&mut ctx.gas_meter, ctx.schedule, RuntimeToken::Explicit(amount))?; Ok(()) }, @@ -251,31 +290,44 @@ define_env!(init_env, , }; let input_data = read_sandbox_memory(ctx, input_data_ptr, input_data_len)?; - // Clear the scratch buffer in any case. - ctx.scratch_buf.clear(); + // Grab the scratch buffer and put in its' place an empty one. + // We will use it for creating `EmptyOutputBuf` container for the call. + let scratch_buf = mem::replace(&mut ctx.scratch_buf, Vec::new()); + let empty_output_buf = EmptyOutputBuf::from_spare_vec(scratch_buf); let nested_gas_limit = if gas == 0 { ctx.gas_meter.gas_left() } else { - <<::T as Trait>::Gas as As>::sa(gas) + <::Gas as As>::sa(gas) }; let ext = &mut ctx.ext; - let scratch_buf = &mut ctx.scratch_buf; let call_outcome = ctx.gas_meter.with_nested(nested_gas_limit, |nested_meter| { match nested_meter { - Some(nested_meter) => ext.call(&callee, value, nested_meter, &input_data, scratch_buf), + Some(nested_meter) => { + ext.call( + &callee, + value, + nested_meter, + &input_data, + empty_output_buf + ) + .map_err(|_| ()) + } // there is not enough gas to allocate for the nested call. None => Err(()), } }); match call_outcome { - Ok(()) => Ok(0), + Ok(CallReceipt { output_data }) => { + ctx.scratch_buf = output_data; + Ok(0) + }, Err(_) => Ok(1), } }, - // Create a contract with code returned by the specified initializer code. + // Instantiate a contract with code returned by the specified initializer code. // // This function creates an account and executes initializer code. After the execution, // the returned buffer is saved as the code of the created account. @@ -302,7 +354,10 @@ define_env!(init_env, , input_data_ptr: u32, input_data_len: u32 ) -> u32 => { - let init_code = read_sandbox_memory(ctx, init_code_ptr, init_code_len)?; + let code_hash = { + let code_hash_buf = read_sandbox_memory(ctx, init_code_ptr, init_code_len)?; + ::T>>::decode(&mut &code_hash_buf[..]).ok_or_else(|| sandbox::HostError)? + }; let value = { let value_buf = read_sandbox_memory(ctx, value_ptr, value_len)?; BalanceOf::<::T>::decode(&mut &value_buf[..]) @@ -316,18 +371,26 @@ define_env!(init_env, , let nested_gas_limit = if gas == 0 { ctx.gas_meter.gas_left() } else { - <<::T as Trait>::Gas as As>::sa(gas) + <::Gas as As>::sa(gas) }; let ext = &mut ctx.ext; - let create_outcome = ctx.gas_meter.with_nested(nested_gas_limit, |nested_meter| { + let instantiate_outcome = ctx.gas_meter.with_nested(nested_gas_limit, |nested_meter| { match nested_meter { - Some(nested_meter) => ext.create(&init_code, value, nested_meter, &input_data), + Some(nested_meter) => { + ext.instantiate( + &code_hash, + value, + nested_meter, + &input_data + ) + .map_err(|_| ()) + } // there is not enough gas to allocate for the nested call. None => Err(()), } }); - match create_outcome { - Ok(CreateReceipt { address }) => { + match instantiate_outcome { + Ok(InstantiateReceipt { address }) => { // Write the address to the scratch buffer. address.encode_to(&mut ctx.scratch_buf); Ok(0) @@ -339,20 +402,34 @@ define_env!(init_env, , // Save a data buffer as a result of the execution, terminate the execution and return a // successful result to the caller. ext_return(ctx, data_ptr: u32, data_len: u32) => { - let data_len_in_gas = <<::T as Trait>::Gas as As>::sa(data_len as u64); - let price = (ctx.config.return_data_per_byte_cost) - .checked_mul(&data_len_in_gas) - .ok_or(sandbox::HostError)?; - - match ctx.gas_meter.charge(price) { + match ctx + .gas_meter + .charge( + ctx.schedule, + RuntimeToken::ReturnData(data_len) + ) + { GasMeterResult::Proceed => (), GasMeterResult::OutOfGas => return Err(sandbox::HostError), } - ctx.output_data.resize(data_len as usize, 0); - ctx.memory.get(data_ptr, &mut ctx.output_data)?; - - ctx.special_trap = Some(SpecialTrap::Return); + let empty_output_buf = ctx + .empty_output_buf + .take() + .expect( + "`empty_output_buf` is taken only here; + `ext_return` traps; + `Runtime` can only be used only for one execution; + qed" + ); + let output_buf = empty_output_buf.fill( + data_len as usize, + |slice_mut| { + // Read the memory at the specified pointer to the provided slice. + ctx.memory.get(data_ptr, slice_mut) + } + )?; + ctx.special_trap = Some(SpecialTrap::Return(output_buf)); // The trap mechanism is used to immediately terminate the execution. // This trap should be handled appropriately before returning the result @@ -360,6 +437,78 @@ define_env!(init_env, , Err(sandbox::HostError) }, + // Stores the address of the caller into the scratch buffer. + // + // 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 = ctx.ext.caller().encode(); + Ok(()) + }, + + // Stores the address of the current contract into the scratch buffer. + ext_address(ctx) => { + ctx.scratch_buf = ctx.ext.address().encode(); + Ok(()) + }, + + // Stores the gas price for the current transaction into the scratch buffer. + // + // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. + ext_gas_price(ctx) => { + ctx.scratch_buf = ctx.gas_meter.gas_price().encode(); + Ok(()) + }, + + // Stores the amount of gas left into the scratch buffer. + // + // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. + ext_gas_left(ctx) => { + ctx.scratch_buf = ctx.gas_meter.gas_left().encode(); + Ok(()) + }, + + // Stores the balance of the current account into the scratch buffer. + // + // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. + ext_balance(ctx) => { + ctx.scratch_buf = ctx.ext.balance().encode(); + Ok(()) + }, + + // Stores the value transferred along with this call or as endowment into the scratch buffer. + // + // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. + ext_value_transferred(ctx) => { + ctx.scratch_buf = ctx.ext.value_transferred().encode(); + Ok(()) + }, + + // Decodes the given buffer as a `T::Call` and adds it to the list + // of to-be-dispatched calls. + // + // 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 = { + let call_buf = read_sandbox_memory(ctx, call_ptr, call_len)?; + <<::T as Trait>::Call>::decode(&mut &call_buf[..]) + .ok_or_else(|| sandbox::HostError)? + }; + + // Charge gas for dispatching this call. + let fee = { + let balance_fee = <::T as Trait>::ComputeDispatchFee::compute_dispatch_fee(&call); + approx_gas_for_balance::<::T>(ctx.gas_meter.gas_price(), balance_fee) + }; + charge_gas(&mut ctx.gas_meter, ctx.schedule, RuntimeToken::ComputedDispatchFee(fee))?; + + ctx.ext.note_dispatch_call(call); + + Ok(()) + }, + // Returns the size of the input buffer. ext_input_size(ctx) -> u32 => { Ok(ctx.input_data.len() as u32) @@ -382,7 +531,7 @@ define_env!(init_env, , // Finally, perform the write. write_sandbox_memory( - ctx.config.sandbox_data_write_cost, + ctx.schedule, ctx.gas_meter, &ctx.memory, dest_ptr, @@ -414,7 +563,7 @@ define_env!(init_env, , // Finally, perform the write. write_sandbox_memory( - ctx.config.sandbox_data_write_cost, + ctx.schedule, ctx.gas_meter, &ctx.memory, dest_ptr, diff --git a/srml/council/Cargo.toml b/srml/council/Cargo.toml index 39cd73e96c105014797b5988b1c0099f19758444..32fc9c79750fd8b2a84989abf1b67e861bf48a14 100644 --- a/srml/council/Cargo.toml +++ b/srml/council/Cargo.toml @@ -6,9 +6,8 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } safe-mix = { version = "1.0", default-features = false} -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } @@ -23,7 +22,6 @@ srml-system = { path = "../system", default-features = false } default = ["std"] std = [ "serde/std", - "serde_derive", "safe-mix/std", "parity-codec/std", "parity-codec-derive/std", diff --git a/srml/council/src/lib.rs b/srml/council/src/lib.rs index 412de7d2b25b3200aa1a6b674a22293d55bcc275..60320c0738dc1818448781348689597f5458e7aa 100644 --- a/srml/council/src/lib.rs +++ b/srml/council/src/lib.rs @@ -21,10 +21,6 @@ #[cfg(feature = "std")] extern crate serde; -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - #[cfg(test)] #[macro_use] extern crate hex_literal; @@ -54,7 +50,7 @@ mod tests { pub use runtime_io::with_externalities; pub use substrate_primitives::H256; pub use primitives::BuildStorage; - pub use primitives::traits::{BlakeTwo256}; + pub use primitives::traits::{BlakeTwo256, IdentityLookup}; pub use primitives::testing::{Digest, DigestItem, Header}; pub use substrate_primitives::{Blake2Hasher}; pub use {seats, motions, voting}; @@ -79,7 +75,7 @@ mod tests { } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] + #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; impl system::Trait for Test { type Origin = Origin; @@ -89,14 +85,15 @@ mod tests { type Hashing = BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = Event; type Log = DigestItem; } impl balances::Trait for Test { type Balance = u64; - type AccountIndex = u64; type OnFreeBalanceZero = (); + type OnNewAccount = (); type EnsureAccountLiquid = (); type Event = Event; } @@ -125,12 +122,13 @@ mod tests { existential_deposit: 0, transfer_fee: 0, creation_fee: 0, - reclaim_rebate: 0, }.build_storage().unwrap().0); t.extend(democracy::GenesisConfig::{ launch_period: 1, voting_period: 3, minimum_deposit: 1, + public_delay: 0, + max_lock_periods: 6, }.build_storage().unwrap().0); t.extend(seats::GenesisConfig:: { candidacy_bond: 9, @@ -151,6 +149,7 @@ mod tests { t.extend(voting::GenesisConfig:: { cooloff_period: 2, voting_period: 1, + enact_delay_period: 0, }.build_storage().unwrap().0); runtime_io::TestExternalities::new(t) } diff --git a/srml/council/src/motions.rs b/srml/council/src/motions.rs index 2b3850369b1e7e557b67193152086d79cf1a2fc1..9cf5e171a544fc890ad6ecd7db9759ec5f453947 100644 --- a/srml/council/src/motions.rs +++ b/srml/council/src/motions.rs @@ -18,10 +18,9 @@ use rstd::prelude::*; use rstd::result; -use codec::Compact; use substrate_primitives::u32_trait::Value as U32; -use primitives::traits::{Hash, EnsureOrigin, MaybeSerializeDebug}; -use srml_support::dispatch::{Result, Dispatchable, Parameter}; +use primitives::traits::{Hash, EnsureOrigin}; +use srml_support::dispatch::{Dispatchable, Parameter}; use srml_support::{StorageValue, StorageMap}; use super::{Trait as CouncilTrait, Module as Council}; use system::{self, ensure_signed}; @@ -29,12 +28,12 @@ use system::{self, ensure_signed}; /// Simple index type for proposal counting. pub type ProposalIndex = u32; -pub trait Trait: CouncilTrait + MaybeSerializeDebug { +pub trait Trait: CouncilTrait { /// The outer origin type. type Origin: From; /// The outer call dispatch type. - type Proposal: Parameter + Dispatchable::Origin> + MaybeSerializeDebug; + type Proposal: Parameter + Dispatchable::Origin>; /// The outer event type. type Event: From> + Into<::Event>; @@ -66,12 +65,10 @@ decl_event!( ); decl_module! { - #[cfg_attr(feature = "std", serde(bound(deserialize = "::Proposal: ::serde::de::DeserializeOwned")))] pub struct Module for enum Call where origin: ::Origin { - fn deposit_event() = default; - fn propose(origin, threshold: Compact, proposal: Box<::Proposal>) -> Result { + fn deposit_event() = default; + fn propose(origin, #[compact] threshold: u32, proposal: Box<::Proposal>) { let who = ensure_signed(origin)?; - let threshold = threshold.into(); ensure!(Self::is_councillor(&who), "proposer not on council"); @@ -91,12 +88,10 @@ decl_module! { Self::deposit_event(RawEvent::Proposed(who, index, proposal_hash, threshold)); } - Ok(()) } - fn vote(origin, proposal: T::Hash, index: Compact, approve: bool) -> Result { + fn vote(origin, proposal: T::Hash, #[compact] index: ProposalIndex, approve: bool) { let who = ensure_signed(origin)?; - let index = index.into(); ensure!(Self::is_councillor(&who), "voter not on council"); @@ -155,8 +150,6 @@ decl_module! { // update voting >::insert(&proposal, voting); } - - Ok(()) } } } @@ -173,7 +166,6 @@ decl_storage! { pub ProposalCount get(proposal_count): u32; } add_extra_genesis { - config(_marker): ::std::marker::PhantomData; build(|_, _, _| {}); } } @@ -225,7 +217,7 @@ mod tests { } fn set_balance_proposal(value: u64) -> Call { - Call::Balances(balances::Call::set_balance(balances::address::Address::Id(42), value.into(), 0.into())) + Call::Balances(balances::Call::set_balance(42, value.into(), 0)) } #[test] @@ -234,7 +226,7 @@ mod tests { System::set_block_number(1); let proposal = set_balance_proposal(42); let hash = proposal.blake2_256().into(); - assert_ok!(CouncilMotions::propose(Origin::signed(1), 3.into(), Box::new(proposal.clone()))); + assert_ok!(CouncilMotions::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); assert_eq!(CouncilMotions::proposals(), vec![hash]); assert_eq!(CouncilMotions::proposal_of(&hash), Some(proposal)); assert_eq!(CouncilMotions::voting(&hash), Some((0, 3, vec![1], Vec::::new()))); @@ -242,7 +234,7 @@ mod tests { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), 3)) + event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), 3)) } ]); }); @@ -253,7 +245,7 @@ mod tests { with_externalities(&mut new_test_ext(true), || { System::set_block_number(1); let proposal = set_balance_proposal(42); - assert_noop!(CouncilMotions::propose(Origin::signed(42), 3.into(), Box::new(proposal.clone())), "proposer not on council"); + assert_noop!(CouncilMotions::propose(Origin::signed(42), 3, Box::new(proposal.clone())), "proposer not on council"); }); } @@ -263,8 +255,8 @@ mod tests { System::set_block_number(1); let proposal = set_balance_proposal(42); let hash: H256 = proposal.blake2_256().into(); - assert_ok!(CouncilMotions::propose(Origin::signed(1), 3.into(), Box::new(proposal.clone()))); - assert_noop!(CouncilMotions::vote(Origin::signed(42), hash.clone(), 0.into(), true), "voter not on council"); + assert_ok!(CouncilMotions::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_noop!(CouncilMotions::vote(Origin::signed(42), hash.clone(), 0, true), "voter not on council"); }); } @@ -274,8 +266,8 @@ mod tests { System::set_block_number(3); let proposal = set_balance_proposal(42); let hash: H256 = proposal.blake2_256().into(); - assert_ok!(CouncilMotions::propose(Origin::signed(1), 3.into(), Box::new(proposal.clone()))); - assert_noop!(CouncilMotions::vote(Origin::signed(2), hash.clone(), 1.into(), true), "mismatched index"); + assert_ok!(CouncilMotions::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_noop!(CouncilMotions::vote(Origin::signed(2), hash.clone(), 1, true), "mismatched index"); }); } @@ -285,21 +277,21 @@ mod tests { System::set_block_number(1); let proposal = set_balance_proposal(42); let hash: H256 = proposal.blake2_256().into(); - assert_ok!(CouncilMotions::propose(Origin::signed(1), 2.into(), Box::new(proposal.clone()))); + assert_ok!(CouncilMotions::propose(Origin::signed(1), 2, Box::new(proposal.clone()))); assert_eq!(CouncilMotions::voting(&hash), Some((0, 2, vec![1], Vec::::new()))); - assert_noop!(CouncilMotions::vote(Origin::signed(1), hash.clone(), 0.into(), true), "duplicate vote ignored"); - assert_ok!(CouncilMotions::vote(Origin::signed(1), hash.clone(), 0.into(), false)); + assert_noop!(CouncilMotions::vote(Origin::signed(1), hash.clone(), 0, true), "duplicate vote ignored"); + assert_ok!(CouncilMotions::vote(Origin::signed(1), hash.clone(), 0, false)); assert_eq!(CouncilMotions::voting(&hash), Some((0, 2, Vec::::new(), vec![1]))); - assert_noop!(CouncilMotions::vote(Origin::signed(1), hash.clone(), 0.into(), false), "duplicate vote ignored"); + assert_noop!(CouncilMotions::vote(Origin::signed(1), hash.clone(), 0, false), "duplicate vote ignored"); assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), 2)) + event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), 2)) }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: OuterEvent::motions(RawEvent::Voted(1, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), false, 0, 1)) + event: OuterEvent::motions(RawEvent::Voted(1, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), false, 0, 1)) } ]); }); @@ -311,21 +303,21 @@ mod tests { System::set_block_number(1); let proposal = set_balance_proposal(42); let hash: H256 = proposal.blake2_256().into(); - assert_ok!(CouncilMotions::propose(Origin::signed(1), 3.into(), Box::new(proposal.clone()))); - assert_ok!(CouncilMotions::vote(Origin::signed(2), hash.clone(), 0.into(), false)); + assert_ok!(CouncilMotions::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(CouncilMotions::vote(Origin::signed(2), hash.clone(), 0, false)); assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), 3)) + event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), 3)) }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: OuterEvent::motions(RawEvent::Voted(2, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), false, 1, 1)) + event: OuterEvent::motions(RawEvent::Voted(2, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), false, 1, 1)) }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: OuterEvent::motions(RawEvent::Disapproved(hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into())) + event: OuterEvent::motions(RawEvent::Disapproved(hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into())) } ]); }); @@ -337,25 +329,25 @@ mod tests { System::set_block_number(1); let proposal = set_balance_proposal(42); let hash: H256 = proposal.blake2_256().into(); - assert_ok!(CouncilMotions::propose(Origin::signed(1), 2.into(), Box::new(proposal.clone()))); - assert_ok!(CouncilMotions::vote(Origin::signed(2), hash.clone(), 0.into(), true)); + assert_ok!(CouncilMotions::propose(Origin::signed(1), 2, Box::new(proposal.clone()))); + assert_ok!(CouncilMotions::vote(Origin::signed(2), hash.clone(), 0, true)); assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), 2)) + event: OuterEvent::motions(RawEvent::Proposed(1, 0, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), 2)) }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: OuterEvent::motions(RawEvent::Voted(2, hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), true, 2, 0)) + event: OuterEvent::motions(RawEvent::Voted(2, hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), true, 2, 0)) }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: OuterEvent::motions(RawEvent::Approved(hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into())) + event: OuterEvent::motions(RawEvent::Approved(hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into())) }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: OuterEvent::motions(RawEvent::Executed(hex!["35282aeb9f95795dc1be91b748cec2d210338f2c9c1a85d98e7a3619b6187d22"].into(), false)) + event: OuterEvent::motions(RawEvent::Executed(hex!["cd0b662a49f004093b80600415cf4126399af0d27ed6c185abeb1469c17eb5bf"].into(), false)) } ]); }); diff --git a/srml/council/src/seats.rs b/srml/council/src/seats.rs index 957b69bdfe0a8479d5aacfae03ff197185fe69a8..6f2adc9bc717827a4295e8ce2a45d1d4abc9d215 100644 --- a/srml/council/src/seats.rs +++ b/srml/council/src/seats.rs @@ -17,12 +17,11 @@ //! Council system: Handles the voting in and maintenance of council members. use rstd::prelude::*; -use codec::{Compact, HasCompact}; -use primitives::traits::{Zero, One, As}; +use primitives::traits::{Zero, One, As, StaticLookup}; use runtime_io::print; use srml_support::{StorageValue, StorageMap, dispatch::Result}; use democracy; -use balances::{self, address::Address}; +use balances; use system::{self, ensure_signed}; // no polynomial attacks: @@ -51,7 +50,7 @@ use system::{self, ensure_signed}; // to keep the system as stateless as possible (making it a bit easier to reason about), we just // restrict when votes can begin to blocks that lie on boundaries (`voting_period`). -// for an approval vote of C councilers: +// for an approval vote of C councillors: // top K runners-up are maintained between votes. all others are discarded. // - candidate removed & bond returned when elected. @@ -63,7 +62,7 @@ use system::{self, ensure_signed}; // they fall in the top K+C voted can present themselves. they get the total stake // recorded (based on the snapshot); an ordered list is maintained (the leaderboard). Noone may // present themselves that, if elected, would result in being included twice on the council -// (important since existing councilers will will have their approval votes as it may be that they +// (important since existing councillors will have their approval votes as it may be that they // don't get removed), nor if existing presenters would mean they're not in the top K+C. // following B blocks, the top C candidates are elected and have their bond returned. the top C @@ -72,7 +71,7 @@ use system::{self, ensure_signed}; // vote-clearing happens lazily; for an approval to count, the most recent vote at the time of the // voter's most recent vote must be no later than the most recent vote at the time that the // candidate in the approval position was registered there. as candidates are removed from the -// register and others join in their place, this prevent an approval meant for an earlier candidate +// register and others join in their place, this prevents an approval meant for an earlier candidate // being used to elect a new candidate. // the candidate list increases as needed, but the contents (though not really the capacity) reduce @@ -87,16 +86,22 @@ pub trait Trait: democracy::Trait { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Set candidate approvals. Approval slots stay valid as long as candidates in those slots /// are registered. - fn set_approvals(origin, votes: Vec, index: Compact) -> Result { + fn set_approvals(origin, votes: Vec, #[compact] index: VoteIndex) { let who = ensure_signed(origin)?; - let index: VoteIndex = index.into(); + let candidates = Self::candidates(); ensure!(!Self::presentation_active(), "no approval changes during presentation period"); ensure!(index == Self::vote_index(), "incorrect vote index"); + ensure!(!candidates.len().is_zero(), "amount of candidates to receive approval votes should be non-zero"); + // Prevent a vote from voters that provide a list of votes that exceeds the candidates length + // since otherise an attacker may be able to submit a very long list of `votes` that far exceeds + // the amount of candidates and waste more computation than a reasonable voting bond would cover. + ensure!(candidates.len() >= votes.len(), "amount of candidate approval votes cannot exceed amount of candidates"); + if !>::exists(&who) { // not yet a voter - deduct bond. // NOTE: this must be the last potential bailer, since it changes state. @@ -110,7 +115,6 @@ decl_module! { } >::insert(&who, index); >::insert(&who, votes); - Ok(()) } /// Remove a voter. For it not to be a bond-consuming no-op, all approved candidate indices @@ -120,24 +124,21 @@ decl_module! { /// May be called by anyone. Returns the voter deposit to `signed`. fn reap_inactive_voter( origin, - reporter_index: Compact, - who: Address, - who_index: Compact, - assumed_vote_index: Compact - ) -> Result { + #[compact] reporter_index: u32, + who: ::Source, + #[compact] who_index: u32, + #[compact] assumed_vote_index: VoteIndex + ) { let reporter = ensure_signed(origin)?; - let assumed_vote_index: VoteIndex = assumed_vote_index.into(); - let who = >::lookup(who)?; + let who = T::Lookup::lookup(who)?; ensure!(!Self::presentation_active(), "cannot reap during presentation period"); ensure!(Self::voter_last_active(&reporter).is_some(), "reporter must be a voter"); let last_active = Self::voter_last_active(&who).ok_or("target for inactivity cleanup must be active")?; ensure!(assumed_vote_index == Self::vote_index(), "vote index not current"); - ensure!(last_active < assumed_vote_index - Self::inactivity_grace_period(), "cannot reap during grace perid"); + ensure!(assumed_vote_index > last_active + Self::inactivity_grace_period(), "cannot reap during grace period"); let voters = Self::voters(); - let reporter_index: u32 = reporter_index.into(); let reporter_index = reporter_index as usize; - let who_index: u32 = who_index.into(); let who_index = who_index as usize; ensure!(reporter_index < voters.len() && voters[reporter_index] == reporter, "bad reporter index"); ensure!(who_index < voters.len() && voters[who_index] == who, "bad target index"); @@ -158,7 +159,7 @@ decl_module! { voters ); if valid { - // This only fails if `who` doesn't exist, which it clearly must do since its the origin. + // This only fails if `reporter` doesn't exist, which it clearly must do since its the origin. // Still, it's no more harmful to propagate any error at this point. >::repatriate_reserved(&who, &reporter, Self::voting_bond())?; Self::deposit_event(RawEvent::VoterReaped(who, reporter)); @@ -166,34 +167,30 @@ decl_module! { >::slash_reserved(&reporter, Self::voting_bond()); Self::deposit_event(RawEvent::BadReaperSlashed(reporter)); } - Ok(()) } /// Remove a voter. All votes are cancelled and the voter deposit is returned. - fn retract_voter(origin, index: Compact) -> Result { + fn retract_voter(origin, #[compact] index: u32) { let who = ensure_signed(origin)?; ensure!(!Self::presentation_active(), "cannot retract when presenting"); ensure!(>::exists(&who), "cannot retract non-voter"); let voters = Self::voters(); - let index: u32 = index.into(); let index = index as usize; ensure!(index < voters.len(), "retraction index invalid"); ensure!(voters[index] == who, "retraction index mismatch"); Self::remove_voter(&who, index, voters); >::unreserve(&who, Self::voting_bond()); - Ok(()) } /// Submit oneself for candidacy. /// /// Account must have enough transferrable funds in it to pay the bond. - fn submit_candidacy(origin, slot: Compact) -> Result { + fn submit_candidacy(origin, #[compact] slot: u32) { let who = ensure_signed(origin)?; ensure!(!Self::is_a_candidate(&who), "duplicate candidate submission"); - let slot: u32 = slot.into(); let slot = slot as usize; let count = Self::candidate_count() as usize; let candidates = Self::candidates(); @@ -215,7 +212,6 @@ decl_module! { } >::put(candidates); >::put(count as u32 + 1); - Ok(()) } /// Claim that `signed` is one of the top Self::carry_count() + current_vote().1 candidates. @@ -223,15 +219,14 @@ decl_module! { /// `signed` should have at least fn present_winner( origin, - candidate: Address, - total: ::Type, - index: Compact + candidate: ::Source, + #[compact] total: T::Balance, + #[compact] index: VoteIndex ) -> Result { let who = ensure_signed(origin)?; - let total = total.into(); - let index: VoteIndex = index.into(); + ensure!(!total.is_zero(), "stake deposited to present winner and be added to leaderboard should be non-zero"); - let candidate = >::lookup(candidate)?; + let candidate = T::Lookup::lookup(candidate)?; ensure!(index == Self::vote_index(), "index not current"); let (_, _, expiring) = Self::next_finalise().ok_or("cannot present outside of presentation period")?; let stakes = Self::snapshoted_stakes(); @@ -276,37 +271,32 @@ decl_module! { /// Set the desired member count; if lower than the current count, then seats will not be up /// election when they expire. If more, then a new vote will be started if one is not already /// in progress. - fn set_desired_seats(count: Compact) -> Result { - let count: u32 = count.into(); + fn set_desired_seats(#[compact] count: u32) { >::put(count); - Ok(()) } /// Remove a particular member. A tally will happen instantly (if not already in a presentation /// period) to fill the seat if removal means that the desired members are not met. /// This is effective immediately. - fn remove_member(who: Address) -> Result { - let who = >::lookup(who)?; + fn remove_member(who: ::Source) { + let who = T::Lookup::lookup(who)?; let new_council: Vec<(T::AccountId, T::BlockNumber)> = Self::active_council() .into_iter() .filter(|i| i.0 != who) .collect(); >::put(new_council); - Ok(()) } /// Set the presentation duration. If there is currently a vote being presented for, will /// invoke `finalise_vote`. - fn set_presentation_duration(count: ::Type) -> Result { - >::put(count.into()); - Ok(()) + fn set_presentation_duration(#[compact] count: T::BlockNumber) { + >::put(count); } /// Set the presentation duration. If there is current a vote being presented for, will /// invoke `finalise_vote`. - fn set_term_duration(count: ::Type) -> Result { - >::put(count.into()); - Ok(()) + fn set_term_duration(#[compact] count: T::BlockNumber) { + >::put(count); } fn on_finalise(n: T::BlockNumber) { @@ -332,7 +322,7 @@ decl_storage! { pub CarryCount get(carry_count) config(): u32 = 2; /// How long to give each top candidate to present themselves after the vote ends. pub PresentationDuration get(presentation_duration) config(): T::BlockNumber = T::BlockNumber::sa(1000); - /// How many votes need to go by after a voter's last vote before they can be reaped if their + /// How many vote indexes need to go by after a target voter's last vote before they can be reaped if their /// approvals are moot. pub InactiveGracePeriod get(inactivity_grace_period) config(inactive_grace_period): VoteIndex = 1; /// How often (in blocks) to check for new votes. @@ -344,13 +334,16 @@ decl_storage! { // permanent state (always relevant, changes only at the finalisation of voting) /// The current council. When there's a vote going on, this should still be used for executive - /// matters. + /// matters. The block number (second element in the tuple) is the block that their position is + /// active until (calculated by the sum of the block number when the council member was elected + /// and their term duration). pub ActiveCouncil get(active_council) config(): Vec<(T::AccountId, T::BlockNumber)>; /// The total number of votes that have happened or are in progress. pub VoteCount get(vote_index): VoteIndex; // persistent state (always relevant, changes constantly) - /// The last cleared vote index that this voter was last active at. + /// A list of votes for each voter, respecting the last cleared vote index that this voter was + /// last active at. pub ApprovalsOf get(approvals_of): map T::AccountId => Vec; /// The vote index and list slot that the candidate `who` was registered or `None` if they are not /// currently registered. @@ -467,8 +460,9 @@ impl Module { let desired_seats = Self::desired_seats() as usize; let number = >::block_number(); let expiring = active_council.iter().take_while(|i| i.1 == number).map(|i| i.0.clone()).collect::>(); - if active_council.len() - expiring.len() < desired_seats { - let empty_seats = desired_seats - (active_council.len() - expiring.len()); + let retaining_seats = active_council.len() - expiring.len(); + if retaining_seats < desired_seats { + let empty_seats = desired_seats - retaining_seats; >::put((number + Self::presentation_duration(), empty_seats as u32, expiring)); let voters = Self::voters(); @@ -566,6 +560,7 @@ mod tests { assert_eq!(Council::voting_bond(), 3); assert_eq!(Council::present_slash_per_voter(), 1); assert_eq!(Council::presentation_duration(), 2); + assert_eq!(Council::inactivity_grace_period(), 1); assert_eq!(Council::voting_period(), 4); assert_eq!(Council::term_duration(), 5); assert_eq!(Council::desired_seats(), 2); @@ -596,14 +591,14 @@ mod tests { assert_eq!(Council::is_a_candidate(&1), false); assert_eq!(Council::is_a_candidate(&2), false); - assert_ok!(Council::submit_candidacy(Origin::signed(1), 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(1), 0)); assert_eq!(Council::candidates(), vec![1]); assert_eq!(Council::candidate_reg_info(1), Some((0, 0))); assert_eq!(Council::candidate_reg_info(2), None); assert_eq!(Council::is_a_candidate(&1), true); assert_eq!(Council::is_a_candidate(&2), false); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 1.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 1)); assert_eq!(Council::candidates(), vec![1, 2]); assert_eq!(Council::candidate_reg_info(1), Some((0, 0))); assert_eq!(Council::candidate_reg_info(2), Some((0, 1))); @@ -630,10 +625,10 @@ mod tests { System::set_block_number(1); assert_eq!(Council::candidates(), vec![0, 0, 1]); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 1.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 1)); assert_eq!(Council::candidates(), vec![0, 2, 1]); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 0)); assert_eq!(Council::candidates(), vec![3, 2, 1]); }); } @@ -646,10 +641,10 @@ mod tests { System::set_block_number(1); assert_eq!(Council::candidates(), vec![0, 0, 1]); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); assert_eq!(Council::candidates(), vec![2, 0, 1]); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 1.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 1)); assert_eq!(Council::candidates(), vec![2, 3, 1]); }); } @@ -658,7 +653,7 @@ mod tests { fn candidate_submission_not_using_free_slot_should_not_work() { with_externalities(&mut new_test_ext_with_candidate_holes(), || { System::set_block_number(1); - assert_noop!(Council::submit_candidacy(Origin::signed(4), 3.into()), "invalid candidate slot"); + assert_noop!(Council::submit_candidacy(Origin::signed(4), 3), "invalid candidate slot"); }); } @@ -667,7 +662,7 @@ mod tests { with_externalities(&mut new_test_ext(false), || { System::set_block_number(1); assert_eq!(Council::candidates(), Vec::::new()); - assert_noop!(Council::submit_candidacy(Origin::signed(1), 1.into()), "invalid candidate slot"); + assert_noop!(Council::submit_candidacy(Origin::signed(1), 1), "invalid candidate slot"); }); } @@ -676,9 +671,9 @@ mod tests { with_externalities(&mut new_test_ext(false), || { System::set_block_number(1); assert_eq!(Council::candidates(), Vec::::new()); - assert_ok!(Council::submit_candidacy(Origin::signed(1), 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(1), 0)); assert_eq!(Council::candidates(), vec![1]); - assert_noop!(Council::submit_candidacy(Origin::signed(2), 0.into()), "invalid candidate slot"); + assert_noop!(Council::submit_candidacy(Origin::signed(2), 0), "invalid candidate slot"); }); } @@ -687,9 +682,9 @@ mod tests { with_externalities(&mut new_test_ext(false), || { System::set_block_number(1); assert_eq!(Council::candidates(), Vec::::new()); - assert_ok!(Council::submit_candidacy(Origin::signed(1), 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(1), 0)); assert_eq!(Council::candidates(), vec![1]); - assert_noop!(Council::submit_candidacy(Origin::signed(1), 1.into()), "duplicate candidate submission"); + assert_noop!(Council::submit_candidacy(Origin::signed(1), 1), "duplicate candidate submission"); }); } @@ -698,7 +693,7 @@ mod tests { with_externalities(&mut new_test_ext(false), || { System::set_block_number(1); assert_eq!(Council::candidates(), Vec::::new()); - assert_noop!(Council::submit_candidacy(Origin::signed(7), 0.into()), "candidate has not enough funds"); + assert_noop!(Council::submit_candidacy(Origin::signed(7), 0), "candidate has not enough funds"); }); } @@ -707,20 +702,20 @@ mod tests { with_externalities(&mut new_test_ext(false), || { System::set_block_number(1); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 0)); - assert_ok!(Council::set_approvals(Origin::signed(1), vec![true], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(4), vec![true], 0.into())); + assert_ok!(Council::set_approvals(Origin::signed(1), vec![true], 0)); + assert_ok!(Council::set_approvals(Origin::signed(4), vec![true], 0)); assert_eq!(Council::approvals_of(1), vec![true]); assert_eq!(Council::approvals_of(4), vec![true]); assert_eq!(Council::voters(), vec![1, 4]); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 1.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 2.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 2)); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true, true], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, true, true], 0.into())); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true, true], 0)); + assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, true, true], 0)); assert_eq!(Council::approvals_of(1), vec![true]); assert_eq!(Council::approvals_of(4), vec![true]); @@ -731,19 +726,43 @@ mod tests { }); } + #[test] + fn setting_any_approval_vote_count_without_any_candidate_count_should_not_work() { + with_externalities(&mut new_test_ext(false), || { + System::set_block_number(1); + + assert_eq!(Council::candidates().len(), 0); + + assert_noop!(Council::set_approvals(Origin::signed(4), vec![], 0), "amount of candidates to receive approval votes should be non-zero"); + }); + } + + #[test] + fn setting_an_approval_vote_count_more_than_candidate_count_should_not_work() { + with_externalities(&mut new_test_ext(false), || { + System::set_block_number(1); + + assert_ok!(Council::submit_candidacy(Origin::signed(5), 0)); + assert_eq!(Council::candidates().len(), 1); + + assert_noop!(Council::set_approvals(Origin::signed(4), vec![true, true], 0), "amount of candidate approval votes cannot exceed amount of candidates"); + }); + } + #[test] fn resubmitting_voting_should_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(1); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(4), vec![true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Council::set_approvals(Origin::signed(4), vec![true], 0)); assert_eq!(Council::approvals_of(4), vec![true]); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 1.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 2.into())); - assert_ok!(Council::set_approvals(Origin::signed(4), vec![true, false, true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 2)); + assert_eq!(Council::candidates().len(), 3); + assert_ok!(Council::set_approvals(Origin::signed(4), vec![true, false, true], 0)); assert_eq!(Council::approvals_of(4), vec![true, false, true]); }); @@ -754,14 +773,15 @@ mod tests { with_externalities(&mut new_test_ext(false), || { System::set_block_number(1); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 1.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 2.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 2)); + assert_eq!(Council::candidates().len(), 3); - assert_ok!(Council::set_approvals(Origin::signed(1), vec![true], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true, true], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, true, true], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(4), vec![true, false, true], 0.into())); + assert_ok!(Council::set_approvals(Origin::signed(1), vec![true], 0)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true, true], 0)); + assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, true, true], 0)); + assert_ok!(Council::set_approvals(Origin::signed(4), vec![true, false, true], 0)); assert_eq!(Council::voters(), vec![1, 2, 3, 4]); assert_eq!(Council::approvals_of(1), vec![true]); @@ -769,7 +789,7 @@ mod tests { assert_eq!(Council::approvals_of(3), vec![false, true, true]); assert_eq!(Council::approvals_of(4), vec![true, false, true]); - assert_ok!(Council::retract_voter(Origin::signed(1), 0.into())); + assert_ok!(Council::retract_voter(Origin::signed(1), 0)); assert_eq!(Council::voters(), vec![4, 2, 3]); assert_eq!(Council::approvals_of(1), Vec::::new()); @@ -777,7 +797,7 @@ mod tests { assert_eq!(Council::approvals_of(3), vec![false, true, true]); assert_eq!(Council::approvals_of(4), vec![true, false, true]); - assert_ok!(Council::retract_voter(Origin::signed(2), 1.into())); + assert_ok!(Council::retract_voter(Origin::signed(2), 1)); assert_eq!(Council::voters(), vec![4, 3]); assert_eq!(Council::approvals_of(1), Vec::::new()); @@ -785,7 +805,7 @@ mod tests { assert_eq!(Council::approvals_of(3), vec![false, true, true]); assert_eq!(Council::approvals_of(4), vec![true, false, true]); - assert_ok!(Council::retract_voter(Origin::signed(3), 1.into())); + assert_ok!(Council::retract_voter(Origin::signed(3), 1)); assert_eq!(Council::voters(), vec![4]); assert_eq!(Council::approvals_of(1), Vec::::new()); @@ -799,11 +819,11 @@ mod tests { fn invalid_retraction_index_should_not_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(1); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(1), vec![true], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 0)); + assert_ok!(Council::set_approvals(Origin::signed(1), vec![true], 0)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0)); assert_eq!(Council::voters(), vec![1, 2]); - assert_noop!(Council::retract_voter(Origin::signed(1), 1.into()), "retraction index mismatch"); + assert_noop!(Council::retract_voter(Origin::signed(1), 1), "retraction index mismatch"); }); } @@ -811,9 +831,9 @@ mod tests { fn overflow_retraction_index_should_not_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(1); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(1), vec![true], 0.into())); - assert_noop!(Council::retract_voter(Origin::signed(1), 1.into()), "retraction index invalid"); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 0)); + assert_ok!(Council::set_approvals(Origin::signed(1), vec![true], 0)); + assert_noop!(Council::retract_voter(Origin::signed(1), 1), "retraction index invalid"); }); } @@ -821,9 +841,9 @@ mod tests { fn non_voter_retraction_should_not_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(1); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(1), vec![true], 0.into())); - assert_noop!(Council::retract_voter(Origin::signed(2), 0.into()), "cannot retract non-voter"); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 0)); + assert_ok!(Council::set_approvals(Origin::signed(1), vec![true], 0)); + assert_noop!(Council::retract_voter(Origin::signed(2), 0), "cannot retract non-voter"); }); } @@ -833,10 +853,10 @@ mod tests { System::set_block_number(4); assert!(!Council::presentation_active()); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 1.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false], 0)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, true], 0)); assert_eq!(Council::voters(), vec![2, 5]); assert_eq!(Council::approvals_of(2), vec![true, false]); assert_eq!(Council::approvals_of(5), vec![false, true]); @@ -844,8 +864,8 @@ mod tests { System::set_block_number(6); assert!(Council::presentation_active()); - assert_eq!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()), Ok(())); - assert_eq!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into()), Ok(())); + assert_eq!(Council::present_winner(Origin::signed(4), 2, 20, 0), Ok(())); + assert_eq!(Council::present_winner(Origin::signed(4), 5, 50, 0), Ok(())); assert_eq!(Council::leaderboard(), Some(vec![(0, 0), (0, 0), (20, 2), (50, 5)])); assert_ok!(Council::end_block(System::block_number())); @@ -861,22 +881,35 @@ mod tests { }); } + #[test] + fn presentations_with_zero_staked_deposit_should_not_work() { + with_externalities(&mut new_test_ext(false), || { + System::set_block_number(4); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0)); + assert_ok!(Council::end_block(System::block_number())); + + System::set_block_number(6); + assert_noop!(Council::present_winner(Origin::signed(4), 2, 0, 0), "stake deposited to present winner and be added to leaderboard should be non-zero"); + }); + } + #[test] fn double_presentations_should_be_punished() { with_externalities(&mut new_test_ext(false), || { assert!(Balances::can_slash(&4, 10)); System::set_block_number(4); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 1.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false], 0)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into())); - assert_eq!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into()), Err("duplicate presentation")); + assert_ok!(Council::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 5, 50, 0)); + assert_eq!(Council::present_winner(Origin::signed(4), 5, 50, 0), Err("duplicate presentation")); assert_ok!(Council::end_block(System::block_number())); assert_eq!(Council::active_council(), vec![(5, 11), (2, 11)]); @@ -888,27 +921,27 @@ mod tests { fn retracting_inactive_voter_should_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 2, 20, 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(8); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![true], 1.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![true], 1)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(10); - assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 1.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 5, 50, 1)); assert_ok!(Council::end_block(System::block_number())); assert_ok!(Council::reap_inactive_voter(Origin::signed(5), (Council::voters().iter().position(|&i| i == 5).unwrap() as u32).into(), - 2.into(), (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2.into() + 2, (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 )); assert_eq!(Council::voters(), vec![5]); @@ -922,21 +955,21 @@ mod tests { fn presenting_for_double_election_should_not_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); - assert_eq!(Council::submit_candidacy(Origin::signed(2), 0.into()), Ok(())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0.into())); + assert_eq!(Council::submit_candidacy(Origin::signed(2), 0), Ok(())); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 2, 20, 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(8); - assert_eq!(Council::submit_candidacy(Origin::signed(2), 0.into()), Ok(())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 1.into())); + assert_eq!(Council::submit_candidacy(Origin::signed(2), 0), Ok(())); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 1)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(10); - assert_noop!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 1.into()), "candidate must not form a duplicated member if elected"); + assert_noop!(Council::present_winner(Origin::signed(4), 2, 20, 1), "candidate must not form a duplicated member if elected"); }); } @@ -944,30 +977,30 @@ mod tests { fn retracting_inactive_voter_with_other_candidates_in_slots_should_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 2, 20, 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(8); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![true], 1.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![true], 1)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(10); - assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 1.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 5, 50, 1)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(11); - assert_ok!(Council::submit_candidacy(Origin::signed(1), 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(1), 0)); assert_ok!(Council::reap_inactive_voter(Origin::signed(5), (Council::voters().iter().position(|&i| i == 5).unwrap() as u32).into(), - 2.into(), (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2.into() + 2, (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 )); assert_eq!(Council::voters(), vec![5]); @@ -981,27 +1014,27 @@ mod tests { fn retracting_inactive_voter_with_bad_reporter_index_should_not_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 2, 20, 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(8); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![true], 1.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![true], 1)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(10); - assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 1.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 5, 50, 1)); assert_ok!(Council::end_block(System::block_number())); assert_noop!(Council::reap_inactive_voter(Origin::signed(2), - 42.into(), - 2.into(), (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2.into() + 42, + 2, (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 ), "bad reporter index"); }); } @@ -1010,27 +1043,27 @@ mod tests { fn retracting_inactive_voter_with_bad_target_index_should_not_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 2, 20, 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(8); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![true], 1.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![true], 1)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(10); - assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 1.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 5, 50, 1)); assert_ok!(Council::end_block(System::block_number())); assert_noop!(Council::reap_inactive_voter(Origin::signed(2), (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2.into(), 42.into(), - 2.into() + 2, 42, + 2 ), "bad target index"); }); } @@ -1039,36 +1072,42 @@ mod tests { fn attempting_to_retract_active_voter_should_slash_reporter() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 1.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(4), 2.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 3.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false, false, false], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, true, false, false], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(4), vec![false, false, true, false], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, false, false, true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 1)); + assert_ok!(Council::submit_candidacy(Origin::signed(4), 2)); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 3)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false, false, false], 0)); + assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, true, false, false], 0)); + assert_ok!(Council::set_approvals(Origin::signed(4), vec![false, false, true, false], 0)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, false, false, true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 5, 50, 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(8); - assert_ok!(Council::set_desired_seats(3.into())); + assert_ok!(Council::set_desired_seats(3)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(10); - assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 1.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 1.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 2, 20, 1)); + assert_ok!(Council::present_winner(Origin::signed(4), 3, 30, 1)); assert_ok!(Council::end_block(System::block_number())); + assert_eq!(Council::vote_index(), 2); + assert_eq!(Council::inactivity_grace_period(), 1); + assert_eq!(Council::voting_period(), 4); + assert_eq!(Council::voter_last_active(4), Some(0)); + assert_ok!(Council::reap_inactive_voter(Origin::signed(4), (Council::voters().iter().position(|&i| i == 4).unwrap() as u32).into(), - 2.into(), (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2.into() + 2, + (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 )); assert_eq!(Council::voters(), vec![2, 3, 5]); @@ -1081,27 +1120,27 @@ mod tests { fn attempting_to_retract_inactive_voter_by_nonvoter_should_not_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 2, 20, 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(8); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![true], 1.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 0)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![true], 1)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(10); - assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 1.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 5, 50, 1)); assert_ok!(Council::end_block(System::block_number())); assert_noop!(Council::reap_inactive_voter(Origin::signed(4), - 0.into(), - 2.into(), (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(), - 2.into() + 0, + 2, (Council::voters().iter().position(|&i| i == 2).unwrap() as u32).into(), + 2 ), "reporter must be a voter"); }); } @@ -1110,24 +1149,32 @@ mod tests { fn presenting_loser_should_not_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); - assert_ok!(Council::submit_candidacy(Origin::signed(1), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(6), vec![true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 1.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 2.into())); - assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(4), 3.into())); - assert_ok!(Council::set_approvals(Origin::signed(4), vec![false, false, false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 4.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Council::set_approvals(Origin::signed(6), vec![true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Council::set_approvals(Origin::signed(4), vec![false, false, false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_ok!(Council::present_winner(Origin::signed(4), 1.into(), 60.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into())); - assert_noop!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into()), "candidate not worthy of leaderboard"); + assert_ok!(Council::present_winner(Origin::signed(4), 1, 60, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 5, 50, 0)); + + assert_eq!(Council::leaderboard(), Some(vec![ + (30, 3), + (40, 4), + (50, 5), + (60, 1) + ])); + + assert_noop!(Council::present_winner(Origin::signed(4), 2, 20, 0), "candidate not worthy of leaderboard"); }); } @@ -1135,24 +1182,24 @@ mod tests { fn presenting_loser_first_should_not_matter() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); - assert_ok!(Council::submit_candidacy(Origin::signed(1), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(6), vec![true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 1.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 2.into())); - assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(4), 3.into())); - assert_ok!(Council::set_approvals(Origin::signed(4), vec![false, false, false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 4.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Council::set_approvals(Origin::signed(6), vec![true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Council::set_approvals(Origin::signed(4), vec![false, false, false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_ok!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 1.into(), 60.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 2, 20, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 1, 60, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 5, 50, 0)); assert_eq!(Council::leaderboard(), Some(vec![ (30, 3), @@ -1168,7 +1215,7 @@ mod tests { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); assert!(!Council::presentation_active()); - assert_noop!(Council::present_winner(Origin::signed(5), 5.into(), 1.into(), 0.into()), "cannot present outside of presentation period"); + assert_noop!(Council::present_winner(Origin::signed(5), 5, 1, 0), "cannot present outside of presentation period"); }); } @@ -1176,14 +1223,14 @@ mod tests { fn present_with_invalid_vote_index_should_not_work() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 1.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false], 0)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_noop!(Council::present_winner(Origin::signed(4), 2.into(), 20.into(), 1.into()), "index not current"); + assert_noop!(Council::present_winner(Origin::signed(4), 2, 20, 1), "index not current"); }); } @@ -1193,16 +1240,16 @@ mod tests { System::set_block_number(4); assert!(!Council::presentation_active()); - assert_ok!(Council::submit_candidacy(Origin::signed(1), 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 1.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false], 0)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); assert_eq!(Balances::free_balance(&1), 1); assert_eq!(Balances::reserved_balance(&1), 9); - assert_noop!(Council::present_winner(Origin::signed(1), 1.into(), 20.into(), 0.into()), "presenter must have sufficient slashable funds"); + assert_noop!(Council::present_winner(Origin::signed(1), 1, 20, 0), "presenter must have sufficient slashable funds"); }); } @@ -1213,14 +1260,14 @@ mod tests { assert!(!Council::presentation_active()); assert_eq!(Balances::total_balance(&4), 40); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 1.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false], 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 1)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![true, false], 0)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_err!(Council::present_winner(Origin::signed(4), 2.into(), 80.into(), 0.into()), "incorrect total"); + assert_err!(Council::present_winner(Origin::signed(4), 2, 80, 0), "incorrect total"); assert_eq!(Balances::total_balance(&4), 38); }); @@ -1232,31 +1279,33 @@ mod tests { System::set_block_number(4); assert!(!Council::presentation_active()); - assert_ok!(Council::submit_candidacy(Origin::signed(1), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(6), vec![true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 1.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 2.into())); - assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(4), 3.into())); - assert_ok!(Council::set_approvals(Origin::signed(4), vec![false, false, false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 4.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Council::set_approvals(Origin::signed(6), vec![true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Council::set_approvals(Origin::signed(4), vec![false, false, false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); assert!(Council::presentation_active()); - assert_ok!(Council::present_winner(Origin::signed(4), 1.into(), 60.into(), 0.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 1, 60, 0)); + // leaderboard length is the empty seats plus the carry count (i.e. 5 + 2), where those + // to be carried are the lowest and stored in lowest indexes assert_eq!(Council::leaderboard(), Some(vec![ (0, 0), (0, 0), (0, 0), (60, 1) ])); - assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 5, 50, 0)); assert_eq!(Council::leaderboard(), Some(vec![ (30, 3), (40, 4), @@ -1289,33 +1338,33 @@ mod tests { fn second_tally_should_use_runners_up() { with_externalities(&mut new_test_ext(false), || { System::set_block_number(4); - assert_ok!(Council::submit_candidacy(Origin::signed(1), 0.into())); - assert_ok!(Council::set_approvals(Origin::signed(6), vec![true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(2), 1.into())); - assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(3), 2.into())); - assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(4), 3.into())); - assert_ok!(Council::set_approvals(Origin::signed(4), vec![false, false, false, true], 0.into())); - assert_ok!(Council::submit_candidacy(Origin::signed(5), 4.into())); - assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0.into())); + assert_ok!(Council::submit_candidacy(Origin::signed(1), 0)); + assert_ok!(Council::set_approvals(Origin::signed(6), vec![true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(2), 1)); + assert_ok!(Council::set_approvals(Origin::signed(2), vec![false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(3), 2)); + assert_ok!(Council::set_approvals(Origin::signed(3), vec![false, false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(4), 3)); + assert_ok!(Council::set_approvals(Origin::signed(4), vec![false, false, false, true], 0)); + assert_ok!(Council::submit_candidacy(Origin::signed(5), 4)); + assert_ok!(Council::set_approvals(Origin::signed(5), vec![false, false, false, false, true], 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(6); - assert_ok!(Council::present_winner(Origin::signed(4), 1.into(), 60.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 30.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 0.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 5.into(), 50.into(), 0.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 1, 60, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 3, 30, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 4, 40, 0)); + assert_ok!(Council::present_winner(Origin::signed(4), 5, 50, 0)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(8); - assert_ok!(Council::set_approvals(Origin::signed(6), vec![false, false, true, false], 1.into())); - assert_ok!(Council::set_desired_seats(3.into())); + assert_ok!(Council::set_approvals(Origin::signed(6), vec![false, false, true, false], 1)); + assert_ok!(Council::set_desired_seats(3)); assert_ok!(Council::end_block(System::block_number())); System::set_block_number(10); - assert_ok!(Council::present_winner(Origin::signed(4), 3.into(), 90.into(), 1.into())); - assert_ok!(Council::present_winner(Origin::signed(4), 4.into(), 40.into(), 1.into())); + assert_ok!(Council::present_winner(Origin::signed(4), 3, 90, 1)); + assert_ok!(Council::present_winner(Origin::signed(4), 4, 40, 1)); assert_ok!(Council::end_block(System::block_number())); assert!(!Council::presentation_active()); diff --git a/srml/council/src/voting.rs b/srml/council/src/voting.rs index b598e8ca05257b1b91708148f389fe7431c06bcc..b1a57b90ad344a2a93df60e206d35a676a50a19d 100644 --- a/srml/council/src/voting.rs +++ b/srml/council/src/voting.rs @@ -18,8 +18,7 @@ use rstd::prelude::*; use rstd::borrow::Borrow; -use codec::HasCompact; -use primitives::traits::{Hash, As}; +use primitives::traits::{Hash, As, Zero}; use runtime_io::print; use srml_support::dispatch::Result; use srml_support::{StorageValue, StorageMap, IsSubType}; @@ -33,9 +32,9 @@ pub trait Trait: CouncilTrait { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; - fn propose(origin, proposal: Box) -> Result { + fn propose(origin, proposal: Box) { let who = ensure_signed(origin)?; let expiry = >::block_number() + Self::voting_period(); @@ -54,11 +53,9 @@ decl_module! { >::insert(proposal_hash, *proposal); >::insert(proposal_hash, vec![who.clone()]); >::insert((proposal_hash, who.clone()), true); - - Ok(()) } - fn vote(origin, proposal: T::Hash, approve: bool) -> Result { + fn vote(origin, proposal: T::Hash, approve: bool) { let who = ensure_signed(origin)?; ensure!(Self::is_councillor(&who), "only councillors may vote on council proposals"); @@ -67,10 +64,9 @@ decl_module! { >::mutate(proposal, |voters| voters.push(who.clone())); } >::insert((proposal, who), approve); - Ok(()) } - fn veto(origin, proposal_hash: T::Hash) -> Result { + fn veto(origin, proposal_hash: T::Hash) { let who = ensure_signed(origin)?; ensure!(Self::is_councillor(&who), "only councillors may veto council proposals"); @@ -96,17 +92,14 @@ decl_module! { for (c, _) in >::active_council() { >::remove((proposal_hash, c)); } - Ok(()) } - fn set_cooloff_period(blocks: ::Type) -> Result { - >::put(blocks.into()); - Ok(()) + fn set_cooloff_period(#[compact] blocks: T::BlockNumber) { + >::put(blocks); } - fn set_voting_period(blocks: ::Type) -> Result { - >::put(blocks.into()); - Ok(()) + fn set_voting_period(#[compact] blocks: T::BlockNumber) { + >::put(blocks); } fn on_finalise(n: T::BlockNumber) { @@ -122,6 +115,8 @@ decl_storage! { trait Store for Module as CouncilVoting { pub CooloffPeriod get(cooloff_period) config(): T::BlockNumber = T::BlockNumber::sa(1000); pub VotingPeriod get(voting_period) config(): T::BlockNumber = T::BlockNumber::sa(3); + /// Number of blocks by which to delay enactment of successful, non-unanimous-council-instigated referendum proposals. + pub EnactDelayPeriod get(enact_delay_period) config(): T::BlockNumber = T::BlockNumber::sa(0); pub Proposals get(proposals) build(|_| vec![0u8; 0]): Vec<(T::BlockNumber, T::Hash)>; // ordered by expiry. pub ProposalOf get(proposal_of): map T::Hash => Option; pub ProposalVoters get(proposal_voters): map T::Hash => Vec; @@ -215,10 +210,18 @@ impl Module { Self::deposit_event(RawEvent::TallyReferendum(proposal_hash.clone(), tally.0, tally.1, tally.2)); if tally.0 > tally.1 + tally.2 { Self::kill_veto_of(&proposal_hash); - match tally { - (_, 0, 0) => >::internal_start_referendum(proposal, democracy::VoteThreshold::SuperMajorityAgainst).map(|_| ())?, - _ => >::internal_start_referendum(proposal, democracy::VoteThreshold::SimpleMajority).map(|_| ())?, + // If there were no nay-votes from the council, then it's weakly uncontroversial; we enact immediately. + let period = match tally.1 { + 0 => Zero::zero(), + _ => Self::enact_delay_period(), + }; + // If all council members voted yes, then it's strongly uncontroversial; we require a negative + // super-majority at referendum in order to defeat it. + let threshold = match tally { + (_, 0, 0) => democracy::VoteThreshold::SuperMajorityAgainst, + _ => democracy::VoteThreshold::SimpleMajority, }; + >::internal_start_referendum(proposal, threshold, period).map(|_| ())?; } } } @@ -232,7 +235,7 @@ mod tests { use ::tests::*; use ::tests::{Call, Origin}; use srml_support::Hashable; - use democracy::VoteThreshold; + use democracy::{ReferendumInfo, VoteThreshold}; #[test] fn basic_environment_works() { @@ -255,7 +258,7 @@ mod tests { } fn set_balance_proposal(value: u64) -> Call { - Call::Balances(balances::Call::set_balance(balances::address::Address::Id(42), value.into(), 0.into())) + Call::Balances(balances::Call::set_balance(42, value.into(), 0)) } fn cancel_referendum_proposal(id: u32) -> Call { @@ -267,8 +270,8 @@ mod tests { with_externalities(&mut new_test_ext(true), || { System::set_block_number(1); let proposal = set_balance_proposal(42); - assert_ok!(Democracy::internal_start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove), 0); - assert_eq!(Democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]); + assert_ok!(Democracy::internal_start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove, 0), 0); + assert_eq!(Democracy::active_referendums(), vec![(0, ReferendumInfo::new(4, proposal, VoteThreshold::SuperMajorityApprove, 0))]); let cancellation = cancel_referendum_proposal(0); let hash = cancellation.blake2_256().into(); @@ -290,7 +293,7 @@ mod tests { with_externalities(&mut new_test_ext(true), || { System::set_block_number(1); let proposal = set_balance_proposal(42); - assert_ok!(Democracy::internal_start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove), 0); + assert_ok!(Democracy::internal_start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove, 0), 0); let cancellation = cancel_referendum_proposal(0); let hash = cancellation.blake2_256().into(); @@ -301,7 +304,7 @@ mod tests { System::set_block_number(2); assert_ok!(CouncilVoting::end_block(System::block_number())); - assert_eq!(Democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]); + assert_eq!(Democracy::active_referendums(), vec![(0, ReferendumInfo::new(4, proposal, VoteThreshold::SuperMajorityApprove, 0))]); }); } @@ -310,7 +313,7 @@ mod tests { with_externalities(&mut new_test_ext(true), || { System::set_block_number(1); let proposal = set_balance_proposal(42); - assert_ok!(Democracy::internal_start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove), 0); + assert_ok!(Democracy::internal_start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove, 0), 0); let cancellation = cancel_referendum_proposal(0); let hash = cancellation.blake2_256().into(); @@ -320,7 +323,7 @@ mod tests { System::set_block_number(2); assert_ok!(CouncilVoting::end_block(System::block_number())); - assert_eq!(Democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]); + assert_eq!(Democracy::active_referendums(), vec![(0, ReferendumInfo::new(4, proposal, VoteThreshold::SuperMajorityApprove, 0))]); }); } @@ -384,7 +387,7 @@ mod tests { System::set_block_number(4); assert_ok!(CouncilVoting::end_block(System::block_number())); assert_eq!(CouncilVoting::proposals().len(), 0); - assert_eq!(Democracy::active_referendums(), vec![(0, 7, set_balance_proposal(42), VoteThreshold::SimpleMajority)]); + assert_eq!(Democracy::active_referendums(), vec![(0, ReferendumInfo::new(7, set_balance_proposal(42), VoteThreshold::SimpleMajority, 0))]); }); } @@ -449,7 +452,7 @@ mod tests { System::set_block_number(2); assert_ok!(CouncilVoting::end_block(System::block_number())); assert_eq!(CouncilVoting::proposals().len(), 0); - assert_eq!(Democracy::active_referendums(), vec![(0, 5, proposal, VoteThreshold::SuperMajorityAgainst)]); + assert_eq!(Democracy::active_referendums(), vec![(0, ReferendumInfo::new(5, proposal, VoteThreshold::SuperMajorityAgainst, 0))]); }); } @@ -467,7 +470,7 @@ mod tests { System::set_block_number(2); assert_ok!(CouncilVoting::end_block(System::block_number())); assert_eq!(CouncilVoting::proposals().len(), 0); - assert_eq!(Democracy::active_referendums(), vec![(0, 5, proposal, VoteThreshold::SimpleMajority)]); + assert_eq!(Democracy::active_referendums(), vec![(0, ReferendumInfo::new(5, proposal, VoteThreshold::SimpleMajority, 0))]); }); } diff --git a/srml/democracy/Cargo.toml b/srml/democracy/Cargo.toml index c037a4b219dbeb5a012878628491cec3edd9d60c..95a67e5fd0fa583e4c8b948d676dc5356a706597 100644 --- a/srml/democracy/Cargo.toml +++ b/srml/democracy/Cargo.toml @@ -6,9 +6,8 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } safe-mix = { version = "1.0", default-features = false} -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } @@ -22,7 +21,6 @@ srml-system = { path = "../system", default-features = false } default = ["std"] std = [ "serde/std", - "serde_derive", "safe-mix/std", "parity-codec/std", "substrate-primitives/std", diff --git a/srml/democracy/src/lib.rs b/srml/democracy/src/lib.rs index 34aad5856c7669288338c1cd63c364f41899a6a2..6f9bc4630657cb221f0fbcda9a3237cd0a90fda9 100644 --- a/srml/democracy/src/lib.rs +++ b/srml/democracy/src/lib.rs @@ -21,10 +21,6 @@ #[cfg(test)] extern crate substrate_primitives; -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - #[macro_use] extern crate parity_codec_derive; #[cfg_attr(not(feature = "std"), macro_use)] @@ -40,8 +36,7 @@ extern crate srml_system as system; use rstd::prelude::*; use rstd::result; -use codec::{HasCompact, Compact}; -use primitives::traits::{Zero, As, MaybeSerializeDebug}; +use primitives::traits::{Zero, As}; use srml_support::{StorageValue, StorageMap, Parameter, Dispatchable, IsSubType}; use srml_support::dispatch::Result; use system::ensure_signed; @@ -53,25 +48,53 @@ pub use vote_threshold::{Approved, VoteThreshold}; pub type PropIndex = u32; /// A referendum index. pub type ReferendumIndex = u32; +/// A number of lock periods. +pub type LockPeriods = i8; + +/// A number of lock periods, plus a vote, one way or the other. +#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Default)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct Vote(i8); + +impl Vote { + /// Create a new instance. + pub fn new(aye: bool, multiplier: LockPeriods) -> Self { + let m = multiplier.max(1) - 1; + Vote(if aye { + -1 - m + } else { + m + }) + } + + /// Is this an aye vote? + pub fn is_aye(self) -> bool { + self.0 < 0 + } + + /// The strength (measured in lock periods). + pub fn multiplier(self) -> LockPeriods { + 1 + if self.0 < 0 { -(self.0 + 1) } else { self.0 } + } +} pub trait Trait: balances::Trait + Sized { - type Proposal: Parameter + Dispatchable + IsSubType> + MaybeSerializeDebug; + type Proposal: Parameter + Dispatchable + IsSubType>; type Event: From> + Into<::Event>; } decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Propose a sensitive action to be taken. fn propose( origin, proposal: Box, - value: ::Type - ) -> Result { + #[compact] value: T::Balance + ) { let who = ensure_signed(origin)?; - let value = value.into(); ensure!(value >= Self::minimum_deposit(), "value too low"); >::reserve(&who, value) @@ -84,49 +107,52 @@ decl_module! { let mut props = Self::public_props(); props.push((index, (*proposal).clone(), who)); >::put(props); - Ok(()) } /// Propose a sensitive action to be taken. - fn second(origin, proposal: Compact) -> Result { + fn second(origin, #[compact] proposal: PropIndex) { let who = ensure_signed(origin)?; - let proposal: PropIndex = proposal.into(); let mut deposit = Self::deposit_of(proposal) .ok_or("can only second an existing proposal")?; >::reserve(&who, deposit.0) .map_err(|_| "seconder's balance too low")?; deposit.1.push(who); >::insert(proposal, deposit); - Ok(()) } - /// Vote in a referendum. If `approve_proposal` is true, the vote is to enact the proposal; - /// false would be a vote to keep the status quo. - fn vote(origin, ref_index: Compact, approve_proposal: bool) -> Result { + /// Vote in a referendum. If `vote.is_aye()`, the vote is to enact the proposal; + /// otherwise it is a vote to keep the status quo. + fn vote(origin, #[compact] ref_index: ReferendumIndex, vote: Vote) { let who = ensure_signed(origin)?; - let ref_index = ref_index.into(); + ensure!(vote.multiplier() <= Self::max_lock_periods(), "vote has too great a strength"); ensure!(Self::is_active_referendum(ref_index), "vote given for invalid referendum."); ensure!(!>::total_balance(&who).is_zero(), "transactor must have balance to signal approval."); if !>::exists(&(ref_index, who.clone())) { >::mutate(ref_index, |voters| voters.push(who.clone())); } - >::insert(&(ref_index, who), approve_proposal); - Ok(()) + >::insert(&(ref_index, who), vote); } /// Start a referendum. - fn start_referendum(proposal: Box, vote_threshold: VoteThreshold) -> Result { + fn start_referendum(proposal: Box, threshold: VoteThreshold, delay: T::BlockNumber) -> Result { Self::inject_referendum( >::block_number() + Self::voting_period(), *proposal, - vote_threshold + threshold, + delay, ).map(|_| ()) } /// Remove a referendum. - fn cancel_referendum(ref_index: Compact) -> Result { - Self::clear_referendum(ref_index.into()); + fn cancel_referendum(#[compact] ref_index: ReferendumIndex) { + Self::clear_referendum(ref_index); + } + + /// Cancel a proposal queued for enactment. + pub fn cancel_queued(#[compact] when: T::BlockNumber, #[compact] which: u32) -> Result { + let which = which as usize; + >::mutate(when, |items| if items.len() > which { items[which] = None }); Ok(()) } @@ -138,6 +164,27 @@ decl_module! { } } +/// Info regarding an ongoing referendum. +#[derive(Encode, Decode, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "std", derive(Debug))] +pub struct ReferendumInfo { + /// When voting on this referendum will end. + end: BlockNumber, + /// The proposal being voted on. + proposal: Proposal, + /// The thresholding mechanism to determine whether it passed. + threshold: VoteThreshold, + /// The delay (in blocks) to wait after a successful referendum before deploying. + delay: BlockNumber, +} + +impl ReferendumInfo { + /// Create a new instance. + pub fn new(end: BlockNumber, proposal: Proposal, threshold: VoteThreshold, delay: BlockNumber) -> Self { + ReferendumInfo { end, proposal, threshold, delay } + } +} + decl_storage! { trait Store for Module as Democracy { @@ -151,6 +198,10 @@ decl_storage! { pub LaunchPeriod get(launch_period) config(): T::BlockNumber = T::BlockNumber::sa(1000); /// The minimum amount to be used as a deposit for a public referendum proposal. pub MinimumDeposit get(minimum_deposit) config(): T::Balance; + /// The delay before enactment for all public referenda. + pub PublicDelay get(public_delay) config(): T::BlockNumber; + /// The maximum number of additional lock periods a voter may offer to strengthen their vote. Multiples of `PublicDelay`. + pub MaxLockPeriods get(max_lock_periods) config(): LockPeriods; /// How often (in blocks) to check for new votes. pub VotingPeriod get(voting_period) config(): T::BlockNumber = T::BlockNumber::sa(1000); @@ -160,13 +211,20 @@ decl_storage! { /// The next referendum index that should be tallied. pub NextTally get(next_tally) build(|_| 0 as ReferendumIndex): ReferendumIndex; /// Information concerning any given referendum. - pub ReferendumInfoOf get(referendum_info): map ReferendumIndex => Option<(T::BlockNumber, T::Proposal, VoteThreshold)>; + pub ReferendumInfoOf get(referendum_info): map ReferendumIndex => Option<(ReferendumInfo)>; + /// Queue of successful referenda to be dispatched. + pub DispatchQueue get(dispatch_queue): map T::BlockNumber => Vec>; + + /// The block at which the `who`'s funds become liquid. + pub Bondage get(bondage): map T::AccountId => T::BlockNumber; /// Get the voters for the current proposal. pub VotersFor get(voters_for): map ReferendumIndex => Vec; - /// Get the vote, if Some, of `who`. - pub VoteOf get(vote_of): map (ReferendumIndex, T::AccountId) => Option; + /// Get the vote in a given referendum of a particular voter. The result is meaningful only if `voters_for` includes the + /// voter when called with the referendum (you'll get the default `Vote` value otherwise). If you don't want to check + /// `voters_for`, then you can also check for simple existence with `VoteOf::exists` first. + pub VoteOf get(vote_of): map (ReferendumIndex, T::AccountId) => Vote; } } @@ -197,37 +255,45 @@ impl Module { } /// Get all referendums currently active. - pub fn active_referendums() -> Vec<(ReferendumIndex, T::BlockNumber, T::Proposal, VoteThreshold)> { + pub fn active_referendums() -> Vec<(ReferendumIndex, ReferendumInfo)> { let next = Self::next_tally(); let last = Self::referendum_count(); (next..last).into_iter() - .filter_map(|i| Self::referendum_info(i).map(|(n, p, t)| (i, n, p, t))) + .filter_map(|i| Self::referendum_info(i).map(|info| (i, info))) .collect() } /// Get all referendums ready for tally at block `n`. - pub fn maturing_referendums_at(n: T::BlockNumber) -> Vec<(ReferendumIndex, T::BlockNumber, T::Proposal, VoteThreshold)> { + pub fn maturing_referendums_at(n: T::BlockNumber) -> Vec<(ReferendumIndex, ReferendumInfo)> { let next = Self::next_tally(); let last = Self::referendum_count(); (next..last).into_iter() - .filter_map(|i| Self::referendum_info(i).map(|(n, p, t)| (i, n, p, t))) - .take_while(|&(_, block_number, _, _)| block_number == n) + .filter_map(|i| Self::referendum_info(i).map(|info| (i, info))) + .take_while(|&(_, ref info)| info.end == n) .collect() } /// Get the voters for the current proposal. - pub fn tally(ref_index: ReferendumIndex) -> (T::Balance, T::Balance) { + pub fn tally(ref_index: ReferendumIndex) -> (T::Balance, T::Balance, T::Balance) { Self::voters_for(ref_index).iter() - .map(|a| (>::total_balance(a), Self::vote_of((ref_index, a.clone())).unwrap_or(false)/*defensive only: all items come from `voters`; for an item to be in `voters` there must be a vote registered; qed*/)) - .map(|(bal, vote)| if vote { (bal, Zero::zero()) } else { (Zero::zero(), bal) }) - .fold((Zero::zero(), Zero::zero()), |(a, b), (c, d)| (a + c, b + d)) + .map(|voter| ( + >::total_balance(voter), + Self::vote_of((ref_index, voter.clone())), + )) + .map(|(bal, vote)| + if vote.is_aye() { + (bal * T::Balance::sa(vote.multiplier() as u64), Zero::zero(), bal) + } else { + (Zero::zero(), bal * T::Balance::sa(vote.multiplier() as u64), bal) + } + ).fold((Zero::zero(), Zero::zero(), Zero::zero()), |(a, b, c), (d, e, f)| (a + d, b + e, c + f)) } // Exposed mutables. /// Start a referendum. Can be called directly by the council. - pub fn internal_start_referendum(proposal: T::Proposal, vote_threshold: VoteThreshold) -> result::Result { - >::inject_referendum(>::block_number() + >::voting_period(), proposal, vote_threshold) + pub fn internal_start_referendum(proposal: T::Proposal, threshold: VoteThreshold, delay: T::BlockNumber) -> result::Result { + >::inject_referendum(>::block_number() + >::voting_period(), proposal, threshold, delay) } /// Remove a referendum. Can be called directly by the council. @@ -242,16 +308,17 @@ impl Module { fn inject_referendum( end: T::BlockNumber, proposal: T::Proposal, - vote_threshold: VoteThreshold + threshold: VoteThreshold, + delay: T::BlockNumber, ) -> result::Result { let ref_index = Self::referendum_count(); - if ref_index > 0 && Self::referendum_info(ref_index - 1).map(|i| i.0 > end).unwrap_or(false) { + if ref_index > 0 && Self::referendum_info(ref_index - 1).map(|i| i.end > end).unwrap_or(false) { Err("Cannot inject a referendum that ends earlier than preceeding referendum")? } >::put(ref_index + 1); - >::insert(ref_index, (end, proposal, vote_threshold)); - Self::deposit_event(RawEvent::Started(ref_index, vote_threshold)); + >::insert(ref_index, ReferendumInfo { end, proposal, threshold, delay }); + Self::deposit_event(RawEvent::Started(ref_index, threshold)); Ok(ref_index) } @@ -264,56 +331,118 @@ impl Module { } } + /// Enact a proposal from a referendum. + fn enact_proposal(proposal: T::Proposal, index: ReferendumIndex) { + let ok = proposal.dispatch(system::RawOrigin::Root.into()).is_ok(); + Self::deposit_event(RawEvent::Executed(index, ok)); + } + + fn launch_next(now: T::BlockNumber) -> Result { + let mut public_props = Self::public_props(); + if let Some((winner_index, _)) = public_props.iter() + .enumerate() + .max_by_key(|x| Self::locked_for((x.1).0).unwrap_or_else(Zero::zero)/*defensive only: All current public proposals have an amount locked*/) + { + let (prop_index, proposal, _) = public_props.swap_remove(winner_index); + >::put(public_props); + + if let Some((deposit, depositors)) = >::take(prop_index) {//: (T::Balance, Vec) = + // refund depositors + for d in &depositors { + >::unreserve(d, deposit); + } + Self::deposit_event(RawEvent::Tabled(prop_index, deposit, depositors)); + Self::inject_referendum(now + Self::voting_period(), proposal, VoteThreshold::SuperMajorityApprove, Self::public_delay())?; + } + } + + Ok(()) + } + + fn bake_referendum(now: T::BlockNumber, index: ReferendumIndex, info: ReferendumInfo) -> Result { + let (approve, against, capital) = Self::tally(index); + let total_issuance = >::total_issuance(); + let approved = info.threshold.approved(approve, against, capital, total_issuance); + let lock_period = Self::public_delay(); + + // Logic defined in https://www.slideshare.net/gavofyork/governance-in-polkadot-poc3 + // Essentially, we extend the lock-period of the coins behind the winning votes to be the + // vote strength times the public delay period from now. + for (a, vote) in Self::voters_for(index).into_iter() + .map(|a| (a.clone(), Self::vote_of((index, a)))) + // ^^^ defensive only: all items come from `voters`; for an item to be in `voters` there must be a vote registered; qed + .filter(|&(_, vote)| vote.is_aye() == approved) // Just the winning coins + { + // now plus: the base lock period multiplied by the number of periods this voter offered to + // lock should they win... + let locked_until = now + lock_period * T::BlockNumber::sa((vote.multiplier()) as u64); + // ...extend their bondage until at least then. + >::mutate(a, |b| if *b < locked_until { *b = locked_until }); + } + + Self::clear_referendum(index); + if approved { + Self::deposit_event(RawEvent::Passed(index)); + if info.delay.is_zero() { + Self::enact_proposal(info.proposal, index); + } else { + >::mutate(now + info.delay, |q| q.push(Some((info.proposal, index)))); + } + } else { + Self::deposit_event(RawEvent::NotPassed(index)); + } + >::put(index + 1); + + Ok(()) + } + /// Current era is ending; we should finish up any proposals. fn end_block(now: T::BlockNumber) -> Result { // pick out another public referendum if it's time. if (now % Self::launch_period()).is_zero() { - let mut public_props = Self::public_props(); - if let Some((winner_index, _)) = public_props.iter() - .enumerate() - .max_by_key(|x| Self::locked_for((x.1).0).unwrap_or_else(Zero::zero)/*defensive only: All current public proposals have an amount locked*/) - { - let (prop_index, proposal, _) = public_props.swap_remove(winner_index); - >::put(public_props); - - if let Some((deposit, depositors)) = >::take(prop_index) {//: (T::Balance, Vec) = - // refund depositors - for d in &depositors { - >::unreserve(d, deposit); - } - Self::deposit_event(RawEvent::Tabled(prop_index, deposit, depositors)); - Self::inject_referendum(now + Self::voting_period(), proposal, VoteThreshold::SuperMajorityApprove)?; - } - } + Self::launch_next(now.clone())?; } // tally up votes for any expiring referenda. - for (index, _, proposal, vote_threshold) in Self::maturing_referendums_at(now) { - let (approve, against) = Self::tally(index); - let total_issuance = >::total_issuance(); - Self::clear_referendum(index); - if vote_threshold.approved(approve, against, total_issuance) { - Self::deposit_event(RawEvent::Passed(index)); - let ok = proposal.dispatch(system::RawOrigin::Root.into()).is_ok(); - Self::deposit_event(RawEvent::Executed(index, ok)); - } else { - Self::deposit_event(RawEvent::NotPassed(index)); - } - >::put(index + 1); + for (index, info) in Self::maturing_referendums_at(now).into_iter() { + Self::bake_referendum(now.clone(), index, info)?; + } + + for (proposal, index) in >::take(now).into_iter().filter_map(|x| x) { + Self::enact_proposal(proposal, index); } Ok(()) } } +impl balances::OnFreeBalanceZero for Module { + fn on_free_balance_zero(who: &T::AccountId) { + >::remove(who); + } +} + +impl balances::EnsureAccountLiquid for Module { + fn ensure_account_liquid(who: &T::AccountId) -> Result { + if Self::bondage(who) <= >::block_number() { + Ok(()) + } else { + Err("cannot transfer illiquid funds") + } + } +} + #[cfg(test)] mod tests { use super::*; use runtime_io::with_externalities; use substrate_primitives::{H256, Blake2Hasher}; use primitives::BuildStorage; - use primitives::traits::{BlakeTwo256}; + use primitives::traits::{BlakeTwo256, IdentityLookup}; use primitives::testing::{Digest, DigestItem, Header}; + const AYE: Vote = Vote(-1); + const NAY: Vote = Vote(0); + impl_outer_origin! { pub enum Origin for Test {} } @@ -326,7 +455,7 @@ mod tests { } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] + #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; impl system::Trait for Test { type Origin = Origin; @@ -336,14 +465,15 @@ mod tests { type Hashing = BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = (); type Log = DigestItem; } impl balances::Trait for Test { type Balance = u64; - type AccountIndex = u64; type OnFreeBalanceZero = (); + type OnNewAccount = (); type EnsureAccountLiquid = (); type Event = (); } @@ -353,6 +483,10 @@ mod tests { } fn new_test_ext() -> runtime_io::TestExternalities { + new_test_ext_with_public_delay(0) + } + + fn new_test_ext_with_public_delay(public_delay: u64) -> runtime_io::TestExternalities { let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; t.extend(balances::GenesisConfig::{ balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)], @@ -361,12 +495,13 @@ mod tests { existential_deposit: 0, transfer_fee: 0, creation_fee: 0, - reclaim_rebate: 0, }.build_storage().unwrap().0); t.extend(GenesisConfig::{ launch_period: 1, voting_period: 1, minimum_deposit: 1, + public_delay, + max_lock_periods: 6, }.build_storage().unwrap().0); runtime_io::TestExternalities::new(t) } @@ -384,11 +519,39 @@ mod tests { assert_eq!(Democracy::referendum_count(), 0); assert_eq!(Balances::free_balance(&42), 0); assert_eq!(Balances::total_issuance(), 210); + assert_eq!(Democracy::public_delay(), 0); + assert_eq!(Democracy::max_lock_periods(), 6); + }); + } + + #[test] + fn vote_should_work() { + assert_eq!(Vote::new(true, 0).multiplier(), 1); + assert_eq!(Vote::new(true, 1).multiplier(), 1); + assert_eq!(Vote::new(true, 2).multiplier(), 2); + assert_eq!(Vote::new(true, 0).is_aye(), true); + assert_eq!(Vote::new(true, 1).is_aye(), true); + assert_eq!(Vote::new(true, 2).is_aye(), true); + assert_eq!(Vote::new(false, 0).multiplier(), 1); + assert_eq!(Vote::new(false, 1).multiplier(), 1); + assert_eq!(Vote::new(false, 2).multiplier(), 2); + assert_eq!(Vote::new(false, 0).is_aye(), false); + assert_eq!(Vote::new(false, 1).is_aye(), false); + assert_eq!(Vote::new(false, 2).is_aye(), false); + } + + #[test] + fn invalid_vote_strength_should_not_work() { + with_externalities(&mut new_test_ext(), || { + System::set_block_number(1); + let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove, 0).unwrap(); + assert_noop!(Democracy::vote(Origin::signed(1), r, Vote::new(true, 7)), "vote has too great a strength"); + assert_noop!(Democracy::vote(Origin::signed(1), r, Vote::new(false, 7)), "vote has too great a strength"); }); } fn set_balance_proposal(value: u64) -> Call { - Call::Balances(balances::Call::set_balance(balances::address::Address::Id(42), value.into(), 0.into())) + Call::Balances(balances::Call::set_balance(42, value.into(), 0)) } fn propose_set_balance(who: u64, value: u64, locked: u64) -> super::Result { @@ -417,12 +580,12 @@ mod tests { System::set_block_number(2); let r = 0; - assert_ok!(Democracy::vote(Origin::signed(1), r.into(), true)); + assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); assert_eq!(Democracy::referendum_count(), 1); assert_eq!(Democracy::voters_for(r), vec![1]); - assert_eq!(Democracy::vote_of((r, 1)), Some(true)); - assert_eq!(Democracy::tally(r), (10, 0)); + assert_eq!(Democracy::vote_of((r, 1)), AYE); + assert_eq!(Democracy::tally(r), (10, 0, 10)); assert_eq!(Democracy::end_block(System::block_number()), Ok(())); @@ -435,10 +598,10 @@ mod tests { with_externalities(&mut new_test_ext(), || { System::set_block_number(1); assert_ok!(propose_set_balance(1, 2, 5)); - assert_ok!(Democracy::second(Origin::signed(2), 0.into())); - assert_ok!(Democracy::second(Origin::signed(5), 0.into())); - assert_ok!(Democracy::second(Origin::signed(5), 0.into())); - assert_ok!(Democracy::second(Origin::signed(5), 0.into())); + 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_eq!(Balances::free_balance(&1), 5); assert_eq!(Balances::free_balance(&2), 15); assert_eq!(Balances::free_balance(&5), 35); @@ -450,10 +613,10 @@ mod tests { with_externalities(&mut new_test_ext(), || { System::set_block_number(1); assert_ok!(propose_set_balance(1, 2, 5)); - assert_ok!(Democracy::second(Origin::signed(2), 0.into())); - assert_ok!(Democracy::second(Origin::signed(5), 0.into())); - assert_ok!(Democracy::second(Origin::signed(5), 0.into())); - assert_ok!(Democracy::second(Origin::signed(5), 0.into())); + 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_eq!(Democracy::end_block(System::block_number()), Ok(())); assert_eq!(Balances::free_balance(&1), 10); assert_eq!(Balances::free_balance(&2), 20); @@ -482,7 +645,7 @@ mod tests { with_externalities(&mut new_test_ext(), || { System::set_block_number(1); assert_ok!(propose_set_balance(2, 2, 11)); - assert_noop!(Democracy::second(Origin::signed(1), 0.into()), "seconder\'s balance too low"); + assert_noop!(Democracy::second(Origin::signed(1), 0), "seconder\'s balance too low"); }); } @@ -496,17 +659,17 @@ mod tests { assert_eq!(Democracy::end_block(System::block_number()), Ok(())); System::set_block_number(1); - assert_ok!(Democracy::vote(Origin::signed(1), 0.into(), true)); + assert_ok!(Democracy::vote(Origin::signed(1), 0, AYE)); assert_eq!(Democracy::end_block(System::block_number()), Ok(())); assert_eq!(Balances::free_balance(&42), 4); System::set_block_number(2); - assert_ok!(Democracy::vote(Origin::signed(1), 1.into(), true)); + assert_ok!(Democracy::vote(Origin::signed(1), 1, AYE)); assert_eq!(Democracy::end_block(System::block_number()), Ok(())); assert_eq!(Balances::free_balance(&42), 3); System::set_block_number(3); - assert_ok!(Democracy::vote(Origin::signed(1), 2.into(), true)); + assert_ok!(Democracy::vote(Origin::signed(1), 2, AYE)); assert_eq!(Democracy::end_block(System::block_number()), Ok(())); }); } @@ -515,12 +678,12 @@ mod tests { fn simple_passing_should_work() { with_externalities(&mut new_test_ext(), || { System::set_block_number(1); - let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove).unwrap(); - assert_ok!(Democracy::vote(Origin::signed(1), r.into(), true)); + let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove, 0).unwrap(); + assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); assert_eq!(Democracy::voters_for(r), vec![1]); - assert_eq!(Democracy::vote_of((r, 1)), Some(true)); - assert_eq!(Democracy::tally(r), (10, 0)); + assert_eq!(Democracy::vote_of((r, 1)), AYE); + assert_eq!(Democracy::tally(r), (10, 0, 10)); assert_eq!(Democracy::end_block(System::block_number()), Ok(())); @@ -532,8 +695,8 @@ mod tests { fn cancel_referendum_should_work() { with_externalities(&mut new_test_ext(), || { System::set_block_number(1); - let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove).unwrap(); - assert_ok!(Democracy::vote(Origin::signed(1), r.into(), true)); + let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove, 0).unwrap(); + assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); assert_ok!(Democracy::cancel_referendum(r.into())); assert_eq!(Democracy::end_block(System::block_number()), Ok(())); @@ -546,12 +709,12 @@ mod tests { fn simple_failing_should_work() { with_externalities(&mut new_test_ext(), || { System::set_block_number(1); - let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove).unwrap(); - assert_ok!(Democracy::vote(Origin::signed(1), r.into(), false)); + let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove, 0).unwrap(); + assert_ok!(Democracy::vote(Origin::signed(1), r, NAY)); assert_eq!(Democracy::voters_for(r), vec![1]); - assert_eq!(Democracy::vote_of((r, 1)), Some(false)); - assert_eq!(Democracy::tally(r), (0, 10)); + assert_eq!(Democracy::vote_of((r, 1)), NAY); + assert_eq!(Democracy::tally(r), (0, 10, 10)); assert_eq!(Democracy::end_block(System::block_number()), Ok(())); @@ -563,16 +726,70 @@ mod tests { fn controversial_voting_should_work() { with_externalities(&mut new_test_ext(), || { System::set_block_number(1); - let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove).unwrap(); - assert_ok!(Democracy::vote(Origin::signed(1), r.into(), true)); - assert_ok!(Democracy::vote(Origin::signed(2), r.into(), false)); - assert_ok!(Democracy::vote(Origin::signed(3), r.into(), false)); - assert_ok!(Democracy::vote(Origin::signed(4), r.into(), true)); - assert_ok!(Democracy::vote(Origin::signed(5), r.into(), false)); - assert_ok!(Democracy::vote(Origin::signed(6), r.into(), true)); + let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove, 0).unwrap(); + assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); + assert_ok!(Democracy::vote(Origin::signed(2), r, NAY)); + assert_ok!(Democracy::vote(Origin::signed(3), r, NAY)); + assert_ok!(Democracy::vote(Origin::signed(4), r, AYE)); + assert_ok!(Democracy::vote(Origin::signed(5), r, NAY)); + assert_ok!(Democracy::vote(Origin::signed(6), r, AYE)); + + assert_eq!(Democracy::tally(r), (110, 100, 210)); + + assert_eq!(Democracy::end_block(System::block_number()), Ok(())); + + assert_eq!(Balances::free_balance(&42), 2); + }); + } + + #[test] + fn delayed_enactment_should_work() { + with_externalities(&mut new_test_ext(), || { + System::set_block_number(1); + let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove, 1).unwrap(); + assert_ok!(Democracy::vote(Origin::signed(1), r, AYE)); + assert_ok!(Democracy::vote(Origin::signed(2), r, AYE)); + assert_ok!(Democracy::vote(Origin::signed(3), r, AYE)); + assert_ok!(Democracy::vote(Origin::signed(4), r, AYE)); + assert_ok!(Democracy::vote(Origin::signed(5), r, AYE)); + assert_ok!(Democracy::vote(Origin::signed(6), r, AYE)); + + assert_eq!(Democracy::tally(r), (210, 0, 210)); + + assert_eq!(Democracy::end_block(System::block_number()), Ok(())); + assert_eq!(Balances::free_balance(&42), 0); + + System::set_block_number(2); + assert_eq!(Democracy::end_block(System::block_number()), Ok(())); + + assert_eq!(Balances::free_balance(&42), 2); + }); + } + + #[test] + fn lock_voting_should_work() { + with_externalities(&mut new_test_ext_with_public_delay(1), || { + System::set_block_number(1); + let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove, 0).unwrap(); + assert_ok!(Democracy::vote(Origin::signed(1), r, Vote::new(false, 6))); + assert_ok!(Democracy::vote(Origin::signed(2), r, Vote::new(true, 5))); + assert_ok!(Democracy::vote(Origin::signed(3), r, Vote::new(true, 4))); + assert_ok!(Democracy::vote(Origin::signed(4), r, Vote::new(true, 3))); + assert_ok!(Democracy::vote(Origin::signed(5), r, Vote::new(true, 2))); + assert_ok!(Democracy::vote(Origin::signed(6), r, Vote::new(false, 1))); + + assert_eq!(Democracy::tally(r), (440, 120, 210)); - assert_eq!(Democracy::tally(r), (110, 100)); + assert_eq!(Democracy::end_block(System::block_number()), Ok(())); + + assert_eq!(Democracy::bondage(1), 0); + assert_eq!(Democracy::bondage(2), 6); + assert_eq!(Democracy::bondage(3), 5); + assert_eq!(Democracy::bondage(4), 4); + assert_eq!(Democracy::bondage(5), 3); + assert_eq!(Democracy::bondage(6), 0); + System::set_block_number(2); assert_eq!(Democracy::end_block(System::block_number()), Ok(())); assert_eq!(Balances::free_balance(&42), 2); @@ -583,11 +800,11 @@ mod tests { fn controversial_low_turnout_voting_should_work() { with_externalities(&mut new_test_ext(), || { System::set_block_number(1); - let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove).unwrap(); - assert_ok!(Democracy::vote(Origin::signed(5), r.into(), false)); - assert_ok!(Democracy::vote(Origin::signed(6), r.into(), true)); + let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove, 0).unwrap(); + assert_ok!(Democracy::vote(Origin::signed(5), r, NAY)); + assert_ok!(Democracy::vote(Origin::signed(6), r, AYE)); - assert_eq!(Democracy::tally(r), (60, 50)); + assert_eq!(Democracy::tally(r), (60, 50, 110)); assert_eq!(Democracy::end_block(System::block_number()), Ok(())); @@ -602,12 +819,12 @@ mod tests { assert_eq!(Balances::total_issuance(), 210); System::set_block_number(1); - let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove).unwrap(); - assert_ok!(Democracy::vote(Origin::signed(4), r.into(), true)); - assert_ok!(Democracy::vote(Origin::signed(5), r.into(), false)); - assert_ok!(Democracy::vote(Origin::signed(6), r.into(), true)); + let r = Democracy::inject_referendum(1, set_balance_proposal(2), VoteThreshold::SuperMajorityApprove, 0).unwrap(); + assert_ok!(Democracy::vote(Origin::signed(4), r, AYE)); + assert_ok!(Democracy::vote(Origin::signed(5), r, NAY)); + assert_ok!(Democracy::vote(Origin::signed(6), r, AYE)); - assert_eq!(Democracy::tally(r), (100, 50)); + assert_eq!(Democracy::tally(r), (100, 50, 150)); assert_eq!(Democracy::end_block(System::block_number()), Ok(())); diff --git a/srml/democracy/src/vote_threshold.rs b/srml/democracy/src/vote_threshold.rs index 2882a984d5d9fe4e19bad9d5e793f4547da1c94c..ab5e1ddee7eb47660b626acd376d13fee6dcccd8 100644 --- a/srml/democracy/src/vote_threshold.rs +++ b/srml/democracy/src/vote_threshold.rs @@ -35,7 +35,7 @@ pub trait Approved { /// Given `approve` votes for and `against` votes against from a total electorate size of /// `electorate` (`electorate - (approve + against)` are abstainers), then returns true if the /// overall outcome is in favour of approval. - fn approved(&self, approve: Balance, against: Balance, electorate: Balance) -> bool; + fn approved(&self, approve: Balance, against: Balance, voters: Balance, electorate: Balance) -> bool; } /// Return `true` iff `n1 / d1 < n2 / d2`. `d1` and `d2` may not be zero. @@ -68,10 +68,12 @@ fn compare_rationals + Div + Rem + Mul + Div + Rem + Copy> Approved for VoteThreshold { /// Given `approve` votes for and `against` votes against from a total electorate size of - /// `electorate` (`electorate - (approve + against)` are abstainers), then returns true if the + /// `electorate` of whom `voters` voted (`electorate - voters` are abstainers) then returns true if the /// overall outcome is in favour of approval. - fn approved(&self, approve: Balance, against: Balance, electorate: Balance) -> bool { - let voters = approve + against; + /// + /// We assume each *voter* may cast more than one *vote*, hence `voters` is not necessarily equal to + /// `approve + against`. + fn approved(&self, approve: Balance, against: Balance, voters: Balance, electorate: Balance) -> bool { let sqrt_voters = voters.integer_sqrt(); let sqrt_electorate = electorate.integer_sqrt(); if sqrt_voters.is_zero() { return false; } @@ -91,7 +93,7 @@ mod tests { #[test] fn should_work() { - assert_eq!(VoteThreshold::SuperMajorityApprove.approved(60, 50, 210), false); - assert_eq!(VoteThreshold::SuperMajorityApprove.approved(100, 50, 210), true); + assert_eq!(VoteThreshold::SuperMajorityApprove.approved(60, 50, 110, 210), false); + assert_eq!(VoteThreshold::SuperMajorityApprove.approved(100, 50, 150, 210), true); } } diff --git a/srml/example/Cargo.toml b/srml/example/Cargo.toml index 34d8d058d114146aba39cff2789b059c6bffffc8..cbddf95d115fb27cf725de29eb17a759e255f44d 100644 --- a/srml/example/Cargo.toml +++ b/srml/example/Cargo.toml @@ -6,8 +6,7 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } @@ -21,7 +20,6 @@ srml-balances = { path = "../balances", default-features = false } default = ["std"] std = [ "serde/std", - "serde_derive", "parity-codec/std", "parity-codec-derive/std", "sr-std/std", diff --git a/srml/example/src/lib.rs b/srml/example/src/lib.rs index 4c2708e953da409a9b5d465d266f9375b22ad3a3..45c33c993ff2ef6ab4c3aafbab6cbc6648da48a9 100644 --- a/srml/example/src/lib.rs +++ b/srml/example/src/lib.rs @@ -34,13 +34,6 @@ extern crate substrate_primitives; // Needed for various traits. In our case, `OnFinalise`. extern crate sr_primitives; -// Needed for deriving `Serialize` and `Deserialize` for various types. -// We only implement the serde traits for std builds - they're unneeded -// in the wasm runtime. -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - // Needed for deriving `Encode` and `Decode` for `RawEvent`. #[macro_use] extern crate parity_codec_derive; @@ -105,7 +98,9 @@ decl_module! { pub struct Module for enum Call where origin: T::Origin { /// Deposit one of this module's events by using the default implementation. /// It is also possible to provide a custom implementation. - fn deposit_event() = default; + /// For non-generic events, the generic parameter just needs to be dropped, so that it + /// looks like: `fn deposit_event() = default;`. + fn deposit_event() = default; /// This is your public interface. Be extremely careful. /// This is just a simple example of how to interact with the module from the external /// world. @@ -180,12 +175,11 @@ decl_module! { // calls to be executed - we don't need to care why. Because it's privileged, we can // assume it's a one-off operation and substantial processing/storage/memory can be used // without worrying about gameability or attack scenarios. - fn set_dummy(new_value: T::Balance) -> Result { + // If you not specify `Result` explicitly as return value, it will be added automatically + // for you and `Ok(())` will be returned. + fn set_dummy(#[compact] new_value: T::Balance) { // Put the new value into storage. >::put(new_value); - - // All good. - Ok(()) } // The signature could also look like: `fn on_finalise()` @@ -275,7 +269,7 @@ mod tests { // 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 requried. use sr_primitives::{ - BuildStorage, traits::{BlakeTwo256, OnFinalise}, testing::{Digest, DigestItem, Header} + BuildStorage, traits::{BlakeTwo256, OnFinalise, IdentityLookup}, testing::{Digest, DigestItem, Header} }; impl_outer_origin! { @@ -295,14 +289,15 @@ mod tests { type Hashing = BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = (); type Log = DigestItem; } impl balances::Trait for Test { type Balance = u64; - type AccountIndex = u64; type OnFreeBalanceZero = (); + type OnNewAccount = (); type EnsureAccountLiquid = (); type Event = (); } diff --git a/srml/executive/Cargo.toml b/srml/executive/Cargo.toml index 33cd0432e096e2b31bd19bb746c137276c457078..b89cf54a069a9dd57a7622c497ae3753e6e93cd2 100644 --- a/srml/executive/Cargo.toml +++ b/srml/executive/Cargo.toml @@ -6,8 +6,7 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } sr-io = { path = "../../core/sr-io", default-features = false } @@ -17,6 +16,7 @@ srml-system = { path = "../system", default-features = false } [dev-dependencies] substrate-primitives = { path = "../../core/primitives" } +srml-indices = { path = "../indices" } srml-balances = { path = "../balances" } [features] @@ -25,7 +25,6 @@ std = [ "sr-std/std", "srml-support/std", "serde/std", - "serde_derive", "parity-codec/std", "parity-codec-derive/std", "sr-primitives/std", diff --git a/srml/executive/src/lib.rs b/srml/executive/src/lib.rs index ea83267c9119bed0c62da9f767b05636eebddb85..38d6ba47277998f54510922ce418df10a2360ef7 100644 --- a/srml/executive/src/lib.rs +++ b/srml/executive/src/lib.rs @@ -18,10 +18,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(test)] -#[macro_use] -extern crate serde_derive; - #[cfg(test)] #[macro_use] extern crate parity_codec_derive; @@ -279,7 +275,7 @@ mod tests { use runtime_io::with_externalities; use substrate_primitives::{H256, Blake2Hasher}; use primitives::BuildStorage; - use primitives::traits::{Header as HeaderT, BlakeTwo256}; + use primitives::traits::{Header as HeaderT, BlakeTwo256, IdentityLookup}; use primitives::testing::{Digest, DigestItem, Header, Block}; use system; @@ -295,7 +291,7 @@ mod tests { } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] + #[derive(Clone, Eq, PartialEq)] pub struct Runtime; impl system::Trait for Runtime { type Origin = Origin; @@ -305,20 +301,21 @@ mod tests { type Hashing = BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = MetaEvent; type Log = DigestItem; } impl balances::Trait for Runtime { type Balance = u64; - type AccountIndex = u64; type OnFreeBalanceZero = (); + type OnNewAccount = (); type EnsureAccountLiquid = (); type Event = MetaEvent; } type TestXt = primitives::testing::TestXt>; - type Executive = super::Executive, balances::ChainContext, balances::Module, ()>; + type Executive = super::Executive, system::ChainContext, balances::Module, ()>; #[test] fn balance_transfer_dispatch_works() { @@ -330,9 +327,8 @@ mod tests { existential_deposit: 0, transfer_fee: 0, creation_fee: 0, - reclaim_rebate: 0, }.build_storage().unwrap().0); - let xt = primitives::testing::TestXt(Some(1), 0, Call::transfer(2.into(), 69.into())); + let xt = primitives::testing::TestXt(Some(1), 0, Call::transfer(2, 69)); let mut t = runtime_io::TestExternalities::::new(t); with_externalities(&mut t, || { Executive::initialise_block(&Header::new(1, H256::default(), H256::default(), @@ -356,7 +352,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("d9e26179ed13b3df01e71ad0bf622d56f2066a63e04762a83c0ae9deeb4da1d0").into(), + state_root: hex!("49cd58a254ccf6abc4a023d9a22dcfc421e385527a250faec69f8ad0d8ed3e48").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, @@ -390,7 +386,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("d9e26179ed13b3df01e71ad0bf622d56f2066a63e04762a83c0ae9deeb4da1d0").into(), + state_root: hex!("49cd58a254ccf6abc4a023d9a22dcfc421e385527a250faec69f8ad0d8ed3e48").into(), extrinsics_root: [0u8; 32].into(), digest: Digest { logs: vec![], }, }, @@ -402,7 +398,7 @@ mod tests { #[test] fn bad_extrinsic_not_inserted() { let mut t = new_test_ext(); - let xt = primitives::testing::TestXt(Some(1), 42, Call::transfer(33.into(), 69.into())); + let xt = primitives::testing::TestXt(Some(1), 42, Call::transfer(33, 69)); with_externalities(&mut t, || { Executive::initialise_block(&Header::new(1, H256::default(), H256::default(), [69u8; 32].into(), Digest::default())); assert!(Executive::apply_extrinsic(xt).is_err()); diff --git a/srml/grandpa/Cargo.toml b/srml/grandpa/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..3dd301676b8456f0fff56a043981530aae153378 --- /dev/null +++ b/srml/grandpa/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "srml-grandpa" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +hex-literal = "0.1.0" +serde = { version = "1.0", default-features = false } +serde_derive = { version = "1.0", optional = true } +parity-codec = { version = "2.2", default-features = false } +parity-codec-derive = { version = "2.1", default-features = false } +substrate-primitives = { path = "../../core/primitives", default-features = false } +substrate-finality-grandpa-primitives = { path = "../../core/finality-grandpa/primitives", default-features = false } +sr-std = { path = "../../core/sr-std", default-features = false } +sr-io = { path = "../../core/sr-io", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +srml-support = { path = "../support", default-features = false } +srml-system = { path = "../system", default-features = false } +srml-session = { path = "../session", default-features = false } + +[features] +default = ["std"] +std = [ + "serde/std", + "serde_derive", + "parity-codec/std", + "substrate-primitives/std", + "substrate-finality-grandpa-primitives/std", + "sr-std/std", + "sr-io/std", + "srml-support/std", + "sr-primitives/std", + "srml-system/std", + "srml-session/std", +] diff --git a/srml/grandpa/src/lib.rs b/srml/grandpa/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..1a0d0f7c31dea122179497f4f17fb75e50df236f --- /dev/null +++ b/srml/grandpa/src/lib.rs @@ -0,0 +1,292 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! 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. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[allow(unused_imports)] +#[macro_use] +extern crate sr_std as rstd; + +#[macro_use] +extern crate srml_support as runtime_support; + +#[cfg(feature = "std")] +#[macro_use] +extern crate serde_derive; + +extern crate parity_codec; +#[macro_use] +extern crate parity_codec_derive; + +extern crate sr_primitives as primitives; +extern crate parity_codec as codec; +extern crate srml_system as system; +extern crate srml_session as session; +extern crate substrate_primitives; + +#[cfg(test)] +extern crate sr_io as runtime_io; + +// re-export since this is necessary for `impl_apis` in runtime. +pub extern crate substrate_finality_grandpa_primitives as fg_primitives; + +use rstd::prelude::*; +use fg_primitives::ScheduledChange; +use runtime_support::Parameter; +use runtime_support::dispatch::Result; +use runtime_support::storage::StorageValue; +use runtime_support::storage::unhashed::StorageVec; +use primitives::traits::{CurrentHeight, Convert}; +use substrate_primitives::Ed25519AuthorityId; +use system::ensure_signed; +use primitives::traits::MaybeSerializeDebug; + +mod mock; +mod tests; + +struct AuthorityStorageVec(rstd::marker::PhantomData); +impl StorageVec for AuthorityStorageVec { + type Item = (S, u64); + const PREFIX: &'static [u8] = ::fg_primitives::well_known_keys::AUTHORITY_PREFIX; +} + +/// The log type of this crate, projected from module trait type. +pub type Log = RawLog< + ::BlockNumber, + ::SessionKey, +>; + +/// Logs which can be scanned by GRANDPA for authorities change events. +pub trait GrandpaChangeSignal { + /// Try to cast the log entry as a contained signal. + fn as_signal(&self) -> Option>; +} + +/// A logs in this module. +#[cfg_attr(feature = "std", derive(Serialize, Debug))] +#[derive(Encode, Decode, PartialEq, Eq, Clone)] +pub enum RawLog { + /// Authorities set change has been signalled. Contains the new set of authorities + /// and the delay in blocks before applying. + AuthoritiesChangeSignal(N, Vec<(SessionKey, u64)>), +} + +impl RawLog { + /// Try to cast the log entry as a contained signal. + pub fn as_signal(&self) -> Option<(N, &[(SessionKey, u64)])> { + match *self { + RawLog::AuthoritiesChangeSignal(ref n, ref signal) => Some((n.clone(), signal)), + } + } +} + +impl GrandpaChangeSignal for RawLog + where N: Clone, SessionKey: Clone + Into, +{ + fn as_signal(&self) -> Option> { + RawLog::as_signal(self).map(|(delay, next_authorities)| ScheduledChange { + delay, + next_authorities: next_authorities.iter() + .cloned() + .map(|(k, w)| (k.into(), w)) + .collect(), + }) + } +} + +pub trait Trait: system::Trait { + /// Type for all log entries of this module. + type Log: From> + Into>; + + /// The session key type used by authorities. + type SessionKey: Parameter + Default + MaybeSerializeDebug; + + /// The event type of this module. + type Event: From> + Into<::Event>; +} + +/// A stored pending change. +#[derive(Encode, Decode)] +pub struct StoredPendingChange { + /// The block number this was scheduled at. + pub scheduled_at: N, + /// The delay in blocks until it will be applied. + pub delay: N, + /// The next authority set. + pub next_authorities: Vec<(SessionKey, u64)>, +} + +/// GRANDPA events. +decl_event!( + pub enum Event where ::SessionKey { + /// New authority set has been applied. + NewAuthorities(Vec<(SessionKey, u64)>), + } +); + +decl_storage! { + trait Store for Module as GrandpaFinality { + // Pending change: (signalled at, scheduled change). + PendingChange get(pending_change): Option>; + } + add_extra_genesis { + config(authorities): Vec<(T::SessionKey, u64)>; + + build(|storage: &mut primitives::StorageMap, _: &mut primitives::ChildrenStorageMap, config: &GenesisConfig| { + use codec::{Encode, KeyedVec}; + + let auth_count = config.authorities.len() as u32; + config.authorities.iter().enumerate().for_each(|(i, v)| { + storage.insert((i as u32).to_keyed_vec( + ::fg_primitives::well_known_keys::AUTHORITY_PREFIX), + v.encode() + ); + }); + storage.insert( + ::fg_primitives::well_known_keys::AUTHORITY_COUNT.to_vec(), + auth_count.encode(), + ); + }); + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + fn deposit_event() = default; + + /// Report some misbehaviour. + fn report_misbehavior(origin, _report: Vec) { + ensure_signed(origin)?; + // TODO: https://github.com/paritytech/substrate/issues/1112 + } + + fn on_finalise(block_number: T::BlockNumber) { + if let Some(pending_change) = >::get() { + if block_number == pending_change.scheduled_at { + Self::deposit_log(RawLog::AuthoritiesChangeSignal( + pending_change.delay, + pending_change.next_authorities.clone(), + )); + } + + if block_number == pending_change.scheduled_at + pending_change.delay { + Self::deposit_event( + RawEvent::NewAuthorities(pending_change.next_authorities.clone()) + ); + >::set_items(pending_change.next_authorities); + >::kill(); + } + } + } + } +} + +impl Module { + /// Get the current set of authorities, along with their respective weights. + pub fn grandpa_authorities() -> Vec<(T::SessionKey, u64)> { + >::items() + } + + /// Schedule a change in the authorities. + /// + /// The change will be applied at the end of execution of the block + /// `in_blocks` after the current block. This value may be 0, in which + /// case the change is applied at the end of the current block. + /// + /// No change should be signalled while any change is pending. Returns + /// an error if a change is already pending. + pub fn schedule_change( + next_authorities: Vec<(T::SessionKey, u64)>, + in_blocks: T::BlockNumber, + ) -> Result { + if Self::pending_change().is_none() { + let scheduled_at = system::ChainContext::::default().current_height(); + >::put(StoredPendingChange { + delay: in_blocks, + scheduled_at, + next_authorities, + }); + + Ok(()) + } else { + Err("Attempt to signal GRANDPA change with one already pending.") + } + } + + /// Deposit one of this module's logs. + fn deposit_log(log: Log) { + >::deposit_log(::Log::from(log).into()); + } +} + +impl Module where Ed25519AuthorityId: core::convert::From<::SessionKey> { + /// See if the digest contains any scheduled change. + pub fn scrape_digest_change(log: &Log) + -> Option> + { + as GrandpaChangeSignal>::as_signal(log) + } +} + +/// Helper for authorities being synchronized with the general session authorities. +/// +/// This is not the only way to manage an authority set for GRANDPA, but it is +/// a convenient one. When this is used, no other mechanism for altering authority +/// sets should be. +pub struct SyncedAuthorities(::rstd::marker::PhantomData); + +// TODO: remove when https://github.com/rust-lang/rust/issues/26925 is fixed +impl Default for SyncedAuthorities { + fn default() -> Self { + SyncedAuthorities(::rstd::marker::PhantomData) + } +} + +impl session::OnSessionChange for SyncedAuthorities where + T: Trait, + T: session::Trait, + ::ConvertAccountIdToSessionKey: Convert< + ::AccountId, + ::SessionKey, + >, +{ + fn on_session_change(_: X, _: bool) { + use primitives::traits::Zero; + + let next_authorities = >::validators() + .into_iter() + .map(T::ConvertAccountIdToSessionKey::convert) + .map(|key| (key, 1)) // evenly-weighted. + .collect::::SessionKey, u64)>>(); + + // instant changes + let last_authorities = >::grandpa_authorities(); + if next_authorities != last_authorities { + let _ = >::schedule_change(next_authorities, Zero::zero()); + } + } +} diff --git a/srml/grandpa/src/mock.rs b/srml/grandpa/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..380133ae80819e14e514506dd1b28a8416521ab7 --- /dev/null +++ b/srml/grandpa/src/mock.rs @@ -0,0 +1,79 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Test utilities + +#![cfg(test)] + +use primitives::{BuildStorage, traits::IdentityLookup, testing::{Digest, DigestItem, Header}}; +use primitives::generic::DigestItem as GenDigestItem; +use runtime_io; +use substrate_primitives::{H256, Blake2Hasher}; +use parity_codec::Encode; +use {system, GenesisConfig, Trait, Module, RawLog}; + +impl_outer_origin!{ + pub enum Origin for Test {} +} + +impl From> for DigestItem { + fn from(log: RawLog) -> DigestItem { + GenDigestItem::Other(log.encode()) + } +} + +// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. +#[derive(Clone, PartialEq, Eq, Debug, Decode, Encode)] +pub struct Test; +impl Trait for Test { + type Log = DigestItem; + type SessionKey = u64; + type Event = TestEvent; +} +impl system::Trait for Test { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = ::primitives::traits::BlakeTwo256; + type Digest = Digest; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = TestEvent; + type Log = DigestItem; +} + +mod grandpa { + pub use ::Event; +} + +impl_outer_event!{ + pub enum TestEvent for Test { + grandpa, + } +} + +pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternalities { + let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + t.extend(GenesisConfig:: { + authorities, + }.build_storage().unwrap().0); + t.into() +} + +pub type System = system::Module; +pub type Grandpa = Module; diff --git a/srml/grandpa/src/tests.rs b/srml/grandpa/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..4d8694b2a556fb7fd476f6c4873d55646716b04d --- /dev/null +++ b/srml/grandpa/src/tests.rs @@ -0,0 +1,108 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Tests for the module. + +#![cfg(test)] + +use primitives::{testing, traits::OnFinalise}; +use primitives::traits::Header; +use runtime_io::with_externalities; +use mock::{Grandpa, System, new_test_ext}; +use system::{EventRecord, Phase}; +use {RawLog, RawEvent}; + +#[test] +fn authorities_change_logged() { + with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + System::initialise(&1, &Default::default(), &Default::default()); + Grandpa::schedule_change(vec![(4, 1), (5, 1), (6, 1)], 0).unwrap(); + + System::note_finished_extrinsics(); + Grandpa::on_finalise(1); + + let header = System::finalise(); + assert_eq!(header.digest, testing::Digest { + logs: vec![ + RawLog::AuthoritiesChangeSignal(0, vec![(4, 1), (5, 1), (6, 1)]).into(), + ], + }); + + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::Finalization, + event: RawEvent::NewAuthorities(vec![(4, 1), (5, 1), (6, 1)]).into(), + }, + ]); + }); +} + +#[test] +fn authorities_change_logged_after_delay() { + with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + System::initialise(&1, &Default::default(), &Default::default()); + Grandpa::schedule_change(vec![(4, 1), (5, 1), (6, 1)], 1).unwrap(); + Grandpa::on_finalise(1); + let header = System::finalise(); + assert_eq!(header.digest, testing::Digest { + logs: vec![ + RawLog::AuthoritiesChangeSignal(1, vec![(4, 1), (5, 1), (6, 1)]).into(), + ], + }); + + // no change at this height. + assert_eq!(System::events(), vec![]); + + System::initialise(&2, &header.hash(), &Default::default()); + System::note_finished_extrinsics(); + Grandpa::on_finalise(2); + + let _header = System::finalise(); + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::Finalization, + event: RawEvent::NewAuthorities(vec![(4, 1), (5, 1), (6, 1)]).into(), + }, + ]); + }); +} + +#[test] +fn cannot_schedule_change_when_one_pending() { + with_externalities(&mut new_test_ext(vec![(1, 1), (2, 1), (3, 1)]), || { + System::initialise(&1, &Default::default(), &Default::default()); + Grandpa::schedule_change(vec![(4, 1), (5, 1), (6, 1)], 1).unwrap(); + assert!(Grandpa::pending_change().is_some()); + assert!(Grandpa::schedule_change(vec![(5, 1)], 1).is_err()); + + Grandpa::on_finalise(1); + let header = System::finalise(); + + System::initialise(&2, &header.hash(), &Default::default()); + assert!(Grandpa::pending_change().is_some()); + assert!(Grandpa::schedule_change(vec![(5, 1)], 1).is_err()); + + Grandpa::on_finalise(2); + let header = System::finalise(); + + System::initialise(&3, &header.hash(), &Default::default()); + assert!(Grandpa::pending_change().is_none()); + assert!(Grandpa::schedule_change(vec![(5, 1)], 1).is_ok()); + + Grandpa::on_finalise(3); + let _header = System::finalise(); + }); +} diff --git a/srml/indices/Cargo.toml b/srml/indices/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..6e51f6999fb8c4a6a8636429758bf0045e94a5b7 --- /dev/null +++ b/srml/indices/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "srml-indices" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +hex-literal = "0.1.0" +serde = { version = "1.0", default-features = false } +safe-mix = { version = "1.0", default-features = false} +parity-codec = { version = "2.1", default-features = false } +parity-codec-derive = { version = "2.1", default-features = false } +substrate-keyring = { path = "../../core/keyring", optional = true } +substrate-primitives = { path = "../../core/primitives", default-features = false } +sr-std = { path = "../../core/sr-std", default-features = false } +sr-io = { path = "../../core/sr-io", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +srml-support = { path = "../support", default-features = false } +srml-system = { path = "../system", default-features = false } + +[dev-dependencies] +ref_thread_local = "0.0" + +[features] +default = ["std"] +std = [ + "serde/std", + "safe-mix/std", + "substrate-keyring", + "parity-codec/std", + "parity-codec-derive/std", + "substrate-primitives/std", + "sr-std/std", + "sr-io/std", + "srml-support/std", + "sr-primitives/std", + "srml-system/std", +] diff --git a/srml/balances/src/address.rs b/srml/indices/src/address.rs similarity index 93% rename from srml/balances/src/address.rs rename to srml/indices/src/address.rs index 2cd545d0d177cfaa5eacc31ee5f32f6c891320db..ccaa6b46a5db8ae63f5e523f885ff545093dcda4 100644 --- a/srml/balances/src/address.rs +++ b/srml/indices/src/address.rs @@ -22,16 +22,14 @@ use super::{Member, Decode, Encode, As, Input, Output}; /// A vetted and verified extrinsic from the external world. #[derive(PartialEq, Eq, Clone)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash))] +#[cfg_attr(feature = "std", derive(Debug, Hash))] pub enum Address where AccountId: Member, AccountIndex: Member, { /// It's an account ID (pubkey). - #[cfg_attr(feature = "std", serde(deserialize_with="AccountId::deserialize"))] Id(AccountId), /// It's an account index. - #[cfg_attr(feature = "std", serde(deserialize_with="AccountIndex::deserialize"))] Index(AccountIndex), } diff --git a/srml/indices/src/lib.rs b/srml/indices/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..3aff9a555f0cb123bf62348a1fc6cf96ef7fcc61 --- /dev/null +++ b/srml/indices/src/lib.rs @@ -0,0 +1,222 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Balances: Handles setting and retrieval of free balance, +//! retrieving total balance, reserve and unreserve balance, +//! repatriating a reserved balance to a beneficiary account that exists, +//! transfering a balance between accounts (when not reserved), +//! slashing an account balance, account removal, rewards, +//! lookup of an index to reclaim an account (when not balance not reserved), +//! increasing total stake. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[macro_use] +extern crate srml_support as runtime_support; + +extern crate sr_std as rstd; + +#[macro_use] +extern crate parity_codec_derive; + +extern crate parity_codec as codec; +extern crate sr_primitives as primitives; +extern crate srml_system as system; + +#[cfg(test)] +#[macro_use] +extern crate ref_thread_local; +#[cfg(test)] +extern crate sr_io as runtime_io; +#[cfg(test)] +extern crate substrate_primitives; + +use rstd::{prelude::*, result, marker::PhantomData}; +use codec::{Encode, Decode, Codec, Input, Output}; +use runtime_support::{StorageValue, StorageMap, Parameter}; +use primitives::traits::{One, SimpleArithmetic, As, StaticLookup, Member}; +use address::Address as RawAddress; +use system::{IsDeadAccount, OnNewAccount}; + +mod mock; + +pub mod address; +mod tests; + +/// Number of account IDs stored per enum set. +const ENUM_SET_SIZE: usize = 64; + +pub type Address = RawAddress<::AccountId, ::AccountIndex>; + +/// Turn an Id into an Index, or None for the purpose of getting +/// a hint at a possibly desired index. +pub trait ResolveHint> { + /// Turn an Id into an Index, or None for the purpose of getting + /// a hint at a possibly desired index. + fn resolve_hint(who: &AccountId) -> Option; +} + +/// Simple encode-based resolve hint implemenntation. +pub struct SimpleResolveHint(PhantomData<(AccountId, AccountIndex)>); +impl> ResolveHint for SimpleResolveHint { + fn resolve_hint(who: &AccountId) -> Option { + Some(AccountIndex::sa(who.using_encoded(|e| e[0] as usize + e[1] as usize * 256))) + } +} + +/// The module's config trait. +pub trait Trait: system::Trait { + /// Type used for storing an account's index; implies the maximum number of accounts the system + /// can hold. + type AccountIndex: Parameter + Member + Codec + Default + SimpleArithmetic + As + As + As + As + As + Copy; + + /// Whether an account is dead or not. + type IsDeadAccount: IsDeadAccount; + + /// How to turn an id into an index. + type ResolveHint: ResolveHint; + + /// The overarching event type. + type Event: From> + Into<::Event>; +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + fn deposit_event() = default; + } +} + +decl_event!( + pub enum Event where + ::AccountId, + ::AccountIndex + { + /// A new account was created. + NewAccountIndex(AccountId, AccountIndex), + } +); + +decl_storage! { + trait Store for Module as Indices { + /// The next free enumeration set. + pub NextEnumSet get(next_enum_set) build(|config: &GenesisConfig| { + T::AccountIndex::sa(config.ids.len() / ENUM_SET_SIZE) + }): T::AccountIndex; + + /// The enumeration sets. + pub EnumSet get(enum_set): map T::AccountIndex => Vec; + } + add_extra_genesis { + config(ids): Vec; + build(|storage: &mut primitives::StorageMap, _: &mut primitives::ChildrenStorageMap, config: &GenesisConfig| { + for i in 0..(config.ids.len() + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE { + storage.insert(GenesisConfig::::hash(&>::key_for(T::AccountIndex::sa(i))).to_vec(), + config.ids[i * ENUM_SET_SIZE..config.ids.len().min((i + 1) * ENUM_SET_SIZE)].to_owned().encode()); + } + }); + } +} + +impl Module { + // PUBLIC IMMUTABLES + + /// Lookup an T::AccountIndex to get an Id, if there's one there. + pub fn lookup_index(index: T::AccountIndex) -> Option { + let enum_set_size = Self::enum_set_size(); + let set = Self::enum_set(index / enum_set_size); + let i: usize = (index % enum_set_size).as_(); + set.get(i).map(|x| x.clone()) + } + + /// `true` if the account `index` is ready for reclaim. + pub fn can_reclaim(try_index: T::AccountIndex) -> bool { + let enum_set_size = Self::enum_set_size(); + let try_set = Self::enum_set(try_index / enum_set_size); + let i = (try_index % enum_set_size).as_(); + i < try_set.len() && T::IsDeadAccount::is_dead_account(&try_set[i]) + } + + /// Lookup an address to get an Id, if there's one there. + pub fn lookup_address(a: address::Address) -> Option { + match a { + address::Address::Id(i) => Some(i), + address::Address::Index(i) => Self::lookup_index(i), + } + } + + // PUBLIC MUTABLES (DANGEROUS) + + fn enum_set_size() -> T::AccountIndex { + T::AccountIndex::sa(ENUM_SET_SIZE) + } +} + +impl OnNewAccount for Module { + fn on_new_account(who: &T::AccountId) { + let enum_set_size = Self::enum_set_size(); + let next_set_index = Self::next_enum_set(); + + if let Some(try_index) = T::ResolveHint::resolve_hint(who) { + // then check to see if this account id identifies a dead account index. + let set_index = try_index / enum_set_size; + let mut try_set = Self::enum_set(set_index); + let item_index = (try_index % enum_set_size).as_(); + if item_index < try_set.len() { + if T::IsDeadAccount::is_dead_account(&try_set[item_index]) { + // yup - this index refers to a dead account. can be reused. + try_set[item_index] = who.clone(); + >::insert(set_index, try_set); + + return + } + } + } + + // insert normally as a back up + let mut set_index = next_set_index; + // defensive only: this loop should never iterate since we keep NextEnumSet up to date later. + let mut set = loop { + let set = Self::enum_set(set_index); + if set.len() < ENUM_SET_SIZE { + break set; + } + set_index += One::one(); + }; + + let index = T::AccountIndex::sa(set_index.as_() * ENUM_SET_SIZE + set.len()); + + // update set. + set.push(who.clone()); + + // keep NextEnumSet up to date + if set.len() == ENUM_SET_SIZE { + >::put(set_index + One::one()); + } + + // write set. + >::insert(set_index, set); + + Self::deposit_event(RawEvent::NewAccountIndex(who.clone(), index)); + } +} + +impl StaticLookup for Module { + type Source = address::Address; + type Target = T::AccountId; + fn lookup(a: Self::Source) -> result::Result { + Self::lookup_address(a).ok_or("invalid account index") + } +} diff --git a/srml/indices/src/mock.rs b/srml/indices/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..8c8305fef8ad44f8081fbf294a9064b6ac21adcb --- /dev/null +++ b/srml/indices/src/mock.rs @@ -0,0 +1,102 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Test utilities + +#![cfg(test)] + +use std::collections::HashSet; +use ref_thread_local::RefThreadLocal; +use primitives::BuildStorage; +use primitives::testing::{Digest, DigestItem, Header}; +use substrate_primitives::{H256, Blake2Hasher}; +use runtime_io; +use {GenesisConfig, Module, Trait, system}; +use super::{IsDeadAccount, OnNewAccount, ResolveHint}; + +impl_outer_origin!{ + pub enum Origin for Runtime {} +} + +ref_thread_local! { + static managed ALIVE: HashSet = HashSet::new(); +} + +pub fn make_account(who: u64) { + ALIVE.borrow_mut().insert(who); + Indices::on_new_account(&who); +} + +pub fn kill_account(who: u64) { + ALIVE.borrow_mut().remove(&who); +} + +pub struct TestIsDeadAccount {} +impl IsDeadAccount for TestIsDeadAccount { + fn is_dead_account(who: &u64) -> bool { + !ALIVE.borrow_mut().contains(who) + } +} + +pub struct TestResolveHint; +impl ResolveHint for TestResolveHint { + fn resolve_hint(who: &u64) -> Option { + if *who < 256 { + None + } else { + Some(*who - 256) + } + } +} + +// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Runtime; +impl system::Trait for Runtime { + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = ::primitives::traits::BlakeTwo256; + type Digest = Digest; + type AccountId = u64; + type Lookup = Indices; + type Header = Header; + type Event = (); + type Log = DigestItem; +} +impl Trait for Runtime { + type AccountIndex = u64; + type IsDeadAccount = TestIsDeadAccount; + type ResolveHint = TestResolveHint; + type Event = (); +} + +pub fn new_test_ext() -> runtime_io::TestExternalities { + { + let mut h = ALIVE.borrow_mut(); + h.clear(); + for i in 1..5 { h.insert(i); } + } + + let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; + t.extend(GenesisConfig:: { + ids: vec![1, 2, 3, 4] + }.build_storage().unwrap().0); + t.into() +} + +pub type Indices = Module; diff --git a/srml/indices/src/tests.rs b/srml/indices/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..f16a93470d172d93b9b0e0e0b204e316456e2422 --- /dev/null +++ b/srml/indices/src/tests.rs @@ -0,0 +1,80 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Tests for the module. + +#![cfg(test)] + +use super::*; +use mock::{Indices, new_test_ext, make_account, kill_account, TestIsDeadAccount}; +use runtime_io::with_externalities; + +#[test] +fn indexing_lookup_should_work() { + with_externalities( + &mut new_test_ext(), + || { + assert_eq!(Indices::lookup_index(0), Some(1)); + assert_eq!(Indices::lookup_index(1), Some(2)); + assert_eq!(Indices::lookup_index(2), Some(3)); + assert_eq!(Indices::lookup_index(3), Some(4)); + assert_eq!(Indices::lookup_index(4), None); + }, + ); +} + +#[test] +fn default_indexing_on_new_accounts_should_work() { + with_externalities( + &mut new_test_ext(), + || { + assert_eq!(Indices::lookup_index(4), None); + make_account(5); + assert_eq!(Indices::lookup_index(4), Some(5)); + }, + ); +} + +#[test] +fn reclaim_indexing_on_new_accounts_should_work() { + with_externalities( + &mut new_test_ext(), + || { + assert_eq!(Indices::lookup_index(1), Some(2)); + assert_eq!(Indices::lookup_index(4), None); + + kill_account(2); // index 1 no longer locked to id 2 + + make_account(1 + 256); // id 257 takes index 1. + assert_eq!(Indices::lookup_index(1), Some(257)); + }, + ); +} + +#[test] +fn alive_account_should_prevent_reclaim() { + with_externalities( + &mut new_test_ext(), + || { + assert!(!TestIsDeadAccount::is_dead_account(&2)); + assert_eq!(Indices::lookup_index(1), Some(2)); + assert_eq!(Indices::lookup_index(4), None); + + make_account(1 + 256); // id 257 takes index 1. + assert_eq!(Indices::lookup_index(4), Some(257)); + }, + ); +} diff --git a/srml/metadata/Cargo.toml b/srml/metadata/Cargo.toml index 2e113ab6f06d597a2669850eea2f17677a3bc708..e0d4e4b09f3f9188def355b76e35dc2a93d1d43c 100644 --- a/srml/metadata/Cargo.toml +++ b/srml/metadata/Cargo.toml @@ -1,19 +1,23 @@ [package] -name = "substrate-metadata" +name = "srml-metadata" version = "0.1.0" authors = ["Parity Technologies "] [dependencies] -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } serde = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true } +sr-std = { path = "../../core/sr-std", default-features = false } +substrate-primitives = { path = "../../core/primitives", default-features = false } [features] default = ["std"] std = [ "parity-codec/std", "parity-codec-derive/std", + "sr-std/std", + "substrate-primitives/std", "serde", "serde_derive" ] diff --git a/srml/metadata/README.adoc b/srml/metadata/README.adoc deleted file mode 100644 index 8f4939087eed771df9b3d360fe47af12d2a91919..0000000000000000000000000000000000000000 --- a/srml/metadata/README.adoc +++ /dev/null @@ -1,13 +0,0 @@ - -= Substrate BFT - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- diff --git a/srml/metadata/src/lib.rs b/srml/metadata/src/lib.rs index ea722a705e4768218411844279b6d994419e7c1f..fc31fddbc9e20bcde4098819d6641d265e3a5eb1 100644 --- a/srml/metadata/src/lib.rs +++ b/srml/metadata/src/lib.rs @@ -21,14 +21,12 @@ //! codec-encoded metadata. #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(not(feature = "std"), feature(alloc))] - -#[cfg(not(feature = "std"))] -extern crate alloc; #[macro_use] extern crate parity_codec_derive; extern crate parity_codec as codec; +extern crate sr_std as rstd; +extern crate substrate_primitives as primitives; #[cfg(feature = "std")] extern crate serde; @@ -36,17 +34,10 @@ extern crate serde; #[macro_use] extern crate serde_derive; -#[cfg(feature = "std")] -pub mod alloc { - pub use std::vec; -} - use codec::{Encode, Output}; #[cfg(feature = "std")] use codec::{Decode, Input}; - -// Make Vec available on `std` and `no_std` -use alloc::vec::Vec; +use rstd::vec::Vec; #[cfg(feature = "std")] type StringBuf = String; @@ -119,8 +110,8 @@ impl serde::Serialize for DecodeDifferent O: serde::Serialize + 'static, { fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, + where + S: serde::Serializer, { match self { DecodeDifferent::Encode(b) => b.serialize(serializer), @@ -196,8 +187,8 @@ impl std::fmt::Debug for FnEncode { #[cfg(feature = "std")] impl serde::Serialize for FnEncode { fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, + where + S: serde::Serializer, { self.0().serialize(serializer) } @@ -238,9 +229,55 @@ pub struct StorageFunctionMetadata { pub name: DecodeDifferentStr, pub modifier: StorageFunctionModifier, pub ty: StorageFunctionType, + pub default: ByteGetter, pub documentation: DecodeDifferentArray<&'static str, StringBuf>, } +/// A technical trait to store lazy initiated vec value as static dyn pointer. +pub trait DefaultByte { + fn default_byte(&self) -> Vec; +} + +/// Wrapper over dyn pointer for accessing a cached once byet value. +#[derive(Clone)] +pub struct DefaultByteGetter(pub &'static dyn DefaultByte); + +/// Decode different for static lazy initiated byte value. +pub type ByteGetter = DecodeDifferent>; + +impl Encode for DefaultByteGetter { + fn encode_to(&self, dest: &mut W) { + self.0.default_byte().encode_to(dest) + } +} + +impl PartialEq for DefaultByteGetter { + fn eq(&self, other: &DefaultByteGetter) -> bool { + let left = self.0.default_byte(); + let right = other.0.default_byte(); + left.eq(&right) + } +} + +impl Eq for DefaultByteGetter { } + +#[cfg(feature = "std")] +impl serde::Serialize for DefaultByteGetter { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.0.default_byte().serialize(serializer) + } +} + +#[cfg(feature = "std")] +impl std::fmt::Debug for DefaultByteGetter { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + self.0.default_byte().fmt(f) + } +} + /// A storage function type. #[derive(Clone, PartialEq, Eq, Encode)] #[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))] @@ -294,3 +331,9 @@ pub struct RuntimeMetadata { pub modules: DecodeDifferentArray, pub outer_dispatch: OuterDispatchMetadata, } + +impl Into for RuntimeMetadata { + fn into(self) -> primitives::OpaqueMetadata { + primitives::OpaqueMetadata::new(self.encode()) + } +} diff --git a/srml/session/Cargo.toml b/srml/session/Cargo.toml index c006eff0a43cc1d81a95da755defce0486d76f0b..3a8fe91716fdfd6d3aaf883ebad0be2f5ed02157 100644 --- a/srml/session/Cargo.toml +++ b/srml/session/Cargo.toml @@ -6,10 +6,9 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } safe-mix = { version = "1.0", default-features = false} substrate-primitives = { path = "../../core/primitives", default-features = false } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } sr-io = { path = "../../core/sr-io", default-features = false } @@ -23,7 +22,6 @@ srml-timestamp = { path = "../timestamp", default-features = false } default = ["std"] std = [ "serde/std", - "serde_derive", "safe-mix/std", "parity-codec/std", "parity-codec-derive/std", diff --git a/srml/session/src/lib.rs b/srml/session/src/lib.rs index df3afa9aa130b62769404be227a097e51df4f31e..bc316938c0f7f26b960ae84c434fb008121f480a 100644 --- a/srml/session/src/lib.rs +++ b/srml/session/src/lib.rs @@ -19,10 +19,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - extern crate sr_std as rstd; #[macro_use] @@ -43,9 +39,9 @@ extern crate srml_timestamp as timestamp; use rstd::prelude::*; use primitives::traits::{As, Zero, One, Convert}; -use codec::HasCompact; use runtime_support::{StorageValue, StorageMap}; use runtime_support::dispatch::Result; +use runtime_support::for_each_tuple; use system::ensure_signed; use rstd::ops::Mul; @@ -55,10 +51,24 @@ pub trait OnSessionChange { fn on_session_change(time_elapsed: T, should_reward: bool); } -impl OnSessionChange for () { - fn on_session_change(_: T, _: bool) {} +macro_rules! impl_session_change { + () => ( + impl OnSessionChange for () { + fn on_session_change(_: T, _: bool) {} + } + ); + + ( $($t:ident)* ) => { + impl),*> OnSessionChange for ($($t,)*) { + fn on_session_change(time_elapsed: T, should_reward: bool) { + $($t::on_session_change(time_elapsed.clone(), should_reward);)* + } + } + } } +for_each_tuple!(impl_session_change); + pub trait Trait: timestamp::Trait { type ConvertAccountIdToSessionKey: Convert; type OnSessionChange: OnSessionChange; @@ -67,21 +77,19 @@ pub trait Trait: timestamp::Trait { decl_module! { pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Sets the session key of `_validator` to `_key`. This doesn't take effect until the next /// session. - fn set_key(origin, key: T::SessionKey) -> Result { + fn set_key(origin, key: T::SessionKey) { let who = ensure_signed(origin)?; // set new value for next session >::insert(who, key); - Ok(()) } /// Set a new session length. Won't kick in until the next session change (at current length). - fn set_length(new: ::Type) -> Result { - >::put(new.into()); - Ok(()) + fn set_length(#[compact] new: T::BlockNumber) { + >::put(new); } /// Forces a new session. @@ -228,8 +236,8 @@ mod tests { use runtime_io::with_externalities; use substrate_primitives::{H256, Blake2Hasher}; use primitives::BuildStorage; - use primitives::traits::{Identity, BlakeTwo256}; - use primitives::testing::{Digest, DigestItem, Header}; + use primitives::traits::{BlakeTwo256, IdentityLookup}; + use primitives::testing::{Digest, DigestItem, Header, UintAuthorityId, ConvertUintAuthorityId}; impl_outer_origin!{ pub enum Origin for Test {} @@ -240,8 +248,8 @@ mod tests { impl consensus::Trait for Test { const NOTE_OFFLINE_POSITION: u32 = 1; type Log = DigestItem; - type SessionKey = u64; - type OnOfflineValidator = (); + type SessionKey = UintAuthorityId; + type InherentOfflineReport = (); } impl system::Trait for Test { type Origin = Origin; @@ -251,6 +259,7 @@ mod tests { type Hashing = BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = (); type Log = DigestItem; @@ -258,9 +267,10 @@ mod tests { impl timestamp::Trait for Test { const TIMESTAMP_SET_POSITION: u32 = 0; type Moment = u64; + type OnTimestampSet = (); } impl Trait for Test { - type ConvertAccountIdToSessionKey = Identity; + type ConvertAccountIdToSessionKey = ConvertUintAuthorityId; type OnSessionChange = (); type Event = (); } @@ -273,7 +283,7 @@ mod tests { let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; t.extend(consensus::GenesisConfig::{ code: vec![], - authorities: vec![1, 2, 3], + authorities: vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)], }.build_storage().unwrap().0); t.extend(timestamp::GenesisConfig::{ period: 5, @@ -288,7 +298,7 @@ mod tests { #[test] fn simple_setup_should_work() { with_externalities(&mut new_test_ext(), || { - assert_eq!(Consensus::authorities(), vec![1, 2, 3]); + assert_eq!(Consensus::authorities(), vec![UintAuthorityId(1).into(), UintAuthorityId(2).into(), UintAuthorityId(3).into()]); assert_eq!(Session::length(), 2); assert_eq!(Session::validators(), vec![1, 2, 3]); }); @@ -298,7 +308,7 @@ mod tests { fn should_work_with_early_exit() { with_externalities(&mut new_test_ext(), || { System::set_block_number(1); - assert_ok!(Session::set_length(10.into())); + assert_ok!(Session::set_length(10)); assert_eq!(Session::blocks_remaining(), 1); Session::check_rotate_session(1); @@ -333,14 +343,14 @@ mod tests { with_externalities(&mut new_test_ext(), || { // Block 1: Change to length 3; no visible change. System::set_block_number(1); - assert_ok!(Session::set_length(3.into())); + assert_ok!(Session::set_length(3)); Session::check_rotate_session(1); assert_eq!(Session::length(), 2); assert_eq!(Session::current_index(), 0); // Block 2: Length now changed to 3. Index incremented. System::set_block_number(2); - assert_ok!(Session::set_length(3.into())); + assert_ok!(Session::set_length(3)); Session::check_rotate_session(2); assert_eq!(Session::length(), 3); assert_eq!(Session::current_index(), 1); @@ -353,7 +363,7 @@ mod tests { // Block 4: Change to length 2; no visible change. System::set_block_number(4); - assert_ok!(Session::set_length(2.into())); + assert_ok!(Session::set_length(2)); Session::check_rotate_session(4); assert_eq!(Session::length(), 3); assert_eq!(Session::current_index(), 1); @@ -384,25 +394,25 @@ mod tests { // Block 1: No change System::set_block_number(1); Session::check_rotate_session(1); - assert_eq!(Consensus::authorities(), vec![1, 2, 3]); + assert_eq!(Consensus::authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); // Block 2: Session rollover, but no change. System::set_block_number(2); Session::check_rotate_session(2); - assert_eq!(Consensus::authorities(), vec![1, 2, 3]); + assert_eq!(Consensus::authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); // Block 3: Set new key for validator 2; no visible change. System::set_block_number(3); - assert_ok!(Session::set_key(Origin::signed(2), 5)); - assert_eq!(Consensus::authorities(), vec![1, 2, 3]); + assert_ok!(Session::set_key(Origin::signed(2), UintAuthorityId(5))); + assert_eq!(Consensus::authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); Session::check_rotate_session(3); - assert_eq!(Consensus::authorities(), vec![1, 2, 3]); + assert_eq!(Consensus::authorities(), vec![UintAuthorityId(1), UintAuthorityId(2), UintAuthorityId(3)]); // Block 4: Session rollover, authority 2 changes. System::set_block_number(4); Session::check_rotate_session(4); - assert_eq!(Consensus::authorities(), vec![1, 5, 3]); + assert_eq!(Consensus::authorities(), vec![UintAuthorityId(1), UintAuthorityId(5), UintAuthorityId(3)]); }); } } diff --git a/srml/staking/Cargo.toml b/srml/staking/Cargo.toml index 7a1f4ef4eb5cb7a1a31a7d233725ecc740f9c72a..d06d4f3f918ed3952c44db5a830a4b7099fd60fa 100644 --- a/srml/staking/Cargo.toml +++ b/srml/staking/Cargo.toml @@ -6,9 +6,8 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } safe-mix = { version = "1.0", default-features = false} -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-keyring = { path = "../../core/keyring", optional = true } substrate-primitives = { path = "../../core/primitives", default-features = false } @@ -26,7 +25,6 @@ srml-timestamp = { path = "../timestamp", default-features = false } default = ["std"] std = [ "serde/std", - "serde_derive", "safe-mix/std", "substrate-keyring", "parity-codec/std", diff --git a/srml/staking/src/lib.rs b/srml/staking/src/lib.rs index 680da340c54c53a1633b05f718a2d8be813188a6..db1405a466064cac6c7b45f3070d002a93d77fb8 100644 --- a/srml/staking/src/lib.rs +++ b/srml/staking/src/lib.rs @@ -23,10 +23,6 @@ #[cfg(feature = "std")] extern crate serde; -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - #[macro_use] extern crate srml_support as runtime_support; @@ -49,14 +45,12 @@ extern crate sr_io as runtime_io; #[cfg(test)] extern crate srml_timestamp as timestamp; -use rstd::prelude::*; -use rstd::cmp; +use rstd::{prelude::*, cmp}; use codec::{HasCompact, Compact}; -use runtime_support::{Parameter, StorageValue, StorageMap}; -use runtime_support::dispatch::Result; +use runtime_support::{Parameter, StorageValue, StorageMap, dispatch::Result}; use session::OnSessionChange; -use primitives::{Perbill, traits::{Zero, One, Bounded, As}}; -use balances::{address::Address, OnDilution}; +use primitives::{Perbill, traits::{Zero, One, Bounded, As, StaticLookup}}; +use balances::OnDilution; use system::ensure_signed; mod mock; @@ -75,7 +69,7 @@ pub enum LockStatus { /// Preference of what happens on a slash event. #[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +#[cfg_attr(feature = "std", derive(Debug))] pub struct ValidatorPrefs { // TODO: @bkchr shouldn't need this Copy but derive(Encode) breaks otherwise /// Validator should ensure this many more slashes than is necessary before being unstaked. #[codec(compact)] @@ -103,14 +97,13 @@ pub trait Trait: balances::Trait + session::Trait { } decl_module! { - #[cfg_attr(feature = "std", serde(bound(deserialize = "T::Balance: ::serde::de::DeserializeOwned")))] pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Declare the desire to stake for the transactor. /// /// Effects will be felt at the beginning of the next era. - fn stake(origin) -> Result { + fn stake(origin) { let who = ensure_signed(origin)?; ensure!(Self::nominating(&who).is_none(), "Cannot stake if already nominating."); let mut intentions = >::get(); @@ -120,15 +113,13 @@ decl_module! { >::insert(&who, T::BlockNumber::max_value()); intentions.push(who); >::put(intentions); - Ok(()) } /// Retract the desire to stake for the transactor. /// /// Effects will be felt at the beginning of the next era. - fn unstake(origin, intentions_index: Compact) -> Result { + fn unstake(origin, #[compact] intentions_index: u32) -> Result { let who = ensure_signed(origin)?; - let intentions_index: u32 = intentions_index.into(); // unstake fails in degenerate case of having too few existing staked parties if Self::intentions().len() <= Self::minimum_validator_count() as usize { return Err("cannot unstake when there are too few staked participants") @@ -136,9 +127,9 @@ decl_module! { Self::apply_unstake(&who, intentions_index as usize) } - fn nominate(origin, target: Address) -> Result { + fn nominate(origin, target: ::Source) { let who = ensure_signed(origin)?; - let target = >::lookup(target)?; + let target = T::Lookup::lookup(target)?; ensure!(Self::nominating(&who).is_none(), "Cannot nominate if already nominating."); ensure!(Self::intentions().iter().find(|&t| t == &who).is_none(), "Cannot nominate if already staked."); @@ -153,15 +144,12 @@ decl_module! { // Update bondage >::insert(&who, T::BlockNumber::max_value()); - - Ok(()) } /// Will panic if called when source isn't currently nominating target. /// Updates Nominating, NominatorsFor and NominationBalance. - fn unnominate(origin, target_index: Compact) -> Result { + fn unnominate(origin, #[compact] target_index: u32) { let source = ensure_signed(origin)?; - let target_index: u32 = target_index.into(); let target_index = target_index as usize; let target = >::get(&source).ok_or("Account must be nominating")?; @@ -185,7 +173,6 @@ decl_module! { source, >::block_number() + Self::bonding_duration() ); - Ok(()) } /// Set the given account's preference for slashing behaviour should they be a validator. @@ -193,38 +180,31 @@ decl_module! { /// An error (no-op) if `Self::intentions()[intentions_index] != origin`. fn register_preferences( origin, - intentions_index: Compact, + #[compact] intentions_index: u32, prefs: ValidatorPrefs - ) -> Result { + ) { let who = ensure_signed(origin)?; - let intentions_index: u32 = intentions_index.into(); if Self::intentions().get(intentions_index as usize) != Some(&who) { return Err("Invalid index") } >::insert(who, prefs); - - Ok(()) } /// Set the number of sessions in an era. - fn set_sessions_per_era(new: ::Type) -> Result { - >::put(new.into()); - Ok(()) + fn set_sessions_per_era(#[compact] new: T::BlockNumber) { + >::put(new); } /// The length of the bonding duration in eras. - fn set_bonding_duration(new: ::Type) -> Result { - >::put(new.into()); - Ok(()) + fn set_bonding_duration(#[compact] new: T::BlockNumber) { + >::put(new); } - /// The length of a staking era in sessions. - fn set_validator_count(new: Compact) -> Result { - let new: u32 = new.into(); + /// The ideal number of validators. + fn set_validator_count(#[compact] new: u32) { >::put(new); - Ok(()) } /// Force there to be a new era. This also forces a new session immediately after. @@ -234,10 +214,13 @@ decl_module! { } /// Set the offline slash grace period. - fn set_offline_slash_grace(new: Compact) -> Result { - let new: u32 = new.into(); + fn set_offline_slash_grace(#[compact] new: u32) { >::put(new); - Ok(()) + } + + /// Set the validators who cannot be slashed (if any). + fn set_invulnerables(validators: Vec) { + >::put(validators); } } } @@ -275,6 +258,10 @@ decl_storage! { /// The length of the bonding duration in blocks. pub BondingDuration get(bonding_duration) config(): T::BlockNumber = T::BlockNumber::sa(1000); + /// Any validators that may never be slashed or forcible kicked. It's a Vec since they're easy to initialise + /// and the performance hit is minimal (we expect no more than four invulnerables) and restricted to testnets. + pub Invulerables get(invulnerables) config(): Vec; + /// The current era index. pub CurrentEra get(current_era) config(): T::BlockNumber; /// Preferences that a validator has. @@ -348,6 +335,11 @@ impl Module { } } + /// Get the current validators. + pub fn validators() -> Vec { + session::Module::::validators() + } + // PUBLIC MUTABLES (DANGEROUS) /// Slash a given validator by a specific amount. Removes the slash from their balance by preference, @@ -505,6 +497,73 @@ impl Module { >::put(Self::offline_slash().times(stake_range.1)); >::put(Self::session_reward().times(stake_range.1)); } + + /// Call when a validator is determined to be offline. `count` is the + /// number of offences the validator has committed. + pub fn on_offline_validator(v: T::AccountId, count: usize) { + use primitives::traits::{CheckedAdd, CheckedShl}; + + // Early exit if validator is invulnerable. + if Self::invulnerables().contains(&v) { + return + } + + let slash_count = Self::slash_count(&v); + let new_slash_count = slash_count + count as u32; + >::insert(v.clone(), new_slash_count); + let grace = Self::offline_slash_grace(); + + let event = if new_slash_count > grace { + let slash = { + let base_slash = Self::current_offline_slash(); + let instances = slash_count - grace; + + let mut total_slash = T::Balance::default(); + for i in instances..(instances + count as u32) { + if let Some(total) = base_slash.checked_shl(i) + .and_then(|slash| total_slash.checked_add(&slash)) { + total_slash = total; + } else { + // reset slash count only up to the current + // instance. the total slash overflows the unit for + // balance in the system therefore we can slash all + // the slashable balance for the account + >::insert(v.clone(), slash_count + i); + total_slash = Self::slashable_balance(&v); + break; + } + } + + total_slash + }; + + let _ = Self::slash_validator(&v, slash); + + let next_slash = match slash.checked_shl(1) { + Some(slash) => slash, + None => Self::slashable_balance(&v), + }; + + let instances = new_slash_count - grace; + if instances > Self::validator_preferences(&v).unstake_threshold + || Self::slashable_balance(&v) < next_slash + || next_slash <= slash + { + if let Some(pos) = Self::intentions().into_iter().position(|x| &x == &v) { + Self::apply_unstake(&v, pos) + .expect("pos derived correctly from Self::intentions(); \ + apply_unstake can only fail if pos wrong; \ + Self::intentions() doesn't change; qed"); + } + let _ = Self::apply_force_new_era(false); + } + RawEvent::OfflineSlash(v.clone(), slash) + } else { + RawEvent::OfflineWarning(v.clone(), slash_count) + }; + + Self::deposit_event(event); + } } impl OnSessionChange for Module { @@ -529,33 +588,11 @@ impl balances::OnFreeBalanceZero for Module { } } -impl consensus::OnOfflineValidator for Module { - fn on_offline_validator(validator_index: usize) { - let v = >::validators()[validator_index].clone(); - let slash_count = Self::slash_count(&v); - >::insert(v.clone(), slash_count + 1); - let grace = Self::offline_slash_grace(); - - let event = if slash_count >= grace { - let instances = slash_count - grace; - let slash = Self::current_offline_slash() << instances; - let next_slash = slash << 1u32; - let _ = Self::slash_validator(&v, slash); - if instances >= Self::validator_preferences(&v).unstake_threshold - || Self::slashable_balance(&v) < next_slash - { - if let Some(pos) = Self::intentions().into_iter().position(|x| &x == &v) { - Self::apply_unstake(&v, pos) - .expect("pos derived correctly from Self::intentions(); \ - apply_unstake can only fail if pos wrong; \ - Self::intentions() doesn't change; qed"); - } - let _ = Self::apply_force_new_era(false); - } - RawEvent::OfflineSlash(v, slash) - } else { - RawEvent::OfflineWarning(v, slash_count) - }; - Self::deposit_event(event); +impl consensus::OnOfflineReport> for Module { + fn handle_report(reported_indices: Vec) { + for validator_index in reported_indices { + let v = >::validators()[validator_index as usize].clone(); + Self::on_offline_validator(v, 1); + } } } diff --git a/srml/staking/src/mock.rs b/srml/staking/src/mock.rs index b22af1b1b540203da1e1197be2fd3601029dae2e..752922da03dd9011dd91d0f6c15fdc9a363963fa 100644 --- a/srml/staking/src/mock.rs +++ b/srml/staking/src/mock.rs @@ -18,9 +18,8 @@ #![cfg(test)] -use primitives::BuildStorage; -use primitives::{Perbill, traits::Identity}; -use primitives::testing::{Digest, DigestItem, Header}; +use primitives::{traits::IdentityLookup, BuildStorage, Perbill}; +use primitives::testing::{Digest, DigestItem, Header, UintAuthorityId, ConvertUintAuthorityId}; use substrate_primitives::{H256, Blake2Hasher}; use runtime_io; use {GenesisConfig, Module, Trait, consensus, session, system, timestamp, balances}; @@ -30,13 +29,13 @@ impl_outer_origin!{ } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. -#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] +#[derive(Clone, PartialEq, Eq, Debug)] pub struct Test; impl consensus::Trait for Test { const NOTE_OFFLINE_POSITION: u32 = 1; type Log = DigestItem; - type SessionKey = u64; - type OnOfflineValidator = (); + type SessionKey = UintAuthorityId; + type InherentOfflineReport = (); } impl system::Trait for Test { type Origin = Origin; @@ -46,25 +45,27 @@ impl system::Trait for Test { type Hashing = ::primitives::traits::BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = (); type Log = DigestItem; } impl balances::Trait for Test { type Balance = u64; - type AccountIndex = u64; type OnFreeBalanceZero = Staking; + type OnNewAccount = (); type EnsureAccountLiquid = Staking; type Event = (); } impl session::Trait for Test { - type ConvertAccountIdToSessionKey = Identity; + type ConvertAccountIdToSessionKey = ConvertUintAuthorityId; type OnSessionChange = Staking; type Event = (); } impl timestamp::Trait for Test { const TIMESTAMP_SET_POSITION: u32 = 0; type Moment = u64; + type OnTimestampSet = (); } impl Trait for Test { type OnRewardMinted = (); @@ -108,7 +109,6 @@ pub fn new_test_ext( existential_deposit: ext_deposit, transfer_fee: 0, creation_fee: 0, - reclaim_rebate: 0, }.build_storage().unwrap().0); t.extend(GenesisConfig::{ sessions_per_era, @@ -122,9 +122,10 @@ pub fn new_test_ext( current_session_reward: reward, current_offline_slash: 20, offline_slash_grace: 0, + invulnerables: vec![], }.build_storage().unwrap().0); t.extend(timestamp::GenesisConfig::{ - period: 5 + period: 5, }.build_storage().unwrap().0); runtime_io::TestExternalities::new(t) } diff --git a/srml/staking/src/tests.rs b/srml/staking/src/tests.rs index 67e793f7bc364fb935d8b5ea03e8222ef26568a5..01a03d3124435979c36d1747d6d0568d636b64ac 100644 --- a/srml/staking/src/tests.rs +++ b/srml/staking/src/tests.rs @@ -19,7 +19,6 @@ #![cfg(test)] use super::*; -use consensus::OnOfflineValidator; use runtime_io::with_externalities; use mock::{Balances, Session, Staking, System, Timestamp, Test, new_test_ext, Origin}; @@ -36,6 +35,22 @@ fn note_null_offline_should_work() { }); } +#[test] +fn invulnerability_should_work() { + with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { + assert_ok!(Staking::set_invulnerables(vec![10])); + Balances::set_free_balance(&10, 70); + assert_eq!(Staking::offline_slash_grace(), 0); + assert_eq!(Staking::slash_count(&10), 0); + assert_eq!(Balances::free_balance(&10), 70); + System::set_extrinsic_index(1); + Staking::on_offline_validator(10, 1); + assert_eq!(Staking::slash_count(&10), 0); + assert_eq!(Balances::free_balance(&10), 70); + assert!(Staking::forcing_new_era().is_none()); + }); +} + #[test] fn note_offline_should_work() { with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { @@ -44,7 +59,7 @@ fn note_offline_should_work() { assert_eq!(Staking::slash_count(&10), 0); assert_eq!(Balances::free_balance(&10), 70); System::set_extrinsic_index(1); - Staking::on_offline_validator(0); + Staking::on_offline_validator(10, 1); assert_eq!(Staking::slash_count(&10), 1); assert_eq!(Balances::free_balance(&10), 50); assert!(Staking::forcing_new_era().is_none()); @@ -59,11 +74,11 @@ fn note_offline_exponent_should_work() { assert_eq!(Staking::slash_count(&10), 0); assert_eq!(Balances::free_balance(&10), 150); System::set_extrinsic_index(1); - Staking::on_offline_validator(0); + Staking::on_offline_validator(10, 1); assert_eq!(Staking::slash_count(&10), 1); assert_eq!(Balances::free_balance(&10), 130); System::set_extrinsic_index(1); - Staking::on_offline_validator(0); + Staking::on_offline_validator(10, 1); assert_eq!(Staking::slash_count(&10), 2); assert_eq!(Balances::free_balance(&10), 90); assert!(Staking::forcing_new_era().is_none()); @@ -75,22 +90,22 @@ fn note_offline_grace_should_work() { with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { Balances::set_free_balance(&10, 70); Balances::set_free_balance(&20, 70); - assert_ok!(Staking::set_offline_slash_grace(1.into())); + assert_ok!(Staking::set_offline_slash_grace(1)); assert_eq!(Staking::offline_slash_grace(), 1); assert_eq!(Staking::slash_count(&10), 0); assert_eq!(Balances::free_balance(&10), 70); System::set_extrinsic_index(1); - Staking::on_offline_validator(0); + Staking::on_offline_validator(10, 1); assert_eq!(Staking::slash_count(&10), 1); assert_eq!(Balances::free_balance(&10), 70); assert_eq!(Staking::slash_count(&20), 0); assert_eq!(Balances::free_balance(&20), 70); System::set_extrinsic_index(1); - Staking::on_offline_validator(0); - Staking::on_offline_validator(1); + Staking::on_offline_validator(10, 1); + Staking::on_offline_validator(20, 1); assert_eq!(Staking::slash_count(&10), 2); assert_eq!(Balances::free_balance(&10), 50); assert_eq!(Staking::slash_count(&20), 1); @@ -105,20 +120,20 @@ fn note_offline_force_unstake_session_change_should_work() { Balances::set_free_balance(&10, 70); Balances::set_free_balance(&20, 70); assert_ok!(Staking::stake(Origin::signed(1))); - + assert_eq!(Staking::slash_count(&10), 0); assert_eq!(Balances::free_balance(&10), 70); assert_eq!(Staking::intentions(), vec![10, 20, 1]); assert_eq!(Session::validators(), vec![10, 20]); System::set_extrinsic_index(1); - Staking::on_offline_validator(0); + Staking::on_offline_validator(10, 1); assert_eq!(Balances::free_balance(&10), 50); assert_eq!(Staking::slash_count(&10), 1); assert_eq!(Staking::intentions(), vec![10, 20, 1]); System::set_extrinsic_index(1); - Staking::on_offline_validator(0); + Staking::on_offline_validator(10, 1); assert_eq!(Staking::intentions(), vec![1, 20]); assert_eq!(Balances::free_balance(&10), 10); assert!(Staking::forcing_new_era().is_some()); @@ -130,34 +145,34 @@ fn note_offline_auto_unstake_session_change_should_work() { with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { Balances::set_free_balance(&10, 7000); Balances::set_free_balance(&20, 7000); - assert_ok!(Staking::register_preferences(Origin::signed(10), 0.into(), ValidatorPrefs { unstake_threshold: 1, validator_payment: 0 })); - + assert_ok!(Staking::register_preferences(Origin::signed(10), 0, ValidatorPrefs { unstake_threshold: 1, validator_payment: 0 })); + assert_eq!(Staking::intentions(), vec![10, 20]); System::set_extrinsic_index(1); - Staking::on_offline_validator(0); - Staking::on_offline_validator(1); + Staking::on_offline_validator(10, 1); + Staking::on_offline_validator(20, 1); assert_eq!(Balances::free_balance(&10), 6980); assert_eq!(Balances::free_balance(&20), 6980); assert_eq!(Staking::intentions(), vec![10, 20]); assert!(Staking::forcing_new_era().is_none()); System::set_extrinsic_index(1); - Staking::on_offline_validator(0); - Staking::on_offline_validator(1); + Staking::on_offline_validator(10, 1); + Staking::on_offline_validator(20, 1); assert_eq!(Balances::free_balance(&10), 6940); assert_eq!(Balances::free_balance(&20), 6940); assert_eq!(Staking::intentions(), vec![20]); assert!(Staking::forcing_new_era().is_some()); System::set_extrinsic_index(1); - Staking::on_offline_validator(1); + Staking::on_offline_validator(20, 1); assert_eq!(Balances::free_balance(&10), 6940); assert_eq!(Balances::free_balance(&20), 6860); assert_eq!(Staking::intentions(), vec![20]); System::set_extrinsic_index(1); - Staking::on_offline_validator(1); + Staking::on_offline_validator(20, 1); assert_eq!(Balances::free_balance(&10), 6940); assert_eq!(Balances::free_balance(&20), 6700); assert_eq!(Staking::intentions(), vec![0u64; 0]); @@ -220,8 +235,8 @@ fn slashing_should_work() { System::set_block_number(7); System::set_extrinsic_index(1); - Staking::on_offline_validator(0); - Staking::on_offline_validator(1); + Staking::on_offline_validator(10, 1); + Staking::on_offline_validator(20, 1); assert_eq!(Balances::total_balance(&10), 1); }); } @@ -235,8 +250,8 @@ fn staking_should_work() { assert_eq!(Staking::era_length(), 2); assert_eq!(Staking::validator_count(), 2); assert_eq!(Session::validators(), vec![10, 20]); - - assert_ok!(Staking::set_bonding_duration(2.into())); + + assert_ok!(Staking::set_bonding_duration(2)); assert_eq!(Staking::bonding_duration(), 2); // Block 1: Add three validators. No obvious change. @@ -269,7 +284,7 @@ fn staking_should_work() { // Block 5: Transfer stake from highest to lowest. No change yet. System::set_block_number(5); - assert_ok!(Balances::transfer(Origin::signed(4), 1.into(), 40.into())); + assert_ok!(Balances::transfer(Origin::signed(4), 1, 40)); Session::check_rotate_session(System::block_number()); // Block 6: Lowest now validator. @@ -302,7 +317,7 @@ fn nominating_and_rewards_should_work() { assert_ok!(Staking::stake(Origin::signed(1))); assert_ok!(Staking::stake(Origin::signed(2))); assert_ok!(Staking::stake(Origin::signed(3))); - assert_ok!(Staking::nominate(Origin::signed(4), 1.into())); + assert_ok!(Staking::nominate(Origin::signed(4), 1)); Session::check_rotate_session(System::block_number()); assert_eq!(Staking::current_era(), 1); assert_eq!(Session::validators(), vec![1, 3]); // 4 + 1, 3 @@ -312,7 +327,7 @@ fn nominating_and_rewards_should_work() { assert_eq!(Balances::total_balance(&4), 40); System::set_block_number(2); - assert_ok!(Staking::unnominate(Origin::signed(4), 0.into())); + assert_ok!(Staking::unnominate(Origin::signed(4), 0)); Session::check_rotate_session(System::block_number()); assert_eq!(Staking::current_era(), 2); assert_eq!(Session::validators(), vec![3, 2]); @@ -324,7 +339,7 @@ fn nominating_and_rewards_should_work() { System::set_block_number(3); assert_ok!(Staking::stake(Origin::signed(4))); assert_ok!(Staking::unstake(Origin::signed(3), (Staking::intentions().iter().position(|&x| x == 3).unwrap() as u32).into())); - assert_ok!(Staking::nominate(Origin::signed(3), 1.into())); + assert_ok!(Staking::nominate(Origin::signed(3), 1)); Session::check_rotate_session(System::block_number()); assert_eq!(Session::validators(), vec![1, 4]); assert_eq!(Balances::total_balance(&1), 16); @@ -346,7 +361,7 @@ fn rewards_with_off_the_table_should_work() { with_externalities(&mut new_test_ext(0, 1, 1, 0, true, 10), || { System::set_block_number(1); assert_ok!(Staking::stake(Origin::signed(1))); - assert_ok!(Staking::nominate(Origin::signed(2), 1.into())); + assert_ok!(Staking::nominate(Origin::signed(2), 1)); assert_ok!(Staking::stake(Origin::signed(3))); Session::check_rotate_session(System::block_number()); assert_eq!(Session::validators(), vec![1, 3]); // 1 + 2, 3 @@ -382,8 +397,8 @@ fn nominating_slashes_should_work() { System::set_block_number(4); assert_ok!(Staking::stake(Origin::signed(1))); assert_ok!(Staking::stake(Origin::signed(3))); - assert_ok!(Staking::nominate(Origin::signed(2), 3.into())); - assert_ok!(Staking::nominate(Origin::signed(4), 1.into())); + assert_ok!(Staking::nominate(Origin::signed(2), 3)); + assert_ok!(Staking::nominate(Origin::signed(4), 1)); Session::check_rotate_session(System::block_number()); assert_eq!(Staking::current_era(), 1); @@ -395,8 +410,8 @@ fn nominating_slashes_should_work() { System::set_block_number(5); System::set_extrinsic_index(1); - Staking::on_offline_validator(0); - Staking::on_offline_validator(1); + Staking::on_offline_validator(1, 1); + Staking::on_offline_validator(3, 1); assert_eq!(Balances::total_balance(&1), 0); //slashed assert_eq!(Balances::total_balance(&2), 20); //not slashed assert_eq!(Balances::total_balance(&3), 10); //slashed @@ -411,10 +426,10 @@ fn double_staking_should_fail() { System::set_block_number(1); assert_ok!(Staking::stake(Origin::signed(1))); assert_noop!(Staking::stake(Origin::signed(1)), "Cannot stake if already staked."); - assert_noop!(Staking::nominate(Origin::signed(1), 1.into()), "Cannot nominate if already staked."); - assert_ok!(Staking::nominate(Origin::signed(2), 1.into())); + assert_noop!(Staking::nominate(Origin::signed(1), 1), "Cannot nominate if already staked."); + assert_ok!(Staking::nominate(Origin::signed(2), 1)); assert_noop!(Staking::stake(Origin::signed(2)), "Cannot stake if already nominating."); - assert_noop!(Staking::nominate(Origin::signed(2), 1.into()), "Cannot nominate if already nominating."); + assert_noop!(Staking::nominate(Origin::signed(2), 1), "Cannot nominate if already nominating."); }); } @@ -445,7 +460,7 @@ fn staking_eras_work() { // Block 3: Schedule an era length change; no visible changes. System::set_block_number(3); - assert_ok!(Staking::set_sessions_per_era(3.into())); + assert_ok!(Staking::set_sessions_per_era(3)); Session::check_rotate_session(System::block_number()); assert_eq!(Session::current_index(), 3); assert_eq!(Staking::sessions_per_era(), 2); @@ -491,7 +506,7 @@ fn staking_balance_transfer_when_bonded_should_not_work() { with_externalities(&mut new_test_ext(0, 1, 3, 1, false, 0), || { Balances::set_free_balance(&1, 111); assert_ok!(Staking::stake(Origin::signed(1))); - assert_noop!(Balances::transfer(Origin::signed(1), 2.into(), 69.into()), "cannot transfer illiquid funds"); + assert_noop!(Balances::transfer(Origin::signed(1), 2, 69), "cannot transfer illiquid funds"); }); } @@ -505,3 +520,79 @@ fn deducting_balance_when_bonded_should_not_work() { assert_noop!(Balances::reserve(&1, 69), "cannot transfer illiquid funds"); }); } + +#[test] +fn slash_value_calculation_does_not_overflow() { + with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { + assert_eq!(Staking::era_length(), 9); + assert_eq!(Staking::sessions_per_era(), 3); + assert_eq!(Staking::last_era_length_change(), 0); + assert_eq!(Staking::current_era(), 0); + assert_eq!(Session::current_index(), 0); + assert_eq!(Balances::total_balance(&10), 1); + assert_eq!(Staking::intentions(), vec![10, 20]); + assert_eq!(Staking::offline_slash_grace(), 0); + + // set validator preferences so the validator doesn't back down after + // slashing. + >::insert(10, ValidatorPrefs { + unstake_threshold: u32::max_value(), + validator_payment: 0, + }); + + System::set_block_number(3); + Session::check_rotate_session(System::block_number()); + assert_eq!(Staking::current_era(), 0); + assert_eq!(Session::current_index(), 1); + assert_eq!(Balances::total_balance(&10), 11); + + // the balance type is u64, so after slashing 64 times, + // the slash value should have overflowed. add a couple extra for + // good measure with the slash grace. + trait TypeEq {} + impl TypeEq for (A, A) {} + fn assert_type_eq() {} + assert_type_eq::<(u64, ::Balance)>(); + + Staking::on_offline_validator(10, 100); + }); +} + +#[test] +fn next_slash_value_calculation_does_not_overflow() { + with_externalities(&mut new_test_ext(0, 3, 3, 0, true, 10), || { + assert_eq!(Staking::era_length(), 9); + assert_eq!(Staking::sessions_per_era(), 3); + assert_eq!(Staking::last_era_length_change(), 0); + assert_eq!(Staking::current_era(), 0); + assert_eq!(Session::current_index(), 0); + assert_eq!(Balances::total_balance(&10), 1); + assert_eq!(Staking::intentions(), vec![10, 20]); + assert_eq!(Staking::offline_slash_grace(), 0); + + // set validator preferences so the validator doesn't back down after + // slashing. + >::insert(10, ValidatorPrefs { + unstake_threshold: u32::max_value(), + validator_payment: 0, + }); + + // we have enough balance to cover the last slash before overflow + Balances::set_free_balance(&10, u64::max_value()); + assert_eq!(Balances::total_balance(&10), u64::max_value()); + + // the balance type is u64, so after slashing 64 times, + // the slash value should have overflowed. add a couple extra for + // good measure with the slash grace. + trait TypeEq {} + impl TypeEq for (A, A) {} + fn assert_type_eq() {} + assert_type_eq::<(u64, ::Balance)>(); + + // the total slash value should overflow the balance type + // therefore the total validator balance should be slashed + Staking::on_offline_validator(10, 100); + + assert_eq!(Balances::total_balance(&10), 0); + }); +} diff --git a/srml/sudo/Cargo.toml b/srml/sudo/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..00afd24f43639914dc5ef162431233502819f202 --- /dev/null +++ b/srml/sudo/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "srml-sudo" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +hex-literal = "0.1.0" +serde = { version = "1.0", default-features = false } +parity-codec = { version = "2.2", default-features = false } +parity-codec-derive = { version = "2.1", default-features = false } +substrate-primitives = { path = "../../core/primitives", default-features = false } +sr-std = { path = "../../core/sr-std", default-features = false } +sr-io = { path = "../../core/sr-io", default-features = false } +sr-primitives = { path = "../../core/sr-primitives", default-features = false } +srml-support = { path = "../support", default-features = false } +srml-support-procedural = { path = "../support/procedural" } +srml-system = { path = "../system", default-features = false } + +[features] +default = ["std"] +std = [ + "serde/std", + "parity-codec/std", + "parity-codec-derive/std", + "sr-std/std", + "sr-io/std", + "sr-primitives/std", + "substrate-primitives/std", + "srml-support/std", + "srml-system/std", +] diff --git a/srml/sudo/src/lib.rs b/srml/sudo/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..63591aba88ad9a18cbf50ee50587f071bd6b287d --- /dev/null +++ b/srml/sudo/src/lib.rs @@ -0,0 +1,89 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU 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 Example: A simple example of a runtime module demonstrating +//! concepts, APIs and structures common to most runtime modules. + +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate sr_std; +#[cfg(test)] +extern crate sr_io; +#[cfg(test)] +extern crate substrate_primitives; +extern crate sr_primitives; +#[macro_use] +extern crate parity_codec_derive; +extern crate parity_codec as codec; +#[macro_use] +extern crate srml_support as support; + +extern crate srml_system as system; + +use sr_std::prelude::*; +use sr_primitives::traits::StaticLookup; +use support::{StorageValue, Parameter, Dispatchable}; +use system::ensure_signed; + +pub trait Trait: system::Trait { + /// The overarching event type. + type Event: From> + Into<::Event>; + + /// A sudo-able call. + type Proposal: Parameter + Dispatchable; +} + +decl_module! { + // Simple declaration of the `Module` type. Lets the macro know what its working on. + pub struct Module for enum Call where origin: T::Origin { + fn deposit_event() = default; + + fn sudo(origin, proposal: Box) { + // This is a public call, so we ensure that the origin is some signed account. + let sender = ensure_signed(origin)?; + ensure!(sender == Self::key(), "only the current sudo key can sudo"); + + let ok = proposal.dispatch(system::RawOrigin::Root.into()).is_ok(); + Self::deposit_event(RawEvent::Sudid(ok)); + } + + fn set_key(origin, new: ::Source) { + // This is a public call, so we ensure that the origin is some signed account. + let sender = ensure_signed(origin)?; + ensure!(sender == Self::key(), "only the current sudo key can change the sudo key"); + let new = T::Lookup::lookup(new)?; + + Self::deposit_event(RawEvent::KeyChanged(Self::key())); + >::put(new); + } + } +} + +/// An event in this module. +decl_event!( + pub enum Event where AccountId = ::AccountId { + /// A sudo just took place. + Sudid(bool), + /// The sudoer just switched identity; the old key is supplied. + KeyChanged(AccountId), + } +); + +decl_storage! { + trait Store for Module as Sudo { + Key get(key) config(): T::AccountId; + } +} diff --git a/srml/support/Cargo.toml b/srml/support/Cargo.toml index f1254a538dc180b0622ef34e9bcdf7989174b587..6a232215b3874e1d8a20f28d161be07787744df9 100644 --- a/srml/support/Cargo.toml +++ b/srml/support/Cargo.toml @@ -7,12 +7,14 @@ authors = ["Parity Technologies "] hex-literal = { version = "0.1.0", optional = true } serde = { version = "1.0", default-features = false } serde_derive = { version = "1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } -substrate-metadata = { path = "../metadata", default-features = false } +parity-codec = { version = "2.2", default-features = false } +srml-metadata = { path = "../metadata", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } sr-io = { path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } +srml-support-procedural = { path = "./procedural" } mashup = "0.1.7" +once_cell = { version = "0.1.6", default-features = false, optional = true } [dev-dependencies] pretty_assertions = "0.5.1" @@ -22,13 +24,14 @@ parity-codec-derive = { version = "2.1" } default = ["std"] std = [ "hex-literal", + "once_cell", "serde/std", "serde_derive", "sr-io/std", "parity-codec/std", "sr-std/std", "sr-primitives/std", - "substrate-metadata/std", + "srml-metadata/std", ] nightly = [] strict = [] diff --git a/srml/support/README.adoc b/srml/support/README.adoc deleted file mode 100644 index 699235e5ae65061e652554d61414c6aa6652b320..0000000000000000000000000000000000000000 --- a/srml/support/README.adoc +++ /dev/null @@ -1,14 +0,0 @@ - -= Runtime Support - -.Summary -[source, toml] ----- -include::Cargo.toml[lines=2..5] ----- - -.Description ----- -include::src/lib.rs[tag=description] ----- - diff --git a/srml/support/procedural/Cargo.toml b/srml/support/procedural/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..206ce708f95ffd19d092484d724941efe8f1b8ea --- /dev/null +++ b/srml/support/procedural/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "srml-support-procedural" +version = "0.1.0" +authors = ["Parity Technologies "] + +[lib] +proc-macro = true + +[dependencies] +srml-support-procedural-tools = { path = "./tools" } +sr-api-macros = { path = "../../../core/sr-api-macros" } + +proc-macro2 = "0.4" +quote = { version = "0.6" } +syn = { version = "0.15", features = ["full"] } diff --git a/srml/support/procedural/src/lib.rs b/srml/support/procedural/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..e2e4668d9392754af4d2751adffd020eaec0394a --- /dev/null +++ b/srml/support/procedural/src/lib.rs @@ -0,0 +1,74 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +// tag::description[] +//! Proc macro of Support code for the runtime. +// end::description[] + +#![recursion_limit="256"] + +extern crate proc_macro; +extern crate proc_macro2; + +#[macro_use] +extern crate syn; + +#[macro_use] +extern crate quote; + +#[macro_use] +extern crate srml_support_procedural_tools; + +mod storage; + +use proc_macro::TokenStream; + +/// Declares strongly-typed wrappers around codec-compatible types in storage. +/// +/// ## Example +/// +/// ```nocompile +/// decl_storage! { +/// trait Store for Module as Example { +/// Dummy get(dummy) config(): Option; +/// Foo get(foo) config(): T::Balance; +/// } +/// } +/// ``` +/// +/// For now we implement a convenience trait with pre-specialised associated types, one for each +/// storage item. This allows you to gain access to publicly visible storage items from a +/// module type. Currently you must disambiguate by using `::Item` rather than +/// the simpler `Module::Item`. Hopefully the rust guys with fix this soon. +/// +/// An optional `GenesisConfig` struct for storage initialization can be defined, either specifically as in : +/// ```nocompile +/// decl_storage! { +/// trait Store for Module as Example { +/// } +/// add_extra_genesis { +/// config(genesis_field): GenesisFieldType; +/// build(|_: &mut StorageMap, _: &mut ChildrenStorageMap, _: &GenesisConfig| { +/// }) +/// } +/// } +/// ``` +/// or when at least one storage field requires default initialization (both `get` and `config` or `build`). +/// This struct can be expose as `Config` by `decl_runtime` macro. +#[proc_macro] +pub fn decl_storage(input: TokenStream) -> TokenStream { + storage::transformation::decl_storage_impl(input) +} diff --git a/srml/support/procedural/src/storage/mod.rs b/srml/support/procedural/src/storage/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..4e2599259316a8dd4917292725f97e905cd2b28f --- /dev/null +++ b/srml/support/procedural/src/storage/mod.rs @@ -0,0 +1,144 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +// tag::description[] +//! `decl_storage` macro +// end::description[] + +use srml_support_procedural_tools::syn_ext as ext; + +use syn::Ident; +use syn::token::CustomKeyword; + +pub mod transformation; + +/// Parsing usage only +#[derive(Parse, ToTokens, Debug)] +struct StorageDefinition { + pub hidden_crate: Option, + pub visibility: syn::Visibility, + pub trait_token: Token![trait], + pub ident: Ident, + pub for_token: Token![for], + pub module_ident: Ident, + pub mod_lt_token: Token![<], + pub mod_param: syn::GenericParam, + pub mod_gt_token: Token![>], + pub as_token: Token![as], + pub crate_ident: Ident, + pub content: ext::Braces>, + pub extra_genesis: Option, +} + + +#[derive(Parse, ToTokens, Debug)] +struct SpecificHiddenCrate { + pub keyword: ext::CustomToken, + pub ident: ext::Parens, +} + +#[derive(Parse, ToTokens, Debug)] +struct AddExtraGenesis { + pub extragenesis_keyword: ext::CustomToken, + pub content: ext::Braces, +} + +#[derive(Parse, ToTokens, Debug)] +struct AddExtraGenesisContent { + pub lines: ext::Punctuated, +} + +#[derive(Parse, ToTokens, Debug)] +enum AddExtraGenesisLineEnum { + AddExtraGenesisLine(AddExtraGenesisLine), + AddExtraGenesisBuild(DeclStorageBuild), +} + +#[derive(Parse, ToTokens, Debug)] +struct AddExtraGenesisLine { + pub attrs: ext::OuterAttributes, + pub config_keyword: ext::CustomToken, + pub extra_field: ext::Parens, + pub coldot_token: Token![:], + pub extra_type: syn::Type, + // TODO use a custom ext::Option instead (syn option on '=' fails) + pub default_value: ext::Seq, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageLine { + // attrs (main use case is doc) + pub attrs: ext::OuterAttributes, + // visibility (no need to make optional + pub visibility: syn::Visibility, + // name + pub name: Ident, + pub getter: Option, + pub config: Option, + pub build: Option, + pub coldot_token: Token![:], + pub storage_type: DeclStorageType, + // TODO use a custom ext::Option instead (syn option on '=' fails) + pub default_value: ext::Seq, +} + + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageGetter { + pub getter_keyword: ext::CustomToken, + pub getfn: ext::Parens, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageConfig { + pub config_keyword: ext::CustomToken, + pub expr: ext::Parens>, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageBuild { + pub build_keyword: ext::CustomToken, + pub expr: ext::Parens, +} + +#[derive(Parse, ToTokens, Debug)] +enum DeclStorageType { + Map(DeclStorageMap), + Simple(syn::Type), +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageMap { + pub map_keyword: ext::CustomToken, + pub key: syn::Type, + pub ass_keyword: Token![=>], + pub value: syn::Type, +} + +#[derive(Parse, ToTokens, Debug)] +struct DeclStorageDefault { + pub equal_token: Token![=], + pub expr: syn::Expr, +} + +custom_keyword_impl!(SpecificHiddenCrate, "hiddencrate", "hiddencrate as keyword"); +custom_keyword_impl!(DeclStorageConfig, "config", "build as keyword"); +custom_keyword!(ConfigKeyword, "config", "config as keyword"); +custom_keyword!(BuildKeyword, "build", "build as keyword"); +custom_keyword_impl!(DeclStorageBuild, "build", "storage build config"); +custom_keyword_impl!(AddExtraGenesis, "add_extra_genesis", "storage extra genesis"); +custom_keyword_impl!(DeclStorageGetter, "get", "storage getter"); +custom_keyword!(MapKeyword, "map", "map as keyword"); diff --git a/srml/support/procedural/src/storage/transformation.rs b/srml/support/procedural/src/storage/transformation.rs new file mode 100644 index 0000000000000000000000000000000000000000..41a24ccfefc16c97b687f05682cf68009bba03cf --- /dev/null +++ b/srml/support/procedural/src/storage/transformation.rs @@ -0,0 +1,733 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +// tag::description[] +//! `decl_storage` macro transformation +// end::description[] + +use srml_support_procedural_tools::syn_ext as ext; +use srml_support_procedural_tools::{generate_crate_access, generate_hidden_includes, clean_type_string}; + +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; + +use syn::{ + Ident, + GenericParam, + spanned::Spanned, + parse::{ + Error, + Result, + } +}; + +use super::*; + +// try macro but returning tokenized error +macro_rules! try_tok(( $expre : expr ) => { + match $expre { + Ok(r) => r, + Err (err) => { + return err.to_compile_error().into() + } + } +}); + +pub fn decl_storage_impl(input: TokenStream) -> TokenStream { + let def = parse_macro_input!(input as StorageDefinition); + + let StorageDefinition { + hidden_crate, + visibility, + ident: storetype, + module_ident, + mod_param: strait, + crate_ident: cratename, + content: ext::Braces { content: storage_lines, ..}, + extra_genesis, + .. + } = def; + let hidden_crate_name = hidden_crate.map(|rc| rc.ident.content).map(|i| i.to_string()) + .unwrap_or_else(|| "decl_storage".to_string()); + let scrate = generate_crate_access(&hidden_crate_name, "srml-support"); + let scrate_decl = generate_hidden_includes( + &hidden_crate_name, + "srml-support", + "srml_support", + ); + + let ( + traitinstance, + traittypes, + ) = if let GenericParam::Type(syn::TypeParam {ident, bounds, ..}) = strait { + (ident, bounds) + } else { + return try_tok!(Err(Error::new(strait.span(), "Missing declare store generic params"))); + }; + + let traittype = if let Some(traittype) = traittypes.first() { + traittype.into_value() + } else { + return try_tok!(Err(Error::new(traittypes.span(), "Trait bound expected"))); + }; + + let extra_genesis = try_tok!(decl_store_extra_genesis( + &scrate, + &traitinstance, + &traittype, + &storage_lines, + &extra_genesis, + )); + let decl_storage_items = decl_storage_items( + &scrate, + &traitinstance, + &traittype, + &cratename, + &storage_lines, + ); + let decl_store_items = decl_store_items( + &storage_lines, + ); + let impl_store_items = impl_store_items( + &traitinstance, + &storage_lines, + ); + let impl_store_fns = impl_store_fns( + &scrate, + &traitinstance, + &storage_lines, + ); + let (store_default_struct, store_functions_to_metadata) = store_functions_to_metadata( + &scrate, + &traitinstance, + &traittype, + &storage_lines, + ); + let cratename_string = cratename.to_string(); + let expanded = quote! { + #scrate_decl + #decl_storage_items + #visibility trait #storetype { + #decl_store_items + } + #store_default_struct + impl<#traitinstance: #traittype> #storetype for #module_ident<#traitinstance> { + #impl_store_items + } + impl<#traitinstance: 'static + #traittype> #module_ident<#traitinstance> { + #impl_store_fns + pub fn store_metadata() -> #scrate::storage::generator::StorageMetadata { + #scrate::storage::generator::StorageMetadata { + prefix: #scrate::storage::generator::DecodeDifferent::Encode(#cratename_string), + functions: #store_functions_to_metadata , + } + } + } + + #extra_genesis + + }; + + expanded.into() +} + +fn decl_store_extra_genesis( + scrate: &TokenStream2, + traitinstance: &Ident, + traittype: &syn::TypeParamBound, + storage_lines: &ext::Punctuated, + extra_genesis: &Option, +) -> Result { + + let mut is_trait_needed = false; + let mut has_trait_field = false; + let mut serde_complete_bound = std::collections::HashSet::new(); + let mut config_field = TokenStream2::new(); + let mut config_field_default = TokenStream2::new(); + let mut builders = TokenStream2::new(); + for sline in storage_lines.inner.iter() { + + let DeclStorageLine { + name, + getter, + config, + build, + storage_type, + default_value, + .. + } = sline; + + let type_infos = get_type_infos(storage_type); + + let mut opt_build; + // need build line + if let (Some(ref getter), Some(ref config)) = (getter, config) { + let ident = if let Some(ident) = config.expr.content.as_ref() { + quote!( #ident ) + } else { + let ident = &getter.getfn.content; + quote!( #ident ) + }; + if type_infos.is_simple && ext::has_parametric_type(type_infos.full_type, traitinstance) { + is_trait_needed = true; + has_trait_field = true; + } + for t in ext::get_non_bound_serde_derive_types(type_infos.full_type, &traitinstance).into_iter() { + serde_complete_bound.insert(t); + } + if let Some(kt) = type_infos.map_key { + for t in ext::get_non_bound_serde_derive_types(kt, &traitinstance).into_iter() { + serde_complete_bound.insert(t); + } + } + let storage_type = type_infos.typ.clone(); + config_field.extend(quote!( pub #ident: #storage_type, )); + opt_build = Some(build.as_ref().map(|b| &b.expr.content).map(|b|quote!( #b )) + .unwrap_or_else(|| quote!( (|config: &GenesisConfig<#traitinstance>| config.#ident.clone()) ))); + let fielddefault = default_value.inner.get(0).as_ref().map(|d| &d.expr).map(|d| + if type_infos.is_option { + quote!( #d.unwrap_or_default() ) + } else { + quote!( #d ) + }).unwrap_or_else(|| quote!( Default::default() )); + config_field_default.extend(quote!( #ident: #fielddefault, )); + + } else { + opt_build = build.as_ref().map(|b| &b.expr.content).map(|b| quote!( #b )); + } + + let typ = type_infos.typ; + if let Some(builder) = opt_build { + is_trait_needed = true; + if type_infos.is_simple { + builders.extend(quote!{{ + use #scrate::codec::Encode; + let v = (#builder)(&self); + r.insert(Self::hash( + <#name<#traitinstance> as #scrate::storage::generator::StorageValue<#typ>>::key() + ).to_vec(), v.encode()); + }}); + } else { + let kty = type_infos.map_key.clone().expect("is not simple; qed"); + builders.extend(quote!{{ + use #scrate::codec::Encode; + let data = (#builder)(&self); + for (k, v) in data.into_iter() { + let key = <#name<#traitinstance> as #scrate::storage::generator::StorageMap<#kty, #typ>>::key_for(&k); + r.insert(Self::hash(&key[..]).to_vec(), v.encode()); + } + }}); + } + } + + } + + let mut has_scall = false; + let mut scall = quote!{ ( |_, _, _| {} ) }; + let mut genesis_extrafields = TokenStream2::new(); + let mut genesis_extrafields_default = TokenStream2::new(); + + // extra genesis + if let Some(eg) = extra_genesis { + for ex_content in eg.content.content.lines.inner.iter() { + match ex_content { + AddExtraGenesisLineEnum::AddExtraGenesisLine(AddExtraGenesisLine { + attrs, + extra_field, + extra_type, + default_value, + .. + }) => { + if ext::has_parametric_type(&extra_type, traitinstance) { + is_trait_needed = true; + has_trait_field = true; + } + + for t in ext::get_non_bound_serde_derive_types(extra_type, &traitinstance).into_iter() { + serde_complete_bound.insert(t); + } + + let extrafield = &extra_field.content; + genesis_extrafields.extend(quote!{ + #attrs pub #extrafield: #extra_type, + }); + let extra_default = default_value.inner.get(0).map(|d| &d.expr).map(|e| quote!{ #e }) + .unwrap_or_else(|| quote!( Default::default() )); + genesis_extrafields_default.extend(quote!{ + #extrafield: #extra_default, + }); + }, + AddExtraGenesisLineEnum::AddExtraGenesisBuild(DeclStorageBuild{ expr, .. }) => { + if has_scall { + return Err(Error::new(expr.span(), "Only one build expression allowed for extra genesis")); + } + let content = &expr.content; + scall = quote!( ( #content ) ); + has_scall = true; + }, + } + } + } + + + let serde_bug_bound = if serde_complete_bound.len() > 0 { + + let mut b_ser = String::new(); + let mut b_dser = String::new(); + for bound in serde_complete_bound { + let stype = quote!(#bound); + b_ser += &(stype.to_string() + " : " + &scrate.to_string() + "::serde::Serialize, "); + b_dser += &(stype.to_string() + " : " + &scrate.to_string() + "::serde::de::DeserializeOwned, "); + } + + quote! { + #[serde(bound(serialize = #b_ser))] + #[serde(bound(deserialize = #b_dser))] + } + } else { + quote!() + }; + + let is_extra_genesis_needed = has_scall + || !config_field.is_empty() + || !genesis_extrafields.is_empty() + || !builders.is_empty(); + Ok(if is_extra_genesis_needed { + let (fparam, sparam, ph_field, ph_default) = if is_trait_needed { + if has_trait_field { + // no phantom data required + ( + quote!(<#traitinstance: #traittype>), + quote!(<#traitinstance>), + quote!(), + quote!(), + ) + } else { + // need phantom data + ( + quote!(<#traitinstance: #traittype>), + quote!(<#traitinstance>), + + quote!{ + #[serde(skip)] + pub _genesis_phantom_data: #scrate::storage::generator::PhantomData<#traitinstance>, + }, + quote!{ + _genesis_phantom_data: Default::default(), + }, + ) + } + } else { + // do not even need type parameter + (quote!(), quote!(), quote!(), quote!()) + }; + quote!{ + + #[derive(Serialize, Deserialize)] + #[cfg(feature = "std")] + #[serde(rename_all = "camelCase")] + #[serde(deny_unknown_fields)] + #serde_bug_bound + pub struct GenesisConfig#fparam { + #ph_field + #config_field + #genesis_extrafields + } + + #[cfg(feature = "std")] + impl#fparam Default for GenesisConfig#sparam { + fn default() -> Self { + GenesisConfig { + #ph_default + #config_field_default + #genesis_extrafields_default + } + } + } + + #[cfg(feature = "std")] + impl#fparam #scrate::runtime_primitives::BuildStorage for GenesisConfig#sparam { + + fn build_storage(self) -> ::std::result::Result<(#scrate::runtime_primitives::StorageMap, #scrate::runtime_primitives::ChildrenStorageMap), String> { + let mut r: #scrate::runtime_primitives::StorageMap = Default::default(); + let mut c: #scrate::runtime_primitives::ChildrenStorageMap = Default::default(); + + #builders + + #scall(&mut r, &mut c, &self); + + Ok((r, c)) + } + } + } + } else { + quote!() + }) +} + +fn decl_storage_items( + scrate: &TokenStream2, + traitinstance: &Ident, + traittype: &syn::TypeParamBound, + cratename: &Ident, + storage_lines: &ext::Punctuated, +) -> TokenStream2 { + + let mut impls = TokenStream2::new(); + for sline in storage_lines.inner.iter() { + let DeclStorageLine { + name, + storage_type, + default_value, + visibility, + .. + } = sline; + + let type_infos = get_type_infos(storage_type); + let gettype = type_infos.full_type; + let fielddefault = default_value.inner.get(0).as_ref().map(|d| &d.expr).map(|d| quote!( #d )) + .unwrap_or_else(|| quote!{ Default::default() }); + + let typ = type_infos.typ; + + let option_simple_1 = if !type_infos.is_option { + // raw type case + quote!( unwrap_or_else ) + } else { + // Option<> type case + quote!( or_else ) + }; + let implementation = if type_infos.is_simple { + let mutate_impl = if !type_infos.is_option { + quote!{ + >::put(&val, storage) + } + } else { + quote!{ + match val { + Some(ref val) => >::put(&val, storage), + None => >::kill(storage), + } + } + }; + + let key_string = cratename.to_string() + " " + &name.to_string(); + // generator for value + quote!{ + + #visibility struct #name<#traitinstance: #traittype>(#scrate::storage::generator::PhantomData<#traitinstance>); + + impl<#traitinstance: #traittype> #scrate::storage::generator::StorageValue<#typ> for #name<#traitinstance> { + type Query = #gettype; + + /// Get the storage key. + fn key() -> &'static [u8] { + #key_string.as_bytes() + } + + /// Load the value from the provided storage instance. + fn get(storage: &S) -> Self::Query { + storage.get(<#name<#traitinstance> as #scrate::storage::generator::StorageValue<#typ>>::key()) + .#option_simple_1(|| #fielddefault) + } + + /// Take a value from storage, removing it afterwards. + fn take(storage: &S) -> Self::Query { + storage.take(<#name<#traitinstance> as #scrate::storage::generator::StorageValue<#typ>>::key()) + .#option_simple_1(|| #fielddefault) + } + + /// Mutate the value under a key. + fn mutate R, S: #scrate::GenericStorage>(f: F, storage: &S) -> R { + let mut val = >::get(storage); + + let ret = f(&mut val); + #mutate_impl ; + ret + } + } + + } + } else { + let kty = type_infos.map_key.expect("is not simple; qed"); + let mutate_impl = if !type_infos.is_option { + quote!{ + >::insert(key, &val, storage) + } + } else { + quote!{ + match val { + Some(ref val) => >::insert(key, &val, storage), + None => >::remove(key, storage), + } + } + }; + let prefix_string = cratename.to_string() + " " + &name.to_string(); + // generator for map + quote!{ + #visibility struct #name<#traitinstance: #traittype>(#scrate::storage::generator::PhantomData<#traitinstance>); + + impl<#traitinstance: #traittype> #scrate::storage::generator::StorageMap<#kty, #typ> for #name<#traitinstance> { + type Query = #gettype; + + /// Get the prefix key in storage. + fn prefix() -> &'static [u8] { + #prefix_string.as_bytes() + } + + /// Get the storage key used to fetch a value corresponding to a specific key. + fn key_for(x: &#kty) -> #scrate::rstd::vec::Vec { + let mut key = <#name<#traitinstance> as #scrate::storage::generator::StorageMap<#kty, #typ>>::prefix().to_vec(); + #scrate::codec::Encode::encode_to(x, &mut key); + key + } + + /// Load the value associated with the given key from the map. + fn get(key: &#kty, storage: &S) -> Self::Query { + let key = <#name<#traitinstance> as #scrate::storage::generator::StorageMap<#kty, #typ>>::key_for(key); + storage.get(&key[..]).#option_simple_1(|| #fielddefault) + } + + /// Take the value, reading and removing it. + fn take(key: &#kty, storage: &S) -> Self::Query { + let key = <#name<#traitinstance> as #scrate::storage::generator::StorageMap<#kty, #typ>>::key_for(key); + storage.take(&key[..]).#option_simple_1(|| #fielddefault) + } + + /// Mutate the value under a key + fn mutate R, S: #scrate::GenericStorage>(key: &#kty, f: F, storage: &S) -> R { + let mut val = >::take(key, storage); + + let ret = f(&mut val); + #mutate_impl ; + ret + } + + } + + } + }; + impls.extend(implementation) + } + impls +} + + +fn decl_store_items( + storage_lines: &ext::Punctuated, +) -> TokenStream2 { + storage_lines.inner.iter().map(|sline| &sline.name) + .fold(TokenStream2::new(), |mut items, name| { + items.extend(quote!(type #name;)); + items + }) +} + +fn impl_store_items( + traitinstance: &Ident, + storage_lines: &ext::Punctuated, +) -> TokenStream2 { + storage_lines.inner.iter().map(|sline| &sline.name) + .fold(TokenStream2::new(), |mut items, name| { + items.extend(quote!(type #name = #name<#traitinstance>;)); + items + }) +} + +fn impl_store_fns( + scrate: &TokenStream2, + traitinstance: &Ident, + storage_lines: &ext::Punctuated, +) -> TokenStream2 { + let mut items = TokenStream2::new(); + for sline in storage_lines.inner.iter() { + let DeclStorageLine { + name, + getter, + storage_type, + .. + } = sline; + + if let Some(getter) = getter { + let get_fn = &getter.getfn.content; + + let type_infos = get_type_infos(storage_type); + let gettype = type_infos.full_type; + + let typ = type_infos.typ; + let item = if type_infos.is_simple { + quote!{ + pub fn #get_fn() -> #gettype { + <#name<#traitinstance> as #scrate::storage::generator::StorageValue<#typ>> :: get(&#scrate::storage::RuntimeStorage) + } + } + } else { + let kty = type_infos.map_key.expect("is not simple; qed"); + // map + quote!{ + pub fn #get_fn>(key: K) -> #gettype { + <#name<#traitinstance> as #scrate::storage::generator::StorageMap<#kty, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage) + } + } + }; + items.extend(item); + } + } + items +} + +fn store_functions_to_metadata ( + scrate: &TokenStream2, + traitinstance: &Ident, + traittype: &syn::TypeParamBound, + storage_lines: &ext::Punctuated, +) -> (TokenStream2, TokenStream2) { + + let mut items = TokenStream2::new(); + let mut default_getter_struct_def = TokenStream2::new(); + for sline in storage_lines.inner.iter() { + let DeclStorageLine { + attrs, + name, + storage_type, + default_value, + .. + } = sline; + + let type_infos = get_type_infos(storage_type); + let gettype = type_infos.full_type; + + let typ = type_infos.typ; + let stype = if type_infos.is_simple { + let styp = clean_type_string(&typ.to_string()); + quote!{ + #scrate::storage::generator::StorageFunctionType::Plain( + #scrate::storage::generator::DecodeDifferent::Encode(#styp), + ) + } + } else { + let kty = type_infos.map_key.expect("is not simple; qed"); + let kty = clean_type_string("e!(#kty).to_string()); + let styp = clean_type_string(&typ.to_string()); + quote!{ + #scrate::storage::generator::StorageFunctionType::Map { + key: #scrate::storage::generator::DecodeDifferent::Encode(#kty), + value: #scrate::storage::generator::DecodeDifferent::Encode(#styp), + } + } + }; + let modifier = if type_infos.is_option { + quote!{ + #scrate::storage::generator::StorageFunctionModifier::Optional + } + } else { + quote!{ + #scrate::storage::generator::StorageFunctionModifier::Default + } + }; + let default = default_value.inner.get(0).as_ref().map(|d| &d.expr) + .map(|d| { + quote!( #d ) + }) + .unwrap_or_else(|| quote!( Default::default() )); + let mut docs = TokenStream2::new(); + for attr in attrs.inner.iter().filter_map(|v| v.interpret_meta()) { + if let syn::Meta::NameValue(syn::MetaNameValue{ + ref ident, + ref lit, + .. + }) = attr { + if ident == "doc" { + docs.extend(quote!(#lit,)); + } + } + } + let str_name = name.to_string(); + let struct_name = proc_macro2::Ident::new(&("__GetByteStruct".to_string() + &str_name), name.span()); + let cache_name = proc_macro2::Ident::new(&("__CacheGetByteStruct".to_string() + &str_name), name.span()); + let item = quote! { + #scrate::storage::generator::StorageFunctionMetadata { + name: #scrate::storage::generator::DecodeDifferent::Encode(#str_name), + modifier: #modifier, + ty: #stype, + default: #scrate::storage::generator::DecodeDifferent::Encode( + #scrate::storage::generator::DefaultByteGetter( + &#struct_name::<#traitinstance>(#scrate::rstd::marker::PhantomData) + ) + ), + documentation: #scrate::storage::generator::DecodeDifferent::Encode(&[ #docs ]), + }, + }; + items.extend(item); + let def_get = quote! { + pub struct #struct_name<#traitinstance>(pub #scrate::rstd::marker::PhantomData<#traitinstance>); + #[cfg(feature = "std")] + static #cache_name: #scrate::once_cell::sync::OnceCell<#scrate::rstd::vec::Vec> = #scrate::once_cell::sync::OnceCell::INIT; + #[cfg(feature = "std")] + impl<#traitinstance: #traittype> #scrate::storage::generator::DefaultByte for #struct_name<#traitinstance> { + fn default_byte(&self) -> #scrate::rstd::vec::Vec { + use #scrate::codec::Encode; + #cache_name.get_or_init(|| { + let def_val: #gettype = #default; + <#gettype as Encode>::encode(&def_val) + }).clone() + } + } + #[cfg(not(feature = "std"))] + impl<#traitinstance: #traittype> #scrate::storage::generator::DefaultByte for #struct_name<#traitinstance> { + fn default_byte(&self) -> #scrate::rstd::vec::Vec { + use #scrate::codec::Encode; + let def_val: #gettype = #default; + <#gettype as Encode>::encode(&def_val) + } + } + }; + default_getter_struct_def.extend(def_get); + } + (default_getter_struct_def, quote!{ + { + #scrate::storage::generator::DecodeDifferent::Encode(&[ + #items + ]) + } + }) +} + + +struct DeclStorageTypeInfos<'a> { + pub is_simple: bool, + pub full_type: &'a syn::Type, + pub is_option: bool, + pub typ: TokenStream2, + pub map_key: Option<&'a syn::Type>, +} + +fn get_type_infos(storage_type: &DeclStorageType) -> DeclStorageTypeInfos { + let (is_simple, extracted_type, map_key, full_type) = match storage_type { + DeclStorageType::Simple(ref st) => (true, ext::extract_type_option(st), None, st), + DeclStorageType::Map(ref map) => (false, ext::extract_type_option(&map.value), Some(&map.key), &map.value), + }; + let is_option = extracted_type.is_some(); + let typ = extracted_type.unwrap_or(quote!( #full_type )); + DeclStorageTypeInfos { + is_simple, + full_type, + is_option, + typ, + map_key, + } +} + diff --git a/srml/support/procedural/tools/Cargo.toml b/srml/support/procedural/tools/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..c773bc65d8ae1cea2a33982075d98d76efdbbd83 --- /dev/null +++ b/srml/support/procedural/tools/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "srml-support-procedural-tools" +version = "0.1.0" +authors = ["Parity Technologies "] + +[dependencies] +srml-support-procedural-tools-derive = { path = "./derive" } +proc-macro2 = "0.4" +quote = { version = "0.6" } +syn = { version = "0.15", features = ["full"] } diff --git a/srml/support/procedural/tools/derive/Cargo.toml b/srml/support/procedural/tools/derive/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..d55659442e40c6cbafafd8adcb142a21ec01dc04 --- /dev/null +++ b/srml/support/procedural/tools/derive/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "srml-support-procedural-tools-derive" +version = "0.1.0" +authors = ["Parity Technologies "] + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "0.4.24" +quote = { version = "0.6.10", features = ["proc-macro"] } +syn = { version = "0.15.21", features = ["proc-macro" ,"full", "extra-traits", "parsing"] } diff --git a/srml/support/procedural/tools/derive/src/lib.rs b/srml/support/procedural/tools/derive/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..604cba45821bfe8f0e72bd1e20329405fe92b4ca --- /dev/null +++ b/srml/support/procedural/tools/derive/src/lib.rs @@ -0,0 +1,250 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +// tag::description[] +//! Use to derive parsing for parsing struct. +// end::description[] + + +#![recursion_limit = "128"] + +#[macro_use] +extern crate syn; + +#[macro_use] +extern crate quote; + +extern crate proc_macro; +extern crate proc_macro2; + +use proc_macro::TokenStream; +use proc_macro2::Span; + + +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(|| { + let f_ix: syn::Ident = syn::Ident::new(&format!("f_{}", ix), Span::call_site()); + quote!( #f_ix ) + }) + }) +} + +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(|| { + let f_ix: syn::Index = syn::Index { + index: ix as u32, + span: Span::call_site(), + }; + quote!( #f_ix ) + }) + }) +} + +/// self defined parsing struct or enum. +/// not meant for any struct/enum, just for fast +/// parse implementation. +/// For enums: +/// variant are tested in order of definition. +/// Empty variant is always true. +/// Please use carefully, this will fully parse successfull variant twice. +#[proc_macro_derive(Parse)] +pub fn derive_parse(input: TokenStream) -> TokenStream { + let item = parse_macro_input!(input as syn::Item); + match item { + syn::Item::Enum(input) => derive_parse_enum(input), + syn::Item::Struct(input) => derive_parse_struct(input), + _ => TokenStream::new(), // ignore + } +} + +fn derive_parse_struct(input: syn::ItemStruct) -> TokenStream { + let syn::ItemStruct { + ident, + generics, + fields, + .. + } = input; + let field_names = { + let name = fields_idents(fields.iter().map(Clone::clone)); + quote!{ + #( + #name, + )* + } + }; + let field = fields_idents(fields.iter().map(Clone::clone)); + let tokens = quote! { + impl #generics syn::parse::Parse for #ident #generics { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { + #( + let #field = input.parse()?; + )* + Ok(Self { + #field_names + }) + } + } + }; + tokens.into() +} + +fn derive_parse_enum(input: syn::ItemEnum) -> TokenStream { + let syn::ItemEnum { + ident, + generics, + variants, + .. + } = input; + let variants = variants.iter().map(|v| { + let variant_ident = v.ident.clone(); + let fields_build = if v.fields.iter().count() > 0 { + let fields_id = fields_idents(v.fields.iter().map(Clone::clone)); + quote!( (#(#fields_id), *) ) + } else { + quote!() + }; + + let fields_procs = fields_idents(v.fields.iter().map(Clone::clone)) + .map(|fident| { + quote!{ + let mut #fident = match fork.parse() { + Ok(r) => r, + Err(_e) => break, + }; + } + }); + let fields_procs_again = fields_idents(v.fields.iter().map(Clone::clone)) + .map(|fident| { + quote!{ + #fident = input.parse().expect("was parsed just before"); + } + }); + + // double parse to update input cursor position + // next syn crate version should be checked for a way + // to copy position/state from a fork + quote!{ + let mut fork = input.fork(); + loop { + #(#fields_procs)* + #(#fields_procs_again)* + return Ok(#ident::#variant_ident#fields_build); + } + } + }); + + let tokens = quote! { + impl #generics syn::parse::Parse for #ident #generics { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { + #( + #variants + )* + // no early return from any variants + Err( + syn::parse::Error::new( + proc_macro2::Span::call_site(), + "derived enum no matching variants" + ) + ) + } + } + + }; + tokens.into() +} + +/// self defined parsing struct or enum. +/// not meant for any struct/enum, just for fast +/// parse implementation. +/// For enum: +/// it only output fields (empty field act as a None). +#[proc_macro_derive(ToTokens)] +pub fn derive_totokens(input: TokenStream) -> TokenStream { + let item = parse_macro_input!(input as syn::Item); + match item { + syn::Item::Enum(input) => derive_totokens_enum(input), + syn::Item::Struct(input) => derive_totokens_struct(input), + _ => TokenStream::new(), // ignore + } +} + +fn derive_totokens_struct(input: syn::ItemStruct) -> TokenStream { + let syn::ItemStruct { + ident, + generics, + fields, + .. + } = input; + + let fields = fields_access(fields.iter().map(Clone::clone)); + let tokens = quote! { + + impl #generics quote::ToTokens for #ident #generics { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + #( + self.#fields.to_tokens(tokens); + )* + } + } + + }; + tokens.into() +} + +fn derive_totokens_enum(input: syn::ItemEnum) -> TokenStream { + let syn::ItemEnum { + ident, + generics, + variants, + .. + } = input; + let variants = variants.iter().map(|v| { + let v_ident = v.ident.clone(); + let fields_build = if v.fields.iter().count() > 0 { + let fields_id = fields_idents(v.fields.iter().map(Clone::clone)); + quote!( (#(#fields_id), *) ) + } else { + quote!() + }; + let field = fields_idents(v.fields.iter().map(Clone::clone)); + quote! { + #ident::#v_ident#fields_build => { + #( + #field.to_tokens(tokens); + )* + }, + } + }); + let tokens = quote! { + impl #generics quote::ToTokens for #ident #generics { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + match self { + #( + #variants + )* + } + } + } + }; + + tokens.into() +} diff --git a/srml/support/procedural/tools/src/lib.rs b/srml/support/procedural/tools/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..1dae39fce43455f17a797d2288d746150ec5009a --- /dev/null +++ b/srml/support/procedural/tools/src/lib.rs @@ -0,0 +1,113 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +// tag::description[] +//! Proc macro helpers for procedural macros +// end::description[] + +extern crate syn; +#[macro_use] +extern crate quote; +extern crate proc_macro2; + +extern crate proc_macro; + +#[macro_use] extern crate srml_support_procedural_tools_derive; + +// reexport proc macros +pub use srml_support_procedural_tools_derive::*; + +pub mod syn_ext; + +#[macro_export] +macro_rules! custom_keyword_impl { + ($name:ident, $keyident:expr, $keydisp:expr) => { + + impl CustomKeyword for $name { + fn ident() -> &'static str { $keyident } + fn display() -> &'static str { $keydisp } + } + + } +} + +#[macro_export] +macro_rules! custom_keyword { + ($name:ident, $keyident:expr, $keydisp:expr) => { + + #[derive(Debug)] + struct $name; + + custom_keyword_impl!($name, $keyident, $keydisp); + + } +} + + +// TODO following functions are copied from sr-api-macros : do a merge to get a unique procedural +// macro tooling crate (this crate path does not look good for it) + +use proc_macro2::{TokenStream, Span}; +use syn::Ident; + +fn generate_hidden_includes_mod_name(unique_id: &str) -> Ident { + Ident::new(&format!("sr_api_hidden_includes_{}", unique_id), Span::call_site()) +} + +/// Generates the access to the `subtrate_client` crate. +pub fn generate_crate_access(unique_id: &str, def_crate: &str) -> TokenStream { + if ::std::env::var("CARGO_PKG_NAME").unwrap() == def_crate { + quote!( crate ) + } else { + let mod_name = generate_hidden_includes_mod_name(unique_id); + quote!( self::#mod_name::hidden_include ) + }.into() +} + +/// Generates the hidden includes that are required to make the macro independent from its scope. +pub fn generate_hidden_includes(unique_id: &str, def_crate: &str, crate_id: &str) -> TokenStream { + let crate_id = Ident::new(crate_id, Span::call_site()); + if ::std::env::var("CARGO_PKG_NAME").unwrap() == def_crate { + TokenStream::new() + } else { + let mod_name = generate_hidden_includes_mod_name(unique_id); + quote!( + #[doc(hidden)] + mod #mod_name { + pub extern crate #crate_id as hidden_include; + } + ) + }.into() +} + +// fn to remove white spaces arount string types +// (basically whitespaces arount tokens) +pub fn clean_type_string(input: &str) -> String { + input + .replace(" ::", "::") + .replace(":: ", "::") + .replace(" ,", ",") + .replace(" ;", ";") + .replace(" [", "[") + .replace("[ ", "[") + .replace(" ]", "]") + .replace(" (", "(") + .replace("( ", "(") + .replace(" )", ")") + .replace(" <", "<") + .replace("< ", "<") + .replace(" >", ">") +} diff --git a/srml/support/procedural/tools/src/syn_ext.rs b/srml/support/procedural/tools/src/syn_ext.rs new file mode 100644 index 0000000000000000000000000000000000000000..3a93a5c53321e4d6ffbef3042083f2342e430b7c --- /dev/null +++ b/srml/support/procedural/tools/src/syn_ext.rs @@ -0,0 +1,390 @@ +// Copyright 2017-2018 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +// tag::description[] +//! Extension to syn types, mainly for parsing +// end::description[] + +use syn::parse::{ + Parse, + ParseStream, + Result, +}; +use syn::token::CustomKeyword; +use proc_macro2::TokenStream as T2; +use quote::ToTokens; +use std::iter::once; +use syn::Ident; + +/// stop parsing here getting remaining token as content +/// Warn duplicate stream (part of) +#[derive(Parse, ToTokens, Debug)] +pub struct StopParse { + pub inner: T2, +} + +// inner macro really dependant on syn naming convention, do not export +macro_rules! groups_impl { + ($name:ident, $tok:ident, $deli:ident, $parse:ident) => { + + #[derive(Debug)] + pub struct $name

{ + pub token: syn::token::$tok, + pub content: P, + } + + impl Parse for $name

{ + fn parse(input: ParseStream) -> Result { + let syn::group::$name { token, content } = syn::group::$parse(input)?; + let content = content.parse()?; + Ok($name { token, content, }) + } + } + + impl ToTokens for $name

{ + fn to_tokens(&self, tokens: &mut T2) { + let mut inner_stream = T2::new(); + self.content.to_tokens(&mut inner_stream); + let token_tree: proc_macro2::TokenTree = + proc_macro2::Group::new(proc_macro2::Delimiter::$deli, inner_stream).into(); + tokens.extend(once(token_tree)); + } + } + + } +} + +groups_impl!(Braces, Brace, Brace, parse_braces); +groups_impl!(Brackets, Bracket, Bracket, parse_brackets); +groups_impl!(Parens, Paren, Parenthesis, parse_parens); + +#[derive(Debug)] +pub struct CustomToken(std::marker::PhantomData); + +impl Parse for CustomToken { + fn parse(input: ParseStream) -> Result { + let ident: syn::Ident = input.parse()?; + + if ident.to_string().as_str() != T::ident() { + return Err(syn::parse::Error::new_spanned(ident, "expected another custom token")) + } + Ok(CustomToken(std::marker::PhantomData)) + } +} + +impl ToTokens for CustomToken { + fn to_tokens(&self, tokens: &mut T2) { + use std::str::FromStr; + tokens.extend(T2::from_str(T::ident()).expect("custom keyword should parse to ident")); + } +} + +impl CustomKeyword for CustomToken { + fn ident() -> &'static str { ::ident() } + fn display() -> &'static str { ::display() } +} + +#[derive(Debug)] +pub struct PunctuatedInner { + pub inner: syn::punctuated::Punctuated, + pub variant: V, +} + +#[derive(Debug)] +pub struct NoTrailing; + + +#[derive(Debug)] +pub struct Trailing; + +pub type Punctuated = PunctuatedInner; + +pub type PunctuatedTrailing = PunctuatedInner; + +impl Parse for PunctuatedInner { + fn parse(input: ParseStream) -> Result { + Ok(PunctuatedInner { + inner: syn::punctuated::Punctuated::parse_separated_nonempty(input)?, + variant: Trailing, + }) + } +} + +impl Parse for PunctuatedInner { + fn parse(input: ParseStream) -> Result { + Ok(PunctuatedInner { + inner: syn::punctuated::Punctuated::parse_terminated(input)?, + variant: NoTrailing, + }) + } +} + +impl ToTokens for PunctuatedInner { + fn to_tokens(&self, tokens: &mut T2) { + self.inner.to_tokens(tokens) + } +} + +/// Note that syn Meta is almost fine for use case (lacks only `ToToken`) +#[derive(Debug, Clone)] +pub struct Meta { + pub inner: syn::Meta, +} + +impl Parse for Meta { + fn parse(input: ParseStream) -> Result { + Ok(Meta { + inner: syn::Meta::parse(input)?, + }) + } +} + +impl ToTokens for Meta { + fn to_tokens(&self, tokens: &mut T2) { + match self.inner { + syn::Meta::Word(ref ident) => { + let ident = ident.clone(); + let toks = quote!{ + #[#ident] + }; + tokens.extend(toks); + }, + syn::Meta::List(ref l) => l.to_tokens(tokens), + syn::Meta::NameValue(ref n) => n.to_tokens(tokens), + } + } +} + +#[derive(Debug)] +pub struct OuterAttributes { + pub inner: Vec, +} + +impl Parse for OuterAttributes { + fn parse(input: ParseStream) -> Result { + let inner = syn::Attribute::parse_outer(input)?; + Ok(OuterAttributes { + inner, + }) + } +} + +impl ToTokens for OuterAttributes { + fn to_tokens(&self, tokens: &mut T2) { + for att in self.inner.iter() { + att.to_tokens(tokens); + } + } +} + +#[derive(Debug)] +pub struct Seq

{ + pub inner: Vec

, +} + +impl Parse for Seq

{ + // Note that it cost a double parsing (same as enum derive) + fn parse(input: ParseStream) -> Result { + let mut inner = Vec::new(); + loop { + let fork = input.fork(); + let res: Result

= fork.parse(); + match res { + Ok(_item) => { + // move cursor + let item: P = input.parse().expect("Same parsing ran before"); + inner.push(item); + }, + Err(_e) => break, + } + } + Ok(Seq { inner }) + } +} + +impl ToTokens for Seq

{ + fn to_tokens(&self, tokens: &mut T2) { + for p in self.inner.iter() { + p.to_tokens(tokens); + } + } +} + +pub fn extract_type_option(typ: &syn::Type) -> Option { + if let syn::Type::Path(ref path) = typ { + path.path.segments.last().and_then(|v| { + if v.value().ident == "Option" { + if let syn::PathArguments::AngleBracketed(ref a) = v.value().arguments { + let args = &a.args; + Some(quote!{ #args }) + } else { + None + } + } else { + None + } + }) + } else { + None + } +} + +pub fn is_parametric_type_def(typ: &syn::Type, default: bool) -> bool { + match *typ { + syn::Type::Path(ref path) => { + path.path.segments.iter().any(|v| { + if let syn::PathArguments::AngleBracketed(..) = v.arguments { + true + } else { + false + } + }) + }, + syn::Type::Slice(ref inner) => is_parametric_type_def(&inner.elem, default), + syn::Type::Array(ref inner) => is_parametric_type_def(&inner.elem, default), + syn::Type::Ptr(ref inner) => is_parametric_type_def(&inner.elem, default), + syn::Type::Reference(ref inner) => is_parametric_type_def(&inner.elem, default), + syn::Type::BareFn(ref inner) => inner.variadic.is_some(), + syn::Type::Never(..) => false, + syn::Type::Tuple(ref inner) => + inner.elems.iter().any(|t| is_parametric_type_def(t, default)), + syn::Type::TraitObject(..) => true, + syn::Type::ImplTrait(..) => true, + syn::Type::Paren(ref inner) => is_parametric_type_def(&inner.elem, default), + syn::Type::Group(ref inner) => is_parametric_type_def(&inner.elem, default), + syn::Type::Infer(..) => true, + syn::Type::Macro(..) => default, + syn::Type::Verbatim(..) => default, + } +} + +/// check if type has any type parameter, defaults to true for some cases. +pub fn is_parametric_type(typ: &syn::Type) -> bool { + is_parametric_type_def(typ, true) +} + +fn has_parametric_type_def_in_path(path: &syn::Path, ident: &Ident, default: bool) -> bool { + path.segments.iter().any(|v| { + if ident == &v.ident { + return true; + } + if let syn::PathArguments::AngleBracketed(ref a) = v.arguments { + for arg in a.args.iter() { + if let syn::GenericArgument::Type(ref typ) = arg { + if has_parametric_type_def(typ, ident, default) { + return true; + } + } + // potentially missing matches here + } + false + } else { + false + } + }) + +} +pub fn has_parametric_type_def(typ: &syn::Type, ident: &Ident, default: bool) -> bool { + match *typ { + syn::Type::Path(ref path) => has_parametric_type_def_in_path(&path.path, ident, default), + syn::Type::Slice(ref inner) => has_parametric_type_def(&inner.elem, ident, default), + syn::Type::Array(ref inner) => has_parametric_type_def(&inner.elem, ident, default), + syn::Type::Ptr(ref inner) => has_parametric_type_def(&inner.elem, ident, default), + syn::Type::Reference(ref inner) => has_parametric_type_def(&inner.elem, ident, default), + syn::Type::BareFn(ref inner) => inner.variadic.is_some(), + syn::Type::Never(..) => false, + syn::Type::Tuple(ref inner) => + inner.elems.iter().any(|t| has_parametric_type_def(t, ident, default)), + syn::Type::TraitObject(ref to) => { + to.bounds.iter().any(|bound| { + if let syn::TypeParamBound::Trait(ref t) = bound { + has_parametric_type_def_in_path(&t.path, ident, default) + } else { false } + }) + }, + syn::Type::ImplTrait(ref it) => { + it.bounds.iter().any(|bound| { + if let syn::TypeParamBound::Trait(ref t) = bound { + has_parametric_type_def_in_path(&t.path, ident, default) + } else { false } + }) + }, + syn::Type::Paren(ref inner) => has_parametric_type_def(&inner.elem, ident, default), + syn::Type::Group(ref inner) => has_parametric_type_def(&inner.elem, ident, default), + syn::Type::Infer(..) => default, + syn::Type::Macro(..) => default, + syn::Type::Verbatim(..) => default, + } +} + +/// check if type has a type parameter, defaults to true for some cases. +pub fn has_parametric_type(typ: &syn::Type, ident: &Ident) -> bool { + has_parametric_type_def(typ, ident, true) +} + +/// Get case where serde does not include bound with serde_derive macros: +/// see https://github.com/serde-rs/serde/issues/1454 +pub fn get_non_bound_serde_derive_types(typ: &syn::Type, t: &syn::Ident) -> Vec { + let mut result = Vec::new(); + get_non_bound_serde_derive_types_inner(typ, t, &mut result); + result +} + +fn get_non_bound_serde_derive_types_inner(typ: &syn::Type, t: &syn::Ident, result: &mut Vec) { + match *typ { + syn::Type::Path(ref path) => { + if heuristic_is_associated_path(&path.path,t) { + result.push(typ.clone()); + } + for p in path.path.segments.iter() { + if let syn::PathArguments::AngleBracketed(ref args) = p.arguments { + for a in args.args.iter() { + if let syn::GenericArgument::Type(ref ty) = a { + get_non_bound_serde_derive_types_inner(ty, t, result) + } + } + } + } + }, + syn::Type::Slice(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result), + syn::Type::Array(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result), + syn::Type::Ptr(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result), + syn::Type::Reference(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result), + syn::Type::BareFn(..) => (), + syn::Type::Never(..) => (), + syn::Type::Tuple(ref inner) => for e in inner.elems.iter() { + get_non_bound_serde_derive_types_inner(e, t, result) + }, + syn::Type::TraitObject(..) => (), + syn::Type::ImplTrait(..) => (), + syn::Type::Paren(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result), + syn::Type::Group(ref inner) => get_non_bound_serde_derive_types_inner(&inner.elem, t, result), + syn::Type::Infer(..) => (), + syn::Type::Macro(..) => (), + syn::Type::Verbatim(..) => (), + } + +} + +fn heuristic_is_associated_path(path: &syn::Path,t: &syn::Ident) -> bool { + + if let Some(syn::punctuated::Pair::Punctuated(s,_)) = path.segments.first() { + &s.ident == t + } else { + false + } + +} diff --git a/srml/support/src/dispatch.rs b/srml/support/src/dispatch.rs index dd52e35b3cf844673bf68f5b22354325ca69e563..655f35bb90b543908dcbf3b81bcf80c82a27a688 100644 --- a/srml/support/src/dispatch.rs +++ b/srml/support/src/dispatch.rs @@ -14,33 +14,36 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Dispatch system. Just dispatches calls. +//! Dispatch system. Contains a macro for defining runtime modules and +//! generating values representing lazy module function calls. pub use rstd::prelude::{Vec, Clone, Eq, PartialEq}; #[cfg(feature = "std")] pub use std::fmt; pub use rstd::result; -#[cfg(feature = "std")] -use serde; -pub use codec::{Codec, Decode, Encode, Input, Output}; -pub use substrate_metadata::{ +pub use codec::{Codec, Decode, Encode, Input, Output, HasCompact, EncodeAsRef}; +pub use srml_metadata::{ ModuleMetadata, FunctionMetadata, DecodeDifferent, CallMetadata, FunctionArgumentMetadata, OuterDispatchMetadata, OuterDispatchCall }; +/// Result of a module function call; either nothing (functions are only called for "side efeects") +/// or an error message. pub type Result = result::Result<(), &'static str>; +/// A lazy call (module function and argument values) that can be executed via its dispatch() +/// method. pub trait Dispatchable { + /// Every function call to your runtime has an origin which specifies where the extrinsic was + /// generated from. In the case of a signed extrinsic (transaction), the origin contains an + /// identifier for the caller. The origin can be empty in the case of an inherent extrinsic. type Origin; type Trait; fn dispatch(self, origin: Self::Origin) -> Result; } -#[cfg(feature = "std")] -pub trait Callable { - type Call: Dispatchable + Codec + ::serde::Serialize + Clone + PartialEq + Eq; -} -#[cfg(not(feature = "std"))] +/// Serializable version of Dispatchable. +/// This value can be used as a "function" in an extrinsic. pub trait Callable { type Call: Dispatchable + Codec + Clone + PartialEq + Eq; } @@ -50,10 +53,10 @@ pub trait Callable { pub type CallableCallFor = ::Call; #[cfg(feature = "std")] -pub trait Parameter: Codec + serde::Serialize + Clone + Eq + fmt::Debug {} +pub trait Parameter: Codec + Clone + Eq + fmt::Debug {} #[cfg(feature = "std")] -impl Parameter for T where T: Codec + serde::Serialize + Clone + Eq + fmt::Debug {} +impl Parameter for T where T: Codec + Clone + Eq + fmt::Debug {} #[cfg(not(feature = "std"))] pub trait Parameter: Codec + Clone + Eq {} @@ -61,10 +64,34 @@ pub trait Parameter: Codec + Clone + Eq {} #[cfg(not(feature = "std"))] impl Parameter for T where T: Codec + Clone + Eq {} -/// Declare a struct for this module, then implement dispatch logic to create a pairing of several -/// dispatch traits and enums. +/// Declare a module struct and implement the dispatch logic. +/// +/// Usually used as follows: +/// +/// decl_module! { +/// pub struct Module for enum Call where origin: T::Origin +///{} +/// } +/// +/// where "Trait" is a trait describing this module's requirements for the Runtime type. +/// T::Origin is declared using a impl_outer_origin! per-module macro (which is generated by the +/// construct_runtime! macro) and automatically includes all the modules that are used by the +/// runtime (alongside with a variant called "system"). +/// +/// A runtime module is a collection of functions unified by a common problem domain and certain +/// shared types. The "functions" do not actually return values (see Dispatchable) and are only +/// used for side effects. +/// +/// For every module an associated enum (usually "Call") is generated with every variant +/// corresponding to a function of the module. This enum implements Callable and thus its values +/// can be used as an extrinsic's payload. +/// +/// The `on_finalise` function is special, since it can either take no parameters, +/// or one parameter, which has the runtime's block number type. #[macro_export] macro_rules! decl_module { + // Macro transformations (to convert invocations with incomplete parameters to the canonical + // form) ( $(#[$attr:meta])* pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident> @@ -108,14 +135,14 @@ macro_rules! decl_module { { $( $on_finalise:tt )* } [ $($t:tt)* ] $(#[doc = $doc_attr:tt])* - $vis:vis fn deposit_event() = default; + $vis:vis fn deposit_event $(<$dpeg:ident>)* () = default; $($rest:tt)* ) => { decl_module!(@normalize $(#[$attr])* pub struct $mod_type<$trait_instance: $trait_name> for enum $call_type where origin: $origin_type, system = $system - { $vis fn deposit_event() = default; } + { $vis fn deposit_event $(<$dpeg>)* () = default; } { $( $on_finalise )* } [ $($t)* ] $($rest)* @@ -129,14 +156,16 @@ macro_rules! decl_module { { $( $on_finalise:tt )* } [ $($t:tt)* ] $(#[doc = $doc_attr:tt])* - $vis:vis fn deposit_event($($param_name:ident : $param:ty),* ) { $( $impl:tt )* } + $vis:vis fn deposit_event $(<$dpeg:ident>)* ( + $($param_name:ident : $param:ty),* + ) { $( $impl:tt )* } $($rest:tt)* ) => { decl_module!(@normalize $(#[$attr])* pub struct $mod_type<$trait_instance: $trait_name> for enum $call_type where origin: $origin_type, system = $system - { $vis fn deposit_event($( $param_name: $param ),* ) { $( $impl )* } } + { $vis fn deposit_event $(<$dpeg>)* ($( $param_name: $param ),* ) { $( $impl )* } } { $( $on_finalise )* } [ $($t)* ] $($rest)* @@ -171,7 +200,9 @@ macro_rules! decl_module { { $( $on_finalise:tt )* } [ $($t:tt)* ] $(#[doc = $doc_attr:tt])* - $fn_vis:vis fn $fn_name:ident($origin:ident $(, $param_name:ident : $param:ty)* ) -> $result:ty { $( $impl:tt )* } + $fn_vis:vis fn $fn_name:ident( + $origin:ident $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { decl_module!(@normalize @@ -183,7 +214,9 @@ macro_rules! decl_module { [ $($t)* $(#[doc = $doc_attr])* - $fn_vis fn $fn_name($origin $( , $param_name : $param )* ) -> $result { $( $impl )* } + $fn_vis fn $fn_name( + $origin $( , $(#[$codec_attr])* $param_name : $param )* + ) $( -> $result )* { $( $impl )* } ] $($rest)* ); @@ -196,7 +229,47 @@ macro_rules! decl_module { { $( $on_finalise:tt )* } [ $($t:tt)* ] $(#[doc = $doc_attr:tt])* - $fn_vis:vis fn $fn_name:ident($( $param_name:ident : $param:ty),* ) -> $result:ty { $( $impl:tt )* } + $fn_vis:vis fn $fn_name:ident( + $origin:ident : T::Origin $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + ) $( -> $result:ty )* { $( $impl:tt )* } + $($rest:tt)* + ) => { + compile_error!( + "First parameter of dispatch should be marked `origin` only, with no type specified \ + (a bit like `self`). (For root-matching dispatches, ensure the first parameter does \ + not use the `T::Origin` type.)" + ) + }; + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident> + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $deposit_event:tt )* } + { $( $on_finalise:tt )* } + [ $($t:tt)* ] + $(#[doc = $doc_attr:tt])* + $fn_vis:vis fn $fn_name:ident( + origin : $origin:ty $(, $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + ) $( -> $result:ty )* { $( $impl:tt )* } + $($rest:tt)* + ) => { + compile_error!( + "First parameter of dispatch should be marked `origin` only, with no type specified \ + (a bit like `self`). (For root-matching dispatches, ensure the first parameter does \ + not use the `T::Origin` type.)" + ) + }; + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident> + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $deposit_event:tt )* } + { $( $on_finalise:tt )* } + [ $($t:tt)* ] + $(#[doc = $doc_attr:tt])* + $fn_vis:vis fn $fn_name:ident( + $( $(#[$codec_attr:ident])* $param_name:ident : $param:ty),* + ) $( -> $result:ty )* { $( $impl:tt )* } $($rest:tt)* ) => { decl_module!(@normalize @@ -208,7 +281,9 @@ macro_rules! decl_module { [ $($t)* $(#[doc = $doc_attr])* - $fn_vis fn $fn_name(root $( , $param_name : $param )* ) -> $result { $( $impl )* } + $fn_vis fn $fn_name( + root $( , $(#[$codec_attr])* $param_name : $param )* + ) $( -> $result )* { $( $impl )* } ] $($rest)* ); @@ -232,6 +307,9 @@ macro_rules! decl_module { ); }; + // Implementation of Call enum's .dispatch() method. + // TODO: this probably should be a different macro? + (@call root $mod_type:ident $trait_instance:ident $fn_name:ident $origin:ident $system:ident [ $( $param_name:ident),* ] @@ -254,10 +332,26 @@ macro_rules! decl_module { $system:ident; ) => {}; + // Non-generic event (@impl_deposit_event $module:ident<$trait_instance:ident: $trait_name:ident>; $system:ident; $vis:vis fn deposit_event() = default; + ) => { + impl<$trait_instance: $trait_name> $module<$trait_instance> { + $vis fn deposit_event(event: Event) { + <$system::Module<$trait_instance>>::deposit_event( + <$trait_instance as $trait_name>::Event::from(event).into() + ); + } + } + }; + + // Generic event + (@impl_deposit_event + $module:ident<$trait_instance:ident: $trait_name:ident>; + $system:ident; + $vis:vis fn deposit_event<$ignore:ident>() = default; ) => { impl<$trait_instance: $trait_name> $module<$trait_instance> { $vis fn deposit_event(event: Event<$trait_instance>) { @@ -314,7 +408,23 @@ macro_rules! decl_module { $module:ident<$trait_instance:ident: $trait_name:ident>; $origin_ty:ty; root; - $vis:vis fn $name:ident ( root $(, $param:ident : $param_ty:ty )* ) -> $result:ty { $( $impl:tt )* } + $vis:vis fn $name:ident ( root $(, $param:ident : $param_ty:ty )* ) { $( $impl:tt )* } + ) => { + impl<$trait_instance: $trait_name> $module<$trait_instance> { + $vis fn $name($( $param: $param_ty ),* ) -> $crate::dispatch::Result { + { $( $impl )* } + Ok(()) + } + } + }; + + (@impl_function + $module:ident<$trait_instance:ident: $trait_name:ident>; + $origin_ty:ty; + root; + $vis:vis fn $name:ident ( + root $(, $param:ident : $param_ty:ty )* + ) -> $result:ty { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name> $module<$trait_instance> { $vis fn $name($( $param: $param_ty ),* ) -> $result { @@ -322,11 +432,32 @@ macro_rules! decl_module { } } }; + (@impl_function $module:ident<$trait_instance:ident: $trait_name:ident>; $origin_ty:ty; $ignore:ident; - $vis:vis fn $name:ident ( $origin:ident $(, $param:ident : $param_ty:ty )* ) -> $result:ty { $( $impl:tt )* } + $vis:vis fn $name:ident ( + $origin:ident $(, $param:ident : $param_ty:ty )* + ) { $( $impl:tt )* } + ) => { + impl<$trait_instance: $trait_name> $module<$trait_instance> { + $vis fn $name( + $origin: $origin_ty $(, $param: $param_ty )* + ) -> $crate::dispatch::Result { + { $( $impl )* } + Ok(()) + } + } + }; + + (@impl_function + $module:ident<$trait_instance:ident: $trait_name:ident>; + $origin_ty:ty; + $ignore:ident; + $vis:vis fn $name:ident ( + $origin:ident $(, $param:ident : $param_ty:ty )* + ) -> $result:ty { $( $impl:tt )* } ) => { impl<$trait_instance: $trait_name> $module<$trait_instance> { $vis fn $name($origin: $origin_ty $(, $param: $param_ty )* ) -> $result { @@ -335,6 +466,8 @@ macro_rules! decl_module { } }; + // The main macro expansion that actually renders the module code. + (@imp $(#[$attr:meta])* pub struct $mod_type:ident<$trait_instance:ident: $trait_name:ident> @@ -342,8 +475,8 @@ macro_rules! decl_module { $( $(#[doc = $doc_attr:tt])* $fn_vis:vis fn $fn_name:ident( - $from:ident $( , $param_name:ident : $param:ty)* - ) -> $result:ty { $( $impl:tt )* } + $from:ident $( , $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* + ) $( -> $result:ty )* { $( $impl:tt )* } )* } { $( $deposit_event:tt )* } @@ -351,7 +484,7 @@ macro_rules! decl_module { ) => { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, Copy, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] + #[cfg_attr(feature = "std", derive(Debug))] // TODO: switching based on std feature is because of an issue in // serde-derive for when we attempt to derive `Deserialize` on these types, // in a situation where we've imported `srml_support` as another name. @@ -360,7 +493,7 @@ macro_rules! decl_module { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, Copy, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] + #[cfg_attr(feature = "std", derive(Debug))] #[cfg(not(feature = "std"))] pub struct $mod_type<$trait_instance: $trait_name>(::core::marker::PhantomData<$trait_instance>); @@ -383,13 +516,14 @@ macro_rules! decl_module { $mod_type<$trait_instance: $trait_name>; $origin_type; $from; - $fn_vis fn $fn_name ($from $(, $param_name : $param )* ) -> $result { $( $impl )* } + $fn_vis fn $fn_name ( + $from $(, $param_name : $param )* + ) $( -> $result )* { $( $impl )* } } )* #[cfg(feature = "std")] $(#[$attr])* - #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum $call_type<$trait_instance: $trait_name> { __PhantomItem(::std::marker::PhantomData<$trait_instance>), __OtherPhantomItem(::std::marker::PhantomData<$trait_instance>), @@ -401,7 +535,6 @@ macro_rules! decl_module { #[cfg(not(feature = "std"))] $(#[$attr])* - #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum $call_type<$trait_instance: $trait_name> { __PhantomItem(::core::marker::PhantomData<$trait_instance>), __OtherPhantomItem(::core::marker::PhantomData<$trait_instance>), @@ -474,13 +607,13 @@ macro_rules! decl_module { impl<$trait_instance: $trait_name> $crate::dispatch::Decode for $call_type<$trait_instance> { fn decode(input: &mut I) -> Option { let _input_id = input.read_byte()?; - __impl_decode!(input; _input_id; 0; $call_type; $( fn $fn_name( $( $param_name ),* ); )*) + __impl_decode!(input; _input_id; 0; $call_type; $( fn $fn_name( $( $(#[$codec_attr on type $param])* $param_name ),* ); )*) } } impl<$trait_instance: $trait_name> $crate::dispatch::Encode for $call_type<$trait_instance> { fn encode_to(&self, _dest: &mut W) { - __impl_encode!(_dest; *self; 0; $call_type; $( fn $fn_name( $( $param_name ),* ); )*); + __impl_encode!(_dest; *self; 0; $call_type; $( fn $fn_name( $( $(#[$codec_attr on type $param])* $param_name ),* ); )*); if let $call_type::__PhantomItem(_) = *self { unreachable!() } if let $call_type::__OtherPhantomItem(_) = *self { unreachable!() } } @@ -518,7 +651,7 @@ macro_rules! decl_module { } __dispatch_impl_metadata! { $mod_type $trait_instance $trait_name $call_type $origin_type - {$( $(#[doc = $doc_attr])* fn $fn_name($from $(, $param_name : $param )*) -> $result; )*} + {$( $(#[doc = $doc_attr])* fn $fn_name($from $(, $(#[$codec_attr])* $param_name : $param )*); )*} } } } @@ -532,14 +665,18 @@ macro_rules! __impl_decode { $fn_id:expr; $call_type:ident; fn $fn_name:ident( - $( $param_name:ident ),* + $( $(#[$codec_attr:ident on type $param:ty])* $param_name:ident ),* ); $($rest:tt)* ) => { { if $input_id == ($fn_id) { $( - let $param_name = $crate::dispatch::Decode::decode($input)?; + __impl_decode!(@decode + $(#[$codec_attr on type $param])* + $param_name; + $input; + ); )* return Some($call_type:: $fn_name( $( $param_name ),* )); } @@ -554,7 +691,31 @@ macro_rules! __impl_decode { $call_type:ident; ) => { None - } + }; + (@decode + #[compact on type $param:ty] + $param_name:ident; + $input:expr; + ) => { + let $param_name = <<$param as $crate::dispatch::HasCompact>::Type as $crate::dispatch::Decode>::decode($input)?.into(); + }; + (@decode + $param_name:ident; + $input:expr; + ) => { + let $param_name = $crate::dispatch::Decode::decode($input)?; + }; + (@decode + $(#[$codec_attr:ident on type])* + $param_name:ident; + $input:expr; + ) => { + compile_error!(concat!( + "Invalid attribute for parameter `", + stringify!($param_name), + "`, the following attributes are supported: `#[compact]`" + )) + }; } #[macro_export] @@ -566,7 +727,7 @@ macro_rules! __impl_encode { $fn_id:expr; $call_type:ident; fn $fn_name:ident( - $( $param_name:ident ),* + $( $(#[$codec_attr:ident on type $param:ty])* $param_name:ident ),* ); $($rest:tt)* ) => { @@ -578,7 +739,11 @@ macro_rules! __impl_encode { ) = $self { $dest.push_byte(($fn_id) as u8); $( - $param_name.encode_to($dest); + __impl_encode!(@encode_as + $(#[$codec_attr on type $param])* + $param_name; + $dest; + ); )* } @@ -590,7 +755,30 @@ macro_rules! __impl_encode { $self:expr; $fn_id:expr; $call_type:ident; - ) => {{}} + ) => {{}}; + (@encode_as + #[compact on type $param:ty] + $param_name:ident; + $dest:expr; + ) => { + <<$param as $crate::dispatch::HasCompact>::Type as $crate::dispatch::EncodeAsRef<$param>>::RefType::from($param_name).encode_to($dest); + }; + (@encode_as + $param_name:ident; + $dest:expr; + ) => { + $param_name.encode_to($dest); + }; + (@encode_as + $(#[$codec_attr:ident on type $param:ty])* + $param_name:ident; + $dest:expr; + ) => { + compile_error!(concat!( + "Invalid attribute for parameter `", stringify!($param_name), + "`, the following attributes are supported: `#[compact]`" + )) + }; } pub trait IsSubType { @@ -610,7 +798,7 @@ macro_rules! impl_outer_dispatch { ) => { $(#[$attr])* #[derive(Clone, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] + #[cfg_attr(feature = "std", derive(Debug))] pub enum $call_type { $( $camelcase ( $crate::dispatch::CallableCallFor<$camelcase> ) @@ -738,15 +926,15 @@ macro_rules! __call_to_metadata { $(#[doc = $doc_attr:tt])* fn $fn_name:ident($from:ident $( - , $param_name:ident : $param:ty + , $(#[$codec_attr:ident])* $param_name:ident : $param:ty )* - ) -> $result:ty; + ); )*} ) => { $crate::dispatch::CallMetadata { name: $crate::dispatch::DecodeDifferent::Encode(stringify!($call_type)), functions: __functions_to_metadata!(0; $origin_type;; $( - fn $fn_name( $( $param_name: $param ),* ) -> $result; + fn $fn_name( $($(#[$codec_attr])* $param_name: $param ),* ); $( $doc_attr ),*; )*), } @@ -763,16 +951,16 @@ macro_rules! __functions_to_metadata{ $( $function_metadata:expr ),*; fn $fn_name:ident( $( - $param_name:ident : $param:ty + $(#[$codec_attr:ident])* $param_name:ident : $param:ty ),* - ) -> $result:ty; + ); $( $fn_doc:expr ),*; $( $rest:tt )* ) => { __functions_to_metadata!( $fn_id + 1; $origin_type; $( $function_metadata, )* __function_to_metadata!( - fn $fn_name($( $param_name : $param ),*) -> $result; $( $fn_doc ),*; $fn_id; + fn $fn_name($( $(#[$codec_attr])* $param_name : $param ),*); $( $fn_doc ),*; $fn_id; ); $($rest)* ) @@ -792,8 +980,8 @@ macro_rules! __functions_to_metadata{ macro_rules! __function_to_metadata { ( fn $fn_name:ident( - $($param_name:ident : $param:ty),* - ) -> $result:ty; + $( $(#[$codec_attr:ident])* $param_name:ident : $param:ty),* + ); $( $fn_doc:expr ),*; $fn_id:expr; ) => { @@ -804,13 +992,30 @@ macro_rules! __function_to_metadata { $( $crate::dispatch::FunctionArgumentMetadata { name: $crate::dispatch::DecodeDifferent::Encode(stringify!($param_name)), - ty: $crate::dispatch::DecodeDifferent::Encode(stringify!($param)), + ty: $crate::dispatch::DecodeDifferent::Encode( + __function_to_metadata!(@stringify_expand_attr + $(#[$codec_attr])* $param_name: $param + ) + ), } ),* ]), documentation: $crate::dispatch::DecodeDifferent::Encode(&[ $( $fn_doc ),* ]), } }; + + (@stringify_expand_attr #[compact] $param_name:ident : $param:ty) => { + concat!("Compact<", stringify!($param), ">") + }; + + (@stringify_expand_attr $param_name:ident : $param:ty) => { stringify!($param) }; + + (@stringify_expand_attr $(#[codec_attr:ident])* $param_name:ident : $param:ty) => { + compile_error!(concat!( + "Invalid attribute for parameter `", stringify!($param_name), + "`, the following attributes are supported: `#[compact]`" + )) + } } #[cfg(test)] @@ -836,7 +1041,7 @@ mod tests { pub struct Module for enum Call where origin: T::Origin { /// Hi, this is a comment. fn aux_0(_origin) -> Result { unreachable!() } - fn aux_1(_origin, _data: i32) -> Result { unreachable!() } + fn aux_1(_origin, #[compact] _data: u32) -> Result { unreachable!() } fn aux_2(_origin, _data: i32, _data2: String) -> Result { unreachable!() } fn aux_3() -> Result { unreachable!() } fn aux_4(_data: i32) -> Result { unreachable!() } @@ -862,7 +1067,7 @@ mod tests { arguments: DecodeDifferent::Encode(&[ FunctionArgumentMetadata { name: DecodeDifferent::Encode("_data"), - ty: DecodeDifferent::Encode("i32"), + ty: DecodeDifferent::Encode("Compact") } ]), documentation: DecodeDifferent::Encode(&[]), @@ -915,4 +1120,11 @@ mod tests { let metadata = Module::::metadata(); assert_eq!(EXPECTED_METADATA, metadata); } + + #[test] + fn compact_attr() { + let call: Call = Call::aux_1(0); + let encoded = call.encode(); + assert_eq!(encoded.len(), 2); + } } diff --git a/srml/contract/src/double_map.rs b/srml/support/src/double_map.rs similarity index 56% rename from srml/contract/src/double_map.rs rename to srml/support/src/double_map.rs index bd154e100eafcab8c0c5ac0ffc69f5b61ee00d32..afc707b4f1546e9ac633599d83189ad2c6c08908 100644 --- a/srml/contract/src/double_map.rs +++ b/srml/support/src/double_map.rs @@ -15,36 +15,10 @@ // along with Substrate. If not, see . //! An implementation of double map backed by storage. -//! -//! This implementation is somewhat specialized to the tracking of the storage of accounts. use rstd::prelude::*; use codec::{Codec, Encode}; -use runtime_support::storage::unhashed; -use runtime_io::{blake2_256, twox_128}; - -/// Returns only a first part of the storage key. -/// -/// Hashed by XX. -fn first_part_of_key(k1: M::Key1) -> [u8; 16] { - let mut raw_prefix = Vec::new(); - raw_prefix.extend(M::PREFIX); - raw_prefix.extend(Encode::encode(&k1)); - twox_128(&raw_prefix) -} - -/// Returns a compound key that consist of the two parts: (prefix, `k1`) and `k2`. -/// -/// The first part is hased by XX and then concatenated with a blake2 hash of `k2`. -fn full_key(k1: M::Key1, k2: M::Key2) -> Vec { - let first_part = first_part_of_key::(k1); - let second_part = blake2_256(&Encode::encode(&k2)); - - let mut k = Vec::new(); - k.extend(&first_part); - k.extend(&second_part); - k -} +use storage::unhashed; /// An implementation of a map with a two keys. /// @@ -54,11 +28,8 @@ fn full_key(k1: M::Key1, k2: M::Key2) -> Vec { /// # Mapping of keys to a storage path /// /// The storage key (i.e. the key under which the `Value` will be stored) is created from two parts. -/// The first part is a XX hash of a concatenation of the `PREFIX` and `Key1`. And the second part -/// is a blake2 hash of a `Key2`. -/// -/// Blake2 is used for `Key2` is because it will be used as a key for contract's storage and -/// thus will be susceptible for a untrusted input. +/// The first part is a hash of a concatenation of the `PREFIX` and `Key1`. And the second part +/// is a hash of a `Key2`. pub trait StorageDoubleMap { type Key1: Codec; type Key2: Codec; @@ -68,28 +39,57 @@ pub trait StorageDoubleMap { /// Insert an entry into this map. fn insert(k1: Self::Key1, k2: Self::Key2, val: Self::Value) { - unhashed::put(&full_key::(k1, k2)[..], &val); + unhashed::put(&Self::full_key(k1, k2)[..], &val); } /// Remove an entry from this map. fn remove(k1: Self::Key1, k2: Self::Key2) { - unhashed::kill(&full_key::(k1, k2)[..]); + unhashed::kill(&Self::full_key(k1, k2)[..]); } /// Get an entry from this map. /// /// If there is entry stored under the given keys, returns `None`. fn get(k1: Self::Key1, k2: Self::Key2) -> Option { - unhashed::get(&full_key::(k1, k2)[..]) + unhashed::get(&Self::full_key(k1, k2)[..]) } /// Returns `true` if value under the specified keys exists. fn exists(k1: Self::Key1, k2: Self::Key2) -> bool { - unhashed::exists(&full_key::(k1, k2)[..]) + unhashed::exists(&Self::full_key(k1, k2)[..]) } /// Removes all entries that shares the `k1` as the first key. fn remove_prefix(k1: Self::Key1) { - unhashed::kill_prefix(&first_part_of_key::(k1)) + unhashed::kill_prefix(&Self::derive_key1(Self::encode_key1(k1))) + } + + /// Encode key1 into Vec and prepend a prefix + fn encode_key1(key: Self::Key1) -> Vec { + let mut raw_prefix = Vec::new(); + raw_prefix.extend(Self::PREFIX); + raw_prefix.extend(Encode::encode(&key)); + raw_prefix + } + + /// Encode key2 into Vec + fn encode_key2(key: Self::Key2) -> Vec { + Encode::encode(&key) + } + + /// Derive the first part of the key + fn derive_key1(key1_data: Vec) -> Vec; + + /// Derive the remaining part of the key + fn derive_key2(key2_data: Vec) -> Vec; + + /// Returns a compound key that consist of the two parts: (prefix, `k1`) and `k2`. + /// The first part is hased and then concatenated with a hash of `k2`. + fn full_key(k1: Self::Key1, k2: Self::Key2) -> Vec { + let key1_data = Self::encode_key1(k1); + let key2_data = Self::encode_key2(k2); + let mut key = Self::derive_key1(key1_data); + key.extend(Self::derive_key2(key2_data)); + key } } diff --git a/srml/support/src/event.rs b/srml/support/src/event.rs index ae7ddea4124eb5bc0ba5ac4c92e183c18e60f32c..8711646d6efe90248b26eb691322a234cebe73a5 100644 --- a/srml/support/src/event.rs +++ b/srml/support/src/event.rs @@ -11,10 +11,13 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. +//! Macros that define an Event types. Events can be used to easily report changes or conditions +//! in your runtime to external entities like users, chain explorers, or dApps. + // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -pub use substrate_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnEncode}; +pub use srml_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnEncode}; /// Implement the `Event` for a module. /// @@ -115,7 +118,7 @@ macro_rules! decl_event { ) => { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Encode, Decode)] - #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] + #[cfg_attr(feature = "std", derive(Debug))] $(#[$attr])* pub enum Event { $( @@ -216,7 +219,7 @@ macro_rules! __decl_generic_event { pub type Event<$event_generic_param> = RawEvent<$( <$generic as $trait>::$trait_type ),*>; // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Encode, Decode)] - #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] + #[cfg_attr(feature = "std", derive(Debug))] $(#[$attr])* pub enum RawEvent<$( $generic_param ),*> { $( @@ -265,8 +268,14 @@ macro_rules! __events_to_metadata { } } +/// Constructs an Event type for a runtime. This is usually called automatically by the +/// construct_runtime macro. See also __create_decl_macro. #[macro_export] macro_rules! impl_outer_event { + + // Macro transformations (to convert invocations with incomplete parameters to the canonical + // form) + ( $(#[$attr:meta])* pub enum $name:ident for $runtime:ident { @@ -354,6 +363,9 @@ macro_rules! impl_outer_event { $( $module_name::Event $( <$generic_param> )*, )* $module::Event,; ); }; + + // The main macro expansion that actually renders the Event enum code. + ( $(#[$attr:meta])*; $name:ident; @@ -364,7 +376,7 @@ macro_rules! impl_outer_event { ) => { // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Encode, Decode)] - #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] + #[cfg_attr(feature = "std", derive(Debug))] $(#[$attr])* #[allow(non_camel_case_types)] pub enum $name { @@ -518,7 +530,7 @@ mod tests { ); } - #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)] + #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Serialize)] pub struct TestRuntime; impl_outer_event! { @@ -529,7 +541,7 @@ mod tests { } } - #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)] + #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Serialize)] pub struct TestRuntime2; impl_outer_event! { diff --git a/srml/support/src/inherent.rs b/srml/support/src/inherent.rs index f87a41806a93a2922e68b1cc32fcab0ddab45578..925ba91cec5322dfc90f89bff962ea97ba07fd0f 100644 --- a/srml/support/src/inherent.rs +++ b/srml/support/src/inherent.rs @@ -15,9 +15,11 @@ // along with Substrate. If not, see . #[doc(hidden)] -pub use rstd::{result::Result, vec::Vec}; +pub use rstd::{cmp, result::Result, vec::Vec}; #[doc(hidden)] -pub use runtime_primitives::traits::ProvideInherent; +pub use runtime_primitives::{ + traits::{ProvideInherent, Block as BlockT}, CheckInherentError +}; /// Implement the outer inherent. @@ -38,91 +40,45 @@ pub use runtime_primitives::traits::ProvideInherent; #[macro_export] macro_rules! impl_outer_inherent { ( - $(#[$attr:meta])* - pub struct $name:ident where Block = $block:ident, UncheckedExtrinsic = $unchecked:ident { - $( $module:ident: $module_ty:ident $(export Error as $error_name:ident)*, )* + for $runtime:ident, + Block = $block:ident, + InherentData = $inherent:ty + { + $( $module:ident: $module_ty:ident,)* } ) => { - impl_outer_inherent!( - $( #[$attr] )* - pub struct $name where Block = $block, UncheckedExtrinsic = $unchecked, Error = InherentError, Call = Call { - $( $module: $module_ty $(export Error as $error_name)*, )* - } - ); - }; - ( - $(#[$attr:meta])* - pub struct $name:ident where Block = $block:ident, UncheckedExtrinsic = $unchecked:ident, Error = $error:ident { - $( $module:ident: $module_ty:ident $(export Error as $error_name:ident)*, )* - } - ) => { - impl_outer_inherent!( - $( #[$attr] )* - pub struct $name where Block = $block, UncheckedExtrinsic = $unchecked, Error = $error, Call = Call { - $( $module: $module_ty $(export Error as $error_name)*, )* - } - ); - }; - ( - $(#[$attr:meta])* - pub struct $name:ident where Block = $block:ident, UncheckedExtrinsic = $unchecked:ident, Error = $error:ident, Call = $call:ident { - $( $module:ident: $module_ty:ident $(export Error as $error_name:ident)*, )* - } - ) => { - $( #[$attr] )* - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Encode, Decode)] - /// Inherent data to include in a block. - pub struct $name { - $( $module: <$module_ty as $crate::inherent::ProvideInherent>::Inherent, )* - } - - $( - $( - pub type $error_name =<$module_ty as $crate::inherent::ProvideInherent>::Error; - )* - )* - - impl $name { - /// Create a new instance. - pub fn new( $( $module: <$module_ty as $crate::inherent::ProvideInherent>::Inherent ),* ) -> Self { - Self { - $( $module, )* - } - } - - fn create_inherent_extrinsics(self) -> Vec<$unchecked> { - let mut inherent = $crate::inherent::Vec::new(); - - $( - inherent.extend( - <$module_ty as $crate::inherent::ProvideInherent>::create_inherent_extrinsics(self.$module) - .into_iter() - .map(|v| (v.0, $unchecked::new_unsigned($call::$module_ty(v.1)))) - ); - )* - - inherent.as_mut_slice().sort_unstable_by_key(|v| v.0); - inherent.into_iter().map(|v| v.1).collect() - } + impl $runtime { + fn check_inherents( + block: $block, + data: $inherent + ) -> $crate::inherent::Result<(), $crate::inherent::CheckInherentError> { + use $crate::inherent::CheckInherentError; - fn check_inherents(self, block: $block) -> $crate::inherent::Result<(), $error> { + let mut max_valid_after = None; $( - <$module_ty as $crate::inherent::ProvideInherent>::check_inherent( - &block, self.$module, &|xt| match xt.function { + let res = <$module_ty as $crate::inherent::ProvideInherent>::check_inherent( + &block, + data.$module, + &|xt| match xt.function { Call::$module_ty(ref data) => Some(data), _ => None, - }).map_err($error::$module_ty)?; + }, + ); + + match res { + Err(CheckInherentError::ValidAtTimestamp(t)) => + max_valid_after = $crate::inherent::cmp::max(max_valid_after, Some(t)), + res => res? + } )* - Ok(()) - } - } - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. - #[derive(Encode)] - #[cfg_attr(feature = "std", derive(Decode))] - pub enum $error { - $( $module_ty(<$module_ty as $crate::inherent::ProvideInherent>::Error), )* + // once everything else has checked out, take the maximum of + // all things which are timestamp-restricted. + match max_valid_after { + Some(t) => Err(CheckInherentError::ValidAtTimestamp(t)), + None => Ok(()) + } + } } }; } diff --git a/srml/support/src/lib.rs b/srml/support/src/lib.rs index e9cd35afa56781ac2aa44e5750150f70a466df26..ec285590d20d0cae9eef2c18193efa64a6c0b72c 100644 --- a/srml/support/src/lib.rs +++ b/srml/support/src/lib.rs @@ -14,29 +14,29 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// tag::description[] //! Support code for the runtime. -// end::description[] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(alloc))] #[cfg(feature = "std")] -extern crate serde; +pub extern crate serde; #[doc(hidden)] pub extern crate sr_std as rstd; extern crate sr_io as runtime_io; #[doc(hidden)] pub extern crate sr_primitives as runtime_primitives; -extern crate substrate_metadata; +extern crate srml_metadata; extern crate mashup; +#[cfg_attr(test, macro_use)] +extern crate srml_support_procedural; #[cfg(test)] #[macro_use] extern crate pretty_assertions; -#[cfg(test)] +#[cfg(feature = "std")] #[macro_use] extern crate serde_derive; #[cfg(test)] @@ -45,6 +45,11 @@ extern crate parity_codec_derive; #[doc(hidden)] pub extern crate parity_codec as codec; + +#[cfg(feature = "std")] +#[doc(hidden)] +pub extern crate once_cell; + pub use self::storage::generator::Storage as GenericStorage; #[macro_use] @@ -62,12 +67,17 @@ pub mod metadata; mod runtime; #[macro_use] pub mod inherent; +mod double_map; pub use self::storage::{StorageVec, StorageList, StorageValue, StorageMap}; pub use self::hashable::Hashable; pub use self::dispatch::{Parameter, Dispatchable, Callable, IsSubType}; pub use self::metadata::RuntimeMetadata; pub use runtime_io::print; +pub use double_map::StorageDoubleMap; + +#[doc(inline)] +pub use srml_support_procedural::decl_storage; #[macro_export] macro_rules! fail { @@ -122,3 +132,22 @@ pub enum Void {} #[doc(hidden)] pub use mashup::*; + +#[cfg(feature = "std")] +#[doc(hidden)] +pub use serde_derive::*; + +/// Programatically create derivations for tuples of up to 19 elements. You provide a second macro +/// which is called once per tuple size, along with a number of identifiers, one for each element +/// of the tuple. +#[macro_export] +macro_rules! for_each_tuple { + ($m:ident) => { + for_each_tuple! { @IMPL $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, } + }; + (@IMPL $m:ident !!) => { $m! { } }; + (@IMPL $m:ident !! $h:ident, $($t:ident,)*) => { + $m! { $h $($t)* } + for_each_tuple! { @IMPL $m !! $($t,)* } + } +} diff --git a/srml/support/src/metadata.rs b/srml/support/src/metadata.rs index 132415d3153e2d36f1ee8513f92d94b80deaaeb5..f22e7459c7fcff76b2b53e1fd15310f27acbbb3b 100644 --- a/srml/support/src/metadata.rs +++ b/srml/support/src/metadata.rs @@ -14,8 +14,9 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -pub use substrate_metadata::{ - DecodeDifferent, FnEncode, RuntimeMetadata, RuntimeModuleMetadata +pub use srml_metadata::{ + DecodeDifferent, FnEncode, RuntimeMetadata, RuntimeModuleMetadata, + DefaultByteGetter, }; /// Implements the metadata support for the given runtime and all its modules. @@ -98,7 +99,7 @@ macro_rules! __runtime_modules_to_metadata { #[allow(dead_code)] mod tests { use super::*; - use substrate_metadata::{ + use srml_metadata::{ EventMetadata, OuterEventMetadata, RuntimeModuleMetadata, CallMetadata, ModuleMetadata, StorageFunctionModifier, StorageFunctionType, FunctionMetadata, StorageMetadata, StorageFunctionMetadata, OuterDispatchMetadata, OuterDispatchCall @@ -188,8 +189,7 @@ mod tests { StorageMethod : Option; } add_extra_genesis { - config(_marker) : ::std::marker::PhantomData; - build(|_, _, _| {}); + build(|_, _, _| {}); } } } @@ -197,7 +197,7 @@ mod tests { type EventModule = event_module::Module; type EventModule2 = event_module2::Module; - #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, Deserialize, Serialize)] + #[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)] pub struct TestRuntime; impl_outer_event! { @@ -312,15 +312,20 @@ mod tests { )), storage: Some(DecodeDifferent::Encode(FnEncode(|| StorageMetadata { - prefix: DecodeDifferent::Encode("TestStorage"), - functions: DecodeDifferent::Encode(&[ - StorageFunctionMetadata { - name: DecodeDifferent::Encode("StorageMethod"), - modifier: StorageFunctionModifier::Optional, - ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), - documentation: DecodeDifferent::Encode(&[]), - } - ]) + prefix: DecodeDifferent::Encode("TestStorage"), + functions: DecodeDifferent::Encode(&[ + StorageFunctionMetadata { + name: DecodeDifferent::Encode("StorageMethod"), + modifier: StorageFunctionModifier::Optional, + ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter( + &event_module2::__GetByteStructStorageMethod(::std::marker::PhantomData::) + ) + ), + documentation: DecodeDifferent::Encode(&[]), + } + ]) } ))), } diff --git a/srml/support/src/origin.rs b/srml/support/src/origin.rs index 5cc54794dbf1f63682602f0e612d330f9d6780de..393e122ac0ecd08388a0e5c4128eccdc9f9f9993 100644 --- a/srml/support/src/origin.rs +++ b/srml/support/src/origin.rs @@ -14,8 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +//! Macros that define an Origin type. Every function call to your runtime has an origin which +//! specifies where the extrinsic was generated from. + +/// Constructs an Origin type for a runtime. This is usually called automatically by the +/// construct_runtime macro. See also __create_decl_macro. #[macro_export] macro_rules! impl_outer_origin { + + // Macro transformations (to convert invocations with incomplete parameters to the canonical + // form) + ( $(#[$attr:meta])* pub enum $name:ident for $runtime:ident { @@ -114,6 +123,9 @@ macro_rules! impl_outer_origin { $( $parsed_module $( <$generic_param> )* ),*, $module<$runtime>; ); }; + + // The main macro expansion that actually renders the Origin enum code. + ( $(#[$attr:meta])*; $name:ident; diff --git a/srml/support/src/runtime.rs b/srml/support/src/runtime.rs index 3e42e1970ee42a8a19ffa6da576bd5526d96ff2d..d658de3426e534118f2e0a6d22f9f7e2381d6339 100644 --- a/srml/support/src/runtime.rs +++ b/srml/support/src/runtime.rs @@ -14,13 +14,26 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +//! Macros to define a runtime. A runtime is basically all your logic running in Substrate, +//! consisting of selected SRML modules and maybe some of your own modules. +//! A lot of supporting logic is automatically generated for a runtime, +//! mostly for to combine data types and metadata of the included modules. + /// Construct a runtime, with the given name and the given modules. -/// +/// +/// The parameters here are specific types for Block, NodeBlock and InherentData +/// (TODO: describe the difference between Block and NodeBlock) +/// and the modules that are used by the runtime. +/// /// # Example: /// /// ```nocompile /// construct_runtime!( -/// pub enum Runtime with Log(interalIdent: DigestItem) { +/// pub enum Runtime with Log(interalIdent: DigestItem) where +/// Block = Block, +/// NodeBlock = runtime::Block, +/// InherentData = BasicInherentData +/// { /// System: system, /// Test: test::{default, Log(Test)}, /// Test2: test_with_long_module::{Module}, @@ -28,11 +41,13 @@ /// ) /// ``` /// -/// The module `System: system` will expand to `System: system::{Module, Call, Storage, Event, Config}`. +/// The module `System: system` will expand to `System: system::{Module, Call, Storage, Event, Config}`. /// The identifier `System` is the name of the module and the lower case identifier `system` is the -/// name of the rust module for this module. +/// name of the Rust module/crate for this Substrate module. +/// /// The module `Test: test::{default, Log(Test)}` will expand to -/// `Test: test::{Module, Call, Storage, Event, Config, Log(Test)}`. +/// `Test: test::{Module, Call, Storage, Event, Config, Log(Test)}`. +/// /// The module `Test2: test_with_long_module::{Module}` will expand to /// `Test2: test_with_long_module::{Module}`. /// @@ -44,11 +59,21 @@ /// - `Origin` or `Origin` (if the origin is generic) /// - `Config` or `Config` (if the config is generic) /// - `Log( $(IDENT),* )` +/// +/// The +/// #[macro_export] macro_rules! construct_runtime { + + // Macro transformations (to convert invocations with incomplete parameters to the canonical + // form) + ( pub enum $runtime:ident with Log ($log_internal:ident: DigestItem<$( $log_genarg:ty ),+>) - where Block = $block:ident, UncheckedExtrinsic = $unchecked:ident + where + Block = $block:ident, + NodeBlock = $node_block:ty, + InherentData = $inherent:ty { $( $rest:tt )* } @@ -56,7 +81,8 @@ macro_rules! construct_runtime { construct_runtime!( $runtime; $block; - $unchecked; + $node_block; + $inherent; $log_internal < $( $log_genarg ),* >; ; $( $rest )* @@ -65,7 +91,8 @@ macro_rules! construct_runtime { ( $runtime:ident; $block:ident; - $unchecked:ident; + $node_block:ty; + $inherent:ty; $log_internal:ident <$( $log_genarg:ty ),+>; $( $expanded_name:ident: $expanded_module:ident::{ @@ -92,7 +119,8 @@ macro_rules! construct_runtime { construct_runtime!( $runtime; $block; - $unchecked; + $node_block; + $inherent; $log_internal < $( $log_genarg ),* >; $( $expanded_name: $expanded_module::{ @@ -119,7 +147,8 @@ macro_rules! construct_runtime { ( $runtime:ident; $block:ident; - $unchecked:ident; + $node_block:ty; + $inherent:ty; $log_internal:ident <$( $log_genarg:ty ),+>; $( $expanded_name:ident: $expanded_module:ident::{ @@ -153,7 +182,8 @@ macro_rules! construct_runtime { construct_runtime!( $runtime; $block; - $unchecked; + $node_block; + $inherent; $log_internal < $( $log_genarg ),* >; $( $expanded_name: $expanded_module::{ @@ -186,7 +216,8 @@ macro_rules! construct_runtime { ( $runtime:ident; $block:ident; - $unchecked:ident; + $node_block:ty; + $inherent:ty; $log_internal:ident <$( $log_genarg:ty ),+>; $( $expanded_name:ident: $expanded_module:ident::{ @@ -219,7 +250,8 @@ macro_rules! construct_runtime { construct_runtime!( $runtime; $block; - $unchecked; + $node_block; + $inherent; $log_internal < $( $log_genarg ),* >; $( $expanded_name: $expanded_module::{ @@ -248,10 +280,14 @@ macro_rules! construct_runtime { )* ); }; + + // The main macro expansion that actually renders the Runtime code. + ( $runtime:ident; $block:ident; - $unchecked:ident; + $node_block:ty; + $inherent:ty; $log_internal:ident <$( $log_genarg:ty ),+>; $( $name:ident: $module:ident::{ @@ -263,16 +299,24 @@ macro_rules! construct_runtime { } ),*; ) => { + // This generates a substrate_generate_ident_name macro that will substitute + // "config-ident FooModule" => FooModuleConfig for every module included in the + // runtime. mashup! { $( substrate_generate_ident_name["config-ident" $name] = $name Config; - substrate_generate_ident_name["inherent-error-ident" $name] = $name InherentError; )* } #[derive(Clone, Copy, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] + #[cfg_attr(feature = "std", derive(Debug))] pub struct $runtime; + impl $crate::runtime_primitives::traits::GetNodeBlockType for $runtime { + type NodeBlock = $node_block; + } + impl $crate::runtime_primitives::traits::GetRuntimeBlockType for $runtime { + type RuntimeBlock = $block; + } __decl_outer_event!( $runtime; $( @@ -326,7 +370,7 @@ macro_rules! construct_runtime { __decl_outer_inherent!( $runtime; $block; - $unchecked; + $inherent; ; $( $name: $module::{ $( $modules $( <$modules_generic> )* ),* } @@ -335,6 +379,11 @@ macro_rules! construct_runtime { } } +/// A macro that generates a "__decl" private macro that transforms parts of the runtime definition +/// to feed them into a public "impl" macro which accepts the format +/// "pub enum $name for $runtime where system = $system". +/// +/// Used to define Event and Origin associated types. #[macro_export] #[doc(hidden)] macro_rules! __create_decl_macro { @@ -497,6 +546,7 @@ macro_rules! __create_decl_macro { __create_decl_macro!(__decl_outer_event, impl_outer_event, Event, $); __create_decl_macro!(__decl_outer_origin, impl_outer_origin, Origin, $); +/// A macro that defines all modules as an associated types of the Runtime type. #[macro_export] #[doc(hidden)] macro_rules! __decl_all_modules { @@ -601,6 +651,8 @@ macro_rules! __decl_all_modules { } } +/// A macro that defines the Call enum to represent calls to functions in the modules included +/// in the runtime (by wrapping the values of all FooModule::Call enums). #[macro_export] #[doc(hidden)] macro_rules! __decl_outer_dispatch { @@ -696,6 +748,7 @@ macro_rules! __decl_outer_dispatch { }; } +/// A private macro that generates metadata() method for the runtime. See impl_runtime_metadata macro. #[macro_export] #[doc(hidden)] macro_rules! __decl_runtime_metadata { @@ -864,6 +917,8 @@ macro_rules! __decl_runtime_metadata { ); } } + +/// A private macro that generates Log enum for the runtime. See impl_outer_log macro. #[macro_export] #[doc(hidden)] macro_rules! __decl_outer_log { @@ -947,6 +1002,7 @@ macro_rules! __decl_outer_log { }; } +/// A private macro that generates GenesisConfig for the runtime. See impl_outer_config macro. #[macro_export] #[doc(hidden)] macro_rules! __decl_outer_config { @@ -1046,13 +1102,14 @@ macro_rules! __decl_outer_config { }; } +/// A private macro that generates check_inherents() implementation for the runtime. #[macro_export] #[doc(hidden)] macro_rules! __decl_outer_inherent { ( $runtime:ident; $block:ident; - $unchecked:ident; + $inherent:ty; $( $parsed_modules:ident :: $parsed_name:ident ),*; $name:ident: $module:ident::{ Inherent $(, $modules:ident $( <$modules_generic:ident> )* )* @@ -1064,7 +1121,7 @@ macro_rules! __decl_outer_inherent { __decl_outer_inherent!( $runtime; $block; - $unchecked; + $inherent; $( $parsed_modules :: $parsed_name, )* $module::$name; $( $rest_name: $rest_module::{ @@ -1076,7 +1133,7 @@ macro_rules! __decl_outer_inherent { ( $runtime:ident; $block:ident; - $unchecked:ident; + $inherent:ty; $( $parsed_modules:ident :: $parsed_name:ident ),*; $name:ident: $module:ident::{ $ingore:ident $( <$ignor:ident> )* $(, $modules:ident $( <$modules_generic:ident> )* )* @@ -1088,7 +1145,7 @@ macro_rules! __decl_outer_inherent { __decl_outer_inherent!( $runtime; $block; - $unchecked; + $inherent; $( $parsed_modules :: $parsed_name ),*; $name: $module::{ $( $modules $( <$modules_generic> )* ),* } $( @@ -1101,7 +1158,7 @@ macro_rules! __decl_outer_inherent { ( $runtime:ident; $block:ident; - $unchecked:ident; + $inherent:ty; $( $parsed_modules:ident :: $parsed_name:ident ),*; $name:ident: $module:ident::{} $(, $rest_name:ident : $rest_module:ident::{ @@ -1111,7 +1168,7 @@ macro_rules! __decl_outer_inherent { __decl_outer_inherent!( $runtime; $block; - $unchecked; + $inherent; $( $parsed_modules :: $parsed_name ),*; $( $rest_name: $rest_module::{ @@ -1123,18 +1180,16 @@ macro_rules! __decl_outer_inherent { ( $runtime:ident; $block:ident; - $unchecked:ident; + $inherent:ty; $( $parsed_modules:ident :: $parsed_name:ident ),*; ; ) => { - substrate_generate_ident_name! { - impl_outer_inherent!( - pub struct InherentData where Block = $block, UncheckedExtrinsic = $unchecked { - $( - $parsed_modules: $parsed_name export Error as "inherent-error-ident" $parsed_name, - )* - } - ); - } + impl_outer_inherent!( + for $runtime, + Block = $block, + InherentData = $inherent { + $($parsed_modules : $parsed_name,)* + } + ); }; } diff --git a/srml/support/src/storage/generator.rs b/srml/support/src/storage/generator.rs index 899bee44b04bbf4fa228a6b3dc8d01a2b0c19558..7cf5e28dedf9a03a29a6d44af3f1c1ab7dbc6220 100644 --- a/srml/support/src/storage/generator.rs +++ b/srml/support/src/storage/generator.rs @@ -53,9 +53,10 @@ pub use rstd::borrow::Borrow; #[doc(hidden)] pub use rstd::marker::PhantomData; -pub use substrate_metadata::{ +pub use srml_metadata::{ DecodeDifferent, StorageMetadata, StorageFunctionMetadata, - StorageFunctionType, StorageFunctionModifier + StorageFunctionType, StorageFunctionModifier, + DefaultByte, DefaultByteGetter, }; /// Abstraction around storage. @@ -517,1332 +518,6 @@ macro_rules! __handle_wrap_internal { type Now = super::Now; }*/ -#[macro_export] -macro_rules! __generate_genesis_config { - ( - [$traittype:ident $traitinstance:ident] - // normal getters - [$( $fieldname:ident : $fieldtype:ty = $fielddefault:expr ;)*] - // for normal builders - [$( $normalclassname:ident ($normalbuild:expr) ;)*] - // for map builders - [$( $mapclassname:ident ($mapbuild:expr) ;)*] - // extra genesis fields - [$($curextras:tt)*] - // final build storage call - [$call:expr] - - $(#[$attr:meta])* $extrafieldname:ident : $extrafieldty:ty = $extrafielddefault:expr; - $($extras:tt)* - ) => { - __generate_genesis_config!( - [$traittype $traitinstance] - [$( $fieldname : $fieldtype = $fielddefault ;)*] - [$( $normalclassname ($normalbuild) ;)*] - [$( $mapclassname ($mapbuild) ;)*] - [$($curextras)* $(#[$attr])* $extrafieldname : $extrafieldty = $extrafielddefault ;] - [$call] - $($extras)* - ); - }; - ( - [$traittype:ident $traitinstance:ident] - // normal getters - [$( $fieldname:ident : $fieldtype:ty = $fielddefault:expr ;)*] - // for normal builders - [$( $normalclassname:ident ($normalbuild:expr) ;)*] - // for map builders - [$( $mapclassname:ident ($mapbuild:expr) ;)*] - // extra genesis fields - [$($curextras:tt)*] - // final build storage call - [$call:expr] - - $(#[$attr:meta])* $extrafieldname:ident : $extrafieldty:ty; - $($extras:tt)* - ) => { - __generate_genesis_config!( - [$traittype $traitinstance] - [$( $fieldname : $fieldtype = $fielddefault ;)*] - [$( $normalclassname ($normalbuild) ;)*] - [$( $mapclassname ($mapbuild) ;)*] - [$($curextras)* $(#[$attr])* $extrafieldname : $extrafieldty = Default::default() ;] - [$call] - $($extras)* - ); - }; - ( - [$traittype:ident $traitinstance:ident] - // normal getters - [$( $fieldname:ident : $fieldtype:ty = $fielddefault:expr ;)*] - // for normal builders - [$( $normalclassname:ident ($normalbuild:expr) ;)*] - // for map builders - [$( $mapclassname:ident ($mapbuild:expr) ;)*] - // extra genesis fields - [$($curextras:tt)*] - // final build storage call - [$call:expr] - ) => { - __generate_genesis_config!(@GEN - [$traittype $traitinstance] - [$( $fieldname : $fieldtype = $fielddefault ;)*] - [$( $normalclassname ($normalbuild) ;)*] - [$( $mapclassname ($mapbuild) ;)*] - [$($curextras)*] - [$call] - ); - }; - - // Do not generate any `GenesisConfig`, if we not require it. - (@GEN - [$traittype:ident $traitinstance:ident] - // normal getters - [] - // for normal builders - [$( $normalclassname:ident ($normalbuild:expr) ;)*] - // for map builders - [$( $mapclassname:ident ($mapbuild:expr) ;)*] - // extra genesis fields - [] - // final build storage call - [$call:expr] - ) => {}; - - (@GEN - [$traittype:ident $traitinstance:ident] - // normal getters - [$( $fieldname:ident : $fieldtype:ty = $fielddefault:expr ;)*] - // for normal builders - [$( $normalclassname:ident ($normalbuild:expr) ;)*] - // for map builders - [$( $mapclassname:ident ($mapbuild:expr) ;)*] - // extra genesis fields - [$( $(#[$attr:meta])* $extrafieldname:ident : $extrafieldty:ty = $extrafielddefault:expr; )*] - // final build storage call - [$call:expr] - ) => { - #[derive(Serialize, Deserialize)] - #[cfg(feature = "std")] - #[serde(rename_all = "camelCase")] - #[serde(deny_unknown_fields)] - pub struct GenesisConfig<$traitinstance: $traittype> { - $(pub $fieldname : $fieldtype ,)* - $( $(#[$attr])* pub $extrafieldname : $extrafieldty ,)* - } - - #[cfg(feature = "std")] - impl<$traitinstance: $traittype> Default for GenesisConfig<$traitinstance> { - fn default() -> Self { - GenesisConfig { - $($fieldname : $fielddefault ,)* - $($extrafieldname : $extrafielddefault ,)* - } - } - } - - #[cfg(feature = "std")] - impl<$traitinstance: $traittype> $crate::runtime_primitives::BuildStorage for GenesisConfig<$traitinstance> - { - fn build_storage(self) -> ::std::result::Result<($crate::runtime_primitives::StorageMap, $crate::runtime_primitives::ChildrenStorageMap), String> { - let mut r: $crate::runtime_primitives::StorageMap = Default::default(); - let mut c: $crate::runtime_primitives::ChildrenStorageMap = Default::default(); - - // normal getters - $({ - use $crate::codec::Encode; - let v = ($normalbuild)(&self); - r.insert(Self::hash(<$normalclassname<$traitinstance>>::key()).to_vec(), v.encode()); - })* - - // for maps - $({ - use $crate::codec::Encode; - let data = ($mapbuild)(&self); - for (k, v) in data.into_iter() { - r.insert(Self::hash(&<$mapclassname<$traitinstance>>::key_for(k)).to_vec(), v.encode()); - } - })* - - // extra call - $call(&mut r, &mut c, &self); - - Ok((r, c)) - } - } - }; -} - -/// Declares strongly-typed wrappers around codec-compatible types in storage. -/// -/// For now we implement a convenience trait with pre-specialised associated types, one for each -/// storage item. This allows you to gain access to publicly visible storage items from a -/// module type. Currently you must disambiguate by using `::Item` rather than -/// the simpler `Module::Item`. Hopefully the rust guys with fix this soon. -#[macro_export] -macro_rules! decl_storage { - ( - $pub:vis trait $storetype:ident for $modulename:ident<$traitinstance:ident: $traittype:ident> as $cratename:ident { - $($t:tt)* - } - add_extra_genesis { - $( $(#[$attr:meta])* config($extrafield:ident) : $extraty:ty $(= $default:expr)* ;)* - build($call:expr); - } - ) => { - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - $pub trait $storetype { - __decl_store_items!($($t)*); - } - impl<$traitinstance: $traittype> $storetype for $modulename<$traitinstance> { - __impl_store_items!($traitinstance $($t)*); - } - impl<$traitinstance: $traittype> $modulename<$traitinstance> { - __impl_store_fns!($traitinstance $($t)*); - __impl_store_metadata!($cratename; $($t)*); - } - __decl_genesis_config_items!([$traittype $traitinstance] [] [] [] [$( $(#[$attr])* $extrafield : $extraty $(= $default)* ; )* ] [$call] $($t)*); - }; - ( - $pub:vis trait $storetype:ident for $modulename:ident<$traitinstance:ident: $traittype:ident> as $cratename:ident { - $($t:tt)* - } - ) => { - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - $pub trait $storetype { - __decl_store_items!($($t)*); - } - impl<$traitinstance: $traittype> $storetype for $modulename<$traitinstance> { - __impl_store_items!($traitinstance $($t)*); - } - impl<$traitinstance: $traittype> $modulename<$traitinstance> { - __impl_store_fns!($traitinstance $($t)*); - __impl_store_metadata!($cratename; $($t)*); - } - __decl_genesis_config_items!([$traittype $traitinstance] [] [] [] [] [|_, _, _|{}] $($t)*); - }; -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __decl_genesis_config_items { - // maps without getters: - // - pub - // - $default - // we don't allow any config() or build() on this pattern. - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty; - $($t:tt)* - ) => { - __decl_genesis_config_items!([$traittype $traitinstance] [$($cur)*] [$($nb)*] [$($mapcur)*] [$($extras)*] [$call] $($t)*); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!([$traittype $traitinstance] [$($cur)*] [$($nb)*] [$($mapcur)*] [$($extras)*] [$call] $($t)*); - }; - - // maps with getters: - // - pub - // - build() - // - $default - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : map $kty:ty => $ty:ty; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)*] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : map $kty:ty => $ty:ty = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)*] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : map $kty:ty => $ty:ty; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)*] - [$($mapcur)* $name ($build);] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : map $kty:ty => $ty:ty = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)*] - [$($mapcur)* $name ($build);] - [$($extras)*] - [$call] - $($t)* - ); - }; - - // simple values without getters: - // - pub - // - $default - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)*] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)*] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - - // simple values with getters: - // - pub - // - (empty) / config() / config(myname) - // - build() - // - $default - // Option<> types - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : Option<$ty:ty>; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)*] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : Option<$ty:ty> = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)*] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() : Option<$ty:ty>; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $getfn : $ty = Default::default();] - [$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$getfn.clone());] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() : Option<$ty:ty> = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $getfn : $ty = $default.unwrap_or_default();] - [$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$getfn.clone());] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) : Option<$ty:ty>; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $myname : $ty = Default::default();] - [$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$myname.clone()); ] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) : Option<$ty:ty> = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $myname : $ty = $default.unwrap_or_default();] - [$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$myname.clone()); ] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - // build - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : Option<$ty:ty>; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : Option<$ty:ty> = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() build($build:expr) : Option<$ty:ty>; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $getfn : $ty = Default::default();] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() build($build:expr) : Option<$ty:ty> = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $getfn : $ty = $default.unwrap_or_default();] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : Option<$ty:ty>; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $myname : $ty = Default::default();] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : Option<$ty:ty> = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $myname : $ty = $default.unwrap_or_default();] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - - // raw types - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : $ty:ty; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)*] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) : $ty:ty = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)*] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() : $ty:ty; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $getfn : $ty = Default::default();] - [$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$getfn.clone());] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() : $ty:ty = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $getfn : $ty = $default;] - [$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$getfn.clone());] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) : $ty:ty; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $myname : $ty = Default::default();] - [$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$myname.clone()); ] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) : $ty:ty = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $myname : $ty = $default;] - [$($nb)* $name (|config: &GenesisConfig<$traitinstance>| config.$myname.clone()); ] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - // build - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : $ty:ty; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) build($build:expr) : $ty:ty = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)*] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() build($build:expr) : $ty:ty; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $getfn : $ty = Default::default();] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config() build($build:expr) : $ty:ty = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $getfn : $ty = $default;] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : $ty:ty; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $myname : $ty = Default::default();] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr] - $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) config($myname:ident) build($build:expr) : $ty:ty = $default:expr; - $($t:tt)* - ) => { - __decl_genesis_config_items!( - [$traittype $traitinstance] - [$($cur)* $myname : $ty = $default;] - [$($nb)* $name ($build);] - [$($mapcur)*] - [$($extras)*] - [$call] - $($t)* - ); - }; - - // exit - ([$traittype:ident $traitinstance:ident] [$($cur:tt)*] [$($nb:tt)*] [$($mapcur:tt)*] [$($extras:tt)*] [$call:expr]) => { - // we pass the extra fields - __generate_genesis_config!([$traittype $traitinstance] [$($cur)*] [$($nb)*] [$($mapcur)*] [] [$call] $($extras)* ); - } -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __decl_storage_items { - // we have to put the map's pattern first to avoid the ambiguity. - - // factor out Option<> type first. - // maps: - // - pub - // - $default - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = Default::default()); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = $default); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - - // maps with getters: - // - pub - // - $default - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = Default::default()); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: map $kty => $ty = $default); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - - // raw types for map - // maps: - // - pub - // - $default - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = Default::default()); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = $default); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - - // maps: - // - pub - // - $default - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = Default::default()); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($fn:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: map $kty => $ty = $default); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - - // try to factor out Option<> to get the raw type. - // simple values without getters: - // - pub - // - $default - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : Option<$ty:ty>; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = Default::default()); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : Option<$ty:ty> = $default:expr; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = $default); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - - // simple values with getters: - // - pub - // - config() - // - build() - // - $default - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : Option<$ty:ty>; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = Default::default()); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : Option<$ty:ty> = $default:expr; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (OPTION_TYPE Option<$ty>) $cratename $name: $ty = $default); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - - // simple values without getters: - // - pub - // - $default - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = Default::default()); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty = $default:expr; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = $default); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - - // simple values with getters: - // - pub - // - config() - // - build() - // - $default - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : $ty:ty; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = Default::default()); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - ($cratename:ident $traittype:ident $traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($rename:ident)*))* $(build($fn:expr))* : $ty:ty = $default:expr; $($t:tt)*) => { - __decl_storage_item!(($pub) ($traittype as $traitinstance) (RAW_TYPE $ty) $cratename $name: $ty = $default); - __decl_storage_items!($cratename $traittype $traitinstance $($t)*); - }; - - // exit - ($cratename:ident $traittype:ident $traitinstance:ident) => () -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __decl_storage_item { - // generator for maps. - (($pub:vis) ($traittype:ident as $traitinstance:ident) ($wraptype:ident $gettype:ty) $cratename:ident $name:ident : map $kty:ty => $ty:ty = $default:expr) => { - $pub struct $name<$traitinstance: $traittype>($crate::storage::generator::PhantomData<$traitinstance>); - - impl<$traitinstance: $traittype> $crate::storage::generator::StorageMap<$kty, $ty> for $name<$traitinstance> { - type Query = $gettype; - - /// Get the prefix key in storage. - fn prefix() -> &'static [u8] { - stringify!($cratename $name).as_bytes() - } - - /// Get the storage key used to fetch a value corresponding to a specific key. - fn key_for(x: &$kty) -> $crate::rstd::vec::Vec { - let mut key = <$name<$traitinstance> as $crate::storage::generator::StorageMap<$kty, $ty>>::prefix().to_vec(); - $crate::codec::Encode::encode_to(x, &mut key); - key - } - - /// Load the value associated with the given key from the map. - fn get(key: &$kty, storage: &S) -> Self::Query { - let key = <$name<$traitinstance> as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key); - - __handle_wrap_internal!($wraptype { - // raw type case - storage.get(&key[..]).unwrap_or_else(|| $default) - } { - // Option<> type case - storage.get(&key[..]).or_else(|| $default) - }) - } - - /// Take the value, reading and removing it. - fn take(key: &$kty, storage: &S) -> Self::Query { - let key = <$name<$traitinstance> as $crate::storage::generator::StorageMap<$kty, $ty>>::key_for(key); - - __handle_wrap_internal!($wraptype { - // raw type case - storage.take(&key[..]).unwrap_or_else(|| $default) - } { - // Option<> type case - storage.take(&key[..]).or_else(|| $default) - }) - } - - /// Mutate the value under a key - fn mutate R, S: $crate::GenericStorage>(key: &$kty, f: F, storage: &S) -> R { - let mut val = >::take(key, storage); - - let ret = f(&mut val); - - __handle_wrap_internal!($wraptype { - // raw type case - >::insert(key, &val, storage) - } { - // Option<> type case - match val { - Some(ref val) => >::insert(key, &val, storage), - None => >::remove(key, storage), - } - }); - - ret - } - } - }; - // generator for values. - (($pub:vis) ($traittype:ident as $traitinstance:ident) ($wraptype:ident $gettype:ty) $cratename:ident $name:ident : $ty:ty = $default:expr) => { - $pub struct $name<$traitinstance: $traittype>($crate::storage::generator::PhantomData<$traitinstance>); - - impl<$traitinstance: $traittype> $crate::storage::generator::StorageValue<$ty> for $name<$traitinstance> { - type Query = $gettype; - - /// Get the storage key. - fn key() -> &'static [u8] { - stringify!($cratename $name).as_bytes() - } - - /// Load the value from the provided storage instance. - fn get(storage: &S) -> Self::Query { - - __handle_wrap_internal!($wraptype { - // raw type case - storage.get(<$name<$traitinstance> as $crate::storage::generator::StorageValue<$ty>>::key()) - .unwrap_or_else(|| $default) - } { - // Option<> type case - storage.get(<$name<$traitinstance> as $crate::storage::generator::StorageValue<$ty>>::key()) - .or_else(|| $default) - }) - } - - /// Take a value from storage, removing it afterwards. - fn take(storage: &S) -> Self::Query { - __handle_wrap_internal!($wraptype { - // raw type case - storage.take(<$name<$traitinstance> as $crate::storage::generator::StorageValue<$ty>>::key()) - .unwrap_or_else(|| $default) - } { - // Option<> type case - storage.take(<$name<$traitinstance> as $crate::storage::generator::StorageValue<$ty>>::key()) - .or_else(|| $default) - }) - - } - - /// Mutate the value under a key. - fn mutate R, S: $crate::GenericStorage>(f: F, storage: &S) -> R { - let mut val = >::get(storage); - - let ret = f(&mut val); - - __handle_wrap_internal!($wraptype { - // raw type case - >::put(&val, storage) - } { - // Option<> type case - match val { - Some(ref val) => >::put(&val, storage), - None => >::kill(storage), - } - }); - - ret - } - } - }; -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __decl_store_items { - // maps: - // - pub - // - $default - ($(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => { - __decl_store_item!($name); __decl_store_items!($($t)*); - }; - ($(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => { - __decl_store_item!($name); __decl_store_items!($($t)*); - }; - - // maps: - // - pub - // - $default - ($(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => { - __decl_store_item!($name); __decl_store_items!($($t)*); - }; - ($(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => { - __decl_store_item!($name); __decl_store_items!($($t)*); - }; - - // simple values without getters: - // - pub - // - $default - ($(#[$doc:meta])* $pub:vis $name:ident : $ty:ty; $($t:tt)*) => { - __decl_store_item!($name); __decl_store_items!($($t)*); - }; - ($(#[$doc:meta])* $pub:vis $name:ident : $ty:ty = $default:expr; $($t:tt)*) => { - __decl_store_item!($name); __decl_store_items!($($t)*); - }; - - // simple values with getters: - // - pub - // - $default - ($(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => { - __decl_store_item!($name); __decl_store_items!($($t)*); - }; - ($(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => { - __decl_store_item!($name); __decl_store_items!($($t)*); - }; - - // exit - () => () -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __decl_store_item { - ($name:ident) => { type $name; } -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __impl_store_fns { - // with Option<> - // maps: - // - pub - // - $default - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => Option<$ty:ty>; $($t:tt)*) => { - __impl_store_fn!($traitinstance $name $getfn (Option<$ty>) map $kty => $ty); - __impl_store_fns!($traitinstance $($t)*); - }; - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => Option<$ty:ty> = $default:expr; $($t:tt)*) => { - __impl_store_fn!($traitinstance $name $getfn (Option<$ty>) map $kty => $ty); - __impl_store_fns!($traitinstance $($t)*); - }; - - // without Option<> - // maps: - // - pub - // - $default - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => { - __impl_store_fns!($traitinstance $($t)*); - }; - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => { - __impl_store_fns!($traitinstance $($t)*); - }; - - // maps: - // - pub - // - $default - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => { - __impl_store_fn!($traitinstance $name $getfn ($ty) map $kty => $ty); - __impl_store_fns!($traitinstance $($t)*); - }; - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => { - __impl_store_fn!($traitinstance $name $getfn ($ty) map $kty => $ty); - __impl_store_fns!($traitinstance $($t)*); - }; - - // with Option<> - // simple values with getters: - // - pub - // - $default - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : Option<$ty:ty>; $($t:tt)*) => { - __impl_store_fn!($traitinstance $name $getfn (Option<$ty>) $ty); - __impl_store_fns!($traitinstance $($t)*); - }; - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : Option<$ty:ty> = $default:expr; $($t:tt)*) => { - __impl_store_fn!($traitinstance $name $getfn (Option<$ty>) $ty); - __impl_store_fns!($traitinstance $($t)*); - }; - - // without Option<> - // simple values without getters: - // - pub - // - $default - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty; $($t:tt)*) => { - __impl_store_fns!($traitinstance $($t)*); - }; - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty = $default:expr; $($t:tt)*) => { - __impl_store_fns!($traitinstance $($t)*); - }; - - // simple values with getters: - // - pub - // - $default - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => { - __impl_store_fn!($traitinstance $name $getfn ($ty) $ty); - __impl_store_fns!($traitinstance $($t)*); - }; - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => { - __impl_store_fn!($traitinstance $name $getfn ($ty) $ty); - __impl_store_fns!($traitinstance $($t)*); - }; - - // exit - ($traitinstance:ident) => () -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __impl_store_fn { - ($traitinstance:ident $name:ident $get_fn:ident ($gettype:ty) map $kty:ty => $ty:ty) => { - pub fn $get_fn>(key: K) -> $gettype { - <$name<$traitinstance> as $crate::storage::generator::StorageMap<$kty, $ty>> :: get(key.borrow(), &$crate::storage::RuntimeStorage) - } - }; - ($traitinstance:ident $name:ident $get_fn:ident ($gettype:ty) $ty:ty) => { - pub fn $get_fn() -> $gettype { - <$name<$traitinstance> as $crate::storage::generator::StorageValue<$ty>> :: get(&$crate::storage::RuntimeStorage) - } - } -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __impl_store_items { - // maps: - // - pub - // - $default - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty; $($t:tt)*) => { - __impl_store_item!($name $traitinstance); - __impl_store_items!($traitinstance $($t)*); - }; - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => { - __impl_store_item!($name $traitinstance); - __impl_store_items!($traitinstance $($t)*); - }; - - // maps: - // - pub - // - $default - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty; $($t:tt)*) => { - __impl_store_item!($name $traitinstance); - __impl_store_items!($traitinstance $($t)*); - }; - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : map $kty:ty => $ty:ty = $default:expr; $($t:tt)*) => { - __impl_store_item!($name $traitinstance); - __impl_store_items!($traitinstance $($t)*); - }; - - // simple values without getters: - // - pub - // - $default - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty; $($t:tt)*) => { - __impl_store_item!($name $traitinstance); - __impl_store_items!($traitinstance $($t)*); - }; - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident : $ty:ty = $default:expr; $($t:tt)*) => { - __impl_store_item!($name $traitinstance); - __impl_store_items!($traitinstance $($t)*); - }; - - // simple values with getters: - // - pub - // - $default - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty; $($t:tt)*) => { - __impl_store_item!($name $traitinstance); - __impl_store_items!($traitinstance $($t)*); - }; - ($traitinstance:ident $(#[$doc:meta])* $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : $ty:ty = $default:expr; $($t:tt)*) => { - __impl_store_item!($name $traitinstance); - __impl_store_items!($traitinstance $($t)*); - }; - - // exit - ($traitinstance:ident) => () -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __impl_store_item { - ($name:ident $traitinstance:ident) => { type $name = $name<$traitinstance>; } -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __impl_store_metadata { - ( - $cratename:ident; - $($rest:tt)* - ) => { - pub fn store_metadata() -> $crate::storage::generator::StorageMetadata { - $crate::storage::generator::StorageMetadata { - prefix: $crate::storage::generator::DecodeDifferent::Encode(stringify!($cratename)), - functions: __store_functions_to_metadata!(; $( $rest )* ), - } - } - } -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __store_functions_to_metadata { - // maps: pub / $default - // map Option<> - ( - $( $metadata:expr ),*; - $(#[doc = $doc_attr:tt])* - $pub:vis $name:ident : - map $kty:ty => Option<$ty:ty> $(= $default:expr)*; - $($t:tt)* - ) => { - __store_functions_to_metadata!( - $( $metadata, )* - __store_function_to_metadata!( - $( $doc_attr ),*; $name; __store_type_to_metadata!($kty, $ty); - $crate::storage::generator::StorageFunctionModifier::Optional - ); - $( $t )* - ) - }; - - // map raw types - ( - $( $metadata:expr ),*; - $(#[doc = $doc_attr:tt])* - $pub:vis $name:ident : - map $kty:ty => $ty:ty $(= $default:expr)*; - $($t:tt)* - ) => { - __store_functions_to_metadata!( - $( $metadata, )* - __store_function_to_metadata!( - $( $doc_attr ),*; $name; __store_type_to_metadata!($kty, $ty); - $crate::storage::generator::StorageFunctionModifier::Default - ); - $( $t )* - ) - }; - - // map getters: pub / $default - // Option<> - ( - $( $metadata:expr ),*; - $(#[doc = $doc_attr:tt])* - $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : - map $kty:ty => Option<$ty:ty> $(= $default:expr)*; - $($t:tt)* - ) => { - __store_functions_to_metadata!( - $( $metadata, )* - __store_function_to_metadata!( - $( $doc_attr ),*; $name; __store_type_to_metadata!($kty, $ty); - $crate::storage::generator::StorageFunctionModifier::Optional - ); - $( $t )* - ) - }; - - // map getters: pub / $default - // raw types - ( - $( $metadata:expr ),*; - $(#[doc = $doc_attr:tt])* - $pub:vis $name:ident get($getfn:ident) $(build($build:expr))* : - map $kty:ty => $ty:ty $(= $default:expr)*; - $($t:tt)* - ) => { - __store_functions_to_metadata!( - $( $metadata, )* - __store_function_to_metadata!( - $( $doc_attr ),*; $name; __store_type_to_metadata!($kty, $ty); - $crate::storage::generator::StorageFunctionModifier::Default - ); - $( $t )* - ) - }; - - // simple values: pub / $default - ( - $( $metadata:expr ),*; - $(#[doc = $doc_attr:tt])* - $pub:vis $name:ident : Option<$ty:ty> $(= $default:expr)*; - $($t:tt)* - ) => { - __store_functions_to_metadata!( - $( $metadata, )* - __store_function_to_metadata!( - $( $doc_attr ),*; $name; __store_type_to_metadata!($ty); - $crate::storage::generator::StorageFunctionModifier::Optional - ); - $( $t )* - ) - }; - // raw types - ( - $( $metadata:expr ),*; - $(#[doc = $doc_attr:tt])* - $pub:vis $name:ident : $ty:ty $(= $default:expr)*; - $($t:tt)* - ) => { - __store_functions_to_metadata!( - $( $metadata, )* - __store_function_to_metadata!( - $( $doc_attr ),*; $name; __store_type_to_metadata!($ty); - $crate::storage::generator::StorageFunctionModifier::Default - ); - $( $t )* - ) - }; - - // simple values getters: pub / $default - // Option<> - ( - $( $metadata:expr ),*; - $(#[doc = $doc_attr:tt])* - $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : - Option<$ty:ty> $(= $default:expr)*; - $($t:tt)* - ) => { - __store_functions_to_metadata!( - $( $metadata, )* - __store_function_to_metadata!( - $( $doc_attr ),*; $name; __store_type_to_metadata!($ty); - $crate::storage::generator::StorageFunctionModifier::Optional - ); - $( $t )* - ) - }; - // simple values getters: pub / $default - // raw types - ( - $( $metadata:expr ),*; - $(#[doc = $doc_attr:tt])* - $pub:vis $name:ident get($getfn:ident) $(config($($myname:ident)*))* $(build($build:expr))* : - $ty:ty $(= $default:expr)*; - $($t:tt)* - ) => { - __store_functions_to_metadata!( - $( $metadata, )* - __store_function_to_metadata!( - $( $doc_attr ),*; $name; __store_type_to_metadata!($ty); - $crate::storage::generator::StorageFunctionModifier::Default - ); - $( $t )* - ) - }; - ( - $( $metadata:expr ),*; - ) => { - $crate::storage::generator::DecodeDifferent::Encode(&[ - $( $metadata ),* - ]) - } -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __store_function_to_metadata { - ($( $fn_doc:expr ),*; $name:ident; $type:expr; $modifier:expr) => { - $crate::storage::generator::StorageFunctionMetadata { - name: $crate::storage::generator::DecodeDifferent::Encode(stringify!($name)), - modifier: $modifier, - ty: $type, - documentation: $crate::storage::generator::DecodeDifferent::Encode(&[ $( $fn_doc ),* ]), - } - } -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __store_type_to_metadata { - ($name:ty) => { - $crate::storage::generator::StorageFunctionType::Plain( - $crate::storage::generator::DecodeDifferent::Encode(stringify!($name)), - ) - }; - ($key: ty, $value:ty) => { - $crate::storage::generator::StorageFunctionType::Map { - key: $crate::storage::generator::DecodeDifferent::Encode(stringify!($key)), - value: $crate::storage::generator::DecodeDifferent::Encode(stringify!($value)), - } - } -} - #[cfg(test)] // Do not complain about unused `dispatch` and `dispatch_aux`. #[allow(dead_code)] @@ -1851,6 +526,7 @@ mod tests { use std::cell::RefCell; use codec::Codec; use super::*; + use rstd::marker::PhantomData; impl Storage for RefCell, Vec>> { fn exists(&self, key: &[u8]) -> bool { @@ -1959,9 +635,12 @@ mod tests { GETMAPU32MYDEF get(map_u32_getter_mydef): map u32 => String = "map".into(); pub PUBGETMAPU32MYDEF get(pub_map_u32_getter_mydef): map u32 => String = "pubmap".into(); + + COMPLEX_TYPE1: ::std::vec::Vec<::Origin>; + COMPLEX_TYPE2: (Vec)>>, u32); + COMPLEX_TYPE3: ([u32;25]); } add_extra_genesis { - config(_marker) : ::std::marker::PhantomData; build(|_, _, _| {}); } } @@ -1980,80 +659,117 @@ mod tests { name: DecodeDifferent::Encode("U32"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructU32(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[ " Hello, this is doc!" ]), }, StorageFunctionMetadata { name: DecodeDifferent::Encode("PUBU32"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructPUBU32(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { name: DecodeDifferent::Encode("U32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructU32MYDEF(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { name: DecodeDifferent::Encode("PUBU32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructPUBU32MYDEF(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, - StorageFunctionMetadata { name: DecodeDifferent::Encode("GETU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("T::Origin")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructGETU32(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { name: DecodeDifferent::Encode("PUBGETU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructPUBGETU32(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { name: DecodeDifferent::Encode("GETU32WITHCONFIG"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructGETU32WITHCONFIG(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { name: DecodeDifferent::Encode("PUBGETU32WITHCONFIG"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructPUBGETU32WITHCONFIG(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, - StorageFunctionMetadata { name: DecodeDifferent::Encode("GETU32MYDEF"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructGETU32MYDEF(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { name: DecodeDifferent::Encode("PUBGETU32MYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructPUBGETU32MYDEF(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { name: DecodeDifferent::Encode("GETU32WITHCONFIGMYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructGETU32WITHCONFIGMYDEF(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { name: DecodeDifferent::Encode("PUBGETU32WITHCONFIGMYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructPUBGETU32WITHCONFIGMYDEF(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { name: DecodeDifferent::Encode("PUBGETU32WITHCONFIGMYDEFOPT"), modifier: StorageFunctionModifier::Optional, ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructPUBGETU32WITHCONFIGMYDEFOPT(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, @@ -2063,6 +779,9 @@ mod tests { ty: StorageFunctionType::Map{ key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String") }, + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructMAPU32(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { @@ -2071,6 +790,9 @@ mod tests { ty: StorageFunctionType::Map{ key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String") }, + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructPUBMAPU32(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { @@ -2079,6 +801,9 @@ mod tests { ty: StorageFunctionType::Map{ key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String") }, + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructMAPU32MYDEF(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { @@ -2087,15 +812,20 @@ mod tests { ty: StorageFunctionType::Map{ key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String") }, + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructPUBMAPU32MYDEF(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, - StorageFunctionMetadata { name: DecodeDifferent::Encode("GETMAPU32"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map{ key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String") }, + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructGETMAPU32(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { @@ -2104,15 +834,20 @@ mod tests { ty: StorageFunctionType::Map{ key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String") }, + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructPUBGETMAPU32(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, - StorageFunctionMetadata { name: DecodeDifferent::Encode("GETMAPU32MYDEF"), modifier: StorageFunctionModifier::Default, ty: StorageFunctionType::Map{ key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String") }, + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructGETMAPU32MYDEF(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, StorageFunctionMetadata { @@ -2121,6 +856,36 @@ mod tests { ty: StorageFunctionType::Map{ key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String") }, + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructPUBGETMAPU32MYDEF(PhantomData::)) + ), + documentation: DecodeDifferent::Encode(&[]), + }, + StorageFunctionMetadata { + name: DecodeDifferent::Encode("COMPLEX_TYPE1"), + modifier: StorageFunctionModifier::Default, + ty: StorageFunctionType::Plain(DecodeDifferent::Encode("::std::vec::Vec<::Origin>")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructCOMPLEX_TYPE1(PhantomData::)) + ), + documentation: DecodeDifferent::Encode(&[]), + }, + StorageFunctionMetadata { + name: DecodeDifferent::Encode("COMPLEX_TYPE2"), + modifier: StorageFunctionModifier::Default, + ty: StorageFunctionType::Plain(DecodeDifferent::Encode("(Vec)>>, u32)")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructCOMPLEX_TYPE2(PhantomData::)) + ), + documentation: DecodeDifferent::Encode(&[]), + }, + StorageFunctionMetadata { + name: DecodeDifferent::Encode("COMPLEX_TYPE3"), + modifier: StorageFunctionModifier::Default, + ty: StorageFunctionType::Plain(DecodeDifferent::Encode("([u32; 25])")), + default: DecodeDifferent::Encode( + DefaultByteGetter(&__GetByteStructCOMPLEX_TYPE3(PhantomData::)) + ), documentation: DecodeDifferent::Encode(&[]), }, ]) @@ -2143,6 +908,7 @@ mod tests { assert_eq!(config.pub_u32_getter_with_config_mydef, 1u32); assert_eq!(config.pub_u32_getter_with_config_mydef_opt, 100u32); } + } #[cfg(test)] @@ -2180,3 +946,29 @@ mod test2 { type BlockNumber = u32; } } + +#[cfg(test)] +#[allow(dead_code)] +mod test3 { + pub trait Trait { + type Origin; + type BlockNumber; + } + decl_module! { + pub struct Module for enum Call where origin: T::Origin {} + } + decl_storage! { + trait Store for Module as Test { + Foo get(foo) config(initial_foo): u32; + } + } + + type PairOf = (T, T); + + struct TraitImpl {} + + impl Trait for TraitImpl { + type Origin = u32; + type BlockNumber = u32; + } +} diff --git a/srml/system/Cargo.toml b/srml/system/Cargo.toml index c4bde66fc8f745c964e94d9ffa7a071f36147b27..f3dfded86341a3316c85ccc0970aa025b4554d37 100644 --- a/srml/system/Cargo.toml +++ b/srml/system/Cargo.toml @@ -6,9 +6,8 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } safe-mix = { version = "1.0", default-features = false} -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } @@ -20,7 +19,6 @@ srml-support = { path = "../support", default-features = false } default = ["std"] std = [ "serde/std", - "serde_derive", "safe-mix/std", "parity-codec/std", "parity-codec-derive/std", diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index b10b3112596ba8d0a33b1033d50eb0064c286ac6..93ccd85c67ec1a65f8f5e58a9dae1446e41f4965 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -27,10 +27,6 @@ extern crate sr_std as rstd; #[macro_use] extern crate srml_support as runtime_support; -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - #[macro_use] extern crate parity_codec_derive; @@ -41,7 +37,8 @@ extern crate safe_mix; use rstd::prelude::*; use primitives::traits::{self, CheckEqual, SimpleArithmetic, SimpleBitOps, Zero, One, Bounded, Lookup, - Hash, Member, MaybeDisplay, EnsureOrigin, Digest as DigestT, As, CurrentHeight, BlockNumberToHash}; + Hash, Member, MaybeDisplay, EnsureOrigin, Digest as DigestT, As, CurrentHeight, BlockNumberToHash, + MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup}; use substrate_primitives::storage::well_known_keys; use runtime_support::{storage, StorageValue, StorageMap, Parameter}; use safe_mix::TripletMix; @@ -55,6 +52,28 @@ use runtime_io::{twox_128, TestExternalities, Blake2Hasher}; #[cfg(any(feature = "std", test))] use substrate_primitives::ChangesTrieConfiguration; +/// Handler for when a new account has been created. +pub trait OnNewAccount { + /// A new account `who` has been registered. + fn on_new_account(who: &AccountId); +} + +impl OnNewAccount for () { + fn on_new_account(_who: &AccountId) {} +} + +/// Determinator to say whether a given account is unused. +pub trait IsDeadAccount { + /// Is the given account dead? + fn is_dead_account(who: &AccountId) -> bool; +} + +impl IsDeadAccount for () { + fn is_dead_account(_who: &AccountId) -> bool { + true + } +} + /// Compute the extrinsics root of a list of extrinsics. pub fn extrinsics_root(extrinsics: &[E]) -> H::Output { extrinsics_data_root::(extrinsics.iter().map(codec::Encode::encode).collect()) @@ -66,14 +85,15 @@ pub fn extrinsics_data_root(xts: Vec>) -> H::Output { H::enumerated_trie_root(&xts) } -pub trait Trait: Eq + Clone { +pub trait Trait: 'static + Eq + Clone { type Origin: Into>> + From>; - type Index: Parameter + Member + Default + MaybeDisplay + SimpleArithmetic + Copy; - type BlockNumber: Parameter + Member + MaybeDisplay + SimpleArithmetic + Default + Bounded + Copy + rstd::hash::Hash; - type Hash: Parameter + Member + MaybeDisplay + SimpleBitOps + Default + Copy + CheckEqual + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]>; + type Index: Parameter + Member + MaybeSerializeDebugButNotDeserialize + Default + MaybeDisplay + SimpleArithmetic + Copy; + type BlockNumber: Parameter + Member + MaybeSerializeDebug + MaybeDisplay + SimpleArithmetic + Default + Bounded + Copy + rstd::hash::Hash; + type Hash: Parameter + Member + MaybeSerializeDebug + MaybeDisplay + SimpleBitOps + Default + Copy + CheckEqual + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]>; type Hashing: Hash; - type Digest: Parameter + Member + Default + traits::Digest; - type AccountId: Parameter + Member + MaybeDisplay + Ord + Default; + type Digest: Parameter + Member + MaybeSerializeDebugButNotDeserialize + Default + traits::Digest; + type AccountId: Parameter + Member + MaybeSerializeDebug + MaybeDisplay + Ord + Default; + type Lookup: StaticLookup; type Header: Parameter + traits::Header< Number = Self::BlockNumber, Hash = Self::Hash, @@ -157,7 +177,7 @@ pub type Log = RawLog< >; /// A logs in this module. -#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] +#[cfg_attr(feature = "std", derive(Serialize, Debug))] #[derive(Encode, Decode, PartialEq, Eq, Clone)] pub enum RawLog { /// Changes trie has been computed for this block. Contains the root of @@ -179,8 +199,7 @@ impl RawLog { impl From> for primitives::testing::DigestItem { fn from(log: RawLog) -> primitives::testing::DigestItem { match log { - RawLog::ChangesTrieRoot(root) => primitives::generic::DigestItem::ChangesTrieRoot - ::(root), + RawLog::ChangesTrieRoot(root) => primitives::generic::DigestItem::ChangesTrieRoot(root), } } } @@ -204,7 +223,6 @@ decl_storage! { } add_extra_genesis { config(changes_trie_config): Option; - config(_phantom): ::std::marker::PhantomData; build(|storage: &mut primitives::StorageMap, _: &mut primitives::ChildrenStorageMap, config: &GenesisConfig| { use codec::Encode; @@ -287,7 +305,7 @@ impl Module { let mut digest = >::take(); let extrinsics_root = >::take(); let storage_root = T::Hashing::storage_root(); - let storage_changes_root = T::Hashing::storage_changes_root(number.as_()); + let storage_changes_root = T::Hashing::storage_changes_root(parent_hash, number.as_() - 1); // we can't compute changes trie root earlier && put it to the Digest // because it will include all currently existing temporaries @@ -405,10 +423,10 @@ impl Default for ChainContext { } impl Lookup for ChainContext { - type Source = T::AccountId; - type Target = T::AccountId; + type Source = ::Source; + type Target = ::Target; fn lookup(&self, s: Self::Source) -> rstd::result::Result { - Ok(s) + ::lookup(s) } } @@ -433,7 +451,7 @@ mod tests { use runtime_io::with_externalities; use substrate_primitives::H256; use primitives::BuildStorage; - use primitives::traits::BlakeTwo256; + use primitives::traits::{BlakeTwo256, IdentityLookup}; use primitives::testing::{Digest, DigestItem, Header}; impl_outer_origin!{ @@ -450,6 +468,7 @@ mod tests { type Hashing = BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = u16; type Log = DigestItem; diff --git a/srml/timestamp/Cargo.toml b/srml/timestamp/Cargo.toml index c07a62aeda357f201e0c90c747fdd8d91d8725f4..4e3ca526ade4741afa4db3bda818b95e1e4ebd58 100644 --- a/srml/timestamp/Cargo.toml +++ b/srml/timestamp/Cargo.toml @@ -6,9 +6,7 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } -parity-codec-derive = { version = "2.1", default-features = false } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } sr-io = { path = "../../core/sr-io", default-features = false } @@ -29,8 +27,6 @@ std = [ "sr-primitives/std", "srml-consensus/std", "serde/std", - "serde_derive", - "parity-codec-derive/std", "parity-codec/std", "substrate-primitives/std", "srml-system/std", diff --git a/srml/timestamp/src/lib.rs b/srml/timestamp/src/lib.rs index 36004e88c3853ade907413376fd82b49ae5d4a60..8f78aabefedfdc535b906d5f83ee06776f67ada2 100644 --- a/srml/timestamp/src/lib.rs +++ b/srml/timestamp/src/lib.rs @@ -29,7 +29,6 @@ //! ## Finalization //! //! This module should be hooked up to the finalization routine. -//! #![cfg_attr(not(feature = "std"), no_std)] @@ -39,10 +38,6 @@ extern crate sr_std as rstd; #[macro_use] extern crate srml_support as runtime_support; -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; - #[cfg(test)] extern crate substrate_primitives; #[cfg(test)] @@ -51,18 +46,38 @@ extern crate sr_primitives as runtime_primitives; extern crate srml_system as system; extern crate srml_consensus as consensus; extern crate parity_codec as codec; -#[macro_use] -extern crate parity_codec_derive; -use codec::HasCompact; use runtime_support::{StorageValue, Parameter}; -use runtime_support::dispatch::Result; -use runtime_primitives::RuntimeString; +use runtime_primitives::CheckInherentError; use runtime_primitives::traits::{ As, SimpleArithmetic, Zero, ProvideInherent, Block as BlockT, Extrinsic }; use system::ensure_inherent; use rstd::{result, ops::{Mul, Div}, vec::Vec}; +use runtime_support::for_each_tuple; + +/// A trait which is called when the timestamp is set. +pub trait OnTimestampSet { + fn on_timestamp_set(moment: Moment); +} + +macro_rules! impl_timestamp_set { + () => ( + impl OnTimestampSet for () { + fn on_timestamp_set(_: Moment) {} + } + ); + + ( $($t:ident)* ) => { + impl),*> OnTimestampSet for ($($t,)*) { + fn on_timestamp_set(moment: Moment) { + $($t::on_timestamp_set(moment.clone());)* + } + } + } +} + +for_each_tuple!(impl_timestamp_set); pub trait Trait: consensus::Trait + system::Trait { /// The position of the required timestamp-set extrinsic. @@ -70,6 +85,8 @@ pub trait Trait: consensus::Trait + system::Trait { /// Type used for expressing timestamp. type Moment: Parameter + Default + SimpleArithmetic + Mul + Div; + /// Something which can be notified when the timestamp is set. Set this to `()` if not needed. + type OnTimestampSet: OnTimestampSet; } decl_module! { @@ -82,10 +99,8 @@ decl_module! { /// if this call hasn't been invoked by that time. /// /// The timestamp should be greater than the previous one by the amount specified by `block_period`. - fn set(origin, now: ::Type) -> Result { + fn set(origin, #[compact] now: T::Moment) { ensure_inherent(origin)?; - let now = now.into(); - assert!(!::DidUpdate::exists(), "Timestamp must be updated only once in the block"); assert!( >::extrinsic_index() == Some(T::TIMESTAMP_SET_POSITION), @@ -96,9 +111,10 @@ decl_module! { Self::now().is_zero() || now >= Self::now() + Self::block_period(), "Timestamp must increment by at least between sequential blocks" ); - ::Now::put(now); + ::Now::put(now.clone()); ::DidUpdate::put(true); - Ok(()) + + >::on_timestamp_set(now); } fn on_finalise() { @@ -136,37 +152,33 @@ impl Module { } } -#[derive(Encode)] -#[cfg_attr(feature = "std", derive(Decode))] -pub enum InherentError { - Other(RuntimeString), - TimestampInFuture(u64), -} - impl ProvideInherent for Module { type Inherent = T::Moment; type Call = Call; - type Error = InherentError; fn create_inherent_extrinsics(data: Self::Inherent) -> Vec<(u32, Self::Call)> { - vec![(T::TIMESTAMP_SET_POSITION, Call::set(data.into()))] + let next_time = ::rstd::cmp::max(data, Self::now() + Self::block_period()); + vec![(T::TIMESTAMP_SET_POSITION, Call::set(next_time.into()))] } fn check_inherent Option<&Self::Call>>( block: &Block, data: Self::Inherent, extract_function: &F - ) -> result::Result<(), Self::Error> { + ) -> result::Result<(), CheckInherentError> { const MAX_TIMESTAMP_DRIFT: u64 = 60; let xt = block.extrinsics().get(T::TIMESTAMP_SET_POSITION as usize) - .ok_or_else(|| InherentError::Other("No valid timestamp inherent in block".into()))?; + .ok_or_else(|| CheckInherentError::Other("No valid timestamp inherent in block".into()))?; let t = match (xt.is_signed(), extract_function(&xt)) { (Some(false), Some(Call::set(ref t))) => t.clone(), - _ => return Err(InherentError::Other("No valid timestamp inherent in block".into())), - }.into().as_(); + _ => return Err(CheckInherentError::Other("No valid timestamp inherent in block".into())), + }.as_(); + let minimum = (Self::now() + Self::block_period()).as_(); if t > data.as_() + MAX_TIMESTAMP_DRIFT { - Err(InherentError::TimestampInFuture(t)) + Err(CheckInherentError::Other("Timestamp too far in future to accept".into())) + } else if t < minimum { + Err(CheckInherentError::ValidAtTimestamp(minimum)) } else { Ok(()) } @@ -180,8 +192,8 @@ mod tests { use runtime_io::{with_externalities, TestExternalities}; use substrate_primitives::H256; use runtime_primitives::BuildStorage; - use runtime_primitives::traits::BlakeTwo256; - use runtime_primitives::testing::{Digest, DigestItem, Header}; + use runtime_primitives::traits::{BlakeTwo256, IdentityLookup}; + use runtime_primitives::testing::{Digest, DigestItem, Header, UintAuthorityId}; impl_outer_origin! { pub enum Origin for Test {} @@ -197,6 +209,7 @@ mod tests { type Hashing = BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = (); type Log = DigestItem; @@ -204,23 +217,26 @@ mod tests { impl consensus::Trait for Test { const NOTE_OFFLINE_POSITION: u32 = 1; type Log = DigestItem; - type SessionKey = u64; - type OnOfflineValidator = (); + type SessionKey = UintAuthorityId; + type InherentOfflineReport = (); } impl Trait for Test { const TIMESTAMP_SET_POSITION: u32 = 0; type Moment = u64; + type OnTimestampSet = (); } type Timestamp = Module; #[test] fn timestamp_works() { let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; - t.extend(GenesisConfig:: { period: 0 }.build_storage().unwrap().0); + t.extend(GenesisConfig:: { + period: 5, + }.build_storage().unwrap().0); with_externalities(&mut TestExternalities::new(t), || { Timestamp::set_timestamp(42); - assert_ok!(Timestamp::dispatch(Call::set(69.into()), Origin::INHERENT)); + assert_ok!(Timestamp::dispatch(Call::set(69), Origin::INHERENT)); assert_eq!(Timestamp::now(), 69); }); } @@ -229,12 +245,14 @@ mod tests { #[should_panic(expected = "Timestamp must be updated only once in the block")] fn double_timestamp_should_fail() { let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; - t.extend(GenesisConfig:: { period: 5 }.build_storage().unwrap().0); + t.extend(GenesisConfig:: { + period: 5, + }.build_storage().unwrap().0); with_externalities(&mut TestExternalities::new(t), || { Timestamp::set_timestamp(42); - assert_ok!(Timestamp::dispatch(Call::set(69.into()), Origin::INHERENT)); - let _ = Timestamp::dispatch(Call::set(70.into()), Origin::INHERENT); + assert_ok!(Timestamp::dispatch(Call::set(69), Origin::INHERENT)); + let _ = Timestamp::dispatch(Call::set(70), Origin::INHERENT); }); } @@ -242,11 +260,13 @@ mod tests { #[should_panic(expected = "Timestamp must increment by at least between sequential blocks")] fn block_period_is_enforced() { let mut t = system::GenesisConfig::::default().build_storage().unwrap().0; - t.extend(GenesisConfig:: { period: 5 }.build_storage().unwrap().0); + t.extend(GenesisConfig:: { + period: 5, + }.build_storage().unwrap().0); with_externalities(&mut TestExternalities::new(t), || { Timestamp::set_timestamp(42); - let _ = Timestamp::dispatch(Call::set(46.into()), Origin::INHERENT); + let _ = Timestamp::dispatch(Call::set(46), Origin::INHERENT); }); } } diff --git a/srml/treasury/Cargo.toml b/srml/treasury/Cargo.toml index 32621e15619b9ec7c338e135103b0a54dc8a877a..4c7d63d778c5ab159fecd0f6aeca6cf9fb8861fe 100644 --- a/srml/treasury/Cargo.toml +++ b/srml/treasury/Cargo.toml @@ -6,8 +6,7 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } @@ -21,7 +20,6 @@ srml-balances = { path = "../balances", default-features = false } default = ["std"] std = [ "serde/std", - "serde_derive", "parity-codec/std", "parity-codec-derive/std", "substrate-primitives/std", diff --git a/srml/treasury/src/lib.rs b/srml/treasury/src/lib.rs index 94e60e4b32efaf2834e73fd3be9c515aba7de22b..7abcebfe922a393dada2c44d54f069d3ca128beb 100644 --- a/srml/treasury/src/lib.rs +++ b/srml/treasury/src/lib.rs @@ -25,10 +25,6 @@ extern crate srml_support as runtime_support; #[cfg(test)] extern crate sr_io as runtime_io; - -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; #[cfg(feature = "std")] extern crate serde; @@ -44,10 +40,8 @@ extern crate srml_balances as balances; use rstd::prelude::*; use runtime_support::{StorageValue, StorageMap}; -use runtime_support::dispatch::Result; -use runtime_primitives::{Permill, traits::{Zero, EnsureOrigin}}; -use codec::{HasCompact, Compact}; -use balances::{OnDilution, address::Address}; +use runtime_primitives::{Permill, traits::{Zero, EnsureOrigin, StaticLookup}}; +use balances::OnDilution; use system::ensure_signed; /// Our module's configuration trait. All our types and consts go in here. If the @@ -73,18 +67,17 @@ type ProposalIndex = u32; decl_module! { // Simple declaration of the `Module` type. Lets the macro know what its working on. pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; + fn deposit_event() = default; /// Put forward a suggestion for spending. A deposit proportional to the value /// is reserved and slashed if the proposal is rejected. It is returned once the /// proposal is awarded. fn propose_spend( origin, - value: ::Type, - beneficiary: Address - ) -> Result { + #[compact] value: T::Balance, + beneficiary: ::Source + ) { let proposer = ensure_signed(origin)?; - let beneficiary = >::lookup(beneficiary)?; - let value = value.into(); + let beneficiary = T::Lookup::lookup(beneficiary)?; let bond = Self::calculate_bond(value); >::reserve(&proposer, bond) @@ -95,57 +88,44 @@ decl_module! { >::insert(c, Proposal { proposer, value, beneficiary, bond }); Self::deposit_event(RawEvent::Proposed(c)); - - Ok(()) } /// Set the balance of funds available to spend. - fn set_pot(new_pot: ::Type) -> Result { + fn set_pot(#[compact] new_pot: T::Balance) { // Put the new value into storage. - >::put(new_pot.into()); - - // All good. - Ok(()) + >::put(new_pot); } /// (Re-)configure this module. fn configure( - proposal_bond: Permill, - proposal_bond_minimum: ::Type, - spend_period: ::Type, - burn: Permill - ) -> Result { + #[compact] proposal_bond: Permill, + #[compact] proposal_bond_minimum: T::Balance, + #[compact] spend_period: T::BlockNumber, + #[compact] burn: Permill + ) { >::put(proposal_bond); - >::put(proposal_bond_minimum.into()); - >::put(spend_period.into()); + >::put(proposal_bond_minimum); + >::put(spend_period); >::put(burn); - Ok(()) } /// Reject a proposed spend. The original deposit will be slashed. - fn reject_proposal(origin, proposal_id: Compact) -> Result { + fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) { T::RejectOrigin::ensure_origin(origin)?; - let proposal_id: ProposalIndex = proposal_id.into(); - let proposal = >::take(proposal_id).ok_or("No proposal at that index")?; let value = proposal.bond; let _ = >::slash_reserved(&proposal.proposer, value); - - Ok(()) } /// Approve a proposal. At a later time, the proposal will be allocated to the beneficiary /// and the original deposit will be returned. - fn approve_proposal(origin, proposal_id: Compact) -> Result { + fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) { T::ApproveOrigin::ensure_origin(origin)?; - let proposal_id = proposal_id.into(); ensure!(>::exists(proposal_id), "No proposal at that index"); >::mutate(|v| v.push(proposal_id)); - - Ok(()) } fn on_finalise(n: T::BlockNumber) { @@ -288,7 +268,7 @@ mod tests { use runtime_io::with_externalities; use substrate_primitives::{H256, Blake2Hasher}; use runtime_primitives::BuildStorage; - use runtime_primitives::traits::{BlakeTwo256, OnFinalise}; + use runtime_primitives::traits::{BlakeTwo256, OnFinalise, IdentityLookup}; use runtime_primitives::testing::{Digest, DigestItem, Header}; impl_outer_origin! { @@ -305,13 +285,14 @@ mod tests { type Hashing = BlakeTwo256; type Digest = Digest; type AccountId = u64; + type Lookup = IdentityLookup; type Header = Header; type Event = (); type Log = DigestItem; } impl balances::Trait for Test { type Balance = u64; - type AccountIndex = u64; + type OnNewAccount = (); type OnFreeBalanceZero = (); type EnsureAccountLiquid = (); type Event = (); @@ -333,7 +314,6 @@ mod tests { transfer_fee: 0, creation_fee: 0, existential_deposit: 0, - reclaim_rebate: 0, }.build_storage().unwrap().0); t.extend(GenesisConfig::{ proposal_bond: Permill::from_percent(5), @@ -368,7 +348,7 @@ mod tests { #[test] fn spend_proposal_takes_min_deposit() { with_externalities(&mut new_test_ext(), || { - assert_ok!(Treasury::propose_spend(Origin::signed(0), 1.into(), Address::Id(3))); + assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); assert_eq!(Balances::free_balance(&0), 99); assert_eq!(Balances::reserved_balance(&0), 1); }); @@ -377,7 +357,7 @@ mod tests { #[test] fn spend_proposal_takes_proportional_deposit() { with_externalities(&mut new_test_ext(), || { - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3))); + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); assert_eq!(Balances::free_balance(&0), 95); assert_eq!(Balances::reserved_balance(&0), 5); }); @@ -386,7 +366,7 @@ mod tests { #[test] fn spend_proposal_fails_when_proposer_poor() { with_externalities(&mut new_test_ext(), || { - assert_noop!(Treasury::propose_spend(Origin::signed(2), 100.into(), Address::Id(3)), "Proposer's balance too low"); + assert_noop!(Treasury::propose_spend(Origin::signed(2), 100, 3), "Proposer's balance too low"); }); } @@ -395,8 +375,8 @@ mod tests { with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3))); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0.into())); + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); >::on_finalise(1); assert_eq!(Balances::free_balance(&3), 0); @@ -419,8 +399,8 @@ mod tests { with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3))); - assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0.into())); + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); >::on_finalise(2); assert_eq!(Balances::free_balance(&3), 0); @@ -433,23 +413,23 @@ mod tests { with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3))); - assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0.into())); - assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0.into()), "No proposal at that index"); + 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), "No proposal at that index"); }); } #[test] fn reject_non_existant_spend_proposal_fails() { with_externalities(&mut new_test_ext(), || { - assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0.into()), "No proposal at that index"); + assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), "No proposal at that index"); }); } #[test] fn accept_non_existant_spend_proposal_fails() { with_externalities(&mut new_test_ext(), || { - assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0.into()), "No proposal at that index"); + assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), "No proposal at that index"); }); } @@ -458,9 +438,9 @@ mod tests { with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3))); - assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0.into())); - assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0.into()), "No proposal at that index"); + 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), "No proposal at that index"); }); } @@ -469,8 +449,8 @@ mod tests { with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); - assert_ok!(Treasury::propose_spend(Origin::signed(0), 100.into(), Address::Id(3))); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0.into())); + assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); >::on_finalise(2); assert_eq!(Balances::free_balance(&3), 100); @@ -483,8 +463,8 @@ mod tests { with_externalities(&mut new_test_ext(), || { Treasury::on_dilution(100, 100); - assert_ok!(Treasury::propose_spend(Origin::signed(0), 150.into(), Address::Id(3))); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0.into())); + assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3)); + assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); >::on_finalise(2); assert_eq!(Treasury::pot(), 100); diff --git a/srml/upgrade-key/Cargo.toml b/srml/upgrade-key/Cargo.toml index 980a7240a90aa41ba30961c33e03be6179b3ebf0..8e51779b25a2e87abe4c28e432987962f3d242ad 100644 --- a/srml/upgrade-key/Cargo.toml +++ b/srml/upgrade-key/Cargo.toml @@ -6,14 +6,14 @@ authors = ["Parity Technologies "] [dependencies] hex-literal = "0.1.0" serde = { version = "1.0", default-features = false } -serde_derive = { version = "1.0", optional = true } -parity-codec = { version = "2.1", default-features = false } +parity-codec = { version = "2.2", default-features = false } parity-codec-derive = { version = "2.1", default-features = false } substrate-primitives = { path = "../../core/primitives", default-features = false } sr-std = { path = "../../core/sr-std", default-features = false } sr-io = { path = "../../core/sr-io", default-features = false } sr-primitives = { path = "../../core/sr-primitives", default-features = false } srml-support = { path = "../support", default-features = false } +srml-support-procedural = { path = "../support/procedural" } srml-system = { path = "../system", default-features = false } srml-consensus = { path = "../consensus", default-features = false } @@ -21,7 +21,6 @@ srml-consensus = { path = "../consensus", default-features = false } default = ["std"] std = [ "serde/std", - "serde_derive", "parity-codec/std", "parity-codec-derive/std", "sr-std/std", diff --git a/srml/upgrade-key/src/lib.rs b/srml/upgrade-key/src/lib.rs index 28433d8fbd5db4d4955f30f3365042eda1e76d7e..1b10d3a3d3a43c22112839121efe1747c3321b18 100644 --- a/srml/upgrade-key/src/lib.rs +++ b/srml/upgrade-key/src/lib.rs @@ -25,19 +25,18 @@ extern crate sr_io; #[cfg(test)] extern crate substrate_primitives; extern crate sr_primitives; -#[cfg(feature = "std")] -#[macro_use] -extern crate serde_derive; #[macro_use] extern crate parity_codec_derive; extern crate parity_codec as codec; #[macro_use] extern crate srml_support as support; + extern crate srml_system as system; extern crate srml_consensus as consensus; use sr_std::prelude::*; -use support::{StorageValue, dispatch::Result}; +use sr_primitives::traits::StaticLookup; +use support::StorageValue; use system::ensure_signed; pub trait Trait: consensus::Trait + system::Trait { @@ -48,27 +47,24 @@ pub trait Trait: consensus::Trait + system::Trait { decl_module! { // Simple declaration of the `Module` type. Lets the macro know what its working on. pub struct Module for enum Call where origin: T::Origin { - fn deposit_event() = default; - fn upgrade(origin, new: Vec) -> Result { + fn deposit_event() = default; + fn upgrade(origin, new: Vec) { // This is a public call, so we ensure that the origin is some signed account. let _sender = ensure_signed(origin)?; ensure!(_sender == Self::key(), "only the current upgrade key can use the upgrade_key module"); >::set_code(new)?; Self::deposit_event(RawEvent::Upgraded); - - Ok(()) } - fn set_key(origin, new: T::AccountId) -> Result { + fn set_key(origin, new: ::Source) { // This is a public call, so we ensure that the origin is some signed account. let _sender = ensure_signed(origin)?; ensure!(_sender == Self::key(), "only the current upgrade key can use the upgrade_key module"); + let new = T::Lookup::lookup(new)?; Self::deposit_event(RawEvent::KeyChanged(Self::key())); >::put(new); - - Ok(()) } } } diff --git a/subkey/src/cli.yml b/subkey/src/cli.yml index 6e1a13dca8c550cb80d0879320b0d01a5336e1fc..57cf98bdf2e5024c1364ce1f3e9d3f52a90bcbae 100644 --- a/subkey/src/cli.yml +++ b/subkey/src/cli.yml @@ -2,6 +2,8 @@ name: subkey author: "Parity Team " about: A substrate key utility subcommands: + - generate: + about: Generate a random account - restore: about: Gets a public key and a SS58 address from the provided seed phrase args: diff --git a/subkey/src/main.rs b/subkey/src/main.rs index 190921d750028aa63855cefea1ecc3d519233c3a..48b9a67654e9af966b9e997224c42dd3a5c5c761 100644 --- a/subkey/src/main.rs +++ b/subkey/src/main.rs @@ -23,25 +23,40 @@ extern crate rand; #[macro_use] extern crate clap; +use rand::{OsRng, Rng}; use substrate_primitives::{ed25519::Pair, hexdisplay::HexDisplay}; mod vanity; +fn print_account(seed: &[u8; 32]) { + let pair = Pair::from_seed(seed); + println!("Seed 0x{} is account:\n Public key (hex): 0x{}\n Address (SS58): {}", + HexDisplay::from(seed), + HexDisplay::from(&pair.public().0), + pair.public().to_ss58check() + ); +} + fn main() { let yaml = load_yaml!("cli.yml"); let matches = clap::App::from_yaml(yaml).get_matches(); match matches.subcommand() { + ("generate", Some(_matches)) => { + let mut seed = [0u8; 32]; + OsRng::new().unwrap().fill_bytes(&mut seed[..]); + print_account(&seed); + } ("vanity", Some(matches)) => { let desired: String = matches.value_of("pattern").map(str::to_string).unwrap_or_default(); let key = vanity::generate_key(&desired).expect("Key generation failed"); - println!("Seed {} (hex: 0x{}) - {} ({}%)", - key.pair.public().to_ss58check(), - HexDisplay::from(&key.pair.public().0), - HexDisplay::from(&key.seed), - key.score); + println!("Found account with score {}%", key.score); + print_account(&key.seed); } ("restore", Some(matches)) => { + // This subcommand is probably obsolete, see + // https://github.com/paritytech/substrate/issues/1063 + let mut raw_seed = matches.value_of("seed") .map(str::as_bytes) .expect("seed parameter is required; thus it can't be None; qed"); @@ -56,13 +71,7 @@ fn main() { let mut seed = [' ' as u8; 32]; let len = raw_seed.len().min(32); seed[..len].copy_from_slice(&raw_seed[..len]); - let pair = Pair::from_seed(&seed); - - println!("Seed 0x{} is account:\n Public key (hex): 0x{}\n Address (SS58): {}", - HexDisplay::from(&seed), - HexDisplay::from(&pair.public().0), - pair.public().to_ss58check() - ); + print_account(&seed); }, _ => print_usage(&matches), } diff --git a/subkey/src/vanity.rs b/subkey/src/vanity.rs index fea1066e2da7b8693b728c187496a18b21c6747d..9eb621cc55116b1cb6e3a69a158dd2db0f4b10e7 100644 --- a/subkey/src/vanity.rs +++ b/subkey/src/vanity.rs @@ -57,10 +57,14 @@ fn calculate_score(_desired: &str, key: &str) -> usize { 0 } -pub fn generate_key(_desired: &str) -> Result { - println!("Generating key containing pattern '{}'", _desired); +pub fn generate_key(desired: &str) -> Result { + if desired.is_empty() { + return Err("Pattern must not be empty"); + } + + println!("Generating key containing pattern '{}'", desired); - let top = 45 + (_desired.len() * 48); + let top = 45 + (desired.len() * 48); let mut best = 0; let mut seed = [0u8; 32]; let mut done = 0; @@ -75,8 +79,8 @@ pub fn generate_key(_desired: &str) -> Result { let p = Pair::from_seed(&seed); let ss58 = p.public().to_ss58check(); - let score = calculate_score(&_desired, &ss58); - if score > best || _desired.len() < 2 { + let score = calculate_score(&desired, &ss58); + if score > best || desired.len() < 2 { best = score; let keypair = KeyPair { pair: p, diff --git a/test-utils/chain-spec-builder/Cargo.lock b/test-utils/chain-spec-builder/Cargo.lock new file mode 100644 index 0000000000000000000000000000000000000000..bcad2f12d2678a1b472deddd77233a154304a3af --- /dev/null +++ b/test-utils/chain-spec-builder/Cargo.lock @@ -0,0 +1,4334 @@ +[[package]] +name = "aes-ctr" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aes-soft 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "aesni 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ctr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aes-soft" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aesni" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aho-corasick" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aio-limited" +version = "0.1.0" +source = "git+https://github.com/paritytech/aio-limited.git#a7c0bd6944902b1c9fb2bcf4f8fe1412c824b5b9" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "app_dirs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "arrayref" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "arrayvec" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "asn1_der" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "etrace 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "base-x" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "base58" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "base64" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "base64" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bigint" +version = "4.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bindgen" +version = "0.37.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "clang-sys 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "blake2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-mac 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "block-buffer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "block-cipher-trait" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bs58" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byte-tools" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "bytes" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cc" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cexpr" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cfg-if" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "chain-spec-builder" +version = "0.1.0" +dependencies = [ + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "node-cli 0.1.0", + "substrate-primitives 0.1.0", + "substrate-service 0.3.0", +] + +[[package]] +name = "chashmap" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "chrono" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "clang-sys" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "clap" +version = "2.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "clear_on_drop" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "core-foundation" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "core-foundation-sys" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "crossbeam-deque" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-deque" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-utils" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-utils" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "crunchy" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "crunchy" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "crypto-mac" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crypto-mac" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ctr" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "curve25519-dalek" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "data-encoding" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "datastore" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "base64 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chashmap 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "digest" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "discard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ed25519-dalek" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "either" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "elastic-array" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "env_logger" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "env_logger" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "environmental" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "error-chain" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "eth-secp256k1" +version = "0.5.7" +source = "git+https://github.com/paritytech/rust-secp256k1#ccc06e7480148b723eb44ac56cf4d20eec380b6f" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "etrace" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "exit-future" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "fdlimit" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "finality-grandpa" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fixed-hash" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fnv" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "fs-swap" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "futures" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "futures-cpupool" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "generic-array" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "glob" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "globset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "h2" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hash-db" +version = "0.9.0" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" + +[[package]] +name = "hash256-std-hasher" +version = "0.9.0" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" +dependencies = [ + "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "heapsize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "heck" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hex" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hex-literal" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hex-literal-impl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hex-literal-impl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hmac" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "http" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "httparse" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "humantime" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hyper" +version = "0.10.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hyper" +version = "0.12.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "idna" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "indexmap" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "integer-sqrt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "interleaved-ordered" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "iovec" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "itoa" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "jsonrpc-core" +version = "9.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git#2ed142d55662155b0dc76b9b5d2732300f265dd6" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jsonrpc-http-server" +version = "9.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git#2ed142d55662155b0dc76b9b5d2732300f265dd6" +dependencies = [ + "hyper 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jsonrpc-macros" +version = "9.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git#2ed142d55662155b0dc76b9b5d2732300f265dd6" +dependencies = [ + "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jsonrpc-pubsub" +version = "9.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git#2ed142d55662155b0dc76b9b5d2732300f265dd6" +dependencies = [ + "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jsonrpc-server-utils" +version = "9.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git#2ed142d55662155b0dc76b9b5d2732300f265dd6" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "jsonrpc-ws-server" +version = "9.0.0" +source = "git+https://github.com/paritytech/jsonrpc.git#2ed142d55662155b0dc76b9b5d2732300f265dd6" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kvdb" +version = "0.1.0" +source = "git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6#616b40150ded71f57f650067fcbc5c99d7c343e6" +dependencies = [ + "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6)", +] + +[[package]] +name = "kvdb-rocksdb" +version = "0.1.4" +source = "git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6#616b40150ded71f57f650067fcbc5c99d7c343e6" +dependencies = [ + "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rocksdb 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "language-tags" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazycell" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.43" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libloading" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-dns 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-floodsub 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-identify 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-kad 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-mplex 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-peerstore 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-ping 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-ratelimit 0.1.1 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-relay 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-secio 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-tcp-transport 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-transport-timeout 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-uds 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-websocket 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-yamux 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "multihash 0.8.1-pre (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "stdweb 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-core" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "multihash 0.8.1-pre (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "multistream-select 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rw-stream-sink 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-dns" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "tokio-dns-unofficial 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-floodsub" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-identify" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-peerstore 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-kad" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bigint 4.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "datastore 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-identify 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-ping 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "multihash 0.8.1-pre (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-mplex" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-peerstore" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "datastore 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-ping" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "multistream-select 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-ratelimit" +version = "0.1.1" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "aio-limited 0.1.0 (git+https://github.com/paritytech/aio-limited.git)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-relay" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "libp2p-peerstore 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-secio" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "aes-ctr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "asn1_der 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "ctr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ed25519-dalek 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rw-stream-sink 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "stdweb 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "twofish 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-tcp-transport" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "tk-listen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-transport-timeout" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-uds" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "tokio-uds 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-websocket" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "rw-stream-sink 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "stdweb 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "websocket 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libp2p-yamux" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "yamux 0.1.0 (git+https://github.com/paritytech/yamux)", +] + +[[package]] +name = "librocksdb-sys" +version = "5.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "make-cmd 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lock_api" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "make-cmd" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "mashup" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "mashup-impl 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mashup-impl" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "matches" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memoffset" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memory-db" +version = "0.9.0" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" +dependencies = [ + "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memory_units" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "mime" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio" +version = "0.6.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-extras" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-uds" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "multiaddr" +version = "0.3.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "data-encoding 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "multihash 0.8.1-pre (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "multihash" +version = "0.8.1-pre" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "blake2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "multistream-select" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "names" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "native-tls" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "net2" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "node-cli" +version = "0.1.0" +dependencies = [ + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "node-executor 0.1.0", + "node-primitives 0.1.0", + "node-runtime 0.1.0", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "structopt 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-cli 0.3.0", + "substrate-client 0.1.0", + "substrate-consensus-aura 0.1.0", + "substrate-consensus-common 0.1.0", + "substrate-finality-grandpa 0.1.0", + "substrate-keystore 0.1.0", + "substrate-network 0.1.0", + "substrate-primitives 0.1.0", + "substrate-service 0.3.0", + "substrate-transaction-pool 0.1.0", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "node-executor" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "node-primitives 0.1.0", + "node-runtime 0.1.0", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "substrate-executor 0.1.0", + "substrate-primitives 0.1.0", + "substrate-state-machine 0.1.0", + "substrate-trie 0.4.0", + "trie-root 0.9.0 (git+https://github.com/paritytech/trie)", +] + +[[package]] +name = "node-primitives" +version = "0.1.0" +dependencies = [ + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "node-runtime" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "node-primitives 0.1.0", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "sr-version 0.1.0", + "srml-balances 0.1.0", + "srml-consensus 0.1.0", + "srml-contract 0.1.0", + "srml-council 0.1.0", + "srml-democracy 0.1.0", + "srml-executive 0.1.0", + "srml-grandpa 0.1.0", + "srml-session 0.1.0", + "srml-staking 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "srml-timestamp 0.1.0", + "srml-treasury 0.1.0", + "srml-upgrade-key 0.1.0", + "substrate-client 0.1.0", + "substrate-finality-grandpa-primitives 0.1.0", + "substrate-keyring 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "nodrop" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "nohash-hasher" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "nom" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num_cpus" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ole32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "opaque-debug" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "openssl" +version = "0.10.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "openssl-probe" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "openssl-sys" +version = "0.9.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "owning_ref" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "owning_ref" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parity-bytes" +version = "0.1.0" +source = "git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6#616b40150ded71f57f650067fcbc5c99d7c343e6" + +[[package]] +name = "parity-codec" +version = "2.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parity-codec-derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parity-crypto" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parity-wasm" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "percent-encoding" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pkg-config" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro-hack" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-hack-impl" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro2" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "protobuf" +version = "2.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pwasm-utils" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quick-error" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "quick-error" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "quote" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_chacha" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_pcg" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "remove_dir_all" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ring" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rocksdb" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "librocksdb-sys 5.14.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rust-crypto" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-hex" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-hex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rw-stream-sink" +version = "0.1.0" +source = "git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5#d961e656a74d1bab5366d371a06f9e10d5f4a6c5" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ryu" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "safe-mix" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "safemem" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "safemem" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "schannel" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scoped-tls" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "security-framework" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "security-framework-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "security-framework-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde_derive" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sha1" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "sha1" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "sha2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "shell32-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "slab" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slab" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slog" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "slog-async" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "slog-json" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "slog-scope" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "smallvec" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sr-api-macros" +version = "0.1.0" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sr-io" +version = "0.1.0" +dependencies = [ + "environmental 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 0.1.0", + "substrate-primitives 0.1.0", + "substrate-state-machine 0.1.0", + "substrate-trie 0.4.0", +] + +[[package]] +name = "sr-primitives" +version = "0.1.0" +dependencies = [ + "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-std 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "sr-sandbox" +version = "0.1.0" +dependencies = [ + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 0.1.0", + "substrate-primitives 0.1.0", + "wasmi 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sr-std" +version = "0.1.0" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sr-version" +version = "0.1.0" +dependencies = [ + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "sr-std 0.1.0", +] + +[[package]] +name = "srml-balances" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "substrate-keyring 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-consensus" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-contract" +version = "0.1.0" +dependencies = [ + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", + "pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-sandbox 0.1.0", + "sr-std 0.1.0", + "srml-balances 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-council" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-balances 0.1.0", + "srml-democracy 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-democracy" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-balances 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-executive" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", +] + +[[package]] +name = "srml-grandpa" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-session 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "substrate-finality-grandpa-primitives 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-metadata" +version = "0.1.0" +dependencies = [ + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-session" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-consensus 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "srml-timestamp 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-staking" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-balances 0.1.0", + "srml-consensus 0.1.0", + "srml-session 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "srml-timestamp 0.1.0", + "substrate-keyring 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-support" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-metadata 0.1.0", +] + +[[package]] +name = "srml-system" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-support 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-timestamp" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-consensus 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-treasury" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-balances 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "srml-upgrade-key" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "srml-consensus 0.1.0", + "srml-support 0.1.0", + "srml-system 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "static_assertions" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "stdweb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "stdweb" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "stdweb-derive 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "stdweb-internal-macros 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "stdweb-internal-runtime 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base-x 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "stream-cipher" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "string" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "strsim" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "structopt" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "structopt-derive" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-cli" +version = "0.3.0" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "structopt 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-client 0.1.0", + "substrate-network 0.1.0", + "substrate-primitives 0.1.0", + "substrate-service 0.3.0", + "substrate-telemetry 0.3.0", + "sysinfo 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-client" +version = "0.1.0" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-api-macros 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "sr-version 0.1.0", + "substrate-consensus-common 0.1.0", + "substrate-executor 0.1.0", + "substrate-keyring 0.1.0", + "substrate-primitives 0.1.0", + "substrate-state-machine 0.1.0", + "substrate-telemetry 0.3.0", + "substrate-trie 0.4.0", +] + +[[package]] +name = "substrate-client-db" +version = "0.1.0" +dependencies = [ + "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", + "kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6)", + "kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "substrate-client 0.1.0", + "substrate-executor 0.1.0", + "substrate-primitives 0.1.0", + "substrate-state-db 0.1.0", + "substrate-state-machine 0.1.0", + "substrate-trie 0.4.0", +] + +[[package]] +name = "substrate-consensus-aura" +version = "0.1.0" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-version 0.1.0", + "srml-consensus 0.1.0", + "srml-support 0.1.0", + "substrate-client 0.1.0", + "substrate-consensus-common 0.1.0", + "substrate-network 0.1.0", + "substrate-primitives 0.1.0", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-consensus-common" +version = "0.1.0" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "sr-version 0.1.0", + "substrate-primitives 0.1.0", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-executor" +version = "0.1.0" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-version 0.1.0", + "substrate-primitives 0.1.0", + "substrate-serializer 0.1.0", + "substrate-state-machine 0.1.0", + "substrate-trie 0.4.0", + "wasmi 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-finality-grandpa" +version = "0.1.0" +dependencies = [ + "finality-grandpa 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "substrate-client 0.1.0", + "substrate-consensus-common 0.1.0", + "substrate-finality-grandpa-primitives 0.1.0", + "substrate-network 0.1.0", + "substrate-primitives 0.1.0", + "substrate-service 0.3.0", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-finality-grandpa-primitives" +version = "0.1.0" +dependencies = [ + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "substrate-client 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "substrate-keyring" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "substrate-keystore" +version = "0.1.0" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-crypto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-primitives 0.1.0", + "subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-network" +version = "0.1.0" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "substrate-client 0.1.0", + "substrate-consensus-common 0.1.0", + "substrate-keyring 0.1.0", + "substrate-network-libp2p 0.1.0", + "substrate-primitives 0.1.0", + "substrate-test-client 0.1.0", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-network-libp2p" +version = "0.1.0" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-primitives" +version = "0.1.0" +dependencies = [ + "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", + "hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)", + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-std 0.1.0", + "twox-hash 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wasmi 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-rpc" +version = "0.1.0" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "jsonrpc-macros 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "sr-version 0.1.0", + "substrate-client 0.1.0", + "substrate-executor 0.1.0", + "substrate-primitives 0.1.0", + "substrate-transaction-pool 0.1.0", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-rpc-servers" +version = "0.1.0" +dependencies = [ + "jsonrpc-http-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "jsonrpc-ws-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "substrate-rpc 0.1.0", +] + +[[package]] +name = "substrate-serializer" +version = "0.1.0" +dependencies = [ + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-service" +version = "0.3.0" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "substrate-client 0.1.0", + "substrate-client-db 0.1.0", + "substrate-consensus-common 0.1.0", + "substrate-executor 0.1.0", + "substrate-keystore 0.1.0", + "substrate-network 0.1.0", + "substrate-primitives 0.1.0", + "substrate-rpc 0.1.0", + "substrate-rpc-servers 0.1.0", + "substrate-telemetry 0.3.0", + "substrate-transaction-pool 0.1.0", + "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-state-db" +version = "0.1.0" +dependencies = [ + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "substrate-state-machine" +version = "0.1.0" +dependencies = [ + "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", + "heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-primitives 0.1.0", + "substrate-trie 0.4.0", + "trie-db 0.9.0 (git+https://github.com/paritytech/trie)", + "trie-root 0.9.0 (git+https://github.com/paritytech/trie)", +] + +[[package]] +name = "substrate-telemetry" +version = "0.3.0" +dependencies = [ + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-json 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-scope 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-test-client" +version = "0.1.0" +dependencies = [ + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "substrate-client 0.1.0", + "substrate-consensus-common 0.1.0", + "substrate-executor 0.1.0", + "substrate-keyring 0.1.0", + "substrate-primitives 0.1.0", + "substrate-state-machine 0.1.0", + "substrate-test-runtime 0.1.0", +] + +[[package]] +name = "substrate-test-runtime" +version = "0.1.0" +dependencies = [ + "hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 0.1.0", + "sr-primitives 0.1.0", + "sr-std 0.1.0", + "sr-version 0.1.0", + "srml-support 0.1.0", + "substrate-client 0.1.0", + "substrate-keyring 0.1.0", + "substrate-primitives 0.1.0", +] + +[[package]] +name = "substrate-transaction-graph" +version = "0.1.0" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", +] + +[[package]] +name = "substrate-transaction-pool" +version = "0.1.0" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-primitives 0.1.0", + "substrate-client 0.1.0", + "substrate-primitives 0.1.0", + "substrate-transaction-graph 0.1.0", +] + +[[package]] +name = "substrate-trie" +version = "0.4.0" +dependencies = [ + "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", + "memory-db 0.9.0 (git+https://github.com/paritytech/trie)", + "parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "trie-db 0.9.0 (git+https://github.com/paritytech/trie)", + "trie-root 0.9.0 (git+https://github.com/paritytech/trie)", +] + +[[package]] +name = "subtle" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "syn" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.15.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "sysinfo" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "target_info" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "tempfile" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termcolor" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread-id" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "time" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tiny-keccak" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tk-listen" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-fs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-codec" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-core" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-current-thread" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-dns-unofficial" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-executor" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-fs" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-io" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-reactor" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-tcp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-threadpool" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-timer" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-tls" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-udp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-uds" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "traitobject" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "trie-db" +version = "0.9.0" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" +dependencies = [ + "elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "trie-root" +version = "0.9.0" +source = "git+https://github.com/paritytech/trie#2616db2a2529098949e5d39aa06dd4e502a9e5f7" +dependencies = [ + "hash-db 0.9.0 (git+https://github.com/paritytech/trie)", +] + +[[package]] +name = "try-lock" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "twofish" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "twox-hash" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "typeable" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "typenum" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ucd-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "uint" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicase" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicase" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-segmentation" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unsigned-varint" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unsigned-varint" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "untrusted" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "url" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8-ranges" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vcpkg" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "want" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasmi" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "websocket" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tls 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "which" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "wincolor" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ws" +version = "0.7.5" +source = "git+https://github.com/tomusdrw/ws-rs#f12d19c4c19422fc79af28a3181f598bc07ecd1e" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ws" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "xdg" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "yaml-rust" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "yamux" +version = "0.1.0" +source = "git+https://github.com/paritytech/yamux#966f2730f7a32150f282eef29fd2aecb14d7b9fa" +dependencies = [ + "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "nohash-hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[metadata] +"checksum aes-ctr 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f65958ff3692041c36fc009261ccd63f24cd8e0dc1164266f068c2387e8b4e4f" +"checksum aes-soft 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67cc03b0a090a05cb01e96998a01905d7ceedce1bc23b756c0bb7faa0682ccb1" +"checksum aesni 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6810b7fb9f2bb4f76f05ac1c170b8dde285b6308955dc3afd89710268c958d9e" +"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" +"checksum aio-limited 0.1.0 (git+https://github.com/paritytech/aio-limited.git)" = "" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" +"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" +"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" +"checksum asn1_der 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "766afdc5c6d7c15de1abe4c9c15e360be3aa972c363ba5b606be3c4271235886" +"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" +"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" +"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" +"checksum base-x 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5cda5d0f5584d129112ad8bf4775b9fd2b9f1e30738c7b1a25314ba2244d6a51" +"checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" +"checksum base64 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5032d51da2741729bfdaeb2664d9b8c6d9fd1e2b90715c660b6def36628499c2" +"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" +"checksum bigint 4.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ebecac13b3c745150d7b6c3ea7572d372f09d627c2077e893bf26c5c7f70d282" +"checksum bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1b25ab82877ea8fe6ce1ce1f8ac54361f0218bad900af9eb11803994bf67c221" +"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum blake2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73b77e29dbd0115e43938be2d5128ecf81c0353e00acaa65339a1242586951d9" +"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" +"checksum block-cipher-trait 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "370424437b9459f3dfd68428ed9376ddfe03d8b70ede29cc533b3557df186ab4" +"checksum bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0de79cfb98e7aa9988188784d8664b4b5dad6eaaa0863b91d9a4ed871d4f7a42" +"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" +"checksum byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96c8b41881888cc08af32d47ac4edd52bc7fa27fef774be47a92443756451304" +"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" +"checksum bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0ce55bd354b095246fc34caf4e9e242f5297a7fd938b090cadfea6eee614aa62" +"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" +"checksum cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42aac45e9567d97474a834efdee3081b3c942b2205be932092f53354ce503d6c" +"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" +"checksum chashmap 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47e651a8c1eb0cbbaa730f705e2531e75276c6f2bbe2eb12662cfd305213dff8" +"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" +"checksum clang-sys 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7f7c04e52c35222fffcc3a115b5daf5f7e2bfb71c13c4e2321afe1fc71859c2" +"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" +"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" +"checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980" +"checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa" +"checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" +"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" +"checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1" +"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" +"checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9" +"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" +"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" +"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" +"checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2" +"checksum crypto-mac 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0999b4ff4d3446d4ddb19a63e9e00c1876e75cd7000d20e57a693b4b3f08d958" +"checksum crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7afa06d05a046c7a47c3a849907ec303504608c927f4e85f7bfff22b7180d971" +"checksum ctr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4b669fcb8e20124db86dbd9b01e74ec0e9e420e65381311ce5249864fc7ff0c0" +"checksum curve25519-dalek 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3eacf6ff1b911e3170a8c400b402e10c86dc3cb166bd69034ebbc2b785fea4c2" +"checksum data-encoding 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "67df0571a74bf0d97fb8b2ed22abdd9a48475c96bd327db968b7d9cace99655e" +"checksum datastore 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" +"checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" +"checksum ed25519-dalek 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cd66d8a16ef71c23cf5eeb2140d8d3cd293457c6c7fd6804b593397a933fcf1e" +"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" +"checksum elastic-array 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88d4851b005ef16de812ea9acdb7bece2f0a40dd86c07b85631d7dafa54537bb" +"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" +"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" +"checksum environmental 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db746025e3ea695bfa0ae744dbacd5fcfc8db51b9760cf8bd0ab69708bb93c49" +"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" +"checksum eth-secp256k1 0.5.7 (git+https://github.com/paritytech/rust-secp256k1)" = "" +"checksum etrace 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f17311e68ea07046ee809b8513f6c259518bc10173681d98c21f8c3926f56f40" +"checksum exit-future 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9aa7b56cef68c4182db7212dece19cc9f6e2916cf9412e57e6cea53ec02f316d" +"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7" +"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +"checksum fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1ee15a7050e5580b3712877157068ea713b245b080ff302ae2ca973cfcd9baa" +"checksum finality-grandpa 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a1dffe3c9d4c59d964f25cea31880e56c20414cdae7efe2269411238f850ad39" +"checksum fixed-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a557e80084b05c32b455963ff565a9de6f2866da023d6671705c6aff6f65e01c" +"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +"checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" +"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" +"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" +"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" +"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865" +"checksum h2 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd33bafe2e6370e6c8eb0cf1b8c5f93390b90acde7e9b03723f166b28b648ed" +"checksum hash-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" +"checksum hash256-std-hasher 0.9.0 (git+https://github.com/paritytech/trie)" = "" +"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" +"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" +"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" +"checksum hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4da5f0e01bd8a71a224a4eedecaacfcabda388dbb7a80faf04d3514287572d95" +"checksum hex-literal-impl 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1d340b6514f232f6db1bd16db65302a5278a04fef9ce867cb932e7e5fa21130a" +"checksum hmac 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "733e1b3ac906631ca01ebb577e9bb0f5e37a454032b9036b5eaea4013ed6f99a" +"checksum http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "24f58e8c2d8e886055c3ead7b28793e1455270b5fb39650984c224bc538ba581" +"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" +"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" +"checksum hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "df0caae6b71d266b91b4a83111a61d2b94ed2e2bea024c532b933dcff867e58c" +"checksum hyper 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)" = "95ffee0d1d30de4313fdaaa485891ce924991d45bbc18adfc8ac5b1639e62fbb" +"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" +"checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" +"checksum interleaved-ordered 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" +"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" +"checksum jsonrpc-core 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" +"checksum jsonrpc-http-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" +"checksum jsonrpc-macros 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" +"checksum jsonrpc-pubsub 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" +"checksum jsonrpc-server-utils 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" +"checksum jsonrpc-ws-server 9.0.0 (git+https://github.com/paritytech/jsonrpc.git)" = "" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum kvdb 0.1.0 (git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6)" = "" +"checksum kvdb-rocksdb 0.1.4 (git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6)" = "" +"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" +"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" +"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" +"checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0" +"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" +"checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" +"checksum libp2p 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-core 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-dns 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-floodsub 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-identify 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-kad 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-mplex 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-peerstore 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-ping 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-ratelimit 0.1.1 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-relay 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-secio 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-tcp-transport 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-transport-timeout 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-uds 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-websocket 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum libp2p-yamux 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum librocksdb-sys 5.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "474d805d72e23a06310fa5201dfe182dc4b80ab1f18bb2823c1ac17ff9dcbaa2" +"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" +"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a" +"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum make-cmd 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8ca8afbe8af1785e09636acb5a41e08a765f5f0340568716c18a8700ba3c0d3" +"checksum mashup 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f2d82b34c7fb11bb41719465c060589e291d505ca4735ea30016a91f6fc79c3b" +"checksum mashup-impl 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "aa607bfb674b4efb310512527d64266b065de3f894fc52f84efcbf7eaa5965fb" +"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" +"checksum memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a3eb002f0535929f1199681417029ebea04aadc0c7a4224b46be99c7f5d6a16" +"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" +"checksum memory-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" +"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" +"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" +"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" +"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" +"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" +"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum multiaddr 0.3.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum multihash 0.8.1-pre (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum multistream-select 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da" +"checksum native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff8e08de0070bbf4c31f452ea2a70db092f36f6f2e4d897adf5674477d488fb2" +"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" +"checksum nohash-hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "27593c72432b8cec9ae79e92792a73c38341064d525b6b612a9fccf8b7d17407" +"checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b" +"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" +"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" +"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" +"checksum ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" +"checksum opaque-debug 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d620c9c26834b34f039489ac0dfdb12c7ac15ccaf818350a64c9b5334a452ad7" +"checksum openssl 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "5e1309181cdcbdb51bc3b6bedb33dfac2a83b3d585033d3f6d9e22e8c1928613" +"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" +"checksum openssl-sys 0.9.39 (registry+https://github.com/rust-lang/crates.io-index)" = "278c1ad40a89aa1e741a1eed089a2f60b18fab8089c3139b542140fc7d674106" +"checksum owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d52571ddcb42e9c900c901a18d8d67e393df723fcd51dd59c5b1a85d0acb6cc" +"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +"checksum parity-bytes 0.1.0 (git+https://github.com/paritytech/parity-common?rev=616b40150ded71f57f650067fcbc5c99d7c343e6)" = "" +"checksum parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dca389ea5e1632c89b2ce54f7e2b4a8a8c9d278042222a91e0bf95451218cb4c" +"checksum parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffa42c2cb493b60b12c75b26e8c94cb734af4df4d7f2cc229dc04c1953dac189" +"checksum parity-crypto 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c1117f6574377d21309bfa1f7d69ff734120685d92b02c3f362b122585758840" +"checksum parity-wasm 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "511379a8194230c2395d2f5fa627a5a7e108a9f976656ce723ae68fca4097bfc" +"checksum parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fa12d706797d42551663426a45e2db2e0364bd1dbf6aeada87e89c5f981f43e9" +"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e" +"checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac" +"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" +"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" +"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" +"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" +"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8" +"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a" +"checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4" +"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" +"checksum protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "671a9cce836bd3635b40b2b0a72783481755ee988c493891f4e974b45264cc9d" +"checksum pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd695333cfae6e9dbe2703a6d040e252b57a6fc3b9a65c712615ac042b2e0c5" +"checksum quick-error 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb6ccf8db7bbcb9c2eae558db5ab4f3da1c2a87e4e597ed394726bc8ea6ca1d" +"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" +"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" +"checksum quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "63b5829244f52738cfee93b3a165c1911388675be000c888d2fae620dee8fa5b" +"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" +"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" +"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" +"checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a" +"checksum rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771b009e3a508cb67e8823dda454aaa5368c7bc1c16829fb77d3e980440dd34a" +"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" +"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" +"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +"checksum rand_pcg 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "086bd09a33c7044e56bb44d5bdde5a60e7f119a9e95b0775f545de759a32fe05" +"checksum rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effa3fcaa47e18db002bdde6060944b6d2f9cfd8db471c30e873448ad9187be3" +"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" +"checksum rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df7a791f788cb4c516f0e091301a29c2b71ef680db5e644a7d68835c8ae6dbfa" +"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" +"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" +"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341" +"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" +"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" +"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" +"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" +"checksum rocksdb 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39be726e556e6f21d54d21cdf1be9f6df30c0411a5856c1abf3f4bb12498f2ed" +"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" +"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" +"checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" +"checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" +"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum rw-stream-sink 0.1.0 (git+https://github.com/libp2p/rust-libp2p?rev=d961e656a74d1bab5366d371a06f9e10d5f4a6c5)" = "" +"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" +"checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" +"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" +"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" +"checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" +"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" +"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum security-framework 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "697d3f3c23a618272ead9e1fb259c1411102b31c6af8b93f1d64cca9c3b0e8e0" +"checksum security-framework-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab01dfbe5756785b5b4d46e0289e5a18071dfa9a7c2b24213ea00b9ef9b665bf" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef" +"checksum serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "225de307c6302bec3898c51ca302fc94a7a1697ef0845fcee6448f33c032249c" +"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce" +"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" +"checksum sha1 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "171698ce4ec7cbb93babeb3190021b4d72e96ccb98e33d277ae4ea959d6f2d9e" +"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +"checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" +"checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" +"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" +"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" +"checksum slog 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e1a2eec401952cd7b12a84ea120e2d57281329940c3f93c2bf04f462539508e" +"checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f" +"checksum slog-json 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddd14b8df2df39378b3e933c79784350bf715b11444d99f903df0253bbe524e5" +"checksum slog-scope 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "053344c94c0e2b22da6305efddb698d7c485809427cf40555dc936085f67a9df" +"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" +"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" +"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" +"checksum stdweb 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef5430c8e36b713e13b48a9f709cc21e046723fe44ce34587b73a830203b533e" +"checksum stdweb 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "22203527a18dc1c5c83bbd247fb005f5877d040783b6626571d6b7ed7a6f5e75" +"checksum stdweb-derive 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e21ebd9179de08f2300a65454268a17ea3de204627458588c84319c4def3930" +"checksum stdweb-internal-macros 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bcbc9155af9606d44c740197d7d6672b49c4ee93a176c7cecde8b49322677604" +"checksum stdweb-internal-runtime 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b74fe9de4c0d07e91987f4d798b95f27f3cb7769fbc222fa951fa386908297b5" +"checksum stream-cipher 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "30dc6118470d69ce0fdcf7e6f95e95853f7f4f72f80d835d4519577c323814ab" +"checksum string 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00caf261d6f90f588f8450b8e1230fa0d5be49ee6140fdfbcb55335aff350970" +"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" +"checksum structopt 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "41c4a2479a078509940d82773d90ff824a8c89533ab3b59cd3ce8b0c0e369c02" +"checksum structopt-derive 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5352090cfae7a2c85e1a31146268b53396106c88ca5d6ccee2e3fae83b6e35c2" +"checksum subtle 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc7f6353c2ee5407358d063a14cccc1630804527090a6fb5a9489ce4924280fb" +"checksum subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" +"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" +"checksum syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)" = "ae8b29eb5210bc5cf63ed6149cbf9adfc82ac0be023d8735c176ee74a2db4da7" +"checksum sysinfo 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "11c5f6e8a7a7146f26ffed9a5ff8bab2706f1ac8a413a415e1d211b819d5c24d" +"checksum take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" +"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" +"checksum tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "55c1195ef8513f3273d55ff59fe5da6940287a0d7a98331254397f464833675b" +"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" +"checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" +"checksum tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e9175261fbdb60781fcd388a4d6cc7e14764a2b629a7ad94abb439aed223a44f" +"checksum tk-listen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dec7ba6a80b7695fc2abb21af18bed445a362ffd80b64704771ce142d6d2151d" +"checksum tokio 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6e93c78d23cc61aa245a8acd2c4a79c4d7fa7fb5c3ca90d5737029f043a84895" +"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" +"checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" +"checksum tokio-current-thread 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f90fcd90952f0a496d438a976afba8e5c205fb12123f813d8ab3aa1c8436638c" +"checksum tokio-dns-unofficial 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bb9bf62ca2c53bf2f2faec3e48a98b6d8c9577c27011cb0203a4beacdc8ab328" +"checksum tokio-executor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c117b6cf86bb730aab4834f10df96e4dd586eff2c3c27d3781348da49e255bde" +"checksum tokio-fs 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "60ae25f6b17d25116d2cba342083abe5255d3c2c79cb21ea11aa049c53bf7c75" +"checksum tokio-io 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7392fe0a70d5ce0c882c4778116c519bd5dbaa8a7c3ae3d04578b3afafdcda21" +"checksum tokio-reactor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4b26fd37f1125738b2170c80b551f69ff6fecb277e6e5ca885e53eec2b005018" +"checksum tokio-tcp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ad235e9dadd126b2d47f6736f65aa1fdcd6420e66ca63f44177bc78df89f912" +"checksum tokio-threadpool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3929aee321c9220ed838ed6c3928be7f9b69986b0e3c22c972a66dbf8a298c68" +"checksum tokio-timer 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3a52f00c97fedb6d535d27f65cccb7181c8dd4c6edc3eda9ea93f6d45d05168e" +"checksum tokio-tls 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e53fdbf3156f588be1676022fe794232b24922d426e8c14f4e46891c1e31c440" +"checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c" +"checksum tokio-uds 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df195376b43508f01570bacc73e13a1de0854dc59e79d1ec09913e8db6dd2a70" +"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" +"checksum trie-db 0.9.0 (git+https://github.com/paritytech/trie)" = "" +"checksum trie-root 0.9.0 (git+https://github.com/paritytech/trie)" = "" +"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" +"checksum twofish 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1eef327f05b0d0ec1b9d7d119d8f4d9f602ceee37e0540aff8071e8e66c2e22e" +"checksum twox-hash 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f85be565a110ed72ed7048cf56570db04ce0a592c98aa59b7dacde3e5718750" +"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" +"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" +"checksum ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0f8bfa9ff0cadcd210129ad9d2c5f145c13e9ced3d3e5d948a6213487d52444" +"checksum uint 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "082df6964410f6aa929a61ddfafc997e4f32c62c22490e439ac351cec827f436" +"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" +"checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90" +"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" +"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" +"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum unsigned-varint 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5c1441164e5da61f00acd15f5a9e61939693c2c6e8b9fae36a220b82de7e212" +"checksum unsigned-varint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8abc4b7d8158bdfbbaaccc35331ed3c30c2673e99000d7ae665a2eb6576f4" +"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" +"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" +"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" +"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" +"checksum wasmi 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8a60b9508cff2b7c27ed41200dd668806280740fadc8c88440e9c88625e84f1a" +"checksum websocket 0.21.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c9faed2bff8af2ea6b9f8b917d3d00b467583f6781fe3def174a9e33c879703" +"checksum which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e84a603e7e0b1ce1aa1ee2b109c7be00155ce52df5081590d1ffb93f4f515cb2" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" +"checksum ws 0.7.5 (git+https://github.com/tomusdrw/ws-rs)" = "" +"checksum ws 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "329d3e6dd450a9c5c73024e1047f0be7e24121a68484eb0b5368977bee3cf8c3" +"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +"checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61" +"checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" +"checksum yamux 0.1.0 (git+https://github.com/paritytech/yamux)" = "" diff --git a/test-utils/chain-spec-builder/Cargo.toml b/test-utils/chain-spec-builder/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7bd99e53aacadad60efe93419fdbdba1f9dcc51d --- /dev/null +++ b/test-utils/chain-spec-builder/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "chain-spec-builder" +version = "0.1.0" +authors = ["haydn dufrene "] + +[dependencies] +clap = { version = "~2.32", features = ["yaml"] } +node-cli = { path = "../../node/cli" } +substrate-primitives = { path = "../../core/primitives" } +substrate-service = { path = "../../core/service" } diff --git a/test-utils/chain-spec-builder/src/cli.yml b/test-utils/chain-spec-builder/src/cli.yml new file mode 100644 index 0000000000000000000000000000000000000000..08c0233c31090ae4d6a5091651324b25a8c14fcb --- /dev/null +++ b/test-utils/chain-spec-builder/src/cli.yml @@ -0,0 +1,24 @@ +name: chain-spec-builder +author: "azban " +about: Utility for creating chain specs primarily for testing +args: +- initial_authority_seed: + short: a + value_name: INITIAL_AUTHORITY_SEED + help: Initial authority seed + takes_value: true + multiple: true + required: true +- endowed_account_seed: + short: e + value_name: ENDOWED_ACCOUNT_SEED + help: Endowed account seed + takes_value: true + multiple: true + required: true +- upgrade_key_seed: + short: u + value_name: UPGRADE_KEY_SEED + help: Upgrade key seed + takes_value: true + required: true diff --git a/test-utils/chain-spec-builder/src/main.rs b/test-utils/chain-spec-builder/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..f0e9ef066ffc5c3ae78869e7b58142d22c676e53 --- /dev/null +++ b/test-utils/chain-spec-builder/src/main.rs @@ -0,0 +1,51 @@ +#[macro_use] +extern crate clap; + +use clap::App; + +extern crate node_cli; +extern crate substrate_service; +extern crate substrate_primitives; + +use node_cli::chain_spec; +use substrate_service::chain_ops::build_spec; + +fn genesis_constructor() -> chain_spec::GenesisConfig { + let yaml = load_yaml!("./cli.yml"); + let matches = App::from_yaml(yaml).get_matches(); + let authorities = matches.values_of("initial_authority_seed") + .unwrap() + .map(chain_spec::get_authority_id_from_seed) + .collect(); + + let endowed_accounts = matches.values_of("endowed_account_seed") + .unwrap() + .map(chain_spec::get_authority_id_from_seed) + .collect(); + + let upgrade_key_seed = matches.value_of("upgrade_key_seed").unwrap(); + let upgrade_key = chain_spec::get_authority_id_from_seed(upgrade_key_seed); + chain_spec::testnet_genesis( + authorities, + upgrade_key.into(), + Some(endowed_accounts), + ) +} + +fn generate_chain_spec() -> String { + let chain_spec = chain_spec::ChainSpec::from_genesis( + "Custom", + "custom", + genesis_constructor, + vec![], + None, + None, + None, + ); + build_spec(chain_spec, false).unwrap() +} + +fn main() { + let json = generate_chain_spec(); + println!("{}", json); +}