diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..53f7426 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +**/target/ \ No newline at end of file diff --git a/.github/workflows/risc0-image.yaml b/.github/workflows/risc0-image.yaml index b5fc8cb..7a2c284 100644 --- a/.github/workflows/risc0-image.yaml +++ b/.github/workflows/risc0-image.yaml @@ -45,12 +45,6 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 - - name: Setup Docker and Colima - if: startsWith(matrix.os, 'macos-latest') == true - run: | - brew install docker colima - colima start - - name: Setup Docker buildx uses: docker/setup-buildx-action@v2 @@ -70,7 +64,7 @@ jobs: - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v6 with: platforms: linux/amd64,linux/arm64 context: . diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 8581fc6..0000000 --- a/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -#################################################################################################### -## Builder -#################################################################################################### -FROM rust:1.70.0 AS builder - -RUN rustup target add x86_64-unknown-linux-musl -RUN apt update && apt install -y musl-tools musl-dev -RUN apt install --no-install-recommends --assume-yes protobuf-compiler -RUN update-ca-certificates - -WORKDIR /halo2-server - -COPY ./ . - -RUN cargo build --release - -#################################################################################################### -## Final image -#################################################################################################### -FROM ubuntu:20.04 - -WORKDIR /halo2-server - -# Copy our build -COPY --from=builder /halo2-server/target/release/halo2-server ./ - -CMD ["/halo2-server/halo2-server"] \ No newline at end of file diff --git a/proto/vm_runtime.proto b/proto/vm_runtime.proto index eddac87..1602291 100644 --- a/proto/vm_runtime.proto +++ b/proto/vm_runtime.proto @@ -1,28 +1,27 @@ syntax = "proto3"; -package vm_runtime; +package vm; -service VmRuntime { - rpc Create(CreateRequest) returns (CreateResponse); - rpc Execute(ExecuteRequest) returns (ExecuteResponse); +service VM { + rpc NewProject(NewProjectRequest) returns (NewProjectResponse); + rpc ExecuteTask(ExecuteTaskRequest) returns (ExecuteTaskResponse); } -message CreateRequest { +message NewProjectRequest { uint64 projectID = 1; - string content = 2; - string expParam = 3; + string projectVersion = 2; + bytes binary = 3; + bytes metadata = 4; } -message CreateResponse { -} - -message ExecuteRequest { +message NewProjectResponse {} + +message ExecuteTaskRequest { uint64 projectID = 1; - uint64 taskID = 2; - string clientID = 3; - string sequencerSignature = 4; - repeated string datas = 5; + string projectVersion = 2; + bytes taskID = 3; + repeated bytes payloads = 4; } -message ExecuteResponse { +message ExecuteTaskResponse { bytes result = 1; } \ No newline at end of file diff --git a/risc0-server/.env b/risc0-server/.env index 66cc732..15da763 100644 --- a/risc0-server/.env +++ b/risc0-server/.env @@ -1,4 +1,3 @@ -DATABASE_URL=postgres://test_user:test_passwd@127.0.0.1:5432/test?sslmode=disable CHAIN_ENDPOINT = "https://babel-api.mainnet.iotex.io" VERIFY_CONTRACT = "0x79F3872E3e69B696d7ebFAF12691130EfA12291e" BONSAI_URL = "https://api.bonsai.xyz" diff --git a/risc0-server/BaseDockerfile b/risc0-server/BaseDockerfile deleted file mode 100644 index f765632..0000000 --- a/risc0-server/BaseDockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM rust:1.79.0 - -RUN apt update && apt -y install libpq-dev libpq5 - -RUN cargo install cargo-binstall -RUN echo yes | cargo binstall cargo-risczero -RUN cargo risczero install \ No newline at end of file diff --git a/risc0-server/Cargo.toml b/risc0-server/Cargo.toml index 5bf4891..75476c2 100644 --- a/risc0-server/Cargo.toml +++ b/risc0-server/Cargo.toml @@ -6,48 +6,34 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -risc0-zkvm ={ version = "1.0" } +risc0-zkvm = { version = "1.0" } # bonsai-ethereum-relay = { version = "0.6.1" } # risc0-ethereum-relay = { git = "https://github.com/risc0/risc0-ethereum.git", rev = "v0.10.0", package = "risc0-ethereum-relay" } risc0-ethereum-contracts = { git = "https://github.com/risc0/risc0-ethereum", tag = "v1.0.0" } -# bonsai-sdk = { version = "0.9.0" } - rust-grpc = { path = "../rust-grpc" } - -axum = { version = "0.6.20", features = ["multipart","headers", "ws"] } tokio = { version = "1.0", features = ["full"] } -tower-http = { version = "0.2.0", features = ["fs", "trace"] } -futures = "0.3" -tokio-stream = "0.1" -headers = "0.3" tracing = "0.1" -tracing-subscriber = { version="0.3", features = ["env-filter", "tracing-log", "fmt"] } -axum_typed_multipart = "0.8.0" -tempfile = "3.7.1" - +tracing-subscriber = { version = "0.3", features = [ + "env-filter", + "tracing-log", + "fmt", +] } serde = "1.0" serde_json = "1.0" serde_derive = "1.0" -diesel = { version = "2.1.0", features = ["postgres", "r2d2"] } dotenvy = "0.15" -hex = { version = "0.4.3", default-features = false, features = ["alloc"] } -bincode = "1.3" anyhow = { version = "1.0", default-features = false } -bytemuck = { version = "1.13", features = ["extern_crate_alloc"] } ethers = { version = "2.0", features = ["rustls", "ws"] } web3 = "0.19.0" flate2 = "1.0.20" -rustc-hex = "2.1.0" -tonic = "0.8" -tonic-reflection = "0.6.0" -prost = "0.11" -diesel_migrations = "2.2.0" +tonic = "0.12.3" +lazy_static = "=1.4.0" +regex = "1.11.0" +dyn-clone = "1.0.17" [dev-dependencies] lazy_static = "=1.4.0" -[build-dependencies] -tonic-build = "0.8" [features] cuda = ["risc0-zkvm/cuda"] diff --git a/risc0-server/Dockerfile b/risc0-server/Dockerfile index 5ab7c1a..7177e23 100644 --- a/risc0-server/Dockerfile +++ b/risc0-server/Dockerfile @@ -1,35 +1,38 @@ +# Use the official Rust image as the base image FROM rust:1.79.0 AS builder -RUN update-ca-certificates - -RUN apt update -RUN apt install -y curl libpq-dev libssl-dev libpq-dev librust-openssl-dev librust-openssl-sys-dev -RUN apt -y install libpq5 -RUN apt update && apt install -y libprotobuf-dev protobuf-compiler - -RUN cargo install diesel_cli --no-default-features --features postgres --version 2.1.0 +# Set the working directory inside the container +WORKDIR /usr/src/app RUN curl -L https://foundry.paradigm.xyz | bash RUN /root/.foundry/bin/foundryup RUN cp /root/.foundry/bin/* /usr/bin/ +RUN apt update && apt install -y libprotobuf-dev protobuf-compiler -WORKDIR /rust/src -COPY ./ ./ +# Copy the Cargo.toml and Cargo.lock files +# COPY Cargo.toml Cargo.lock ./ -RUN export CARGO_NET_GIT_FETCH_WITH_CLI=true -RUN export RUST_BACKTRACE=1 +# Copy the source code +COPY ./risc0-server ./risc0-server +COPY ./rust-grpc ./rust-grpc +COPY ./proto ./proto +# Build the project RUN cd risc0-server && cargo build --release +# Use a minimal base image for the final stage +FROM debian:bullseye-slim + -FROM wangweixiaohao2944/risc0serverbase:v1.0.0 +# Install ca-certificates without cache +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && apt-get clean && rm -rf /var/lib/apt/lists/* -WORKDIR /risc0server/ +# Copy the compiled binary from the builder stage +COPY --from=builder /usr/src/app/risc0-server/target/release/risc0-server /usr/local/bin/risc0-server -COPY --from=builder /rust/src/risc0-server/target/release/risc0-server ./ -COPY ./risc0-server/Cargo.toml /risc0server/ -COPY ./risc0-server/diesel.toml /risc0server/ -COPY ./risc0-server/verify_contract_abi.json /risc0server/ +# Expose the port that the server will run on +EXPOSE 4001 -CMD ["/risc0server/risc0-server"] \ No newline at end of file +# Set the entrypoint to the compiled binary +CMD ["risc0-server"] diff --git a/risc0-server/Makefile b/risc0-server/Makefile index 6a2aba4..2caf105 100644 --- a/risc0-server/Makefile +++ b/risc0-server/Makefile @@ -1,25 +1,7 @@ -integration_test_depends_stop: - @docker stop postgres_test || true && docker container rm postgres_test || true - -.PHONY: integration_test_depends -integration_test_depends: integration_test_depends_stop postgres_test risc0_depends - -.PHONY: postgres_test -postgres_test: - docker run --name postgres_test \ - -e POSTGRES_USER=test_user \ - -e POSTGRES_PASSWORD=test_passwd \ - -e POSTGRES_DB=test \ - -p 15432:5432 \ - -d postgres:14 - .PHONY: risc0_depends risc0_depends: cargo install cargo-binstall echo yes | cargo binstall cargo-risczero cargo risczero install - -integration_test: integration_test_depends - @cd risc0-server/ && cargo test diff --git a/risc0-server/README.md b/risc0-server/README.md index 892a04f..16091c0 100644 --- a/risc0-server/README.md +++ b/risc0-server/README.md @@ -1,11 +1,7 @@ # risc0-server ## setup -### install diesel - -``` shell -cargo install diesel_cli --no-default-features --features postgres -``` + ### build release @@ -16,22 +12,9 @@ cargo build --release ### configure database modify `.env` file -``` shell -DATABASE_URL=postgres://test_user:test_passwd@127.0.0.1:5432/test?sslmode=disable -``` - -### migrate database - -``` shell -diesel setup - -diesel migration generate risc0-server - -diesel migration run -``` - + ### run risc0 rpc sever ``` shell -./target/release/risc0server +./target/release/risc0-server ``` \ No newline at end of file diff --git a/risc0-server/diesel.toml b/risc0-server/diesel.toml deleted file mode 100644 index fa8cc69..0000000 --- a/risc0-server/diesel.toml +++ /dev/null @@ -1,9 +0,0 @@ -# For documentation on how to configure this file, -# see https://diesel.rs/guides/configuring-diesel-cli - -[print_schema] -file = "src/db/schema.rs" -custom_type_derives = ["diesel::query_builder::QueryId"] - -[migrations_directory] -dir = "migrations" diff --git a/risc0-server/migrations/.keep b/risc0-server/migrations/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/risc0-server/migrations/2024-03-28-110112_risc0-server/down.sql b/risc0-server/migrations/2024-03-28-110112_risc0-server/down.sql deleted file mode 100644 index f70c928..0000000 --- a/risc0-server/migrations/2024-03-28-110112_risc0-server/down.sql +++ /dev/null @@ -1,3 +0,0 @@ --- This file should undo anything in `up.sql` -DROP TABLE vms; -DROP TABLE proofs; \ No newline at end of file diff --git a/risc0-server/migrations/2024-03-28-110112_risc0-server/up.sql b/risc0-server/migrations/2024-03-28-110112_risc0-server/up.sql deleted file mode 100644 index e08fc3e..0000000 --- a/risc0-server/migrations/2024-03-28-110112_risc0-server/up.sql +++ /dev/null @@ -1,21 +0,0 @@ --- Your SQL goes here -CREATE TABLE IF NOT EXISTS vms ( - id SERIAL PRIMARY KEY, - project_name VARCHAR NOT NULL, - elf TEXT NOT NULL, - image_id VARCHAR NOT NULL -); - -CREATE TABLE proofs ( - id SERIAL PRIMARY KEY, - project_id VARCHAR NOT NULL, - task_id VARCHAR NOT NULL, - client_id VARCHAR NOT NULL, - sequencer_sign VARCHAR NOT NULL, - image_id VARCHAR NOT NULL, - datas_input VARCHAR NOT NULL, - receipt_type VARCHAR NOT NULL, - receipt TEXT, - status VARCHAR NOT NULL, - create_at TIMESTAMP NOT NULL DEFAULT now() -); \ No newline at end of file diff --git a/risc0-server/src/core/mod.rs b/risc0-server/src/core/mod.rs index 206b703..b8fcb1c 100644 --- a/risc0-server/src/core/mod.rs +++ b/risc0-server/src/core/mod.rs @@ -1 +1 @@ -pub mod prove; \ No newline at end of file +pub mod prover; diff --git a/risc0-server/src/core/prove.rs b/risc0-server/src/core/prove.rs deleted file mode 100644 index 77452c5..0000000 --- a/risc0-server/src/core/prove.rs +++ /dev/null @@ -1,52 +0,0 @@ -use risc0_zkvm::{ - default_prover, ExecutorEnv, ProverOpts, Receipt, VerifierContext -}; - -use anyhow::Result; - -pub fn generate_proof_with_elf( - project_id: u64, - task_id: u64, - client_id: String, - sequencer_sign: String, - input_datas: Vec, - elf: &[u8], -) -> Result { - let env = ExecutorEnv::builder() - .write(&project_id).unwrap() - .write(&task_id).unwrap() - .write(&client_id).unwrap() - .write(&sequencer_sign).unwrap() - .write(&input_datas).unwrap() - .build() - .unwrap(); - - // Obtain the default prover. - let prover = default_prover(); - Ok(prover.prove(env, elf).unwrap().receipt) -} - -pub fn bonsai_groth16_prove_with_env(project_id: u64, task_id: u64, client_id: String, sequencer_sign: String, input_datas: Vec, elf: &[u8], bonsai_url: String, bonsai_key: String) -> Result { - let env = ExecutorEnv::builder() - .write(&project_id).unwrap() - .write(&task_id).unwrap() - .write(&client_id).unwrap() - .write(&sequencer_sign).unwrap() - .write(&input_datas).unwrap() - .build() - .unwrap(); - - std::env::set_var("BONSAI_API_URL", bonsai_url); - std::env::set_var("BONSAI_API_KEY", bonsai_key); - - // Obtain the default prover. - let receipt = default_prover() - .prove_with_ctx( // no bonsai -> Groth16Receipt with bonsai -> Groth16 - env, - &VerifierContext::default(), - elf, - &ProverOpts::groth16(), - ).unwrap().receipt; - - Ok(receipt) -} \ No newline at end of file diff --git a/risc0-server/src/core/prover.rs b/risc0-server/src/core/prover.rs new file mode 100644 index 0000000..477f336 --- /dev/null +++ b/risc0-server/src/core/prover.rs @@ -0,0 +1,146 @@ +use std::env; +use std::rc::Rc; +use std::sync::Arc; + +use anyhow::Result; +use dotenvy::dotenv; +use dyn_clone::DynClone; +use risc0_zkvm::{ + default_prover, ExecutorEnv, Prover as risc0Prover, ProverOpts, Receipt, VerifierContext, +}; + +pub trait Prover: DynClone + Send + Sync { + fn prove(&self, data: Vec) -> Result; +} + +dyn_clone::clone_trait_object!(Prover); + +#[derive(Clone)] +pub struct LocalProver { + prover: Arc, + elf: Vec, +} + +struct ProverWrapper { + inner: Rc, +} + +impl ProverWrapper { + fn new(prover: Rc) -> Self { + ProverWrapper { inner: prover } + } +} + +unsafe impl Send for ProverWrapper {} +unsafe impl Sync for ProverWrapper {} + +impl LocalProver { + pub fn new(elf: &[u8]) -> Self { + LocalProver { + prover: Arc::new(ProverWrapper::new(default_prover())), + elf: elf.to_vec(), + } + } +} + +impl Prover for LocalProver { + fn prove(&self, data: Vec) -> Result { + let env = ExecutorEnv::builder().write(&data)?.build()?; + + Ok(self.prover.inner.prove(env, &self.elf)?.receipt) + } +} + +#[derive(Clone)] +pub struct BonsaiProver { + elf: Vec, + prover: Arc, +} + +impl BonsaiProver { + pub fn new(elf: &[u8]) -> Self { + dotenv().ok(); + + env::var("BONSAI_API_URL").expect("BONSAI_API_URL must be set"); + env::var("BONSAI_API_KEY").expect("BONSAI_API_KEY must be set"); + + BonsaiProver { + prover: Arc::new(ProverWrapper::new(default_prover())), + elf: elf.to_vec(), + } + } +} + +impl Prover for BonsaiProver { + fn prove(&self, data: Vec) -> Result { + let env = ExecutorEnv::builder().write(&data)?.build()?; + + Ok(self + .prover + .inner + .prove_with_ctx( + // no bonsai -> Groth16Receipt with bonsai -> Groth16 + env, + &VerifierContext::default(), + &self.elf, + &ProverOpts::groth16(), + )? + .receipt) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::env; + + pub const HELLO_GUEST_ID: [u32; 8] = [ + 1729087496, 1782151309, 3201877536, 1628959901, 2308880694, 3762575800, 943710734, + 1150869179, + ]; + + fn create_dummy_elf() -> Vec { + include_bytes!("../tests/hello_guest").to_vec() + } + + #[test] + fn test_local_prover_creation() { + let elf = create_dummy_elf(); + let prover = LocalProver::new(&elf); + assert_eq!(prover.elf, elf); + } + + #[test] + fn test_local_prover_prove() { + let elf = create_dummy_elf(); + let prover = LocalProver::new(&elf); + let result = prover.prove(vec!["test1".to_string(), "test2".to_string()]); + let verify_result = result.unwrap().verify(HELLO_GUEST_ID); + assert!(verify_result.is_ok(), "Error: {:?}", verify_result.err()); + } + + #[test] + fn test_bonsai_prover_creation() { + // Set dummy environment variables + env::set_var("BONSAI_API_URL", "http://dummy-url.com"); + env::set_var("BONSAI_API_KEY", "dummy-key"); + + let elf = create_dummy_elf(); + let prover = BonsaiProver::new(&elf); + assert_eq!(prover.elf, elf); + } + + #[test] + fn test_bonsai_prover_prove() { + // Set dummy environment variables + env::set_var("BONSAI_API_URL", "https://api.bonsai.xyz"); + env::set_var("BONSAI_API_KEY", ""); + + let elf = create_dummy_elf(); + let prover = BonsaiProver::new(&elf); + let result = prover.prove(vec!["test".to_string(), "test2".to_string()]); + + let ans: u32 = result.unwrap().journal.decode().unwrap(); + println!("ans: {}", ans); + } +} diff --git a/risc0-server/src/db/mod.rs b/risc0-server/src/db/mod.rs deleted file mode 100644 index 8dd10c5..0000000 --- a/risc0-server/src/db/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod models; -mod schema; -pub mod pgdb; \ No newline at end of file diff --git a/risc0-server/src/db/models.rs b/risc0-server/src/db/models.rs deleted file mode 100644 index 4924694..0000000 --- a/risc0-server/src/db/models.rs +++ /dev/null @@ -1,78 +0,0 @@ -use crate::db::schema::vms; -use crate::db::schema::proofs; -use diesel::prelude::*; - -#[derive(Queryable, Selectable)] -#[diesel(table_name = vms)] -#[diesel(check_for_backend(diesel::pg::Pg))] -pub struct Vm { - pub id: i32, - pub project_name: String, - pub elf: String, - pub image_id: String -} - -impl Vm { - pub fn new() -> Self { - Vm{ - id: 0, - project_name: "init".to_string(), - elf: "init".to_string(), - image_id: "init".to_string(), - } - } -} - -#[derive(Insertable)] -#[diesel(table_name = vms)] -pub struct NewVm<'a> { - pub project_name: &'a str, - pub elf: &'a str, - pub image_id: &'a str, -} - -#[derive(Queryable, Selectable)] -#[diesel(table_name = proofs)] -#[diesel(check_for_backend(diesel::pg::Pg))] -pub struct Proof { - pub id: i32, - pub project_id: String, - pub task_id: String, - pub client_id: String, - pub sequencer_sign: String, - pub image_id: String, - pub datas_input: String, - pub receipt_type: String, - pub receipt: Option, - pub status: String, -} - -impl Proof { - pub fn new() -> Self { - Proof{ - id: 0, - project_id: "0".to_string(), - task_id: "0".to_string(), - client_id: "init".to_string(), - sequencer_sign: "init".to_string(), - image_id: "init".to_string(), - datas_input: "init".to_string(), - receipt_type: "init".to_string(), - receipt: Some("init".to_string()), - status: "init".to_string(), - } - } -} - -#[derive(Insertable)] -#[diesel(table_name = proofs)] -pub struct NewPoof<'a> { - pub project_id: &'a str, - pub task_id: &'a str, - pub client_id: &'a str, - pub sequencer_sign: &'a str, - pub image_id: &'a str, - pub datas_input: &'a str, - pub receipt_type: &'a str, - pub status: &'a str, -} diff --git a/risc0-server/src/db/pgdb.rs b/risc0-server/src/db/pgdb.rs deleted file mode 100644 index 65fc9e2..0000000 --- a/risc0-server/src/db/pgdb.rs +++ /dev/null @@ -1,152 +0,0 @@ -use std::env; - -use diesel::{ - r2d2::{ConnectionManager, Pool}, - Connection, ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl, SelectableHelper, -}; -use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; -use dotenvy::dotenv; - -use crate::db::models::{NewPoof, NewVm, Proof, Vm}; - -pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations"); - -pub fn establish_connection() -> PgConnection { - dotenv().ok(); - - let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); - PgConnection::establish(&database_url) - .unwrap_or_else(|_| panic!("Error connecting to {}", database_url)) -} - -pub fn get_connection_pool() -> Pool> { - dotenv().ok(); - let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); - - let manager = ConnectionManager::::new(database_url); - // Refer to the `r2d2` documentation for more methods to use - // when building a connection pool - Pool::builder() - .test_on_check_out(true) - .build(manager) - .expect("Could not build connection pool") -} - -pub fn run_migration(conn: &mut PgConnection) { - conn.run_pending_migrations(MIGRATIONS) - .expect("Error running migrations"); -} - -pub fn create_vm<'a>( - conn: &mut PgConnection, - prj_name: &'a str, - elf_str: &'a str, - id_str: &'a str, -) -> Result { - use crate::db::schema::vms; - use crate::db::schema::vms::dsl::*; - - let new_vm = NewVm { - project_name: prj_name, - elf: elf_str, - image_id: id_str, - }; - - match diesel::delete(vms.filter(project_name.eq(prj_name))).execute(conn) { - Ok(_) => (), - Err(err) => { - return Err(err); - } - }; - - diesel::insert_into(vms::table) - .values(&new_vm) - .returning(Vm::as_returning()) - .get_result(conn) -} - -pub fn get_vm<'a>(conn: &mut PgConnection, id_str: &'a str) -> Result { - use crate::db::schema::vms::dsl::*; - - // let results = vms.filter(image_id.eq(id_str)).limit(1).select(Vm::as_select()).load(conn).expect("Error loading vms"); - - let vm = vms - .filter(image_id.eq(id_str)) - .select(Vm::as_select()) - .first(conn)?; - Ok(vm) -} - -pub fn get_vm_by_project<'a>( - conn: &mut PgConnection, - project: &'a str, -) -> Result { - use crate::db::schema::vms::dsl::*; - - // let results = vms.filter(image_id.eq(id_str)).limit(1).select(Vm::as_select()).load(conn).expect("Error loading vms"); - - let vm = vms - .filter(project_name.eq(project)) - .select(Vm::as_select()) - .first(conn)?; - Ok(vm) -} - -pub fn create_proof<'a>( - conn: &mut PgConnection, - project_id: &'a str, - task_id: &'a str, - client_id: &'a str, - sequencer_sign: &'a str, - image_id: &'a str, - datas_input: &'a str, - receipt_type: &'a str, - status: &'a str, -) -> Proof { - use crate::db::schema::proofs; - - let new_proof = NewPoof { - project_id, - task_id, - client_id, - sequencer_sign, - image_id, - datas_input, - receipt_type, - status, - }; - - diesel::insert_into(proofs::table) - .values(&new_proof) - .returning(Proof::as_returning()) - .get_result(conn) - .expect("Error saving new proof") -} - -pub fn update_proof_with_receipt<'a>( - conn: &mut PgConnection, - p: &'a Proof, - r: &'a String, -) -> Proof { - use crate::db::schema::proofs::dsl::*; - - diesel::update(proofs.filter(id.eq(p.id))) - .set((receipt.eq(r), status.eq("succeeded"))) - .returning(Proof::as_returning()) - .get_result(conn) - .expect("Error updating proof") -} - -pub fn update_proof_status_with_receipt<'a>( - conn: &mut PgConnection, - p: &'a Proof, - s: &'a String, -) -> Proof { - use crate::db::schema::proofs::dsl::*; - - diesel::update(proofs.filter(id.eq(p.id))) - .set(status.eq(s)) - .returning(Proof::as_returning()) - .get_result(conn) - .expect("Error updating proof") -} diff --git a/risc0-server/src/db/schema.rs b/risc0-server/src/db/schema.rs deleted file mode 100644 index 88eeeff..0000000 --- a/risc0-server/src/db/schema.rs +++ /dev/null @@ -1,31 +0,0 @@ -// @generated automatically by Diesel CLI. - -diesel::table! { - proofs (id) { - id -> Int4, - project_id -> Varchar, - task_id -> Varchar, - client_id -> Varchar, - sequencer_sign -> Varchar, - image_id -> Varchar, - datas_input -> Varchar, - receipt_type -> Varchar, - receipt -> Nullable, - status -> Varchar, - create_at -> Timestamp, - } -} - -diesel::table! { - vms (id) { - id -> Int4, - project_name -> Varchar, - elf -> Text, - image_id -> Varchar, - } -} - -diesel::allow_tables_to_appear_in_same_query!( - proofs, - vms, -); diff --git a/risc0-server/src/grpc/mod.rs b/risc0-server/src/grpc/mod.rs index bfe15ae..74f47ad 100644 --- a/risc0-server/src/grpc/mod.rs +++ b/risc0-server/src/grpc/mod.rs @@ -1 +1 @@ -pub mod server; \ No newline at end of file +pub mod server; diff --git a/risc0-server/src/grpc/server.rs b/risc0-server/src/grpc/server.rs index fb4eff3..18735c5 100644 --- a/risc0-server/src/grpc/server.rs +++ b/risc0-server/src/grpc/server.rs @@ -1,184 +1,396 @@ +use std::collections::HashMap; +use std::fmt::Debug; +use std::sync::Arc; use std::{io::Read, str::FromStr}; -use diesel::{ - r2d2::{ConnectionManager, Pool}, - PgConnection, -}; use ethers::abi::{encode, Token}; use flate2::read::ZlibDecoder; -use hex::FromHex; +use lazy_static::lazy_static; +use regex::Regex; use risc0_ethereum_contracts::groth16; -use risc0_zkvm::{InnerReceipt, Receipt}; -use rust_grpc::grpc::vm_runtime::{ - vm_runtime_server::VmRuntime, CreateRequest, CreateResponse, ExecuteRequest, ExecuteResponse, +use risc0_zkvm::InnerReceipt; +use rust_grpc::grpc::vm::{ + vm_server::Vm, ExecuteTaskRequest, ExecuteTaskResponse, NewProjectRequest, NewProjectResponse, }; use serde_json::Value; +use tokio::sync::RwLock; use tonic::{Request, Response, Status}; +use tracing::{error, info, warn}; -use crate::{db, handlers::proof::get_receipt, model::models::ProofType}; +use crate::core::prover::{BonsaiProver, LocalProver, Prover}; pub struct Risc0Server { - db_conn_pool: Pool>, + // TODO: replace with LRU + projects: Arc>>, +} + +#[derive(Clone)] +struct Project { + pub project_id: u64, + // TODO: share prover across threads + pub elf: Vec, + pub image_id: Vec, +} + +lazy_static! { + static ref ELF_RE: Regex = Regex::new(r"pub const (\w+)_ELF: \&\[u8\] = \&\[(.+?)\];").unwrap(); + static ref IMAGE_ID_RE: Regex = + Regex::new(r"pub const (\w+)_ID: \[u32; \d+\] = \[(.+?)\];").unwrap(); } impl Risc0Server { pub fn new() -> Self { - let pool = db::pgdb::get_connection_pool(); - db::pgdb::run_migration(&mut pool.get().unwrap()); - Risc0Server { db_conn_pool: pool } + Risc0Server { + projects: Arc::new(RwLock::new(HashMap::new())), + } + } + + fn extract_data(&self, regex: &Regex, text: &str) -> Option> + where + T::Err: Debug, + { + if let Some(captures) = regex.captures(text) { + // let prefix = captures[1].to_string(); + let data_str = &captures[2]; + let data: Vec = data_str + .split(',') + .map(|num| num.trim().parse::().unwrap()) + .collect(); + return Some(data); + } + None } } #[tonic::async_trait] -impl VmRuntime for Risc0Server { - async fn create( +impl Vm for Risc0Server { + async fn new_project( &self, - request: Request, - ) -> Result, Status> { - println!("risc0 instance create..."); - let request = request.into_inner(); - - let project_id = request.project_id; - let project = project_id.to_string(); - let content = request.content; - let compressed_data = Vec::from_hex(content).unwrap(); - let mut decoder = ZlibDecoder::new(&compressed_data[..]); - let mut content = Vec::new(); - decoder.read_to_end(&mut content)?; + request: Request, + ) -> Result, Status> { + let req = request.get_ref(); - let exp_param = request.exp_param; + // Decompress the binary data + let compressed_data = req.binary.as_slice(); + let mut decoder = ZlibDecoder::new(compressed_data); + let mut content = Vec::new(); + decoder + .read_to_end(&mut content) + .map_err(|e| Status::internal(format!("Failed to decompress data: {}", e)))?; + let content_str = String::from_utf8(content).unwrap(); - // exp_param = {"image_id":"RANGE_ID", "elf":"RANGE_ELF"} - if exp_param == "" { - return Err(Status::invalid_argument("need exp_param")); - } + let elf_data = self + .extract_data::(&ELF_RE, &content_str) + .ok_or(Status::internal("Failed to extract ELF data"))?; + let id_data = self + .extract_data::(&IMAGE_ID_RE, &content_str) + .ok_or(Status::internal("Failed to extract ID data"))?; - let v: Value = serde_json::from_str(&exp_param).unwrap(); - let image_id = v["image_id"].as_str().unwrap().to_string(); - let elf = v["elf"].as_str().unwrap().to_string(); - let content = String::from_utf8(content).unwrap(); - - let mut elf_str = String::new(); - let mut id_str = String::new(); - - for line in content.lines() { - if line.contains(&elf) { - let vec: Vec<&str> = line.split("=").collect(); - elf_str = vec[1].trim()[2..vec[1].trim().len() - 2].to_string(); - } - if line.contains(&image_id) { - let vec: Vec<&str> = line.split("=").collect(); - id_str = vec[1].trim()[1..vec[1].trim().len() - 2].to_string(); - } + { + let mut map = self.projects.write().await; + map.insert( + (req.project_id, 0), + Project { + project_id: req.project_id, + elf: elf_data, + image_id: id_data, + }, + ); } - let conn = &mut self.db_conn_pool.get().unwrap(); - let _ = db::pgdb::create_vm(conn, &project, &elf_str, &id_str); + info!("New project added: {}", req.project_id); - Ok(Response::new(CreateResponse {})) + Ok(Response::new(NewProjectResponse {})) } - async fn execute( + async fn execute_task( &self, - request: Request, - ) -> Result, Status> { - println!("risc0 instance execute..."); - let request = request.into_inner(); - - let project_id = request.project_id; - let task_id = request.task_id; - let client_id = request.client_id; - let sequencer_signature = request.sequencer_signature; - let datas = request.datas; - - if datas.len() == 0 { - return Err(Status::invalid_argument("need datas")); + request: Request, + ) -> Result, Status> { + info!("risc0_server execute_task"); + + let req = request.into_inner(); + + if req.payloads.is_empty() { + return Err(Status::invalid_argument("data is empty")); } - let conn = &mut self.db_conn_pool.get().unwrap(); - let image_id = match db::pgdb::get_vm_by_project(conn, &project_id.to_string()) { - Ok(v) => v.image_id, - Err(_) => { - return Err(Status::not_found(format!( - "{} not found", - project_id.to_string() - ))) - } - }; + let project = { + let map = self.projects.read().await; + map.get(&(req.project_id, 0)).cloned() + } + .ok_or_else(|| Status::not_found(format!("{} not found", req.project_id)))?; // TODO move to guest method // param = {"private_input":"14", "public_input":"3,34", "receipt_type":"Snark"} // let input_datas = json!(datas).to_string(); - let v: Value = serde_json::from_str(&datas[0]).unwrap(); - let mut receipt_type = ProofType::from_str("Snark").unwrap(); - // TODO check v - if v.get("receipt_type").is_some() { - receipt_type = v["receipt_type"] - .as_str() - .unwrap() - .to_string() - .parse() - .unwrap(); - } - // let receipt_type: Result = - // v["receipt_type"].as_str().unwrap().to_string().parse(); - // let receipt_type = receipt_type.unwrap(); - - let receipt = match get_receipt( - project_id, - task_id, - client_id, - sequencer_signature, - image_id, - datas, - receipt_type.clone(), - ) + let v: Value = serde_json::from_slice(&req.payloads[0]).unwrap(); + + let receipt = tokio::task::spawn_blocking(move || { + // TODO: move prover initialization to new_project + let prover: Box = match v.get("receipt_type") { + Some(receipt_type) => match receipt_type.as_str().unwrap() { + "Stark" => Box::new(LocalProver::new(&project.elf)), + "Snark" => Box::new(BonsaiProver::new(&project.elf)), + _ => Box::new(LocalProver::new(&project.elf)), + }, + None => Box::new(LocalProver::new(&project.elf)), + }; + + let data: Vec = req + .payloads + .clone() + .into_iter() + .map(|v| String::from_utf8(v).expect("Invalid UTF-8 sequence")) + .collect(); + + prover.prove(data) + }) .await - { - Ok(r) => r, - Err(e) => return Err(Status::cancelled(e)), - }; + .map_err(|e| Status::internal(format!("Failed to spawn blocking task: {}", e)))? + .map_err(|e| Status::internal(format!("Failed to prove: {}", e)))?; - println!("{:?}", receipt); - let mut result = receipt.as_bytes().to_vec(); - let risc_receipt: Receipt = serde_json::from_str(&receipt).unwrap(); - if matches!(risc_receipt.inner, InnerReceipt::Groth16(_)) { - let seal = groth16::encode(risc_receipt.inner.groth16().unwrap().seal.clone()).unwrap(); - let journal = risc_receipt.journal.bytes.clone(); + info!("receipt: {:?}", receipt); + + // let mut result = receipt.as_bytes().to_vec(); + let mut result = serde_json::to_vec(&receipt) + .map_err(|e| Status::internal(format!("Failed to serialize receipt: {}", e)))?; + // let risc_receipt: Receipt = serde_json::from_str(&receipt).unwrap(); + if matches!(receipt.inner, InnerReceipt::Groth16(_)) { + let seal = groth16::encode(receipt.inner.groth16().unwrap().seal.clone()).unwrap(); + let journal = receipt.journal.bytes.clone(); let tokens = vec![Token::Bytes(seal), Token::Bytes(journal)]; result = encode(&tokens); } - Ok(Response::new(ExecuteResponse { result })) + Ok(Response::new(ExecuteTaskResponse { result: result })) } } -#[test] -fn param() { - let receipt = "{\"inner\":{\"Groth16\":{\"seal\":[13,130,138,212,74,234,176,239,95,29,228,225,143,171,188,84,199,197,244,148,214,38,199,17,199,58,134,101,217,241,136,201,12,22,9,213,157,120,249,214,255,96,0,200,170,149,120,109,143,229,183,161,226,83,220,46,139,2,50,113,217,0,187,186,47,205,143,50,147,175,156,184,200,208,39,186,129,20,149,87,98,224,66,93,24,245,84,67,67,81,183,244,100,51,144,189,18,149,157,185,195,219,178,223,162,234,214,12,219,208,23,44,21,3,90,125,93,114,77,34,109,20,69,101,59,212,158,7,8,118,175,66,105,237,183,63,191,203,227,40,40,215,38,212,214,1,47,97,188,60,124,142,116,128,113,135,4,47,141,194,16,214,58,85,109,62,206,209,79,51,245,98,179,153,217,229,235,72,105,61,144,182,7,95,192,149,159,8,152,218,246,235,42,107,65,59,55,111,1,209,243,208,74,120,248,240,155,215,124,207,189,31,221,94,179,134,199,130,187,202,254,49,2,181,31,205,80,114,104,112,98,188,156,219,152,234,30,6,141,109,111,194,112,12,58,16,53,191,130,8,192,148,245,77,216,35],\"claim\":{\"Value\":{\"pre\":{\"Value\":{\"pc\":2131092,\"merkle_root\":[257142831,212867192,3019768776,4077566949,3774766206,1955124911,2139138887,437463669]}},\"post\":{\"Value\":{\"pc\":0,\"merkle_root\":[0,0,0,0,0,0,0,0]}},\"exit_code\":{\"Halted\":0},\"input\":{\"Pruned\":[0,0,0,0,0,0,0,0]},\"output\":{\"Value\":{\"journal\":{\"Value\":[82,0,0,0,73,32,107,110,111,119,32,121,111,117,114,32,112,114,105,118,97,116,101,32,105,110,112,117,116,32,105,115,32,103,114,101,97,116,101,114,32,116,104,97,110,32,49,49,32,97,110,100,32,108,101,115,115,32,116,104,97,110,32,52,51,44,32,97,110,100,32,73,32,99,97,110,32,112,114,111,118,101,32,105,116,33,0,0]},\"assumptions\":{\"Value\":[]}}}}},\"verifier_parameters\":[2565148465,803857384,666633640,2019065645,1753987992,2480395716,2877601933,1558279850]}},\"journal\":{\"bytes\":[82,0,0,0,73,32,107,110,111,119,32,121,111,117,114,32,112,114,105,118,97,116,101,32,105,110,112,117,116,32,105,115,32,103,114,101,97,116,101,114,32,116,104,97,110,32,49,49,32,97,110,100,32,108,101,115,115,32,116,104,97,110,32,52,51,44,32,97,110,100,32,73,32,99,97,110,32,112,114,111,118,101,32,105,116,33,0,0]},\"metadata\":{\"verifier_parameters\":[2565148465,803857384,666633640,2019065645,1753987992,2480395716,2877601933,1558279850]}}"; - println!("{:?}", receipt); - let risc_receipt: Receipt = serde_json::from_str(&receipt).unwrap(); - println!("{:?}", risc_receipt); - match risc_receipt.inner { - InnerReceipt::Groth16(_) => { - let seal = groth16::encode(risc_receipt.inner.groth16().unwrap().seal.clone()).unwrap(); - println!("seal {}", format!("0x{}", hex::encode(seal.clone()))); - let journal = risc_receipt.journal.bytes.clone(); - println!("journal {}", format!("0x{}", hex::encode(journal.clone()))); +// #[cfg(test)] +// mod tests { +// use super::*; +// use risc0_zkvm::Receipt; - let tokens = vec![Token::Bytes(seal), Token::Bytes(journal)]; +// #[test] +// fn param() { +// let receipt = "{\"inner\":{\"Groth16\":{\"seal\":[13,130,138,212,74,234,176,239,95,29,228,225,143,171,188,84,199,197,244,148,214,38,199,17,199,58,134,101,217,241,136,201,12,22,9,213,157,120,249,214,255,96,0,200,170,149,120,109,143,229,183,161,226,83,220,46,139,2,50,113,217,0,187,186,47,205,143,50,147,175,156,184,200,208,39,186,129,20,149,87,98,224,66,93,24,245,84,67,67,81,183,244,100,51,144,189,18,149,157,185,195,219,178,223,162,234,214,12,219,208,23,44,21,3,90,125,93,114,77,34,109,20,69,101,59,212,158,7,8,118,175,66,105,237,183,63,191,203,227,40,40,215,38,212,214,1,47,97,188,60,124,142,116,128,113,135,4,47,141,194,16,214,58,85,109,62,206,209,79,51,245,98,179,153,217,229,235,72,105,61,144,182,7,95,192,149,159,8,152,218,246,235,42,107,65,59,55,111,1,209,243,208,74,120,248,240,155,215,124,207,189,31,221,94,179,134,199,130,187,202,254,49,2,181,31,205,80,114,104,112,98,188,156,219,152,234,30,6,141,109,111,194,112,12,58,16,53,191,130,8,192,148,245,77,216,35],\"claim\":{\"Value\":{\"pre\":{\"Value\":{\"pc\":2131092,\"merkle_root\":[257142831,212867192,3019768776,4077566949,3774766206,1955124911,2139138887,437463669]}},\"post\":{\"Value\":{\"pc\":0,\"merkle_root\":[0,0,0,0,0,0,0,0]}},\"exit_code\":{\"Halted\":0},\"input\":{\"Pruned\":[0,0,0,0,0,0,0,0]},\"output\":{\"Value\":{\"journal\":{\"Value\":[82,0,0,0,73,32,107,110,111,119,32,121,111,117,114,32,112,114,105,118,97,116,101,32,105,110,112,117,116,32,105,115,32,103,114,101,97,116,101,114,32,116,104,97,110,32,49,49,32,97,110,100,32,108,101,115,115,32,116,104,97,110,32,52,51,44,32,97,110,100,32,73,32,99,97,110,32,112,114,111,118,101,32,105,116,33,0,0]},\"assumptions\":{\"Value\":[]}}}}},\"verifier_parameters\":[2565148465,803857384,666633640,2019065645,1753987992,2480395716,2877601933,1558279850]}},\"journal\":{\"bytes\":[82,0,0,0,73,32,107,110,111,119,32,121,111,117,114,32,112,114,105,118,97,116,101,32,105,110,112,117,116,32,105,115,32,103,114,101,97,116,101,114,32,116,104,97,110,32,49,49,32,97,110,100,32,108,101,115,115,32,116,104,97,110,32,52,51,44,32,97,110,100,32,73,32,99,97,110,32,112,114,111,118,101,32,105,116,33,0,0]},\"metadata\":{\"verifier_parameters\":[2565148465,803857384,666633640,2019065645,1753987992,2480395716,2877601933,1558279850]}}"; +// println!("{:?}", receipt); +// let risc_receipt: Receipt = serde_json::from_str(&receipt).unwrap(); +// println!("{:?}", risc_receipt); +// match risc_receipt.inner { +// InnerReceipt::Groth16(_) => { +// let seal = +// groth16::encode(risc_receipt.inner.groth16().unwrap().seal.clone()).unwrap(); +// println!("seal {}", format!("0x{}", hex::encode(seal.clone()))); +// let journal = risc_receipt.journal.bytes.clone(); +// println!("journal {}", format!("0x{}", hex::encode(journal.clone()))); - let result = encode(&tokens); - println!( - "bytes_seal_journal {}", - format!("0x{}", hex::encode(result.clone())) - ); - } - InnerReceipt::Composite(_) => todo!(), - InnerReceipt::Succinct(_) => todo!(), - InnerReceipt::Fake(_) => todo!(), - _ => todo!(), +// let tokens = vec![Token::Bytes(seal), Token::Bytes(journal)]; + +// let result = encode(&tokens); +// println!( +// "bytes_seal_journal {}", +// format!("0x{}", hex::encode(result.clone())) +// ); +// } +// InnerReceipt::Composite(_) => todo!(), +// InnerReceipt::Succinct(_) => todo!(), +// InnerReceipt::Fake(_) => todo!(), +// _ => todo!(), +// } +// } +// } + +#[cfg(test)] +mod tests { + use super::*; + use ethers::abi::decode; + use flate2::write::ZlibEncoder; + use flate2::Compression; + use std::io::Write; + + fn create_dummy_elf() -> Vec { + include_bytes!("../tests/hello_guest").to_vec() + // vec![1, 2, 3, 4, 5] + } + + fn create_compressed_binary() -> Vec { + let binary = create_dummy_elf(); + let content = format!( + r#" + pub const TEST_ELF: &[u8] = &{:?}; + pub const TEST_ID: [u32; 8] = [1729087496, 1782151309, 3201877536, 1628959901, 2308880694, 3762575800, 943710734, 1150869179]; + "#, + binary, + ); + let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default()); + encoder.write_all(content.as_bytes()).unwrap(); + encoder.finish().unwrap() + } + + #[tokio::test] + async fn test_new_project() { + let server = Risc0Server::new(); + let compressed_binary = create_compressed_binary(); + + let request = NewProjectRequest { + project_id: 1, + project_version: "".to_string(), + binary: compressed_binary, + metadata: vec![], + }; + + let response = server.new_project(Request::new(request)).await; + assert!(response.is_ok()); + + let projects = server.projects.read().await; + assert!(projects.contains_key(&(1, 0))); + + let project = projects.get(&(1, 0)).unwrap(); + assert_eq!(project.project_id, 1); + assert_eq!(project.elf, create_dummy_elf()); + assert_eq!( + project.image_id, + vec![ + 1729087496, 1782151309, 3201877536, 1628959901, 2308880694, 3762575800, 943710734, + 1150869179 + ] + ); + } + + #[tokio::test] + async fn test_execute_task_local_prover() { + let server = Risc0Server::new(); + + // First, add a project + let compressed_binary = create_compressed_binary(); + let new_project_request = NewProjectRequest { + project_id: 1, + project_version: "".to_string(), + binary: compressed_binary, + metadata: vec![], + }; + server + .new_project(Request::new(new_project_request)) + .await + .unwrap(); + + // Now, execute a task + let payload = serde_json::json!({ + "private_input": "14", + "public_input": "3,34", + "receipt_type": "Stark" + }); + let execute_request = ExecuteTaskRequest { + project_id: 1, + project_version: "".to_string(), + task_id: "".as_bytes().to_vec(), + payloads: vec![serde_json::to_vec(&payload).unwrap()], + }; + + let response = server.execute_task(Request::new(execute_request)).await; + assert!(response.is_ok()); + + let result = response.unwrap().into_inner().result; + assert!(!result.is_empty()); + } + + // #[tokio::test] + // async fn test_execute_task_bonsai_prover() { + // let server = Risc0Server::new(); + + // // First, add a project + // let compressed_binary = create_compressed_binary(); + // let new_project_request = NewProjectRequest { + // project_id: 1, + // project_version: "".to_string(), + // binary: compressed_binary, + // metadata: vec![], + // }; + // server + // .new_project(Request::new(new_project_request)) + // .await + // .unwrap(); + + // // Now, execute a task + // let payload = serde_json::json!({ + // "private_input": "14", + // "public_input": "3,34", + // "receipt_type": "Snark" + // }); + // let execute_request = ExecuteTaskRequest { + // project_id: 1, + // project_version: "".to_string(), + // task_id: "".as_bytes().to_vec(), + // payloads: vec![serde_json::to_vec(&payload).unwrap()], + // }; + + // let response = server.execute_task(Request::new(execute_request)).await; + // assert!(response.is_ok()); + + // let result = response.unwrap().into_inner().result; + // // For Snark, we should be able to decode the result + // let decoded: (Vec, Vec) = decode( + // &[ethers::abi::ParamType::Bytes, ethers::abi::ParamType::Bytes], + // &result, + // ) + // .unwrap(); + // assert_eq!(decoded.0.len(), 192); // Groth16 seal length + // assert!(!decoded.1.is_empty()); // Journal should not be empty + // } + + #[tokio::test] + async fn test_execute_task_project_not_found() { + let server = Risc0Server::new(); + + let payload = serde_json::json!({ + "private_input": "14", + "public_input": "3,34", + "receipt_type": "Stark" + }); + let execute_request = ExecuteTaskRequest { + project_id: 1, // This project doesn't exist + project_version: "".to_string(), + task_id: "".as_bytes().to_vec(), + payloads: vec![serde_json::to_vec(&payload).unwrap()], + }; + + let response = server.execute_task(Request::new(execute_request)).await; + assert!(response.is_err()); + assert_eq!(response.unwrap_err().code(), tonic::Code::NotFound); + } + + #[tokio::test] + async fn test_execute_task_empty_payload() { + let server = Risc0Server::new(); + + let execute_request = ExecuteTaskRequest { + project_id: 1, + project_version: "".to_string(), + task_id: "".as_bytes().to_vec(), + payloads: vec![], // Empty payload + }; + + let response = server.execute_task(Request::new(execute_request)).await; + assert!(response.is_err()); + assert_eq!(response.unwrap_err().code(), tonic::Code::InvalidArgument); + } + + #[test] + fn test_extract_data() { + let server = Risc0Server::new(); + let content = r#" + pub const TEST_ELF: &[u8] = &[1, 2, 3, 4, 5]; + pub const TEST_ID: [u32; 3] = [10, 20, 30]; + "#; + + let elf_data = server.extract_data::(&ELF_RE, content); + assert_eq!(elf_data, Some(vec![1, 2, 3, 4, 5])); + + let id_data = server.extract_data::(&IMAGE_ID_RE, content); + assert_eq!(id_data, Some(vec![10, 20, 30])); } } diff --git a/risc0-server/src/handlers/mod.rs b/risc0-server/src/handlers/mod.rs deleted file mode 100644 index 1772e6f..0000000 --- a/risc0-server/src/handlers/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod proof; \ No newline at end of file diff --git a/risc0-server/src/handlers/proof.rs b/risc0-server/src/handlers/proof.rs deleted file mode 100644 index d750b56..0000000 --- a/risc0-server/src/handlers/proof.rs +++ /dev/null @@ -1,84 +0,0 @@ -use std::env; -use dotenvy::dotenv; -use anyhow::Result; -use risc0_zkvm::Receipt; - -use crate::{ - core::prove::{bonsai_groth16_prove_with_env, generate_proof_with_elf}, - db::{self}, - model::models::ProofType, - tools::parse_elf_from_str, -}; - -pub async fn get_receipt( - project_id: u64, - task_id: u64, - client_id: String, - sequencer_sign: String, - image_id: String, - datas_input: Vec, - receipt_type: ProofType, -) -> Result { - let connection = &mut db::pgdb::establish_connection(); - let proof = db::pgdb::create_proof( - connection, - &project_id.to_string(), - &task_id.to_string(), - &client_id, - &sequencer_sign, - &image_id, - &datas_input.join("#"), - &receipt_type.to_string(), - "generating", - ); - let mut vm = db::models::Vm::new(); - let vm_result = db::pgdb::get_vm(connection, &image_id); - match vm_result { - Ok(v) => vm = v, - Err(e) => println!("image_id parse error: {}", e), - } - let elf_cont: Vec = parse_elf_from_str(&vm.elf); - - let receipt: Result; - match receipt_type { - ProofType::Stark => { - receipt = generate_proof_with_elf(project_id, task_id, client_id, sequencer_sign, datas_input, &elf_cont); - } - ProofType::Snark => { - dotenv().ok(); - - let bonsai_url = env::var("BONSAI_URL").expect("BONSAI_URL must be set"); - let bonsai_key = env::var("BONSAI_KEY").expect("BONSAI_KEY must be set"); - // TODO - receipt = tokio::task::spawn_blocking(move || { - bonsai_groth16_prove_with_env( - project_id, - task_id, - client_id, - sequencer_sign, - datas_input, - &elf_cont, - bonsai_url, - bonsai_key, - ) - }).await.unwrap(); - } - } - - match receipt { - Ok(r) => { - let receipt_str = serde_json::to_string(&r).unwrap(); - let _ = db::pgdb::update_proof_with_receipt(connection, &proof, &receipt_str); - return Ok(receipt_str); - } - Err(e) => { - println!("generate proof error, Error: {:?}", e); - let _ = db::pgdb::update_proof_status_with_receipt( - connection, - &proof, - &"failed".to_string(), - ); - return Err(format!("generate proof error, Error: {:?}", e)); - } - } -} diff --git a/risc0-server/src/lib.rs b/risc0-server/src/lib.rs index e7d1d55..995170f 100644 --- a/risc0-server/src/lib.rs +++ b/risc0-server/src/lib.rs @@ -1,19 +1,13 @@ use grpc::server::Risc0Server; -use rust_grpc::grpc::vm_runtime::vm_runtime_server::VmRuntimeServer; +use rust_grpc::grpc::vm::vm_server::VmServer; use tonic::transport::Server; mod core; -mod db; mod grpc; -mod handlers; -mod model; -#[cfg(test)] -mod tests; -mod tools; -pub async fn start_grpc_server(addr: &str) { - let addr = addr.parse().unwrap(); +pub async fn start_grpc_server(addr: &str) -> Result<(), Box> { + let addr = addr.parse()?; let risc0_server = Risc0Server::new(); tracing_subscriber::fmt() @@ -24,8 +18,9 @@ pub async fn start_grpc_server(addr: &str) { Server::builder() .trace_fn(|_| tracing::info_span!("risc0_server")) - .add_service(VmRuntimeServer::new(risc0_server)) + .add_service(VmServer::new(risc0_server)) .serve(addr) - .await - .unwrap(); + .await?; + + Ok(()) } diff --git a/risc0-server/src/main.rs b/risc0-server/src/main.rs index 215b6ab..fcf4a1a 100644 --- a/risc0-server/src/main.rs +++ b/risc0-server/src/main.rs @@ -1,8 +1,9 @@ use risc0_server::start_grpc_server; #[tokio::main] -async fn main() { +async fn main() -> Result<(), Box> { // start grpc server - println!("{}", "start grpc server..."); - start_grpc_server("0.0.0.0:4001").await; -} \ No newline at end of file + start_grpc_server("0.0.0.0:4001").await?; + + Ok(()) +} diff --git a/risc0-server/src/model/mod.rs b/risc0-server/src/model/mod.rs deleted file mode 100644 index ff92946..0000000 --- a/risc0-server/src/model/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod models; \ No newline at end of file diff --git a/risc0-server/src/model/models.rs b/risc0-server/src/model/models.rs deleted file mode 100644 index 8f9b084..0000000 --- a/risc0-server/src/model/models.rs +++ /dev/null @@ -1,30 +0,0 @@ -use std::{str::FromStr, fmt}; -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub enum ProofType { - Stark, - Snark, - -} - -impl FromStr for ProofType { - type Err = (); - - fn from_str(s: &str) -> Result { - match s { - "Stark" => Ok(ProofType::Stark), - "Snark" => Ok(ProofType::Snark), - _ => Err(()), - } - } -} - -impl fmt::Display for ProofType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ProofType::Stark => write!(f, "Stark"), - ProofType::Snark => write!(f, "Snark"), - } - } -} \ No newline at end of file diff --git a/risc0-server/src/tests/10000.json b/risc0-server/src/tests/10000.json deleted file mode 100644 index 12ff75c..0000000 --- a/risc0-server/src/tests/10000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "code": "789cecbd39af24bdd226e6eb57b4355619dc93142043c6488e2043ee401020f9920069feffa04846c413416656d63975faed7bbf06ceedfbd696dc82b13cb1fd77ffef7ffd3f7ffd5fffcffffdfffdffbffeb7fff17ffd9ffff3fff19fff97ffe9bffff59ffecb7fadfffbafffe1d77ffa2f3e1c8f5fa53d7e1de5f1eb708f5f9efedcf95f18ffa6d8ff1fbfeb437afcf2a93e7ec5f1a51cf077cf6fc4f4f8159747ceefcd5f1dfddf349f398719e394f547ea855f5f84e7a46412ead5d97f5f6f805ffe3be0bbea45323f2d274354fddf31ac2f6a7dfe3ed14fcdcb7c67a0561ebffc11e8cdfef2f99c18b7af7d98c7e9762f6f2dcdbbfaf8f59c659097cf6162dabe2eb80f21e27197b3e1aa7f1e6b7bd2c873feeee2e4eefc9593f7996afd731f527bfc2a999675f617e3d98bfbd4f6f7efefdfdfbfbf7f7ffffefefdfdfbfbf7f7efefdfdfbfbf7f7ffffefefdfdfbfbf7f7efefdfdfbfbf7f7fce9f6fe44508c93d7ec5fcf8953af0fcf8e5d37c9d1ebf7cc76ce98d8e2d67786322a63e8fd7b10ed0955f9701c0f2eb3490607e1d1ebfda21affb0c7c1c0e053d8568a710650abe7879e339077f1ce30d1f9f9f1c91a0f7f8f8153a329c1fbf425fc8d15d19fe1888727fede3410873df25a75e057a566b13660ecf590e97893ffa4c26323f06f7c37b43bf7f7e185c1ee0f8f39df6f8150e19fdf9499b40fcd1fa837d3d3a88cdaf5393198430f639f709c43eff01d0c74cce879268f5cfcf8f041f87e563efe063271ffbe9dee9b3ab9be5cec9c95ee5c7afea64656938199c9c6408b095ced103032d8dde90a7ebc7b5c23f0fcfddcc59beecbdfd36cd05d7f1fc76f6fd807d1dae82e7cb7e08871c427fe873824f6ace7efac87c2de35c06d5449aa1efdf28e279ea8410ea1c33c4977b7df3a4ce0efab9fe4243ce253c17e7a2d0519fafaf8392e69a83f3bc05e3f323f2e77dc9c185f188d325763fd298a37feed6f3091e68dbcc49d1b69a535f55f77716bebcfd3f07e71a8baeebc77d11bc2b65fd42bfdf7adbf417e6a261db9709084586e508b3bc919f3f499dc90ae13df7b308591239d2ff872accc24fa20e9db2073f09cc4f06b97b76ccc5f149f0f3974d769c995d8611fa1926be55fa0cf3736d618a833cde9bec4a163819cff3ce77d61a0d6b1de4f21c62ac80eed2f3aacd337c7ef779e2fc9b954316c312c7e56b050927cde1e9988ef9a61349d3b94d95cf0f39b9a7e0e91f17dae627e114f9bc1ff49c4a3ad6db352710ec9482e7290d79317e432b9411f29cc0f311fc6d37bcc06346cf779e0c679e6ce8e22dcbf5ec973b096907b77964ace68921c884dc3875fabcbf410107af46ec5f487d7fe9b6fbfc7c762cb24b9dc2c6379e0fe82ffb3f4ef48365ca213a10a7fd1dcff4dee71852916ff4776e6ed367261d7647578a99b4cf4e4ddad76026ed9bdcfc9f9f3693bc7786e29ca5389cb5af76d631fdce59a7cdac63b50412d4a473c2cf2bdffcaf4d99d62c531682e3d744b4ace9b8c9f93a4b0de3ad304e814ea36bc2cc041b8b1652489eba791770fd117570d12e669a486fe2994300042dbdbd3ba6dec6c2766a39f095c1cb877008752f1c9e421bc58b57cf3cfc859a314639468cd27c460379b41bd2abd576a19a8f7134a40a3d8d84639e717fa3c5fe86b211d08e390e52dae3d8f73a7f5d1a5914e33e770e19481fedcfafd3ac0960a5c0f37d9ecfaf9343b8399f6aa449c5f1e5f1347d3f1873e7d981ce544dc0c3828a97019c9940d51378de389ac024b7c4515c6d525e12e5b9f011f5fbd8d73d958a3c96cd94e185b2eaa446bd26a68b4aca0bfd88350bab26f419f57b974004674de0457449ba3045992244ea11f6c3134db6a95074cd473f4d9412efd0486c6c169eeac2fdc585b67fb84b6d5f7fbc6afbc0c6401f899bdda6e59b5b7968b374fcc31b40e6c253a98bf0c06bd57f00064c537e6373bd5ed2cd1d39dfcfaf9a1ee15fc3f418fb1bee581fd96946d9061822b7328cdde8a7dad5d35479959db3b588f7a60c6595d94a99063af19581bd38e46c80fe0c227276fcaaaf6515cd4a9ecf8f6b66b060981cf2d1b9674a0a042d359a70f9e7af9b911101c442d73c9a61fac13079106b05ce421ec770c511279c734c2b1174c67ee382d05bdf8b2a27d3373324795d66a026cb085a909fc850a107f2e9233af7f895665c317ddc5ff7070cea4901e0c0f18d301f908449e0c7cc34060b5460def8469a0f985fc873faf471a60704042c47046954ba021140976a0e0e9cb61099e2427e5e93b77746ac1623568ba1b8a2e4b8b3141335854590e27df8084708c3453d9ac7d1c8ee983669146a8fb8381a7bbd1b347600e41555a4042a126d458bf2dacdc11330b7340fa78d493dadedb405e300189c7a5553924c1411df0dd24ed7210a1ecb4cb1cd95868ccac9f301411463467789f6a6da302c9e3435d6468a8597c865be7973effad5edfcb15a5d00d425013a01f28973bcbe93ead70a93cf0ad5f41d282af0ec97b0e68c365f268612584dbcf3fb01cf685855d8cca0d177e0a6fa2edc149ea7d8064176cdf615dc34a1a3ccd2ad92a925e0935fc0a7e7e3a2c29ef2a1d1b16e963d471063a58c01e40d8286f92659a489746bfa82859ae0da568b33d11d376a1d8c5e58cb2d73be3499c3298ce92816627268c7f46f3bd6c89e978000266deaba33d336b8dd3363c5470600b19eaf27c4f4fc3408be7463c0f91d3f0c3db1ce094000f3bda21df13c109f35c8b4cc99573527ed0133e86f2406423a02fbdb671db6a7570ace9a30269e352bb463d68c30fdbe7933b97b67a9ce29aa53d39e28134d3ba6df3eedb49b76ac8a46829e7566b67838c198be3ae72030d3987310229437bc76a8b17e330455171e6d224bac651a58a9faa926cf51f314ab165502f026be44914a7b81220d4b305dc248e0adcad3dbb60c721f44720ff611777edf1d1c77102466685bb38484249b3da4c9d1514403294d350540a5a82125112b023175ad1c109e68101e161cd5608ed5e8be7ed17dbd9e80070f47e35bdaa68110b231a6aaf1ba57b3035508099cd69e7c234f8b86f0963cbd4cec967832b7ca7a5b186a85dc97635808e2159a34e2156643b3ee6fb5698293721882a0c7447737e848c8162e7098bbea34a2908549f8693bd3e523fb9f26dce51020109900809016b7343f003cb42182178121867ed20739f386ec0a397cd1268ac91c7c3084582e6da20b8b1fc9dedad8c518e5deea4b7e276ea2c200f4f8abd52faa0058f972d783bdeb415420365217352bcd6f4e25bf91beada0c4a0e1d5302d6322d2e9109db11593b4eb75d448a772057089e6cbee01cd7283f80786f470e3da473cc84361574da171609b4eec4a7f1e1a7ceee473b45cb2be3c45e1b9d56f173cec8abea02c111a65ba1d14828b77fb04b0ed5f7e35e5bb4bde6f18ac30a34c8be27e81080c0d713b14aca74b4860ec829632e7a4223cb218080ef678f26cb3e373dfc7547c003cf8d46d136243c0923836075af90e2520a9278927eab34b415e7bb26739faaafb04348a1b418d12a62c4b2ed61b45746345c2791c4fff2756bca0cdde3e9a0662910189a95aacf60853599d02380a4e3150879c80a09ff292f6ea200f0a6182c038080c39000d9948d173053289eeea2c2a14a30ea812f59aaecb1eb07dd34b3349666eee7052baa9a2869c143bae9a208d30380cbc9c0ce09b0c9e7ca1c4b197eccc8d268e36e4f676c40dc4ac50b070eac82bf9c2917838235d18710c0686db80cca416d20456f42810c66c847db2c23029519fbe837e2ecf0e1700e429f4c9639dc18f49c18f5bec9390d50df2ca523eeed14f566acea0d705791dbca02c8026cb7f8f6c4fe4bf023c0d363a4305e6a50de72162ca293615cac86899033c1f78671c4edd5418dc9f751d7e0ce61bffe40ade032f1c121d1e6d288874c7272c790b079cc49135020c3c6c48e2ce6e0be8d94d7e1fa18486a8bcb07565cae93449c1cfcd56417607a0b89d00ab277d75c40d7ac3fc23327fabcf91fa13d01e3d2c1f2b5a7b12ba684697e98ca7a30205dc997d21a063b29331834b733878cbea56452d4d691810f4ebc0e2f98486d1f96f01516fd5a9d21482464e119665400603253a566fe9d6c5cc1a5f083baffbeaa4f7146aef735788d6e8efa6f167b17add959e4fce88b0c64d0cb334f3b68c388a3443991bb0a7a274ccf9b86d20b407431d02a1cf42259819ec3528e72f746de3ec5f746df3b9d1b50fb36bdad8d9ed5a739a8ef52e1cce288d5f58739bf90e912794adb656be791d7c034c8d82743cc51f4e42209692a35ab1899789a8873bd1354fd7d7c11b1de89c5e9dcfddd33da30e031f6aaeb31e1f31a1767ccecc71e4992733bb22834bc04106987d08470de0b312495150cbef95bae0d8d2a41a84ac864b0874fc56c4a0113b8285453618539c50e82ea43d4d35f550c1d7401b46e71ff046ab5ae9f7da1442be1a03989d1a8202f9bb7c01186d67e5d52f7cf63905f25bf66b1717faeea5c67c8deb37fa3a332f0ab808a53fd49d61d808b3f33e3f241926684ab58c69f0828ecd9fd9d1239aca3cf3646999b0c0d3858dc50f805494ce78b5b2fe4fbf9a776651e6e6d55525da21adbb11a9d8d9b291d7c7d536a2f272516db7b397a795af4ecbcde3fcd42ea158395f837f8b3a4670e63975f4584157ccacae08bf105fba3b8b41817dc817541a82cce305918e59dca5517a2b74ade6d52ca29ac5ebbd7027543558e1608e90758988768020a6be78704cba99722946786a8a13827eddd547e58028b88b9daf63b2e2b06426854f8f4f810bc0465863a4a916886183c4498aa650680444ef76d8eed45d22f192d1446774b42f93b89cc20ce48cfac1789528816ab0f23c2f5d4e1a7a4ed398abd34322fa79c6fbaa8cef187510f0b9a7d3618a9457734cc409c7fcfab5eb08459673635a2cc67cdfb0a6fe983aa71e769246db22e34b9a29b39e9503d83333d514ed9b52758822187b3111e020421ae2132440d1c4273e4c78a28a4e7c98e044a763139dba636b9ce0b2596d6c623b91c95f3cf349f25f67c08370dd1b0c7842d23bdef7a35c0771a6790993de4c00424093a3340348ba63c081394ca5cf09dcaaea2a1651f968ad8901aba22577aa6ad801c700a97954923d3c8060044c22d259a0fc424ec37a7d0f0869040d9cc2c4e3b13eec4506ce4ecd19db528c75905e136b0505a48849aa1f96d51e7cecfaaafb1a08a29dd7d58def9463821af63adbd7f2ac5435a51743e9c5507ad1947e684a3fb47c3d84c355316ca99cc10123fbc8f1ef3c743643db988a6c622ad8397668c23a381256fc6b67750bb4e81ed1e2e0d52efafef70ad05183b307280ac94bf6c55c1884511892245491b58ce04da4e6f001eac0cb00114013780ac3559815c210f43320c66a807b42183dbf3f818bb8c34fe8f1ec831cb867a582ba1128a3230a3b4b84c90e199d4c4a8e6cb97373a3f8d36678840ffade221b9820c49aa55d496d20ad46300f8eaeb7e29e63008eb9215e04e1f0516e3d0db13d5468769a7e8d30bff09c86f647565267906205959244c76e4ce5bc928f997a42dfde91763cd5c886bb513d7dc49e353e943ecf89db7837505f0cfbcb80794dfba98ea3f775abc1b3e7cbe62080a40649fce431d56b150cfc835db794988e19e4c1e1c559583808609dee2362cec0323cd39d73743c2beb5d00d754d5905035905031b935579e5f0c8e15ec93dc81acd18993b4b0a392f56f1091c264c63f269a81bc8a871577b075607b78a3ffea74b8513afe23651cce22d59ab02a72642e20dcf63ce8b0e8643b9515e45749a987ca9dd4b93bf17dd2720ab8d42ce637ad3da58295096ca21bae1d6a43c10988fb4b93a68a106ace5ecfc843bca30cd6eda89e4602092ff8f8e1913ef48a8a96a04dcd3578ade4e9b81b9330521285a85df113dfa0143eef910a5f6883580c1f23db7e62196c17b759d05fa23fb292eac6d53703702158c9e97966cd2daaf99879cdd63e3c94cb376c3e2ec08d769fab03aa270f003d5cdbaeec4065c67a186a2ac6497c4ad10b03906f2085d7dd3792d943fb3958e06981d2491e1c9a040ea3a41fa8a41f56492fdac6262640e97ff3e32147cac324ff65511103217f90fa373f16af4bc4c4bf842a7dddebfb5f4369a761bcc597c15c0eda880846930f46930fb2cd88ab412486d66ff822a5bdcf5c5da48358b95b9e7630a705b1ab15a14b6b32faf33b9e30bc0e219e39b0b6f6c1cc9e00e18e1ca326c768c831e221a4f5d8b93ad88c3540d3956cfc0a363e4dbd281b0584be3bd996b2bbcc835d92bf0122a9cf8b6f49964458412593b877361e29f8008feee190efecf489fd3dedb665e43eb5b911a96e39df4e921732662286f9b9130d38e1b73954cb9950ad2018b5374a030259006c4d8ba7a802738822969943d31541a57706156ea5444e808a6a090cd02e51ab1767f34126182569b17590750ebb5f024ccc97dd57e1efdd0e45bbc1556d3f238fd6446c73ddb29ba8761377b8bc721212117500619ff99c77acebd3cf9e37aaede90c9b00b1a98570227596849f675286ecd95e1f85425bd8fecccb5d4fcb111beefe4597862a948887144e3e74406e8505d0c3440358ae751df59d17fc71fad1dd64333b691d26f64201c3af1d17afbcfbe9d25d5c180dd981ece52c6aa91f8a551a5430352406e390d9c86d557334225a57a8c15a88b22dc88fdbf359ed67a17da3ba58c5a6917acf9673380bfaec975623661b45a88122b43954718b7815a168054bca9bf9210c207b0cece8d48f5bc511d8e1c89c116e05c75d74e0725b36e724c0a1eba63f88a75f00e4d9697ab1557f6dd15f53f3376b7ac91a20cf1a20cf1a20cf06208f66e868868eb2e6283c77ba388be4f609221d0c37e683e7020f41a2b47a5609a6167a8d1f86a59e03e96a9781a99a4eb1d4edf31bec043e88ebd7a99f1da4dd4aa6fcd0f0511dec60b9f3804e433c254729cf83127ab5c1253704b280aeb3ca873bd782011712bdb78a9e69d5de916496890d9f0d5257d5f7283bd5979f19fdfefbc44bd5e30a00f73c057225dc545801bdbca1b01a8876d4bc06a29faf1b0436798bf7108fb152449483e10549da0b32eaba32d31d49e2cd001950a9688643fc5e7dd49be0be2feaa3847a863b0ae939f0dbc82372a196a68dd27b72abfa372d2ebe581478f64e2730adb727556d8bc5fabedaaa027caef556851893315ef6076fed28ae5e5950cb3bd758b79f82ca9a12aaaccce8ded55abbe2e131a1cf5bebdb9335b1575c07577f4775d572dfa0b4d9c8fd8c723f5bb96f4a742503d1a9025dc94274a63c97adcea530824dedaddfaa813b124857a89d72a0237b2c0a5206ceb2ac811025d2e8b65f284ce8278648e52f24b80a429a876816e9100f1b5ec07a47c19e1d10909c94b2e7af35c1f7514eda1fc5ed857105f636b1ab65f1765becff07e4eb1700210a99dc41421b196625e65f54682385df8185aeddaf7515c212b7f0263034f2b08c0c961486bcc586a4b4dd8f02439f15b07f0422345264b4ddc1a11b2662f05b80d0473d0dbf55b60d1da45d0bb764849baa39c4855bf00a7b4c80846cf727c5a4a68aad60b9d430ae1b544f6d87ae8ba2e248660d1f31a517b11d0ec32f95eb5cd59dd02d01a8de4c9e021976ba916d1cc1e73de37d4ececea48452daf995ac288acd01e0306b19d0c0182958e5b7c895a24a33a32d23186c035f9713029674fbc59bd5ca897e1b54b4cabc1e2fe3a7f2eb10d241a447f81a71b0ee1d31ea712379702337f471fffce37afed707fe33273c27f589f31d2cd1c71f3a6047918f22fb11c43570c63c8f935d2922ab93bcba228ea2a57e5c83a0da8ca81b614ac129b99d963dc58a14b606046a993610af694a821029c3a69e43c5805fce54381f69ba5e4b98b461530af551439f122dc63bb372fd4dbe747c902db9f0a36c29c77f826edd94fe370897e3247aa1e377097709964c262e130d22e6c79b657f846e8579fe69543b94caf019baed0bfe3169daff494199bb49af3cefc5dffc72b0a217fd5f195477d843132b742a647ae10349eb46d50969bace1cbf963478193f77bfc6e6ebfbc571fa38f65b7220e8eb7415e6fc828f5c5ca874fb429da82b7fc28d1ae115f5739260f6edfc314910347b8d18b5524d912c94492b9a6295045b465f6bc2e9ea3ac65701314e72daf4cfdb26b3aeea6e00873e8d3b95d574410e8d7114154a531eaa96573174688b69617c0216514b52c3ece20e40861a05745a2e467ef62db36e50e1984dfb91f06c0558a55d2bcd101d4637660a09ae496e80f4184ad2f755473e3c5f1d23f8e008afa3ff7516e586dcfde66af6cbe49af5eaf466694bf4a8ced8c647ef6e3da7be2c188536a0ad8b9968566de78b65cc6a1ad784e1dd6926e44bca181dabdca7492311291c55bc36401a61210dc1328f1146d293bbbe421a366bec84a7380131eed3467b411be31f7f461ced342d8b56a280c5572b711422b1a73420ae53444a52bc551e65b2dba0d82e2e21a95cf056f60eab9c0d07272d25cfbaf22a98fe6473daf57a667a52faf9154d4ddaefd694784d0a590725c31949bdd9afe330aa984eebca207be7a7992ce64da2fda6c3cd455e7ef89eaa65156d255dcf552f52766f6a5e836d3570f272ed77a12428d03d739449789864099e88c91df7f2327bd662576190d2e9a39d262c3cfcdde3ba73771a081de8ce4b2c0794a93b3cb0c953df6d5c267739bab72a4fbda7802aba3ee156358b33a79d3ceafae29f73f41ae5d9e9ead9a74cf274d6412ebab11050e675315c679a00b9fdae12349c4ed0c8a2f05f3b02b9fa81b63238253973ff713422fc07b232cc6033cef962b072e7e48e62fb23d6e581daa7be3762a174ef4c032cc6c82c0661c71208f2caf236e05e3b1fc9a67e02be8ec09cb60917201ed67c0bcdd9007130c2e5937e7553d2789a3d9ff3ac9b0db3b264c64214855996cbf8b614ce04c91dc73a452183d55891e2eaf2f097d733aaace27a92712156a33acba8c18af5609487099ce349dc0079033c98fddb3ce6bbc7fb695ffa9965c781ff3fec498fca4f0ed2452d08636d54961db4aa93e54a3b36febe071cc3a9e74338b14982c3b683ad40f1883b6cb7ef61c235f7ea6e103d7050700d4a15b7024473405d9177152ae58698cd618d4659cb05cd998537654c7656adf1674f87f271771e3f6b0c981406533943dabf14e82623590cce8633361dced84c3863c370469505e337916e2785174b43a5d8a97be3b4adb5adf2d97b5b2e76eeb5cedea7bcfcc608b3682a7a33c486658b9241a98b41a92f2a64bc8388ebc1e36ac06c0d9cb4726baa977f627a3d55e3deeb7209a741fbb533be7dc0cd743db94db80d97fc28afe328fb1c76b95d703c66fbaf1cb87e1b21c44b2aecb53e5b5321ea3e5914025cdb6549b5fbb7ea72be0e6dda4deaf2be945dd4ee3726910d0a766f12797fbe7d9f8582c33dfffc9de3cd2f8ff7383d5ea570ed4ed711d8f8872da97c7d49132e0c9fa7d8f360bc1db97425e155a0f98d143a4a308aaa14cd2e227a13256a034fc8c2c236d71830b54255cca970aa56010e2806aba617e54a46cdb16139f873677101c05c59fb6b9b636389598316cab1b8c75a228392274f9426caa5bcab360dc96c359b4d92c6556a04488eac456dde3b0c938925af0fd3b2a72ad28acdc8f186729ca3c4970a5c4856bb5e4693ac7a8f1c88fde8f058c0461290ba548126289e6096adcbd31309316fc7bcce536b06c37c5c88d628057a329fceb8b1f86f888417a4f990de9121c1affa8b80c1d8a93f353dd61a5d5c456fc006d97641daa03c4aa156e103a634565da821a209acf42c282f4188db024f605dae62d2144dc5ace083baed01a371d97a4d614d29c30d3896d255dee0e406c5bbf4540c5fbc803eaf3c15e98ea7e2dc27a21af263420b36f6219f9376b356c5711ae4900e4f4bc92ab93d00176b16f094769e66afc20d84262f96a9e49c519d8a13e3f436e2796d42f6cadb8646623a9916e1b0711354f10e039ea95e1a9a886be4cd8dd491e4364ff25a9cff4071645fe2036b2af6464b5054712177acbf4d2486059532180492cc359488a8ee52efd694222603fb38e1a8f19028b47d347c0add318454bb6e75903901b55bfbfe573233c6d732bd24ffcb307d13bf357e1a290d675828d8cb2c2bd39ef783c4a7e7d20c95bf7e4cb9212f4394eeb8b35ac4cc493b2619662c58da7b60ccebc209835349a501b2d7e2c493cb5b0a64f1e1f7ded980c84d473f6fc040c33a7d65e8bada19cdc1e9d7bd2f39ae3944e4e1b3795976c68d40e966c784b79c242cd3f7fb9aa28c305a933b4e0ba7b6c200d5b4f944e4d9a332b3939d0e735c0f4decb887e54196c27352d4a44660daf863b530c210ba9bca563e1c70a255bcf0ce5368861f675167f1d46511e0fd8efff4929ebc991a6b53cd63278a56fe53b63d8b6ba16eb2d3842952c057dc640b6112dd45ac478bb7d50df765756364c194bd769157bf59f9f1cdbfcafabd21eda6bc32c6ebb19760c30d5cc9c303154180fe0aedf254f32b6e72656eeb59fd8fc0fcb31878bdf07574e2f5f1e45af242f9bc5d10ad95a46603f06132257ce6b149f00d5bc3d170419ed17540f0768f82b155be50657e05aad1c2a745a2a547f28e09f386af3bb331f491bcbaca763d4ca8b4d32ccb38ac2a003ad3254b82cd731dee2c5a08f5fb1c5acaac5b15a3428e2018432f40effe78041f668141942652c2a2894486c3381fbf44ab88f0a450e518caa62542437703da775c0891750cfdaa8a1cec659083563802f4721bffb4ca8f3fe6066389f563e210c7d46c44b928c458fb8226f52055478aa7210195270535562eaa34c77eeee87cc905adc6134f548b51c5c4419d8cd1bf14b50b19622a17457e32948b4aef4e061dc6c8cca21b1417f4441bb3ebe618b4cc41535d2fcf5564752ddb3b31b943b556b77b6867119bdc553b8f92f67f0edaaa8f8da7a9a85719c31f266442b2706c5ea20667aad6c185c15f0c4050dfe8c1f34a8c64cd00135907410975617ffe50b210b89fa74fc39ef9bde470fd8e863d83ab1c9ea5836c3c96371200c06de4b5d24a3cd5c68d10887ec07e94a48ced32518046575df0012cfa3709e090759e0493f6c4169062962ad53a0c156542d682e967e038cc43b66032acbec622622962970a91edb8b7e552addb5cd2ef4a381af85cc0595cd95b84b4d9db28af6c0f0aff0d2af5b55df09cb584041c505188af7fa8dc0bbb04ab628a5b56574b54dca20a3cf811ee805a7b795f6b1f477adcd4db830e9afc025038d283766c33614ca5c605dfd2e37fdba6b5b5169e47c419a987a849853e6ce1e4bac2c9aa467efae0569091f28502ec00c9450dc941c62c81f0598a544296ddec9912b148a537430b485495ab2269e23bb68ebdd7ecffbcbb6ca00869d6b44a465d32807a35db7972fc89581e0c22363da7aacc3917e63805b26242646f719b02917ec95fe95a39b7cef52c30e775a69a9a1e43d9ae9241b69c99c1e37d33bce0750122f25c75654044decbb1bd379cc74361d76d12c3f41e664522b0dc2f1eddd951cd92a06956ad6435bf673425d6044e521ec060562d2ea0fd4f54d58d2ff76ce83945fa0cbdda24ff627183509b84f2522baff9b2c6a93abb4971995c3db3f5c00835e87ae6a21724adcb6e2a90f925adea1cfa713765558b3765d52e4d612670f957289386d3cfef4adfb67ce310b4ed32aa2c4a386715d9a40d163638ba42d9664c00c81868318a06cab5747d5dd74950b26851b2a0c30b83092f0c185ec81f4625cc94186079b5a920f53dffd244dcc282c15d7891c637448d187e2407b7e7a19a7252ffb668013b620a8edddf06478b3abc473fb7ce807bf872576e0214bd8096487ac322643dda253042e4291889372903f77c32a8ba99b8d420506c90c129dd168fd759dcc56cfabd1a815cf80e84c945835f7504a3736bfae670a4757cc92574ae757464bca742aae978a65e44683f46f772fe38b5554c6a578eb9810ef6526d458757720664aebbbb66a559bd95cbce74a93420f1440862774134023b19e2f1434b659e18e65419361a73c036c98417ca7305a4651e5503173bd6ee8e6163deb4750cfcfedabb3151c9895a8da8fc419465e2e7b4b0486e31a24c5546b382f3861b5892ca5ee362db1f41ff202befe30f2fd811a039fa98823b90575de63ef47ae8099d9803eba50a2dd676899780c2e78ca79ece18f3a72dce9364c36367377dd4517469659960041babc0b73d4af449ff7e561425c7ccac86985760d690d9dfe392961e0574833ad16a5a68708e2996f86355dc892b5c6aee3425d2c0e0ca0c6f72184916a26659c10b9ccc8e244994e19b7346fca306a1da92ed574783d1c2124f7990e6fa3c7f0af82939a6f58705e3b8686bce7dc2bdfe5f8818153218abf285fbb806aaf0e123758439e18d0466478bea0530d51271fe657660d0fae3f5f9763f41cbfb088dfd694e778e6a1bcc31514d629482389ad03117a6a672e5c70e9d64cea30bb8f2e96d35b0cb27cf743af66fd8e21b30a151644f219470a0ceeaf08a3dbc32df253fed61af36f2f02a43c721672a6a6efa5a3af2c564f408aa0e1b51ba10c0b141948a278f2867d659845b7c255bdb43257b9240d8bb427e04c7bb30276fe378a33bccefb12853bc65509a8e1db213ff66fdd6d9c45576585e5a867af087e80bd95d9435487036b418256da6f0053ba6295540e6a86648d516963fdc4ca29fb2b6a2c695e67034f58326c3899233f0c961447520fb15a0aa2836d5140c0c07452ddbf0728e1853e8e88d79d8559460311a30b8b687cad6aa9b29c165c5a406be502feabd48a549c8ecaf0dafd41851cc0307d11d6e32c0832f619ec1820caee9cac4ac6ab09f3f26304f240d443671cc53748a4a01853b9e3760d50a9113036e740f9550dba56a61d129281f27d9cf30d3b57925668c6085bb405047ccd8711888de435b268ddd36669b8df032d4cd9cf22fd6c90179b981603e3a7670c1a61927e1201bd9eb1484fe9f60317410da314404d7d3ea092411bd4a40784aa6590c5153f9b2ad122ddaf1a52077bef0791f9e89ae37200c33c0ba0fd318348e18844e6082526e1a362e49f3ae0513618bab9ac12f94e04d2914d37ca53ecb12aa13cc4d9de1dc54d56372509a4e81281efc3d5267b8b7835c33a41588a82970659af2a8143cb2b163c3e9d91037a87d4e4b40926df65a343b3a9be8dc964a679d0dcb6926c24b34d9d7edb8fa41cd8ae047d60a89c9a872b3408ef79267e1930a88c3a6e2a5893e36989c58a059523c48b53c302f303540270f8a2ec0dedbfddc6cff7e49aa99fd400e2558030196cc29419dc5f43093f5c420af5f718098759e52c4e4644ed348101fb1294c735607c9475b98c454538c9abdfa5d4e06617ad069de4d44cd3f4c164b82607decb23c6eab24cff9dde794b353a2fa029d0e45464072878a78f2eb5928c5da7caee06d3b5f8c77603dad4aca55d5396eaaf3fa43771b263119d46238832ee932b75ac40cb89213c020cb841e0eb7f86822e55769ca51147340e1a76154696b5b651e785c1c4acc140bc337c8629f9dacfcce842d0af2a30ae1ab6e72f5cc580385aba6c2a34ca7248e129a1d65c6f7ec8749340c363a5c8689ce0e231debe630a9b256bf8e423d091397e60a344a4276964c5d9069d6ef450b976c4cd5c642b06ab23ad6bc773f460724dc937b8b0eaabbd83a92ee090b668d4a97f5837450689800e0040f23272494d02c21406595d3331bf90307159d3ad807ed6cb09f8b3f7e5d637aeb9862b83826baae9259c8fb17de3aa64b62a0db1a8bbdad31bc754a97172bd3c58a697395d2b17359773de96098f0003b8855253d8b19439ead2504eb1dfc31df3683322783e88cc59db2b6cb7f1f9056dad872ef4bb1d5ace39e01c92dd60b893928860b55c82769a021558d1d55d98cda194223ce9ea98fd3d6ba667a949bc61025c3460e163090856f03fe6063a787ec146b1061c4fa98593506919b962267a606630e75811eefd285b77194fe7006d7b954eccf8ad9a7a8234321262f82c544ea95ad12e87506477e87cccfa6db6cb0d5558a722aebfc6dd6ba9f058e55d665576eab310a41e14b51856570c98ac6905b282b2b317842c33e1b21081cb11117e10058a9624a85890d207814992a197e7963e7bd6624af73983fb3c533f1df178c830efacec0a676ee4039921d213bea5ce226aa5a85245f300205ba628b11a88180b1d08b3521c6817ba8706867ec4c84ae6cb97e48ed30796044424d975351d6e24c23f179313e154945a73f8f1c6284a64d9228a289c5180d149b854297f233b4f04a8038b274fa8e239f4fe7eef61696c98687a905e8e116372807dbc6ebe34b85cd31de305ff5128ad363b2ab6b1e569706df412cb27b9cb5a7182510706690b19292a2922b7cfa24208031da5ba107fecbee9e46694327fe1ea077071faa140f7783397bc9bdb866ce9cc80ea67707e23abbcdde4ab76c918ec1782a21557ebd8c9a62a39ab88eefdb0407f2f5b3f65f4e0882052c3de3a30e512d18a2eadb7988f365a06625a62c3529a737220d3108403b66eaf845d0493ed010b606f087d24f77a8779a59fe26fd121cf68d00d89acd4537f52b01b9f2c60d8ba246f7edfd3da2c60a12cfb97d97a247721a2869ae4a5ff0a435001db17c913237b7d0af1057824f771d2636ca623f3d1877d7726396c9843542f89b8f8d1fa044d286f75d6576167d4d63839f57e12692d5e557a1f75546ce7ec51f67e45d0f8be61aec20ebc011303bad72e46a447f564dddbd0f63fb4d69a193366add887b6d1293c6631422a8d7d459e6d7f52136acca9f604f67b2a7fd4d7b5ad59efa5173daf81737f6f4581d00ee04b18f99a639381759e153bd5ea72ac92fdb62d0f99923f5bdfb4bb93a3f7f7fb3d557719501c12a70d28e728901d35766ba984d560dc9d06fc0fa19700ab75daf057dabe25b3f1eafcafb696294f27e14a5699ceba1d0f6774932ec4f72fc0f84146637eedccba55c396747faa75282fd12f4e4dbaa5abec5704758575c18ae6e3c1fd35a9d3c02028bf7a99be34515e84362704b943494effbcafd18faff5d4def7b96ca6024591885f819fdec6be345bfc2226c41677c269dd3e996aaf65ec09199bb961635fdca2def93b550f68fb2454abd8702769754d319b8157c8d6e4fd3d51316c15cda56302faae2696bc66a0053bfbebc5c8343c3ce88eeb6b4fe42a49bf2220b9ba4750ec8de6fc8cd391e4bee762cda06704e450740fe59278c2a2f030550d8a050d3fef878e8d8fb03d3cf8e87493f2bdac2a4b001680126e967c59aa759a79f91ea46ddfbe7c783f7f2874479842cf5bf7a1abc7aa2e15fd535702bc7f2b59d8ba7c14d8151a005025caf67950c17cba5317155a5f9d3651dbd2ad18c493b06e7201084a219c8b987bd330f517299dca50fc021ed3434786c10b989a015dd7f0bfa33a9764b8cd7452cb90b0f208e91f063d5bd915fc861d848d9030bef623de619387bbcc1826627c8045bac5b3d2a078d26d9f34ec605318884a68206c47e4b8dbc26ce084cdae8748fd4aca29585cf154dcdc3dbba2b29be64719a465e21d9f89c00d0851e492d59cdd3afcc8545ed4553b00a549a6631857a7ab2a7c2862ba72e774ce2f948ff2353730d80bd65da9ef509d3e351c539f7e25a7f67bf4f882892689ec45c7649805f182a7072e82689a8b59f67c1a86d32d30126735ca4c0781bae3f32d9a3e37e6ea6247f7de850e5aa010013996c0393252e799381349b1da0f5d3539fa293f4e1cb84190edc2521483617571c3436970418739e9b04182745b88ea796ae20807efaca9c72dc5da71ad33339b4e5ac773151c4b218a6bac48c0603e4c08e301c9f108454b1d4fb8b0dec930f541fb92d066ed55a739da124af375bf2d4cc19bba4ab03d6cab966330cb96a2b373a3673ef255145ca5ad8e451c00636960ab07fd3cd22dd2014061c0d94d04fccdfda6c2f31149003722cad8785cd9fa2ace8bc76db7089606249255655dd44d4df01f2ef3dbc21d82b392aefd3a896e14ce0ffa2471364d959e3f2e0c5a39395a0d495e42fa393f6cfeedcffc49db994b83a4f5f3b05093845ec5345774fdb8c1ced56f29a134ec4d9287b1f73b2ddca3db09e6bd7c6e14e1817d6392913ecc12888af5615fbbada795583ecb8072f41c38843edb95f6db9543442e1d6679497d6def0177ccfdcb3ea026463d9ecbe137561e426fb24e9b34a5b384476509d061f54a25266809472e7a53f3ca4d74e5543e7e98d6cb4f9d8514d6326209f8a8e99aa2db0b6e5ce343c20a4cd24e0597a7d9325bc575ce17642eb8e273cf5f1f374d693f0860f24fd76aa8d6070978aeac4d99e6b2bf3320c6c1417fdcc6c9b4deb9df52ddfce567f4f758f59b32bc8eb156c4549b3a0686bcb79bb10a8ab1ca68389b33af24886a5bd0738c14191966378d60b5795981862e4fc9c9a35f47fec85ef38f657528341ee317a987089312e83f2f4cde96e563bbadd44d0c69aad2b17a783fa74c6b75cf8292873b7a28e7524b321c1261015a5a2cd1c638a615f6bd4e5033b6c4c4037cfa4af220d0d76e1952f56531243cb9d591c72497ab48d93d75d19a35a4653492e7b05704b78dc53d88164261b55230d9b6c2b16c76dbf5ba2248eede226fa882e1237cd22af8254e40d1e16377c7ea5bda5e11a567b83908ea20c0ec80d0609312a8de7ab6b768b68a33fd5f5c00331cc13f79a6e24325869e715fd310b9ae8dd4ec7bc1a66d4b3d820076615776c8ac20522d5b497e39d4c7bd4ce9fc38dd238494cd63e20ddc6fd0de08e910b332c270d2d43de4f47385bfdb4568cee1867dc312f95e6537d75086b7f6e6495744609a7cf0ba746dbd7e5f5ce9f414c08e238174de5cd23b8dcc5a861538ab743acb262fd162ede7196d65b747cdd6da3d5d777623fbe67b6fa2630b706e46f78232e4083c2919b41e165688b692d2f993acbde165af6b6d2b237a596bda9b5ec4db1656faa2d7b536ed92ff5969782cbde4ec11b5af0de2415f8c55bc7521eaec6c3f67758ac0f209c1398a6c425881404ae43a4eabc72eb8bc0eb11ac875015c412303405b8955fd245e2da0236d195546ea3640cbd24a7396f926037edf64e0dab07fa13cb8f9bf6fa97217ab282ed3628cfdcab89ad345605b0ecc11e74bb2f7efb5d413f4fb660aa39310d55f3add0a749512318b7ec745c90b7c1c5c504179bae8fed6122979b8a5c6e0f15b9dc4cb837762f86620ddc2836c96da356f2c80a31cc1f42a38aa4b850d8d8d4513d15843d8916f1e2d7a60128e56b621fabf792f3f70bd4c1b8f0373af037c2dd0fafe6d7c9a2e9d38ada836faa3f18d7e1b77c8b321665b69c8e555e68c53de8ad2ca561dedd8b9a4f89e10e4b488653410ec69c0230532822522a4ef7847deac8ab977457c3a2da9862d3d2161a659b2898d16a98dee494f860744caf4a4efb2527c57b1df5e359894dd4d31ee37ee4635eb8d262bb416ad5d8a987f883fb6e36611b8496a7cc6e3d2fa1151c9d9d4c71258401c24307df130f0c3b6bf1f48006d2f3656a1bffc497e4369cdbf372256426f37f73b36714211fa6c710d2f74563a1671d07fd5cb2a51d919e764ede31044f4cad03a41394d9e39ed787707c28bbe749fa1c272b35ec9f62de98ff53c4dcf5410f65bc195d215092d5e8524aef8c421c9e7a7e53eca59f75c7e93467e580e37d92d3391253b6ea1ecc90004dd746387c6a4be6c4158757034c00942c6f1ce01e977793708cb3452835b5eb030c2f49a9f8173a11fb9694f6e571197d6a57e3f4a4a5b642d6d132e4060e5bd3cb43b9b1118a19e7f402f41988155dba7a665d0513fef24775b1e91ea95a94db75d43f9c29651c79057af3451b1b4e8c14df94c768bcaa3e9fc8da0d4411121f081f6d139f5db539cb052fe1afd454f580b0fab959c1c8da672bebc8ab461f2a53b34cecfd274f53ae82d885c013553451b5f8d0b110cc7a4a43cf852af415268b847954ed95a1ca63a665993866a003c8927a81a5d71af8d0d3a9a17da369633bc9d624dd09853119bd92edeb2538681a11bce5deeb367198fa296123d07ca0642817aa23564ef3127703986af769ed10b7d4595bb24fab313ecba63557d3ac2fdc0937f847dbac0807dde9ab4bbc4e3e6979e78bbe6918fe5f399900037c82ac1a795ea9f6d6f9f3ab003bce5661d2148639491c218a66a3296076cb980b6ccd813cca71252209f0a3b6129a8118d97f66ac963bfe069dcf34fdcc658b832fd5184e91f5913e639070158e3f4b59662d21308a03855c812c844a0b45e7dad01e7bd6c5ec21d07745c7dbf640b843d0270ab73b7f62d70d2f9ed8dfcd7ceb75b6bbe2073119896e4065d80716ef17cbe8fd02f6f74eb529410ffdd9b7c9ed39f9a75ba81dba1909a93f2757cf9a19589c5e67624c4d82b20c2ae504ebed4ff4ee210d74308e73d3f5cc2e1476756a7b6b84fe9ce7e1348726f9754e1b9d4d947d0d705a4012626ba6f86db855d6a42efe348d166c8ef5829abbe979f094660af6d56de956efc513cbc4f86e3d31ced4d8ab07f6d88fa658d8f903210be3fc91598a69bc9ce18cc86f2f0f3eaf98e1d536f6a0ad17db98e3c2d92ff6b187115c3cf1a91c66b986e9728e631fb9fcfcbc2b51df9560b259ac5b0254f528b508b47ba7a208cb4cc20046e015d18508ef14914711cd8f062d9d825a2633d2d5917ec324275ee1cd2ca95c553c408f3bcc8507dc483184a0f5c060f4c0807aa0f247c7bdabb76e0ab560a99ebe3fe8b372da824ae1715a4e452cedd9db3e3f76ad2f7bf194724ee083a8f6d7b46fd588a029886640333c76cf9d335f47854a8c0ed35536ef77d935e5100cf05cdcbc4a08c32be477f6be8e759d7540a8719f0bf46d030d10933974be1714599a395998d350c081e14b360a99adbc7a2360be0515220f1c24168d3ea305a4bd75109e6dcb0334407e6e9432fbb2d371162a3ca8c5d288c44d4b93665b4f6f37f516360b3539096c3e55b7b9ffaff3c3e4febf541e54fa2841b3edb1edfd96da77e5c51284c85044e616c036faa500ddf5d06bc8df1de19a160759c3374ebf9fc4e0e98ca54743f4ac012d5de5fd6e7b8da29f4e0b8666fa05f7fedcbce8d458019608bbc9ca39bb17d55e00267b5520180a682c15cd6c19deb2096ece061cec601f8c183a0fb008aaba3ed2a4167072eb97ae505b3ab0d9d9c2af46bfcc0d0a3d739177c6e7190491763997af65eaa518b59537cf27dc430877f3fdf7be5835738534a3b37690f3fc524d5dfbe252e5f8994b656fc96fbd55339e28fc29f7aaccc0d27f915b35eae0bc8ac6fcb67d43479d20a8d2eb76c6dafc39258ba63181b434c368d7c1f3176deadc8ac99376618ca24e147503df1a90944bc6a619effbf50c4a8a865421da33be1cea88a999e3da5f6aa2171be36f6d0cd69ebbf68cb475f433d362fabe6d44222288a5099d6f726721962a6e4ae95ce430bef231203bab8fa558a7b6ffd8204497d98e1fa0c3a33e548df6d1f629aca317eb90f17b03956b5af3d3ab05f38a9a0d8d6667db202e372dd0fecbfa3b17a90dd53a04d1a5e13e33949b069f57b5f7ce4ee42eb57c0b6ad09156afd8fb393b1fce93337efe2ac5faf4917db7eec6eb6380beb1d753500975fd589ba248e35186e26854fe0c2f0f05035017b57adaec825b1aa37e17e62aaa783892aa74990e2a373955c1082532ead416b4c382024309df485285af8a7ac1df9fb0c4283dd51ebfa43fed28b82c7e832123c7e8519445377e93295887bf2c5e0415ac4babea5147698e381d63d37f40fca2737ed475fb6fb2967453dece6025a9de31c593e4039b521251bfee495bfdbf66c2e251b1b8e22185a1a9146325d09bb08cf18c9ca19a45a206a4dd61d31bd13a5be793baf3cc863405d74b8b661729371f22ced4b1a14031dec7f40cf3b23ab0ec40dc7797ce7cc06cf84fbe456512e488b3ca9876dde3bc3c48bcf1a2c6bbe3f607f40326d21dfd15b2b44d9c7b7e00bb7f3e92824355307fe3afeba57b80cd0f8a70aa87dcd82f9ee24c1d1da7c3b1652143d85cf7abd5c6ba4818d95682223c175630ae8e9e495564a8d16a46df7690ce19aab0b35c387b4ebe35b3013dd8e29b744ce147698d87a3bcc73a551fc94408b3b993c4fb4d1e104f4afa7e9945a459f49dab8152731daf6ac413722aa7c2a55e9c491bf6cca79dfad0ed3e43de37b77f98b0c0df91dd0766f783c13b095b0276df116aa7b394d3fc9fb456116edfbfefd562f3fc9fe31233ccecb3a4b83ac5dbfb811ae66ef97923c6944918f8c97c2ba91047d2b9a1fdeb6b409b07ea19e5cd995fa39fbedf0cd3c6b7531b25657496506d6862621192f5f9ce9deee597a26a32360cfbc6eb9c173949627bf7fb66084a198ff1073e66140051cf69f639653af6f4739c57cfe96bd0ef8d02314171df7eca501a78c4af78e0bef40dcb4dbd1a493643ce78c382f58f3c76adeedf0f59f4a2c1410e430ab3a6db209c3283d359bcd479b494a0decfdaa1a4eca5beed439a636a98a5f829df65d01a75f29e4d6d0334ddeb6fcd4770e87aa361b928807b70d23e7b75ea8cc562c9a0187beff51b66dfa9c94e49082f8c3d606d5a501f5392d5b2f888750eb34d72fec2fdc41a6681d7119815537c77e19a0f450a562f99303a47821c7fe8bc1845b6a8919eae5fc1ee1a1381d9a79267c2e9c4beb0898e4648bc4decc38e265ee72f90498529cd1003c91fc7d55db3c9cc0d84c96da2184679d653080d909d2572296fcc8de750e5b023c55971c80cb3b87527a095a53b2b845f99e81d56a42108aa9c041a45137a2580c0c61d2c96b5b516955ff3b81a7686ad9d19895f2ac222fa43dda0eb4b35c44c2552143a0cc9d952c192355c5f7649e21739b33e9f3f3cedae0ca5142415998b6d137701c81bcc895ce85db9597023599680defc652c07e2e6f4266a5b7451a4d9d225614ad0f48c94a8bf3d95965d2b8303069748d550d699612f0c9a59daceac6f20e4ce8dc64992a57f3ed1cb65c5991c665695d65c9704f3f070452bf94cd444a8a5e76e150142e3df5ac6ed3db0ab7a7db29b3d281c1dd059f6f6224d62e7f41e12dba9613269b2df05f05687f2bc06a91d6952c70c58ceba80828173778101ef56deb892349a71bc04be4fd3fbfcbad34b40f4a7f96bcc9725c2c75c94736d4a4773ea2616870d08e1cd8d8ac5dda009e3c6b843134f4aed43fc3e9a885fa851f86d2271fe82484684ba2592ef075a7505fba96947acacdea8ae8310ce49fdb34da3a792140b282fb23e874735aac22e5ac633ecf85ce76162a19b5e76357524b0725590506a01fc9bba3baa16d64fc61a99423bd8b0e21cb91f8da77709062a28bc877a527bbed328f3325224b39f586fc25d2e4afd2b7acb8bea40a775ceb7155a862ebd54677aa1e3f7bce33365bb6a6d5bd96d6fcf2e4e53f66cb04e4e15ac86a37c63b49ee1102f0c8951280f6b29b86f0c37b63ed4f3f17add417009a6f49de1468e44b9585ef552b701337dbe7c765cb86b37da936356c95448df2194919c122f467b328a7a7c66b47972fe15614a864208e93b97943b4d5d1f5dfbd07871a23aa7a3f57459f72142e967e72fe8f24992cd7f6a2ffbd9f9740117c49153fac9a3bbe4618f5f2d7e8630294cfc6cac27736fe943fcab9fdb9528e889712deb9d8cdf3b38775c9065a3ec5d95c5f39d8373170c8ce2bc61b42f2faea3e31734d9cb5db8a46f5cf8dec95dd02403eab2b42f0f36cfed42ac8ec57d8a798daca2f642ac7aef3e76e5fa1857cccb7baf4fee5b77ae2ff08a9b78ac09f32dfd6b5a2326bdc469d33819d33819d33869d3386bd398fc3160d3906eaf8b2bea602a553c81031c356017a5985d42f3d4b602956840ec79ad675bc8fa644b05eb141540008a3cf524cfa807d91d26a6172a4fab0a460d5e6f421c4f62e35d162770e6fa446f34b456fb7ca38335cfcd376ba9a61591c210b0f9c069097bdd458748b6bb63c4d43ef451c076f7f05ab5dbb41358c6289888aa70fbecc404b494e8d7221f6593a2a6e814e2b510994fba3ed4829e5fd4966d0f153b191e2b94bf7a5e6c751fa82a708a187443c99f577fcdda66cfc666cf68b3670bf9246438e586a7070ea75c24bda6d9d4669b0d0c3e9b03e38b6729360f9998fe451f95ae895f85f8fd07cdd0db52d3483af0ff52397ae7d7c2bbbf497a3f98a457d8aff2662e5122b4313cb611f7b3023a7c61783ba5844ba2965e611655d497252e05a94d19e1a20e2dd9fcef4d720fe9dd16f435d39f211f89e6cf2497c0ab736b45e349d80af1adb4a29b68fb101fcad5fbbbb28cc2dee795fed0dcbddd74a7b3227f3ccd88b3db54a5f76e74d6f0953b37da4564f72f7be796b09dcd8deb13fec36f9cfbc7b2fa76045cd249a3b93ff5c2f5fa017e77dfd2813134741818d46f7c5edd5a293b41ee558cd0ae146fcda6f34b92b3e2cf1d44190452bc830c5e01a9e500ec6dccc266aa3aace6c554e1bee6b24e143b24f144d33ad17163b8e0abdc208f796a6427e2e46f2d35ce8798956a97f6c54abbca5871d3fbedf6719d1b198dbbd505ccc17c6f796f6f102df93e296c3648d7703dd9a06f8553781343176916ca473ccc0f65728835b39845109a9a502f7c6e45147e38abc47871e5480cde586a8fb4f545198f75eaa73d1577fed6b9f5b7739a8edbbfcd1fcf3803c8d712313cd26a38dc35d2bcc4e8af89aedc7c7ee166be9470d05f560c62f5a61c611d21cdb30161959a79dc7f702cdcab8553ed205af830b9bcf9a56fe0c2a66d889b6513f848259bbb16c194ae12527b2e63a56089638a01e28103bc4c94943053c6bc05053c4c7f02288e8bcc2d0f61b336a7eb6550ee8594ebf60953dfb0c3fa28ac3a7bba8dd6bfa6ec5ca7a47b4740bff71069033ff7ed64be09b4be0eee38410c86f62077fea9b11c01afc9ecdf66089f7e7b38f56960d8ab179b8544595f6c11dd924430c402b95997781b6b639897a18cc7a2f838c05e2a2344b1954db630dd376ee92d04b209dd544fd395f9b4ce8aa63f28ada234f72884b05b09a814cf935fda28075be4b9871f415a466f031e703a21688e2cd92a9d1bf594866679f0483dc8192b85aa5ed4bd3cdda13b8aaafa84a73d2fe7d19c37f4f49aa06cc4af6378f2c0bcc8338aa0bcc1dd2ecebc3387b92554b973ddc04929b235639965d93fb21070ffa81dbddabf7cb27fc6bff3623f7bee69dd4353be9c69e0afa3fafc65dcded94d41038a6f46a640e0686eca21a520ed821d9951d67aeef8aed5e62f4740cfee713dc220ce5da498df1427d5116f87ee583faca181b04b69990482749756620cdf495cc56e7ab847c1d6ec5b89782a1779e1cd42c2c4f8917ea9d03090ef85a2ad5607fbbaf10c8c3e41e610eb3cc4eb5373bb538ba6626d5461787bbbd8590bc4188643b486c75254f662adffd44916cbf1b3182c7c92854ef21b878706c31fd520410ded3788ec0de3649f518372bc69eb4273a2e197a032b57d7c4f8c6b3a620ee523686a5793981b9430470aea3cd1ccf973524b685edbdeb2d29a31e45e567a1f0514250a1c0ef2a061822651fd0a5444879e2dd5a34f816e61653958f929948d3d5a1634609a2329918b8184870a633e388c394bf7666eeeec964e73cd7e17fdd94edff13be591466b42594d551e71eac43cdb5bcc2de51dcb418fbf2f7fb474c03d0b7bcf4592f4b3d4de99c41c2c3123fe19888087066300d47d35998bed3ac9092b69738a4be9f8f6c0e025958446faecc660a80fdd8e22dbf2ef7bbdda3817a308e917bffc0734c9a492cb451347fedd35c9623449829c2f35c7e7b5384ed5f09362407f50438968f83a0ba05d7f0929e51da01e56632db53f18ea62d4d9020db1273f51972d1beac805677a51af65bfe743d488e58b8c6898d551f84c6eacd11f36ad23ab0ca2cae50e98295561eb3bd776969837738da0f914971b29b44fe98d218b66a25920868b96b71918a77d3ed272219d91b9061ae49d827aaba49bf6b82ec5637183fbf638d8dae5940d5855fcc41a57dab8d9a7d876fc3c0fdabccfcda71bc92d9765e1e6e9853596f6f61eb50b5b6448d8b99b2e4738d6111619766562e69dfdf72de324ed628a2ed750bebb86f4ee88f91b23b659fce9d3adcc17d59c74e553c53c91a50a114e4a55069700d4dd64a799f03eb78f8dfb2e7072897c92ece8ea7dd923a1dfd373f2bf959e730b719c810d3bf9e61e3a720b245a7d0354d240ce35c454260b3975486f1126a27b00987a5a6f99d561245c787bba65b535ce63c97b21acb559c1ecf80177f0f5605d68fa4ba199153d0da119cf28aab173ecb020367a2d76329368ec0cc1fae2a6440a3bac7163f773944927975bf43122ac76dcdb7f2b42086350d742c4c489d1ed6ca3850c3c5274cd108e9688c297f769eff27b2cbad7ef4401ba1999193b2e2458585f6bd6095879a3078e0a856e2a6489755328a97f26dfe364bfa6659ab2ace72c99d5632ec45a0ce57ea5956bd0bfd6f331b605573014c4444df9f6b3f3ed2850fee27cc763adf3aefce88ca717f94bf325604f7b232f9ef681f976abea82e8ae271cd65e88fee709f838beb3c14e53f0c565f814011fe9abf32d6e55ca2e6ec367e8f7b8a8f6747ddfdc2698fd23a5a32ec9b75cf0a0ebed4d5aa3ab7ecf7fbd2a72623d2a12a3b08bc6ff6e1deba89bd8facbf04695982613bdbb913df8230a32eeb8909d44de42f2d8a670aa891453c95bdabf5986df0650e8f48661323c36b50de70d694d7ea6ce350c3da6ea102cb75538a58392fb154c0767e3f8b89f9493ee051ce5d3e8c079f17e059b850999ecb93b91f3ae9eb44eb53ad1b581f62d57e2db46da050a653d8936a4e116103db388c26a846d9eb4bb0d6719754dec7c04fd660c7a3531d47670520afb7d8feda11a6393d4cc14b8458804d536875f28020c55a9a37ea44de9e4d71d89e91ca617822a3f74bc0244be6d3873ba68287b89071ed13255bd85319f5132c6480163f957a4f40dfe492969ae6df542ca951bfd8a2650d56b449ada8717a8f617ae849bc133e6460c746546795fccbe3aeeb0ae26ef27ff4d41cf16aaf1bd9aeca5343b0e16666aca54347162d2bdd8203564aa91ed3a87b559d1804cd2aa730dbba6c809aa85c32ed346157aadf20182a908e0d8e5944265daac533b2b59cb6f0b16851658c343e0661013d9a842e3fb87c09b2350c0eb1f3461774d4bd5a6a3e1b75c2d2353dba96212fae62912795049c9ea2954bebb37abc01d3a66332e6a82336823cb13c641ccd039287c45ce03ebfc0819628d39557e66c59ed519ddde351f763222a4135e7aed4c29124cbc619d838f5090bb97426d376fda32d5f1c0e0bf3457b6558c9ab38b5abb53a9affaf598bcbb0fa0dd881374b320cb2dff479e03947c39873e6a35fa68b8f25d490cf26793c995cf63a95ebc2d4729e906e206776b2414e378a488faebeaa8ccf14abd9bbe82397ff3f75555990843a46029b86953a4b5dede640a3330d166d7ecd28330fa5f82fd2152e68df46b39467f1a70a0739192e195b7e27b1b85c0c851ef0b5ca6768d62d6bc5104af74bf4090d5b6480f82375faa0d9ed727f774871e3ef0d174245ba3e39fac9e7d6db9bf8980b00feb6f09edbf25b4ff96d07eab84760c7bc56cc423fe4bd6d07e2144725836fc6f25edbba43140aae4fe6d6a69bf2096142f88655f51fb5f8958ca6f2096fef215b1fcebd1879bc8de9bace48f4e0a51434355b711ed6f804ada79480b1f4864755a0b1c75d61c1c1496ea9a41979ef75f170952948f29bc9d26dd4357eef5089a86e0c6708155fe7e2e6e7e6b0c27691edc376914cf65535b51c1b6b051225b5bc137c52830693aa2049482fea43c17be6eb33917efcbc000fb2438727b16fc27e0364a669defa874da001390dce5c0be4ce3f70e233abc298a6ceefb3e032d7b8b0fa3c6eee61d36de369a867454cc9c3e9f255a3d491026b4fc8383f290591f1ebae1dc73e75294431afb1d8089f8d21e92f44340d3ec6696d71261079fdda6c0d81f9c23d03f4f8a9b66cd4dadd678955140accd69d6f6eda2aac8dab2666d59b3b66c585b344347337494c3c5ca0eba276d321d6a2bb239e543b2417359611a5bc9d871380ca430354b0f08ae02091fb1e4a87b6c123bad2b89bf006d2c86fa66be90b504d84d0025c676021e294025ab79dbaa19aad6f68b6a6ae3062ddda0826b652ad7f10157c64c05f990b7da103310945db3125415f6154c25d8f3e481d353ef9538a07b6a5b743e53ecb130ff2a2365c442010149d43bae84966d326354332ef2ea6cc23402b04b87906627a4004aefb284f905cc76c028fa53adf1900675c4f226ec991368b7deeb7b2805924757db42c927d92982097ba5f6c6964c9c289fb0e824cfb7993a0d82349c942529a64fb25b90116ed122aabda4dbeaf4ab0c459b46a0e1e4cf5403091d557552b0179078f938cecd615059236e98c0e5211b8c452727026da843a8154371449835bbb2bef251b7ae4e5ff1ee60a5e2bbdb1cf315ad87ba395623f4694083bc4d4c7026c6f5df03dde6914ec3749b5532c37826295c5109769dda0cbe05b2374e4e26d9b4d5a4cbf1bdb8846ebab737e229d8e030239ed2e673259e96e832239efae1da2f1883643701145fdb09a0fcaaee4c3ca56222a683651165b793ab1bf194cabc550eb3560ef3e3cd4ad3a81c26a31c26540e93550ea3560ea3510e236a789b2ad61b96aabca1562afa722615393098a776c151a72b379f5cfda5fcfabd192c504258eeb20d8ef2e7ded4483270f1a6b2f369748d08a71ed7cc12b399480b59ebe4a7e76dbfc83578e97ffdabbadf56dd6783f2bf8afb4f2bee43ed097f84e65e3857e6ab8a7bdc9466538afba190d76f2aee334f395dabee1db23ad3ce5077e758861b5a43f90314f71d9377902af4576bff57d4dab7a2bba780b9bf6abbf2b894bf9afbc7357709f5feabbaa3582ce59f53dccb0ca1f83754db6798e8b69a843dc90b4c7e0dac9cebc88a334010ccb231b48011b27a123fca37111bb741ae12061092da0d19e0307bcbccaabd716a85feb72d7faceea4accb6ef91c8dfdbdf5a7cfaeff555ced48eb77d2cd7bda53a3feb3c2715bb1bc352d8ce4eae652e7dcacad0862e214a4e60b573f1a93f33239b8b41e2e9baafd9af6154cde8c6c0d9185b4336d288d8b3f566d4cfb621dedc57ada8b8901394c10c8a12d6a7f6893da1fdaa6a6d7e2eaa7768bb64dfb08a435e5a9cbe3970abb2fd2c2f9d43bcfd7841e06e1bd2aabc8b63669d33b70a1b637c400869c900e8645599745599e05c85b5ec95354da5b0f65880ab2984d4c12abed4565ca80bad66697982c75f7677739f1e0f774b8a9cdd5197868250b25dc7993c7820ae45007461041b1b92fbb5c19b82c33b2722ea39b86aec83441e7f5ea2a57d15077550910b4e16a71c33b04693fbd485420c9b716b378cd351ce56c11bb8d87c4696480587b11d8e7940e50f53b5cd1efcba2323070c009329cf388726092703e1ec6d57f1949c9b126b68ef9ad1ff3d53d965e6f14f3c018827aba53fcb8dc89f91403d5265d6b35da19ba7d65968c87035a12552c6fe78a873c7e166ba22de78fef8b9682d69e36a73d8533a9af8041bdff029ad4fd13fa4acc94dfc24f8f94d4469fcbabfe61959714359c453acba74d88a6eacdf20865e9dd73d7fcb4c3977ef3b42b4cc7e5130a969f9bd874e0c90016f73dca62f460094289d659ae9e8cfcc6d5231c83f19977ae1e8589598563db65d116e879efe241fe455ba4a931c7bcd628a170819b4f4beba5bac434db7175b2af7f5e7e861b5916a0b7e57bcc68a8d52e2c81b67c9375bcc2bda08e821730600e0c97f78f5ea8675698935da7484aa9f1dccbcfa1ed999ac03143c285f6d06da8ba008364d648f6284bfb2055b3e11935e09438d58226c520cb9855c038b283b3535795632829c1e824331582a7ec65924371a27ff0099c9cce73a2539bfc2c463d272fc16d070b7edc26d68b86b28029743caf4396d5758602ba579cf5f1dc6e6fe7ac48d3a24995a6e6e450f70c5405dc9c9d5303823e9958568cf90699e15c93a76f2cfb2a47e7714659cf2742986f291aa896737338de616684331c253e1ccc280c0456c81336754e49f510ea9b8485c74a91a20471da639021caa7c69b98e69b38a7c09b3e2ebdc719256ea4c453aee6d452d31382e8fcdeedbec01def6fa874713e37d9c7307c154e26851b9f0e33c95e6f98ee073fc1577d78d20b0b4b87f29c9c4709e7155cc207e7d488d825321d3c491290ca52f1f24c7ea342fa03413068a50dde0f265c13f3ae83785032a4838a55548d5eb7a182e1d8a2bc263f6859cdd253a52abc9401054aa9a8e2cac3d229fa539546292e146a60af525d755e40d73c83f1087b74b3f6b05fa886d837c3073d016f27e0d504bc9e808783c009c46026c01d4a3d64be8c093805fb46d531dffa7da828f9a522eba1f40a424858a7482f51d638e6685739f7886c7dbbcbce10945d22503357e1d013086602e69c2904822610cd2e63494bc2baf19083b911b880a2dcefab1d81558a3699fc6e72432f71fa69404bead27832b7d34ce8ac2ffdd4256e2f4ed4da51944ea7fb0c6bcfec075c3dd75a60c8f8eb28fd38665a292182e470615c23a10714dc2d542421b3256d92771dba5ec3033beb8e9fa7e9b7ea2331f28939cd231f6136688f87aec8048af5d9ad09fd49c63d9a2ca5469883da6658eddce3b0d4055d1dbad72047b3e8ac3f4c0ed861f0d9f905ca023b2ca2431edd00a0ab72aef982de35bf78b17c5608f0261bffca85d4430dae6b798c9094b42ba4114ee2b8bada7ab79c79b75d547d95c0847156a8a3eff7dd7a21c321942f7d6573a5db2fb1b3ac71c887dd8db9942e5ff295afa4c31a71e72cbb8ac44cbb5fec91fe59f7b93dbee95f91e42a05b1852f44a8b5c752a2ec6ca107eb8d4fe53a16a3eb48d98664621032a7f3ed23083e582784f6f4878b3a93fcae5ec52534b1bc3aa253cce99c94c5a0934b825548d1b6c36121431000044969cf88332a90494abd117cd53f83da7eaa4865379ad95100d6277771ea5f293a68aca8e2f38532e202070311034514aad81593588d52b9a2ab1059b59a91b299dea9bd02c4685c9f64aa66d779a74a52d0a363296c0aaf1d065b5b0a3a99bdbf11d59df2f9d697493613d7a53ed77a974b926269cbae37d8f4f0fc7fa70174137b16540ebebdc1db26469f2eedaa64ad12b578dde37b62d5dfa891d5abaed139f6f6d1576275b826767215785232f1d1de06487b1b21ed4d88b437c174ac36037389f3e0677593b474ac5f1bf3b37b6d5c8b59ba244bc4a604430541645541ee8c956033386f39ab757d569933549f05146e54bb2a3ea00f9be76f94a5db91f2a77024b547b255466501135fe6e0973938330767e780f5198ad798c171284c0131846e61b986ede632e9e70f132411b42aad6bb60bb4ca05ccd02815c430368ca5e360726f4d42b4ccc5f047abd43b3b01a727e0cc046c152b05a2786b147b6760186fed720f544517006f2cb44eefa561dd721d54f1e2a0bcfe1cca90f4cba05e4edfbe0fca75ed830a3550f6bfc158a6dd0369e82a36999705f8920f97d6750a363edc2d56e4bc985228086ea64aba4fce5e4e75d3a02f109799d3540c97b7547377d38a075938c8a2413ba4c4dc533301a727b05c5c0b896d72241420e6ccc5e55036ebe5e76253d1ebf3ab8fb3d0b6a643c140793cf0ec27bbb855f02ed4dda6ec78cbd412e6c1c7bae32ec83114f218a302fe9ae63e19998f8af44d06900a1a9062fe8ce7be206271d78d58d7cbe323efab4d86393bc39c3700e037cfdcbbdf79e8a3e6507dc91df9aa0ffe1793f9c5818453b8c43c5dde63d9d8622571b2923859499ccc49fb602651ec248a9a445926918d2856dc5861cccecababa9b442b80f00267b3ac6de16d562f095f207a3589f5227bc3debcb393b08a89bb4ffb30090655155b184244c0fe86287468e269a97a0798b90623f38361efc6d7d0f4e0de695783b3c37beb16b2e22519a527191c3ce9f4141f2c880c38bc45e1c931a048a018122886048a21013b016f27e0d504fc32017bfc96f52573fcc91cbf9d40b213486a02699940343b50cd0e54b303d5ec403113887602514d202e130866078ad9816276a0981d80d71116d4e1fb39a13359300d4911f8ac3d6e793f662d6d78bf2e447ab7b858c80b286e924dbccd36f12addc42ff9261cbf2d98f73910970c10e72d12e72d14e70d16e72d1867d1380bc7593c0e220639bc4e4fc16f303a8bb0ae98dd0ab096b518a917265e165dac81383fcd4b0bfe4c154307f4a28a219fc32f60a654112eb04bb44a9b8f552271d87d0152bd98d1a7c73e57ac021bda286c59e9e8cc4312e496e6e955696831854f98c6ef7028d44d17bbfc2b66f1bbdc09058c30c7a20566d15ee36ce565fe88354683673d78d683273b78faa22156564525347b0a512d1e52efa7ee709ca86ad5acdc194525ac8a0a857ca8c10f1cbc9ac1ab9150c1dc4eab2782d64232fad41a0914f9bcfdc6b191515c09719370749c48a1466514ee19a43d84df0825031c7b8b1c7b051dfb153bb6e0f1821e6bf8983f8ea82a2118abbd4d1b887930a9e99e214777985a780c88a712577a1509ccceb5b6f75b1837c36529927a7038579612084d092da70e74298fd09642892591d2efa7c61f364c637e1a9cd7b2c86246f1d0b2a87865f51c51cb22f371539e38fb6970868998cfa9e7fa62e9c3e09bcc3e93880f0ccec6e42cd6085e6baf11d0aa856a705a86f6d0063db837b6901e7c318594c0b53dfa3420838377b2f52a9b9cb22990487ae54d8e1ff1939a035e097df2e0982af30aa4e3a1828a764ecc13d473ba20d2be8d03a2b84ea3b84ea1b85581b85561b85541b8bac95885bd1c1e48bece4979421ba0cb7cbf386e8676355ca70e4de23d71710d237832232417776a3b6bd3da9aee9fd105da196ca041051abc7e4017a013817240fc1a534b204433cbf027601d69165a165a3225d1eade958e238ce958aed1865c462d0c478585eb674fbb9ad3aee6b48b39edf2c9d32ee6b48b39ed624ebb10789d262216006ed5ada796ba1837ecaf4da161efd495df668feacc529375aa7249937e8a623891999109b5731293b5543b8155b5b3e8bdb00d7302bbdde41fdbf4639b7d6c928f4deeb1493d3699c726f1d8e61d67337416ccf3cc361ff92b45044e16f153c42604e4583c18be6cac64c8054f492c7716d83e68811daa5226b27663eba6e7e561dbc1e7d54a2ebacf124ea00b6d98c0797c950987b4d1902a1872898534a19036125205422e7190592bd72a2a72131429aa35edd585725d4460fe0eddba27c8f9dfaa5b03f0b1d5add3fa39ead6ac7ba7bd6ebd71e7b655f3b68abd336cdb2af656f70e7bddbaaa8fd984b640b3c2991798397e4cb7d675d50facab3e075f20e6f031ddfa4a955ed4ef2fead69435b2d3ad5f98eddb86cb4d89c2a0c45650222d2871e79428744a4c3a25429d12afeebbfaf5dc80cfe9d73ad2edc048372857a8bd129b8b8d98a375935a2fa9b92c8b5b48f944ece0d62764fda3276017638e48ef289f9d791d34b3cf8fa56c87d1aef9ab3fa15bbb793bbfa15a7ffda0b73a0404540e0f68318c292c8ce94b07bdd51f309ad3283411149aa15893ab39843525e34b8a75e10c20a5d406d82ebd59496d55521ba5fbeaeb7526b5caa4d60845f0b17fead7156b32583edca434a233ecc125733691fe181fc8bdf903c74950a07056ba29b6d1e19f629c0194c28b45a9d22a8ba0182a482fa9c0499e57e06688b47ae2e42618797394e5211da0f0dba6906aba5988e12c8afb8a9621958a7b99ab3a23a2a6bd983836734f7626bedc50f29d56f2dd6349a210255f63dca7e5fd40a5084ec2c86d231b93d6f27e0ac648064f46ebefe98235302e936c2a19905d705c196110b49b416d619fa93292a1520359d00e954fc73593a83c81be28d1729d94b672ceedf13284c5774da174e3b58c8efd83db761f4872092ed7adf58c2725a15cada4ed529b0b88a3b6def53388b6d752d28e31906fb0b9d219b54adad228464cac180f3949323c65366409d8afbbe93cff697ec3aae5509261c6bb1e73afd31d2e9314ac2cbf942c793b5d8368682f7adf2d5f49bbe26a2290fa353f0dd20e0cfa151fd293caf1618d954abf30b7a4b7d5b3cffb6ceb89ee4d71da1c3c59b4016d32d8a0e9f3c5648ad33ce9d36d1511d5f27bf6a4b3eefab2d9be2b3a147ddc94838f6393bbece1fb6bf272a91bbe73257f7b955ff831d181d203c44b6b9cb4d647ab5cb4163f721a3fd2077372379280163410b952b19f7f00e50643e61183d9654e1f536af179346d5d272efdcb99d387c99c2e4d674edff0540dc6bb664e73a823046443f33b502838573a4beec2aa96a32af3db8eb1f38dddc50fe13a508cf6b09aae0bac63b2f270e2011a095db6e2d78cd21af82e561870e7717872841d663f2937b0e1c6803d5360b383422d075d4bd5e892044baf09d701d34acdb0a8bbeaa802991edb82dfdebcd48fa0b8721f70946047e9c55a0315ebdf968c3f1e5c63788cb379482fcd48a1cabc5c27065f87a27252fb4195776685ff3e0b3110295e04b49794a1bd63ce5c2e8857db89b0603d81001a679f1015ab92ba51ad6a2dad93139f02adacd2330214bcca535fc03752c067a81d4464558d328a3f2589a41fb25d0d53cd1b87b36f989945358c0000d1745c3393ed277500543e2ec0a4383aab54e4aca6440134c82c4e82f70fba9afd017217c284fc9663bab7e79fd82e7fc04389a9e2c6708d554247862b8e8d22cbe2c666165386ad5f1c88a5caf272a92436f436a9a92b9c31888e5e75ec642c3a3ad554492d43e577cca4a89c55937335372e4391ae5ec2eb908a581903c7fafc13e7fdc06c75701ab6a515bd73a4210d6b4fac9a3103442266ec6790bb0525f33a58f55c4384bb07398193f62878747e41a9568e184d81db2b6d1b46c9af44f7abcbcf46d38864a8317927a9bc9b811187aa69ad57793d70db222f3b66f0bcc9497965d915ac367790ba437af7e1b41598e542cf5d7e4811b1810005daacfe332ed0c6e5d5e8a272bdb4e773eaf19022728dab93a16faf68bebed66da30baf0ab18da457d4e1465131356516e15c6a2d0053494c97f240741a8ca966fd800a0f2886b0233e90984536cc82ecec26bc02af664ea631b4837ed3eb4dcec859e462cc288889d1a5a47546e0c283fb805192d01e15321e6cfc801a589d3f47b449d283ab2a0231147d88451f40087a3fab1202c7eddddce11fa3fa218296292c56d46196ebf5fc17a9a3eef1ec729d70cebc273c05d59d7caaf16199c232a48c7038b529de9a319217d08cca1c5996ac8c68cbdf2dd7c0ccdd0bb6e12cdbf01f621bceb20dff21b6e116b6e1bfc736dcc236fc6f641b2118b6311a19dd9047b2080ba9c46ae4931637d15d11cef4e85d10cea1a54dfd08d1542d69c2470826182953bf432cd54898e3f7124aaccb8f2cbf0288704a907aca513394a0d833bca200a4ac38eec19ae0cca6699a489915320932d9ce87e57ca61101a764b593186921f072c36bcd66c4ba2c567d1e4053a494f91308eb74edcb7227efb5aed4e542aec2e8647a1215c94e2935a3750a6f2de0b387371f7e7878f88c9ed99cdc7c9687789aa9b217f84974f6f1dec37cfb55b64f8c19264038de7c9c37ab39262be00706bb0131a819e46914f30fe2e689adc10cb8ccf6785c5c674cc59863b636f5f849b27b40e59f23abff9a02adfd317f5dc87a794d7fc42c2601da9a12ff41286aa719c608aae34a54a73b7a38d8502ed29196c8e40e200fe4b2b1072f51f848a15e6991915e27206c8fc59e3874e40fcf2bcd94a401dca07d2bc1f85682f1ad04ed5b89dab712b56f250a9655bdbc9c11c318fee74dd290f2531e0a75f0a70d7ec7beeb9717f5fb06669d00761fcd90273293b920ff0842235f2b7829b0dfe0046193fc7a9416d385a0493a87b950fa759b75de2ad81eed56f4c3493cec9ddc9b90549f114a27847e1060b7c0b30f4820d4bb94b9a8fcab3d1b9660199b269e12f6413482d36a9b46f549a544dbcd174b259ef990bb3362363c6a7248653cad4248436dba05e89d8717287a38902eecaa1b755b5d55da50d2cdd943bcd42d5395cdc8f1a4545c6f0c415dc2a96209a751164c57420b6909db82dcfc49d3ac9e6204fb26c2dddfaa3f18b56b0b1d8712c89bc4211f372d1f83f1e64343568970e70fa372aa2d2ca7ffa51358f8b42d966e6bd5d884217b8aa98a22b1ef51157d44cfcf643f72188544d9042ff7915c8d872ee507416713ed059e4531e03993c474ca84511dca54fb91ded12f8a85d4791635709006654e1e691b94856c9f10e407d249a0204ae51ed262816671a84eaf27d180ba81ccc9cef75aa36de7a5dd71a2f6af44d9610cbd467ab8e3ca293b22560c48e95efb5d87f3dc385e4f037ddcec4fbe2f476de645f2d18bf3ea62e6e050a65a5ba7531fed65eb4968e82ed414a4eec9ba7681a651a2ed2923a6eb472a1c6d842cecead6600fd204188fe24aaf594c974e5731b09f8ec2b15d29a90351786c1b6ca5c3e4ea5c76963ab9cdd54623025c03cc6c3899daa11877949ee61cb59831cfa9bbcd9ba82f1575b85da1873cbb9a5d351c6473818e24418f853c602689c02cd00986a6235efc46fe355ee6c4073385a6b4e196f0ea7e6f56d0a8118c724a74b7563fd2cd22fd5202e9e48c540d5fa58792b3f2d57e7a5be7020b3927d5408dd156053edd98a40b769c8f46eb5c4759fde0ad9c7d594cb3d8a1c9c0cd4c5766d6b7afe911970b9fb6c5b9933ad3d70fe634ed3381fddbce6dcd289042d5a7c95cddb81aba60384f9889602ee9386477632037ecb23351dbd811f342d466309bc6e471ee3b09e4b6a256eef6db3b1a4d8ec6caf9a5bf93da2f62dfd8bb2edb404de8aa715dd5d34376ca1d7368930b7019ee2f877bb243dc928be51b7fea33dc9593331f2110255f9e792473f3cd333fd33ad49cd786c1272bd8c7f148b89eaed77af9538e38a1101e1dd8c85a56672d01dc36074848c482e7d8fcfdf98002f25326aaa776b0eff0b97905010581b042144d1ea3f236dba0719d752212adf06a1e2f06e6a6498722d5b34d9bf10112d71636fba6b1d3bc89d01f77d0ad6d714845a2fde030e32b4238795a37788fb03eec32fa4369e39a2beb49f4c658e10337b3aff7788b19774d7967b19d6c450fcf3bca4f6dc5ee4e63a89c44d4c8acaabda7580372009cc5da71791ae11568fba008498eb7ed994d729fe3e9f95090ac3feaba33b7173f83d8305510e1f09d5b109422e91b0f4493b2f62b4b58a1ce2a223613265e3971993adddf8574ba882c3314da3155501396020b53bf9c30d694952d0d2df5f6e6fac403b72951f7e985fba388679b5f8371041cd6348ce4e29996581ab3971cf791a49da4cf0baf88c9f9b98cc933a5616b80cea0f1c14d34a901c22129f192264197cc272d86fc44edb384742a3a2ca0a17b7404ba327f6cf3194a5af370397ea177f811654abced6483fa965578c7280ce47e909687955c66795b7946dd739989fb6150c140dc20b414bb7115ab58222c79c5c73529df22d6ad92d007027fcc7087254bad551accb238efd28388334ee9c3f49b23506b23840a1ee1bc78c8fb3b95fd4026d8622556e602c2604bbc47a97ed62cd28995e5788354d5e1b061b8a788c63078b2326613e2c9047072e4a38775f51b65045bf4bc212a8837a72a67098103c062dd7210939e214bb5bb957a7259e65404390c534f64a784f1a668395ce06cf73a554d6f2a684b2b59f29e95064e52708d50bea9cc4535a285268ac1233fc3bceea43c3d87522228c2a4a8ec0309dfccd4373d00cb27e3da992c31f1c6b80757162f2a9aa91f39fd78815539ad65d683d8eab7ab6ed93d3115b038eaa175e9fd1c55dc767aa3817ae38c34e45a02e63cc27a1e73cb9992ac84ab1a78d4e87c52c2e2a02c25b4f0a70e8dbc91ba8d813a18d2a19f7218e627ad501d40c7e4a67a7596a3b7d7abb32c056add428eed0f1d6da12a48aba9fe2d402653ec0ed045993dfcfd9eaf2a0f66e08220bb4b9ccc25ce2662c3c18ddb79f8f4851d078d44053c749abd83ebe8649f74a85bdf551f499d83a0f4c904c8a5fe9a5028837c77c12ca190e560d68fe004326b0ba017b6395e579c4afe12197f13ddfa140933c17eafcccb8e9315e164be1963f3fb145afd96ab317b62a67642a420a8843b51c3cc9d749aa960d9a65b06d1be595e1511c090e4ccca992aea1120ed7991d814a8e0a9122a0526a50d416ed0ec6b0036ff891439a6269d94afb8ea69090a7137ae7505b2129f527561e7f70ff14c85bb7d35e28b0a48242c39097865bae047a2fcddcec182f6da6f4a88fc5c359df94dec032235aaf8209abe95c99cb5cd648a67c7562506c73cecba3a414080af8573a176f302dcdeae2d41751b8c8a0a7ccc53297e97baf73baaf0ce9948bf34bd53f5d90aa60c2408265a9cd56917db32984b3e7fbe92ec98f0ef1edc6c3bea5f6a67075fb2625ce17dfcb9c30319c1503baeba08715e01bfece086bb39bd198a42e50d1da135949718797233cfa444fded348b206e0cd903064f12165bd699b5b2ce2c6d67d637b0481a5187aca1a6cbf9442f9735dd11765569453513cc83cb7a51f4af8f6622d40778b78a10aafaf5ed65dcde03bbaad727bbd983921437d8dea549ec5c567c56c3e8134dfb8b110f1572a27ce9a64ad57515f64c90d5f3ffb3e9059154636cb7e183ef3aff5ff9fa178d651fbd70c65eba8296fdb2dfa7a0eb4f858498fa48095cb3ba9a9b397b261bd90488e86209df8e5b94b16b8c7f873266f649feada4f1765cc8276825850b5a9948dd0fd34a5c4b6badfdd9dae3bc76ba18291c6c4781802818145169b93f2aa1c6539aca51731b87cad29dbaca54814b9af85304ef5c7cc6b4d22055319585274e8e6d10c86faddab50f956e271bb3a33fc716a2bf6656dfaf37897685ed3228e44b9b94a1c7a0102f36e4ab927fb42891945ee4ddc2cdf6e1a9e8a2ce59574d1a058c2bd2c261ecb98c77e0d0b46acd740a101de72d25588a5426eb14100fe4d487b2e04b1329ed7de18852bf1408d63705032ab3c748051bf93ded039c896e74ce336b766278492fb27cae3b69723201a7fa88e5c00acca4b8595e9f8356fa8e44bb75d2e60092750e6fb80cedec38979e4dcee12a77361757b8db5d376969b7b73b2f17d3265da71c4e98923b6349afeb660a4b0a962579cd92986505c5cfa2e6677127404f800a80507e63b8ec9f20efdc0fcbbba140b98380c055e0fd9b09b82d37135cee5cc4f5a80df43d9b6b4560d57e7a27589f2cec0bed7daceeceb9a3eccfd680c76ae452a4d85cca0e00f19c504bb0b291674b706d87d0793b2e95daceb5cb144ba6e7488394f25884216f5a944859799348e9a187185c1340f0f8f29d15f5577d04559341e82840e10cbe56900354f7d091c31e2ac80dff122991e3394daa0d8c5cb9ce3e7a74be0a1f720fae8d38dc9a098a708a3a7138fea8115ae6a13267ff5267302e2b3524cc8574ca6826d36fc483d8c4bda69defdaa75736b15ae5fab0dcfdc372fab0bc3a2c6f0f8b9c359ea095e865e7fbae3cd7b03bad712e3591612bb50486b7eeee61798a57e9b177b2ed85ca71ef4f0b94c352ec717de3b48a3dad2dca29a26dc91ef7e7f904232323ace875b46d884cb7939d3f2d0b63df3889ce584c084b2385d38ad0a67fd4cae7384c01c3fc71335de09fc7b55353e40a8c7324edfd80f404fe08af0c3ef4bc610e2905a305af2ab1bc8411b3b0e45fe8680ddaf6b44fd58aaa7fb9b7517b22cd4ccbe4d95fc7431d7ba826b1fb78d3766b219138e9df534b7acf8547d00ea556d7f3c35d7b9da4abde7b8c9ec4d223ece25bc4fc457defa8e8514a55f23da46dcaabc69aa07e1e05de46bad0acb1947949a8cfbc12d0916eb847673405f1956d4d0a3e64ca09f0cafb3bb729288a22a67e1621d767dcc4609af5122e1d61f1783dbdf3f6041b5f3ab62828bc08dea213dffe2b52e04b3a8fec1e698c2b9e9d2edbb1ea5b7c8b12983449ba54997e0dba32c0f68eaa4c7b28686244727e61b01e927eeb57291d75ad14c34c2210fa3eab5612a547510c4d35a42a4ca17c19c426d37467b3f46b957f9b51acb730064d4de4f81575967a4ea609fc60d8c6881086ecdb91ff3b4348be3681ace45d96095cdb4087db5586c9b23daf7e5fde5fb174b45245d1dee891296654ddd858d733aea8ec234b2cca3db966f4ddd60c46fc32396ac3364e695b3ee1048b6d16ccfc59aeeb19e82ab3bac4a6c8557ea18675bb88ba1565ae13bb3252b5cf06ef1ab5d6ce9598012a598618b1a1e6096ba1f8dc64d594027a89bc2af4ea6a9fd3494d8bc9aa8e956d2568e493df5029468db16d239a6c82acb69c3f7d93f3e7f35dede36dab8eb0fd3208379ca6b991deef210aa61554e290edef7af54c8ccbbd5174a419fcd0e8a4a67d14368cbca40d7ab4e6db5b423b53ee4b535a1d9e0fd57f5f1371db8bd848a7b1a764b0a7b4eaa1889c668d9c668d9c665959f5f272168a9b74deb606d9ce2bb3291d2dde6a88b052f642c0dea12a1427db9e0b68913a311080386d1fcc6e74bbb65ab1119b8f05432fe7c49727b12a2399d6ef15ee98827677050649813c82756b58eb1480e8a45b6ee8601384630b63b72b4c332e1d6b575d6943a406915e6e0ed0bd2c60ac9786ee19ee6f3c3ed08805840d1210cb8570b36e22409f97458fe7aa6efde79b2d24eeacab2e983a241b43d97bf12209a9f6c3b0e895eeef666fb225fbbca89b780bdae659375c01c5dd8935bcdda6b8e72ab5b78e9173fb464071b28973f52429a8a37254357063f426672290676bb56db90b542aba772462afa370c22fce91190914abf502fe527717e3221515bebe6de881a13b6c60ff0d759f92736287d50d7d3ae94b0f8e456c74ada3e167765f3e8b062e105eae6c83ac6d836c6c838c8ea66cd94fd28ea664dc9609dd96aab26af9c323895fe470a4f7c2895f5ef014d758241b0af2fd52b4889199fdd5aa2ea55067c009f35263352b465134b653ee2cdd4d2d46b505fcdce34796f05ccfac5f1f1089076355874a43d2d8a2e51ba967b18335743a192003db1d4ae6f7f7500a44f8c34b73675cbd4f11f03cc5d724e4161272df3fe316c445b112d1f707281396404cf1db34a411ea8bc0ca772b6432bfd89467cd644dee6a5645e41f45ab5160ab81c20bc656d8fa1a52315f5ee473d386198bb7498953ec5e4650f52ef78bf372a09cf186b4ed39d5afc1a47f6f3e5c46b8da8ff1e199e240594959fab9fc181be68f43fd3677f3ff3077fb59e6f697b7fda9bccd7f93b795bfbc6dcaef947f98bbf5a2397fd54cb3efe5f8b09d34aef83fc28a29ade1a758f180d863facb8dff406e3ceac9862fb3633717f41f9d190f223f37d73e02290436d77eb3aee9106ffc22830bff2883f33fcee0fc5f06f7c732b8f82d0617de66709b22df3cba8ae5e13cf82b8fb0afed6509e6ee88e03d3a0a547a3df1fc8ef0ef4d644084a2627c24c7a1cfb39832054d4ffbb506e5c7c5fba894f09bf0dd0211e349a9958103a9e6a2d30941a3ab384a9505f4045fc6dcce039262e0ec59b9ceafa0de698771d64e228e705a71ebb955a787dbd9a06d5e3f0ca82131930e966e3b5aba9a06556b072b70443b33a36ae869433fa69b147244f56c39b64df0a7ea97d6b4aefe367feff928265a7c9b5a809b1b8bad54531f6bdd1caa4576ed69f470a01cfdffa61cb864fd7b09c83b765a0ce5f94f3beb96e36fe7dfd9da46f33263a5a369ab258c98df134dd52437efa853eed48b8622eb8d4531717e638b8438f22f78595951890eccb0ecd4b2db85a69cf9dce86f255dae8fe8c99fd706daa4e9bdcab43b977e315f978cb261ee9368db3b379b20cdb7118e5ee458e30c268efad5cdf4b0a2b8bb994e6fa67b2c859664fffced9b19ea8b9bd9dd00dbea8dff587cd738cca453337aa38000d914a6f7a7aa7cbe74fe741804d616ed3a24234bea435a33b6513c3c3db675a5eea511f522fb506fc9ffc3218fa07ced9a910d356fa7c1de884c89a0ae5f84a8791b05037c182b320455afc107b81f943a91da2ecccc32ce3c539b36da736cabda7a32f5420de0d5e3c516c1b20169130f68427436eae3cedeae176950a6fe126d523a311a84bd97a8f72c22795ca99e6e068849ce14263f04c21d38d708aa99e1b731ae27be88eba997713d5bcd627983668beac2b4aefc253a6c3465eb6493730aba2eb34d34aaac357c97d4fbe20b07147a55015614e61930ef1b6a2c18c6b4541e4878939a39f7bcd2eb465fe77d6d3239b896af6120a7330f8f8552b8b40116563311803e570a099b6dedfe15e2ab38d9f5638e8399c676cb1976063074ba0996a5867353ec96e57b213916237a61982ab079e580a037bec100dd8e019e1777f4d5b2c0c5fc937ef9a3945f2c4b487334d6ade682339ad5112df7afdab249e7ca449ec0963d383e2a9bbfbaeeb60d9e35f38509d68e188525bb27bdc8c80e0afb6aaa2411d49293b2fda8df028f72a755fb15b0a6134d8deb8f23456fab77e39f48594ed340200d41d5acf5c10048cd481ab8d0fb32d5bb6b7c71f421fd017796540b3ab2937b76961dd48bf309753086819ac4eb2096bc4512df83165fb08374ac0aad8106a209dcdeaba4e4ae4714fdc539d715d85bf5d105472feb858fef128c57d1e60c2e1f4a9d2474e0ec9c475d98638b844840fa8d689eb43dd5b3be91372bf0d86c0165d9375ee5d663a38b3384c8a3395b1139ff748d6d92543bfc44a3075c7db3aa3356e5b5c3430a22bf8963fc8bd6d73eed8ada29cfd5f794b68fed59a01663323522acde47abfbb25f389e4681265500886956a90a3b38fe85d329e285834b614aea4b4db35387d4a879fb8a6f7bbdbc642e4a321725e98b928555a6c6ec908a46429d812acc928a466299100f4549006c57435b5e1b51e21c5bf097cb0fce5e66d788548d9c14c6a7d00df7be4bd81a2d9e3479f0b6c62ef435ea07857d8f0eae5919278606a56d2a76e0cbb641d2d09f604279fec31ae608a29d85db158b6ddce4a743eb094ad171cf95c675dc48b1ebc51fa5d251995f76b6ea0d27f353910f3f0ddb06cd56472e9e97d210883d0629e5995421d006481e888a860c098a7e36dd7fdd68afa850ab929f594a7e8ef20c529f097d729ba29f6dd6fca47e0c3d430aba508d06a38218807abb56f18418872f94f1bcec7c3dda00795dc8b3110c865ecbc4f5d0259bb3924289bbc1895c079722497252f7ca78a2fc48af0b799e1675a1f4123cbc5d294fe60db474c50ba86dd82cf077e38e737d35682616ab24614a25dafe4e49bbbbdd6924696e33cc610797db8d2f9eddeed16f8e4ff4d8dede0a0fec27db91da04bd94aa29a88b7efeeee88fb3093c7961c5652051019b9a9c071de7bc9ee281d5413a3401cb42c61e4c1613ebae82ca0d5a6a37486916dcbd24a5b4a883e8c36684b99ee97f49eb32c9e832097599f4302995501018ddd3848c46b989f021151f9b456693098520e13d3fce6cf4f40fc93a53cecb135d5ccca9575b7261aba5823114259fdee7ebb6cda3668a1219e79ad338fcf666018b4e8bd62d7211faf2da758ea04f8caffcf057252c426c42a61949ffcc9d751bf19c565148c8c75fedf06908d8cd431c95206e1de32b05f823bd74d282f61f622b346b3a472863ba0b95e8d4948a45162f2135ca8d652c55b000d029a71378053bdc45840378f2525b438880fd1e66d8c52c9bff5740a90893b5bbadcb2a905d3d55b2d2745854ba306f3789fb5f356ef37dd336ddb26c6f5bcb6e162fc20ee0128997cfd8eb12e315ac44bf884ac153f328805e86ac0c13eac062af522dabfbee08aa8b1520a44acd41974aad331e245ac099071bd19c542656061b9602d6f95183892100e55da732c7586d3847b9c621b9851362d1eaa1e4685e6c98da24cfa1e468984b69575fed4f7785747482f9c9faeefe9f6c327656bcab170f3e79bab2b7feb618fbdb62ec6f8bb16fb61873f5aaf851fd576d31766e3106bf6cf8df1e63ef91463734dabf4d8bb1735af1eff718db3b233209597053aa7ef6a07e276d9b408935d4309d12552f84933f154e69cbc2f2090b33df2eaf6553be964dc7a96cb2b5f8525385d5af99faed55c5294af4a25e8a267f5334ed1611c047f4d62a6e6fc166512fce75dd02ede28b1ad0d7916f97507608f5920fa8dbb37198fe9cbabbea75e3264212984109d28b9b98d69b5880e093bd8961fa0c65300c99d24786b616aa2e7a7a97b731d9db6827a76ee39c5c5a27d766f4099222799b3cda5938cfdb2b23bd4a2fece2460e64116e64a1f5e05c5059b40b5137f2f64aded9065ad47be7bb6e83c2af8b09266baf5c618b0a19a3a036d69975a143967b6a8213ff627aa832b4c3c7a6edb3dfa13f6e9c0eed645567a5d68eb6eef64e7d3c411f4659f4ec3f823ff4cd082e5d631df13363f5c047f732e5f76f0ccf1f12c3e36689fd3f2e84a713adcfb6e7cf1d151a8bd4bcf0a0b7f852d3507ce77776515c78f76de3ff0fb2fffcbfbff9e7737adbfcfbe1969b11120bbdc4df2023af5bfc569f4552edc2a668724854daff7e1d2958a17eae44b3b6364b534375713b9d0cfa5073833a91d1dd0a997134059509297e86efaf723a3e9941bba193523ae560fef575d2aeceaf7a979dfb7ac889430cfe7f63ef4ab3245779ec86e207b361ff1beb93a0e14a60476455d61bbe7ee7f457fd32c261631042c3d59571f8e1f62710fe0d26fd5cc96ec15d8e2e9bbef4ef323edc748f56633186433f2a173624b8b3ef8faa17df6e15211b6fb5cfc33ccf12afef71a86c06d5ce0275610a60cf3c61060082491feeeb71d8d60b8d540ee75584925f7d1bc8749eba493d581c8fa1012c098fbf67d97c6abc0c8147fdfaa2e56dc9cab69e9481a0cc166cf6dccea9c44f14d8d5fe8deb1953ff730b3a290daf9fa77638d3338475cfa7a291eb3a1d959095c53d7eee4e78e089f0651e9f9c3804ff3294936d3bc47c16dee7f2d9bae18a94bcf7a968ed050400ab70978b7d19f6a9b5c0f38daafe295845ec323b5793d18a84b951e8fc0a3ff0ed33430c5618173b6b221f54bf23a079ef27bd0f708287b8ea2b173d835a977be0e2fda17ee68bbd29c5e388daf70ea707b49962987c8dc4051aebbefe30b4ed06b770b8af91f49f8d2c3fc208e39f4111da4658bf86224c9fcfda3ae3df31a5fc76f5c98d8622803cd01346ec3ac55da6a0dc30b959ffa4dc706b787507de3ccc7adceb0d835b9386d18faaa8dc6fd105ca191b4d798e61cfb0c5e0fdf55d360c53bcf801fbdf42d54b29b89214b0af21c6c8ca4a21aa5089305a3585b2c88391181a94de820a0fc03abdf71be604a16e8816aafdcf0fdead729fef92263c1b80b97a25f95d6cfb13a03c575b827fd813e11b5bf7834ae1b575efab94bfb375a32986fb6ce73e6cbe1cacf27aaf89dbc9375cca33b9c2ff2e894371adab1f0076b206128159d697cc813c01bb9f86609b1ffafaf27d85f28db17fa2ad04c689f0022a17c3227ae7084d633fc65b633fe56753e0f7699a2180976d002ff38266bba0b313de821fe675cf791884974b3bb3eecf04e010ed76bd1c8d1862fe5cb8d8e03b25927462f7f9a8cb7907a1bc283644c94bcb62c5afe42da74d2c154511f36e4add17a2e4b86ff5c3fe4daf3bee5d5bd32bcb0e65c2a56d4009934c38d35ff8ddc23eff2d87e78f3470cf42c9bc3d612d5b058feb9769954de42cd9c899d12927eecde7e87b283e862db1f799439a8bf1e616195a3557dade1b994ad9fbd777ec7b691f5b4f7521228425df9c37104e7cb2ffcb0da3ad9e5756686f3cb06f365cf62eda2141f6966cfc6d1d7bb6674a729e44729e44da421fcb1eeda8b2eea6311fb8f80ebae0d628f840cb383d42bd2ec3193261cdb45bca9592a4b2fbc4f28a963087ee20ae6ed60b71ed6f9a7ce7feaf9c2c34900f492e2a18272d58b7b84db29a2e394d6784f78dcd70b0966ec22c12db7c5f5657b09df22c0efc5600c393ff495cad49485ac36caa18b0f9efdced145513d6802689af247f3d53c5ce275b1f0ee0714587e263e0721c76251c985f2ae5a18917a0a00ecbb2c5d40bca470dc8a941afceb3b47ccae5e63cc45aca8d89ff4ce8538fa9b64f5feb8fbed43259e237df6a5e507f3faff50628547ce773539a34a13f1a999840a54227a1c14830d6ed02b1b6dce6e46a60f70a412e0bae0ecf5a63f47d9ee5bc92b1a3e1f8237cb851e1304396163e3a68e42a3585684411fdff264f708f8e7b7c95c9411149df7635b32cc8c0e78d6e873fd2e1656f930e3790e21fc37a19bb5ea81d86983bd6201dbf6df078ca0a94bfeee4fed0eb2105eba2ad4a57dbd15a72fe025fc10ba8b2b920bfc5cc7ba4a2e0e18825ccda8d404e768b15451b02c28fb2881ce73c000cd0f873c35f8bb1266fa0c81597777bfb46d25fbd7affdf5a4aa02c1158700037dc55ec270dc05d5658a59fc29a5e8574dc7b7fc89f643dbfa40aedb921e1d164d775711ce2a51f36dbef5a5172d8d7e7dc68a06a9c1ff63016b11280df573e7b4e68fa952db73abcd4f0afdd72165d78de702b51f5cfde70813a93fd33b6db32f24ea6df3f73bbad0cf9d154fd0ffefd4fca203d6274e78ef9dbf0dff741f874fdae1c458f6dd5da0a5639cbf5bf214c418f6746f444809a7dd5b909dc338cb5af4f5d01079285c595605d596fd0b3f63cf2317d0b909d142e667487d941d992c8fc3c8ae5e3d53cb86fa69fc95e7178ac54790f24adf97727e1d397fec369a30cb8ef7c9a409a15684f007c2fb487126688d2b29aabcd28ec8c9915fcef7f076166ec020b4b2fcb98c9d0ed28758fb79c9987d4d9d793ab49527995037873d4e51194e5b8ec0d7cc08c545255877a786d526ff445fbcc615f75b9c5c74b810710ca3bdeca405b69bff0f22c837302e2b48e2f99e1417f1eb815d7cd3bfd2314a0a074151b376f7b2b081c6678245784415687674d403909725480dc7086f18af4938c601c306f273f420f797842e6f875dde68d258f67559645ec36813c6650fb477ac686b738bc44a09728efd4a47dc3b7a7e94189172faae1431d9e613874ae3dc141da21d8f467539c581cf036e579cf2d3d38635e4eec7937b0c7d5d0ee738ebec353ca9ba72c75114ebec0cd3a4c83fe4086f83339a5d2dfe5946ee5f3ebe5c124b0c09c520eefbe20b39ff32cae475c2e70f8bc84e11d04f39fc77fb8a10bc3bbd08dc70ffe09eec3960e5bffff1ff5e1b34b987e8dfcf0d99848ff1efec3df763be7416a4364cd1c7377e6d9c79e0b695c3ad917adae054799d678fd4ff974c2f938b9695336098a85376a308586f431f0e169a2689d8d7a9968fc511b42e761732193a71d794d777e4942923a74d46c7599eb3351a421687c643f68b2fd5ce2b561b8c7c3117c39a6491e5eef9e1aafef1e06378032f22eb664dab27881a9510128e97871e47563675343189e16877e9c95707d59c6d19412a146e5afa382bf4ea436fd8d150afe850b8da7846aedb1c95c81124ad0c53e12cfb154507111d0b56af57732d11b04b5610d98b766ddf90a26f32560089e25bef483aac0a7cc6d0ac5c752cfd3ce39825b1ea4e484e13706b64eaa00d8d1e0550b28c08bc3bed023e0a40e0fc7c8d349416b90c058d035c90bb49b016b73a99319b912272bf7c2b425d8438b04c6403286958a5ab2346727f33f788738a03bf36ad8173a76eba1360c69b111d5c86f01f1de24d573eacb56ce16db4e77f5c1db9a3d12eadb7e396db85c527ab2b897733a6e9d9a481d2e90d7863f0fe5e6345a67c17579453c80bd7e3b8d56396013e9d1936f700ced7c1e4d5f7d1af6751be227c4c53f9b61197454af39a86763cf54970e0ea49d4b7330fdf5ff3ecbb23c80fccf4bb3302be4d95e8966a7feacc1b21a7e800cff7605e1f13434c413467ee948eb5a239182fcc466f0f3a1b8e07d35357708dae93c867ef92eae15db655ce28d22e54d94ad18193b40b8561c2e3dfa82b834f77434c5aa13b0a9f2a9206adae2be9623e77305457d9ddb9bdf56883522afcb8752d03b80734cc9adf5964036b1aa64224ac98ed45799a453c0028bd7f4f01be6c1ba4cb71978d3c53beeb19c01d24f5cb568ae7edbe65a5db9d18a8f472b3e89938603446471353a6781264f5c7bf9a7aa116f29fa579f67ddc8c6283882ade994a7426fd31f2cbf6c479c693dec0c7fb16465a96f0a64f670ec8a41b963c9c7756d5b25ee91d5fb7da70e63785b43b51a5295dbade2fbf79fb78a03f4cbb3b131f36fef8ef9cf18af1d087073ccfe68a1ab4581ede2efe0c64283ecb81b7e7680eb69c1af16165fc78782a946c9cd6fb610febd2cb73df1b64e199ef604ddaf128d45e0a20c3307d8aba91f5f717b3ee4eb76c8d7ed9077d3f7a139988b29c0fbd127045242301da9a03a29dbb98036ad2a9b556e6cfb0fdc4fe7f43cfb8339cd7d19e9ef22696f2b8ccc09c7c58d3c4de31b5c3662617f77de4465c0bc6109acd81fc57a56b670c0a689abd6bf38912290e4a72b7e6ba9cd91d78344fdd403e89f6cb8a8e20f08151bf19701b116668b506a4ac37a05bf04dfc9620eea63f12ba47cda0fecf6371317fb6feff6c7b58f9791dafec39bdd6ccf85b3e10d7a8088d8fa43f31dd76965bba448fb6c0ab3f89cc0a88c452e4f6c0db20f14657d9af65a4f22155b844d4d18e01410ce7367a29e48ce68cec0adf466066268ef03c98381180252b80ea7ffef62121e4107b53a6b175da3ecb93936a93825dba16a7e18f3edd690ddccd870b6fdb4fcf881a96ad9c10764f7326121eb7e5b83791dd9b14ec6cfbe79e5087a32a6e23b3aadff8ca9f7eaf5cbd3ff83da75d4ff4ca95f99b6f02fb5a4faf5a70da95effb3a37e69dec21fdde8b3ddfc7f56d4bfdb8aaaf53f2bea97aca8474682117fd7943ad6b5fda429b5a047ffb3b6542b7f8586ad7fd651add64f95d2cb3f694ab537a654f6ca46d4065ab1d1c685cea6d63cc87fc7d60a2602fc8d658b069195fe15a6d6824f9d04ee078db962252efe80c4eda6d6329ffa3b4b6b65a82364009de1e52dad095f69e17cc14a36a12db68cb3fed2faa1bf4a774c1073fc73aa6315419379a62ce37fd83a4b6fad335bc16f7a88849be33d17408b5b85a308231d71238cdb7f66cc4f983173077c62c63c633e977ffe8bc64c789f629bcd387e85c4a26c2b8204df8f18cfda36db3b3b52011dc08135e0466418cff72f1498753eb5df9698afb51bc7f29dbf6e85977bfedffafa563b9f46881fb54aff384afc6716970086ffadef615af2a78eebf3febd3ef65eff9c869e4509ff2db1af1a2c3fb185aff8c9fa6e454059ad3e80d432803adee2b3bd3718a1363986cda2bc672f9a5871283839c521309eeb51c5f1095e7d83009b2274dd137a32a63fa65bd8bfbc6bd577a50e79bcfa1770a4def59f98cecfb10460a36e56da84a836fad14fb0f57a293362ca2d72ff6cbf3fd08a6d10f462c9ec4ee4ab5bace20019e3721083288caefc88318234e201544b50ae54093309d5148b886311e417a81dc920336b49a428821bfd0c7275a8375a7f99764cab410733e974661a711519851eb7be1a1c2be0a64babb6a2ecb51514d09e2f5223075f94ee610a8c71a45765d175dc4617fd2d71adc8b51318c596fe5bba9208b74b5ab2644aa43f5acce01733d8c50c6e3159e944aa3e26be57ddc873794eabb9d6ad176e1bab442c31b56f2c66e460e60a6fcab234a63c3caf26d0cdb4e697f3d756d38756565394f1b2fc1e7d0b0bba12c364f993ba5d1408fcd6767b5eff0e4f9b0d36bd8dcfccb2e96f32b51904727c13e24ff9233bf80e123da5eb971a91c7e1153495e25e3bf0f650d7630e4bcd8bad3bd753ddccbce92a92ff0b5b42474732b93a0e1bbe427ac9fa3736849e98993b9cdaf53fd30ffa7e13c0dafc45dda035e2d8772b22fa5210aa0aba40e15caf9bcee2c07c7402cfdfdba539dfdfdb4816b6800c90a1b0bf64cb335a9171f41d94685c97afcacc0ec4d29d0fce75a0ad3be2c501f67088922fa0302cba452b0a5f88d143dca899cecff66a476b8439a50b1eae94f7a9ed231b6d1f59398e6c755aeb22179d8d92f86ea08faf95c9e4776fe578b9b93f248f03dbad75ae3e310389f5fe2d121cb0df7a8d8fe7c0bfd5fb953dcc81cd267cd4a17f5079da1ce8072ab73a1df6a9ca6dd21ef4af53ba7f56c706f3c44dc1a659ecea15ec7f8ccff13fc667132bbd09fbfe51cae71b62aff18fa47bbe9bb9fe8eedf9bf7606ffb5333091f39b8ceb5fbdd5565b9d7fcd5e9be6e1bbda80eff37e3855be5789cb320c8eea148d60fd6c479c68dcd1f28d40069b5064293b901c102197b3b1e32819d024670ae042a4a7ef815b3bbfc3e7fc0af39f5a14325b4f745ab2883dec038efe6d6fde0ef81feacb97fd7ed67d4776ca2f36d479cc353c3bc43799abc505d76f536b9f375abfbb376eb1fb3eeb9e2440a032b5bf4e693e78ef2d8b7bdcf4b76ae407835a4df8a5dea50df93458af38e419e0edf97c0a50c49c237679d5d9fc6c5cc41fa7a2a7da1dc57c169562519171b0a3a2536a4afb859979b90e97c41be0fc52e8de89b29a4b7aaaa90661d7dfa9e743bc0fb18285386c070c615c06c24f016f5823e04a021b02f1887b8ac3f709dee071140e4875fd0fce8e21e7ccb5f8cbe307dc3abbb675fcb98f07474e1ea278d6871fe0d9cb11d0b3ab1d9f312f36badbdee991a9861a8c14b6d85b036c91b3641f57ca366d648c12482339dd598e8791bce4688743e12783078f98c416ef095ba8824659e8dc4d201d3d7520b09965d9abd26bfb916c84d8f1bc583cb87fe99d43f55f16e160335df97f399110687bfd7fcf23904534fe4b25a82cfd974af82f95f077a412e8200bff43b90472bfafcff2099f3a45cb8ee86ae45f2e32f04dafa8c477419ff831986d2d717c2ab29956f6668f94cb139536731424668305ffb9d879892abe8d6edb0abb158cff3013c9d14b29e36336eb05bfa25c0cbb5c0b8f4733d2959074d90b2c11d2e8697d347f8477c1ba664601417f1c38654e7e1dbf5c0bf010e298bf74616fc21e6798e809b03b456cbcb578aff468f14ec3f92aa018ae6600b8ef2098c4c07de709d17b95cbbe573f96ca3623b117ce0fc7cf3bfa7fc73a2cc2262a628c34367bea220689c7da0884ba44ab2a308d808f3a04c803daf8fc94ec84015629f7a3787de7027a89d777da8675e7d2ce262cd739a0c0abc84dca16c08e62ce2739115d74f5dd6fa63d664da2fe5e5b6a1bfa048b226b3deefa436cf22718e1ebf2ef7b1f219bd1dd53beec3f69fb48daf2bf48da66ff86bf55da96437f14b73f09fad303339d73829b1f9664c5c166cded66428a21b11d71779fcc7621434411c4353b0b6c75b372ae53865c036501970f185ed2f248627dfbedd63f98d411fcf275ba7ebe0b3e7f3683b9bf9e9a07800395fafe03ddee913d28daef1cf0483833f9f8a87c59c5c19d5aa292b060f6a7f1d75d1858b87cfd3ec3d4efd188f9e4a37ed4d26d61868b27af50f3beabab7d973b354bc25bc30431a76f079aa18b08dc17987025c735405fc5668acea1e67be0031b15595de085b13fd4c879f6fe1ffacc38bee767479677cdbc75c1391f2046440f80e1b5af5f3748232c0c3ddd00cf178025cfaf41542a3b363c0629c5e03170950f8d21f2e993c9afe6e9608a62c032ccd91cfaf56c9da3afaf1e7038cc16a012829e986b6b82b73f5f1a09b6d7155099b1fae58c7757483f83fb4baaceacbde09010911f215ff8d70a7f8948379527fca9103448a79522b79c7002e575901e225cb65ec959aa1aa8e38fc8cd686ebc8beb1b270e3d112babfacc9eeee7554725d56184aad0a4d6b287caf199b562651fb75a5acacf3d20e14b48c445ce42982e745ec216885990204e58683a163d45c76e42ed78534685239fc81e4372299f5cab2fc3b51260da097f1341e704e755c2f0863a94f4e778794a10afc8ef68ed604bb37ea62d4d69288746ba3fd3e6e17502cea480a08b38cc5fdd719d04e251a168ecb93ddd4f6790aaa9b96cb4b0e960ec9fcec9a39d38cd8772cadb73dd578391134ec61a7b96ec0c9e5f1eeb106386938a0cd0df6fa442e62bf418ff7a39e831fe65bd72db18325ec76508b266d2318b04381c0b061982ad17b6283a009ef097ec1294c407abcda35a748698e2be6899fa0c08f66c759c5bc294e4d065fa4c2c332e5184da450d29b15083392096e607eba15b2896ed6caddc5491e2f723e0f73c54b61245de34718ea692a8a692551a0133a2e93c0631449321c6b2d0e5fe050e55d16710b903d35155af3252891ed73c8a2911e7a1866416bd4503219b53101ce2c761d0b8863ecba0138612b300d7342d15a231f2a10f787d295dcf117653b810d9e3a9acffe03b3e808f75807b41f8cde38fe04d837bd1abfccbde537a7ea05f0c02c12f15b6214b38f6d84f06152f3e99cc5c5b540bfe514cb8134db7aff08286f266332646f088aa48afbda5f0da4ff044a1b1f27aa410f919bee9a086d1a2a16e58c3fc2c91cea9f9a873681897e8337ea55fd10ff9c29df6997a885822adf8234770fa76f508c8ac0cc3dbca650050cf875e0c56dff2d4e9a63374d1f933f5b798e25ec66cc039420e82aff3ac265dd5a266e2a70ab858f9eea812de4cb6b7333cfe35bdcddf7db7fd8cc14d64915d4358c64df1e96b31f9d697f975a036a9cf21b89fa6f964850c16d074ead4029ab832b580e693a3a26fe4d1d13d3a82166cd1a07556a892cdc0c43e394be0e58c8666c4ddf49a03d45d49bc4f68aa139f07f3465fdb28815f34770e44a2a71c202b70809cd174dfe69b145892af9f5f3a828efb54b8d086d432b4e1be0d60a3912fc4da20583319b691af1d5f5b0523e28baf20e1e1271e19bab1b5bef6028415670f74cbe2239f7793ab610e9ebbc5f6b3cf9470435744f904a77786d7a2c98d4427321a1b325bc4e46decbb085547e240d8e1e1882a9cc43019d472a22c6486978c7978f3306aafff7142c0eb282ac01e520802ebb313e1b55a0aa04fae6cdcc68cfb2c2f9b39dc220a70269b13c2b7c0d15658971ad39d1844cdc68827be9edfa57c44f59b9cfa4da87e9357bf345fc579e1ec174659fd085f7aa8891c0b071e8b0a3497a795404ffcbe35e0ffd20405f6f775c7c5bd9401422974d7eb924d7490f8a212af270fc87834e67960bed8fbfd11d30f6e1036f3a7fe23c552929ac0b2fdf5e04bd59d84a90c7482e8e08845eddbe47d98c3eb591b730e888be5ca0e102a3021d800b341608f0178a64c6fde023e986d28934b9e8ce4f6051ec1c9586a0fab4d04bd2676807e00078f64ea027db84ddca3a67c337156c63ca255d2357f5ad0da3218dc708cdce50446f9ec16fc5ddde46df0797b2a3d580975f1010a88f540aa3a0aa0e9079a450141ebcbc3abbfb354fca40053a10b378da4412e4cdc572ef53f325b5ca1aa6951670499a43a2833d65ebd3ad8c3dab0a982651d114576115f9379c71cf1373f95e9f7c0fc4ee948c3f6660cfd7487bedf4c7da6484be81c0e84addac8483bae017f7b721b91d92a41f554d1705db687ba7de86727facf23f5e55c7df073ff787dc09f92217455a37555a37555a3139abc351ec67ef75216885e92af0531dd2e568a3d75a85c6b4bbbe405e212c9b0b144456a4258fd5278d4be493a2ba26c005142c209406003ee5f5f676d74b3e75de1a3602004d03ea22436529a0e7685f0f4205da3a27959c9e8c6f628cee14c271746897d69404a23ada8c62ad2c4c63cf3e25440dda7a6e1fe39c0483c79456e90d5d49ac7109e9df3c1f4f395ae862b5678ac4baa64ca49a34cb41a3533178a8166ce519f1ebade822791eb7abefcf351745de6093030d2d6f9bd932ce4159c5531f576197241ee6e9863b847ccdad85df7972ef7d85e75fe24c0b8e7121cc6019d28a608f091d94c283376568634351c8c6081e61301d05fd39a28e66bf691674c87be267407cbcff416a21187b8501b2b9445cfbff4139a633305955fc78254104630b714aa7e5127c21619d51c89027f2a4dc57032ee8f01da0890da8cf7c6605551bcf8211b421a233bb69f2ec645331b938ec74abf1e019e8ded1ed8ea0f477d4375be0c45518b5855d4701a6bbc363e906202e8898f6f39842e7fbc09c74651ecdd16612b7c72bf3f9cffeaf0da60b556334aa18d14396f006bb13b99850c668d835154cd80eb6e828be1b89cedb52104cab5c1314eb1b5c0bb724ac397184f66d99a5f58e67661b44d5dba052136a8a4bfc48ec2c8487091918091918f6c2ef4910b548eccd3bbca16e2e9873f07fc89021f614cf72e6f1edff179574225584fca9acd9ffabc876c0b72e3cc2771e2fbf4a84f9da6f706bb868ac9f96cec7bf2847cd3f70c8c3bf89d397b763e4f192a8d0030f9010325ff4172ffbf90a08a07fa2d2ca530587425e4e189f4b4c8c2635da21a6c124a55185e61281e623d2ecb729465811796bd593d50f8db4b0e37834f8a262901bd3283b8488e6548fc9c68317170f8f7b58bba63de69265d1c5faea27993db7f7224dbc4aaef7169496d6e7ec7d314745d67526de3a8da56c647f23b4f6c105393664709e4e83658954d1915d4ed74949b57bcaee7daf2289a35c9348fb182c1fda081112d9fc4ff862c271d3f4a733e24272896c9006fb552c40a6af6acd1bae64f8b957c259378c2eb14d214a4b2d80cc86166e9e856718829603bc56074c0ec05302f0060d2f2880537b390cb4c2990a9606a4683f54733811a9b1a7d978ddbc6994ccda6f0e9ebc75782091d5416120e45be09a781e7c7954b4945d5b56e2c62322b1528b2a18fead7f12e689057579b8d86eb50f1143a362ec2829a91b255cdbf5335c45f048c547725584c0df035f8ae784baa4bc8ce9e691fa541a68577592b4cff1cf0e7210302b9511f0fe6e3c69ce319b23d98f250e13506602c49ee9adf844dc128fb205dc4efb1cffff9c66f33655d1ddd6a7af09c8878fe35e7c986d98ecbc91d0d337fc9d8a9b2b6c652adecf2aa9dcaf6d2af2e2c48cdf599a52a285c3876e62113ae639c29fd8b2dc54fa04c032cc009f1c3b4dd16e730f98c6689663c6c6e1ccbe3beef2015042c2f4c6374f66d820d91affbe37981ca23e0a3c2f26021055b86139426b591debc615b75a6d7e290c455815d11a1ec73555655fc41be2d66e6697558d0dc7f699a75ae6654dc581b4bb8bab59bc56890242931dc66b9ba585cb8f50c7494eec633c55e35d453991df882eb4b42fb538c26ad1d1a97d40e358bdb91c26839f83bf5a3e108d1e88abfd539ef18c000be8985beda209086395583bd87f093b79e6334077185066391f6d1d43364447d6d3451aceefc954cce80f1e75ba1b88150dd0cd0ef0017dd0403072accaf4362077763eee624b7a63482b123d7504798abe6174d82f2315b6cf9dae591ec3f5ef57ee460b948363ad41e5281191d5c953630e1523a59b29c45b9c846cd1a5ce55afd15318b0c0538b930136371e06b81034dd2ba359db63ebf4efd541324cb4e1334d62548c719d7e3c9db2a0b1c34f95f67e1fc0638ee9167680248793dba89491c8bc894ffe75c2d5e4f64079a0bcec6891f2e264d4bb461d7baad7fc35b095ae754ffa61e27ea3e12d3cca9cf9bde4cc3da51bfc0946d2d92cc7e61f6807c9d8725bee360c1c81e392a04bb466c7142b9e8a4ff84aef13107a85098b39fc339ee1fecae086e5718e98b7f2b56c1c419d71e09774247b3df09030cf30da9cc7c19f48ca646018f60f68063b986974aae0a3e61c8b7ca1fcfc874dab8781aba6cd1edc69cbd14e9c8e960eb4c33c3b2ea9e5c41346c353ae0ee23a40b854bd2b1faab68de40a3090f4b83b5e8b6c45af7f58294872c7bdb111b721932931b5fdb79fcb3c359388feccdbccd85f8a30986bf0b39b46fbf3cde4ceab5abbbcb6ebf66b69f9fcecbdb4fd56a627c8f4309af6e47480d1c37e403cdec69cbf1c977b34f92ad9fad62e9972336aee16f8b39e82c719c21f0f64ada1899a72697c3333c138f4eb3790ed8d31c4c7f99dad9a4a77ab5e1b4cf76d1a2cdd877919da0a39578ec27f1dbe329f5b35d6de4dfd99d737992e572ac7f1560f163b6c06f9a3438cbd9da6734cd62f48ceb60d4383605da6b93c981e30d76f90ddbe53fc8c86154d3c954e36315c32a333ce6098930dbaf4c994f76eaf8b2d9f323451719f9436edbc3dbdbce98860b23067b58147758147758147b58547b58546bba551b46ac368c585d1831bb4767f7e8ecc288d98511b3fa5ab9e06efb5a41bd1e6b3c7c5c31466f87e784465331a7e5b88cc042719be45e1e9cd26a25b33ac9aca80daad706c55a07c539a5059dd2e29dd26c9dd2ec9cd28c4e69f64ea9119f76a387c40a93b050e185bc20b1394faaf94ed5e80d9387717999a5053a5812110eff6e43d2a86b4dd2373abe8fe8ab0219e14aa50d7e0a839dc22053d6d049d157b978b036a70c002e8ee2ba94efc56fb6252252e2138cf2534e51052d80c237bbc0e6d8e8b86a70767e2a5ae2d5004c2d81b1de5854bf1e5f2c79404533ae0c0b953638ce33ef16472610af1a92e05583f1a752b4ccdf33d86b0879bf3b824b2bfead7862dd73a1454a5ddffbb2215dcced453b4b29c290561a0033a28724e7fcc5ed08a33614329979ef7732e2b29ad4d891f4f952ff926f2bf2a331b33905a962d6ac0238da37c877587a2b6fb1de202cde5aba2b6648c6624948da10e81045dcbe027956037a38d6932aa56c03346383fc7634363dd3a564b9a755e66ad61316b803e1ca7a9e448faa7b38ad58d47d2f015b4f74a9f42e950a0cb7522c853887aa78bffa5c7c45739c94437723fc10c54b8663b56a99c97b10c08505ef026c17454dc70f57734baa66883cf75d8dc3b70106d734254a7e443238a06412489b0540a6c4fad29cff2b4acec9c0822f54b178430ae7398f7555c368347d42434535f74e44a2bab493316280273879be224d9c38c270cc09fd8f38a41ee6922386fdaffb27ae291f7647cd82fc78990427ffc0bdee12c8d722d593c3b2b29b8a3e7137b13607c68aa9da4b62326f9d1405b065efc570895984a1aaa1cab18d4caa432300bb13f8202c2c9ca966a3e34a349fd18d0d70c0230d8833682d905db3b857d7121f7420e59052e4d365ce6a33a65c86840c3d2505bc3e687e6a3831a0cf76418a4339d4224879036b303a4d6d54213b954617a6c5b2c399cc8bddda95bcac2fdff370a9c724f2691e1a00fd9c87495dba701816b66ee78b8d08d848d359b992f608ed8d1f8282f5bfeb5cc86e397234ae5d9711266701b8512d9d21e537ae0ffa7c759fdd3ae12c389011211af05cc16cbf2d9fd01ccc3df59dd1845f1fcd075d7aa9cccfe7fee416763f7e46577913a1587d266d8022db60d6075da3339056025609724b987f05d2caa87000886ecf4013a4f294a8d66a0296bf781332988b7f173268e7f48cddd5ef3b0cebae4e7e5747bbaba3dbd511673d1ffc7a09091a7a394c4e50488f8b5d2120befc8c546efc8cf50fd83d091cddc1969db0b96535fbc2cb36b68ce1d60e84afd11034edb71fa842b5afd7490793fb7530053994ce9e1038da680ada3aaf09a035150c24bc408755200aa23cd9c46f61288ebf4ef846e7acefd0b496755c6e593f7cb976b23988f7844f86abdcbccba6b07d0985809e7a35fb8d7f2040f45eac9dd8ebf7ccc4e8ccc4a022b85c4c85e6ad3176a93443dc5392e92765c29e251ca26df80a91f7534d9b49d96b14a1059f0d5b10e707face48ccfd9d0a3323fc9b15d36fd8049eb8f964143001db37bbc9acdbb74316655ce80abbb05bd5ad6db2f4fca5ed4cdb40795d966dd26be2a0d08253c37adf3125116aec50b053f52997f7a4f5394a08ce4824784c3be24bf34bf10eaef0d720e906ff8f6c6a8dd6055b3d6039e91b79bc9c262ac4e900153b39b98a1dd372875e049dc2359b4dc256bee98e74e653276b4251b44424bd6e5b3ca5ffe619c0b9487ff51bf39cefab75a45dc9dfd1dce83ef29abae45f9f76ec0ff538baf38be6e49d98eb19b8e7cb3ed9233d02fec455d66bbb15bcfcd802f111d497a2f51af6ea085c2db3752e63a1734c8b0f16db5d8f48524e31ccae6721f742da7e3cd538e630a14a63e672b18a030672a8665cadcff1e1cdd0d0203f7eb0666e5133d702150f697f9a250897ca58115764b9f9e5cf47b37f4958f3329e71210fa8d7e755be2dedf48ce9c316f54aab1a4da00437b71f0805ae2b3b48f8a0f4c1addac72250b9018e63478f8649217b327d1bd62ed0f8d54c27cc57dade0a134c5589656e74c9329dda29c872e7e9a36bdf9c6b5f6c0953b2fd282cc555b114574529ae64bda205bd997c313ffa83fc3179f1a4ef79e3a8cc0a218e1c8995c9feec89582e407eadbf72741721697b929a52ec11c4850202fdcfc079bf8e89ee61258d38a8aa9e9fd0d695f7347d998d5d5130124b416c7a383b2712ac2d7c547e7d540c6f43a0787a118754488e8760da353040f71be0b72123262505957b4683d95405d5cd81cb664774218491cc9101283f1a1db530a3a9ef4a69c3655686d1aa31ea81c17640590977a8981cfd7a4e058eab4cc32c18894bc99b7dddb06f23446e0d0be9c2161372c75aca60618bd3cfcd5a30951b6d5b493406caba24918b687bd54d0ab2c044cc3034482dafc9714ca698b858182691365ca614a1366bd984a77559cf410401d348278cbcad36b950b63773c99ccebf440072876c42f0a4da8c48d2e4a98c8d398c081fd63721c0e1ba0e0c8be3da3f2961f54c31fd4431f551712c24c0cd43168ac947252bf54b8044ea0b0751ec2a6a84730e7e186f365131dbfc7a6ec0a84e118ff48341a48f0791e8a3a6fe7659e79710ac4d5ed0e106211a840130976c4c61154098cae2cb7737897893544d4b0fbc0be11cfa2ab763657671d9664d227b8ccf8858a19eb40c6e3e2943ff8ae9f985e2154341fb6f7ea2f33c9546ed1a73fd9abf0a94640b96439189bb1dadf7d41d5c272bc3750028c99cc48c445f7303d4b6cd6c436553016c335511a7dd05b3040736f56c1dea235268d12c4cb684645f2f53306ffcb5545086f6d952d18c24183bacd4348c97a2fc7c56679072cd6a04d5e96a274c445c4c14316fba339c1db085ce7c174dd72fe3aeb3cf95ef49cf7e85ffd82d50c6ebd499b1373362396b79c408fad24818db6b7034e7f6b29dc34c5649c17a2664692a0211f382114c4a90e26a51c2142a020728f7cfa1848f491ab0a67710f863962fbc89760e7bbba6a128bb1ade15a4fff1e2b09fa5c115ca3d2c70b2844f22b0b726e86b4916c9544c6d9d70597facf031c42b323e92ae5f53d7599a58da4e4f5bba5c3856967d0c5f4f7bb4ee3eb8f7ba2b47ddc08123d6dbacb7eb37043cc36fd3d3932ee8bc89963dcde30c8c4584540b666336f295c8dae23a826db5322045e7cef9fc0c83ef529abd78478b0ff5b95d5b3687d2bbefe583488a8461cad1e396a92adf70de8b3ab62e493c67b9389ffa8692a14a3cb1ec8104ceacf44db77648f24d9129c7a0c42fcf51b10db30c82be1c26e2218af1c99c96e7396df6c9126968cf71afece35e204887b2ffcca582eca50690fce9090668c0dbf4901676971a499f683367ccb7747534d9646a982f34d2bf587b419b5b9ebc45f4c2acb5fcfde2ca52ff7eb940c31bff12d9af4a4ddcfd45d88567bd61be0f6e0f8d3060f8dac5679f433f530037404b141e10653e304a27b36b227cdb97d32b0e880bfdad96c3d4b0ecf0442d6be22d94af0f4c26c6cd0d9a9109c7b19b68310ad0370c6cff9b8bcfdd38c8daf23aabdec282a3d74385c9e9715be006e7e65b581bffdc11be9f329e4c9784ef64e93208b8ddf0a42cccc963a264694f9198b34ed2d44b722e13bb01a8d13d766a05318e3c059763f822f66ccd306f64f186df7a19e58594065520246df5bce259118bb808b4bb8e63b5323888b6e209aba53acbc2349122c3e4dab091be7784dae731c44beb3856407e50f11e42e825d440d59211b0a5ec16d810019827545a91dc2d8bab3fc1d8dc0ada690da519d51675d6cdbea7d9d6ca04788539d1de13a886786e8543558157a3894cbdada83a6cba69da9d1bdb37b9a4834b05f848f2af1a3936f1f4741caf5c6ebf3ddb5d6e07efb59a791f5834ab4f2cdc980aed735301cffe83a9203502cdcdc9bda940e6d7218fc36759b0363466e49acf90b46aab21afeb98aec35948c70cc9adfe6da76ceb33e2c44021bb8342760b851c160a795928e465a19060138f4bfe94fabacb3dfa728ff66b7a397bafbe802900dbf44a7a58db8a14e8cfba4eb2d634e06fa036d91fbe734a73765a2642309679a4da0ba84390c0e6e2fda67a8dc87e94cab175886aa8c558c954e53fa351322b7c9ef5deab0647236b6cd0c1cff96f811612b9b5d6a245c0adcda7c4b19fb470c70eb39b9adc10dc6d9ea8c8fd492e1c10e2e472d417885418c5dd3e84bc8d0a7233279a80ef87d96841654f234c2db68e9672919c147d8591a279b0b78a6bb178482b1c8b15acbcaac7cf045f711b0e7d57e43a4bb609c4ac21d0f33011fb4344f08be1a38945f438e5d614de103950991d65e570c38b04587d3340bd1c92faabea2103f1d8cd202328d5f330573ee969a02b55f1f940916f660ef44a6fc7094092c330e77f20a546b690a6354c2a0513dce8f330531a6e9825bc1d66366424b63bf732d59285795e86ba681685e460c51aaaa298730bc8ef7b871d9a48233492fac2f876763ea823502baae1bb333628405aa1dd32679993a8b8e55a5151287308b6b52d2aab4bb235794f922791b79263757ca7c71e21d65e75172f2bf1c25995fa4855047dece592c144f504b05229e3c40f5cfd68f2cbf2dd895809047965a42b68c6592a8d0d85a4ff225a4ac8d30ae624d7072408d925fdf951b3177d5e21ba67cc0cae1c065b55d31e672ea9b0cd1a59c0cab0616ba874dbeaf3a7f51d319dd95fcad8012d95a03ca26b50302b183fefa224333a6442c8551b663ef9fad37c2e77b2da19e51bdccde890f7855e49ccf3cbdca4501fac81a3e91bc92649121ea243b2e91ee02845a3908bd4dc71088a72dad3e6fd5aa099cde27c3bd341d6acd22b5970e28b4cc53e7cf5e8217d7001244523f8156d802885189105b9a2680732a2205cd814e2bccb557c90ab4e31fb83582da009388dabc9d6d0e3470c26191f572c1a46890968cb7ad44f0e72261298b23b6f044798f1552321a7afa8fef332d50db6a652e867b026ae06e6ffb51f2f2c902f88c2cdc4b905a6ed8cc667556bd3766a405d51f5ef1598ca1cd89747f80f7aa0d74a5807491f4017849ef593aa6eb63258374c2694e4e7735e33ec21d661faaaee3ea9f1e0ebd7bbcc5b5eb220439f40f71b20d3b4e00d0c948c9de9e719872f39f3a8d9e45e1919123145920318ef99ce6a3bc6eced7d7393729abc4be57d42cd52706b861f5409596aad0aff4d036d74e4ebfb46fd444f93011fac60062ca2a85c2889b9c0a62bcadb7a7303282b161968aac01b84b160c6bb939a5160c6bf3e1b2e24d3009bb320427609facbb267147750cf6320751cd734b9745c52dcc49f5ceeb0f73a6ad2be009cbe723e953fc8d6a4698698658a91e942395eda8a70c6182f309a1856179174eaea88c01d1c7903a3282d2d4677757ab80824e3c289b8601c629a8110acdb99ae150cd4e6c96e90cd5f7bd02873b65e932e56570d270e8c08f6d77b9a8dbc8244602db6aaa70f61928c07a43e00631cb7062f3cdb72c0a8cf2b6e6450e513a90090566bd6f9152b1c2b085234127955746566fa9c677c70254405668c1e2144dd384a41bf508c8c006038a6cb91ce2b9ae71528740f2f4b2411f83ff07b15d64bcf560cfaf66596b461669f02820d4bff2f453cb3bb0a43a94490c3ae0d9235f08b51123cdbc67f145f8a5907daabf7019ace0136c75965994389df175940b8ec34e14f66d428efc624e78a13d67ec1cb35483470ff88cad60022c67832ca4793c175d5763672d3c1c678e8ab12d9cccc4c123b648658cec5570e9795123f3fd948492cb6bef2ba0cb8a0a9653ecde8824a7c56c9153cedc5b964b7da61989aa11e9a3ba3d953b7e39ecc3674b47e9193554cdcc7c91b3017232ebcc193dbedf595caa5e2f675768d36c0d688d888986cfd565da05673d0c376d6e9ddf0c748fc1bfaaaf006ac6c2fe0b137d3d415348169071825b1c98eb108d2841f9ab613fa71744432c5707c541764ce46cd7748eecc00fdcc0a2b12523dfd8be0a6e97246512a961227658060cf9b76ad719a20175ce585eaad802decced55126e923b4bc677bc42e78111eb1cbf443c9ca51cfe975052772d1503546276ffb28b8dcd4bd399321e19da5a9b55765f08388d0466208d1cd30ffbf64de78718a19e20516cc7cf38af1d5123cff8d399b09ee9ce83ef388bcaf9a99ccb7cfa5720353e92cf777d99b26143aa7ecf96279ca90e50d8d71670a0a38a44a19c8968de4726e1f04d39cc1b87f1877c820464b8f3defd6083700317d6942a7de02f06d3339494097a4f906c109a89f6a60b49b229bbeb67c6faa3a700d087a1eac780433822b7833cfb09945bd64db8a17f30489a9776bef96277b7748a35e311ffb4b3a7cebd115fcd115b7dd99e4dd2eef81430e895e36e82fa23804655387c09fbbc01545f33089a20dcb0d91810c00206aad6c917e2e8173a2627224884f70559d7c50a1a2ffd20455370df48b0b40553dc8c4935cabf542e8d355bcb70ac1460e82a7ddc15a1b12ee20c8a36463ffc99dc7cd24ff1b7da22fc2c36ca69361d2aafa79d366042ed00c0a9223611c6d6d7f28d92997218a96d5581bb9705051da4de05a145d0b12b37ed9a8bf141cad29d2a024612f202a588bc941ac62b351a0d8ac60e68ee2d798eaec09c4fa106da5908442f9af64ba8693a22dd6884b173ae1a9db984f334af31aae3049f12ab25a0553d1095c49dd88110a21b41119e0393194262910b199e3b71ea04832836ebc1932d5ae7763859b23b4210311e56625e6d604d007510b6b24736a5e3799e34948b0226b85c049e9dba1476c92f23214729578b3d13d2080245ca7c5d6e814c4ea4ac67c144779006f377725449189bad35c1e1cc7ccb8cc5456d8db2b9825fb61331f2521713b5fc78c044cd1b222926546ed6cc76a5c2a15a369659ab45c4cc07cea6944f7a620b5df9031c66f70826318114fb8f13b509c050d7ff119d4200d34592b5b337b84a71eb4ac99d308b8fa61a76c467e47b78aaa43e2adae83b3d55d70c4f218c3a915c01067fbf71a3f36d62d6a65c0fb78d3f06b2ee5eceb705eb6ccc7c047b767762ab3defd2073f13cfe955b328d801db9657fd23151c82345c7f46c62af35380dd3ad8689c325458d6373d296a0136873b07e6936228eb1e64268cfbb759ff312d1b02b1c69aaa874f2500b41727388ff19057ec25483b2fb8afe023009cce93acdb6ca588c8586aa1c0dd40ecbe576d6eef29ef26653cb0c7b127772b3830eda200c70aa40cd34a366caba074ea74af13784eca8640a07170b2a4608a18316304ac680bed2f09b3216ab64b23860c836a5240092ee04c8d56a70cd85903ae1edb735a0c62e0b0ca7d32083b7dad103a69ae10aa6658ad85d8396028df86493ba5b31c2e2fe6d8e5d37c5e8d25026c914edb91af7bea14176747671780a27c818ab8ddb6b6e13ccb70e26469108f1d9b82364b95eedd52e0c9cac9708a81976e133fbeb394a0474c1162fe5c9b96cc1ce026b5c07eb2945b76b83516f11372d8c77656a8ad9b4332128b642d5fbd11bf4ea9cb601f613896407aba10172910da452dcf8bba27a700f455be89ee54f2123bf183d229651043a9c6fee6f655aab91637e080bb354bfef04ab6b229f9786ff3e1e53413515ea8239af545864764c80e8c045aa4eed91022bb97673d57bd603828ca366bc96eca0a77d2dad618ee3c74875b3c7668cce091ad82f9bc026b9c1ce88070368e06433b8461ed1ce8f18d2c84959d05bb12b63635fc5c6be9a2a425e59d45772ae80d2386cd206f6b7eb63d7b27722202abefa70665c591cedcdf0b337f9e18a243a4ec7df92f5abd0cf87400b7a10869484022ff24af13aed43461b08406bad343944aa047b795682cdc6d36135175ea09f1ebe4edeaec84119c00d4d62b6287b436ed991dc524265917e7c59724b013c2545dd4b76eb7a392eeda6b5e289d9cb804bbb49a978842fb9f8a0bea07660ecb5e24f057f83b91ea0c2ef54f1770a860709f4f958f8d30391caf64c01f7187d2760eb674f64d01c941155d9659f146a90dbea9e969558ab9c8849b949621c2f5b86ab6057614f2d4abb56bc55f966689f4efd1adfa42dbc4f850c32f865bc1c92ab514a6d0f8338e7426eaa746603f5f076181daa695666eced3014fafde930f2dbc450afdf9e8d69f97e388cc50f5cdecec66a2e50b45b797e3f8cfacdd918e369184d744a01d6e00f8691bf318ccc69a2378b329c6ca4f7c3f88e88ce8ce0b388ce4bf2b78711ee44d4ea0e968c58f67e96664162fff62e0927f1d4a3e32f67e087b2b3b8a319cca3a37b747465671264fab2251ab8bdaed06ca6227a4723b10378e0c232f255891f83f116e80813669f462018de0ea6ab39e3e103221c4cb94a16c666c99843e92c61de24515408f11235e13e9ae9acb53c2b2975ba2419b370075abbc429e10e90af5af0e949caa2286d156c7d5c9189dcea9c2420ac083637be7a3b3e4624bc1ba18c09673c150bbf398f326e6488a771c6dc9e472a21f98f47ca286f1ae995de0cb48d0fc64954c81510497ea058ed54df8f53ca9d689c48a4711c27943a5dc8b310d90a4a523816a938156ec1459e4166da642ca97a32e123b0e8e2d29c9020f465f89d988baa1d5dbb34c0a0451717e0a73b4716b4ea42a27a2bfac98517197e25e09e628720c04f7c0c063996652a88bec8605e5a14603418ca84cd51d3a8a9884ac93b2c050bc5166b420d4395322c53fa97a17ee1d2dc1429f8ad7aa163a780628a1722074ea078210382a1f09f1c0c666f95037d17e2d98770722d55dbf84f00df5ddd952c60eab8181596a3ebc958b32298b61ba8d072b9828d17b52d5e946d15f0cc0d9adcb81036cafda24b4570b9ca1a4db037e8669d334d503057236a4577ae621b92ee6dc24837b07b0352dbad0145ace29344a78a72f170f4523c1c1dab77e7619fc3c9b75feaac4a74578b59f12daad7c40b721b192161b0e6f316ad9b72624055ad8dcd6ba59a37a1e695bc0b560fac71157334cb645eccfb093c1a5d91155a9e806dc82e4c24cf47248e878839d05f826f5d9311a8802e42e41d545382eeef7128ed6b1e1ce2ebaba7298bc03090f2a572a129cf2a2a432f3ebc2caa7c5854f99ab2dedc05aada8bf63539116afadbadcc822166c9c2aeb8ea208235e1c37ac842cf5f3cd357461372a64ba3011cf29bcfac1b5b9e751b686147eacabef86d8d3ecb5416cd5c2c86e2b553fd0f04053f67ad66c863eadff30e807b35376024fce5705f8a8497954360fb5a5caeb491c5c30e3dc3fde4eb09d5c15e19403a4f458172563fc8069458665a16a7673a4d4cf970629ed682871d1da3b245c57744c5cb6c0500c6cf417448b7fbb95aeb1b8ca4c75ad0ea491980559776cc78346a96d017f97a6d73e258d2047450f0a79c05f616948c896667a180e470c85f487d77d56ca368e5929c56d644ecaa8ef3a7119e962b5e55dc157c802df32cec20f3889fabd5b0780d657ed2c2d889d53b97395c86786d0667ab6f7e325564abc72351a66942e4600499119662a9f02c26bcc4bc2d773f8ece14b176b11400011e140c9ce61f5358e305a0bacccca84e07df21931141709605ada064ca961a0f026664592cbaf4d1f443917c232ce4bc6dc4cfe7efd26b6f0107850865636599a500ddb2fc2d0ae008e262909897a81fb94134dcbc5232d2bc0ec3df109048f05f4d830861e592791587741c53c87c58d1e9b5ec1cb3c97886db7eeb1b62be336976d57aeec4bba3de70007e84981f970b3d19c8fc6de8299f229264bf81436e24b2a0f9e53383a9c315095ae04feb6ca1fa8a17ca920d7543262d03d199631b4b8ed19f485bfbcb01f7d78ad8fe35c5f46fcbbaa17b302ad89842b3ca76eb0447f65c15160e36cbf436f1b5b5856a0538e1c2cbb1c14c33b2422c227930fb2c3349974160c40a8ed8dc26a8cde7e4d22f64f3a2af963c9b1dd4122894bd046bcbae5381c6391462bf106ec5b1e4d333e5b566706800daa8d947d0f56903c6c72ea758203795e67f98d0c54cfc993a81696502aaf0710c82d897f6046294276e403db759606f6073e5324481ba712c13b6d0225895f4aa5c5ceb6a8d24ee73cc6f32920dac9971fb3202a9aa4006868b0bc50ce7cfbac46e4c514ed11cbcc19d6b70419377d98e6afe24b39c86dd11e573ef043fa0ef014d55b93a7d185f2cc3a0df6a93059bf2c654faee4f2522152143509cb58b6f46461e346dba4bb3569f1cffc39d1f33f2a6dbe478b0c9f1e092e30193e301131af97bb9f09545fc20197e3ae6e858ff562e3ca6f0fa28197e7aa0f8c53f9c0bbf3dc3bf91627d9b6eae9c97fb34bf1af4d0f9ecf9cbe079ce694628fd63b0ccd3fa7e33ab3a4fc47743a87649de0c619902ff9a149e1a2d60af0eccb14de30eb65ab1aacfb450156c04dbf2c8e5b36a24d4477608a41b8016976cadd071027e0307604a526c20971b1478a5d168359bf80945ab6fa12e6b859a810cbcf9010605799271040071432003102b04786533bc1cde8d2e42643a2ae2ea3cba297817dc2ebbda11f875e7232d5240574e66c9202543183620ac480b811549d3bbc232bdb9e382f18d190ca87c75106c27bf745905a6c0656c550750a2b9507fb728b7283037a97e5da1e3b7c780e2c98b3b04a07df1110934b810fa5c909c33962f6abe0e1899f2cbb4c4f6e039467d0af3ba64e340903358e15b194b403472942839cc584730af2960679a96b3e0cace8b16793af785ca424f9ad5416c27cbbe30a39d71a4f4466c8d6701a1b597c56bcd0146525bbac62e44d15e52372f8a3fe036e686efeb7dab7ac7994b7931bd5a4d66b0690541b9a99dd7160305e734438b9a36766b04cdf8465e3aa3da838a10487ed1a852b5446c62b42dc484b047b8b6a181b903311360b0d71700d70d1f1912fe2e56763ae4b020e21f61d93e5aab249d458b3c285f03c285b58673818c3035fc29768cd735e0a0c1274b42a507e3756c04157574c74650d13e73a5b8e07b6a301831d2357c9c9bcbc8247908e75abe34f27f1dd85b0c57f018d0df80672fa96f4fb58a926a4a8acf6169ba00a9545e86e6739ec497738f33f3143e1f07f1978f831534f9d452d727a6df3b80ca3b60d94dfbdefeba6d6f14355db0b3babfe5d137ed790b34be0def79dd8f983c41f09e3bf0620fe6f2baebc06b09e30d6dbede0a9af9be6fc7fbc6475c15a4e1e4b8fc637d86b7b03f6c2d0e055b995e8a78dbaae610613145ac2b87e1d8124cbee583e9c899887d384834b771a02b51329ca7bb4bb2810b542a93a037db4464a9af8e5004e922b26edba9aec08cbe02491c142621f1310dc541a84c520674f38a5fb702c86b3e86243e58e07a05b340d9fe0a1114e0fa596df3ba5eb17a303b8e4b730fae8b552ae4e99315774f386717c34e498893a81a63cc046a87f097e22e567f4a4a5025c1fe4cd045cade0c8d6c451f8f366b6845e914c5175ce6af0ed5324a00d1cd32177f438289494fe5b643ed561a5829b207fb3c73dd672422edc45cc57c0e198c9910e5cbcaca0da921bb46cb1202388e4385cea2292978d48ea8be3a96906aa55c64972371f19b9258e74b29d733254b30915735df3d988b1851d45d2e3f047b279ba8c6ba677eeec0ccd9f179c1319272ba1fb15e7de8059796bcd7a84112b17d327d2fa60e90852ea80fd27230cf196281f48e6b00972bb2a72ec3cd5d928bd8975f5352b0c7d19ce96c6a7d359de16eaa2edb50acc1ca81308c862df840746a92410d905b582e1c03b960f68aa517623b35e30427d489fc8c48047986e4748d9b9be4ccaf579641aa57a76e10656a44010333abb15435fc72039160f32797496f0c9b149a0b6156667e194c66a9e8254af4bed29c6c5cace3a68cdd04e5acdc8aa4286ea35623f9ca026e3c8aee4ee1ea687d355f5a3af04426d881fab514a7b7610d9f71b91399ef2f1601f89c42ea20d69ee5d98dd8db1b1b462d288094e60a26da675c9686874cac51f83c68361a6845b8207869e47f8ed3f9269df29c41893c2370353601e86ceb78684ec5cf01d31e027e96f09c91d4ba9c7a793b678258a4414933d6eda7e6be40ea92a5b34a4007b61d44780e3783a520ecc1520b6c96184486c1b777209863f6c85a702f4783eeea769045b15f92ebac50cb2b36025e9087780ddf403b6171fbd6eb82f0c8a8eb32855033e29af8d972852154252060fc489727bc0429a91abca2c0d720984b088c82ea7cf1373394b712af34d04c2fe315f4747224d34c50caef5f280e16f54fe4c992958ae6066016c5a85790ca80ab48874f4bb1f43dcd0e114015da9b92b1ca9b56633f0bf6f1945d3c269b76f798db460c8c8796fef9c3d63ff52ec1777c5a0e2e7bd8e36b4bde3e64d2aef6c629aed6290ece330dce330dd6298eaaae00f3f9e012101d175928cc5d812ee7cb37680ace3f6b40a431ba711f449555031e9216247547be46d50a7814d237b29dd3d6ea20429502402221b15288a22716a4134841fa4a476e8e5c78ef3576fca83a255ca6328e8809074262f85503789b7c89c4d64d7d456372c4b879d6a2ab53529f9df44a5202ab05b018124e98666ea4f1f240467d995ec44b93b115adf048f501e6af3ab97b01dc696eb9bbc03541efbb0051cd6653a39db3586c41c8d713e0e71cec4cb8f60774372501fb16cc28970babac33598faec181ca4f8644fa714507d4c5dd40a137a38ce0fe837d5b2d97d060013e093c978002ed45f46d08aafdc0b510b8e4db2a09642b4b443e545919d56e6529b82e15a37859ea1c14f995576456ad2c591c2ae96a06071d5e4a22b46d71885508f6335b8ea509a81bdd684ddbf25cff2a1260b5bc7810c9729dc3967eb940e18c869910d808027734258d336c2231a5c8ed0ea40248f380a04d56e3fc0b5da5cefc92180d3242491506193ef25ded646f0d04b85e968acdbfc2a4f13195c6f60db4a8650148b1a26ede0ce961a7ef6449a8a1d126413d41267d1dd904e0675ac3cd905219cc5cc8aef0dc644a7b7660abb45a880c2eeca635246d38d9ee033a264f7f9ee1eceb58c14a11d5ffec76c02770ac14bd424e1553c29c1469076755dda0aed832196bbf04b4e75b59e5073db5127554982eb155da964ed77084a46c0abc7b05de5fd2116f097d009b574eae7502560d55b9adc155ef11e3a1cdd27e6dc68df7f9b2fa29906600d3831b7d7f471e1a6502ec726f1ff8ba1df87e4560dc311d35a6bde864614c9b41b1f88193945efa53ccabfd8f6c8e752e90b1438f69f218f50cc537ad26ac545ed0099a821a87b852b5c57171730196e65c86edd0bc49b25d206234cc5412d1b80286695240a5de5e50b02f6beffbe7580ab2606a706dd8fa5ce3c75162fb921215e8e6d84c26e0829e8309f5040cf598e84b3ce3574ffe1019c0efbcaf2237f229dcb9934f1822f6afda3befb27dfec800b69ff7bfaa6139787a60fefc8113eaf326491d9cc757bdcb57bdcf579dd3c7e2cfa9d0326c2eb40cc99598f062429463315edfd094af6dbace32ff756fb7daecf94a18cd813866a6ef3a1c57748b61e7ba588f4088d0daf0053209f0f2e46a2ac0442b4dee736680755f7b8a1857c465e53796d42fb32e7b2c161f2b5337a93702f327c954d0282be18e1dddb2f2e4a9314a59e8cbae46b5dd8800db202e6d5d95156ccd5d385dd94e577d375d1a9dc4b3639147747021a4cf2dd33cd1c3b3db4f41392444a95e7ebf324f60d960aa36be8125d1fd388e24b1f102e300281bbdaf89c66a7baf53d690fcf0e5be0045ba88a7bb79332e0f299d8d84ed300d41d8991bbe7861b8f715d7597519395baa3cb810f9c5b065b08b400e80f42549a578b0701fde2849d82e7daa3843026458137eb0dbbd8c834266785b859301d3ec17a45b2fa023156303732e2b3e877d1c828db5e7a8353c12c28dd8fe8b6c16cd8b19e756c7456a87c7d5dca872d7afa99f98ba1468796f76128c4b75f0442402f09c82b8c17d6000045543f6eb8311ec9bad0246887007df13b3c820e6f7235af87b744d4a8bfb7a55d2623df60c3a01998889422da7925a5e0327735420acf61fccdd684b0d8e62b1973c8d8bc2a98ace700d25aefb14a28bc3d7b45a8dd5de90ebb10928c31fccf3f2f102b5f7e0eb013f0f4a760ac09283fe17a4ae3b00c4402d9bf68e64da408e6245f7132636819f4ce835c6e180eb2fc7f15d8fd4f8c774d7463af07ca025a65f9f3bed0a36034607b96ab2154f2924431241e984485e8757a0e3772a3b10a98e0730e758fd12f8c0a99e7f8743c91f58fe0012adad13c4b070285e09514e4bb29d7ad00d9218946c1dd714fc1163a1b47e287baf6c5c562e7fe849f1d806475990d60e4a611ae0e7435434fc4ad5076e785ab0f6992b45b0eb28b1e31427464941cb50beb563865733149c7463e6a0e91410cd16098d4a7a3e58ae7d2952581e6de2718a5f91092d1c45dd5d80f162794f067183dd22adabe5275d504b2901cf97ba1eb932a3c2a537f00a438d0aae42703b79f96d4e92756bc670b012bf2bc4897116e06258ab2b2a87bad4dc180545f4980ab7d6e0cce4c64fa6cc02fc90d50d429fd318a0ac6f9507ea579b5c738a52024c3d3311d3bef79e0d6d68224583491279f3909140790aa7ff12e8bf54241db0a088542b2461dfc6b34a7ff4e6341d05daf283a68ba7d9a97659562044b3e7eda5f8d1ecf749d5284a76ed44a3229829d130b8ea2d6d0e2cdfab5da71394c65cd48461d7a3956f39bb2b108a85afce819e20b72e03281fdc72fe24fa304f75719eea033dd5447ae46b41f59461613d1c2e886026da68d06378e43a8747ee2a4b3fe4a7e570530747aa1ac91a3a83f798f463adb4a26112f4a0eb5b09156148cc89d644d4e7b56ad66c604981789d9b1fcdb7ea8abe8db7f700aa439bcf3715a6668824f7054289fc5bdad0ea1def7cf709df3fc64b213e21a8e576ba5f94f3f1906e6b2fe92667d36f9bb84d4516d5e59a9c8844742574d9593f9be2d33457caf932fe88d9eaaab64095b06d11475962a126d3281db4dbcaaba28b98ac898f6db88c1bca175cfdcd05f79eac73238eaeeed54d3e877f82f47f69cba2f1df9c899b3718031742dd9ecaa8cea1658ed9e579bfe6b25df66b8091317b88c065b91f3f41d28497772d927ea9b1aaac61b60c03e6a3469608d16eed3299ca4bb8c15cca9afd693daf2ff5d252b6ab232502ff49c01f9280c7455ff6f668949ce7f040b95c0f9bd92fb859b766119a45214eb0875b611a9a48672372d962dc430e57821ad1d93c64a54197096c56895c2202e927483a01e8bbbf94f1f75277cdfca6a81abad818b0bf0996abad64571dc39529661c5879bd88edf0274d7fa228c888987f8e43daa11b04ffe022451c3b800f2adc03402d900f2d50c8d09aa952b1a63083f1c3f5da9a88457928cc57527f21070947c14a4b2870de2dc0b69f9385ab38e722412b40e9db17ef009c75bb87c2e90d90961665bb6d8d2758e88429dbc2a8e4a069eb13e8f1b97a3c04874e4576e111fdca0a602fc0910c43cd0e8e951d81b0f018f29c5e4cd9198d6b3efc07c1e590907598460542da6c0732b2be128a1827ed45eb41a74f12aaa0e608988f430d11a8b88f5d8d2b1bf4f16a957e91f5fa0befffdbd6d5daf9589e8f4f974473865485e11ba7376646904ae70c685042c44bd0b670543363d45341ce7dff33b80864971fcf30342afd65a9eadc0d2ef9abea30146189d628e0d49f517d8e6c1001065d3417afa8a33c091f87ef51d80c68301640be565178c354abf797697fb932ec004eacd80c71ac07a3111e2b68d2e5be4193d8c8d4f086d23907707e2eaec809d67647fffbdbf2d55d3de97275d00ee90e0e97836522559e751f80d49b5ac27a6a3d8a350f05e208fa093f66d0fc574b6d6182d5152287fb2d257b96712f25d570420287f6c081e1562c97850a345540d8635320b808a12203a33b41e3cac5a58a06f15cb07a835229951ad794fdf6c5314f1fd0564be60c5ead8a0648777c997ecf95ab31c478949f8a4a8ebaec62185cfa22b6a2912702c2122921d228650eee47e9c7d27594916898704311678f5e604b62a97c9ada65451bd6bf8cb5d15fb65bf36ad41a9eb75dcc9f6cbbce6925cab0258c3352b35488007361da94ad40a772eef8a3ce801f016fe08f1a5bd6b19b472d06e6b1d7cf51abd8791d552fd838e8147d9905fe957f4f45d208528ce81e0a3023a4a17fcfe155fd9ba8da0187433d65f83d5bd53fcb2af9a0c44c93003d2f75638a3509aaa500c91d89dfbb101789a604fc204a1820e445493bc664ea14285691e338c41bc6c903338a3de26984cc535e1c182fdab5335e78868bf77419c5fdb8bd0c4d85105194c776661381fb5b0c1918a3359c2197dd89408ad10c420a394bf6782421c76fa2c413eac8f1700a4d2e599a408eec142c85f4cef2b3a02d2041f91301c287171599cb42127925f86b2a33377c2246e0d23ef5f03dd35599854bf6e93ed89fecd30ff22ae29c0177ff4b6b13c8821b645f525357d7235646ab79ae36f80199db5f7b6e996d28bc204d7e77c98592334ceeae4014c21c804c359a893d599234dc478abb175c60f055a9366a9c5460f8d192ba4b3c46389eaa27afa3c8497349e015af0ef2d5602965a293052e2a5c65b2e5bee68bd4c87b1de20ccb1288ee839d436dcf28fcf676c95a25c7eb6356e7cadfdb77aac683515ff00849f8b87c8f4ff7986ccf96ec71b99e972de12e78a0b6e7d376a7ef6183cb7a1ad84decd2c62f112ae413620056bc6ebb804592373a2763d67fcc349262de963175ad752f01874f4dc085042715eba92cc3a6acf89e98e74594eea16fd5021529f56ce2c24a5367b20206553d56886d49ea97c658617f5c7a79863f9310eb0c41b12986a8123a47a3365c305d085e95a3b91a3b252cb398ff4be34ba697444950eacc0f91b8cd04e70c573d52bba0c5d6c4ceed5dd858e27052e0193506b3be3813a02ad4ce603234f42a8701e2f1a35479cfbb329e8b664bf05c3a1dac07a182292b5e6ac845a50306a7518ab968bc182008176d019b530c468419d189d1cda4bfc74ad74b0454abffb4de8f0d27a524350e6faf38b486f88728319eecd1cbf3e5a6c8035e0a1ab05dea8967c3ec483b30a2bbc67ea92e869a06418158d19046b33a50554abc0a069bb101cde0c99775e24477ca636da65621c0296eec97d93416c129e371e27c0100213fcc15ad6ddfaab878d42d0ba1b0afeb6a669a6ede9a5532ab58fb8476ec32cd85f0685d1d1b563c5bbe830bcb377e123d630e3420860046546541a29b69353770aa977036687214bc60f406c907b13e2cc0e0c88d4f4558cc37cb6bce9a822cb96a7f6aef1b9fee3415556a7fab9fcb1ca697fc399f1c81848f1f9ddda3b333e0395e0b93b240a46c15c6dd6e80a00f6a218ef5b12dd12f6375b1192c778897bf0370800fa4001703044d934a0814096e114c8f4d917c391dce35656267f83e691cd2bce4d85535beb1b717a9895b72aeb6c6005b639e904238ca9f841ba80c8be3b8ddbd04dedf6a9a3a44eb32e4619a7651938c4ad77d1719e5b51d8315fa936608c26151e585f97b6def0a364a9600954933164866536565732795099f070be558a4cd62a4443981c446912c393c34814d42b156fca03bdc5ee7ce3bd64c11de0c3e196bc49331611478628b2e1fa4d4a37361f16d1b686db739ed9aae67266649b079606c00864cd18027a7c94a9e6badf2ca6089f544f2aec8d601be83746e516b842deff8825650c96202df5b363ac98285af7c70b840586bfea016a7fc0a0f07757b09238b8a017501d3833a02fd001dd4cd7a8afe7070f68dc441f595aa41a9d56d1c595b027a338786b031a71f0c9dc314dea829012c7bfb101c66e07bdfec43984940a04620df0746b660a7f0b2bfbd94bf8f5c65347528bdd0eaa7768e8d1e945bbd79dd403803f57cff2bfd79a564932f33fd78fd1f1ede86928dbe96cac3e7c880e7d3f3964f7b619bb1a9876f5acfd0845ef76651e686626014edc449710320a7e8361001faf8106f9ef4b60854a581296f8c67013cc661ee77a8ae90a6fb8a515875f91c66a4daf26ad378a79fa84dd024c0a16009aca19b41bde47e111178b6401a38b299323599d6203cdc84d86022fe335fceea3f819432445d8c40f466b3d27458eb433b4ccfa21e6950dde3f970fd1db4633b14ed46a99029cca000c1cb8db159081885ed488b73747eabc1e3ce330c5bb2169b46e5d60c105d984c7975e7022037ee5257b3ab42e3b874b37746af66e67fb0acb8c00144bb557ebd42ad504aeda9353db997587890d82693ba38dfb2d4ddad5a3651774679f3bf10b3fa74e09bbc6bad660363eca714a89f588036859574016f5dc96dd0ca26a7d6df969b0e1540ed9011f3610216023608fe1030ca2c7e48c040b28927bfcc9d73cd6b94e0f6468970a2a47b7a9ed62a47477e0a9da44e0f6bc4b3fdf7d32164e0862fc392c3f3dfc20ecf31be82c79926726a4428d6a1998856644852874e47d3c3dc81572473b416f8920e45067161c634e4c4d97124545f15875c6a91ff31806dbf511ac85f9a0cd4f4dc84bb34cd15165726f7874b558cbd338cc133bcc523dc3e008e3ac095642267e5612233bca83fcd8da48ea746272fb8a8df15b06abe90d4334552ec02195063f982096cfd2c79a283ca0792387566af5ef65609d8dc6cd1e4e8a6f5b6dce079cdc55c8fca1217a4d44662264ba8b839418c6fa66ae8548d3d2b420f94d2ab6de292625560e6e271e6b6b3754e7902eeaa69205c01545ab29d139659133e5d89549e629f695303845f2f3c8a92702d2651a99a424956c3849ca0732fa868aee6bc2040430b28b0c91311e72f8a5a20176813a4c16d9a2e802e53f7fe0663a64586e2f456f0500541b8ab4a2418d178427e05d67962de6fe97929cf7a5cd1406416e20445636341f8b7475b779c2f2cd03219ed818d82e2a9727b45d7877c8b1590da64e7519fd343daa1369d0d3848a8f403151e4094aead3c2e65808a5308356360c2ffcddd2868ff574083c7862dc4c01fcab0e1a1245b7c0850f6d860f05c5dbdc225fa8aaeb45ff34cd1d4f31ff32b142e8c19f33951ea16e210aec600b90b53d1b126104d6c0ac87109f0cc76ccb3b06f170ce96901c979536f9bb44865de2862b8b09bdae34325b8e574e810a90ae5e5736b60dad4621bbb6920107d8f9c7d2c530d9f22f184f3ae6d9f1e88f5fa03bbd61fd7a78d67ce23dda3b666e0d2f03a6bb0628ad367b29b37db7fdbfcbf6dfeafdae69c7dea3a6c7f428b0b0fcd1ba07f1feb8a080071e325a1af73c1cc19a7693ef4f27b6696806a373d0a58cf54253fbac2dfce0e092660ba82e4e0d646efd646efd6464fed1ed10a4586f6153ad2f73521965890272393f1043e7d0192b6c45643ed5acc4397719a960ce273b42553aed997677006dee64bd4924e9a411576186c74257d9f9897e7b27b3f849bb2c8cc4e4432cde9676407aa0e9abf0793629c30401af9022a37a10c4cc01e636273984e1e9cf9e1168534c65b162476b9234692b8c3855a8afb2a4b4a089659288254d57142e310334ffbd244adc35f502a48402bcaefa395cb1a8c5b0b17825d380356392e1cdca2169bbbd59027b29bf033d681534977d68d33c1442413d047cda5e35e1934caeb5b4b57d41f5ab1196fc928cbe56e3a54ea8a790f2997c0ca30fbbd4a5c6e4800a85d77005936c2cae6eeaa6912b67418efc06b3373808c05a471399f132b778fd3bd1d46b3c36876181a7cadf794b0cbcfc646eff2d8d3526c7c2dcf2b31408b37d2e22004e98f084150c361978056be230195c36ffbfab7633af4fbeb5f680c79c79b15298b390ea2d9417c7bf5093b97ffc8fa87b5da4fab5ffe9c0a4812fcdc2580713ddf1081741601a1f7fc5d199041dc96b6dc8da2b951fc920a48f5cfa980f42c03fd8f6900e58ada2420a56f298145bc9ecf32c0f7fa5d199831c246b6c343bdc6711ccd8de317550147147e5e152493a63ac801130bfd116590ef8f8315a9fd5814daa0ca829336b82ca3f76f5b04fd4e106e47d1dc287e491b04c8d4fcbc3a28585357fae926266b165dd64c8d3b463d9bac992054d7ff7d9a4b6eeaff69e03bb940f8bbe4eecae76fd9dd1bba387de4e919b79b74c5ec3e4a58df3f81c311efb4c21cff74faee73d6d3ad4140766f0e162d1f302e5a3e204c76bf2c285bfea62596bf09962d7f132e9bff166076af7e08d50fa13a6c7637210a2ebd5f10970b715df34fa063c13e2bd3a52acad7c1a94ca92fc6a269bc016584964b96f406a7aaeaf96785146e79493b183380a6f44c129de310a5f03529cd4f8552c2851411cd58b42a45ef808f9cb0617ea8f2f4615052fff6e0257665090d2d60dc2e215e0956ca1405612c6344618a9786cda77856ea77c2696d3249b962eb3c0d90fe6b962b8cbf66c0e4c6c1d79f39f8bae5e05b43845e03d280aa046950a5705e0ea8b573b177b400c219f7c2e6ba41086ac904b2bc685d89fb25a6df41f9770d83dc7edfc6f3f756e80f17a04cc3d783f0b2961c1646ac0c2a40ed4561086d2cca25de1abcc4178a97793e326047626283f7abe6e27869049233f7219a7246944b223a303895c621d62c1dddaa10b1b7f4df42fcf842e4887991b8d31e5830cac28f30b6b151ad81e00266543e2620bce9d100f53bd4ed76dafdcdf08b90d92ba163d88d3d6afac6e1f259a0a01e32c90c520433aade8b92cfcbc6b273c046ed8bcaea251936a8795db2b4dd531b311785f07827c7d3ad362f61acd96cfd52f8e3bb4e5ee4a99c25c4eded2b01cec8bf82b22c246b9cc4ecb83d205fb92cd2df7f8b842b13debe06675d8eefc10743465a9034e0c50aaf05bcc8e07af2df7a916bd83b66b82351467cc7791b32e58ae6f19c1a25b90f32d39e774260b997c43d074c1877467d4c151dad98bffdfb62443e7dff0659617fd4877e30fd70ccae7c2846035f9a850d1e2f5e45727a50b5e0aa99a87c08714972b3bbe1d23f611baff63e8c9c6316d96df74318db109e5630dc0dc886ce6f57f0f6f7797cb682f737e898bd8d500a9799adc52b95ab60dc2723bb0b3bdeefa3ef3d00f4b651a192e45da71b54c01b84a0d89a37ac94d4da2c9b3925d802d7a695261e03a44e4dcb8fe470850d5e7903ea73b0bdaa7ad2fc7566f7130a1220d4a20521a89e56c74d381f8b223a2a5b0609db134d631f3b9cae2ba0946de6c082c18860d9c20b9beb15648511e87cd13e8692b77673446938e2604864034807c066f4e3cc0a021144c5823309a6149487c6ed484de448984962b6850a16928bd240b1cc46764161ff108a31985fb19573aa528e21908b66dfe8428d74aac610f61be22036552b16c234e91833c05ba2faf455ca39a138677d25f48239024247a9b960b78c7dfdf5336a0d6a53e823a9c3bc5cbab8e08e2e8a1839586ae127a638644198e986b6c54bb9497caf15b3c55eac88c43446224ea0a3f81f4876d32e6b50119d1d23e1068ad6f25fb4a4686788993c0d38519c498a7a8b0e096a8c6f712283fba9446d5592b2ed6e2030b64ced0fb66047e91b7224381d62faca5cc969527b872f43b6db72548b1b31e8944f9023975b921510e23cc91b4de7cd7ab9ff1dda6309bd6d2fc147cfff1fa1e7b2b078a0e154c3072799edf4ec3c8a9231f83c8c43f0911933844a83bdf35939f3f49837255ff39fabefe7a05a8858bdf62ba39ed39461eed2d0a2bdfd11bc696f473c4f827a3be2566d7f9e5f19f2fa3d82f0c4083d3f84a3c10f95755776d6e7559c6300cbe8eaab285420b6a846bf59c3bab842745e60dcb31e584f01646f5a5e0d456a12d86810b790ef67355786c9c22b4a754b14c501d7402f1be3910c95689858f8cc589b2d3de091cfaf88ac0685e95c9020f9006a0bc054d2640ebcddc5765602186cc1fec47fa5a125aae8b76dad99454859c93efc19116d6cc9ec0647b87939f744feced65929723a1643f276a96fa189134d6a4407a626f27f08f9f6e4ee309955fcb1634f113b8996d0f9ecb0243b8314c34ee910103452ba79104ce8493b644134998a24bdb6c64e2b5096df18bb2b4394d9f5725127a374de0f27705b61ac96800b16866eca99203f9766d455e0c27728de163d5281e40e047f4e6e30b5ee6b938173282e30fabc5767e370de392deb32aa4911142fde290ac464edd4b0318ae85fe1c69e137bc5f10352db2bbbb96251047a36b5189619038ec7617c0e7d9c10d214cb420ab332f8add13062068a689298f73b2b39ca782a9cc7a21cdc5573e2ae930b2823874d6582049a42c52d45553e013a552ea24f09f8a561b62d54bc43150fc29e570b069379e23378eb24af93a71b6a757018377b069fb68a0b0da12f7e9da4c429c8a1944d22e8b45ff854fd64bfa47ff17e6966bf74ef10460bac170bf8b061f0f0d194f06f6f9722ad83dc7ed95a3825a84cc9c15626b81d0373f78b3b86b3dee39496b2c93ade32a242140076e55fdf2309f788dd9287c7cd13cd34c8ef62a8ad3d5be8c3513402504c5796692d35c7be663b4365050274de15de3ab3bbc4633c28b1235560da24a5a88224f61f4df462efc6e3026f21bf6bdf1cb97b534d9877e5956278384dc41b3adb6a118dfff1cfb6d5b6c8e22f186a240160a72d3afa836bef3bda96cb10db9d76296d03eefb938471c208feca42754aa20fca8b0cd04dd984d1b088521831b847bd54d9f7216e2011bb8d83b5271bef520c42e40a33ec22bd0072e2250e26e25a2e5bd47cb34d69705e8b5bf99a244e4ca7624089da60c45d40226ba39ab3567d2cd987d841cc10d50b3922f73362d6013d5d2fd14531dddb2fc25688f179e75651407925008ebe6af2947a5b1ff36f66c0da3d29c11680c0f457ab0ac4384807051c0eb92f70d785bf64a9f9a6fe3d08d38f65c2e80a4c855d2e50d3ef0c62a142c3f3f9af488dad9e1dd9697db0916c726c3fe4b7cc58ee7799b1313031561b462f3b6a50ac4fdb325fc47b065b313004c7dbbdd6f76be1936497364f39e5b520461e0fcae0df97c93a55d03f65aab0bd07c3ba1600405f725de0406ec88f40ed2962d7f9b326822bf02c46ed6196abdab25434afd96040b45863bf7f0bc5ab249ad3fbc202f19eedcfab30efdec5fae923ec53f8cd7ace444659a987583ffd3c81c90ef682ec4640d91cd229c554f542c2ea30b76488fc6f4ced0455cfbe91e3368f32165c0f935591905882a2ae020f7d48565978ca797a0d78651883eb7f60b61399d3f93e55fb41d66a4f0568589d4b2a9a0754453fa7bf72fb2f7159b7f7890e255718ec1164c84430e751d0d30059e2182eb6dab75bbe15132bf8347936719d66002639c2411ac51179e21157546428180aa320c9714851641c8e4204ca22e1596cc2ab4b621b2fa16080c432dbc4c2f0b9cce6eb65bb634e542df4566c78900331bf3b3eaecd26ae2fe58df355e8edb551502fe7615b46149b88b1a229369709b441955553bf28178b774e0118814dd955bf6cbe71354d8dae2647caaee46b212bec6efc8bd408c80af98225c1fa35931512599f29e13104cd7cc17a1dfd9ae55ab06debfb7ec37658b37749b241dd9a2523933430735ad575d7400853d8410ed2121b312cc410f533e7a11eab5f7265023be2d14e591f062861a0c22479aa66f5365d9fa49e28f7bae3eb5d65294e4e57730968dda1fc891e1618ab2c1d47aad1f77973d0d113d228cc938fc74594765f002251ca15209857356c944d0d66135ef8e056a3246340d60d6b1eb46f83d27dc8aa01d4f9c15b055aab22528d2198a24fa0b14a281d9a8dcc5101c15189ba60769eb64311629873e2f27862c2bd00666c8b09de809aa92af23a55159a19246782387d27b7e1c370c207c389ed66384b68bf5955f941a9e8e981e1c51cde9f3c4e72b3727cfaa8cc9bf75b22177fac32f51ef83de1c63f5499face1059a501a77adbfd815cf8b1fab87fface8d34f8addc4839f30fbc73b56ae206511367ccf2a3175e9c44edfe8585e84a636ce9cd0bcf8d924ffbf63884f584f166080d4fc9d03f1ac2c7b3b09ef020ea4bd6caf767e1b3fdbb3eb81ee46e31f1a1b66a7aee3d3cff33b1abac1c1fa6a02e625c9980983e19c034493f1fc0b4391fd7a03b3178d2a03484e3092206df6cf96cb8d48be7522f9e4bbd382ef56ab9d46bb65cea355b2ef59a2d97ba69121a11342643c87e08881b6c784f46a2d508e929b407156944a1d8c441153207579eb9359efb64f35b3653994d2aacbe6c0d3b1f4c624586a4f97e6d82d1e071128cce50521f5d8223e2e03985a17e140f1fc2a498f7e8dca91e939fc9fc090502c566338b9dadda64f883f38a10d2c5b2d44339fb8a179b78c67203db2f95abcfefa16c93de66c900f146f5eacad19bfe5dab028daa4215e4230ac84a393afa13d3d9e9dac1d31b8ec2dcb2c44da4ab6eb9c9d992194b8fb9e610becfe3f9fb2b3e7fcf4407f73780da66f87a40a8fc3862aabe04e24314298d08c46e6363dce64dea9b7df07acbf174cd93bbf4c0bac1f5320d1e2b54177fa3dafcbf05f91b16445ddf7f514df958d1b80aaa2912c08a75853692d680c75eb65c1126950d8a451a94cae928dc3ff4c1b4b483e368b17905f599eeab97ef1c70b22b4c1d40843bde572f3f0527c424a9b6388f7149c97f1099cf9428b25c55e89ddf77ef227d49fa604c00dfb130bd8dc195c894db4e78f5574a85e55677a39bb333253c492bece84a8351c43eab4e0eef58cf89d1688b56a6606f54a2476ea823173e431fcc84095b8bd37a84a96e1080e4c63c72b2265b7b595ecaa02a31ddea4e62cd3b2c1872b665e0501e30e8e02f19b3509029c26a01fa66462bd150e4a07de52c53fcb29f2aef100ad3474d8927d33030fab6c01953ea5ab9b9c3b693a30b2941bbefd03bd9687c74ce86c57c3b168293cf9d826a500a39ab42856e5c835c0eedc59734fdb0a4bcadabaaa01157bb9882c1bf19b7ac17f71f94944a15cb743ac953f72f45fe2b419cbb40518ca7188e8801661f4bd4d9e5c07d53b0e9522d727525cae023011b7d005d470bf8064508bfd7fb17da80a9ec33e4934a5064d9b9793488d8389606fcb532b6fe897f46ca4cb5428d76c222225c523c96779fe63349ea4cc8bec8d7db404e4b5286361a84baee125f1b533a829a644adb865bfe9bebfd17a8e9b3727f837b7d5bebbf73a52f7eb9884c22b6d2df12704b7e3d6993d8b97661ac96620a3c8efe27e361c997178899200039ed456437f85e34ec3cf40931fef1a6a43f0916fe5f596ae6d2ec0bb7d0299a160ea0109f108ee34ded937b02ad5da347cc8deb8acc1f19ef8beb8e2209c3ffdd1ae8b528ec92c478dc65f73042e1a74dfc87fcddd56415b518235e91e58a85d868daba7a3ba4a21c2560ae4f075216a9e3cd24d22a90e660cccc9560bc4c9572fa4d2b78f51802b2cf7912c4db4740f8315a30ca6d14b877852138437e227e7fe40d20cc9bb32163f7cfc05aee9bdc1fe31efe94eb412cb1a0fbb92de8dd53b096fbce30ece41967f00c8d21610140646a944b7d9b2c049f391eddafa27c0b1279f1df277c6221acb5a9962eaa8d284390284693b40aa822989fde8c8dbf1b4c76107eeab6a0be0c6068ee14056cf38e90ef649b156f68ed6829b9a1c71a4f586b07e3082db785c5d27de4a0c88bab2e617c6c2d021c9c08c563d51033d7d2117fadd8f9c580aabe44a968eddc42e06b84af6a4baf1ab9b45d8be962a8f273f639aecbf91cb347ee53114200fbd7c49a0461362de876ac469d13b41710a9739e7d2826755774096913eb582f184cf3e7149c749774628b3256884c4a95311c8401229161e8fdf4d02af1543d2463076892ccf175e1d949bb094abd9733d8203a17862aaa08282bf5477509668fb3946fabbbbfa6011c80f1727d3d9b85632d0b39442c37cac6a46936d8604733e1fd97e5360393734a7f143e6686241a269d97ebd41a54cd5d43aa91a09438730e0cdb54b93d16708b01a6317d6b87711092cddab5c5108c0bebad4241a0188ce85d779b4c70882563cd2a3442c74d55b48a450ece603d3eacf18e57c1bf7462e686626c9be2ca5814603af86d79bc7e47159dae96b8d79ae43587de50b714827ebdd2af1b43ae1ca25893574d4d0ba9d8910e11f0c8e3b8ecb104329ca0aef0d4c976f2a4de6d29857d956c4a57f77d62da8835b6f3b574361245144956396d1450f719f206b251b0b9a2dd16a579e50a49996017fe4b3468e179617942eaea6cb75605b705ff7edf177e0f9c36ca47fb024f1bbf33769b38f84808ee85bbd9f8476c8c53e5901e7df7bbc2f868996c991e1e0e9ae2c2c8cd8ae48c721cabb9bfbd27ccb63b3d6f4a6f88f6fb713245e3b55b9ba63c7b2dd91c69c105c7bce3c2df4b5f8212f9613fbe1fdeda5952986d8f80fa7804a8823bc8ba11ee7fdd19f04bd24e6700b7d3b0210592f613ff23184de9519adba6e1f38600ea4ef91686e0331a1550ebf366942596aaeb14d0765cd6134760a2f81b6090dff11d4eef2e9a0a27f0c5d87a86851dfa2ded16bbc833c99877122b2511344d53af6c6c2ef3eb458f970b1e1799de5d93de8d7e65a250b1fa625643b06842bf73e5a73c7cc47568244640478dab5a7c98052def6dfabd7bafcb291b60af4a92414f5c9276785cdd9f10ffc062c3cb580344c62cf85f29360ea9dcf972a61f7c37750d5bc04d31081890931d39671ce198d699376d9a1269858a1b66dc5077ae573149822d12eed83bfb99bc73bd4a5b9f054c7b44606bf97bc83c9327ebb825f31493722eea75106fc91353b7e30c0d8252341193713a72e3234fb59082bfa36eb051fecf7318e19cc2087f5302e3274ab90707d2388676c86734c025e121c571e56cfaccacda9c86191e8ab9a87eaba636469839926dd12101a9368cb31f2f79a04e7fc4dcda97ae2aeae89a4d7551481d4e75132cc1422e4911017700574289c35391cad2e1db8c3e8fa7daabbcd57815ec162fd381c85a988f82b04d94cf00fd23826de63fa7ff0ab4fdcd083f57d58d0b9a0c0491c5251caab0f8f565f195d5e5d2e925130ab67e1aa7b1695deebb332551791b8c14ac0b1a9bc3fbdadb6f29bcb559aacff50cdb8c6a41ac13d065cd131243b7d38c82a5511399e706227d50b72f7e68eb846de0143630e64c03f6b285a1a942d9291786d6620b4367281b0b43e9021a8b7c2db1fe9a6d6168cd2f5b18ca179085905fae30b4265b182a400781e5272c0cd5af39a1c2b9101a61dd0b437fbff0eb04f498d19dcf4a96185fdf75db1ddb8cde3c8a88013eaef85acf2a9fde7efef36115ce77abbdee4bada64cfe50f1d37c5f936883b29fc31bcf64db69467fb1f2693e1f64c7543edd3dffb309e7e7bf2d7beaf99befffa3354f0384196b9eee1e1e7face069bdfc8097c792a79be72f7d7d787e8adb00a6602d83fc536c1e376d7d1ac167e2f7d17efba82476520b7c435581660c77baeaae1e369c645b860bec082bce5c8937f14fd47ade4dff070258ae8f2a3d9b1bce27ca2f7ca6fc6431fa2f2e064dfc374fa9faeb4bbfbc31ff2c0a3f585a0cbab52771f07fcbc99eb89e8f3bd3d2c9def69728aba8c1e45e3ebbbaebd5a6df84678109c6c4a56f537f992e9e1ec7fed8dee9b446f8f2d9963f26a40051067dc3700f2c42ae30e138fced651b837eef35334f1c3630cd9af6c743cc96f1b74793a409dbe4d394242b0f8797344d0560306a28779d3f2eabcbd99d7e63f8ee230ed3e3a5c337b17b3cd947dea7301a9a12732fac0bd847925c796970f5a7562ce2a7ebb18e9063753c2e48b5320ab1295d7b24fdaed07021ecfbf5b1d27c807ddb6c1e13330fd747af7652c7f06265d8176befc76e38be4df8623a2e55252aa52d60128ec198c4d1987667287fbdf7a83b4ddf83f0d577c2a74c4cd7511857acb4b31059e932b7865de07758bbf61d03774285f4ee4ecd497c39ef5559bbe2a2ede551dd75f74e0ab02c87f2e1f8501f316e5a3fb305fbc1d45322a86b648dabbbb9d318de20ee4acc54df252c0e1f6e005cf7c9e5e296a6abe10873730f28562b4aec017415ee921f951ea6543b89cfdc89396d8b3c03299b0c6dd228476ff9401adb1b69ec561a65916ea571da5921dc8a232527cdb414737434ab3f3d3141717360f736848bfba37a6592f8c773c3513b7866074fece0791d2cad83637570a40e8ed3c1533a7846074fe8e0f91cfcac6978d16462ad5a876824833ce14fcd87d3f14726a3401a3bc78df380fa01a645a52732f694f90567bc8de59313b1d5cac8258c0ef992ecc2494709c7872f780ddc0cfff29ba10db4e0c1d2043c8146ebd63e844a5e391afb4d412b57b3e4adab397b32113fb0dc914189072de99e565c0d3337cce10716ab5d5ec81a303c8cf1868b86612c2300f86da5a5dd8c8cd5ac9b6c58303d96eaaddd01e8decc20972c73117dc224bd7d4d0e3d94d34b7b82363707f8ce50126e9b092cc69de56068ba76424919cfa0d91b939a5e38082d9d9c4b59a10d78cddb834adfeac90d2074407f32ba43bc7cde57eb5d142f7d05f3d6022578eda55b522c9656d3e4e26d8502166e450cf8a234d8f955bb017e8fee4bba267f8ae369c6061fb3814776c478eda68ea849aabf2af87f58fe921a31635d419c2421aaf94ee069c85b3bcb1920e917deae511890df6eecfd1bd69fd8e4e2a29a92e36d8e7d52e65ff80bd3f6429eb25e8fe68d1b97d89882e5971c5c2368a16b924744a18a08c58c7c12bc11aae20a1174b5a08befe06a46e64c6ccd93529a251b6657aff2849e4c0ad50d8450955ebaf386b8d327d680c09be0efd9c9912a0e0c21fa7ec5c7c122968a6ac1f91b8c196296a22013cdf111d1c05e99b955450641cbc1f4697c860f73867fa2b1a902bab0cadef2d687dc2498512693e712793e8f67d2785b16cf25f17c0ecfa4f0b60c9e4be0f9fc9d49df6dd93b9bbcfb6efc4f4c97e48c9502a64da08e311674127542b2d1e7a293b2161af064d91e1a62d50d699957d0279262106f12b1d93dc0aed3e3d664088fa72b9fe24ff210ad3c44270f11e5217a79b0137fb32ad2f0ebc9ac6a9a4b6f5918b1b61c2874acffd3af11b05a8c452b58d12a4eb48a13ad6245ab5ad1aaea4490afc43e448ffa672256397832e331a5cf886a242379f175535d69f9363249492005dbb848a71d56c1c2021c2ac083020c26c0cf7ab1caa4386552509914af4c32ae4b3b4bde7001c5649230c1f95e7ddbc54aeadb1017cdf89a0ee1c6a8b47c839893e0513d193812d7f7c53d4057804769b1eb19dbaf812551b151507d493d90c47632c6761a1cd92e5c2afb6adab341713864cd6cce8b952553db52da61c2ecf544a4bfa4da069ff4e05854831a8dca3e500d09184de8661bbdba8c55293c7b990c96e13a2d8106ba0408ac2669cc4064d86dc91d469f7c7a250bb22d9b883fc7b224b68588470ea327138a019e2a38c87c6e62c5ab76af3a1c227b3efda470360b81053693bbd8f8422e4e6120e99c5bea2cdf1124ad6e3500584f7dc3cfd3b393bcdca41453aa310ab4c68e701ac191198c49c831d25cacfb0aac3cd808e6b36db5da05c0bee23246bfaf301a7fdd4d1d45f4ec10de6f7d43c492bfb1b1d9aa0dbfa66b9e05ea3b2348fd67b55dfa70554e43a2a3331d64ceca983e6e1c648eefbd231d06e983e7ac99094186b341d0e1506b43c2719045da0cc4651d480f1a92fc62ef13597d174e56c1f9b778c11c4d7f5633edc403fb7e1f95715cb1439c2f6b070f6bb0046bb018eb2e1eac889f1b7c76872bcb931337b6c5dac9dcfaeee8ffb6d0f949104d54b95866b8621398dac88bbd6404cf98eeb64903ccc49d1930fa132f2797e2ab71297d0f1aa0c9948b8b6790cfd1300b2f6d8b55ba029b55723a4a0ef5dcf88ee42c85ff56510d60ec4ce7e928d608bbd40196e16a4f90d595b6ab09969c09567613ccd075366782e54bb871b87303ce55975381c286176e015e1e0d03a6908e2690192bfddd9df9159cf995acf935cdb3b2215cd41772f80a7ef2c19f7f678c6116548e787cd4e9dc80a536860a85556ce7ed3f68a9b4e5a3dd182a5d6e26ebfb762f183325bd15f4b04fba9936194b389dbeb42560dd5fda45459c42ec8397082ffde814ffe108dbc761b0bf5fe59b6044b0c18860cd8dae2aff312ffafbbe79945a7c4984fdbc2b0de7c47bebd24d0571e297dfb42d4de020fdd9c001f0a4b4bb653e6d635ef6d352da5ff3818599c8b74183df3db1fe6cd0e01f7368a18cfdfe9975eb61c382a7bfe5d41a2fe8484e8676eb26e6f90fd7eee2c461265fb4ae0bf3bb1f5b70f5b363c361f8b773bf6cba7deb9b00fa114fbdecbf82c94a8b683ce2e5134f99e2a3f95973bb157b04fe3af2d783ae7e0bfbab61c9ef227f2b1151dc2000ff1ee0ef3dcf7a2206803f04c7fe072d4abc813cfdf31685138bffd34bb292f1ff3484fcf346795bb7f0d3796c45eb74acf35e508c7630b69d499fd5999a08b578497871a7fe8102a8c12dc7c9c0e3a021d0bc28060b73df1aff401e06a005a452f60ca1c88da19aaaffccc965280fa2e5a8605205ee8b2285d40bd0d35e7be32dcfff961950c96da98e6f73cbbec0406d45e90695cff5f65437b366b650bc9045320b7b0663ddda99e9f454620c999e9c9ea437606438eac3683184b97b00deb46d2c79f5c0c1bc5a4b94bb056d16d5d31af267305046006fbd297a6d4d60de9ace62130a1b1ed886c7785968b0938a62a8d7aabb56a4489dd0646d943faf01116914e49801c865e43b63da3f9dc5cbd5a577a1fe6622e85200b3b6e06954a60f2e4070a41476a9125e32a17919a67681e0d4fed2342678068bb741d22842b82d4c23a90a5f0e1194690b867c21b7538ad2ab48f5f2d85ddf6d99e5ea1e5497dd18fb7f141c73d89c76d27fa9c7c7f399934fc6d947bc078e03e5f3c70e225efb03ac014f364fba2b66dd4bb7575bcbf9834fa7dc54ee3f4ff9b186fd8fc2d5aa915051fac8070d08ce21a577ccbfd38d2ba6a4ba0672c86a068f6b6d1c17c9bb45a514392219f4904d26dc5a6c43a0093c0ee8d69524a0acf58384ed25af2a24be7ae05e06d940f3a11f68d3013f84c4542e1511b3d1d2f1538382007ad8181ac904ad577e284b82666e7dd03b8b3a7abb0134a09c339e25d139f44f20e763736ff1797d99a444aa12292085e74bdb7e912f8d016e379543ceb009cf604a46a371728b23bf745aa48d88962d2f6890711930f39476272ab9bb73332ce64210ae71142e30c72e3768632772455bb4e7d3c5f6166b20e8d231079285d3aa7802384b2dd5b0590a3f52055ece75487a5943c588ea84372bdfa4bd1f754f2d44e4c50f1c037fa34cd8cd5884d7cd90ed1b0b47cf8f1d97181b7b7b7afedae9717d707a505aebb1d2f7b2c995ee922bdd2557ba4dae0c501f15f7bf007c486f176d906bb2555c3ca34458dc6b31991c3ac0f15c764ec36b1684de2c7dc378f201aee8f9d50c862987e3d32fdc204b8b741cd8d6df24898f66c5bd03b79d38060832ac5bc183d754cd6a1de3c1cec45102a661493f9376e04a1ab15e99c9b36ec548c46ef5ef998aff63ef3b93dd387e6fb7f216703f740efbdfd82b0238083d33bc946cc9f6efaf2a5916c9091dd0c838382b117f7629eaed52386373055470a948dddabb664835d25d5c02d52b79ae2b610b2baee581ce0f9892f206c48e304351592f51ca0710203abbf5ac2dbf0c00bca11e19abcad948610b5575085498e33ed4d7903bbd4ec7864ecfdc4167dfce9c59de1c71eaaefbde1e47a28d2f75b2fcaf6dbf2a88eac99bc67a624ee3de305b51d2ac43d22c2f6996e7dc5b6208bbdfc510e8eb9eef07f6ef3dacbf876ffd37d6e25fc0b84a334eff37f0ad1fe054acbe32ab09bec9fd379fa14b6472d5eb3c0d772d6b8f6b5dbbf7b9e4a46fdfe95fb147e58c25b0acdf9f70c5d06f4db014a6bb52bc8b787553cc095dd5db1b4cb9e68315c4cb53cbb70606d0e3a7237a3cdd22d29597d6dbc063599f487e19f9dcac0300d2e71f4ec3d28ba56a70391360f2a8d6b839c967360cd4cfbb92e2ed938163ae8eb8635dbb5bbabf1c8656b918eab114ff281905728c3421ad2e5e7464740f8d37d3b3ecc8f164e0573321d88e5ad94bab9e23db4decd9038abb68ff512bd5ad0e86bc9063c1fcd4e25a738c09d69402bf76bb0022697735e469beaedfbc306ae756741d55ba94d6ba3e88cedfe3fcb2d114cf6680ea6ed6d80086b851754bb9ecfa7d388f68cf9bebd2368434f17b0d1d20e7018e5ef4e1d5656ce05e8ed054474284fc541c6dd27a05c81a6a31e10a8df776b7b0971cae15df37767b17d206593a4fb9c206c233d58411e95018c7c01350d11befdecd1bb3aeafa2071567cd357b3003822fa03afa59e3083b5a0c18d8f9426d399cd8ef66cd5ec7db49e2b90f9364b7dfdd9bad3119451305f82d823e943b8e5c62d6d18f702ce5b86758f207d8d54d8e66ec95ccd00229397cf5fc1a4db36d5c164961576bb3233c51a4ef002db4df71f6b2b1fb2df41eb31abb0dc44e01bc26cd4320c8862741c6b01336240aa43bcea116bfe14b869fbc0433a9edf8e7d94543f109268c0a45a0da820351bbe3a00e3be2d272da35b5ad2eba9a55b4383920abf626d7f65a9ba31e6c3118059eb69f9cb222125f4ccbe2e56fbe52272995403443866509722e276d66c878c8085ecbd33614aa16eece3e3970c677735b086f5d6e4f29ee65a500458c75c27a668da997b52d97d8d88edec30e6eb2b89f2364085a8ae13386b00290d9b0f9585072868c8fe65dcb4b24d50a3812aac09d557ad08e81b2b2a4bd599c35ec1a9d756d7a3eb1a898a55b4617ecb11991cc75d7decd9087819e12d97130cb8908c0305c93ef14140f3c7fb34e66733a4c9075a73029cd2cd75bc7bdfe7ebab117697075c67c1e2e8c369cd727af8c92dbb8f8bb734cf16797bf9c9d05cc16dda5dc03ed4434065fefe2cab6f2db3aad16db08fffc931ee64f5b1950c06ed1b17368423c3e08ee9269553ec7c8e6b794ef07e2b2888a78c63e1849fad191f47723d1ee497e7f3e5a92fe3eb38b617a9cb898e5081fcc72c40f66890184596379c6ccb13e63e658a0319d97f135afe98b43b2e8dd67cc923e3f15df659f1c260a450f8d4cb8db45b5dc332ee06c76ae1397bf0e7305e15735f18a8fd0a5e158d286e89ed73b18085c2c9d162b5ee901edf48cc8163b14e6a6a72a6cee9e21c0d27c1d490e488c3612e3a7be228635c8e157c37c460e7f8ce330d32ade72845051614abf430465f3bb39768c73452a8073d5fcd04a1a88d30228ca21209ce3af5d39e509f8b48fa069702e76c1dc63f3bd4d1567b6902eef3c3a1c992a9bae72bec095dd3dcb91b0c00cd8cd20600ecc214b3f0731be2449bf7a9c8ae11161c59b1f52e64deef9ab8113319cf0a2a20f7c91518b313defb2e42f76bf2fe7fea8b0bea6e01821083c930f28b8539354f8b60bd83011ded603b593cb26c0e2454d48c7027cb1614ff0ba5533ba0bd4e0457f92c98ff698db9365c74286f2b0f3ef7204dabbc735a9619340ff8de7d6d15e7d37fb014eb82fb55f4b2b8a3e5d3ce871e5a246a0dc867e6e6ec1a6f3859262dade85b4241973ddade0a1b78416c4e327374c8fd88f6ed8c37684d1941cc2e90bce79e7a6b314bce6cdfde53c7582d9db4f1bb1b8c7e614036e731890a720fd4db3e6d6d1a29dd9716b410c2f175fb372998ef45017cd3af21f2f79b1b2129667b05c26bb436409cb5a76645b1132a61ded45de6503fa20225e637865ee471991863c89355a5da4de1c82ad9e5532ad0f9751478f1812015256bca564944adcced1cdcb10a6caa9b84cd3649caecafb9e4abc1df9d8b3716cc3fc896de0f1b93da1b0d463e048fad9b935610fad36d9ef570e73cf510a37167dceb67c6628a1c8444d4376730c8fb586705b2c727d6fffdcf394c8342e03384f034640327e1aa10d072f7ea14445361febdcc8f9f523213e3942eb340b6789a1bc598e589e5c20c13cfd5973af668ec95753b3b38ab327148dcd7eae7840b04c67fddec88d7e5b846d1e2db577c66b1777295eb192b3d39ea89e3951fa2ecf6bc4e4dc7524e7ae233977c5e4dc1d9373774ccedd461e2bdb4701fcdbeecd19681d7f0cb4f7061a6b8e3107aeae5f63a2f5d344236bdee9aa5d6d07d694c797f6057d30d1d26fb7d0d077e9c146f331cf60a351ace78d5db67fd02cebcf669984577c4d4d0b56d934efd0c04ee26c4796ddbd0bf0b6d3c18343907f0db955c3ce369b6822ae9a78587020ebd51c3bdbbb6cc807678d0d3b968783daa7522db39d4eee1823556cb1ecaf0074193709168eb7eeead53603c6102e7f34ce0eb0ff6f6c33dd9374a7e9fbb2cb9b877d6498913caf9fadd49183877778d3ed9b95eb29223d7bc3386e83f2bd3d9fec386de9d3dcda4e1f68621bef432b2eacf555a73b8128247c576e8f87c782f024327f8e2682f9f7394dbcd9f2c3a6c9870a6601dcec63bcb2bbe02cdc4ffc41793e0c867cc1d75573a69ca6448ec6cc89d0d9bc9ff8c0f011308ad39bf6890a7cb7ff27cb8bcde174e94eb1e17e3e8dc50f57f631c39c15b41417b79d2b18ec961e0db3fcd37619ff554754d85c94d74b9363b7b478fd5c90f643ca3eb12b92dc41d7df51d5df87a6bfbda2bf4f3d7f45357f1d5afef24afebae8f82186917e54c52f9a6d64a5985f0ee245d353c6f87a6a4163decc126594c77af4517f1f4a935627ae7f246ee14e1edf5e5b518ee602fff7c8091ee43ed80725da0735da0735925b8df6418df6413dec837cbc3a1faf3e794b3e784b76e7d3773e490519b8ed4e1154677d871d476b24757bd30ab1cc83800cc70aefd508a7ce72bd449cbdecd5090775e3a973a971024d88676bd80d215b8945631505cfd97bdd32d2cc4a9224600335d3f6b31d6929a8b6a13b9aa6df6464f9c73e4d397491c89e9a0df893f1f096234bca4ed3f2c6d963f21a553bfa6cabf1153bc7bf8c31b222e4f7f9159ad173777a587f532b2ed23cbe3148c8291ccc0654e378aa9eeb299af8bbc1e534cee1641b2e9142b2541c1a97e440e917d3a592d1cdc5720c32f52696e9b0102739e9d23c0b0f549f28ab24a19ded8638c169c8984afe1b5ca38342576d5ec1aea3ec18e0cef608c2e9db96f5c8dd3d64d4c083cb32589e9666c1c5963ac5a54d763fc616af7fcd4b0a69e502fb428da752e3c23693f76c995aa61881aa02dad13657be107ff672f74cd1a6777689562b2c13ad7d29c7dafb952e7a9b3e92c1a11c91bd2e4b562dcb4d63f28e334dcbbf65db2d6ee4768a68f2c9ed6f4fc74b69d4118064c949aa4676da865117a3443a94eb1d65bb0b5e94ed892ac58fb498cd0639641efe604c3b5ad31a414229f0251a2e31d98a26d0d5664b63b21baf427f2b2e02f33b18a304b686a95051c74030c3cb831193b145465764064761c00525bac75deb4bbac3f9a0441f2d23a05a8dbcc2a9cbdb72ac388b69f86d4f76876f48e4a8879eba0246cc08c9fe93d31a7d9b8582b1c36e1c0262dcceba9cb868f153f117d6f053fc945bd8248490649d58de0f0196681e420625aa8bf3969d0f888bcaa728eeed2894103d1622e0b5a4c8eacd9a0be89a79993ee630076c3d13dbaf1ec88752928b6521e5a0b380142599dc12df859c3a5c089cc814f516fece2c719a5572fe7184e7587581bee174178a11040f6e13cda50504e76e482949158f0dbd45148f4371694e7141f059dc16ce877138f97c9359628dd641b124973fcfbf376e7e8bdffb91206c4a47f20252d510be668843443401da79272bb89fdf3cbe407ab48e33af6360258cab36fff36b55d2f7e3ec3d0eabfa614f1ba7dc4256413dbff14a0c35f9a84ec920c9d7a79749c715d297ac1f622b1797769da99b5df77a87ac93537d78a1c3d0c232efe33574184a713a5921a6e7a61cf6c630d18bd0960e6d1a58ffd4e892cbfc1e87fe32bdb424a7a7bf85a5a78160d0ad252eb2dc20427dbbdda56fb6699b6ebb9785c83970ed5a3cd2d5fe967cd916da8499e326f845a73d1bc929355528c0cf85ad4c470e595ac3b8e9fae3505de126465ebc32b655d3e651d9204c2595518461174f81ed50ac02e93345f66ef291dbf2e583d0efa938aea8ff8225e8f6843e91e91fe5723681c562c3b048b89789ab436281401d1ca1d3306419fc2e6013a774dfae24a31e4a09bd7928f6ea5439ab72408b4ab74471788cdd9529d2f0aa9b8babb9d9bac33aa89dc556b7b3c5a58ce170f93b48c865af6b7262badbfdad511e676088ff435bb22a968b774796a5c02683abdf4c8a932a63cd8a4b4cc3cb576c93ee9405c8cde42af21c96c611bc12231ecb4dd43dbf149b5964a7c10ab26930ec0a266019b982b7acceaa2faa848ac142f16217f94b27b52461428de02e23f1da83ed303cffdbe4563edb66b852cf2660403449de199d95a88b44af1422cdef7d39a8372c2e4de21d81f7ae8d641165913debea535852ce6d8833f2987a9bbce40c225ada882c55dcbaa2745b97357d9d38fe47b6ec12cb42667946c4863f9839d48e6ee01624774ad94f2a6f270efa7c06a7214b693d613880e32bd6814e38e15c26973824b56755a9b088d9bea3dfaa1d0657c49e3f53f97d1bd472f4e31d96fce6cad2e6d63b3d0a04ccad70288b55816c77a4c6094e242137dbc798c07052a4b70389da56f614a9478c1bdd493ddc4192603546902de0ba1ee4e9f86ebd505c2811e45df19e9f0a061ce7e7eb76c59139544f9db1a761ab5e8ea8651404c94665ec74e4f1c6949d52d69b3c1ff376ecf85200529b3e1056f184364d4250456756f253d8b10b8972e32b1e64d59ad1b07f3578dac400cc1b9968db579afa586c75c8b3d3d76f6c14cd0f69b1ce84b9c7035d6a8bbbe1931f22d057f784edc3cfdb571e6a0d5b242ae70377b4116b7f8541c35a96c35762e96f157bdd619a444bd929c05cb556c3c97e77ce45e667079b9ac538d5eae82fe0dc3184817194c406b28f0724cb7e100f0884c83a45a298d70610dbccd8d3104dacb324b95c74afab79bb9ae4e6bab16407b135dc0995b1d4e5c722559bc58f255a96e904251c16fe90242374db8684c9cd181b4e302baddffb72da2dfc8af9f68e1a5e1eb089c664b10c563bc739fc22da940dbf811f28a45c4311944f33770430760082cd9cb67af63d87a12d8977f2b1cf2f40e8024400f732e3e8f63ea7aaa3aa1c600dbea47f1e772c09099a919114a0c93db28d837d1143533883cfdc6f01538f7b267db3c32ba639b89b936b017f2859cea3d5039f0c2dccc5cbcf8120abb54d35b0367aa32592379744af2a8d5678d33d59594f87a8500c11318c72762e738eee17e52f2360a4dc941c1457bf5c2cfb5e93bb8e8689da451f095c0e68d594c121f89248680c71f81ae3f0f588c3571f87af671cbec4387c39e2f0c5c7e1cb198797545c17e7e5df5b4059ec1aa9afbe8f7af2e1eb077002da51c7310b82bab27fa3580ac72df680f0f376b195238924d3188673e31a0045f61e2d0f4911955ac2ccb9c97b319ca5fd75a42e1d32fbfbfcf8fc4da2f00d0280d87ca83871eefa61873ca03479a8948c75932fca0150830a5565118cd2ba9c8ff9b4a2aa018cd084d370cfd8bc09cea0cd0c8e6d2e302e840956546e969243cfeb2686c761d2d71af1fe973d5d201ed437df156f3dc9f642926c4905cd3354dfb8c4bb62660885a5cf45f6e57dc1a1228328127460e7846730ebb20cc235b18e3aee81f40553f69c47b7ab95e49d5a2e929f1b10508e84bb2fce6cf1db5ec1a491f35c8eaee7ddc3e3030c1fd51a6b686ddf91d9a565465ca78f91a1da48781ca937e3b460bccf2303ac404511474cedec17c164c9f7439cc307a0c68e4614675d2f2fa0c0bdd2ddfaba4d5e5e587352ee1da30f1c333f704cce1cffc9bbfb576cd3ffb323795740a1bac173d1fd72c6aeeac4df7346668f2767fce655c33385f50113e6bfd2ddbbde71fe352e6716539c1fb27ed2802ff333f9014cadbc62ed83f1f39b2d1f22be7c6597e3617945ce8c2e7b774f6b534b12b3731b483de263ae33a948e42f3c739d910446895ff526195a4ef30a45d51e6919f6759eceec482c319eb3f08499a22e33ffe07c78bfe7e37c9033fb309b9910afdce698b2f98cf6e5f1f1c95ffd341b820fd16cb9d76496d56a9612766ec86e2fd353e60937e58b215ed72df827cf3e3209312acbfa08cf29e6491427c93eae5926b47bb71a8ae4f655557365bfa1bd8a7881f511bd87c16e8b1f14174f7088df7a0293777e168f06cf6a01909c40129725a9beba57f19f62554953b2c858a1a3e75d1c3c09380a12b5c7d1d76d3f4b0fd06dfbdfa028f805595302500f8f5cce631c9e987d86a6ae464de11d4a219a6b7bd08771bd100c00258a115c6cab596ea7afd0b2f7cccc0d82fb911d0ada057943d5b7d50fed160cb0aa0e55e35ebee390a6a5870288a9353b6a4b8d236776c474dd19d375674cd79d315d77c674dd79a4ebf6e3d5fd78f5995cded5bdd38f0556f7787baa04d49488d8275264bc697a33482f6f02b2c614db0f14f87ed41926600288996e75d4645726e08acd76d40d5c56fcfb962a736a8e295a17e77da99969920560655dbed0900b579a38d67628e753cc4cba404aa3c756af91f6e19c9a18ceed2cdd7ad317a1d8f24bb3daf9d4e6a356b228a25b5493f3cd71b327f8f49b612b2e43da7140680fcb29173d4412b68dcf84433c843d79d0396f7a383e748dc1967931643a904b0e48188a4d0eef2e119281bb445c2fc15dd2bcbba4397e903db234857e5d2e4e17f5d0ff4e4702f450a3f53b53108d324d6774000706b6f64a3e9d24d95e5d99368bb96c428d9ed1ccb175bd823de1cc0e2ccc9ed1f988c26156a1a76190ee7ea73def33a826473f0d59c32366e13baf69c0466b37429ca7cb544306820f26f5080cc7cafc7efc5d7051fcbe22d8e281eb14f29b25573d5f0a2fa63f4ab847d7de8dbbb7e325b415db4b6537ae0ed0500baaf5e6a86b591b2b2f5c3d7ddc9c7627f62d41b6acc85d8b17983b28e8a7d6e9986fb79fe95d8ff01de40699dec3589dfb514700802a6771b193fd9efd21d953b84275581dc5465c9c3de470995c624bbb089bfced72bc9fef6bcbc5a3ee6bf662f36a57c4a7fbcda7c6270c112b7118d1cc5f87a3536eb2dd9fd7c89ab7bb29a64fe429cbfa9b1926892a852d4ca70b5915aced32231c0459463e64c8e7a2e1f7e9023928b1454860ba15088943b1d6348f679131a4165c05a09371c9141048c07da3901a2f0cee56efa30aecda8e63304188f80be2daa6744b1a8025f33b03cf18169eddd9089bb1bd02831e4bcb014e263e2d022f170a5c9094839cb4f516ac1eeeacf6e9d3927f1a81c5365685fce338d1d3287dcfcb7c667d98d0d8e7100ec2cf03724ebd256579516c480896782231e5107f474a1d65660263e9ece455bde19d97771c36f144b8c688f9f4717bce52d5da3f5aca5483f0317d9e6a3692795b198cca03823d7b3ea074bbaebace3f7ef6f04d97bc96fea610761ee7cd79adda47db70dc3f1eefe75cd5e9b30a56f20abeef0d928c1ba0e0e9600eb2964f3b91149fba6a6860c5b57dad7e9bcfeb9338013e28b0453580b60c542bea2571a73ed9dccb6eded4c6c6edcce39ef846908ac6d32fce26658c9e6bd3615d477c356ec35dc79e19e3a5f388974e1f2f9d67bc74c478e9380c80e10d8071c64b7b8c97f6235edabdb0ebde5db06e9c15c620f3a189a195ac73a1a9b70e3ec00ccb135f32e501c63afb280abe555d0739c35eb2c08fdcbb46989c93cdf271a0fb2b8f4e97f8614e47478b6a3d2dec0aafd2dc5f917df2fefd251e0efe72414af740f3ae2a8a7f76f9040efe9cd3eaf10cecc98a739336cb67f7477f0b9536cd7c5ce1a278bcf8f9acb42cd537eba64c9edabc22da34e2b62d3c57b0dbc54175234037ddbeb5d3637bb474a4642d3836ef4df903c0fcaa0b3d472e1a30fe631e63f90a2d69fe90d22f27a5ef4887b495b9acf71036d6559ec39baf49191cc4342b6b1d685e2454d6e9f0096d4d723d01c0f40e7b6737525104299778bf0ddd1e86b4a22c6e07da193c65d31bd3dad6c1370870c6756f879b5fbb9ccecb23d29df7e33c18cf412d7558632d15ec924ddce52aa38e740cf957c8c4723d9b6df5f382beb82cb9606a061a141009ddf8f4c5a279982e4f27b8dd89fa1148a015e8b19ab6861de49e6d247a931678dc3cc978a1a35716ac34d41e12d0a4183da6a55ac42185cee405f84d61591dcc689646279a5252be1c4a6c437e40776a32d35b75ee59e934b3ddcab886446756948e2b3cc3f2a278f4ec41d3a768d69c65ce156d598606f9db527e91d1e24685800339a7e25eb8f7eed0b81ab956bec4a02ea59c1a5334abf96792056c2972803c5decc148ae9884a1da62cab8137b80412d16a07508307584d0c6d4ce50153688ef7cf34d8734165f3547aaabd1461f321f1d3fd798e961b2e35703e1f9b62bc8154e06ddc651f112c8ce41fe5d2846a86efe65aaf3518383e46227310e8318057a82b36ccbea99568c12b997dd50d6d6861afdcc835f17a1e53d440e8bc6a56baba7223c491a7bad62f699b9962f0697aeae2c4eec865feece57b9069edd63948b799a4b08e31b414d6d10b71d918f9b5219270ff629a1962fd91255c4d3cb5ebebb9b5c70c3bef7fabaf4dcd40761e9e73125013a3caa1e9a159fc1e97e778cadff14080ba738d255684e2582a30532b223dc0edca86e49f5066ce0122ab58a8056b69f4cc53b0c5dcb40976f900fc6e2d6f1d0197640d6877fb2df0c40c391c700ea052333544cf66338c9d4c5f70179381a340def7375271d5ead2e36a78f048ca0944b20d14d44fb78998277f8242c0df1d693bc2cd70b1e464daa53758a722c9dcc935e5582cd2e153308133955a786afe6f6574db410ccdd1918f546b4551fa9c97e4168b465b884f825753cd1b926ddc0b8fa41dc67c3fba77d70f801a8cde772149f72aaac3a457f414ce15f16d65bf163f5393c4dd3547db4d5c27ab4289bdd8aed24ee02dcd235ad0a394b78bff8f9b62f6b171913a6e10f29ae46855cadd2236b0bfa7b9654532190f565ad882d449ebddd16f2a75c540f6417623cbc6be009eb3ca4b79ba449d3ba0e7e222c42d57fd8cb1d34f035d9e07c119ba0d5ca2494bed058f24a5f317a75c3da581cb0bb5ce5595598937e2c1429d8c38ecd78f25864277ef2091361d2cf67210620bbfee52ac70cf455749f7913e521fb42a71d63f4d1049e304ff335d07b4b12523f3f2027d0d523437f56dd9063015616dc9ff753330328d9bf463c8374bbfc62fa8fb8fc0fcfbff8ea6f0720ef5b71f7a1d4914f4090fd0fffa4af175bd1afe0c89556717a1f4b8bd505d1e7852b7c42c8fd156f726070493f38403499f73c2b7f399fdf5247763b3cc2cdbee3dd5098ff8bf3018d5382cf5824aefbaaf4ab7ff728bf60badf33f2e49d9e172cb8409030a25e69af82b4db9748a69f39a9a56b6a1e971794b0f1b55ad54f5200aaf752ed2c0d8b19db1a23d767c3786eedba20a67473ba683b4826f758eb3ce4508b8ba52ab7473a7acce9f0b5aa55fb8edb0579c50be6198b382fb844ae2f578ce8c4d3df91e7648a24ee7029bdefe8d70913d73e18ea8c36c8049dba90473ebe0d3a90ac5d00f75bf63b4cf4341e57eaa251ed4b4445b5b576f78e6c86711874467cdabda4b8ed86cbf668ca93b56f0368bd7e857cbfec14c9bb9af118a34c97307636c3fd52a0e6ca1d2b9228bd45e814e9e24ed1aabe39eba36128410a7748867981ed02dfdadb5f6159f0351dec6af9eebefd2bb68d957a78136a3be98605659d27338112a0458544cac53d85bd385215079e850c45939dd0743451737ddd34b94644c64bc716de5a42756e81df321b4e85f88b101f271d0b1587447f9a7de24af4bad1a78885f5e6a17864f18f3ce148a52bc6f5093cdda43e4355a65dea4f40b6282b640bc9d0bc03441b3e330578956ffb4cf9331fa85d5a56349f572c84a8158f9a56e62b2069df3c184b02b48e7387956c2264c9108dd2a7396c994af3a941e640d7a21fc656b9c9e37d299aa22f67779e0cf6739de5d7e1115a4beb313e38035f5f1a0ab8d3215408cba4ee388650ad9b0ccb9847bdada0b703d3a7b82754c1da710ee1b27d32c59a7140210bd4bf504d50ac928fecd9995c50bd3d43c9d527b099d16b1513de45c70a6e0bf10c85ae1757337313395dd406220f9f941eab208e93e4d5cbea80ff934b9fc8ae56243fd606ca51063604f0a1ecf88ae118307ab359e97fe9edd16366cbb3ce501e71d6a0e70fef9728b12dcc5a5f01998c06eca28d283dcd1797806a3e319dfd8812e8d67138b521f80d338d4e4112a07235a37688ecc26b9f9ea295ec386dce629c2672b7d3aa6bf2f9ccc1f5cb74e273f63a1717d6072b9493d94f2dd165179788cdcb0669e0492e5fafbb1a6ca7aa8c9b5280bf8b8cb773ffc21b52efc9382c4ec892faeb343d4f2744171f8346aba192c1f9d75cce8167007f795998961cfe5cd634725710e3101953367e0787388c3a4d54f54c3796263ea09e48d2458c7e083f8785ba5b548780eea9aabb4523bdc9677cb9d8c8591a57a0b6257f0dd409b9a6b86b34a5623a8da34b6e8e8e2356432e57cd2967d9be44ada337cab3ff0e716c672f4f6510c9fb793d3f84f2390c8a435c21bc87e92ce014b4e0472cbcd705637d7301600b9faf70764af85dba535a6198de51bc32cf05181e510a5f201b859fe0718189ce5c628864b23ba774979c62dcb1058139b9dfbb8b1a30dbdf41e7c85db1b14220c22a2263001cba8d0a1b7304998dc3be83a9e688a62be51272d00b58bd37bc81cac53a6c3d459eab3bc159f2e18762689d17ec3aac513982d669399f077baf5c5f85a2e903fe1db91d7941beb649ca6cbbb391e08be5796932c2086940d5974b1493a48e69184fbf6319e2d6ed2e1478ab67a0818257247c3dd04dfe7fb5f8e4658aa71837143c6ee08db5ed0035bd95559672ae4eff0b84496f3119ef2cd2fa0bf22dc4089121dd1056f8ebb2d38cb323589f118f39313d7d44e90fa3fb458c0e76b19479e5ad933438dddc0504ae3949089dec860be5ed1cebd7f3c9aabdf30bc7859ddba73f266f7907cac73a8e332132db340f2673663c4e550834663ebdc1329f1da15806f5e47776169d0a817e27f0c15e213040a28f3582dc2caea61a81cf13f873507ee0a09c50672cfb5cef9b265b907dc8e0540a142da90426c623f9c3c47ec7de808b6dd7c056ea1f1d1b33f8dc76e15b62f2b8ac8323fca44a5df16db5d8f9a995963dbb4cebecddce1e05da6b500f9c6a7d9dd95e70e58e904fab801c11226f36f531252d6e3d9286545484a86069dedaef06f6632ef2f9153aeead43f15d0a7fc68e3837ca2ed9d8c36986297a22a498b19d2f8713bc388627575cf26030b8bb407549b1fa72dce439604d6fee2f978df1b948c79233c35e713dbf8fa5b36ded80569ec14ec46134b9f62c9f1586309491233d2e01a908c01d311d94c8fa556f735a5dbf1d689bd17f770def5aae57080d9db95e9e427da0c0577460b5341742847938c3d65079c6cc046f0f0527a846b32e9906ae74388f9b3c83e3f76b96c171c19963e095b3bb0c83b3e86c9d9a09b9bf974b3228520893bde50096d33917d5eb2ecbbe3207ba1bd67d82413f5ea009b7772b8521c05dd2a276a4e8c5ede615c834341e2a0f18c7c3eb2ded9dd1d99b6c817190eafa8ad902363f554003e3bb12665f203d2bc6503a9c9adf2674087ccfe483a6b145518e99ef97c2a3fb2b72eddf3ec4fb2d8e0ba4026dc6322bd7b27d49d3a88320937d6b04b52e8554f07e9005ea6952c9fa20cb728ebf1fcba40989e13ded8c475f2ab670cfaa076dea482ee439e35d2beaf268f6e668b46b76ed95fbdd12e95422d5470653ae5ca81493552a6dc6088ed4591168cbb9f72552d22f2902ed4bf332bb57699b6eaacab2e08b9997e68165b9a81d1c31be0d490a85213e2257da9134311d92ff4494c757eb9d50300b3893b7074fad46c9255657d072f2685b89a7334c8f3aba69f27a8b95a9d407b249de515d42b9a48f19b5331bdcb927bd5baf4d570425def01c905dc708d182a9894b9c5c6f668630016f664e3d65e61ff3fed06529fccf178015bd79c4e1fa6cae602e5ff8d0b2952401b162e6d2b2afecc0da1ba65b34e63ffdc27f4eb77f497150e7bae4a3bc71bab4e59b659aee69ab1e2184161370dadd3b9cf61d068dea70ff92f2e8f79604634d4ee9e948cf61fad33acd33f9ee26037b39e0de8b66ef54f7fb8a4bd273896d0e0fd319130838f279cdf67513693e36384f1830f37f8754a4003fd942d6a1d659e6759cdfee8b8e8753e8db736eb98650f735bfff4469c9eb808d34967167532cf17c5982f10827bc3b17fe5bcff01dda620d308564f18c63f6e30eb5e22e33bd7787e7bc59b87805dd9d59adee9c41bb97d8390b0858da35c87a8766cfa49edc7ea614d9b1c3d4a63794e56ed00b5c6e72b362f766b5ed01a1ac594845dc0856a7ae2f0957b89a32b19c4a90bc5c0eeff5a074e8347fd74b03909a5326f4ada1e3dcdff5d6e21f914fab2da44898965a4f453714ee7b49ef1574c5f2752505a66ecd5076d6468c6d233fa40c17f972f2e1265ece1d694b50496a147bf31ad0d341763bf9824e52e030a6833d4ed67d99765bca4c5926ad9b13e26b6dce1332afe72334c2fba9f3a1dd951f89265cf1f79c8fbfe3a5012ec21f907d63c4f5742e16f935ddeea4f38ae917f3c8b9f281cee793126ab59e4e4a008e1e87319aadba299880fea6dc8f03575a4c3089471236b6cfafe9e53011dbb09cd06b60894229decf6a7bbeadd5dfd7a56fb95a93cb112122efb09bc836f1c0027369445a55a2d591928a083037fad46e4525169a1f237465f0bef3a03b26ce2bd8ae7ee6a1ed98afbb6f9be402e7ae53a00eb19d50189e617090ba2cc71c2f54685dc96f900342cb729be181da162fe5e81e00accb919e59824e0a1c10ff6e97cb6c65561666940a94e8ad2e9708fb68772a8a3a498ffea5758482c4de0eff4ea8e7de37e1f1d1ac8e8497de6c5cda0da7e9be154b92f52e7dc8aa2a6dddf7e8ba03fd691e1927b86b603d84b3eab9c65d354e203e1af73a09d843faec60ce3d70b3b9826d1eaa98a738d9aa3b920004b8603fb8d8562d41c1ac2df432731fcf94b872eee40d11f73b22ee4f44ac3a168f470b383c1e5b814b54cb3db6eb7ed59cfbe546753fb561ad88b4f1b811f6ac455cdab4df72a2c1f39d6bbb5c4a8f3ca2bc7f5997ae83f14d1edac24376aa43f7ee5dde8fef5c18b9dd2d7d7be41f4d82ff3384e9a67f458db6bd2100dc9e690739b92dd5d7b714f6aadae1fcbbb0e61dfaa485131c197b9b77127a3bd534dfe438a936a1e1d0d357787fc40f19b5df89a8db136e3ce2512ae3845fa4323708e480ef71c22198efd582fa2091de9eeee382f6434809eaa7295739128d834b0a7cac61dc31c4e62fe870a8f8f063b55db39c98e41c75793b578030faa2392a344cd27ce257355fafba802548f7f5902958be1ee112a084455f1437f0b5ac9c2b5602d7527133cfbf052c219dfaf097b56245a675f50d399ab0c43c1f03171e7ace285d3115eae1c8aeba1eac820cfb7c3191d5a66c0fd52d1fbccf5af69560c9a7d092fd875f1a81230cb04c8ff22dc80416d92b0f9c807b26d8ba7cf8d40e7732c3f095081e766865f0b9563723f58d0666e21c6b46ae678f0414ac58abe5191238e0449d4e698ce650f0a18a6dd8ae464cb9383de79dce8421225b5309318bef4c5dd46e98e7283888b81cbdff180045c0df683eed24661e7c83bfb1630dcf8d49c7e4911cae34e704045c831f01b910742cbef11ec3b85c2e481fe35e3c64cd664dc7641a00c70c7568ba50ef1de3132b185a2eb197f4b8a504aa2e47ad9da9d9e64dbe66673adda61d39e2115de093d5a7cd43c6f5ddeed485e27b3801347b5e154614ef6b018843a1f8e1cc90ff0606056b6ef51290cff6ade59c852cf91f81a190535cbf7e1887c29ab63e2ddbbf05890295149a2c0cfafa36afeb081bfd20584593dcec6bfac9dc31fd24e4e58d03ab426c3d4aa2b4827217f435cf633f0b3fe881776815a984df2f6015c7ef57ac8ae38213aac2fd7c4055ec8054f13195f708d8355019da62641724eed02baefa677e02aa4897debdfd6999c6a1ceee48daaa01b7db17740f52617aa247a848e527102a7600a8609df3089d927918a29a449259cd976887223b9ac7fa1140053c18720ee0ee68dbec1f075fe123363c0024d4eb516b5a76a56d80914866f92e775df3f75744b8c8df225ce477081777beee8a5af1ec5998b77dc9729a31197d3bed822a651d3aec0376455dee11d53d83b94915168687485eb77b483ecb4d722c452d96e28b4253a920e1699469d560574c097ee430bf95ca764a276fd5268b51a054324b47bdae09e82853e36e3947b9bdbcc5e513359e6b031fa03db392d9ca1d655a7b7a6279e9082df8880069e1344879042ff78e3748459887f6e2bccb6e08724f355a11eadd6853efc08e7b8f0be5c77bcdcd039af114d45f1afc4449bfa06eee393a69b2af8a66c3b0fb8ef0e089c371f2e5697b9db819ce93c2495cd5d9d8915177d7a8cabcf605c134f902f04fe64a9a7685f1fbe4a4b2fca747b889334ff19af184e45f5af3f34bb7395942a6d1bff28d42a1cb5ea963d058e0eb928ddc14e79b0d0934473749655ecd075eba7d010b8213919c5ca5f28be4585728967525256c4c99022301dea9c47fdea09f8b275b7e67c008e340cf72499c9a74a86a4476976c7ea57fade7a857cf8a2e869bbc5f8c2cb651903fc5b147718fe0f43bbd459dbb535943f3383e4b9883e17a61c15d2820644748f15098b95b8a619c23df81d8cadab9a702734b95d27d541ee5be83da8a505cd549a0a543f527c2bbd5d35728aaead31e8113137a2c15f136dd3cd05e19cab4b86746b6a5659ee9d9ec6ac753d931d323da77e8b846ef4e4e434380c51e5122ccce382ea8ba851a9e8e4041c4a73dccda52c423f0718061b17c1b311e14b520725be61d7084bceb89bd8e791df12724e882afe7ed81827cf0ae9ba75f5fb85d2708bb5a48deb93dd5d7b5841b698431fba23da932335696ac864c649fd35bc4093dc0587310d89b4be0aab9a8f0b433ab72b8011237d7011220ec31c0524266468e2c5db389b3f7cbfb8adc75448ae0a9d265033997c0e1a6db37a00878565a93bfa0da2ddd37fee86eafaadbac512c1debf60245fc1add41c534c100e950cdb623d7b8773f02cfe4c3f4b5479cb772ff36a8a8860563b68ade3e9b6569d7e92d153ca2cb05c189e0e0dbb4d75999364336bfbe017d723913684136246f389fcf73386d53b4316fa08e43984d0f98978e8ccb3c4cc33c825eea4d0ed271198e9b471b1ac6bfe12be19020ebea39fd20605074b1830ca8b372c85a48b2be1e286cb86c7c56a1a5a256a35cc3c1e1099cbec7afc125ce7fd9985d6457e8365c83df77f8352ca51ed16b7859ff6ef81af65c0be19b32ed3df82fc20d6d9f484d72305dd4b77d7d730164edf315ed5060438b0c6a4bd15af09f4e2d8a568334d7e0b52c28abd0c29a66bb2c3b568ed93d9756eb608b96451b9fccee7849b9c8cfc3d83035c3d5440d00b9a54ed178f80d4bf4f954c3bc2d39b4fccfbe41d5219a593dac963a22fd0fc04768dce338785eaf0e8d5d387f281f2e7a76e39e30a2c18ecccb6c7e8dc08c4f60265dd6580f48a3637e1d2d0e6a3a6aa21195d671b1a2639bb88607a753049ba320dc77f218ca54cdd3398b428f4d6dafc1077c2bb0de090b245b371ff6cef232bc6f98dce3e348ee0c8d10389c1340778a8bfe2b86928f819f45aacbd44356e73479dae98b88b09a1b6d8720868cfcd1b62a5fa11c46a2d8e5882c6b91d899670b1eea7a3d779159e36635a1a8ace5fc236d1d84dccc17c88a79536e2b0fec3e7f25f417a636b6770709a373604cbc88d5c1a24c4d560c3ef2e7def5df2103499f4fdfc554fa7e26ef10cef73077d26679c5284687c3f1de07c6128a3a9dd67975839df843caaaf32967721b7f44d56f125550410044c4aa46f3bd8c6416118aa87d5da0884246c75744ccbe207a8cc3e1702ef1d4d058f7828552e2b34ff5e74ae47500123593c40b8b7e0012f9ac96a12a9ec081892a398b57f2caef51f2e09c37c390362f3b0d6f997deb14bcf6e7d4fccda7461aa93d9e9a79074a04ff6d2cff496241fdd9a15fb2434db08dbc0e4effde8e8d651468df21ac193771d8ee07c41a9959f5110251a1e2c1585845bb32b5e02f57687b8f53146296e3002aba2b6d2d5c1a73c480792e5daaaacf2ed9cbbebae49988a5a1df9df91f6d1e092097748fe9d23d62cb6e8554eb9e87b5af3fcdb22fc01cbfb759f69591fd6944fdcf6f93867f7dd3e77e9ae566b0c68e80bbb938465b47ebae90f5ded65784c615d7b7669be5adb50a9c15697d2ea77810238a4a54fa767443515670e8c9b7625d4c70fd760f36695481620be38dfda6c1760d2b958e6cfd00a51bf3d092f9467b7014384b2e24b6ebeef93e7ad278cce3d5051e0ef3550bdece16dc3376f37306e47de6665137bf82e4a130e2b5345572291c7aee9522cccd0cb78c14a3c4ac1131a37d46a8d564f4ec93f35df67669675abd77dc709f412f49424788a41db57959ee337921b6ce6e0c25c86324bce76fdf2da6c138ce04bd35b8b22e5836be6449fdf9be4295ab751cd0c4d4beaf8a2313aaa81855228796c016d6e077a0aebe1fca4af5db7479a877c9df3cb4dd3cd4c5977aff3adbab5f8635ac98d2bb37fd131c0ed29b31b4e59c89fb0943df8ee8cab774f19e88fe9c923fa7e4cf29f98688cca1c8c8af68897ff4c076227284ce270eeeb2856ee422f670b47a0ef3641d28ebd92c703d925538cd3d2ad9f0fa1cfabdc8ef398cff41966a395c90a59c3931d7db8b06eaa69e6572658f41ff083b767e9dd8b13749f7a130e8d23a86be38fb633d550e3dfd2154353aa64bffcae2ea782dee86572d231d86f232899ac9e87d1d3d4ab0a4299109c0667a930767c1f568999f568bbf9dde31ddbb96ff95c662372d3f56adbe6ce8929a113cc8da6bb2a16a52462df1332a329cfcb4bdef27c6f7777d9a4d2ff9d7a8cf8267ad6f4fd3bf9defeef2a69ffa9ef7a67388c62d2f85d7b2cdc7ed24d01b9a3dadd9375b071cf7fefd824c0c60e84cb3db889cb6dff7a94b95c23d34e0e1772a53621a01f84849eb7464cae4a7e2aef99f789409feb984689823b4292fb7af5ed602d1dc8a17e963b2240e57a37b4c96635acb4f8dbf0289d5e20e96d14cce61182dacf70c8bc18fb2d3b864cd705cf89eaac7a0fb07f260b69fb8adca365a388ecb75c72baa48b6be2472085d20fe2db9951ff8bf98754b928b5e9fa7b0cab5ff9cde7fd7e9353ad5b3148fe92f221f7b63f5af4d36c2ae3f36778a46e6ff6a09234aa8f3f9ec29cd55c75068ff45986043c5f39a3e0061c2f50c2647dfde36d2d36dbf643923b18c0bb78238beaca0723e26dce73bdf4eb72c8fddf2f122f581f0a3d42f7d765f29c9df377ef9eafe5a627d3a813f44c49fae5c76981bfeb63f4cf9dfc6947960cb6fff0ec2fdd0a6c692742e6cbc3f176b3b76d4bc8d90c5695015a9da68e2b8ec6515d4f2c788f843f1ff0a8a97a6c6944e7f47f328ef1631e13face497410980c2c6b60478f7d87a65f39b7518d6b477876d02bdd884c0087b05e5ddfff7e189e4c8fbd2ebe4a8e908d3383766ab9d81a1216ce6d7d0bc56894b2f9df1d33d1d075bc9046f9a776faa729c37ec1a67a4c08032f9c704994e82e41536d3cc0caae95fb5017f517452eb7080b8f94463f5768d126fa27f600e3bef5848f55b9bb3be0f44b38de5a854cff6aa75bea75fdee30fa319dfba3797432221fa72bfc3417dea39bcad442eb8cef3688b95ed7a5ce1cec5bbf7377f69d064ec797b0546b6bf79f3372f5c4f1fb88ba49d841ff59aade2295aa8004cef6f1278f6e1c298be13784952ce8db584ddf6abe20eedb71b1868a6e58f37bea7a7fb16422cdf30400a93d70f8719e93cd027da72e039c767aa69cd4f1f7feceaff6b1fbf591d46bf4ffff830bff998521c65fa2f6c39d5d5f6f5fb5f4c91abfd4ba6f4eb1e7d7ea4e0e576749c82fd438beb3e1389f8cfc7f514fd729f1b7339f772f7b11d1fbf355454ffcafe130b29b127daf00eeaa69a470ec68e867cd5ec393df8b726c1a3431e6f75522e687d2d980b4d9219d9358270691259d1457bdc22dd9a04c4c8285b027493ca7be3ad4b9b0bd124976850afefe9f7c1ef69e24583c17737e543d18b4697e994ebd4c8280e1d0d3551d805ea2492c927d6f85861184622a9075ab0d967ee10a37af3d051a865f7373c748a5056a2fbebcf7ceb54f8eb8f5fba25493a22fcd4335730940449b15c0d656890acc8e1fc3867c6101b374f9db6a985edf29c557f68da42bf45ffc29d6408e7a0eed210535cfd174798d593faf1b6f4bfa139534e8663fee3e158ae787ab9e3da6ece680ceeef9d9e229c2f65639b347a3dd77d7c0d771f3a96ff4cb5a98722b0bd3ab3e2e71a9fb7d8692c9fe847fb48fd1cec235585952826fde7161f467593ee336952fe738dcf6b41c1a71fed232d927d5c87354072d07d6ef1615424e43e9304779fa7e429ebcc9ef69c7bd42969a4789bd222164c9c966345290b1f0b515fd1e84c0f87ce1d9e7df55ccc7ba65843e859e48df9bed2e53cfab3e2d58de0fbaa251cc8cfd89c45b58559bb950afe14ffef1457f48fdbf6e7dcb6a736e754b67a8925b04f7028e39aa793c8dc5fc111fae4291d82dd32951eb57424c6dd2a44dce99d0da3adcefbef3d9398e12f7a9d3b4e194ea98b93f5574ef5ed16fed217dfcbc50f8f3d842ec1f98d1fbeadb58b586ff6ebaebfe0a1b9f41f7eaacb8839f29f7ee0197fcf42d786d19b87f45e39ab41f1da3e93cb859ebf7d42367d71e364e420621e7eac9f646c39f61762f09f0eceeeec217c95dc8178f8daa9dbee65c35f7fe4b9a9fda44f0d16d02183fc3a3444eff37456ed32cbf5fa234ab8555f3896338575f84d8c48e260392832fb22e66a71c4f0234fff6cd3ef0f524ce9f8f05c5fa7a346fb9b497c47f53a0fbedcacbc6b704cacb34b60f269789facb63cb3fbb361af053d9a97489f326565e7bae39ead1a2aac7f7a11208b740dd4d7a0dabad0df85fe9c75782819d758f1cd1a5b424df984f529059ef941d77361cc0356b20de6f3277cc228fc127cae78bbb9469610d8ec8faecff7e9acc10671a7747b828be7d1a2a5297063e727b9ea97cd85aa8ffc043d829a76528b8f3711556ecb971a879bed298acc85f8fb3e20dccf1f2f26ced31f86e4bbc61fc5121fd7b403c9eeb9f985811aebed6fd2c8a4dfff98862b3a0dbf50814295d4b5d18fc1d38a4b8788f347a9f3e9520f72f93911b65697bfc2cfb4adddb22a87dfa4a2fcfe65b2532145d843020f6dd2659628c17ee73e581ba9884b2e1fae2b1dda21933e45f52064d0e815bd304c2e97731033961c682c1781e2922b9bf21e00e48c4b684e19d5ae6b0a2a31e1024e734d90539005e04605cccc7acd783dba89d64a91511a6b9117312924001e51bdf4eb3113684b0b6157836b69f2a0d7a7d775e4b26800509ad3206ea5664e9cc654f8329bbc1d90548c2d26af62cc57828ecd707890b7980656e1296e8c7886d34dc03355fc6b43dcff953df65287f79a2672cd8760615585b0e7566c554138a6709422757b550c6b86a7d872f8879c63690e94a4408cb6b50129825e567595873081056479c92ea25337b9ca4e30dea8c45a92296642cfa12485c359ff6a28ee4ec84a46ca52d5868d63805a04b6b6001b8bc7a6cd38693de849aff94cb02b953c03ddef81ad43878ceab879c365c5b8df6216c0c724183b5c6a8752432ad57b4d815e33042ac3505113c081e8399b69876748fb49d020958b0a09d9674017de804f6e40f71258376e96db05e5b2cb8ed199c9d2509984d9c03ef2f16618812e0b396dca12a313088086e2b1227ec2099391166769e538edad543f30987d01001e489638c66b23e89a2d457fbc7643e63a64235f97d0bc07bcba5415565144490b3c81274fa3a6e5a6ebdb567cb02d57517700eacf2e7d4da8df60e3cde44d6810c1c43c69cde4f717514e245c148249e3b4ae25bb4917bfcecdeb2a861ceb401390cdce54e4bf845d0ca8cdfc20736c2d0da036900b0b0b8831c27228d20f630a7fa5102ebd92eea013dcd9593b698b855ee8e9afe9bd46b6c0f3e992cd4783134d928c30411a4ca176221d86c1ce72968816c83a5375e7b5a56a0df321102d620ef0cd2ae102e99dbd64d8a899a565a17f50c5e296cd22aed6850cb50a9515b5016d91763ec9db585068eca79ac2c615b4535b243520c55766b5a8689ed0f6387d50e1896961d865297c850eb501cdbe56620ac190aca5772132c5278d02a159d2d889ebd2eb08ba9ce2f20b112a05fbaa10900958768c168bd34b626348a2f080ca570a7a9d1211b213549a55bf968f87bcc1d4131809bd932e1a40b42c5ae84c2b8ddee713628c3510cb5323521a8228cea5da34e30e4e2063a65a6924530bc65306771056d4e5ad13dd036871270aa9939c58aa1c7d5db3ade34785d2b6b30caa10ecc9c653e87b6ebd37d01b4de4219d95228e6fd21b00c34c0ade9212306e988d0ae0a5b0f4dc7b017ac79433a45075b4a0050af892e0ff588259bf843b296c1c8fa61aca07c51479b22f59b3609e318a5297e564d293a09ac2bb525f94020827a0b45053e72ca4caab032d8c019b48e5a2f8af32b0d715fc35f16585a363f0f80df935100e6c029e4c6f07094e50a818328d653ecb5b3c68c9a9d982f4947066a839dd565852844db857cb80185e02fd35053a4728a20a1d2e092e4f31b4190570aac203064e17156181dcb076b21ed0e0a25fc2474894cd8aa89ff653a0c26bd4f14f0c7cc39863215ca4555555d3972cd4caf367b922786ec2f468256963ea768a0bf1e501f642ac70606a03729d94afa28443fd11a68c9e8eeb94976d6dd5d1607292e2c07aad8472c586afd0eaaa207433dd2f74d32bc2e570ac99eb13c60c520c86a48ab3d20ffd9d48e24520f49c049c69fa9d0c63a258aa8107fce1109ec34d2093d26b1102e51e61b2152fd21f000d20f65205ee8cacb005a8d924395543e2d3749a52456f79b06ae201c22697829b73084a54470ac037d140086d487c791945a574f658697c71e885148e2a3066ac8eb26e270f24684016b242a284929ab1681c799ca221b299d98165475775a0b4d1a3f81c4cc870ca2992863fc46317eeddc00e213a58222805e696ce6dafcefa9413d7d1b018fa7982824ca27bc1e142d7bcde4522941a510db5e970a609204b981cab93a4b092f2966090be2eea8241cdca7012ae89d6090ba62899685da407d91a507517789c53175e0fac30748b3830b2eaa49c9725f15c06f99277b12ca36fd443b814ddec35c585ae5ca4da4355135dbaf0366fc9231224ef2f073ec53277f2355dac64c6d712e42b76a3137032f4e20a059d64aac82e1295744987fb9ed1a26ca129b5023618c9c3b560073312589593437bd611c96d2075169f92bd213a0a5f47e430e0876d920092bb752a94cc22b5b5681bb7af575cc5276408e3dd5071073a87120808ecec26260a1dd82ada3aab5003397c53583fdba6e229228a652283d2b5258d85d8d912b2223226488e54f01c1c25766640201401e9d8723e59cfe7c6f713bd22ba481e12ac82620c8833a48492fd401791a63f258f845676aa277da88139c5d5b4a44bbdf1998cb7890b9d2856c5fae0924c067ecbb0f9046f54149f210d55a465e996606637b527c386236fee0267e0a32b088103af21430e0e8fd7da2c747da673a2da6597acfc26dc3fb3d794953ba2ac058b85b743c5f284eb8e95d60e410fdda2e11011e027247e5fea8a0274dddc68d12fbe12d4033135148834ba868433798410195f00cd29b266c43a89b43a74ed05837b210c3c27cc6b85c681e65ffb69f935f12f2f3914c499b640349246ac867a16ce4a5ad486279655e22c2038d203b2b158da06f09c655a349e8a28cf864f8376ba40a62f7193b11504bb8fc8870e0fc56b1af38a0e91bbc58b79b42dc9d6fd00811a29da661ba2800bd0f140d40bbd692b2c13ebdac7d1039c8c84ed26086bf16b91cb6ac3e94c6cbe0a252c74efe684360816960580ca233ed5d99bb66103b32428d2517081eb74f436de801164eaa75b98f34229da82afcf1ed92eae3b39655b70aae97d5d4eed18d60f8a158a8c084f873eda604476d9158ee2403c8b5e51e594d396c12f9bc2eb49bd292c00d9c3a919a2783d2b4ce4f9d900579c08a192065604dbbea0373c8b5a6da237b022437b1e6428c5a5a9471f5a7f13a45ba2a20cdb982d91a1c610265dd195b166bdaa8818468351feba438dd6e861519e925012ad4d37934838d284b4879bb0d30cbbaa481526492f1a27af6603f8a8fa4e68370a7853511853967b08afb13540ae1766b70b2c16dbaaf9c6c44fc465d520b20d793241b71fcbba40b169b224ad8511d988f90aa8176f6c836dc29e9f2adc83392c566bc2459e95bc8b769a1d6075155e88a495045b542328bab4c040ad26b54d33cb48743746a6a387778536804712d0c7c5f29239ce2ddedb011f362d605f005ac7cb36e0df98660d7893d746df37e1e924e59393a3d5b05715f3b57cb43024ee553920b21b9a689dc0cbba029c6aef1224e370b3bf25412e9247a8743395b668aa3c69e6bc3080c42faaf1c33fa1f9fb133f95a414a8f91845fded1dc7abe2aacc4ee6259a4f2d4a57a0c5252cad4b96642feadede784a02c5bf16baf3ce8b3d50e49aa97dc268c0dc304f50de2a36b909976c6ae074e8ddea31cf7c02a7956bb02ed3b509de74fa4e99eaa2c648d8db42af53a72ee5563491ae30b8d51e03d760de08995db598b82260dc109a60550f7a21855d38760758c8ae7e1d9aa6a1af6c581cf42f8a52d2a2c2cf4157f5ae66ed82adc80133364c290949f322bba05b2dc9eae4e3bd9dc36fc0b1cedae7403d8d5c154022998d15f16774734d816b76c0d5d16a2cb875f92a283664bff0bf48d3928ee64c4908d6a0bf708506dbb558a2eb89eed05997b03d49a8818b92bdb2dd6ca08c618fae5107b8b63a34a8ca5d734bc61b9bfa8118197081a3113d580d8d1a6820303af20837663813b9e7ae980ad0610a9440223840ffe70a49de2149327c2c4537294159674f48d1649b224617ab81f43dfb12ba3004de387133482c0b9ea821de5504b6a5d726c216e8349e35918c8882d8d996f8f26ba55a56374581fb910afa8a90a72c5e076be11e52a2dc27c72a48a9ab70a231136433b2a98d2cea16d38186e59aba6dd85da5e7352bca63d660441115b863267215185d01b8fe46370256937285729a356ca126506f2ecfbcb0834d9439125f535caf9af7cd42baa94f8c3e5a2e4fd7541c72946d44a769794a45d0ac6bce8cd863c592bdb36866eafcea42c3142848926c4834def5aeb2e1cc94c016ab914df36e40422cfc2819a6419162fb0fbb0d43aca86fb2007bd3128ae8e601ddab0be894108abca5240dd60e8d47c2261fb08ee9e505697cec235587a481087484d54ad2d83e45599443220f5490d89b50ca14eb89630ba4a9ab3f9d970e340df07579ab681a0bcc882dc0012f4d9e210384a355d08ed855ad094f5b22ba886689ab76c2f0cad0e448c12a088116c9a8e0d966c544a76c81a16ad26061a1a62c59f1a3f8f2172946630a91fa8ba9dec5aa3daf550de5072d9435a8a0e6c8cad65814c797359a8c0c9f86ac8ea21ec40d3ed8e0d8e39b89272778f2688d2b94ec26964a75651e7521c5646be6859c4f3eeeaadb177535d2cd5de3eb781b99dcecdcc8cc5b86c4f5d9e9cd70fe1b425144b5ac99283b6cde2c98824becc6be5466575c34a4ac356b1c81597743b48d2f4be2eb612a436c8b6d547d21fc7fb08386049ba777f958eb1974ec65175742d50afc5cc4c111fcce10f59c07a431db267a04b3d0d694cc35cc6e69cd50ab0a18349faba2016258bbc55cdefa88268e7e2e0f961a73b49151794cc48f1ec9fc4022aa62a643f66a177984e186b0f116098a3709cb360db06eb964c3dbdda014a90236e47dac9274d9f70e2b8df34f925e84c4b02ae0e0e8664db297840364199d9a8a4826e768e165143d1bd09f267895cbfc92e3323047a67ae4b4a97f9c4dd82aa6d184dd8230015fd3254ac6dc2a21510b2aae224aa89acdbe11e2c89aa8c7393dea51c8509597901b1fb202e599257553db7f4ac8b94119ea586e56fc35ef5a0bdc39d144bce7551802f209d880795dc2d9170e5251285dd74bd53b56258885a8f522fd3dcbd01c8f69c99c0390289c6ae8da81407126ff78d134e582b0d09618dd44cbdca979931c35822ac2a96370fc2f35ea8b9930a23117d1779b2467303fe05e4253fdc3920ff0a29601a6a13b5161feb3539079e8fa32786c4bff18e2e2e1a3685184a1fa00e79029d877d2ecc462f50306e8c184b0ffb39f99defe8726f4e7f3ffedcfccd47f2141b31cfb0b2f2808ddff432b34cb5f7bbfb8289f1f20be48bb8015297fc71f9c9a9fc0a9896b6508881a44c8a192a6f5039d461257c991329f8bbfb16c5a5e7581094c30b91d846c008a254d524b3242fdc9dbfb483db34f9fdec799425a66913fbf6fbafb46f9f8be1cdeb73ebd8f6289ba2ca185c12ffe73054bf8f7fff96f8df6cf9fbff2e77f0024fa7ba6381ca07af3a7dff53afa3ff1574223263601d91dc086fbfee801bcbf121eaa522cf04fcfea5f3eb23f7ffdf9eb1ffa8b0d82ec71c81cf7f375c31ac0c4856b1d772adfae5730a8ffe312e88f55f5cbd03fcbcf007f3ae097e6b6c8813774f9d4c2a7fd06216c77b7502e72a11905073cd744476605ba0e664740d6ce1e4be0dcd4ec41266a093b78e283f8732341177d58525093ebead4e2af0a385ab4a95245ddf511fa5e0da75897229b496890761cfb801f3747bcf0cf81fa5b0fd43e004d8c0ac6cfe1ea5ecfd1e9a9e0287e365ccdd0e8634432f1d2c0de786cfd95f12b299ed02d38068624a447e1bee1c741c9e56d972dcda8e02067fa0a20379a01873557b0942760144e1ef4d4ff20a3299cd40c79f3db8138dcd7372d52fe17c05ffff08bff25f86d4e02c8fd01943760c7b49f9338b9c40b7fe4952b48f2f7377235abfa1b825fe26103fc7173484bdd6b1c03d4eb58df7efbc86900508a3ce03e3ede377a60c80eaae9411d67aa056ad39b39565f17e6c1b0c0420fc45cf3173789627fc32f5764977f98c47f8e4944cd3cf0885fa2283c75befaae5b6750264a00c80b375501d579fd9f8a29a5b4692c2b979a52933a42c7c8210539f74c26f96bfbe7f785264a65fce48da1215484e03c2046f53cd5127f0b0a490480bc7bd661e898dae1436801af6f07dda6dea389fee110ff390e91c22ede064c51c7774fc901c7efc0bb735db8a8be1885d934a2a563a39c4cca0144c654d1ca08caefe4f24c147764a9cbd714a82e65c1640734e44951a21f17eb09440a57f931c2cd1f62fd4dc47ac0fe672df073f6dbcfd135a7e5e5af03bc53adb05327fe0f335693315430164ea3971ec5a721f4ef75e5fdb071fbf38d33e3f59bedb00b935bce2ea03b4b94d62da5e943ca1187b42599f33f388f64f39855612c3fdd4c4efcffcfef2690bd66feef8d7d0934e69012f4ffdcf8a7540b3ab8d0ffda1ca6b8fe30fe29059ee9b4c9cd2b6668cf66fe47a77d410afb273d48bc819d9ec5510900feddb7f37dd788e47f207e679dd50ada0827ab4f81c758d7a00862d4485f67179a3de3aea1e68a4b703f6855941511144e5e49f3978f5ce3ef5b22b5f8453b3e730ae82a47647775f7458a837b729a69c5076e9c80f0c1bbf231ba145f5d5198249fc9c8749fa540d0327c0124fc9e3803b5f9d3445475461868811e00c3b900bc5822518e1dfd4afc3518128a217783272e04121c0bd69abb79327a17ba83277e75abdcdb02a60db8ea29d57150428654340f29eddae3aa035a78a8c5b3b32fba623c46ca87ef35c1d883c1770cb872e4723467803e6ffb1c90fa9d63d44cb9147760c614d702f4cbaabaa67368840cd170023e3ebb520bea3a8dd16af866a809455b7af63e660c14fdf1b7ce116f5d0f770e801afce87997da1c77e0d30f1fc554beeefaa83c3c05a2c0f1e8ede883e58d27b7d864114242db0cdc5f7627ced23b52f17f16c08fe5b7a31d3a8eeb4d36f78f31b2ef5bc1d869b5c3e01ca2618e6fdeddc6cf2f96002bd86ac4b486ef56c33c0fe6ec8d6b90be8ebcfa5349385d0cbf63d638c8810c6218ca4ba2689b476eef5ea6ccf64313fe8d3bfb8ef7f6af6b13997e7a5fde2d58fb666481992c81660059d48f25e56f583afe5a4161ec04857675e1ebb34d4b39676e2aebb1c0be2b926320b6362121b91d1ad3635f7dc50209a2e66f3104ccf1f69983350183c14daa4473bf3bfb3fd089054a4ca7d00633d7b3ac4373691b973c0bfabefa5e4a223cf2d7a5b78e322817636d9e0a4cfb49d5df90805aea265df70f2cc9744b12f3bffe46932e18b15c287de3e5143f70d3a89b1d31e3b826750e4699fd188c76ee09a5014ceb8e6b0602bfe7a79f31bbdbb3982f72d51a1025df26eca9e1f25871f041812c7e0bc9c4f026d7a352874a75e8870c5916bbe7e77da4291c3e0b63e1377ad61333549dd74d28ee541077f5543e1f674434b282564aa192270d9894d1fd4186f20fafd5c74f66ecb39da3d96a0feec7cfb28a61799d1cbd869ef51891c273a7aca9b73dadafe08a8f8efa1c9a2c5a42e855b8e3149d5b1c04ca9f36bddaa6f72163f83eb5d8a50a6a782707d1f5c0010be8f6ce422d214338641c8dfe483bdf66f5e5abff4115dffb477a339c513b9f557845390b6ec05a5c0a8f1b93864c8d1bdf7be4cc5f900f428cbabde7756fed4dd7f335862ff31b4a3e8cef7d6ab937263303c1f65fa197bdb3a68cd02f7b71a143ee35e5a8b0c6085d68dc367e9166f2ed5cdea89d3f6cfbd4a8c8ddf0ec7c89783225d40b517e67d34e81e6092945a686a8e72b38b14c5433d853bbd8c551d7aa688b02fbca4bee157f2bfb24e4f6a077be0d36948b973f50daa3e8f3f18cfa26c5ea5ba3363ba742985f387fe7ca0481f797de1fdd1acf2318c7faff22e5fe6133e24961601d3f54bf1ca1e83f84e1db715b9c3e4617dcb33fe2b3855fdebdf05cb49062fbc67bbeb4f7ede104b0933e2e7bea859c1d6347afd1fd7ed839edb7fbed4ffd302defc7bf15842a5c1dbb333757ff8a36cf279b061f980211227e12fde843ba9ffca853fad31bd98098cea2a0a491ed1ec5ad919c6f643c3c8b2261f3b045dca303892e18055579c9ff88cd7ef576e9ab53cc1a0f195ca772cb78878e327adc37cf797ecddafd84e70a88c9ff87fc56adc53907b7d5fbf5f8bfe9b492a8f0fc6fbaad040b7f7ee0b7fa3bbd4beca176af7de35d4a318de06f73d4fcacccfd4fe75afef294a0bb53c2cd5ad6bd9e59e279f1e4e7fc2ec143f464919be2958222c3de9eeb5949573fdcc1782fcc7a8f1f2f2ed9b13e449d10b704a02b5ff235cc79a3d5cdaf10e1342aebfe861fa71f4fe5c10b130a657dad77102c47aa53744d46274fba4ab0a7d4f0b81ece7bfaad23e9d9b036969ab4a9481e870afdc4a7718e914bde05e8ac0b0633d083bbb4afc43af310522489c8309c997184ed03d53a53461d133abcbf7880ccb088d177ef29195fb73eda9fa4ba9f19f063903e0e37fa37bf7f8faea12a73295dd98b39077a58c3b0681f3ee2de0deb8e1fe8efe6b47eb823c95eb1715235a6c092625e19a3cd4f49f45bb6b5aff10a5b8672e3d5eaf130db36ff40246507b6a8c013a636df1833b78b5e8f8cb476a18fe800b3e1fffc133ebff6512c987baef8fdb873a3c6a04ca88cbe67eafd4d41eed5ddfe215f8ec9b0327d131d3f358e64bc00f47333bedbd4a0ebc2df715c9382c1a1532511d9f943aaa512b981a71d9ec283b86497d8e85b98ad93c481143e38fcd7e5e4efa3704e5f3fa106d855c6fe86e31faa649e8ac1a1f57ef6b6746601dd64fb38e5397f856af677865439b4f6a847a6ecd7f3603ed1c48cd73f64c0de11f84f1e3e8d45847abec8645d78f2300ad21bf27087383b2275eed1fa75b15c1cffd69df76a9719a5ee5c9830d033e877f9b3057c78faded73dd550b453a22e8e97e3ccc7d37af0bc6054dc51fab18c210a5bdebc8c43ec71c5f3f1fc1444813d231a02f79be94541fdfa71c9fb6c129b1b3cc65e5df8f647dd32dee85192d1c1dea8704f66c6514e7377f0f2959bc59bde85c57c54a27d7dea1eb1e91df1b31c77473998eb5c92be79b6ca283d04df5f1e23d82d9af2310e8e46c48a6ae67f1debf8f5e3e7fe8eaccfef52b3efc3e7877c4b5fdf646dc74393e278e83bf179b5b856fd3767c1fea88be343a02d5d9160259801645653a0eb2a7992287c9a92d9b25c1f612d9e931e3103bd5a2cec5d2ddd3214ab8608508c2daec7cbc287fd784f7df405871d0de1a2fc7459bce7d1cd1c8653fd707ac8dee88f9ede10cc0894f7b404e1fef23cb470997f5a703bcfc7fbc33bcbe3dae4a7cb0e30c5c74dec87cb12edce5ce4c37fbef02f09f4db17adc63bb481355e90e2e75dcf37cce38b728c29b7e311dceec87f318f97e6f32d52b9e0be28c72ddc73ce7f51d1964ab2d676fccc4be3bfa0ee79fe8b7ade42017ff7852425b9e5edc71584a4156ee106ccee0b0a24f82fea31f23a62ed1fb76cf2771c5c59629a36ac7a88382a91729f578e9fa9942808ccf30de514a9e72b926b407c1eddc06fd671e12cf10beef8545c5ef247a9910f89260f21037d86165e7bcfdf43e970f4dbde38c8f3d799cd20ca9c69b621818588bcd6877c9295e2af212256abab04f46cee29d3d231280d797db3554c55fbdc99cb17b6557b5e03034f21ba6bfc39260f077f86d31d728982fd6a78bcf7cdb568082925e574aa493b64cd3ca92ac6adee5332aec022e5070b627e8cb60fdcd448ca68067f1700a3795b75a99fc9c4aa96ab31f23f0cd86993674ef74de1798ad7fd0abed57dbdff5398d3584b7b4a91c81ef3244ce86fcd433f89d136123e836bde2f378477238f38968fca22b5272dc9612a2dd7d048bea7ceacd229ba2dc360a25ecad2f190fe3f5c23a4ed9eb52dbe46ff977af55e1ca69360500304aa499376faff7463492e56975ccc2e59b3e82efdd5bbb404a6189e28d0f4ffe9e6946d4cfaacece280599e27ade7e9ffd2129d9e97e579c5add1766329ee59c5c5168b3cafc8f38a3cafc8f3aa5bebede654dd98f0aceae295559e27cd52d1c152f7cae17deb1a653796e69ee53aa87669fb49ff9f6ecfbbed99ae757673ea6e4c78567771d52ecf1b8e86b6dbabe1d6bab8390d37263c6b58ac9668d0d12268087b8f3dc35a638d30378c09cf4a4e4baf4eefaae55ff1052b84fe0bd2437eec192ce8fef1b9fc6f7f917e785f3ef8a21c0f9dc74ebec1b540ac416c1aa40da9042459e4c1427fb5a87b97db19a4d4ffc1ffeca48f7b515f5af179adf78e474d9477fadab74f7e3149b5c362edd0dbfbda70f7d580791fdaf835e9b17ee3423e7fcb1ffe167150d85cbf7fc3f95b703afdf9f38ffe49ff137fca2ffb537ff04f8b7fbe1df9ce2e1d7bb06fd3d2d81d76ec5dfb8d6bdcae41ca64728eadfb722ef2f771beaf7860fd892ce9f4d7fa5f095dd73fd84fe6bf8f687753e556bf4bbb7417bccf57abe5c8f0d348a24bd20bd92651faf71d5e366e5fede2cd1a2ed231d7e2b37df397856bb7d5bea7937662a065c55f4314854b8aee31e248b7725efe4fa9ea6e79f3d7dbd8f3d3721e4ff8d1b9b3efdd47003e9dc3dfacd8c552ec4f8a76d8fad8f75ac476836d4f5c8b1ce263b37a422c08cb856802874c28b2427a783f1e55481fa5052058eabd2544429f8827cc8c68043d86fcc2e763288a421c8ccad0b62ad213ee73eee3f75a037e0c3ff0780c3d5bb3c04697f5c9ad7394941e4c6c54035e97670c7d37e191137cc9acac1a72bd1d50d5c48734ee0642a8e5af6f17fa5f8bd24431912c2d8af809ed6e6139c2433c891039a97d1121a94f4d80428a353fa6df2d2c37a5e688d38b8cbb2ce74bafa4fa67f28165deb2c29834fda809b32624451b8e742eee66c44dc27cefb66e37cf585362540405b3b5ddc912e450a2b5a97349378fe8b289b4ff53bc0f143bcb0024a0d9f213d6cd13484ebd7e9de217a1c3c52bd0936c36913d3d8377f65c0c40f3d190a9c29a97189565453d8c156472d6d8114dbd6641f29ae396a9a313380d67c8792e705b5d9f52b610432b7ce67297940aa64bf181d113c6dd82523f983ce1332bb2b4a4a1d0ea508201a632ee56f425bd46150e404d8789a508225742a7cc8499ccdb25a55da505a0fd185c8637802a47e5abb4c0f48c754ba3447e240ea780ec30b975cd4d21963a309d7db7a63cda01964e35d85acd320184c8e3ed15b18cebfe0e91a914f3ab525b9bc00c091496da21ca43ee5696029f940abbbb44bf6806521d3ea4af026d333f26dfaf6d43ec9c3a054c04eb99a150ff05fa0bec9401e9ae0bb3bffedfc4cf0cfa2ce8937414ba1c057a42bd6500e29e2581d24540f398a861f56beb860a8e76b7ae04d3bb64fd89057175f38b32482da4f6073a9176b7ac542197cb409a7141b757ea4ab1857e652d95475e4f4ed570f856e0d22d8fe74710d76e3aa371bbac0d64c6929f384e0216100966e66f1b8f99b7ac80e89b7bdc2e8c4e8bd6e82b8236da3aab75cb0fe89866ceb521d6c4c4d604b9aa22a62ecfb85fdf62e10b527796d006d596f3296f3a9d7dbbba53a52fbd8d4edf06d913bb21c686398866723c6530776ac2dae855e4bb83e46f7877b99558c48b721b41e97ebd97fc3643ce1209417ac8adcca20487544c272077139fb8dac18a54bdb9955a852e1cacb8f080924bd1618da9e8646ea516cbe9d74f0b56ccc6b7743f1da4ae93b9955b0d1a2ca7030d69354f47a10a8201b77ae59ecb77ab7afd33f494258cfcbd914d2765e8be55fd8b0ec03578ca7f36583849135a53cea49d150df1cbcdbbc8940033d1d8df4bf1223aa42c0559e275bd9bfbde52577956e5989e878affa2496a755c6fa74c901274b424511eda703ae8abeae69cf727e5fda49db0ec9110100b6b5223a55145bf2edd504db1f146930eb9a1496da129d19a8f3f2c99324e7916c64000ee6c264cf994b42143dc678829d6241aba7e12099240a48cc7c5c39fd70564694d0b3f45b1209d67891a276d85f8c675b38034ed2deaf618605d5b34589a57939c94ebea2de42e112b7bddde90c43cf52857f6daa5ebfaf1aeab982a38f8a4c867d130ea96fbafeb47e29ae41a5dc4d2ac8afac1b62501f70f7e42be2140221b122e24a388771418025b26ff9a7916cde042c15bd2c848acd05f230ba35b1044ec0f92c3763e61372880afe3bd9527bf16873ef12ac924da0d7fc9b25bac212679dc9210307f33650eede11073ef7852d4bb6c360d9db83951f59639f41b322c2ad1c165590d791da06959879d9f30aeeb4827a509e321aae6eafea6621f0c37cb644eee57705ee9a2a11db9580a2f28adec20a5a99d9348b09f899950de71859ac096bb04de8bc894cb2a489af26bc30a6c16566269502f4e423a829cac0b3b00cb6644f22c73d716092ccd92b879d3751549775992e996f5ed5bbc3ebc348567506e044997985255a3adc05017b8fd8131c96f177ea242814842209b4870727733d6d5640a37126508abccd4f374a09b1b6be52c75e1a6806fe2467af2139a3c660e20172e584e55e6702354788e43e4f62aea6251eb866c377625dd8894060b61812966756361e8b5c0ef7e44339ae49e90f2cf09adc49e792ee81eb7e9ee5c2eb793c384be2739429ca8673d43c2ad4961656de0e6f5b426af57b0c53b5d91c94475443d9a77396ecaaa3aedde8be65e27784a3f2292d4b47aa2649e6fefe0a393df317c3a2ebb12068fbd5d974e4c1179d7868bb1a370933770f393fb75ede8f4ada6aae2d002184e0f61658c4492b8744ebadbe2d12069487c9fede4cd0a25e738379ec0b82e1f137a56fb8a8cc09cd489024d39b30239af0bf8773b6c6386d98c69b8d0d3d44dffe0e8bd2b78526092a47cdad5b65dbabf6281e15a42002878e363f94388f0fc9ae21778ac63d51f7cfbe8e2c3e6eddb918fc77eaebf7ee03ef2e26b77fcf0d3873b30d33f330fcb647e9cc27723cfbf73e411c0e9bb6ec3c5d54989cf7f1d0d84a965a8303e7c9e4e87f97803db3f4788d713d4eaa71bede2c86dbb90b37c8f04c7766d77f3bc14fd6129beb9cfcb853c2fcac1f5cf1de256847ca8a1ce575744967ddd864b77c07fb82982ff743ed5cd677f7cdb680fb7fd7642d2e6b3296041c45ace1d64cf6bed5afa8451b61cbad7f6f024dd4892b049c9ef3bc2abff9633f8f1d245389cb8743747f6a756ed83852bbf73e16abde7e3614a378799559ff443cca8044dfd1fe7cb3fc26ebf9b587e98d877f795a7fb0e5eec3e04555b0c30bcccc362b20fa32a077bf132b2e2f83d6cc490e66bc61fb936b8e7377f263db98b21f57e32645bdc8a8c6fee6beebecf597316d3f947ef23ab46ef9b9fab851cc0d31bdbe737a6f674a343d0b17c991392e40979b5968bc275c0a6d612753007b3a545560f1953b1444fd9a793da3958482a55de17dbfdd599b845254a9df770e612769da1caf9d890769f59fb1b6c4f6f68b2e919acd1eb4556eda8497317c39202b16ddde3e3ae90d2e57f797b5bb445f3e7f78d3385ecc3fb826bbf9e2dc61eef2ba15b40a084f7f7c54fb7d12cf66fb0b76491bf2c73da7746506070764c69709472e0815a551c2640cf51f44c19e192ffef0cbd034178940610bba67f34a4c4a02688ac3eeeb329953d44e003de7cce23dff20f89848a65d5e4ff43129e0873360bc5d13f280090454a90337c0efe0705ca96fa48913942ff10e0762db1202f52321d7488038dff45b90e1c81c599e240189f2ef1013738832702ceac8e9097970e0dfd8b9cdd559dbe95c51239c31aa2531429681ad1a075ed1a3d4c49e388704116cea3b8fd1fbb603926c0ff18f847755fe6f8d30469e9954c8bc35dbf2f0fd974e3888f6af4281687fe990589d01991da11872a15357c30e2f833bebc8e5c905fe8fb793797ecd664e1d7637613ffde987bbb4cb6e2b18d2ee6b997cbf4331e3ee18c5eead78e03d3f51c7471c3ebc6657d1a46c8077f6252aa73d4b8ce3cd4065ec113d4ccce7c19b084f5a1bb142c916a5ec792f2e059ab6818300f723ed00faf2deb3705aba1439d58d22b95363c2a637174c03acd2b114eec60c2422537eced5e5d2e943fe398931b7cc300f603192f7c1c18804e4175e38d11a6cb69e28fba383a91815d6bd88beb41686e11061ebb408709bb533198eb49298e4a3531bb8144bb133a1befbd1ea5ec6838e3ae82c529b85d8f4606f11c5befc97b62529aa05c31df895d9858b483128aa3fceaa6d670d944bd86eec870bbb02ed4d8dd3157dea28b36704e951e12be6c179e53705eb6e342d99d5c9ea69247c250afa7be82c94cb0a685b74fb76e13b76c8c5017f6ca1654d9d8f8bb393edcb0471db39bf846d5db79e17809cfd9b825616013032bd8faea1857c7abf78537eab968d8cd0e6569616c4a90d931b7f92cda0a76a7e2ef81eb1b0e45717bd1dd8c96dbd62b6bcaa0ae81e129579f3829037f2bf3d193ab6b722b643b1ed85c2854d741ab301696bdc513cd2bb31fc474c1930bb64c77d3d70e35b7fbcd9df4867d9f0f823ebb8727905673f2ae604112ee9d1849c39635dc78ab2d4c3cbce3162598e90e82ba3d96531b3286dac0676ef58dead4b0e9f6da1f49ef5fd94ef1e86eb4d9f1a55b363b31e6eaf6bdba739a70b117d303376aa874b8adbff2e1853f1977351c99e916ea902015cc7663b2be26ee5671f285722b2a24cb2d978a577f4c74e405d39918c6adea559cc2d9b02cc949eaee88b3c683e3c7afb57ec331cc2babf72596c5690205af3e74f2ee8e929f45769ba56ea65b25b03b3995f1e48ca7e5a800146c65711c323b66de9cc46c0f6a6471ea5f77dc75c42b9793e0dd1d46d599b7e32dc58ded5611cd4e819c8ef7ae78718be2be3bc54095d5eea4b60eefc91a1a4eff5cce6af0126a46c5404f6b73eaee74f4a6c31b4e4dbada20cd117c7397e56850e4c8fc57b40b9653e1a6f327a866752bb6a6fbb5b87f7b4977a81ccd89dd0d826fee5ddb594caa8c5de5da72bf0e37182f0a0fe56446d13c9c80486eddb6e34ee341b1ffc079b37d48ef73dfd4f2f576114be863bcd4ed8b1f635bc0bfdb7d781d8e9619bafbbebb6a23b01ad0598ffea45a64079f697083a563819d93f0dd7d21dbb61c596616b9a84c02c0f49008842417720aafb8d99378dbc4a3462e1f5749ca75a05b32ab46b2ba828696288a4a36d051b6891234a44321e536a10e720ff5e7f32c2534c469505d8649518c2e9ca308229094eb540109aae231e4df3bd2f08444ba7490a60cc1910de7a748b13455949027112ed629d97d5d68928a459abada5e97ac8caa6f29382788354aafa37202ba06f82de2c65bc04de742819135fb82d3c6aae660333acb6b3a54b632d14a8f9e3251e380cc37761a02f1969febc003eb924b9af81ec8ade8cea6b2b9e6c56c717f675ea52c08589cc62cfb909d16517043934a4bd9ef29a9cad2aa73833b95e694b00c09d1c5b1cbfedc2595797c5d1580281d66739a9ca8d1226fc5da5a714ecab2b7d21172cbd559319d06df9ca2536d46f890f3714b772fca52a3c327541d3e36a4e2a6a0924086544533d96efc92d229ac3df9353be47dc593c512cb376be277b83acb24deb27482e5fb65dc462bba02ba546a87eb53241b7569f759f171884d20eea3e957c066dba236d8f9beccfc00c3d28df01b5ca482475d95625357778dec966a76157f4b7e744dfe7fc3db92b6bab657ddad02e358486189e4e8a87f6463b415a9a178b291cdb120452328aaf9224bbb89e6e2edbeaed4b3a5565918b87b170a602f3b58791c4bafedf66bc5e0fc8a8bcfecb5bf92d79fd1135d97946b3c0cc722c96cbab36cc0f3451355eb393b5acfbaaf721a24765e24942423ac3201a198c68bdd96a36d5915d98ce9989b4cbb387a6e62d667b748c55913c2a88ad705eb8a0c203b833d0ffbcfcfb3141479ec68d799d9999cb3846b229c2343d6ad727c2c1b7970d007e257c2e73a5579e6760bc31316bc843a9c9b6d146554025db8f9117a40b677a46677d6e49baeae06913427f791db50b0e21c1f44562b12ac4c6d1d2fcb710432dbeab9f7f0bff000963edfee4c231e45fb9894149455a9fbb2483e48f6a7564981eaf0bd234883f9bcc7e3c283871a32c333b2a47ba52cb86895cb8cb3cfa538f33c3b86661a805f59f5024006968ba99ef4dd1ac0e8dbf94a87b8d4fcd324cd43ca63923b53cdb971c4df25bca1a9ab56aa27bb4698454c14c714dcb2e4795909cd95143dd7069ba35f10c90762220ea8eccdebe1228a10cf0638c8603952514d8b3adde1a03ba57e3739ce005b287c08e91bbf357129d820318b247e5acec546f179751e0e91bb0ee39e8a63aa1945821f22e444281755583702ca5cfe6f33dde89ac291e62aeae89182c0a54e152812549ef2525307b242b8c866392fe4d39f2c1613d788c146a402cf8e320d2ef7242931263087c8446a0222c1f88b0206f309d0d6ed40064af204478fab9a8bc45b405a287327d3a82047a66a0175031c07159a2d09fb6bc93a89532d68975278b12d3a8c40d4cb6699da5c91667ee99f2c5561c410491065d49c939eb8911c41190a545c5338f704ab92456bd84001719da791dd45a619a30fe07e2a01e4fe5cf48a2a4022154b960d3268427e3691755bcaf15e43a4e6c4895998627e90176223e96b69f5bf426128ee00d13e1909afdd59c8eb6284a2a21e86a2a499916d27bd1470ddc6ad4b0352ffc14aa2e4af726d952ec052ff7839904893aae0972dbad302c6a6fbf7bfad1ce8ed24d63f33890f6a81de0efbb79662fd738540efd6a03c26d2bfb96987a77f76538988f99f8ecf294b010cecdf5b20f1db6a4bde6eeb6fad71fb2f1596bc5db5f41387e1b15ce31de7f9897b9eaa20debec7877f42f9fc77ec5cef5af3c3bbeaf3597db77afeae4fb9c2ec7e5a9fbeaafdc402d6877b5e2686737b1daa6ab8acbb1e55b1bb6928f7d3e3f12d986b441a05772da21aba5719ef4d92ec203ebb00bcbdc24c42e1857f4491a0bf64e0c163248dfd1e2a21ce0a0aadfdfe896efd3960d9da4f58416346dfbccdc182e77ab626f36744d258c4dfe677ba26ffd3d964ef93513a127b370486827afa75b4a7613c0f906b44ab85f9109ed55117095b34cd2bc7febdfea129e2724513a7d716609a2b49fd8dcd07726c761dba91c71edb2ad3be3d4e7c73be9e4aec9b12d3d39b63dfae6f6b788e1eb4df55f4303cc9fde1a560a2fd1658211dfa6794ec3777beaf407ac7991ef620f4d6d7157ee0861132fcfe568470ddf1f444263919ed46a8fc1af52787e550431788da5e9ba7c8c46f2a9fea689fddbfcea67aba9c77e01ba3fb050c322ee09279bef2ee9ef570cfdfdd4c04c226341fe43bee20466af1430e3d2dfa634f57f6d6a0b8e69bc7ecd07db0ffbaa95f4960af20fdbe692096c415e87630e834d36b9fbf1e6e454b2d1d4c7afb0acdf2f6afb465bcdad04f26a6a5cf7031fc9a25c817cd50c5cbad83063ec051bda81f3dc88331ecdaa2388514f05e1c499434268abe09524a05600581ec6a64a108da532d1ee8fcc520583f005d92a3b80188ecc892fa893f6df8da618601b5e3f73bcfd8677ecd77b8f7ff5eb8020ac5d8ba46e6b57eabc32fce654b46c4aef1306cc18f6c4be364efe7f07b81982c6f3268453fe0073499f4765e3b3dccab498bbd26c97b4d82389436b7a26af72b59db4f3b42cdc82ce97253fa687102ae41ec67fefca75ee2e43ff1e7e9c6721745fb6d71b50ffffcfef1fced8d9ffe673a49fde605cf8f37dc80fcf29f98b710ee1947a2b9fb25e633f83f476e43b8ed2ecf218ce5c87908bf85fc87cb8d8b35ffd52ef4cfa9b92f4b7c96c333946e11bdaf33a554270144d8c75c19c26b3840d763bec441f9ca210977bfa43be3cfe2721cb2aebf31c2b05ed9187670c0ce47708dff81565eff4c1d44f48d8606f03b2ce551fa90fbf33e9513acc8f6ecdd6d81b9b4e31c0d972d965dc5b156a42e57919793260d17f6f5374b6b97844329a4daf20d33bd92353d4d32897335f00aaee291d0464596bc64182779ee947ce089f74842adfcce80c8c20e185756aaddb3640566a9fd93c00bf9da3b7897e0f8363883d1fba8880faca1b185c458d1e12a4bcdc796be3692a9c5a81e554a33e4af0db72f831f4ff054ca3e22c2267c5a62cf73c2c1266da487a4292dede242e50b49724cc55244f3e7d75504964c99e013ae485a44d2c939c1a921c997366402d1b72f4bee6ed24362199272175ff61028720a8b373771635f45f09eb9d9c3140398130dc5e753c4edaf7da11730ad09fd97db23c93a7434d7a23cd0b1b478016b2f7cb26b439321c3cf70d06da41253b2ce16f751b1de5c5d82ffdc9fa509d27313ae5ba52d17159950de2d091a8ace1042ba4264fb8e39436d77c167c8a051a6fe2e1e85d78c57568ceb894c259a90645616e9ec41197a5374f78aae0155d39068b188d1eda5154d68ba532568ae4dbf45ca4e41415ed27d67819696ac95e04fefe13cd6b2e8ca2e0bc2194c7d55e5e884ace19c2ec264e736494a9b06ff45c966c49a9be4fd97eaea20511e9034bfb6a18e8c332293e48b4a2aa480e434ad75a849cb6624bda3094b2b78c614e7f7d0fb24611c784299899ea1b98540b7245a4b75aee83d43baa34beb1629b85e9a652b698c455109d07343dc3f926027c122c57918d85764a52bbf90aa032196a93f4b6dd6acd6453e0b1cb7ac1fce26addee2f4e7292b85ca22a910a852138633bc793d6c9187941094ae477530a589ff60ab4495e43de94d2699bc5def59d99513672d7c370074f24c247d78563deef558d0d090521979689672be6ec5205d8af02441901ff13a0603daf812a0f86999fa53fa9e94a9ef67ec27618e6e38d433618a541602454e51179a6e3a03e98d3fdd9670791fd7def2ed848b65c5371d2175ee39a051092cb368b7438ee6c451aee26547773c6e1f56716e696d33781df1bf9a74788d93ebb7e4c32f5b17f81aa01470d7be21c9a5540b2709e8325121eba867705d8a381db85b18ce2a9a92142ec0dc42d47c8c0a27fa67ab3c2e0ab855a769185d73aaf960715aaa44cda71425656497ea4666e85e4b74be225d1ac9ba281297c5ff97947c1bdd7619d01405ac5633c22899b6a20245cbfff9e5b91aeb12676486322dd522432b488a20ae5551d3ba15bb17144272d677420b4f9ee11458b6a19c479e88270d21a06174d504ba14eae4928afb293d06750bf49cb1be20ba8d9ddb89ae43429ccd6388085928bbe7267268cd234a4bd54d259ba349261fbface981914f7df863276cbe8a5e43635ec243cb7694d285aefce88486983556e9c5822896028d78cc0f2dc71f803110059ad88418c945065b3cde5f437b0a55c6ab68758b4fdcd6ca9f22257356f755553c48c9a0d42e56a9ff101f83d496363993d239474a4824e8d0931480c8ee0c3119a6e4c04fc989efe28eeb523cd9611308ae8ec850d69cf8e464d599b39c756204539a24563dd14d422c8c822ba5592ff632b5076c2fa6cc0de9e948cdb6d19f8cfb39b273be68cfc02133e2e6b2acd04daf6015ae522eda9907bdd6d0ceec4991ee721e379f2228d3bbea50cacd00521cc5c2bb13ba01da00d247ca3c9414afd0efe69579194d8750e953673db40f29bfa0e5e3a155985f762a640f0fe705ef98e539417d179990b6b82dd95bf1269f33016921f615e2676c06906642ac96711a32385b552b8dd5f9e16f933ddf5aecb1a4ec94c2b79c22b6a1b4f3ce607d66352b89c877bbb530fbab55dd67d84ef2e60abf14bd9e98d71475acdaf2725fa686e69ad2e46e6928aa2a910a51d4ec556f5add2da3629e338292cedd58268c70797b1531354551d0891eb6033f8d9f81e52c6ab1737185ee0757fc997ba469e64e86fd5c979d68b6bcd8cab555b3adea98746fe8229865d318d1144d9b89ede6e23b0c623e5bf2b0c48cede6706dd3db96b6a0d441476af748c9ddde8e658c832a53e284a294bd816f46301b79dd755aacc8916c90dfc2e5e9c390d23f431284a9c2c9064d85adc0f589a653449915d57d41988b0d225d9f274c2f75564062d1f1edcc6926eb000a205344c82a888ea2ac6914a89a5016f1ad8e2aa9fac17e88cecdc7c94015e4014bc0afa68a2f2b7c9e5a659985050a5a6e95ce6b1a0c6be28daa26d3459f555d56e4e8c01e74c1c0126545a0ed0461ead00ae9d943150f798edc2a3a9e2ad24d0d39c56f6862d3c06a311783da2fb3f837d0266e2e79d04b86a0c1498574573089a99a918c456608de236812b2f9b2c615cfa858e205e05b2c5bcf564fce127ea034911f6795af42a9b27ea2674a3e9dc4d4552f9615c8c5cc431aab7e006d08a2ae544277a3fbad7bb304077a795d4e4c5218f6d50c3551dda48e56965cfdee020fc54bb0b69b4a15580f1c0c211768dd7c8d58a8da8f3317d5e71aa0511a4e6e96dab9a90bd1bd35cc4bb685bb4ead9516c33bbcb865f76127f55260630f773257e201a59f9b7549a50cfbd8aab8ba3a068db6ca6443571095051ab2e8a664c32e6991491583500c88704603aa4b1196cfbd2c974801f20ed25fdc50ac43a22d49b92988d89314d222404eed9326802c1ed3f08d8da956547b1c729560464e6096069e34750e3635a37296e74b50b919ba9f75fa2e5e4c724693382393ba77e577f4784af8616402f81e493624490862fd81b39b875663aa7bac0c282d1902b343f99d131de6ecee293c90fb0e33ef961169df7909ab68fe00576f0e68e8a48030388d447572535d0e9a58038c93b58cd50e9a15559bcbf5a1cf709cbef48b2ee021dc2f93607d24cb8a37945dd458742ed984f1cbd5e6499e4a345f90a44daa65063b5ddd709cd8b228f2b4a65d92a77040aa844d42f4b4204dbae091ef6168b073a12934bd8c8cea2df4dfd0757ca384569baab2b543d5c212e4a2a7d199cbaa9577a17fda615693a52f2deb9109910222862ca507ac2c32b8395d859528702ae46659c44dc217a8e9c5bcc53acb80552705680b4bafc09a983007396ed6843897fa8abb55ec8acfbf282717da2ed2547eeafe4be00afe9bdc8b367bdfd8502a5fafe2a19982a3c5ee0f9c22a9861129256e1752656d1c0931e9d7ef5b5c0ad6ba75201e4461ebd73a75b467de6271911130d49c222f1b6fa1ca4d72d38b8e00c386d9d930bf1336808d8a827893e1ca6f74ec24347eb8ee4912811f76190911376dfe800f2e83f74863ec84a769605e3c67622962233494cdc66ad380eefe429bc6265ee5a18bba0410401d90ccad241391975794015a2f76f717686605ab50259ccd961581f9c0aca8887ad12d5d021f700bb022bf24eab397da3d127460626a08f9d0926c7592499e33179257a9c3905ee2e25ae1d2f717ed0d33ee61c1157059b47dce8a6646da15e8ad231cc3f867c67b27dc63706feb201220784895d6cda5d56289d670f8a53c8225163c591606172b5d97b1835736bc182eb0817c8e2691073aae2f7220c711ab74a23b6da5948cb0e2c261a033cffdf5d1b962c26301dfed50bf1e737e01dba1d2fdaa9187a21bca0d8601e58050aa88eaa56b09778524a8689c71e0183424147327f325b306776452e05ef0125be3b32acdaa898ada34bc132e0beb888a33121289b122cc40885791ff12f2b80bce0aa7c5c2414a4c155c68a38b46911064198a54c476f3805b78c1bb4efefe2c83269eb834ed830e6912e639e4c46c84acb9013df00ea53f7e069d11d60e4322626f99f72df59773043c2386c1e25c426dcc49ba9ef90121d2d06176c0da6dd995b732c44f03da05873ea0857023f824a1346a9c22be1c1ae852e3bca826d604de254b084222a100a260f5b22377a4c0f3d3847f72cf5c643dd0c32778019138ed34bda40aa673d34482c9bed892b4750970d116f26ec975d730eea6590f9ae7d9a13174b80aa82d19240ab947b6e0b101dc0c64bc35e96bab677e03c5a7e37cd3a2aa423c257097c1a3496092d02e1652de20b3d7f88728a905e132fe50e191a323b0647a12986421d5927669911895b811c14ea5afb1606f831fd0c3c03bd9cb23b67115dc0056adc744d259f151a28516e6baafd26c46d2c1a76396138897de4e81a733295d342149669f5b5de5ca31a9e4204175a005622f238c04693593851296f49c13af18ecaf0c272693f180b1c24612cec0c4b1ec68b18d6a4656dc389722092fd80ac362302348fa20f5e3ffb3f7fe5b92b4aab6e80bf51fe16f7dff17bb23818960a6994676f7b7aacfdd63f4d9677d554568188a30994092ea29499ae448e374b8a19cb648577950ba438c809d9a441b298094c010a4976f9354439a98ac1ab57ee78ed79ef56c2b34f865734cc41d925a69b8f5b5bd7f445f6ead0fc3467e56041d77209bdc1dd823693476a322323b1016a9b88b329c4d0973b0fa630e5c95b94c043ac1202b501c742137ad809364c8d6b51c8fd07c529d7c27bef628ce9794a552706565a9a3412bcf566b17e54e8a32a9ef8ab06d0694d0605f443022bb98054c02a3809fc4bad94f958cb8aa4a9f23249792d79b9a33305b947983c86f2dda8e5ec82eb4bf3aec32fec9bcfda3ecdb04389a3d1cae4d84687256134d9940ac31aab685ca36a69025fe5d259c8f6efaa2d261b70b252acbaaa99a0f5aa9284ab571f4c212d7262862916507d2fbb1375765dca07c23522c0151ad24817d46c7ab6cc2aed5732f8d3190a985efc9949f81dabdcce7d1e25a018633d9f745833f280b36305171f545cdd2cc183ac4fa57315e597ff7a09423b908b3e2ac30321adc17fe3f0c650e14f84af068229226ba60f7a4bc32f0c30b35f206b451846ee52255412d9e80afc1b741020a1510b220579bc8576ae9d163e96145083e15b71caff3634f5704344481a94d8caaabac6f0595a041e97fd07bc7a03173e06ef4dd1a6ffa2a2112b28d8ad4b5e57927d0eda2425321c3c60758a71e6ed6cb1dab35ed18d8921164393638539f65b3a49c6841d1e72acb44ea93a2ef555c9831b420d9252a50c8245599a1037162061824c4cfdf3ac8c9a90a7764a026594b4557f9100175c720dd04feec50a301c8146372821d5738b511c0b721eb880f9b856538a4175e14345f27c6377e97901f2c835c2c3d845176058134123ae087180b1761f679a88d45dcf141f5c845b59402dcde02a7b1a98f1440ae8c509c59d4023f29888f2d704582a121150c67d50b1c89acf06d0712c3d070c64e8fd3f9b4b5c54bd43d497f05ef880e19e35a15474e5e45192d0d6c29f6d907380a4922a54d1d9316a732a25b8bbf94ed1fde952ed91098488086e89354e0711195791559e61a81a0094bd233cf9900d92c542a1a447036286b0929abbfcaaf88407b15163da5a3d6a4804c00f1122c6f5ad9065b9e2b37566c4f6987c8eeb6c4ffb8d81e3a26923badf0301b9a423bc980a22f70ae2e53ef3d036b13a4159b972e46e16bb3e950006c32741565783eb1a8c29885561761330e09fb55e8c731497c72db005d8219c8fb2d61db74051112bc7746cbe00cb1e95735982e400de3cc41be1abb3e09d5399bac3d63ff28a7880d9de15276ec4bc5782b00173646abb8980d7c8aa839168aef4d9e784343814bf1f1241814ed0bda126c5767c4eb2ffd0031e82e661ddf500e515f29c01c0a1ab9e2395e28158f929aec6c5ebadc527079a8aa9099d36f996a9d7ea1b60a5a3290599b9439c7f03c883e1c94423fd1aa6084124c2aba96421f2475cbd88ebbc462efca591312f085d05c06558bb1e3ac5f0256222b03298ccbb668011b3088ed2148045a09344092528cf21243822d3ded5f7a09d9ec4a4a43a9e0a7280f8271d6a8267c9c0cfb0673a5cb91923e1855e160c6fc15baad72fc06da5b74e534d0631fbfebb0f12b066ad318053f2de8f152e356d4a0ac7583e9c93e6586dd4a948f08620e0363091e518767c1b1329045a4ac34b35322767151c59984555724b9bfc3fe53be184315978dab0a6b4309334d7d9314103550251da57837f3311144e5f61c6888410761203a1126d3c96dad22e691760d21bbffd26954cd7d1926a446bfabc86bc88a6602c718aa3146549313686283a5cf256c2f64ec65f9f3a63cc0069b964b084b960a5bcf599895f4769744b039940dc48f3f69166619fd88f71730bca98284cb40e7b30b6d987d3a213a28932b74754b07b0cc80f2b05083157037ab3a305649e3b217dee56ebb1489bb94994c2a45d322e88903506d44d5e0c7dc49a74f4fef97f643105bb18bf6e3e86895fbe1f11332911316069b4b02435576568237d2d56262e0b8201c88af89c52125c1911c350234ddaf691082de7c08d348953a050d0ac2d045dc01de414101c22c0cd704df8830e1c7af9ada4f801c874cadc85f115e5290ddc54a0b3e0287a98759dd2a547721bf65d92bf021e8b4340de888d7c9714aaaf93191401d552e0edac0d49e2769c8bc209c537eb91ece0de863eb602a25347b11a202286602d228bb93ada82a063613c5abf5995803c0d3803543be99f8d15df24e586d75a8e3045f904d2d65f8a09033fd651388b7e1e2221dc125c1aba926991044ab0860e7eee809c3c0d80114062c13ebdd21c12ab997344008bb9ae79f40dc60a122a498009c8d8d59c4ab3a32f03ac8bef9b2272320e8c4b666847a498a1092b11141f563cd91675ca0612f347446a74398dc2d95922a9d0107084604d7db4aa8592d1ea55088d8e3624bf302e9012402b116a5170dd334346834346222b42f01048bae2f8aa80e89937585613520d3e1b9cb825799eea88809817e1a941f4a484bc00dab579640919212c00707f771441856b0a309ccc2b98cca17ee802d4959550556c340ae0a2c24c97c17ab9b2f9c7a39fa6f12f326a28f4ec6859da101383c0fb883bd39767c2bcc2ed8940589bea5e8cd03a2197c318e565c004a073e2334a2a2c805941db687a76da81646d2d49a4b1598802643a3281ca340908a0143b2f483ba96099cd83cb4e74801039627aedd04ba6c26c1dcf2cc7b9a6ab940b968d608996619612d26e2c09ae40840d75b167a3f44d4e14f7053879ab0dcad5f2235d24a4c1266f9168dd132ede8349071941bb437bc9d06ad1a11ca655c2500d59138809025d9ec0ed50590980127e03567b4088a13b45201dba8882ad2c7534f8dd47d42f93046aaa0e5e885cb65385f51316789632bf107b0029ba1800d2ebd45402e6222e65554c5654d6a956c4709486421e654c5c2b477076fafc9df19fab56b574a73912b4f73766097a66cf2f687f00b1911c562f3140aec6b695a03c68e70dba11b8618327c7cd427afd83a7c8336936218a49f40065a45bb8176f080bfc498489bbe46768f5382a6334aa0c58b862e1bd27e03882bc27397e006b943302d5483670dfb13bb44996b527223804e56844744c094d071d9f8449899757354a5078a1b85418324c404d41925dd51114f1940d08786a9945e9c71f51681daf92e960c133253c50d54c4b3e1ed12b616390a11c4745ab43499a8984bb380b9b2f58612d53abc0a996443dc5fa21f759aa8b4abbb381dbc6383e20e01df6bcea4e3c5c5d448c648655b03177f85a193b9a58dc68cbad214d20c6368e790c7774ab088aa74c319d341d4685106d3875d117cd5aaae61933dc11d47c09743b4983f3cc37cc03f117be18f9ac12a28361da4e301281bc55499282ee8d03b2483d32050116e30e18762f3330326e34207a13347b55dd0574d13ad9bd49b62630bba836699840e9fa693806631cc1e60385afd8f8c985c8c68ab79997646516b2d50a614b23f1b5c4ba9bd1081d0d33bd4c9560932d8c866673464b331f62fdbb88244d810d6a6d569288851e0630634b342a31df18935842f0e187374459c519a06f7f04293af8a562cbc1c744632f0eca8ccdca0cc74ce7641421d13323a22e161f6620cc074399e2fdd50997406690ea78a2b401aedc225c9d0dc053e8ed83916d023d619eaa1a18a222d5091ce40c128a9a464c2495d2ba20fa47623ef14e5d665e9597c358daa0f5076158b2f7217f4ae9d4b83e6655eb824f83d06006425b0f0cfa3fa165df5f115818d497d0c393949af6c250d32605791db1b65a367695f03fe13c3349338d5b5047bbcb4bb91307ca2e21d311bd88c0367b80e1abcfe322c3bb7aa1f13d43745742f69e65e9653d435042ab04386874acaa449393dbe4ff536424af02589ada4a4b8da87f42e62b00621b6046f656ab3829d55381d836238191e62c9aae8d0fa28d61982e5b8e900e13d43f527f4d3e50b3d093f3a83f12235c80b52cd24a158e2f66a526484a93a90772619a805c10972009e145f12df19bd88d05e2aeb990e40ff25cd1be86db93023497c29e0eb81944dc9e7e28f770469a2a289014eabf0eb9be2d773c3016ba60dc61e5b91f7acda522922fc21ddbed8879d042c52821ced888089322ac6185a1f5bfc15865110fa31a3546d466a82267a4413828ac8e3a715eb9224c62a34239071290a9a90e6a4a9a7e89cd512e22e88b85fc21d0c13b564da2e30a102062a0a4c1a023f78b29c39ad7dd838cd141bba816a362bc824c4cc91232171556163834a240e77d628b0b0903b40a149fd2a7a79bbf8c3d0403a78696c042404fa831e2c260625fb11980aa081415ef361631242151cf3a348014c5c0a497963035f3b89f68a8683a719039298d3b11dab46b12ee43af0c94157690e7604f9111b2038007c27c0591f92ef5705024d0ae26b45814bf224d59716070ad62582550cd172806ce094245c406471459070afae2ec6404c3e88e6eb096447c9959eee336d94198a67d20838653390480b9591ebcf27a7027cb8843c11e0dfb3c51595bb58ba7283c1eb28a238b286a35198a546bbe4f4610a2af9322b3d0392e26c58b81011a95a975ef7939e07ae98faa9f2b42239d8ac93129898c27967458c46a04903410a24319ad494324e0b45d78b78842d9a2ef0521d0a0e6647c76af63b41e0cba0f62b6b5c981ed2910eca2a5d8865fc32c95161467fb2ea7a18fb0d740cbe2d94ec3504efe85d490a0167be4fbc305b8ae2a8f6d84cb657173348f3fd387e7d812e9200f472a2276f74d42448414df5a156ba929cd8b72b72150570429a36e905dac9b453668214e0a1497e39c0bd240dacfd1739bd28358d7c675c0f9a58c721a5a43c92cbba4561361bcc8066794721378801d082bdaa5d5c628336863e10001231502948996c920f1b5d92f08642305a416c20d45f24d1a68b7bcf1817ae6f40ccd30dbb94c20b8d44b31bd0374091220e7d03cefed8931c3454178cfd796475c6e954e98ee02d4bdbaf2a7695a4e53e6fa580329214cb99292100dca3baf741e41a4a6c7315f52e2a274a3fe124e9195d7305c66598dc8a98737eccc0becb201db1953af1672c2bd3a3241493618871785193b448cb86b9dde42d51f34b15386ffd2870708797d08071f2bd5f95301ae1bd77203a15a64f95978ae0a9a3126553402903ac8ce061ccecc00a045ec8d488ac5dd8a61db9560ddcc4010b9ac5b0e849ca71912d95657e5109deb42a176e225cda338f3bb499c5a17c4fe5a0f70a8818efc331d6c19a8db4e5d0a854008fa4488a159fc182989b769f65f0b568b864d25cab42a91aee4843ed7398be035cce048ca12675ef94e19bf45ee278a9329883d2ceb914515668b4626be764bda7aad0dc84fca3707184591e1408d1209486769a5edc2d2a1c845f826d98f5624e8abe56d452abca5b57e897dd7d25c13620dc0da609200a8e394e82c1a5a0a2fa25295b12a60e362911455bd36a3c02d4e859138401748e23225f3c2a25592c0265f7512d6167e7471415a46b52d0d601a29bdc0458d4a2417d5e0810444803c3336655164062e03c267033995ec269206832cc4a73a80b1be4d60529b081793aaa61080aa541e2441c08164a5c17f39f2cfe9095ea5171673169a9612b23525ec135cfca46b9506973eaac0266770523aec2a567bea582725785de807597253e9410dbe1b857913971329a6ab00bf514345c20653207c21502577463909468aa3fced6c14ce46b60d28049c7fa6a701d143ac61d65641e9b00c103d65a1d647ae696641087d5e9694321f1a81cf12c1fad8a2d59e5dc7174818984c89c0c08dcb3168ebf4c5226672ae92a0518a15ac72908502cfc2465b68084115067a42ae332c378c992aa30c04057b88d6bc066e553f55fb3d5196fdf6bbae082fcd6999a9626be238b28b86593204006d05e130c9d4b5254c083a8c3a03bacf52f10001f6fd6a584a1e8623d9ab4531966ba94b2a27484009f25e1121e33445c6195b23d7d615f2b619edddd2a664a970f95148b0f12067bf83f492f6f457c02fa820b283cf91558b48cc2b8a27778391a4e67476426c11e135848a8ea1c56f8655296b3a53eb065d2d41865ed572d1f222bbd3229001a74b74a50448a69086da2e96dd7d4d0ced55d195d004b00e801380833141b6277c0213b56be0b03b8087a53414c14469704843a027c7cb28b524d326a8b4481ed8558c4382ff2a810e491f5059b9b915ff0ad3a10915ce0f92333582355436121f8c91d193fec06658913b2bfc55e825aba1185710aeceea6548988622b01d52482d2c5222801b35a716e20342126de91cd9050c7926baa2b11a6e0e30cec34d44ee512693055bb9490b926e023a591e2cc5b69d07f490d08044313427f6ca471f82e29117298c83e27dc29cb8f894b034806b250d4f50f2800cd89f605cb12f5f2150b5500fb22901282c6a87cceda6326f471613821b34558b251939e3abefa00b2d1354fadcae5d2948c0f4ebb46020668b459f6d164fe24240654507cb9ce2b0058364199598537d05c3884222a6258cc022575da3540d4355e3ba9c520ca32628b86fffd7231a0f46b76fad77ba9c1ca2a9a42c5f6459323326442da6913e5dfb4fa4e040f8d8ee4c0018b974d0863c29a743a0ce0a016008c19873617e5ad009be240a1d0d6323808b0cd84931241c701a5984e5ad2bdc37aabc0b540bb043a0f5582626d683831835d1c1463ea304f0a1c41366f9392aa2fb91832a29c6522a948eb2f70b3349d414c6f445079019077a49834088664f3d60b75c8e7a9ec7ab5fc32fd16a2d06fe93465a5fdc5a2d177840719121850795143e570bb060aead46c1326f87ac781e3a04c50b0bc68201b0199aa99618c78823f2f8d8c4882313889f4f14a83ee3b10f1e089b504f6a646b12b12af3828111cb387ef6cb518c05baceabe0600ebac16197894e2d30d8c860a13ac04533e4598ff41490c0561ad7899f08a24a719326f073d74160618493f27fef692e03dc2e3514a191720f29a037b215648864343565362e67d9658b8e4cd6539a05cbd2b1a466ed23871132b45a20a4ae89bf91df49d6bd7e860130d56bb2a25f9f643198530e3346a361466c90ac46952384775a47144407429f7096a307352b56047513b65f306b53c32466ad0b2088ccbe640702d030169197116907724c158f1b93a9366781628aa8c63dfe185cc36b901b4d8aa8ece0433c0bce32fd367b5446611839e9fb8ae5c1f665d997f50e18269ed31490228287726516c846e991051902ea0154c8646920b90c2042014599d308392308763509ce9c22d16b5576c45f1aea85fff3271c8c9648e521c9a53aa8b60860c1ea95e2f1a526d0817073506c8db8462e55c88384321eae24624c28599a30a974b720e2ff5c70089f1f55070562f5c8251b36333f45356e702065c8f1a9dd4c04352b2ce98d7bc14a9484af9aad0090550c004d039542c1c7fdec7c2d095c94a6b0a46c560f9b229073e8c00240390504be6b6444719494f564134c8d0cb57cab3aaf3a2b4097477e880e3af86fc3f318273b480740338c18a80498a451979553c0241b5115de9524985eb2d08852b29a27015437156fba82b35a04a7c09305695e2af1d61e9895ee028472ddc28a4a3aabe92128302a81d9a6bc999516a9b8f0a4a1e1c34f1d2e0000df5c934d6ca3ce326142925df6859075405464485af79f42acc925c35d40f64d314176af79727a8f3f3a538f0249535f905686f73ccb328ba5b1153500fa220fbaa89b9d9c55a4d974d1e1bc052f36509e06c4749f6d1d49e1c46001949b44f95af1db88e67d17ac71511380030b2ef91551ad4efe60a215a5b69c0a3af6083829226509d744ba952a854823c92a219261e182f0d418075348d71a6c34a4b0504408566ad8c9601a5d0410a9265175e0cbfa38e90c0aaa88ae33490465487333432f45a1fe62294aaa8120a55868ba6e80c75645bb3f13bd8a89a3e86da16595e62202dae01fae1572dcd44eed8564ef07b244143ce56ba14e5caaab3c5cd01aa99e4d94983fddad0948c6eb1b2646550e854c02c3424ea1abf4888c4f488322c1af48691c8f147c15ec530c9d000b4a1abc4da386884fcc90855c126bbc2c24c83905ad3cc53cb806092da5c5958aa62086ae029032f55b348bbf0c5b989d59c84e318515cb7a3415493828151fb345549bcc8c0d186da1a38908a1c67bdad097bbc60155dcd1e2fc9c2110a7946933ca5755689ca93ad071a712a268b3a82f02e902a3c20d5b051c069e132f0d5ab7c36e48f33002989408c6f302c0d7d91105ac9f8425a9092739a8b6ab520a15572eb157b07a6d905d763d34f8b8f503aa59265c3e50c65ad4592109753c39ffdde0bc52a98351000ffc4a06197a1ba0d3618435f13644654b242590e29cbc066fb40042283b88e5044d55424b099d12327a2a11b73052e59b1018ab6c4aea10c9bd671c04e96972aca75d2cdded44251cbab082187cbc65c4af66a7223b6ac70120e40c4ad2ac921080a542960aa5429a9dba565252e85a753d1608b565e44d691544e105c3b8b8d5f817e305a2eb797293c067a1b9ad515d0291945d3446e4da49da1238175b8b06617c589b0ad603452291b7e3dbba14589349372089ba62032c301be99d987f833276699e2b05dfea44414af80554f2fce4c6e75800a5a9004f184106ee7cc2fc49fe4d68d48cdd6eab3b3ff41d234ac062a9f1017982093c0d4112696abdf530495e0cc5c64a05c28c84adbb7e49923cc5f8b0d3aa5237070b7a2ca5f57bd2c5dbeb94e8cdea44c13bfc4ee148bb7285d03f663567ba0d7099231b8425d421a52b960d525844d49e9804dc1364e008f95afd74b7cecc20ef8c89adc2005aa791b679428d15ccda03185eb9a79f702b361ab4a2a99664fcddc7550794653fd82d88e66de2707ae5dfd9729e9a6790a99ad809140a157f561d6bf41d31429d53b50c20459bad4bd4f9d34a4d9b2a57029c690352455407255422d5b87838fdc0066d6145a6733bc2be2a191e88ab025efa90b8fc9e09bf34e003184a25193f0acb04743c4a96aa5e5199b04770be688b6afbc90ae0f28862d90d9777336d141416c3669712340a7091741ca7a5480dc526699354e05d534ab8b9fb4a24498253f24740248b98e4962978a21e2e84af131588449fd3da40571026203941bc43a889a7ba07d2ec5e29e2850838ed0c03dc3b230abe8cba63a59fdb52bb8a5ac27e5f916012eb91832fcea3c0c935dd246c0d941ed13b9472aec23bd6275b51a6af36b6e56413a4802a7b8805b3e79257ca1a9221ac1f86ccae2c99a3323c7a12a596876ce97ee8a41ed478edcc1ff1d98857a231546bea6a137818a9be6600c842b3ab6798083a7ad252242229afb129196debb6185f1f55411f368286f00a373209a5e107a690abb691d2e56add08149ae79650b8b33aef54484f495809886a71f6b3ce8c5eff063a9ef79f07fcad1dfbdee902e77ca8d26ecf56edbf6b8edc2be9528b7fe9ceb55d43b221d24ed7391847abba70bf5a9effbeb51e22f53a7f5f05fbe942c7bfe39a3b49e838d72b6cc3da130c7e17a7f6835bf7da508174b1ba79dad383305b55a5d7feed5ff6a8e9761e80c90193f4f525931b60ef5e7e106e8376c2401a43d587ec7e40da0217ef8d05ac51f8557078cd4f782a35b8d2c55f7812d7dfa0e019dcd34d61ad50e79279bc19ce452da17c64cb0ecdf097790442e436bba402679bb0350c74d1426aabed1151ade6c22a98d211e5f9580660770f66ebf4b7c590292fce65da9065ab46427cebd02d0665dd2c36651dd78bd59699a9772a439827ccd2aba21ee96ab2a6b21202207f05ed395ea6eb9b8e45a440a8f7434bb8afa3488966e561a3e9706f32bdaa8b0d71ac4667a29de9442abe52472726c68adeefe2cacadeca11b1a08a0c280d686e1cfb2596130d47862177a00de8d49c3502f3f9996a11db0002fa80114f60bc00a5e298d889c6b94e96d084acf4a944c2e7d5e3b2d5ad5b0d3b4596397e6069373432bb46e723679e1d94d1f10fc734e6f429a4258af7e5226b5c31b17cb38810c131d8b115cc8a703da513265d64251461edcc63680912e87ae839c8e52585c9542cb0e3092859205520e7bf992529b0e6923438370e864ab9e3b87267a5abf6291908cf2ba22547955ba4853d276c19846db484773c6152b008980c243da265ef9c38cf8e7e45653b058449ea2f610e7a039ddc115dc4d94c2a0ad676f07adb7157105328811904f5bc0ce41ba357badd99ec8a07dbfa3dc86014d38a2d435ad7084aba4d087b947673572b07a52473101804cb4b6d2501b4d2fc8eb912f0372d3ec3a1a1082e10a73405a7b30dd1278a9849359c5871fa0aff24a447413904f9600efe7a409dae0fbe8657269a9f90b0c0f055c644b991e9b1d24c70067f2928b9b61c9a8cd6f2558abd7694456d9eca957347d9d63c99820af6589b67327db321955a72e4d27281248e03015425b1d19ae1a0fd7f5e3ec7734c1ba5052b8a20437d86ab5a1980302201a5216701fa467eeaa8e68e88596fffeb45fc845a80acbc6a6e411e55c1764bdcf4e52caa889c834a4d560fa65fb352bb848659bee922e3212de52568a193a9857b8fd1732a984b9afd031bbeb0dba1b0b9e81c208e138c972d4ae4a79d87c1929ac2ead4d2f04ea93ee7e8d44148045dc0c20a1394707938e4f69d5c2b8993574922a4eb3851d13be90a99f253978c0acd462aa6d7a5eed97e977a6a11ec9aead4a2a4a863cd8a48198c4a2a07198f189f41561ad76c4d022f697347a2ecaf7ce1abb457e29d531094b2f3b5acaac26f6e411e60c1c3d833904f884f76211782b6986cb008f789693d76c1df9cf800a2c5d79534ad1d412bd400223e8ee5552a21b82df09397c1dd064505c2668e92ccd020b9351a8ad32a4f01780f719a193a257886fe408f2f38cbe61c38f0b4d1fe0ff76015098651d7ea1cc76848f27fa45027e48eb492e3ace64f286ba1f5d06295213664832f400b5ceb42809c8eaad1a684e48692da0c895a6f93d4a54e66c2ea160a1a23b57d680d522bc32512b639254c1786f13ae0fe2ffcc7cb8a0f62e976292fcaf266520a2528e062e9e883d42579062ae1a88ecd8ecb3a95bd08ea2fc7f50a692b59fe4e3048d0ad2cd309485afedafd8d10c96d75332d2ab95ac720d50b19b9c6acdb59444fcae51caae6479ad4ca6ac06ed8d5f2f8470d53e44c53b266a29518c932c2ec953bfb4728652b3299228d5ec07dc3aca25927b800d528e342873b648b6ba144ab9c414e2d3383069641134bd820700e3ac912b447b93646f5425799302bec44a60dbfbd298d910b3a5a0c9465665d9d822e870c41a483433932ec929895ae43368b317d12660ae69015c2d88cc11c26ac05e4943ef3844d35b6851154856ec14f83d63d54af7c4ab4a8d15611364cd4dc2bb49aea392b3acf553c41340a1daa84653d6cc5d557b41a10c2c8eda3d35215c3389d5d8f9ea8b744569345eae1577277d9459c25d7e8e243d0ac1680540f6397a36565a97f21a12c4955906a90768f2f43830a35104c97750981f2c5b4ecce81cd456a51fd1f709f5080688180dc14c8e8f70cc2ca30f40947bbfa35045c115308b1384d9318eaaf5272c97ab6e371a2a041453c94d2ea7a404aa26fae9022513145fa99d2fae76e766eb43fe9b59f2086dc40b458382c5d82e9434abe8e2d2d0115ab35607b65b2eb8890054b0ed85d4450d31c006d10e7111373c9b68a2b4d853ad1a6e965cb1726978ab8b522a12a5be249d56d8deba358316118a41d52f142ea70475859ee26cab2f47b6a995a851ce02942a49161fef38981492783e895c4a1dba24ff48aa1e0081652d4e71a5a4511d6c456d1d2bed63c06ed70a0f0d650a38b14f600fb6867332b687cc52af066d8c50c08e6da8a72aa16d74d246f9c3594d58555492b0e8d0d35ae5eb5584cec30c7e6510d1b5e20bfbd211659851b38f02fca027c5c958c69e2f17321d381b22a300f02cefd4644dd9f8c6359cb5b0533551cdd42773b3bb90302fbaeea8813a286c985cd89bfc5ba852edcfc13828730693321c40dbd5164f5153c92f8d6703e798759c030c4c90da847f17f429ca036e20ac7404e92b029da982bfade4762907a78722686758ae3b11d1281224bad9e08c0d273415632209d2668670d9a55816dccc820c11594261aa664083519dd92eecc8a1deb39aa8b3aa2458c7f38a919706659327d44067e7fdcb2442f00fb4e426e37572c984facb76dbd5ecc958957ad6c579d323c3a42a09e2b49933a7090e5d2e8a04b79d6c260218e03ed99e01b02533f334354d4189225592ccb81cc3857eda979c1ac67306ae4d49106c45ed5725fb29bf477284aa86da238a8732b4200d0022922c3ace4111bb2c81fa272b2f2c2176211b5e30ff32bdf5c460e55e1b15250ca6cba7c5e17b32c49ca8fb0205aec22c77c4adefe166aacf17b3a60ae0648fa11c270dc7679cc559eb194ce92c6bcb4ddb54234664d92a7398531af42eb8922d98a3b74051e8a6eaad5e41328e6aa217362b071c9c088fb76b5a99c6ae849182a840963a056ccb28d3bc49c5df213435051dd175f352bf2da3a21bdb2043aae04ba536fc2fe181826382fbbb0105e1fa8b2094cd5d2ee6198e65166e57d77b46e0d3909103daa7e517b5a58526d746cd35bb10851a60fb649b0ca1951daa64040aa15128fe493ad40f0e0f35d8e194a0db5483aa5f874425a32ef40a2ba0354d4861086ea225d08316590fe830c67b70f6ba8d33fe2545af41d4e1ec06297124ed2660366b99b9010879562e4299f8088e77039453875eddb2f0b38d6b87034a11b58c5c28f409656731fe42e735eb2d4b0a17da965724d773ab091c58c6712b7c992aa5c48626ba0d2d14d4150e1a28620cfc556e44251e4794e2e0280520ac52a4e0a56b4c19a0bc875072188ad34a401d1ea6801280da6a99f60f50e980188bda5d175c68669829eea19919dccda0fe9a9d46b8b4ba528d85bd2676f840afee0cd829a3550550570d384827d3cb11adb342f738779c0da920281b05f00815121fd80f19f8a6563d08b835b89a86da54514b6ae4a4a00138a65a129d2117b9de121448d7f227b3b9a774466398a26abe58c25b29f8061f0b0c78cd7314352d7081a83a8d978931c5e52151ef41713c5437d604f4e9f5667c8c30d1e5fecb3483e3bb00409372d6b5752c59557091e1afc193905a6db3629868df3aab280425bb0283857b26972453e51410c8d8595d8b1cd1e1d644db2a2095d22b192ca803bb216b281a0db932f2a3a619d7ba95e9183401ef09019e5e42a04e2b365c5969992845a414b40b1c6dc6432e2090624dc036698252021d26db27694962741ece637203c8ae4183dad9360af446ed7541a71cd6459b80af14bb15cb2360a3ceee1b03f06954fc916b938cae014fe97b1023f67a90732ecaaf600d92064af59c444b0196da14034b8a02ff7c4e250d35a131a5b63f61b6b526c3cb766c9eacc9065e946d8a2c811c15c942e684168a941e2f0094e8e356845e8b460787e46e9564ed10a9533694a40cbf40725182528333d489d2712bae7e850e23c211288a65125134bf365e9a8510717cebd09c17f5d9023ac25e938f3a77231ec7566f7320c22c0880dad55746a6ab20a90cc0694f256e541e2cb410b31ab3f08095d13a8ad19b525aae7207d4facb16198ff0cc06bcccd15483a38b83f60dcd885a2505848518aff092b4b2004f52ee0885928b6d7dd1a6ad934c383e6b064dd3846a3c45f24486691eda91ca206ae7825953a4cd2e5d6f39aaf24589d03c9346952e3d0be881055e259581ff48957daf9a4d0e74850d328d304d7f31d9586643a12a89f0c9ddc51518344828e49b0be49de9104e3a87045a439f5701e0400a4d5e627276601a9332d72e4cebb214816aa33288bfa0d598f648e742bc0d87b1a030985204d823ac801c8242bc700624da28ab6e4a68d2be4e45f712a29a5cde46cae484a267e802ed1f999d17fa4d6b2e43d44432146211e4f912b9a46979417317038ab4470d8f28b4df11f66d208c490249d2e700131ea8ab22016cc1e294a310c4789f31a00e6f2381c754148f8da24790f707ced39551b2b1c11de7622560bb17fc32021ce39a4119ec1371ca8a86e2c145c8bf4c63469ab37a6d64da35b0a7c4ba8941c905ba9593a4622024a87d872a7406dbb297345411ef8b43c105a7161dd11a8230b49105232d1d796851e17776bc323041d146a8dd32c0db655f2dc1a2e1230fef07852cd18991ff4483ee4183481db918d4cb4073872e100ff2858815bae60cb014c27c47d5e38c33a4a0293c9754e44118b7892218b0b614c5d45ca6642bd75d4e2149a9ba62f22a350b7a800b2290faa5143aa072cc1c68a6b22b478014c6469e86867a0a72c9347334e37e19ea049b5b48efc1d9a31d59857c23721559a9331694dac92ef224021731010130cccc62206a51abf9d58eaad35a337b82eff8a8e44a00646197a529bd02579e44139044240199f86bf6a48ef3d36545c1c0de919418348e99c7488a3c07855ba20616c14e993549c9f8169a0163f4f0f5483f688dee314cd60b1dd5a4d4ae8c2af1f9175a53a0d2143f09263b289cbc03f92619369b6a2883ae22aa410e084cecae194405e45d6ef19370667354ac4a093bc050aa86c7417ee2d0164c71ae8f7701afea1a7029e8a5dd109d0bca206e8a1016a95e371c7f4e728d02fa32a0f6887606d202e468ca40abcb7311061d6d4335a33a80192930d840af19927c1ac016537c8b53d58ad2139b96324676a1b66f8a88c0cdce1db50990a8780b9126b46d82a2d43d3906105a015ea0a9c0abe28c581923e3d8321c375957a0950b14da951d983171f80d454a16728d42bc21df5bcc404100bf2a401705eb0930f94159994d20d96b526245537fb22a896d6819ad88e02b3b5f5230220d5b5b54cb4fb16a04d737227dbb2b3786377a12bd9791bcc9392b38c50ddc0dc917d5ea935a455b62c31a20ee53dde2705e82547524c2712d3e64fcce6aa9b0918a871d2e055586f01739d716388df6d2a74d0c2325a0535044730c25d2258583b025c5178b5adc3a6a891f6a4bd3d196eeb2ae4084cb52d5ec1da8a61a94ff024ac6a4ca65a0131d1f92bb7622f016a661a1685da800042b824db4fb2bfe745e611cbf115a8478cd644aaa7fd32b182f05a1b4abab2f80af38008073ab39d80c43197c1a9b417d9a7ed971e3accec047a04bb9a1810a509af42b7f5c347d51a9d76d2865a24ad6309fba040c0ced788700e711bb416b2e0c2c252376724db1924d937f32345d36c8754d28ec809288179a02c034e0aeaa5a093aa3f45e474e3dda9571b7af5933ee42a11b407c02461644123b08f041bd388d1a6143d78834384504aaa2aada4c90679bb4a9c890b6d74a99467f55b5dd07a3415db935976d445a01fe4bd76e291a5ab53a8950fe8bb03833a816fcc5f8dc2459b2ae3e81928fa316a50eca32adcaeba5496937430eeb0693f335aa1a109a931c341cd1c0389dd56c07fa85b32a5752827692b89ad2c5252c52501d5708aeb81ab2a4fc3535892b1ce40c231a306a9746424195d150cb15b538024a4ab052d4f07ec8cadcc8b8b6e8ba1cd01819a484215b969802d580fb51028aac3ba2588917587f71d62f43616fe96597f4fed30ae331c29f07e0483cd80823f01a9add9260f62b7313b59a7b55c26bd06d22d57438cf8289704dbdcb8ebb1364e88834e7aa00cba51c19d6358853b2e2d33947a9dc03c4450b2cf3a53a8141e58a1494b0e517e30364dd04329c90b4c025a623a008ada634400b14facbc8a6d771d3686bd4dc19200d821514a903c9d1c16924054c356238b6cbf50eb8c08de9d34a624f2f683395aa74e8d9253028749bb4c24ac9ca5dc870558022557c58b045922c168a21739a138aa3d60e76bc1658516c87311f5c9f9cd384e41e462985c5d8049ae2c80aa0c20b957862535ce04263960ef8b669c8788651d8975505169382ae58efa1557e94bf8dbea9bc069ce30ff6c290c2d56c7f66c502e4fa4f20476a0d53c49db5ec5903355dafa49414e26aaa481d350516a4367f93b84dc46d3e6b7e4594684a7a7a35f69870710212215688d40a9242710ab049b70346bf87093e6a6515181cd2be8a9125848699548df86e423a4b42d81a7d15d5fa0282c7a5a8a4dede98fc1f7571bbd61b53a62977b5e2fddaf0ba518b4e288b8a56a74acd8e88bfb9aaa6fd8050c1b4d0ca2f88d608922c8088325fc929285c77018f939ab955431b11655a9948259d5822c88c11752f856dac6d76512756e36211555326fec0e551a30442d123b3816d3c73a0b4592e07c910b1e7200c024f55bd572d956cda1d4cb34bfc23add527cc32985b098633431759ac9e80e40a291b8a4b3f8b9bcf2dce913b4b10438db390aaf4f52fc87640cfcdac08679fc558a67f1a01ea269d99fa6f3d3892726bea1a25e56a14c49f3452a27ead46a725d80e4a93f6f7345da52b087ad2d027227d5bfdcc4b89c3555972010971305e9944c22e77917dcfbb37639dc479d748049fbc696114893d4a7e0e371504b6c21f9eecf7aefd7451287312d8222cb10b3c2705843b700f78d415f77ec3ee5547854b3c152007d510c9c4009068175b0cf03707ec990ea522f5c49bc869aad950903e093fb16bb89a498cca200bca97e81a69540637e39c883c70a609e80a92de32ed6404707a520358980a682a16b4a54995aaa50aa523c4cdcc33edfcd3205981ed706f0db5340afc42848dcb00f5b7496e67e23b4bbf87e03a427a8de05846146896ac18a97fcdfdb13542d6c546c056e76adde018ea16cec25b94e6195abd8d3b3948fd022a89da105506c58a99b845b643a928cf8180bc905861b57252c12c2faa86605250b49a7ed0420d4fbf6cef51ed2ac1b5c9022cb280fe9974e7267878511bdd0809fd9aad47b9a5454755d80ac21ecae54b5817c09044fb346685c92475d993ee4fed9e14b4a42a73989bcdf561ce47c62992e76a5ca001939b1d94588b831624458091b750e13bd26dcbf81b920842b2343aaed624fc007af38c6279517cb0d9d07608c0c7011489ff25a5e6f29e050c5e500db233f0a3cd6c83a689066574731c2a281904ae84d67d9e09da49f242588d233c92b49e6d927e2c55e17b8646c4ac61bd0f744c401904d03802322cecc1394cc2f8a5dc6fb4f82c6237686bfa00503f4705eba38b54cc2609eac936b54c06f41470db00f3ba6a282320d09624794fdc07f125f5b2143f10f790dad2ba7b24ac6118b6d07409e96b55151812142fa4f805e0e94d5caf96d54c2cb62d454332092bf098d1ce77021bb36868979bb00abc38906fd934ea16072a565cf0256a40dd7cb96d8b1247a22513cf487f46759d5cd4a41f7af7c9f648dd9036e3449b708825c89b6d6c6de846ac1a68420083b417fe8038bc0dcf4eca96c608b3b32cea2b28d046edb9c1f72c92bd37311b04cd40d7e862cd854b49aa087b27a41327596ed50ee95208085e4e032d6532a0d0a78e114b24dda43c3387389007ab9fb31a501db5808a4f1b296969343007a35ad5f4cdaa9670056a97e08e484703890d5246a7b2146751c2deecd25c4aec958a0e4c7fe9069d1fc0a70a9ad8064054156f1260d44bdf168d65e2d1b4090aeed0a03c5de58729f7517a67305d195159767740c063a075c0f989e8265f905cacd4920abf5bb6945290bac6f41278cab1a354b32288ada17e8182f11d54adaa8ccc62c3bbbc51003f07655569b89ab91f621db2052bcd81b25ece68dd293d2e41884002c0284881e9581b79c3069a9a9604cee8ba5032721d34d525abffae715851921cb5546a6c551f522d31b8e3ca01c8d2b886b552417469262217c1ac0470858d8be4158e9b82d35506dea1b1f993011e6815d8c9466192801cffae35e7a10302ac9b8c807c00efa0222cdc0064474583ab6297413313340839a1b4240489a6b0bc56809420560319362a635bbd5d83a77155071083d8bf00194a0b7c0c3c232b4753c2eb1c51ed1a34425678510a4e450b3b18874cf4508ea3b20906da6533501040a1d3e43c4d7bcf801619e5465bdc4b13a343350d0d3bf66d6cbf5c0f53e99d698b94a2c13665f58ae95eb4007012c07fa8391a24a8ce199b6af25d4a5288427506433628598abb69069332c31a58d9c9ac6628b74d10c022e069073f0aea539bcc73ebc75f68d354a40f32dc7c698a56349aae59b01584c1a8f84d467d8e0035d14170933603a24a6628ac205d4aebe04a7d1b20c31af797d230157f1b38116300d2e20b2a48ab84a07dc49874a18cbec0381093cfa486591ca8cbae11042939d9b0215979e31c697b7b048db4d5445575abfdcb38142491dd815830939e553d44fc2fa911a3a9722958889c6fa5a2b90cb0c58a4e5173081a97bdae201869a058eb864d5ef4102e620370255a54869622f363e201dd32bc3846caee15940b7a388812853b2aa640c4ffd073c9e92e72c126a07dbe713c23dd6a0033275da31e550950688b05e6e0e368a24a6b9c34f1282dd71266d73549e5126c35c303cd557707d244b5e2be24eb6145124e39dd5d14dfc74ee8c2c8d288449330043f50aa032390cf0932b252b3f52407cfa3ea1d851a27e108371ca3b44a4551e76d32aa03bc5076f1449db29122fa6748128b10e08188b5f8cb749e646d40578c308885a2f8ba109fd902f84f71c7c445e63cb86b7946b4f5e934c9be283b675bf7cf16d3b3cf90ced6ee29db4ab77529a8666a21d6ef9ed2dd53d8e0744fd916d775bf08575eebdd2dcf792a20cbe9f602322102021c042e7c1248246f074efeebbc18f8e2effa34308102df0f5cfb5add6e320f0bc0b5572f9c04c6fa346e90caff5228ce14c1735f93e10a3f747d37743f1f3a082f441fe457dbfd575606a9db3baf565ebfd2dd7990b2860aee720d8d17a7f43203a7aa99139f8ea95be76c1f12f3d3439eaa48ffb15576ef226c52f9cd6c4f36e7b1ab16ea1e33fc63aee335711a2f04f798f8623614b77e75ce653770e594d72be33614b83f180be195a9e02ea8683fd24037ccdfdc5d9b83df9fa6c5b7fa54389b6d5ff3ef289ce8969e9b8eb8535f377aee3787cdddbdee0528fbafbf6f365f97e1f790ffcefbdaed5eaa19561ad114774e36a75ed12c19763d3addeed608ebd528cbdc5f3f98b0d237dbf9e98c5edd8e949f877aaa986f35578bcf436d9481fbedd0a40abf33766bf5e1959c2ae690b5fe577b1e4a5c8dd7bae0c51b9dea82757bb0a730ff4b435d66713797aff6bc9b1bc45f5a6ec7cf96d137153d7b7df8af9c9f1eb3b5e8bc6168d6f3c55c76c6655cf5a63e24d5e717fa7336a17bca6586159fd58dbbf6597873849d11d7b37d70efcf2f34e2eb2ba9ebddf9872c1e711b40a1036ac9e072e138ceb3ad6c0f494370c5ec8cddd6bd6d2a87ba9edeb96e11e18ff93d8e367670cb9ff3d363ce3676bcf2d3d63e7b8cdfdbd13e86195fe53ff03b2ef3bba0bdefff8edbe14e558a66648e5dfa91b7bbe7d5cd685fa9d8f79563d5d6f3fa4756d26b386ba8325ccdb1b57bfb892eb9f99cd9dde7ae0b1dfd73fad373fe92bae4ce21f82fbd2cbd9d6dffd1f57bf05de9c066b74ecb93ff9e8f1ceaf34771433b177119f9770d06b7d4c59d9b0bf9116611d67bdd5949c7d658cc580954964f8bf5707d398cdbee92c7833d9b9fc6d95a0679d942c5ef8c65b6e3cd1dfdc91a76bbfbbacc50115af32b63c03fd82d78894f0f6e9bcf8a4ea5db6393bb5b9ce7297378ecc5a3fbf55b8aa0dba5928a4ae9dd45ad6dc19fd7eaf9ce351fa13f3df908ac8c6ec9a512927b4cdae1bd5e3be44fd3199b1ba7e6df84769e8e6c9dfbe9171a9a3a73f2d516cafdde2128d10ed4ead348ef74c3bb0f2b0d12f1e017afb033ede2ba8fe6636a7e7e4c7de3b1be3d4c440ef2a7b41e2b9a7b67e909d6d727cf2e17d65cdaacf9c9c7cdebb1ad6e60a644fe99a19cd17bd9eddc2721f92f9828fe3fec2bca81f503af919e3bf7858f5de01a07049cc68a3a6dc779778b3e61cbcd1ea26594b881366bfe7deba42fe757e7414e4c0e7fc7237c86a8745cce73f003b7ef3fa7b7ce937d43ee9212bff03d4b5d3f987fcc193613fc7af7a7c76c5badf9e51bf6314c10f550f00691fd88ef3d5fb76d1e8c4be3b21f176f4172dd734a7c7ace9f531b4f61a06e7f334bed7e58edbe9cd56e7fb33c25ef219fefddfc167d0842aad358fb64a71fee3af94f715cfd01e72bf4ff6460a98282bdd64146748af74f8dec0f6877bb045bf4c073cafd838b30d6af58d21f7930d913fa603256ffd493dd6e972ade5f3f7a4594b5811a5771390b63c6f5648e39d9a7a7bcb3e6de4dae44f3dc519f9ebbc77056b776b8b3b43c266f30c1bb063d176b9cc7e5d23cbedd844f1782ab58b9fffaf0e4d7ba9794e47c4e8ae7cf597816ee39f9f94dff28e2e986966a0b32abf2fc0a7f10e375ffe176393db3fc39837e59ada0ff2bff4275ee3f3e0e1305dcc22e433df5bcfc16f0618e983b28c27cfe0298f10accad9694351cb7510cedb1ee8ec6f8e288c56542cfaf7a78c6f2c7376b1bc4e93749542dba81b997f4f59f9c6e8662e7e6cf9a91f1e74f7778a24d9997d6d4c19bfbe8e2b89fdd54fe29fb8fbffe877d4e7f7ace6a269f22a4b4a4e1dd7b8615af0373eac5d3e3d31426392b3e4ffaa999bece5aeee0edb347f40b922511ebcb67fb23cbf5a0fc56a84748e8b3b96c17e07a9ee4eadbfda960ae5b7a4e00af47dbceb3bbba7b4eab4fcfe9fd4d2cfd0fb307f3d3f56b760033bcdd6d95fb6bba49cd3f20ce1f2f6b4d4bbda670b481bf89bbad667458b847cbd0f5f5ca6931b03f45dacb4f67dad0ba32aa7a780862e75fced8e55ff9a44f9c70e6cab8b3d1da0abc6c27fb3fd87fcf448d397d2e3c3dd64df0f9829372867e19c67db84cd249743efde939fd1da87b83a716fdfee7ebc00f15d72bef8fb1869d0ee000b07be5eeecaa3708e15dabcab17db31d97eb398455ab7fb9d49ecfec5e90959c1f690b4efab316fc83b832ca1361ee15a39939a9ffebc3c67d90bdeae8ded1de99149e63d9fd83b882897777e94f5eac44ee7f9865c9f132bbb33919fb23f9f7a30526ed569d5ceff79553e6f1ec3eef478b1e573d651ef3623237d8a4def8eef6c9e1e5a3afe347e715e59a8feec8e233db6403d532151931d88038a5ec0f948104e8ac89c7bf66a3dec741e9725006cec98573a2a9f471b7de12c4989b3c2333f39b50b87f74cefed1d7d3a383a31eda678767e8c16ba9ea3e67347dd23d29e4e5d35168e4bfd655deaa0ed5bd4247f2b359f9cbdf68cffbe6ef4f7e2ac705bb0e9e19137d3202fb07bbb9ff616fe5f9a03b1e523c64e1bf3ae7d77acee75b73a198f6f4d6afb61cbff5df369abd4b1caa9d6ed622949f4fdfdd20a3bf37fd07e0346cbf37ae6b931225f499efcdbe177677711a28c6a75be9e5c5f4c2f02e4eb3c5741636f7f670f40fe2f2291ea44a1b64f14f676e64fb92d23d7639c26fac9bb7ecb66e7fc009e89ebeb462981b93c23fe7d262a0bbab694a3eedae778f799737f79fabd917f098a3c445cff3d97b7c6e59937b0ed7dbefcfb7e546192c1f3b3ddbdb662369fb386fffbc543472deffe87db0403f4f9b333fa5e46e5551b8a307fde5ce25f3fc19c84b62c26575c15366e8ffde40c95c0b466e7ca988cf013f50a15eda5760a7fde7d3f754cce8a62f275fa77f14511aee198c660cfb94b30057f08fa1c378f498e510fbc7b0cd6b1ff32ecdfdada9ceed0b7427af6bb50b107ee47b30d485ff2c717db02f9370c39b9342496e69fca3bfa5b147945ac7877c5a0dd656af1efdc96be10d34bf207a669b67ef82143f22618e8bc0d90316b39bfddb0a00bf01a393329e9cb3eb5a477e7b85ff696fe3b900c03235a727c32e8ff91e4336f8c5a76dd9fc389b6dd9afdf361c5f00638621d6518471eee237f918bf39157f99fbd5ef283f534c58eab37e6685ac7f9aeafa98b3c0b1a8e37954d21fd275d93e986b24fd992793813d9c4efd8d27af744df36474f89a2bbadbacbf9be8c6e1e9e13e6d8afe9dde41fd7f2ce0207817fed3f52c9bf378a5b3004f9d9b9e0ba73afafd829ab673f11765f97a3b33d771794e3fd2389f7c0669763f377896e26bfe8edd6277e30f2bf527d6853b215a7a4bccdedd671377f98fceccfbc36e6a5c94b1389be728c253dd63b4ef9179439b8cf10382a90bd3b3bbe977698a64f6ce2e95f523d51356e4d4bba5bcb5fc5e2f7028ee39a4928ab709eafb9a40ff2deab0605d6ec55b441b009d7ba89b45589225fc367bbc620db73db0e8373d170c7f7f95bc7e5066531b9bfe928ae0774d05ff98dcd7c71c17bc334f797c5fff142e36f9ea394fc1e5f91cba93fd490ed5e475be323d97b8d3ebe972215b9d019500f55e4b59aacdbc7e0e6343be5a56f307acd4a30725f7a02eb543ef7d043ea5cb6bf5d5a978399967cea6792bb4a7715ef92b75aa30fb87e0df66275eeee33f76621f6fed9cdd397dde8ce33e5212973d4dac79af37d65484d70f923ae2f3a08c70f694a7b48868f84dd7fa9c7784af4f7911e6c125ae0f3e5aade69f929fa6778c4e455f9beb8ba7480b567dcce397fe31db2472f7cc83bff91bffa463feea07f0bff4e677726ec7cb5f96e7df5105ea8eaae7417d7f5419e782bd1d1d8f2fa9fe48ae30553ae7ae27d9567ce782d501d564a4e55996bad5681898a55760964e3c598a45ebffcecb7f27ae679bc7fcffa9d6f315e50fa58c7ceef3018f5917295b5ce47fd3c08fd7e2fe4401b65588e6e71f6734a4c96630ff2df57bf1bf4b91ad98757d61698c717b0d739d6d3d752dd57ce347f0d130ad4d2e94b2d721a8a7429c5d9c6a379fa93c7fa64b7af7ba7b94e6ca2348730b8c1deca99bf1b8a22fd8e79a717b00bbf454fefb1af6a7bbd37e748a0efe865f316af3d7647fd9d1ed912fccfcfc707e570725e745caeb2523155c9c84403d2356d24eacf864c378381cf5bdd0df90db732496d7fa8647622998f5172caa7f16a3be00fa0bc24cfa981fa0bf5b4a335cf472fb4f509a95d3eed31fe5c6b0f3e4fe7cf3f5467bb79821f8647c33a03f662425033291befbcd297f5e1c558b6504a84f8e013696cf90d36eb8509d200c0419d095fcb5e371971867c4123b6ab39e71aecb2faed42df35cbedfd82d0bf5ae8ec6e75bceded80f180ef4c3aa1c827560b88abbae894f6d8be6d30f2b459484ac527923c39c4cdd26591acfc5e75de2a486b1ed4775423ec5ca490557724f06103157a2c14a45c7f1e7643ffba9cbee08d84259dcc76dbf41542a5b4a4b161c4f84764aa15b3c82d5e46721329155aa9d4a35fb5abc169fa5b85fb2fe262d8385dd0de0ca6ad5653542dc2d61792aab74b288ae4c5558de6caf20a5d7b67ce7ebf272abe2310be90a9c55e9eaf1f1920a6d2dd37522e62a33f1bd7df06eb93dd5593a111baeba4d5e3fdb7e2593ab8a73f86ac1156dcac7eb38dc2457fd1d3672652d3063dfecdaad635feb9b58a99dfe784c6706b2af75197733e4ce17936c9e0f6f266e49135d61d3bdfe9e176f75acee75b86b371a43a4d97e6e339aab466a87637b243ada4e6c53cec6465edcd7f3a01230392f0d5f27db0872e7b2b9bf2eff7e7bc3826ffa797cfa75f82134a86c5491b9a73cd5cbbde3e525b5498db94dc3cb8f28fd2575757af273dd5a17d4bba73d7de94fd6454db65e121c3cbca0ab56e76e6257678a9be9cf3dd377d77e7335403ac279e6427b391ae9c9490d28e27dab159477b38caef64b9736472257979dad62d45d14bf18d5bddad216c44ef2f1b9676d858b7d5b3bc7bd4de34b3218adf9fc4f4e1775e5d3378b1218d99218652c6a933abf3647003e09655b7b44228e07339c3c0f80ac07334c3e6bff9ae0c11ba1e04e13c126afc128f75ae1a932c1815472970befc403a9f134567d8da55929b410c50a5e4752e8f0273fa36a81f5c063907ec1f8151a4f2673b5bf9623282f4dfc5c281bd6f9347253d1057f9ab874a639319c1efb4a94826ed9eab43a3749da5d1fdc5ed688893ec24cc3f2862a48ca3a879bc3719fb8971fcafe5b15b2f400d6ef4780217536e6e3b6f3f253f299e5c18bed2c9be6b2fda99cdaf8ec28d21e532936ebf3478dc0bdcc7ce8b07d3e3ca12d1509aa1f6e6f57765f116199e63b0bdd8474fbe12cd3737eba1d6ce7eb1497554687fc60b4eae778f98fbd1d8cdb94ced14ebf40f093ec7eb8f842b99a7d6216e570b8ea6699fbe1db49cf0c956303ffe335e0e65897e3e6298a66b0e4d248cfc6f2797463fd6a3b27da1038e48c1e8ce5d3a567f34c0c36de7f33fbf0160ed4b9f758a4ddb431cefd706ab5f2a7f68cee36af2b9fc3e3d42b5d57d3c2ae7e59e2b5dc732a481d65934140925f99bd1b41c880916ccb5ed9238d57f29263fd1a3b49eaee9b4c55747780564cceb81fc9c9d1e768ddb9582f0509c7a402b8d77ce7660047c7267343d2314d9e8ad68c719f771f847a73cf55cfddbfe376aad41473ca757f77c5ad200db7149ab79afa8abb0d4051addd1da7ff9e5c2cee62eedd9e1e0f0c0f6ee599bdbeeee140921b1f1b17dbc9f9d0bf1fb17ef38a046c4f13908cac9efcb7df9ce22c20e4a53bba1787f9bfc61e6af9669ef6775580c64f3a9b1af8de1e69a933f03018cd603bc32ab9a04a8b4e286e2d77b4aa87aebf0ee5868fe1646c8d0f3623a5209af1a27fb96da480cc3f0322fb69fa9a686e9ed40b7622227c757e0e31f864c5c58a78fe074cc78a5501ff3e19114e87f77c26e458a9a31e09259f82998bff645b73a5079ffe7836c5e1de8bf418b5fe97c176be08dfa9530edc9e4f472dbb543fde8e66b82decdc5d6d0dd2af27c30d97b8cb969f196ebffddbd3ce3af9dcd9658e72b3eaf6d9faa3b5f406d2c168d9e5477167633bdacefca3a5b4b97e237ede253e838cba459f8cc588830aa67a341af7439fc3e575217747806d9b1932c847c37118c9d4182f87c371eb7d151cf16cb8927cd2dc38dc26d97946e45b1f0c57bc543f5d4bea7a3fe5f2d946e16d686a409fae65c82eaf882cef93f1ca9252b62ee676675268c3089eee152fc68ef28106e374c62998ce368bcffd2054cc8c56b75b65b8fc2afe9a9f368a93e1705b3f40002e97fa42eff579308eaba8545f462bbb1793c3696779325a75521212378495ed09bf5cd6d7c39639188e61a9e1f6b21d2eed36892bd3c08cbe83977352e296f7cf27aef8dc907cb64baa9312a4ae1f9cb7e04aa55220e8e4e562f0692665d9965b1c0cb9c838df873ba5653f4dd1149f8c2fae6da3bf62aac081d1965c52c2e5475b695bf378572bc6dbcb18f53bb3864a7885e514d413aec0e5d8ffec4f9f082e747fc6f9a660db03bb9eb01ffcc26cc7737cf8e5dbed0903d98a95556cb7986de1a4befcf78414c4f89558f96eb4f1d568317e355a65e2da3d21ba86b365940c830dfa3c0517e9a94e8ef6e4a16490f42f39749909c21f81139af2edf76b6e552836372c8362ebda52112007545ed5435ff9a51c25924c4485335f4e08b9293a4166f59ff08dbbd56f5c2ee844ae3abdc8297047e35dd10ab2528bd6eb0f2fc51efa201a48e321764011e4fa844b31c42bef61e8294fc9b066c44bc8e91f79069cfcac5b2a0b00f4c92174525d8cd50f604871429c07757d0ee2730a9efe8cb3263f8bd17d60d882f54c8c4baaeac4f3752636bc58177cf7a30be3c4b8cbc081587062cc693c918b5e8e8c8013b9e4dfae9cce333fad8a3d3e7b0a654febb258b9379c765fd7830b89be39e8d1c7a98a9ee65570f48d60e466da9b65d8aaea6cdd371e2c7db6e0c816abfef3857000cd3e74ad65ac752fb8074b894d3925b99a7f3a814bc9c7369f822cc037939d0195b66081470b4a68e2fc7e4cca7333bd36e391dd727f3c5a98fb629412bf903f63f808e57389c82917847a8d7dbdc34ebb5d683e7ffb38e154d4c18a71066939e0b5662b267538d3c171a7bff4f8c8d13cb964f99c28acf98ff647742f2876c4c1809d717688453f5eda2d0cada76fd07434dcc8568edfd62c68d87e765e51d3e16b1d718d4a1ad32c4b1d02fe1d75d70907f16cb21ca63b2836d641509a995b539208bbe135ffc7c951a4b7985b10d988ca2eb015417c9c307951ce9e2c07a2c977a558279bc36eb6dcdf69eae0ebc3669d92144a9892140b3c9264ba831db3bfd536fa92bdc98d6857d6c8d59d20439646922be51f48b6eed202d9ee3282fb18b3af6f4629b48dcddad76bd3cc5a4c392eea13fd0e282fdf915663c2a161fd1e636cbe074788d2edcfc1077f3c9d868f5714cc65ec72a43c7d3a58d5cb7125fae4d7e665209d423065e1edd80caebea5ff733fcbb49bec4ad33206587582e95a04e3463055a7e8f23a60db9ee4e404d9b249c6d18e5bbdf350de5f7c480aa41457c38c4cebcf0004818ad504f3c175fd084144f2616fcf35ba0464be3d0c36e9d7d45cc8ee6414f42dfe682b06f77a5480e6e81bf25174bd01cc785b72115198df2fc8abefc74da3a6739197d7dbb3921efee1170326f715b83d6efa4cc41ddd8af5f524edf3ab87c43d64bceec7731116bfc7aeaf5e4fcad6dd937a4ce6be14d57c996e4544d3874f012e374556110762edb2626208b71ded717ebe18fd2cbdd8de7ea69c952937baffe2650748c7cb2d8b58b4475bc52d0c7b2407334dd9ae5d5ed7e57925f96f9bc328040e3859185f9b84f290edeb6dcd67b20ba6605f26fa4690b648f52c17bb657cdf2f778ae2e544d7d92e8b6378a4efea946f4f04f1b5ee8bbd8307f767f62ba9fa9514c3a5f7c5f2eb9cc84f62ad7d2366ddbf3b62f9ab2521cb6d57037b2b457959b7a5fa5763b1e6bb2f469bebbe18110c6f8bb11b7c5f2c7f37c9b120114752f92ba9f695140718ee8ba5efc428bdeab618a3bfbe97ce983bfbf92a66fd4b7e8049adefa857f58121d11d57632461767cbae008d935e331927550a586ee8be4af1b37e296af78b9c2ac441172825bda02e5e6fa04bda3a9d2677745f0cd82e6dd854a94f8295517b12d16490ecca42c8e456e6b82d12e3385efd322b85d4fc2c4d7daf3d664d8d15c88a2956e43d09454ffb126d54ba57e5b8ac8f7b7a5b89acb7d317239ee8b515ac96d31aa45f58558babe114b7c0c6e0ac56fa42887fbb6d4b8be91a228ca17626417df17239beb3ea441cece7db1e43e9aa06a9fb336ecbf27a1e77f128f77970447bfee8eb50aedc62210c90e96bddc360ce947cb67a3d97f8c279e4cb1073bc527b9b04212bf379cfb09a1ba0759fc8f8d32c3054f62fb98ec57a33dbfd741f23fa19a738e4f72fbf0ef57c3f917bb0433fb44804dcb3a2e72610d39fcde70f65f7ff2f75f8a8c6ccd944568ad43f73b03d97fdab0ffd3f23d0cc839bb55ece4289f0e3586b5bb72f652be47cd6eac55ea68bb5f8742f1e14ce6b4950b474ae374b4eefaed7186dfcd957f12da8d452045f619c3d63a7db116cf83c5c31723f6ce1caca1d4ef8794130ae4d8397ab97dda8f35aeb9bef441bdd352ad98f4e13317e6e5c136a312bb15aca7e3b99fafa39dece26321befb4c6c7b99e296e94d1fd808f6ec3cde672c981db62a28b9ac55befc703bd2bc9b38b7ccbf79437c23c44dc4eea9d26f64b841dd3d3df58d8ce493e5bf2fd465c5ffbc08d930965e7d9dfaea5444dbd7fa73aa668728b8497ef362a76f46577f35eb41cca38f091e64764dd25df47267af75c1dfb9f15a5fc870d6d2df12228d34419cfec54210afa0ddd3b5a732b5d9e9d57c383d2266e4a549e29120554e9f581171888ce03641e9a1c6cd807c251c54777db8afd9224c27526e9d28acd5efd9d5c742b1da583dafff014db88eb50eb7a99f7164e42d32dbf35f5d039b27b36b9b5116afe604af55b3ed4156475f9014a0eb230183348e2f00e8c6db88f5cb89d5e5ee6ffb12c5c90af6651fe7adb157ab1b70d508e5c51e91051d56901bfadb11b7f06c896ea67e8b6d2bdca76127d3979393b774dd214943f2abd5c4f1bd639e8bbb341759b7464bdd16cea37af55370b542f6435258cb0eb99a15db317b5c3ed5cb7f2fc346538cb348a77dfabcd79e633e84449c1c5c6240b6e98c509391ad2d1c610b13ddaa95dd705b1e137de8fb2be27e77a8939c4cbe2fc389347f4b884a4d996fcc8d620e74bafd27f9ef07a3e5624723e2444c074534a2e5c684f578ef5b43142b17d797dbb786e84e2e9f5e7404684d416e81705043dbad1419bbfd1de7e315bafb8d10d75738a83b4bd55fe7faf37bcdf5d8d75aa1ce7cc1ed4a2b9876f7cee3d84fc838fb65dcde1d0f03774a3154900ed2c92fd8e19bc3b3adb746f9633d6dcf011b20af24b9ad564fdb0f18e38e9d4cf50eba2799bbf75c6c95e8ee6423b96ab02d1d9a58c67dba058b167b02f7675a2d9a726c36ceb59929dd045630f7f79ac2484ae142e8b3f508968d60cf4ef0786db8c2cb7db9b8f2345ffe7b77011d1f5fa7aac9ba3810e2a69afa37626a1ee4cc5192f214943e3ef55eb4ea49eae4ddbaecd24f6f16ac1db9089d45810e47723f61dbe424dad7ecfc9ee4ce6240c7c3ad3fec27157d93ab88feb4a7b666179d7d23f9b485f7cce52b2cd6ffd179a1d4802fc4d035edfbd379b8966ed3c7fc5f09696f893f2f136717b84b3ef691deb0ff4a3c1bab763b56fc74137a40680ace86129b0bedb512b8be58c474f866bf2f94bf98deecd5f3b765aeff4a88bfd24971a02a06d866e32e22263da93b5b25ae26c75a5d4b25b91acd76219f14fd02214cc9271d50ea0e4288d94b2e877aafb9656e9b4fe13a8dfb32bfc5492e6a716fe5b20530055795b09fe9900fbe393cdbbc74e20f95dbf4dfaf769bfd97b420fedf95e1cbf640886da056b66f1556ccd698c31e9059e719b6997379a96d757fed4f5fef854eb929c4adc96e3adba742d405cd971aa153a239e84f122f308452cf066b6ed9e9b81d70ae2973dba69e773fda5363a58de5d2cf2649fba9f882345406e463f213e138ab4a3fa9c7607d7e6e0c7e2266ff752de778c381f94246faebdd144a874294945d97cd68da2bec36e343df1a396ae86e57706b98a5ec0419c33182dbd034613fa6aaefb5cc7437229550cd75f709f60e49babc925c35c99b2aed54ead3e04d5c926d9ef1b67c08937b7d394979cd83d2043c5b93eedf0f05090b6b26c0e5e57659e28484da01572c74ff8acb80c7af482501cccdff74216c4b21e0cb9945ddc73966ec8192a1c7e2cc1a7dd6767b473b4ff0afc6a2cfb66b9aa3930beb267fd3c1a23bc9a7afb11ec8054f73bd24dd4eddcdb5472fb75e63e939a28397ec4e7251007157eb41befe24712c2a672d9ce9cf9443785ffe7b4e166b5ec52d1af508a43955c3d446ded4ccbebcd8b6d69c7bd22a757451b46f6e97af842a4a73fe79198a629bf58ba2663eb13128fe696a47f53339fb4f4ede4d78e654881bd8f95c262b47f7e7cb9df170cbca5aea7adc64deae52db693ecee61c4dcc8883ec7537dafa72dbafcd653070c4968fbdad754dfdebd650c5819cfb39495d9f2992bdd9c1e4363e282f46d57a8de0b5ecc86d888bfa90b6b56cf53ca26ba750d76ea787edcedcfa73118694f97af6159735991747f772d49e615ec6f1496ca68186d1b7c36defd496ec82eefebd773c0f3fbafd4777fe750f9dfb4686ea655df730b36f6468275e07309bb0645ebfd1beb04eeb4e709de25e50420e7dfbb5de54e4b9ae6ff60655582e9ea475409b099e0053e2072394a598c064f29febdb3bcad4dfac8be0a2ef76e793d7f38de0ceb0a312706d5508fb4bc01cd1e1cf36f0d60dbf7e4e35572728febf29b7b2b37a292df3fd57ffa0144ecf83fb092de57f214497e2751372fc4286f81e07320f6fa19ab5bbe4147de20551f2b811ec8bdc9ea7d3ad1cef8bf6d9200cc18ab1df76301c258e4f393a7b4782dfaca5fb09595a07d5947f5b8896f0a042f137328f0356adb85dbb2df7a8672b95974fbc651e111833e5c4e86f9fc947441b35826dd91d6fba59f8bbed69fddf0549403892dfe57575b67e7df581f8558b846d6f4222bc4cc9552d6c0b4e8665c8753f47bbeb3dfd288bcd79cd3fb453dd627409cae4e5ceb9364b338a938a4f5a6577df10e66525c3aa20f61844f392c7af48f589eaf3d95afebdb55f89da73f3ecf2bbdd158a87279ef6f17c2b1aec202eb10e77ddcc42d1b2fa1fd018d79d894ccf934235c579604f6b91769f98bb3ef7b2fd5e6fcafd051f9a5e3fda9b385e16039b7fd7e51c7c820b2939dcc811eeb75f1c75dfa84af73583b6d18fb76679ce23a72745e6b94e746b54528b9729589711f78a930edc6e831c1db8d37de67e12af2f84b45dc707a72cbb1dbd8aad3bf3b7c6a2b8c91c8b6c8064a9d5db824d9d3b53c83408323912749fa51fcef22a7634be1ed3492a6176d364c673fa9c3166ff7169a8cffef743a39852b3a9fba1b6edbabe19cbfd8457f1a629fa8d90d4acba4971fd46a868a6d89f97697d358bd2cda4bef6c5ecbe12e20c897b50d63732e202fd07420c911eb4937dfccd52b8d95e08cf1230fa9295a3fb677c067259c1cc986359e4b62e686e568eba1059b96d4245e2c401fe0ddf7607c3b562c538ef661c44e31f0f9c72639de5bea85bb0724485b6825bbe01391275adc1300e8a60d07a4ec1bcbee26ec4874163abc786c399b6e6e45a3c942303c0083eade9d62fa50deafb1d1f7d0c72418d605c37cdb64e5e1e4e302f6b9376bbeda149aae9958cea6d82d66db3bc8615a3dafd466c0b1050ae6ef5ad619ce076773ff64b5de81be9a4e2ca63ed8d605aa6ba2f3c189c1cdb3e66c09d727aac7435d0773f7cc31e9c1cb5e83a5bd26c056907b989ee0f7e7382f15a0477332563ce08a665d36cc376d4a9d908965570a7b9b36020d8dc8bd1b5355f93155b6db5b84738ab95abd722b755170f9929c75f307c566b640b4eb9b1dabddbad8d3ad0f2abb0aecbee03e668f94e72960e26faf0878d5c3995a3abc108d6d56adec9b560e5b854bc91db966ea74bcc46765643985c047dae43f786830cb8dde4d674541795ba0374b3a68bebf80630f348c3eaa87e021a664ba1c5abd8bea2549e30f7e862e2ed09c3d29bda74155fecddbda8b681bdf4adcfc62420dfe214abab41b0c92b49aa4b3c1b82aeaec39bd7e48a98cec0347ba0ee3a6ed00e7344c297ff3ec6b00e4c67925e8ed4cd3a01ccd2b899ac12fb5f1492a4e0b415dcd716b8fcb15d97710fba8dcb1ddcd9f7f67d118487da6db72160b2774ce90b3e79264fe2a81ce62a75f20d24be7797607028447198fbcb41b6d91762b97e25d6177ae891d4436fdd9772ab382b11bd5fc5874a362129facce924b3eee9cd9866fafaccbcfcd28bccd1e6e86732e475cfd9ad6287e5550f07733f69f14ce8e1d0b7b4153b2c527b3a9a3f60604c7d528c4d2cfbcd96da2bc6873dd36e67d5d27d725fec9b777332f93f13ba9497f29785a4bccb17c922274244db6bc96f0ca334de563d33726951366f78159cc1841559c6dbb3282374c1e6abbd69f046ed178ce8b12447c6eaf6fb85be3d37a53a51ae7f934e7229c27bc19593a0920fb3b2dd4e857cd82aebf788f728f14f42dbcd465ac194f38d5eeeacccc42a75e38c9f44b1fdfe5ce5cea6783ada43e7b725c3c37cea1d64e31ea441d00f6b4fbe4531db80bad87eb40d1efbb8f9d2c1466eef413f9cbce651e874d275385f568e4ffd89a0fdc7dcb0038e7b6507fdb5d49965713a96db1f13eafe14e0b8ec0c9fe4ce4c8be3e1ecbfa641d00f6b18dc2272ecf460634586d55f3ef932bbd429abc77cee4bd5cb4aad2f76f2914f178370a23914effa83def36e435d870b9f9b1d8b6ffc7437e9f8ea67a33d1e6a12fca8efa9196c5b7ef8b1726d29ee79f7387380e76092cf9bfee49b8561a7189fd6f128d1e502c4f3e9068c6eb06bd1a7fbaa6ce4057dd149277f23f6cdabb99f4cd8f32f0b35b53b3fecdf4b5854f2c2113d1a117258440ce93e3a490e1e9ce46f86e687bc9621377203fb42c62bcb9159831c2ad8388ef6fd973e5ecb6a479af6a92c585a80e3375aee20f7245e7630066fd3bb269470178695131572305e72cbc885614ee4b25b14211f1dc895ece4985b7520478a64ca8dc36fc7489bc1394fc77b289195097920e7be0cf1cdde7646fd5342739bdc5525f7e8a7a732445d6c4bede86cab571da503af622753fc4a88656ea2bd5fc864b85c7f4126b296911f91e5913d01f7a5967af8a8468e0ff236c7eab5c1b20e76f49d4e85a8109a7db3e167b82555d2553605bb3451b897d09b852b72fb34de14ca52a7fd2ea9eda60c3b98778528ae516e9ec3ef843a9a82fe6d21ba416e0a31a3f76f09519d8eb95ff3e986a53f9a727c85dfdde8fcbbad95f11a8bbf2721d1ba3b63448e55ff5d91c782e5bf2cf1f8989f251e739f89ec4fba78cbf789d5d9d0eb8db16f131f34acc8bf5b4de27db9e54b784d3219deacf52037210ba4693e1797be4b4f23ba9cfbcbcb65bfc9b7594b213d8f17dddd115ebe2051f42623c87ff16de219e93b23e63ffbbe5c76b5df7df7efad2f73b423997ee2b933e924138f5880467059fd6bb7fa44aedbcb858ddc28dfac47f0c767c4b793dc5832f5641d83ff60ec8cdcd4b89577ed278d700da712c2f34b854f23913df27a1d76eaea0b914eff3ebd0e9964ebebf48f1180c7fe9b29a4ac17c767d0f52132c5b8ce8a192dc58d1ce56c1b41d636e33069db08f286ef9f71434adb9e82dd8f77d641902a1a7ebe60892036875a8fc96e4d1ec7ccf40220b427edd3ede637c84e8e428c566efb099a952360c9c96d05dbe504435f3efa3e733e59c1cb7f8237477ae60be7e5bb6da9a88f7db0a4195bb16d2ba06ac58ef5e243012fa5d0e980df02a50f7717b15cdd1c897ef491955ddd8a300e954fea675e6e4d0805cf07659bc83f335f2e1fca3d6c9c6eca8a66bf96db0cfad69d1c596427df801cb6eeba07d975596bcd99058d568edfef683db395abd732de3ee9c72d0c25b99e8cf7f8d0865bcbdf7d5ffe64ae677172fdf4bb53dacf14accb065d4bf099f50c6e4082e98e361a2da86985b27c897d97315a51433b3e3d12b4a4335056fbe180b4a413f8e737bc5952560ec4172edb81d5459f6eb656ecc08f3e5c92fce9961a79f9c4b1a64fe757d2d2f06906fa1646fc71c798724efc7e07033e2c2323c77edc49ad18b27c97ca6247a7a1b6a5229b1d2fed8b16bb426e04441d2d68496e9ed7a275d3360343ca48f16f4a3c1ccfed88e5eb9deccc539987d5603a01f5d30d469933b6f7d0e94252ea4c5fc22f7757a44b8ae01d23ff4c841c6e33bd2a28d84792c443fdf6a577a4b925f3eeb51eb68ee91870ad076e2346ddac8d58f1626f121d9b138ccb77db77276e9715dcfd7b5fbfbf1f7d03c2c94de786b67c0482705e7f851cad6481b5644c80f2526e70516dfecd58c7dba646062bd6e1a17cbec8f3d3702772eead2f51d67774c2a10c19c26371754fd6833fdc146493f64090f6cbb2922772f61f1d9d7c17093e93a143337d6336490fe6f7d0754b5f8fdbef95a59df85dc8f69e48931ea67f57846efb0319da7266e16807da23b2853f8828bbc01f467027f7744cca67209e889373acbc7cdc6d0d34e63bcdfceee56b519370dda0066a4dc511a097e57f933d78d969eefebd55dc872bb23cafdc0c34dc97e8b745ea7d11b2bacbbde3f4954cbe6ecb6889ea4f0accc7049655c8d72ec842e6c8945b3702b7657829d982dbad7c176c56ded7b86a5eb0e7f7d7e34ccc6dc2c9975fd57e284845a78c2427c359c9156e353900d58992a9526c0b8f6296d671c0a2e4f56cd6675f942b71c98fef8ff3e9a6713fe95233ee2fc890d1a67f5298948692662ff6b26cc562a5c065db66c5c28a7563f14d3e5340f771eae1c4ea65c5b6c8d2433d9b0e16bd5ba96dc10da2b99a8619cb1cafe3c2f8f57390e61b197a0ff35a91b7dbe7350c4eecca4762a173508d7fd3fb91d063d3994e1e0fa7267dfe5ce14a4e8cfacd1fcc301727465ece1c6d0b73f666c53845fe6019c957996214b93e78374920ba703c0e5691dc005fda664a6de1cd80062f3a543959c36485e8349bb1b6d066af4e6cc4b3ad486b684ae858a97d09dac712cee484b3a1ecbf2111c41b67f25084be944e6d1c6ad098ac14f74c3ef854b5aeeb702045d1e0e1b8d9275254a7dd11b30fa44859eb4178e8d903a11ead10190f278b118b132b67abc1451c4c17a6c3e508c189a5b35723b3628af5b357b3ffaa301b3e5de48fe90dbb0da766cafba61bdd5942a9b8eb6edb91e84a4e6c356ac86e9cb154639af66467b9fbf71c8a8c5f89f9353915fb62f19d483f12614c6f56c0894eea28dd2ade9edbc3443e10a1962333d7833ee7dcb53b9d46cd0cb652e7394c37df894b281f2cf8c35308b6faf599467bda0e9fbd442270d8a10e95857b92d617fee05d5efe6391c229bbae32462f5d8b583c11e39da11f2133c501425b32c7e5a49cd03e933d39a1c7d69d525b0e8edf19725bdeda4df765a8c3d0750f8dfb4606abf8774532acf1bf2c43b6fa7f22f45094e4b2fe651942b4a9a6f95f17a29ed17f4b88ac4c73f408823938e66eb02cf5543eaaafe1c66247f8a6aaa4be392783f10accc1a8a8e3bdc1b831c5c16054e2ced48b675d77620a3b297f496d5d4c5e6f956bee836de38ad4d37a4a25a799b7187ab89c54cd47522539298a5ad7cf6fa6aa457ed5dc68e95d51ca60cbd9f99b6a1bc3a01eada678befb685b9e4175b4f6c568dc163f195e8ceb34bfe9071731a538698c5c3cf74d213583785aa97a22c5ee81156b27621c48b762e3482c39d6f793badaf7c5e7f19a5b7f43cedad1eeb9faeb5467211dad65cccd892d06ff8eaddfd0615a9e188ebe3675c67562c5edffed27e88b583a1a0d7d4021d54fa4b4f998fccaabf0dd140331048c9857c65bd45f5b6c422c9d7cb49ea4d68cb9320e0e00b504ba7e0bf1ef58923b3e649604c6bf2c43306b38e1e746b9aaa14e4fbb915042cce5bb73b6cf7b8334eae5293dfbdb73919b116a8a829cc851e06b6a1072be0ee4a230c5f937c9096dfb39d7e1a4c80b38188b9555da7d6eda629b70607792f4dd0e065cd49c2677c8ebed237ad9c911697d8aedea32843cfc09cd4e6cdf1cbb3ab15adcfedaeac726eb00cd1f8fde6d642f36fc6ebe76ef36fa576a84decb1a3ff9b28bb2350693c09a90ea56eaf970bfb0a84ff582fd472668b849e2fd42861242c36737464bc1e21b57b7a336cb40b1f350b72bc13c609dbf3d67d4246dee8e87e41c6fcd379f7baab9699eee8d6f5644ac5b1d8be0c0dd25e801732bd5acd41660622fc144609d1ed87276c5ec9b6a27b8cfb60f3c7471d8452cb9d55f9bf22fd0d48c71ba05d9471ea21f2c5bb1ad4f22b0a0cb923818cd7dc79e258beaa35f5ddd588f7b787cd40144d8b4cb11dc8bed96be8aa17ee9927ede558c16d7d7f3db6ec518fd50f9647ed4d5c24ab593b1b821b891727b236d93aa4b706264691e7ce5040c63f3a1192cd41df734f59bfbc329e12ecee727f571f939ae724caefb34c5d3d1d61fde4c0ff9428434cf4946490ffe5bf90b366d537318d2be5d99ef9b398a1ad5b1a82976b8a96caa5846b7721fce6478bbbbbbd24c6fcb84e795f731df93d7127cccc7986faf0729ba7413b1fe4628b2d04d5bea5448603f933194b9d30e1663cb6471c3d1da1f50da05e2ed6e8b84634d3ae5423913a40bccd018b921fc7cbd87d993ade4b4c5d0cfe9f5660ef1daf958e4d419c9222e0c4cf565590ce8559c2035ea31820fc325bc12cc45fe58de91676b02fe2fa5c8923562725fcc796ebbeab7e6052b83024a15d8bac8393941f2ce9d64decc9555c4edf03dab88fb6401d610f7e5f830dd9613fbf8b7d809c747d0fd843e403e4804a0959ca7ec6934ee7bfdea3808d87ffbe508ec0fef653ef1e58f5f8fd452dc0beee0660a2dfce62449911c4cd2fd842285f9e67dfc95107de903a1c87ddec2f6bd28eef2728b24b4fbd9cc336fc326e4c4de5f7fc6727ff3bb1d2f0c914dda5e701bcbe08209bf374bca0cb8bd51bad069ffb610995ee5b303c02546e2f6ad38ecf3728b94bc6cae659a042a9497ebcf7cb3dbeb9f0113dd13ebe52b318e78df97fbe633d87f645485831c1e3117c26e303a0f2f198294bcf2c5ab5157b0df5c92e3d7733f61a1033b3854b72b9f46a390f8eb4591ebe9e69ecc5f897df772795178abe0f6366d7f6092fd6c92ee27b425ef66d57c23c48c91fa797adca8336c5f2b5fbbed41994e46729d66cd8668f75491ef3797fff8fdec3ff23bda8195461d0df3d80ef62eee957efbdd4ea749b1c33009d3abdcfebaafbf3dc7c73d793247fb8f56b11d245f93fd96c66e2ceff739fb4e4807dfbfd7e91cdd5ea433732094e1cbbc1e6bff5eb97ef5627d7c25c65d44bf906be52b398a4b7f2157248cf7fdd73efe72d455c36a845570cbf7c9fdf767d9919bf60962bb04f57b2db7d307237c354542fd7ef3d5083d3c783542b652df896dddb6d67e7b8a64d09cac3e3993738eabdc561b93d1727f8e4daee09b67e6fa4a6ca4afc41887fe428e0275f7e5283de80b39fb3b729a0fbe3783a66d2b97761a61088875f3c3c5afc446f94a8cf6f1377204dfdd97e3daca5f8c1724f2285f466add8abfe370e56ebe1d1b40269696e11d4ee6ea6bc998bd24fd77a9beedd76b51c6195dd2a6958cdbd916ff923cd9e43a0bbf16ac7e44f68767a7745f33cd0976277879b9ba9d69f37294376166ea9a393ac1ee0539aa7424494c16f341480bdb978c16e9779be05a76010f5a7cbb9ccd068ae1d53e30ad76c2760b8952f445fe9cec7e5882b8fd7eb77ba86f97898a96da4f2321a9cf82ddbf295b3e76c7bf99eec82ff6c3eb0e96fe94114c6ece4af482a16dc78c4f2714feace1c36cce5916f631b482a7d4ef95c2185eb0b57da3719e58959d10bde0daf22dedf5502ccef7934042766dd1f36b511ed574bc593259dee8308acc8449eb5c3396c29be346edd8a363ec04d31db3efb57576e161dfcd216ee7daab137b6abdf16ec0b08cb8a44be5ad28e5ced851d72626f18d522992b660f4916d55fa66032657246f2d46b4df465440c14a2e2d4bdbf67352428291a4bfb49f73bb4244f73228adb23159b0d4dd90bdbaca3c5c242cecbaa8f3418bfabdac63b4921642dd1d160ee078e2a061c294fdca5e32840cb9240cbf3b63e447cc2c0a5fe73fecafc230dc9d45df71cc6b65ec8f66733157660c0627b8bb06ab93241b6a5c47372859a626d0cb3cafebe4062dc3795a64490d5bf2be9b9430b7118418e3cb98da770d3644b07c962e9a019b283a2defaf501e54867e3cdf4a9226327c397f3eed7cab449f44b07b33f5cdd5cbcb6944d7464f7bd122d55920b8a8cdd87767a544d799f7a9ab52dfeebfb84892fd699449ce5b5106661cbdd59cb26ea375cbfe1b4e90867764d5f0f28b109d2ebba2dcfd40ebd196cd86e15d0f4d04bce3a53b6598dd3aeaf6fd28457f4ad2670c97b5bd760bf32c680b2a6ed50fa19bf3665cba84edef205204b9bb9dda0ec62b0e917b6a92b557cde4a5182c2f1f9b3f317bd1a5b4c5deb42483a2e8ef22521ce7c5f27ab711826be4d63ce077d70899b3539654dff057fbeb1d40718462141db80fb647d36681e87818d9b5db63efbb51ab7bf0b95540a92a4652e820c677dc5b6b646d917730f77a301aeb8db1c6b52c8a87248d13b7d704f487e3b61c7b7075ee8550fd6db0b7b8d2221917b863efd0d367a7a01e747a777acbaf0fefdc6c25f5b32ce5b897aa76cf57574df6a31c29201e71322c2edfb3d837f27c0105545309ae1ecbc62bfa61975e9ba1ee2c0ababaaaefd3605288e9fedcedf94594be687eddec546e7a7cd0ec2599869b5f6769f09ff1abd151a9cdee5babdffb7b3fac3a30c9540771a5485f5cedd51503b35538c23b2fcc4fd6b7f3a304cd9d5723d6c7fd7dc0464ced5f6c3f0e01547f051e1a6b4d7c949b972e7385a7204185cddf0eaf772d7348ab6f21e0bfcb7edf660799fb02c07b1c9362838ee7e1ab4ac73deac05a728a52424d7bb7dbe5faa5f5698bceac16a4dbdac114ad6d3a9f16dd90e185ca943109006886abe395ed0bf7969fc59108fd5cd498261affed83ee6ad6bb25ed6bee858d2b9e04199cab6ae1c437572e93148de82580993a605b514a689dddc0f89eb0a2fb3b856c53dbda2bca249249d5d89cb0e444b956708c07b83dad88112567e43278cef6bb249cabfb371979e4fd2b0d46c08cad7aefcb5333c4b819357bd135ffe4dd5df6f0c1822dd17b7910f40d8840cdf7c3f02e27210bc66cdc7d9c28bece3cfd0c22c0b57a837a2471eaefa9316e1e64cb0e1d7f9a5ae5b07e619f3c0e5c3499b4be3de87ee3d7227d46a65d63b3a6e3f6e21e45f6f9a5dbdc3662cf7d7fb5245ff1616d30bf3f6b5cdfc027f09a8a6aa816fd72232427ba16493386f3b3a84bdb766d25d9a6da6f3d9bee9d5ff46c34b628bf917c8445746975c7fffd7ad89a5cb989b5951529b6fa7ac2b47ac1e8235f389a6ffcb2f9a697935d0adcf2bdbad90ec5b54d58bbc93021eff50ecc5e72e983f2eedb542fba360ca1476da0e2ec2a5eacc5d0f7b819752e33926bf196b837a8a22f4471231c2385eca7ebbba4f3bfb1e2a8a172742dae2c261ea3adb0e82495ca06d4959d75d9cffc2b30aab9ac74835fd4e69f90e0e3bb107244260c35d8414e148aade5faee29646cbdfd2dd91ba14c4649aebb1f0e9df4b0936027f8e9f52e886be03057330ff93ff8cb81d8b8593633364f26eae07813a9ff6bde35ebcce742effe78fb27975d6d4e2743cdcc87342a0f1799784189383e3883d90c452a6564b1c60b4ac23d8cad8c85b910b27e3c38cf19b66a870f5867fddc340a6a86168c4d254a1b3f5a51ff2181b2c70fb3946896e94696859892a730cd52cdfc0b4613ae1a2d45fbd7669cc7bfb8ced854ffe0ace3bf386b81bfffb15997eb5f9bf53f38e3fccfcdb8fc7333aeffda8c455ffc6fac061efb61280e89fc9568edb500ae4309ea4dc1f429f2684615a6610a2a87d871086192f025731b3001937c28ea4e306db139f6854f807a416280d9cf39cdde90fd54f2fc034e357efe3dcd20cc19d072c220a4e08a7c45acfe5c79b58f4bc557bfec7f047e5afdad554ef8de7f70955f0cadebc8a705cec25c5efd10c3ec702667863affb0abcb90edd76c97fe7130b6fc571f856b90e023e84bd2d1cb82d35d822aeb062dea33f5fd57912f4e08d9ba64a8cf62dec2aecfe216e857a103a78b93defc91f25e0b5020556065f7db37df9117682c9fa7f65fc6c1f2db852b402d2b6f165b9f653f86595cd507c12a9f6a3ecf10fba80826489fac6ebf45495f7e8b6ef6aaae7d353f5c9f88ffbf36f9ffcbf34afc87df2758b7167be3ce57792c7feef8816aa66b9aa8fa03fa06051f0a3f4caf3f8adc6e2f3fcabfa053fe99ef97cc0111a5a585f2f54bcd9fe2da89d304a8477e082eb6d28cb932ac1255b006ff35e711659349b7ad82595473f9c164221b462d2eadb11944eb561efedf9af09175fc93267c04b9fca0099ffbd33f6cd26780cb4f9bf4bf7600f33875f87ed0a47109ff73933e83e37ed0a471a3fe539386f5f5ef4dfa5fbb5c1e3afa0cceff4993befed149ff733762b94e11db9f36e97ff146fcf7f4f4bfb6cae7519e9f36e97fd2eec8ff3b545fbeb2056e10babe0daf2baaad710bc24ebb3e65795e71e85cd1f6000ed8b5c05bdc80bd8a713fe33ea3fc5ab0231e092db569f027388cd66bb8b731e65616d982688f7ed4b6858bffa94545c8e9b71675ccd7e87e8a13b7a39f8de5034c80cf1c2d9c2adcb4c58e8e4d90716cfff50f0055f6fe034cd257b41396a1ae9758619c48e004e227be7a4d9d05a212f0de2c9de1ff9f59db0ba1d8b8d2df26ff4ce364e623e035fca6ed664fa29d3abc0605606908dc34252d57cbff132bfb511717bb39e5924d76a827709bb7259e796171f3dca303175e366b0c75f1ffc4b2d64fcbdabd0a48df2d37ae33b28a8afcff6d2a047b051a9511e667f8d757bb5c279bf84cf57e7d05d227887332c5126c55bb58de8046e724cabd44745ae6376cf89ee5091aa8f2fff0ebc5947efa757972c45e0e32de3fa5bdff757802035e4df3d354d3e7a7e42787e7d50b7f7a9ba203fd1f4de607d3647ed62a876ed556803361b9082f7efd9ef5d2ac8a303647768ead7aa2c06467b0bfe81aff6fdcd223041056942a3f307ba27bc132cdb362a4d432cbdd68da88658c13409d13bee695c81fb7df8de3fdb0393fbbff37cfd19fa69be15e6ed77fc9a5da9e24cf1d03af737e8a60b6799d9a0bc4b1c7a2bfb98a61dabdb98edd9f1c85027fce0efbd74ec4c68eb09fe00c15fd41af943ebfd2bff695f2e7573a82817fd02b95cfaf7414e7fd41af543fbfd251c4ec07bdd26b67c5bdd25168eae7bc527e4e537bf95a4701ac1ff65aff4bf335fe0fc746767552834de1fc6a60850a2788e687a2f4c6dc6af20e5ff835259a57281828ce51611fc9e3e42b8f36ffdf3e75f5f73c6c8ba6fc1729121beaef57b90cf8f8b032e74bc24936894608394ee0346c11ba9b36fff5a7d7ef7f6be303a6577859e3c0bcb6208c5fe6306aa84469f0af965580a7bb14f8fb7be65fe1aa3f26a08e93ee530dec29ded3a6525474b3baedfbe12e426045035ed9a4d43955842b667473d5cc186498238f614e9add3448f99bc11fb9fd96bbe8696fd4ff1fe40ffd7e7e830d3320f830cfa1e8298d520c7b4bc6bdcafb7f7ffd7bf383d75f7be890e333e3b5c0d0bb389b98c8539c0e3a5e735caf8996e0b3946cf644317c9afffb44ef3e11ede8779f6779e127bbc1459fa7ed77cd2f076d592ea3c3aa4befda4258d76708eb7a1b0fb27fb289c3b83f39822c7ed61df00e89b9eec0163fecb5dea031d71de8e287bdd61b44e6ba035ffcb0d77a83ca5c77208c1ff65a6f9099eb0e84f1735eab3c93f75fbed65126c50f7badcf77c00b5cea9f78b583bb2b1fe729feb0577bcda0585fed2c40f2c35eed4ddcc7beda3f667594e7f4b0edabfd639647794eb8d9beda3f667d94e70c97edabfd63164879ce38dabeda3f668594e7acc6edabfd6b96c873eee3f6d5fe356b241c7ba4ff9c3512ce3ce9677becdf78b5cfd6c80b7becdf78b5cfd6c80b7becdf78b5030ce4d91efb375eed000779b6c7fe8d57fbc7eee27f4e55c77f6f5ffc7377c6bf7611fc832af09f9a6ffc07f770fc37d7b9c49fca24fab1134b3f74624aaafb7113eb3f7462e5faa913cb3f7562e5989f165ff112588d69a21387c95d2b9499be3d33612f3b825f04d330445e917fac83aee99b4a70806a1c6332578b2694f4e97e2bd1699fdf96bfcea28d76cd94c906cfe473a22bdaabf01f81c7eb2906d17cef6ccba814143ac75594cc9bf7f9f3c312a420e4699502b9e926bf509e37da84a4c09cc5f2439329e756897c58647874c3d2020bb832c7f6e4cf99ee5995b81f33ddb3323e3f66bacf8ce43f7d5a1f43b4c8c7a4af256be68193f71ca24ac6983a48d958d1928331a77fedf83ddf117f433fd2c2aac693ffd35c627f769a12e6f513374e6deb8272e652b5d9be6ea97325479f06ff7f701b14571362cdf77e79b9798634df09dd3034e354f0f397d9dd6f2fd1b26412fbf37bde59facc3b4b2f19632fffe40d8297de962b7073798e816fffec0d1a9ab6f1a297f3fac0aa485b6c75fb6767153a7f8c3e38abb0f763a6fb63736bced631cd72018016741a132708f32f41329daf686667d32e865dc23a17dffca5bc77ee0e89fcbf7416bd6efe6a3acbfff1b1ff8f32ff4f7ca29f4199ff812abecddc54ee75aa99a3d9586da27f4b59d4ee68d3cc43b2af16ed79db6fd47e8732353d2d04d7e9a22fd67fcdce2fa59aabb72e30b3af0ca606ac3e5726fa37ba99d9b4cbbf55f8447f7ff9dfdbfffe902a1ae6165245b31410b310cde8338deacc1f9c40d79881061e37e901f697bd5c43a34d37280f3b59e046799eabd1665001c1d2d1ed1556efd0187fdcac8fc0991f37ebc30e953f68d687fd787fd08c8f39753f69d667d8e84f9bf15934f827cd1a26c2bf35eb1774d27f60d6ffe8eea83fd0f2fa81d660b97ee09cce9aa0d84a74f04b729f2e82c591751f85a77d081157ecd74086ea90a6098e29a0fb53bf6afc81734abfe377689597bfe877b08b2e6ff7be92eb98642030922d3e5126d6070f55c4a1e94ebd8ccb7e024b3dc2544d111138a78a412ab63581ae6b4e7e0665e26441e9732e1bbfa88634f193b694cc899192a698032634a910fc1713901044658c3b0f181a138bc1c9e32bf2761c762f9b6761e11613e050e85d20ecd627e135c6324e9e03d7c86a0c743d767d2ddce9b7157e18c59f06bbe1fe34f4495f41304f37be46f66c55a6926c10a1dc73ba8d6a9f748e62b97b5a70adce3f874d322c3e60ac91b4d0512e13b034f5dae679b8e1bafe9019df30987fc88c6f801a3f64c64709033f69c677c1a31f34eb1b30cccf98f51d78e067ccd88074e6fae4ebd23576406cd799d47a290433778bd182ad036be383dff43f9bc0ffc7deb7f4daae23e7cdfd2b2e6c20a3d568922245d18607061224990441908c0cc3e8183786e327eebded417e7db09754555f51a244ad2779f602faf43d67eff52815c97a7cf5557155d178b1006b2aedab05b047d15fe29b47acecce94c55a1c65529cc795c04968094c47e07041b2fbfde56951b8e304fb9dc235bdac8789f53b35779861bf5338ca8b2897984dc228492b15d439f3e2489c7346a6e6595d137d04b6e5a0da3b61666f28c54d60c7c2484fede03d8bcbda1f05dc8a3887e7ecb5e29c82879e2f0e6d57ce7f9d1177462781c8679c484a6b16c44b425b20c0646fbb4a0476a50348af845db00b852d0723e8206230cc330e1a293c3c2d6ffbfaf4d6af5f5ce2dbbedebef7ebdd7bbffea0c18e8e5d200f83b7030b6110fecf029ddb48a4f9c81ac81ad495ae24048f93ec6fca9318c454a3f2a946c0e91135e81c6621390217e2339f26305bcbadfa9198d0e60b2f0c45e65bf6abc0cfaa38aa5f1b8b3a2fc630037f69f9ef15081c72ee4d00aa9e9ad41ea55ec3b10476872dd9f098cef015b0918afeab26c5f30f39bab2724c2098b2c0082254322569006672b4e2142dbe8924a924103723733d84d298cc7577e0b725738f7ba3ae0fa219994992ee64aeeb3f6b4ae6ca0a7d5b32d77556b625735df36a3332433141428b84c5e09454dc380a5c1de0566beac3e24a62a2faf16e464740e03bbe7a7adb5713c2f88eafb6effbeaf76d334aa1def1d5fe7d5f1ddef7d5e3fbbe3abee7abd3fb4c4a7a9f214defb366e97dd6ec8d4e332fef5a027709a9e2c6ae20596e88e26e5545196a1687eeaa691ea06a8fdb650226ec2795f8ca60f57e01c82892a2d22caddb7db7d2199869f14885dcdc80c538e0a881205601b6e352912961aff8e79abe7c9301a339c17025c269b9359340dbe080a77cb746476cb97cc1c591c2839cf5caca57cdb06ee745b76ce831ae4e3f19c2999543cdaaf213163f1b1ab2bca0f6aacbc3e3c46835aff528dc9d84d86a04fe0e676b9f6ee9cba7a1bde7256aa3a15d2d8e5d198af970929198bf8039e46c14af6f2213bdb5b45b6fda5477b59ddad3f2fa537511aabc0df6761fdf7e093f9d90d9b87a68bb04096888c7706c2aaf6a2eed0cb50db8ca47516bf0488371590c9264640b955e0b7ef4b3139ad80994451dd80914683118ca6229ae2d075f64cb139070b9cb8648290127fd482a103edba6f56d23416ca07df2e04dc4090f11b4793868001f64245fa70431ec5c5dfed9424d6ca1c3e8a4c0d620e392156002fa1c0b3dd231abec5066f0d91aed6e0de97d9f2eaac37015a542d3234724bc704cf53218a6ac5a286fdd09a525789171a4dd4d595252d421002209f1c4f26588d517e34fe09bf96326044c935095e8a8f1b8a0a8c1cf94809a9a54a30d0dd43638b88f09d6be9adfd492c0a9b67ba935a1eb6e8d684c6857758e899d2d0f6538368d9755da9f147f53653d1a3d93cee3594976f940427593420096620599bfd50f677926fe3446ebd822a8b75dc55b7d18ff7465346544a6d17c84352a4faa4544ba3fd3916a69210d090ddcaccfa6deded45f7fa299273c5fa1e9a50b9f08b75fe1c697cebe7e3fc6fc208c102f1ae8eff490ab5278e1a7acf9d39c25de36b6b3ba744c75b4bf8684aee7fdb52674dd85628d09dda389afa393b72674dd1d8f8d095d77dd704342afef1bee43e82e35dd9f9db67c105580e87790a802c0a49ba0f8c785e1547efd491b10d5a07fafeafe37544a1f828ddd8833f1842dc269b8568d93b5c3904d1ca155ab9f5dd6d2eeeacdc4d7f739b52674dd0dff8d09dd9d89af6e1b6a4ce8eeb647a81ed9db98d0dde5c4c404ed4fe8f1c5fce9f5957b75e5be6294b3c0a2d796ee65cee364e4ef699903492de0d7df8719a51a2946a0da9091dbd4460c5bc2202f8a0b25624a1bfde3b45e7ed2c42cad7c22ef782276cdcfebb2db475eb11c756d854e364b82c7a6e22e1774897326f52f7ab000a30ba4fe6791549880c33664c5657faeb5be1979eb13c78664ae6f376d4be6ba71006dc95c370ea02d99eb5aebdb92b9aee5bb2d99ebdaa7db92b96e54443b324b84fc3a9f5bb7ae14a051c0867d5750f9a3ce786a72a5c74e13c80f3415629db09e05203188ab8cab82eda7a3e9a91d4d9f86894f4f4b374b149ae8697999c9f6affebe57bba4bad07935506f247b67c1bf523701791a623185089edfc2efe09312cebe239209d5513c0cc8eb47dafbbce748c1cf03bde7dd051cb16a7b1660dbc28cc81087a735c88a3e6559ef2344ef11a077838005d2b1b0456078e3bc15acb4496465ab517999d71df4f0e2efabcb07a20ee8291798371b74060708a1e96cd3bf13065fe440e6830f370431850ce6f286f5008f237c7228eecb2b16b9e091d73f618b2fee2408275a38494551498ab2202941c09eb1ddee10d5e414fc3dfa61e14352b8947bc94bb4451d0e38d90101f23306c623b0fd22b4405a154cf7b1c782ad4e001b12b80ea56a48e03a88aa2181ebf0a98604ae03881b12b82ec46d48e05757e6e267b291206c774f360a90123c3b703fd171306215dad23e580bb3feb8a4546ba56d61c20080be201aad250a60ec11cc31516a300f96e75083d6f31098e33ed4352d2c8a294891caaf164aefd7975512c4a21e0a05f1d30403482533c9fa1718f31ef5aea388476ac34ebe8c00dc79f971d46a1d61a22d999fd627169fb8c15be9b8098a20e9c1daf1b64e93a640a649a00ace340a8db74bb5e01475b53d2bc496866d0f7f9036423556e781e0ebf6b3b1d466ebb7670d6310bd12a125c32ff0a84bac12e44ccbebad5a2c2b45d52e8d651d63b21d99eb697c6dc9dce1dee851e6605f9829a4175727a4d9f028507017d53e41c5be7051e31b127b5e469d9d019640529e1986399a0bb4e2ce6f56af60439cc4b90b5351dd582d21bf2a904dd343e9884670c340d8a1542a906a41c94a88527178393a9daaa3d8049f3701abc1405a3e0269c44f52ca4970271b136a2360f840b960d07110aa454aa783ee16c4051a4737e2d6759034236e5d73400be25294da89b83ed5c28ded885bd70ad08cb87501710be2428cf63ab754d7b3102196e3c4971dbc02f6be5e3b8e95af0d188224c636241d5b7cfa97b7fe926d0cf387c7a53636e663dbf86369ed0334527aa64972d69a245065b8f35c1152185d6175c71fa7c9d7d0cc24dc765719f662ad39b0496bf02040e2cf1afe922cc6790a49ccb5025da8aa264a8ae192a34355301f75f9ae4c2fafdba31b601abdf9c7a5ab8dd305c6bb65b752ba2dde9a5d7f963e1a065e24758308cbccc78732bbeb0ef1b2aa1926b2c89630824fc45e9cb53d6e1d6c3fd6afe76bc6be3f723def1063c5154d17d5dbce564576a5d33914bbb5d5da43fb99019be02720f24e6018fd8426d37d16ffdb2f3edaf8ba5608feda004d92022911d39cf93104e50fd0179a7bf211127e8fa144405747a44696b9ba85aa21997bd473753b5223320ffdc95c97e1b6236f25a3a61d79abdbd31a91b7ba35ad1179abdb2cdb90172a037dc95cdd9edd8ecc75c8736332f7e63faa61c7c664eecc2ed7e3a58dc9dc59dc595fa4684ce6cefc607d75a531993bf383a1ba02db98cc9df9c160faf38384d7772773677e9004e84ee6de7c4a3503b031997bf329b6439f623bb4cfb643fb6cfb8bf9af6fedcd3edb0eedb3ebd03ebb0eedb3ebd03ebb0eedb3ebd03e0fbc375ec7bad998ed6257df1fceb7b05d1fb9dc0105c5755916c0a5be162c26197c1bc7f2554c34209706e87efd6ef28f64a2f32e98f7859165e72d80b79e5d77100930cd2f64267a5925f411c23920a61051dbaf72f057a465fd9895e860c51390e287bdaee96cf56bd66e5bd0eb41dab8e681608eaddf09d58d9766e71be6854c17604acc7489880becf32eeaeb1238c101b8bb25404b3c011bea0d11d6cd5ff0620762c124ee909ead45524abb8a848498b0344ad0320525f412375c99a5640f1c6cba791b6eae24db8db6c5f47d6893ce45996318a2d4b192ee2b1cc0562f0e212dc8353986ab4f68ed9bab2229f22ef81dca99113d9a798829661d62b81e8bf50aa3bc3118389dc05d3462e840dccf484f66ff92b3cecd3f094db1873811e1822e6ffb8c8cbc343f32f2b3389b8be35b1ab9fa7aebbdf8ff777c73553568fe22072639a9c9960e5b22acf815eeb6e1a88f72aa34490773a22c6a829e9d00078ee87f1435f425701566d792c0c3db36e34613497d5460c9163c322a38df1272823baed9df1cf62a651a511aa12242f9a657a678efb8a84f48752aa4b205affdd0edf2a2f6259aad626341abc1ae3f01152d6d086c7f629e1120eee6c57a505f5fdd1817ce0e19311b259f99bf38c0e70fd20f4a38819c2b00baf8dd6c6aafa22df6d127d931e9d404e866c4ad8352db11b7dec537216ebd836f42dc8d398b9f44e4932576b0382d6589dd1cf7f16dd1fcfbf2087f4f283c20cafcfc3ce2e80cab7e722cbac101e28db8f19a1b1312de63db575ec3f0f814a5ea9a2258bf2d6346ef3d173cbf5347bd44e11acbe7ba1a1d269ac3c9270ccad764036b4d9b831c940d5d4a79e9dc4369c04bec1f227cbb91df91e59564d84bc19ed3b31004a9a80dc35b92b74799eb282f8dc95c45e16a4ce6c5576f9b903526e404ddbb4a99689c3b5cebc187fdfacba31b9fdef2d5e96d5f1d366e5b29040a6e2bb20c19a561bce0752386a84004836c0ecf30fc191c4a941d8bfaf64d0f2e032303e8c93a4c6178af6b8f2357a9b89cd02341418a58e43512487bbc7988a2e900b7cf6c4c27897e963e2e216e0a2b1ee3b8fca15f67b628fff586b95a7dc2b0ff6bbfffebb0ffebf150bc93b56fedf2bfecc7de6cfbec322b5287f0817842a8e479f296f9807808b8e4037673627751434e1dbdcc993c4a31c26f23763085219c96016b31c0d5a2d70f3f0973dfa53d26ff1ddf3376fc81663d589ca78bd9fc922688bf033c8ee0a956b2d4ab9a46a06778adaa031788a13cb1112921a39f097f2366350ab6c0527a61c87d82d13578892efb5b6261cad8a0ee24aeab9f362571f5cd39ad485c1f363727751d27bf21a929227a473066dff7d575e35d17ee1b156a49b5d79f0f58817642f19d454b5087b7f00b2aca0787363fe1f2702e42bb63acdd57edc84b8eb43799eb0a678dc95c3708ba1d99abfb801a92d9d67afe8664761dca5cdd5bda98ccf537bcb421b3e9d3a774a7e7eafeeec664eecd0fda5a16496332f7e8bb7bb31beebd594efd51c2b6c180801655bf931e039f310e14cb2065550d2614103445492737a18e0a92c9692fe79290669ee484f16d47e6faa0ad1d99eb83b62664ee6d5ff4b627badb0f9d59e913c14e1bf2d65daed58cbc549ce94ee6fa80b21d993b3b7b5476ef49e6def6c58944bf0979eb8b3f8dc95c0fc436213371e8bb93796370cf1e43d95c88a793204f5ed8b02389cbb49ee5dbb2a42d312b41c81e8e59a3c345511c02e5ad099be40a3407cd1c4ac48496eb6aaf6f239a352508cb4fec0586c1cca36a98e9eb986122bc5c5e5f93934b66621db632066450f815cfcf27299d92fe4fdc28dece76eacdfd98fec2a99318793b32f7b89f3b4bc7af7fef2c4409a64318a17a0e7143329fabc9b723736ffbd9f72773777bf91cefa10d997d87b186679bf1961a5565033eb53550752e528c6de12f214a3ba7e7793311844b201815f488131960924d58badc3c751984d3d768b525735d98d38eccbdc9ebabab678dc95c8568b423736f3aee4dbfbdd9b63a77db8ebcf5686d5b32f7a8e7ba54a82199dfd718bb2cef5bbe7a6c099fe6fbd1a53571c01df3a585c92c23e4a30ec8030ee7090a12c61117b4c778e34912b0bcde17265a34ac96b8ad966bc76d12685fab29480cc2c8b9e43d4b2294121cb8596790effc586a0a5680d4a07ba19793e261c68f3c166965fe0b75382751d50fa6262fbd1c01a72d059b99eeab4d9ac4e6a6896457a59b9d9158ed6a89b57274ee0cf061495b09e08030821eb87245be8db2740fe8c255d41f4f5bac90dc525d7510e9738dfc80fd77a0e672978d6123035f3bf006911ef9176f68dcf661a12973e3fa8856009d0a3de82c3fe04801a62af099b811376849ec13694c5362d76706ad88dde1063981213423723d8cd08cc89593605b12b91e8c6e46e4fabcbc15917d35f1b23db1fbdb202781e9a6c4eed0e8d5434ecd88bc31a4b9dd303e2cf3cc26bac6ef108b0930cc2450fae2f89b69ce18d75e3978f712d57718bcd7736e9a13bbc328f82444de94d8fd992c5fcd816b4aec504d9f6d4fecfee2b5504dee6c4fec0e039f6afa6f5362fb370e848deff96a8199def2d5775d1d350258fd8a7bb7b6af363ef87536f2d450e709bd6d325bef8a43f10d9bf353e7a7a78fba3ea5be2ddbac82eeeb4270b78c3c337d4fa481f72ce1757ebdccc127c07bff2eac280e9aa27ff27c3e41a49d2679211f7e5fdd16c3a907db87658b126c1df0ac4ff2e5810a8b5ce777b0d7810c30273064813c58202a8d54f36a5b11b62bcd5603e20d095c174d3722707db2d588c0f5817f2302d7c7ce0d09dc9595a037f623f0d0db1ef6b589544b02d78d9e6e48e02af4a81581bbdabfd548684b0277b57f4d6ffbd77716f850f2d495c07d053e9ec1d977e022e14d6322cf5587c380389d41506d516b4a627019df0b547b5b7e91a25c0720f45e93f137e7e74a128084451bfd097ca209a80d81dfb81beb1cdf880d17238803fdafcc694dd08511086a0e341256cd76b5804705272663667d26d12eabaaceefb5236f5daed48cbc955eaf19792b33a576e4ad8b8cdb91b737fb501704b5236f5581ba1d797d35f3a21d994fe0aecdc87c027a6d4be6cefcdd0900b629997bf47b5dca6c4f15d08dbe9472b828ba26157589b7c98c8a8ddf27a925af2f77bd6a806e974ddb15e9f9f25a55a0de19e6a86acacccc0cd04b8d57d4513b5b8a90475112f4f5e7bebb3cf7d4b6eca397abcdb272447ea007842d3d128c12981001b75eb0487e21e82bdaecb29d2b6bf3cd1c9937525d4e70e694fa296f0f21cbe9e18ec600e3930808a0d74b566fa56bd14f009e45506f3c0d51bc5fd87abfde88c0f5015f4b02d7d3f9de2f705fdaad0730df2f2c04fe9953b27cf7b66144f1dab6417395e736117e81cdb86cd0db98144b8f06a80cc2201327052e8c2cf6feadfb2b17d093f02b24b62be1f3b982dd086f1954e85078b9e5b44fe1fbddf38e03a9fe84a743dba5f057cdf77c60bbf5b0642ebb149e86bdf429bcef39b6d91a3bdc8bf0142e77293c012a5d0a4fe6b24be143e87cdb746b2ae94f97c287d0b1a9a457f629fcd8736c33f66c2a8539d1a9f0bd9a4ae2c4f62b7cb71e36f66a6d52cf6960ea39aa4cf231fd0adf656c93e44fb7c2f709f725d5b6d0a9f0dd5a9bd4b3b549bd066649115dfb13bedf3a6c5264883e85efd65442276ca7c2f76a2afb2ddf27e1bd980b322b4904a281860bd024670e0e7128797692232e650a40d0049a27cd7bb2ac242b234c43e993669167d50965f3fadaa9fc1e8f2294c514e9ae5f5378d1f6ecaac317477a81b1e5577bf5d166f78533b9299e7de12d4ab7a8c56cbb3afe3ffab8ea0fd9381e2cafdc365ffab8745177e18fa85aaf344e6ce2c4c76ede45b4afe7cf132e5952e7cee43bbff0e1db7bbce29d406bbefd33b285bee533f64ea9532bbcac9a05edec30f18807c7ecdfd928796153075abc3489f9f213ad1837f23a791bb1f884e03e0adf38d03923221871076799e411a765f37918534e747e84c5c2087facb0e9037db995ecc49f1bd6178b26c59aa837e2b010ea0bc3f534ef9f46482f8b4305fb595f51eac869a2b7611780cfae3edadd7ab4ec87a65ea40be460023f62581f44f4316942c7992b77287ef3ceaf3c6fbd95dd956f3a7a283814aaa540b70f58f1c204f8d1b48644b7e7314f9f9a2648fc50b83368ffc97c522656a96ffeb9c41716554e1d0c30ffd0583cbe72ced97251a4fff570d195b5b99a2159907f19ac7893fcfce6c233789e42b97e0e9f4f74945f4d6af4792f0f2261dcfcde885b969f562294717e9c312e8f18f4bfa7ecf77d3ff6a87ca65bcfe7fc611e754cfcd6018f623e8bd45ff294030ddc3ad848bc713cbf5e392c6d061d74ca11a983b212892754fb94051f26170a2ccd5d1c3c429b17b888ec5589c34c57df0b38f0734dca37b3a10edad2d9a5278f479014de0cce83de9ccfbf559f97b2c4917fe4304d335b376a725b18ab394dd049c6e1589ac41bcd3f344ae91d04797e7a7990b7b5c938a169c16593fd98976fe2ad42b270eac47d86cbf6cc7d9c846d3221fafa731b05a86cd9547e2293861ea4ce6f4d3c4c5bb9954f8cf22d6394fcdfd4967d08a180a153fb48125876b410e690a9986dba0a7ae411d8fbb1cb35cafc862cf5cb3a09c5f331bb3b74e571178ffa6a68a57dcd5c25fe68656bbf0c6f85e208a840f838c0d30ae01951b239dca79209a2d4238c5f906a04198548c1c6142f9b90f5f567b9db8e85eb22ae617b09fc6694db65159290d9a894a45f99c77e804d5777c2806d4a5126948ee97815a9a844eff13886d4c01eca568e878d064de3dededfb4a7784a87ca771c58e2040db6bc13273a2193547da92f8e67a3d21e9461a9039ca734d5e71fafd1c9f57c50e16f9027f654324c09a3c694108174f2bc29c2908f11f6071d9740db892b4c6c643c3cf4d171278d2ea2f23a4458177870fe372209e614f26e2fab7135e376255632718639ae69f104abbfbc67a0904d1549e57459a3a22867b383c9264ecde4f17aca00dbbf41d44f4b71f672797d4f9083a9308fba27e81a933bb16807416a7ef74e86272daf9a869d17ed5eb3b3acb9d1c5723104164ee3222ded0b5a831acbf7e80dddfe29af815e9e78cadf01ad30e843553c7ac071d9ffd91b6284d7ae3cfe411e3b868d04e810b05def7d766be21ac5b9595d90e2e48a9c112627efd67ea116c5835bec07f169ea415e86f86c69cc7354ec2e6570e1870052bed4336da025643dcbde9d3fce5185c24ea08c15cc410c03fe7b64a117965a501e97bc2cbdef1d8e14ad56908cefe421923a13fe741ae187f927d27ff7ec79194eb7a1f4db756427424a88177013add75f1d3ffdab95cf71858fd09ec648eb7316807819c8391b72984d199c243dfb205843a14f309f7870ad941af8eb89677b8960360b59e7801f393705f0475ea00120b2c70c0071fd355ef2acf286937feb636451e2869331ea11e1a59a0cb56606b2218c979c60ba7ef84d786bba9c66ad6ab744c8890320c74b44c816c8e39e5d6097b43df096f1c850da4fd51a959fac6ba9ca48df5c7cbd419871ba61bdb7bfdc385ca35baac37778d6bd52d17d9b7b538c49033d02c5da12a85b12f4f4c13fbdc495b2a29bd77401fd36e0735edfbf62fa8c180832fc4ac04a82817534979388a884561580ac60f6ce2087d50f0ea4344ea8cf8d207d08875d43e8954ed798e32aa66668980c0e16439c04ad9e8a32ec8acdbdd3bae3e2abe095aa76aa2b161eaf47dac04193223e81b7544fec05704829cf1738b20851dafc29c661cb7ddf433f0df39527914456d1a0754566928489ea6ffc84385385ce1133b9b9f6f6cac527aed0eee26748aec531f52928f5188b8af769f58223fd1102c57e3f6078ebe44cc9ee82cd6bca1adca1961317725652829459fc57125118f913b89c152409b7c58f5816424dc8bf7ed3cada7265ce5e3020076d684e7944f5140ed172e86e488f9f0b9028c8958df18b20d71f284577e8a481b6e2b269d956a2e3344972797d61e1c8e4bd6c54000beeb2d55aa84d610433a5280b7ca88334b07070c13e216f5e21b146312c9f8cf0118f719cd205d5d4a7da8b94e506fa810324c220bb244a1c244d4bcb55a6f7b93e79b8b8fc3c3000cd1917110cee63c63e27c6bc290f9b7fb0547d4f47aa0e1c8a871230fb2227f3bc5294288eb86f275dedc6aaf9d563ea8845e0ee9d17659c7bab4ea0aecc4f809e534b1df3493c00543e2b88efd9ca177191825511c4aa33434ea547729821ee97c1b8d3c0333bd071e9f1521965cfb901cbf2d2eaf4067bdd04a46c230505a6eff391823b9f21af37ddacd8ad0ce2a8b7c802ac6081b7c80669d04441a2c0155c881cce821667eb21e8039db9a0fa772451762a22e306587e40088ab64bf746e63f48ec330813c8c36c6e06574c11d8a4b73e075039ad360501cabe6013a7c1d38d26298eaf86eddf1711e7fdae2b710f14b16f6e3d7273aab261257b27f7c8576d2d8ee4a13b6f28ab6fbf5f6ddcc1b71f11de94129d7b961253b90dded71da1d19376ee346efe7a157dedae949bf7c814660dc42d4c2dd093aa629d47f78de41fa9c3de86a9695b11cc4ea675ae8ea1eccf269921f30e3255408579aa8363830fcde6d938ac981a08eb4cd640992194e7b3902ce5086aa3a9e0d54c10f49662a9c79c52a574f9f1b6875247399a9577d32ccddb8f23c3585b29e6b8e759f5e3ac4e8947908112cb41aac73232635cdbf66c4006a4f0c2c573cfbc78f487cb4877d7f928238d60caa0ec64f01cfb8d4a0375a5fb73b79d22987b3cb88563e1edb7c850257bc11128bc937860d2ba0dcdaf268d0cb03792607764c93cccd2a43e1daabced736e1a6ab448750c936fd78052d95ef52df552d1a6f868bd5418125db3986d6a44a74fdf9fcf281388dd1587412cd630c75cc522a22a19e057a1082d1e0e1ddcb195258f94433dd36babf4ab0ae559ff92a0d1d0c3bc7f8e0874432f0097b45ffae133d68c4a7b6ec3d68fba8b14eae4c1e6180c1ef36b66d9d26ca305f441a7b86987a92c901f3c6a8b3592b67fdfd572a09f900c20401d9dc6aa721123c0e0bc57a2370a09a0a3f58014fbf9e870b7388c02024e3f76e6712da0e16c831d78e70471869fb2fbf909c13db4cb41bb8f9c36c6d9ad01a478144a19d9693f6d9a99303edacc6c54876991147ab05d6c7e1d245d16b38ad82cddb64c4db9666fd2486b657b316aa159325bf40dccf706305fea15b28f712ae6364de23ee355721a14ff6cfe8e08764b8316a17a33a0b0a20b78d8acc452316a869c13cfc9193e1eae7cb269015fc9f3702361f1c668afcfe1b8ed70302a72f60024b89f50b83f1302daaa83d58be14383aa36c2f58b864b468b522f111ee2a45eb746f91e543efcdae4d3d747a6b9af823e76ddf610216461034090a6d81dae490d48be711beae062bc397ad647d024e3bc5df8657777d351d29fa7d760a426b5142a2201cb1c2f7bb45d88db43f64c5419081801d0e8068a2af73a4e768bb34f29ade611df27ba7c5a74f9b096948d2fab6bf8e8b3f144f37ff37c8e225c3c4301d8d1f433704b168285427efdf1edb7f8765d24f128c7617dce4059166161fa93fb41cdf6b11bee8c79e59bdefd6df1af262acea7dcdc911928de959f64b02fe371068a3f4044a14ad8d61108cf70462b6ba1d8fa2315c792328f764384f7d1e54e49bc99132a7207183926763abb6ab8db46f50312181435931057fe4594720616693e2bffa2951f7656be105d546d81048d72620c35d2ef645185e5128411f1d9047d1e7fe17b4539e99c4226a864eaae3dd549fa468eba9fe7357d69f12b028a4b3036ad823c7e2cabaf43239f96b0063542e5d5d8f20e8fd50fe8cab55c77c1db6458608bff221a914ff09c4123b25f5f198759b2afff4eabe8c8896b97612a9a2c680c70fab0429ed24eac3bee0c807f567b91d60d323f6ba7cddfdb1205fd75bbc5a8d5daee3fc3359257d5e3658137ed81da54bb97a2813da0448937f83a8a4e700c400e0fb80da1625c7b709a0ff4817a0440a770190af246026b626e62213195678b3caf439b748b27605cc512dbc95742d3622ec82c31605f8146ab4a0c45e3e276e8ab77f71bbcaf8a6ce0004f70b83c367e1893b5cd51007643ef7e36b615c952985cde33b6f5796d562a45ae61131467b9a2e5e2ea3d136678d332b9cce1d4b141d0d777b2c2bc78fc8697a09ba338ea6837c1ca79badf08e35dc98f6c1bfbe1a9133b863cf6cf277648d9936ba2da673e685a878703cb213ce25601213a1ee235eed30f3f33df7a9cf9c651a37e29fbaaacb18223ae547bdb8142bcacdc0da179ae943973a1185a3e7aa2c5bfd378dd9f1a80f72e1892d9d40cda4de5237112722ac17862aa4c3ae6a2d1207d12b4e887ca9c34b58a7a3d573f0bf233a66901d7ebf65e3bed6dcd65353d881bb5849dbcd529c56e43d55b54612dc808078652389a15c60d105803a03227425c1148f5d5643391b903f0e8954cdc907e40c060960bbf7793249705cb7426be6c5e7482d18c0ba63399394d1d97e7bee23971c1b6b6882cbc0f9d321b74d63105dbc82a36384df31247dc2f29144f670aaba830cb8ef7ee48bebe6af5e5125458dc6d6f1532294b02dd561ccc68afa376d5070781de91089d97c1e29c35b0a201235766ff176c418bead4a14951952a079dc5ae7b23ef76deb087fb78837e842d1503c44be470284de6889bfa1f4b71f42db36e8fab3d85937b947e8e7165d05f98912a1f70df744f85af0e60c43d34670ac23881dd6764add4fd710caa19b516b44477af4e9f4ba1d97a1c994728849acc1907af581a85b578c6d0b15246db658b37389690b3f86e6ea48a00bf43c4a9467ef2dc61bbdbbef8262cfe70af0e52ab4d58e20de26565a4b903becfbdc33c24a2d82e37554465075794ab560576d7020f4167aac0001efade4a85aa5353164ab733deb576d86bc943af63c6bbe0665cd5d210f44c916de441d06c2fd483a0b215a88f538cc467264a498697d9b8acf3881a106932b190480070a8011ec89c320831c2d8ae316b171d00900950935c5eb3d5325aa85ac35c05bb6b26db775ac875a0794d49088f8c9f51c097543e7eee940ce523bf3f9ec854d80b49f78418ba9ec6a83f58389c0cb9d69817266620de1660944b4a6b1c8ca0b81cb7606062b30d24e8d608b10d75ad4596ded02caaa6009f8d290139f18c13b30136405517238c2a09707100af0d3259014a63141626013e659ecbcecb0f7dc220a68f9e95d78700689629a7103cbc6b4f314c247504306b04e06accb78487d6684966988e6d71d018904f136e955759257314c5ec591ebbd6697d881370383bd0ee68862ab96d9ee38867a010acee5c5ef6b4a684b5e23aee4e5897808ad8b15f3b228a941336a3ac111ad89aeea2299ae4c639ce81385e5e5d4c350fa625afd131ff287c31a03630d5d120d6de4cb603da1aeb89cc8b148c93fa0bd77270001b55d85e6027a508b1d3e572b4573c2ab0b4072dc71e599e65060c2cd610e1b22138211c255b00fb6cb26e019c1fd04b0e527303f1737390fa74b39852aecf4150e4433ef630f74776be0354c497b3ffcfdcdf65dbefe61afc4b6e584c02b9c5cdd80eb89358d68316e151821fe1a5033eb52cd7fc2dc6f2f7894e0feffd970a8d13d881c33ae99343d3ab9115e695c0694566bdec543e884e8f57ac3d901801f3611b210a824b483c8e4232d0dde9b70fe4f8783a907800591e299a51fd325d20d567989677a9da3f586fbbb56da5f82c69d29b7c13a8d861b50b8661067464d28398786937515c39ff850f5925131c160f59b441dec1e7bdf53805adc00a2b07caefdb06933bf88c316ebeff5bef10366dbc0306083a8c663261cb53c85a7f3ab09eb55cae075acff6b512c68f56b6f74af538dc2779dbb83724e18dde3602e4cea0d4249d1202e051d2554a8cef6e2ffd71ac30745f8611ae0a8c1ade537c53b82769df0a3344466cfdb001a44886eca0fe1375f0a00425d68b1a7f10e04186fcba2378eebd93c523c91224898442e3cd2cf0733e5520bdef462bb4ad3f5a515a39f04d8fd6483e30cadc6e630a9dcb9ed1449e323428fb209449851a5c6d5f2a543151f731bf7b831d6990bf7b680e2904f9fd3cbfe2461abdabb84329c250dfa403857e4c67881f03b176261fb3b9e962cddb4ce72e156add672b345fa993dfd367bb432c490aede720960104ae037cfdb474fdcebad27253abadcc151aa024efb3d15cc85261403a558e2f7ee61aef309adb5a806e1a6d03a0dc58c50ec2a84940505410ded70fdfb91b764ae77b0ad574dd6aeaf4e13691b2856d83697df7eee09d31e4b11dbd8c4b56047c2024912abaef9e1c4ccf45e253b0c5e981475b7cac9526a17ccb7e8969b1506df50948ec5662c6cf8c9f9666fccc90deea1baa5b999310f90cfe5f80b96f4c2e8aba764d5be969d3af0e41a42b00bf0755055cebf34a49112029a07632b56a40eda175284d13285c43f3e01db70bbcd5407c8ff50de9b09f9885220d4c9230b8b5ba448025fe971fe4bf6500760b70cd214bb555a0ddcee423e33cb04f54179c47885e932c264da7f8b42c0a8923ddd1b2483030254548640f0ecfa74e4bb17dff8d430a971314971df1f5dfb80c299ca8d17b9066ef68a501fcfafa695ea9eb1d5669ae434c39a7564f2f0ac0815248981177a3995315536c7e80e8498258cebae52c86e2453c8a3a8eed55c1c20c6742e3e67f00e451ea5e7e8803dd0621a5298ba38ce1f2d338e636476e0375b969e40f356cef544d487dc4dac1724610608405c5f73cb660c02e56a7638f927fbdaf60f8c3fbd7c3d471cbd3e2fd784ff1bcdce0c8929508bfaba490032f269aea7921e4bda596eeb2dfbccff653f19c06d45eff2c833dae76dc2fb69fecfcc2b01c9721aee40ba6cd81ae062f70a1f2fb88a12a5e76bd365837f4792a7093ad3b9f9807019c9d17ff770121adc66c26bfa2fb155ed494b28e78897b4661173ce69ad720acea3465ed469ca805606e81fb38e2b670ef9701a409f8091e7060d54b06b38048c00774232de7f9aecefd4debadaf3cdd33dc1e7058d8ab7b06bbae436342db289c68e828c466f8f9032a5ba5a8e28affe5540167cc50b8c1a75a52bf7e4aa4b4efde58fa2a411c7924d1db4dbbb27206baea559b8b93f16942c30f5276bf7b282fb3015f502c6ca03a51b4ff41b5be793814b488015bd7e4e099ac6ad66089f8e6b12e2568b1dbb12ec468b9ab94e8e4f831fd27c98291554d713ddea440d31d30931f84599b308fc52d888dbab2173d4c5e618e0e5ca6c405cf41a046daeed52c8701c8ea00d2a96eb451f60fbb0f3c56cb796b77888085782c6440205e5a9f223453012dfacc00010625e06e5024a272d03902886140f3f19b394da34234a7477812a95db2ce206a9216ba870fc61a76ea95cf339771c43d2c8e347284e84aedee2fb199bc1a2af8f55376a91b05dd5e950e4b258d0ed7699244d7b5b84e64c7f8d4d089410f44f90ec1bbd47df1d231651c9faaf67634dcecf98c1e664d36954b4a02edc1e4b2130f132f67c6b1a0f696e0262b5f8dc5f453fcfc26f182676ccb5013b311408e682ec9763ef779e3bdcf9b7739abb926abfaa9e219701ace0fadca523e0b1db2690ca5f94f6a72d2a0e214ec0c9784c9dacbaa4fdbe0697e1552ac9921fbb8cb46f514ae5cc031d5ebea15d381a65cf54e821b615e4ee8146c25b1ca087ac5711accc452f3982084f23897294ae8b487c2a4ac6bce23835058fa161275e01ca6a84c9f816d4905518fcd6b5ece2ac337bea24ffdd11a79852df709f6c2466478ae69814d1d2437540f14bb60a46dc3230e7ad2f46f3cfba8c4174b66b4d1837ba80a01b1be5a593f31c07f6c4cf96b36b0a571a36a83e81ffb4142b5c578deedd85fa3107f3948f856252c71661a4755ce5395934963bc8d4af786a51dc2ae14cdbb4bb870f88c0193482d42413070861a98667f1ea4ac0be24bb361fa0ee21f3177d8a3d5630760c434caa85adefb88e26c8fa5ea71c55e911e3f64523410cc3c8051aae73da2db3212cd16c3f8e1a68692922aebfdfa4b8c5b6916f24af504186ebd7823c2d0a12c407a5cf74dc02922ef3964444172ad9f65b979598e5a372240e14e96c14f4833c428d7c91a6d2d8b4a98d8d39f99b76a30715b5f19b3378bd526ad04bc2d060743c78d0d1ad480bb8d40976151b02064595e1ae24de5104f54e62e8001d4c7bb742cb93f4731236967099b12f8d45cfa7bd56d093f5459cd84dba14706ada8d601dd2248831985224338084d252d8c9d2d61bcbbd5e9cdf379f0eb0ca0628db141345bef822980f48617a60407fbe0ecbdc200ec233386322caadfe97e060b510cc26ec267342643db98fb35c31fe42482dd187e6e33bf68d43bf24f96acb1f8c90f73136bd443005078bab1d203f00371c22ff91a94c2983d8057808fe56cf67e6fe8966be7d2f26775e3e520090937032264c89b4915792789849f23b7bde4cce135f90b13de28b570c513142fc734117a90b7081ee0d6cf9460ae56147a1123b54018e0ddf916a985f43482c396f8108933c8cd519d546f915c8071279b3c602128c960b3a087b0ba7261adc57e2e6eeda96bcdcac20a2895a89e92353d372292e932705ded55e998e1fa4fe106fb16f5d9437f1c9c3fa3cb4909008bdcb89371ac3c91e29797057eca0d4809583e0147887861627186cf65c328a9fc53ec0bd399ca7127c47f12f300bbe86b4fc585353f2e7b2d2e81055dff1a97ce8f7121828fd42d18a413708d2e4649b803669d44f54e13265d586e2dc5ec6fd797c4f1415559e5f8d815f79ca1c52cbf1fb74c18d5f5d294014660ffb1eb20e110e1fa33f372adf10e8bb7ef3002c4a0acceee757be804165b754587f81f9c91b0f32545c38cb643921e36e1bb6cc77b083c3c307983a63a562cda505c0149a59456a83752a8d811c311c5d0ce504e67cb861d7644c86e79a3ac41dad1275c017366930ac721f0ec8490efb6b95f43369fc1dd4a270cba8ae26593322219f9f2e66929004ccb161897feb7447dd1d30cabc654b92fa9b071fd80c51dac1aa639f21bc153ae7a8cc0748af94478ea70bf7a18aa314a2d8e89a626a3f00e901978dd8150b16fed6a0d83af58c360aad610a3310ed282d474c2ee0be98b2247416ea35d616b70ee9c45a8d55ea7525c491ee13cb06a1daca8429f2941b93502ca5e20bf244341a6f5dac26fe4ef647ae99aacebef831c83abc95eda46c7a518bfe609aa9622030e8be350cabe18a0c7889db6f0119d4599d4080ddc233447e4f78b9a6c003494ad1faf6977bba66f707640dedf6013d1b667faacd01ca1b9a8da7c3c49e73b9996d366c480ebf334c1c5df914f7166bdd1e3b411cdad7b018465c2f874806d8d551522b5895bf4a733cfa6f53160c30a36af458955b9681a04fb25d774a2ca8273e9454fc1a13fe117703c9af2df8c71f519356ec02b5aa50abd72f442c1407900a28eb4d5c1b49c4779bd0527a83cdaba1535a80dcae637891f4e70a155405a5cac8c2ad81cc04012c5260cd0ecea61d63a742a52ce58e65aca69b13a04e2e41be6c68511486a7a380a74bb06f2fb542e4a383f496a83c098e4e71d5f1f69b5ae976a97fd8d74c22d051fbd68bdd8f7ec971e9a36b8e63588ed144491ac32576924f2b01bd9c3f646a0354e78c59bc5958c928cd2e6f0d8a839089b93037a196de0b2494b30f58b3f7d9438f9fddea525850c1f8568851cdd5cf29d14128ebaafbf9332aa7a5ebe8b325e6d48f36ef2c225956fee267f3093c92394ad001776ca0cf2e78db065d6fc8fafbb94f05ce0602b9f0577417629d31cea4b82b7d60d88105a532de15a0c9692d795429fe1b9425419344426fb09907f064f0e02398491d9bed84b46b9a30efb008f8a1475a6fb58645a3a641060d90a5b66c93b33eab367821ca0619380871e0b9d6472a057888c648046eddb671a8d8a14f18299469a6ea1297ccc02753b2fdab20b71a18ea29dc07f13bc971f103ef80c56d70e59aa9d9ab48992213900e7e1cc9b1732656532a3ca2517477888473d719715ca029ce9059c5028152b617ddbc5c65d6bdca3d417af75eea51cb089a632de29b0aac5d16fd876179013593b79f02575ec97d867da4901f94e1bed169a490cd8b6dadea7abe9ebe280b0a51c96bbe27ae09164f2bc16db35738ec64aad0285637f02d91811349282e7ca3a9628ef3b64316557f63a94b2ce5e2d2133e785b060b146fce050699ffdbf4de3af1171732cf1fc0a82df68fbcda2b9dc46507819022c1762fb093b62e8ad099a253e3becdbecb003ea02f902b6ff116c3d0cade3108acc226dc0d294f4d21cd97eb6116f15e0f0d12aa85df4236e9bdb0c93a2188c123170d8e7b12421ee7b941ac47e0244062ce1cd5143960f21598afd2a0ee75bf67ccada35b0c8a1880c23f4079ea8f270d2eb20e90dd07f138120018931c94cef373b41cdf6663015e150619e51c5a73e82a04dd1f92e495b17bad76cfbe508aa63b2516019555b9ac53d6ac5f1f1d601a63731459ba2a723d33540004a157e1ce7230d3146989b5b4fe3cbb054d164ab989e7fbc3bf2bdc4a0ca4deeaa65f83628ac3a1bae6e531f7616ceeb761f9805205c646c6863bc97f9183ea32d3f7adf792613ed0e40387fc612f4339125d7a0974a67e1957e6770f5538fd81e8b06ee8a45ab61255662483ec961e38cb1bea5a1457bc98c41de9f886fab51238ca1f00923ff7e5febfcb34ca74cc001822c197f7e6e441fa485736728981504a2c4237be04d3cec97f15edf31e04fb71bc898eccfe38a04005d9fe8493747082cecc03742ab17454d941c7c174571d6e4648b4b450f1b11d9acc07522a14cfdfef13435c079a22097673dead29ada6e0093a5c31209cc8f5333ef181e959aeb006511f0d468f2f8772e9b779624a6121bb1085e55ac76906058d009ccb6e03f414fffe61aaefb3466eca31b9328c9c34876c6c408d5084ef7a9e6a172b91c47d14e4a3ae24911f63687e42384110ad54f08f30b831708e0147908ab0f761bb75f1cc1fe439671fbecdf1674e0d669a987e1b83fc2aea300086b710c0e5a8b046e8be37c65a8ee46e884e33546b8ac0138f06c8c1290426e993954b8108da1ad07153c736a42a1514161738c11419c49ae65c4dfaf124e63b0d5e13cc9e18eca267f51aaf9a284e809a3646b1451b56d3cef6b7485eb54a136a5cc178e609364123c52963cf216080a7ea7013ac50990e9520f3a2277630d82929cc86e305633eca91cbe4daaf6c860d83fc0d9540b927c841fae9f7f59a6a37db7bb0f21d3b61a4a105f0de50908eaac9e01d6e846ac9b8cfae35d1c72cf54389f74c32127479370e2831ae62c6edd9553ac0e57e9d91387ef592526bc31fb2cacabd2d2dc902e6adeb6bda92f92ea1b8940a135e6e51f780b54841619cad7fc0489bd9a24ef000e439473372b8cb0d5ad66e332256704383f64398b1150a68bbce58042f80c4bdd366ec065a9176207cdef127bcc777f814f2f5163f2e4a8b71bd4d2a4b7061711e12e5bca07847697dd6e97eb6b51e99982629b91f216eef492d57dc944f3809d9506eb3e2498e0640e5e1a6feadf3f57ea11f6e85ecd2b5db2bb3456c572ae5221399303c7210f46b8c091cabbfbfda52cce5f91f692a0b13fe0305821e1c05d4f5d819b072eb11d6cc1409bc6c3b085bdc07c8d402a36b8f49bc4fc960f49a7e345f77c379c416fa8fbd1504eeed03303ba0fa4b12ab1979ba03e290a7a5d45cfb903ed03f9ae70ef9c181226ff65238d249ddeba495ff2a508ca13fea9e2fd0f906ac63221b5b09dc20567181add9560c00b0553f3caa4438b116a4d72199fc7c80310afa43e84a1f34c63866d3923ecb30cf1021d27eb8e12acd57b68bf832a04369c528672d2fd55e93348dcb5eea74b6ca3a65cfd7a16e7c90f5815eb113ec25945003a264cf5737a6a9bc10e76aa72816a92c7125b94f058390112da0c766419e0c02b7ad23ac47090ac171eec93a37491a3786c39182086a78888e836298a234cd03bff90696bf865b3194fdafa28c62a179e8575afa77cc9f267a3c3b6cbcc879fb7e6b9a9105c4c8187a4de4090306050741e32cfc2b2e10945e8221179872920fb779b0400272e252421f1709fda3e586d89b16f9a20624e74d8784535a90d2ea4aac28a9f38e1612304f4079a0ecb4a957e1f07154cca6949d0229b8d81be4ececd031afe587e4884434d86bf0e707a2be3eb1f49b1514593123a442d07133456e14494820ee93cad1249ee6c81090eefd634754a9ce968789b21e9052a96ccd6eaba07b0a8b87892cd00cd99fe05d8296adc28bc6ff0d2ab47ecb4af90cfac329846f562dbd6b4320e2b96df49195cacff280414123f0ad1c6b4892343293327beecc265d60cb776801e14860c7cd104d789537395a806aa86cc27f595f384038c57515dd2d0e1cd65492f71286704cb9f46a6d6b83c94bcbefaebc7787fcefa964488bb686761ef21019709837f569ba908c99fa4662281dddc607ca87e0fe4f39a25e0d7efe1c93a7e16a06a35226f1cebbef585d1fe8eb4e7e37e874564a40450b643143f82969595ac986dd78e250aa6256bb4557bfba19b6802960cd81f639189aa3609ae95e12d600f37da049a7def58f4e52c1d167bbfdbb878731c2f3e432f9f83b8065ac968d19370310626d48780d5d220c597fb6a08f185358436eb7a2d8d5ea96f259b808632021b49b0422b1d910c4a26284ad530607c8236cb0818f4f9e94a2583d8c2b0a9a340e41ba9a20682fc6eeaa860c53f521d1f43de9b21d72c81f33dc1513608197668039e803b9ae0663135c1aac10d7adce0672f79231f89f3e29ebfaa5cfef676bfa5072ee0fdd667d101ee3b1a9066360811474af65e5209c937eee6d56dac1fd1e07ebc36da47ac1881d44ca340b084f9040384f970fe6e88ec5b5daf5734d43e64bd22d0bb07394b9c987280316039822c31b6d66e4734ccaf5ea47042e84890f24bb40ea81a1f7fa852f0c1563c54613d0de83426a0eb9d81459083e021a58f3ad5cffd04c104287b45fa7f7027bb9b5d6f848b80e3283789ef5d00bca6587820ed06ac4b0468e6086aa00c0cf43f75abf28395d8c1f6a296828f66b63453d367fb3d3553d382f65a93d43c22f994a96e596528c0e6e01cc45d742d3738bd492ae7b336afe047d75e0220e47853b41157c30c71a9c944e9a8e9ea02ab23829f933f1c608d4210e164d48968a1f26aa18521b215efee85b1fbc3ff37768a55a0882a9473b2b2f7e25eebd556aac3b24703d40f555bd162a253bab9ad5d1f3dee2a07f8c5a0a0d2216c736a837ef576dbd70c176db47c20db837b30ec45f71bf0fe75e8190b4d52f78fdff9fadac9c1cb76e788d17fe946b33114602a655957f730b310a53e1b77411abc59351d71679cd36188159ba0500c790384e6bd2894bf795f99aa1397b76ee52a80d9620fb87317cbfa3c53734c3090e326a09d249ce49d205bbabebdedd95270075e18f3cda66119e6470ce292aaa85d110c830343e1053b60d310411e0b2c9b4592f67a44397cb612e511232e630f4d6418719b84a3d805787bcba3a594d9098eef9071c0759ea46cb1116213973eb105db49295d46afd84aaee48357ba79851ce566af5108b6d233f505f3d5650f9a0be69f98be22b30c882db263c1bf4ba34d045ed928e1ed61688ba3c16cd63f079451a4c9b06410eade6e0be2fe656d59514d322bb74aa5146973d9546ade82c9674d081517366f80db58144750cd02c83d4afbbbe100ee7af46e685f213513f67a3c1e71fb78b8aa4f315882875c63dc4a3824e75e3d82206e085f73e28ea3a5bb3942fe28b87acf8e7941dbfdf9741e7a4c19beca59654077e0cb09af6307aaa815e5f15738df0d69e001a33fae681a64a539296d56531606a02a78d86f306e8e2be303ec0a883b76d032d8b9c41292f0276450978719bb9223289cce0992c7052339b10899014bd603e275887f8f1acfe6e736c0cc8d80893bd0498093d1895e2821fee865432f35d5c707eb25cbed43e116da1b104ac139860bf01616bb64d04df6099906ab32320bec46b8c85fbcf90826942cef59cc543c5840d88311d0942e9ba0f4d717461aba1313be9a7004552a9935a33e42dac09412a8001161ef19293c725d1101b700c5a7aad97d507164e710c1413850adcbda1b00fddc6f734d600488c4cfbe8fa34360f3eb328c94d6d0a37a9878aeec869fe013a5a3ea2c81f9b9ee942b8556327eae181a507a90ac9f176494cab08c551d2590e30d95a2a64a21a6c0b5e49aee96e76f93861452135c7c1b85b84a86cab752480dfde25b29a4e20af2efe56a6aacea8b5c4d4b5aa930addf2d9f0d95ad44cfcc4f48f81ff04609afca9b460a37bc9e01883d64191358c587f3cbed65d5cfb12e28ce294294fd9c814b0eb03ca80ce95282c13da8f9179597e479d492831386ff1e6187531a33c02e5cdeff4e255a0148549ac9d68f0d1d9ff5110ab85e2862fc74be090dfea8e79611f094777b7395979a0f0645d0b5621a0b2737143aa7deacb247022801d840f297084ce209b46bb1aa48d5972de5ed0cb26c109aff41464e2708c7525a99ac08eedf02d51b0a419fa57cd8527a1ec8b5b39c6b92a45f75500d52521410331b64211c3ec889ee6f797b1aed29ef227040b28912b1b30e4d76abd711e9c909968a231a244da52633c94058bdd0a8e4a1cca888e3ec4d26c985b9ee1b0508e184fb28641f44430127a6394879bd24e8ab90ded634a7b4a3177ad68f5e36f64be5a5818fd4cb4d7c71e16e88290f880765bc5a35409a4d4452ce40a8b9ebfc0c89b21e8106a5cdbc578af8e325f74649fbd99e065506921f6b72f090bd6d729bbfcebf98a7a3cb55f3afbe24e341c13947d1115a671044047e8b47ee8bdb092ef776a8cefdc40f4de4d30c461cb463b29d2d3c2321e5394b10d5a09d1e658e04a652d3ec7514e6c216a286da6929fd4d7015fd8a52cd073864f11c58202b318040105672cd8e5446a6b5c4f54a8a980eaf82e02fa8d72a8ed18a6fcd81860723cd0460b6eb8c81cb19315dead7d7e8f7faa1cec08eaa52e7082ec6c1a925a7c8643a443db1d3eca0f3ae19ecb53a60792ef6bab5c7147b525f6266d8b7b2bfa16dcdfe62d5fe32169db3102e57a464a6148c62ebb9f307302dc666168eb23fbe5ba1ad3d50139c7d33de14599906cfc60bec2f133885b53f5cf2d6eae1813e4e5b60234537a1320f80792ad6b315ebcbe7b82d7756a54e73bb4b5b47a703c061010ec4fcc85e32082a657286e71ea23ca529b356e7ea4552cd60aed835b999f65f23608a9872b7bdff4cc05fae202935f9d22a953939c67e82e04319a4de94a651ae396bf3a735c7e72220ab1b988b1cd80f5262674bec179d37a23bc69ab3ae0b3a78a9fa4314d619a5b246be8dc99b92d1e78d1c64625fa01bafcf0f3f97c5448259a9326e033ab73740d269792d1bb0cdf84a22eb4127d01297cd1962825fdb9d33b71cdd2de8e3f1152d09639ccd29caa654bd629fe1380911d585cb46304a562ee18c8e8053413cc6496a7655360de489db88c65da6e2cdbf8814d08d825f127dfd2c2ed2c5e522bd6941c453d08bbfaa614b572bb9358b36dac071b240604b3aefdd0151e5b3a2d460099884fc1a62115d7c206013a9db1ce358a87f3be0f618a928f88a3eb967d4da9bd7490dcbecbbe9a48663f67a564bb8f478c13bdb2d1c27e866538e76ebebcfb4f86afaddf5757483eab0a277a8420c62caba15df6e974653ed40dfcf4ad7ad74d859cdd5eaa9a294171f9b92645e49753b323f0be9251fd39599ae9a11ea2fd2096e54e072987c6260809063d0d59e795f5121801f74c2525e024272c2cd6204993d6adb0938dd7000a21ff2102008f388606250753f02751421ba0bd655f5fc9d7894774db84ad7839f54f2054327a45e80930895f10d6857583d11517e23b5004016cc0eaba85d8429709ba4a54415866fe142acaa77244a08d0fd001b97a01129e6a9d4eeeeda12a7368c53642f18e73bdfe4054cfe75d0ca2f48d15a0bc6a8cf17de8f0d65d5c1a413c5f5d2ae22822160f05906ae636d29418ac2850a5fe9e9bf1b3ecf805c17f8fc83f6f0acc4a353bc667a1bf43be075b9626ca4d0c5ff06dbd84b318b6293cf6159eb25d4b431be462fe1d24ce7de8b9b5d6f9b2563a0b8f5d059328aa4bb3bce2504e43e0cc024a4f05345fe4053e3956ea421bf91cd6725eff928844cd4a7b13853c8a7f53c53480d53e53b29a42adaf9360a711fa3ba56c88b77c86d4d39f55d54a1cce39ed44d1541fe65309c9a4bb52ab8c1d03642801e863c8e41a8314aa07c9020b5b31b1a31a04d65465526e39b658c04087ff4b2a19737c04eadeb050b16efd70b43aa52b031585df1423d0b468c0003b5fc2d58c81b842cc994132fac2997c169b503e247e8154af06f0b88bb03e38a8d6f018cfdd3f9c35e97790a6879927f6d32e6aafabd47581f2bdc7bac3424bc5226a1e37e15d369bb562595ed9d5a96fe4e614caecb07039463f1b88cd0db19850316e01e8e708e3c5855b7e72a1d36e65074b5e67dd199d137875c3b38362a725c8ca6760ba37ec3bcb711022723b4afc34b37a8b7076ba60314ffac0e9b4284ef003cacc2f4484896b2493b68586002159f6caf6bb57c3053d2969ed8b35cb50cf2616c8f8f6e1ef8760a39e8e7f87e0a39f0d8df4f2147d7337c3b851c5dcff0ed14727453e18315029e9b7eb5c5c2cfda196918c116a60214194398ca7029b2f68355219fa5c94961c59db8eac122d6a163199733fe3d04e99a139520e404dae34638d38552b88b61a514cfad234ea23a8ae63c86e68ad9360ab9b0299d70e2c8711ba944ff666f9b58a876062f1bc123fd0fb2263c718566a2272a44f14c2185503f5abece5ee0dabad5d9805e9789b56c351048d6ca6392cf7cb6b73fb95ffd2825fcca5549593431020ea0b876d241465900b65b37b5fb336a8eb608ea573bfb5f0131013877c2c01da45c9a12603274c47a554ad94c12812a38a0140ff816c16e2ce4eca4a6379d0e951e9333c32987d84698440f5f2f70ee027cf10daf225385f8b4796eec443ca0faad61c55a64d79460e810ac93c9aa00fc3eb1c36ffc9f2dfc7dd42f9b2e3f0d0efeb1fce56b2546afdfb9fe9f2ffc3c96e498e01fe96be37c7dd130c8bfa3a377d86b3ba20b87cf39967e110a5238fcfbb0acdee0e5dfded28becd73f9d3b92a1a407571261c09f5fe94a238b70fdf797eee7af1d4acf5723c050da054a00efb5005fff06010e1f7f4f005cf1a924401cb5005fff1601428d06a69260be4280ebaa9705b8daab9b55e053610d7c49e6fceb5d8d3129ad74d87ce8dd47fa92780cbcfec3c96fc7ff455cbb1a2d4e1ebffb1aedf0672b99872f9bbda57b6510265f58f2e2837c6d05fbb5e516e59b1aa94b8f9fce7ebdfbda81f0f5575374bc02dbdfff377ff127fff6c7fffdd3dffdebbffcfadb4fffe3affedb7ffe4f7ffb5fffe39ffff4d77f1cdc5ffc34fdcd4f7ff9d35f3b6f8db1feead35d08831fc3b5032c4dce0fd7fbbc531a434a71f6e99337c97a132f3f8d31043f8d5f2e71f02e98d1cf3c4a33b9719846eb36befcbfffd5fffc2f7ffed37ff8f5b75f7efacb9f7ef9b33ffdfdfffaf5e75f7efdfd6f7ff8d7dffef04ffff8fb7ffbe55fffefcf7ff7dbdffef2c75f7ffbfd2f7ff897bffff9f7bffde197bffff9b7dffff20fbffeddbfffeeeffff8f3afcbdf07f70ffffcbbafbf99dffdbf7ffcf77ffeddcffff47f7effcbcffff4f31f7efd797ee79ffed95ffcc9ff0f0000ffff61b6466c", - "codeExpParam": "{\"image_id\":\"RANGE_ID\", \"elf\":\"RANGE_ELF\"}" -} \ No newline at end of file diff --git a/risc0-server/src/tests/hello_guest b/risc0-server/src/tests/hello_guest new file mode 100755 index 0000000..808107b Binary files /dev/null and b/risc0-server/src/tests/hello_guest differ diff --git a/risc0-server/src/tests/mock.rs b/risc0-server/src/tests/mock.rs deleted file mode 100644 index 158f5ac..0000000 --- a/risc0-server/src/tests/mock.rs +++ /dev/null @@ -1,29 +0,0 @@ -use std::{sync::atomic::{AtomicBool, Ordering}, thread, time::Duration}; - -use crate::start_grpc_server; - -pub struct Server { - pub started: AtomicBool, -} - -impl Server { - pub fn new() -> Server { - Server { - started: AtomicBool::new(false), - } - } - - pub async fn init_server(&mut self) { - if !self.started.load(Ordering::Relaxed) { - thread::spawn(move || { - let rt = tokio::runtime::Runtime::new().expect("runtime starts"); - rt.spawn(start_grpc_server("0.0.0.0:14001")); - loop { - thread::sleep(Duration::from_millis(100_000)); - } - }); - tokio::time::sleep(Duration::from_millis(100)).await; - self.started.store(true, Ordering::Relaxed); - } - } -} \ No newline at end of file diff --git a/risc0-server/src/tests/mod.rs b/risc0-server/src/tests/mod.rs deleted file mode 100644 index 9656f71..0000000 --- a/risc0-server/src/tests/mod.rs +++ /dev/null @@ -1,202 +0,0 @@ -use std::{env, fs::{self}, sync::RwLock}; - -use diesel::connection::SimpleConnection; -use lazy_static::lazy_static; -use rust_grpc::grpc::vm_runtime::{vm_runtime_client::VmRuntimeClient, CreateRequest, ExecuteRequest}; -use serde_json::Value; -use tonic::{transport::Channel, Request}; - -use crate::{db, tests::mock::Server}; - -mod mock; - -lazy_static! { - static ref SERVER: RwLock = RwLock::new(Server::new()); -} - -async fn init_db() { - env::set_var("DATABASE_URL", "postgres://test_user:test_passwd@127.0.0.1:15432/test?sslmode=disable"); - let init_sql = r#" - DROP TABLE IF EXISTS vms; - CREATE TABLE IF NOT EXISTS vms ( - id SERIAL PRIMARY KEY, - project_name VARCHAR NOT NULL, - elf TEXT NOT NULL, - image_id VARCHAR NOT NULL - ); - DROP TABLE IF EXISTS proofs; - CREATE TABLE IF NOT EXISTS proofs ( - id SERIAL PRIMARY KEY, - project_id VARCHAR NOT NULL, - task_id VARCHAR NOT NULL, - client_id VARCHAR NOT NULL, - sequencer_sign VARCHAR NOT NULL, - image_id VARCHAR NOT NULL, - datas_input VARCHAR NOT NULL, - receipt_type VARCHAR NOT NULL, - receipt TEXT, - status VARCHAR NOT NULL, - create_at TIMESTAMP NOT NULL DEFAULT now() - )"#; - let connection = &mut db::pgdb::establish_connection(); - connection.batch_execute(init_sql).unwrap(); - -} - -async fn init_real_server() { - let _ = init_db().await; - SERVER.write().unwrap().init_server().await; -} - -#[tokio::test] -async fn test_create_and_execute_e2e() { - init_real_server().await; - - // create client - let channel = Channel::from_static("http://127.0.0.1:14001") - .connect() - .await - .unwrap(); - let mut client = VmRuntimeClient::new(channel); - - // create vm instance - let file_content = fs::read_to_string("./src/tests/10000.json").unwrap(); - let v: Value = serde_json::from_str(&file_content).unwrap(); - let content = v["code"].as_str().unwrap().to_string(); - let exp_param = v["codeExpParam"].as_str().unwrap().to_string(); - let project_id: u64 = 10000; - - let req = Request::new(CreateRequest { - project_id, - content, - exp_param, - }); - - - let response = client.create(req).await; - match response { - Ok(_) => assert!(true), - Err(err) => { - println!("failed to create vm instance, {:?}", err); - assert!(false) - } - } - - // generate a proof - let req = Request::new(ExecuteRequest { - project_id, - task_id: 0u64, - client_id: "test_client_id".to_string(), - sequencer_signature: "test_sequencer_sign".to_string(), - datas: vec!["{\"private_input\":\"14\", \"public_input\":\"3,34\", \"receipt_type\":\"Stark\"}".to_string()], - }); - let response = client.execute(req).await; - match response { - Ok(_) => assert!(true), - Err(err) => { - println!("failed to executor vm instance, {:?}", err); - assert!(false) - } - } -} - -#[tokio::test] -async fn test_create_failed_e2e() { - init_real_server().await; - - // create client - let channel = Channel::from_static("http://127.0.0.1:14001") - .connect() - .await - .unwrap(); - let mut client = VmRuntimeClient::new(channel); - - // create vm instance - let file_content = fs::read_to_string("./src/tests/10000.json").unwrap(); - let v: Value = serde_json::from_str(&file_content).unwrap(); - let content = v["code"].as_str().unwrap().to_string(); - let exp_param = "".to_string(); - let project_id: u64 = 10000; - - let req = Request::new(CreateRequest { - project_id, - content, - exp_param, - }); - - - let response = client.create(req).await; - match response { - Ok(_) => (), - Err(err) => { - assert_eq!("need exp_param", err.message()); - } - } -} - -#[tokio::test] -async fn test_executor_failed_e2e() { - init_real_server().await; - - // create client - let channel = Channel::from_static("http://127.0.0.1:14001") - .connect() - .await - .unwrap(); - let mut client = VmRuntimeClient::new(channel); - - // create vm instance - let file_content = fs::read_to_string("./src/tests/10000.json").unwrap(); - let v: Value = serde_json::from_str(&file_content).unwrap(); - let content = v["code"].as_str().unwrap().to_string(); - let exp_param = v["codeExpParam"].as_str().unwrap().to_string(); - let project_id: u64 = 10000; - - let req = Request::new(CreateRequest { - project_id, - content, - exp_param, - }); - - - let response = client.create(req).await; - match response { - Ok(_) => assert!(true), - Err(err) => { - println!("failed to create vm instance, {:?}", err); - assert!(false) - } - } - - // datas is nil - let req = Request::new(ExecuteRequest { - project_id, - task_id: 0u64, - client_id: "test_client_id".to_string(), - sequencer_signature: "test_sequencer_sign".to_string(), - datas: vec![], - }); - let response = client.execute(req).await; - match response { - Ok(_) => (), - Err(err) => { - assert_eq!("need datas", err.message()) - } - } - - // project not found - let req = Request::new(ExecuteRequest { - project_id: 99999, - task_id: 0u64, - client_id: "test_client_id".to_string(), - sequencer_signature: "test_sequencer_sign".to_string(), - datas: vec!["{\"private_input\":\"14\", \"public_input\":\"3,34\", \"receipt_type\":\"Stark\"}".to_string()], - }); - let response = client.execute(req).await; - match response { - Ok(_) => (), - Err(err) => { - assert_eq!("99999 not found", err.message()) - } - } -} \ No newline at end of file diff --git a/risc0-server/src/tools/mod.rs b/risc0-server/src/tools/mod.rs deleted file mode 100644 index 095a814..0000000 --- a/risc0-server/src/tools/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub fn parse_elf_from_str(elf_str: &str) -> Vec { - let mut elf_cont: Vec = Vec::new(); - let vec_u8: Result, _> = elf_str - .split(",") - .into_iter() - .map(|s| s.trim().parse::()) - .collect(); - match vec_u8 { - Ok(v) => elf_cont = v, - Err(e) => println!("elf parse error: {}", e), - } - elf_cont -} \ No newline at end of file diff --git a/rust-grpc/Cargo.toml b/rust-grpc/Cargo.toml index 12496c3..1835790 100644 --- a/rust-grpc/Cargo.toml +++ b/rust-grpc/Cargo.toml @@ -6,9 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tonic = "0.8" -tonic-reflection = "0.6.0" -prost = "0.11" +tonic = "0.12.3" +prost = "0.13" [build-dependencies] -tonic-build = "0.8" +tonic-build = "0.12.3" diff --git a/rust-grpc/build.rs b/rust-grpc/build.rs index e3891c1..6153116 100644 --- a/rust-grpc/build.rs +++ b/rust-grpc/build.rs @@ -2,16 +2,15 @@ use std::env; use std::path::PathBuf; fn main() -> Result<(), Box> { - let proto_file = "../proto/vm_runtime.proto"; - let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + let proto_file = "../proto/vm_runtime.proto"; + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); - tonic_build::configure() - .protoc_arg("--experimental_allow_proto3_optional") // for older systems - .build_client(true) - .build_server(true) - .file_descriptor_set_path(out_dir.join("runtime_descriptor.bin")) - .out_dir("./src/grpc") - .compile(&[proto_file], &["../proto"])?; + tonic_build::configure() + .build_client(true) + .build_server(true) + .file_descriptor_set_path(out_dir.join("runtime_descriptor.bin")) + .out_dir("./src/grpc") + .compile_protos(&[proto_file], &["../proto"])?; - Ok(()) -} \ No newline at end of file + Ok(()) +} diff --git a/rust-grpc/src/grpc/mod.rs b/rust-grpc/src/grpc/mod.rs index 8a8cf61..e44013b 100644 --- a/rust-grpc/src/grpc/mod.rs +++ b/rust-grpc/src/grpc/mod.rs @@ -1 +1 @@ -pub mod vm_runtime; \ No newline at end of file +pub mod vm; diff --git a/rust-grpc/src/grpc/vm_runtime.rs b/rust-grpc/src/grpc/vm.rs similarity index 50% rename from rust-grpc/src/grpc/vm_runtime.rs rename to rust-grpc/src/grpc/vm.rs index f43247e..e941121 100644 --- a/rust-grpc/src/grpc/vm_runtime.rs +++ b/rust-grpc/src/grpc/vm.rs @@ -1,62 +1,65 @@ -#[allow(clippy::derive_partial_eq_without_eq)] +// This file is @generated by prost-build. #[derive(Clone, PartialEq, ::prost::Message)] -pub struct CreateRequest { +pub struct NewProjectRequest { #[prost(uint64, tag = "1")] pub project_id: u64, #[prost(string, tag = "2")] - pub content: ::prost::alloc::string::String, - #[prost(string, tag = "3")] - pub exp_param: ::prost::alloc::string::String, + pub project_version: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "3")] + pub binary: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "4")] + pub metadata: ::prost::alloc::vec::Vec, } -#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, Copy, PartialEq, ::prost::Message)] +pub struct NewProjectResponse {} #[derive(Clone, PartialEq, ::prost::Message)] -pub struct CreateResponse {} -#[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] -pub struct ExecuteRequest { +pub struct ExecuteTaskRequest { #[prost(uint64, tag = "1")] pub project_id: u64, - #[prost(uint64, tag = "2")] - pub task_id: u64, - #[prost(string, tag = "3")] - pub client_id: ::prost::alloc::string::String, - #[prost(string, tag = "4")] - pub sequencer_signature: ::prost::alloc::string::String, - #[prost(string, repeated, tag = "5")] - pub datas: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag = "2")] + pub project_version: ::prost::alloc::string::String, + #[prost(bytes = "vec", tag = "3")] + pub task_id: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", repeated, tag = "4")] + pub payloads: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, } -#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct ExecuteResponse { +pub struct ExecuteTaskResponse { #[prost(bytes = "vec", tag = "1")] pub result: ::prost::alloc::vec::Vec, } /// Generated client implementations. -pub mod vm_runtime_client { - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] +pub mod vm_client { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] use tonic::codegen::*; use tonic::codegen::http::Uri; #[derive(Debug, Clone)] - pub struct VmRuntimeClient { + pub struct VmClient { inner: tonic::client::Grpc, } - impl VmRuntimeClient { + impl VmClient { /// Attempt to create a new client by connecting to a given endpoint. pub async fn connect(dst: D) -> Result where - D: std::convert::TryInto, + D: TryInto, D::Error: Into, { let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; Ok(Self::new(conn)) } } - impl VmRuntimeClient + impl VmClient where T: tonic::client::GrpcService, T::Error: Into, - T::ResponseBody: Body + Send + 'static, - ::Error: Into + Send, + T::ResponseBody: Body + std::marker::Send + 'static, + ::Error: Into + std::marker::Send, { pub fn new(inner: T) -> Self { let inner = tonic::client::Grpc::new(inner); @@ -69,7 +72,7 @@ pub mod vm_runtime_client { pub fn with_interceptor( inner: T, interceptor: F, - ) -> VmRuntimeClient> + ) -> VmClient> where F: tonic::service::Interceptor, T::ResponseBody: Default, @@ -81,9 +84,9 @@ pub mod vm_runtime_client { >, , - >>::Error: Into + Send + Sync, + >>::Error: Into + std::marker::Send + std::marker::Sync, { - VmRuntimeClient::new(InterceptedService::new(inner, interceptor)) + VmClient::new(InterceptedService::new(inner, interceptor)) } /// Compress requests with the given encoding. /// @@ -100,79 +103,113 @@ pub mod vm_runtime_client { self.inner = self.inner.accept_compressed(encoding); self } - pub async fn create( + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_decoding_message_size(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.inner = self.inner.max_encoding_message_size(limit); + self + } + pub async fn new_project( &mut self, - request: impl tonic::IntoRequest, - ) -> Result, tonic::Status> { + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { self.inner .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; let codec = tonic::codec::ProstCodec::default(); - let path = http::uri::PathAndQuery::from_static( - "/vm_runtime.VmRuntime/Create", - ); - self.inner.unary(request.into_request(), path, codec).await + let path = http::uri::PathAndQuery::from_static("/vm.VM/NewProject"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("vm.VM", "NewProject")); + self.inner.unary(req, path, codec).await } - pub async fn execute( + pub async fn execute_task( &mut self, - request: impl tonic::IntoRequest, - ) -> Result, tonic::Status> { + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { self.inner .ready() .await .map_err(|e| { - tonic::Status::new( - tonic::Code::Unknown, + tonic::Status::unknown( format!("Service was not ready: {}", e.into()), ) })?; let codec = tonic::codec::ProstCodec::default(); - let path = http::uri::PathAndQuery::from_static( - "/vm_runtime.VmRuntime/Execute", - ); - self.inner.unary(request.into_request(), path, codec).await + let path = http::uri::PathAndQuery::from_static("/vm.VM/ExecuteTask"); + let mut req = request.into_request(); + req.extensions_mut().insert(GrpcMethod::new("vm.VM", "ExecuteTask")); + self.inner.unary(req, path, codec).await } } } /// Generated server implementations. -pub mod vm_runtime_server { - #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] +pub mod vm_server { + #![allow( + unused_variables, + dead_code, + missing_docs, + clippy::wildcard_imports, + clippy::let_unit_value, + )] use tonic::codegen::*; - /// Generated trait containing gRPC methods that should be implemented for use with VmRuntimeServer. + /// Generated trait containing gRPC methods that should be implemented for use with VmServer. #[async_trait] - pub trait VmRuntime: Send + Sync + 'static { - async fn create( + pub trait Vm: std::marker::Send + std::marker::Sync + 'static { + async fn new_project( &self, - request: tonic::Request, - ) -> Result, tonic::Status>; - async fn execute( + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; + async fn execute_task( &self, - request: tonic::Request, - ) -> Result, tonic::Status>; + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; } #[derive(Debug)] - pub struct VmRuntimeServer { - inner: _Inner, + pub struct VmServer { + inner: Arc, accept_compression_encodings: EnabledCompressionEncodings, send_compression_encodings: EnabledCompressionEncodings, + max_decoding_message_size: Option, + max_encoding_message_size: Option, } - struct _Inner(Arc); - impl VmRuntimeServer { + impl VmServer { pub fn new(inner: T) -> Self { Self::from_arc(Arc::new(inner)) } pub fn from_arc(inner: Arc) -> Self { - let inner = _Inner(inner); Self { inner, accept_compression_encodings: Default::default(), send_compression_encodings: Default::default(), + max_decoding_message_size: None, + max_encoding_message_size: None, } } pub fn with_interceptor( @@ -196,12 +233,28 @@ pub mod vm_runtime_server { self.send_compression_encodings.enable(encoding); self } + /// Limits the maximum size of a decoded message. + /// + /// Default: `4MB` + #[must_use] + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { + self.max_decoding_message_size = Some(limit); + self + } + /// Limits the maximum size of an encoded message. + /// + /// Default: `usize::MAX` + #[must_use] + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { + self.max_encoding_message_size = Some(limit); + self + } } - impl tonic::codegen::Service> for VmRuntimeServer + impl tonic::codegen::Service> for VmServer where - T: VmRuntime, - B: Body + Send + 'static, - B::Error: Into + Send + 'static, + T: Vm, + B: Body + std::marker::Send + 'static, + B::Error: Into + std::marker::Send + 'static, { type Response = http::Response; type Error = std::convert::Infallible; @@ -209,78 +262,91 @@ pub mod vm_runtime_server { fn poll_ready( &mut self, _cx: &mut Context<'_>, - ) -> Poll> { + ) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: http::Request) -> Self::Future { - let inner = self.inner.clone(); match req.uri().path() { - "/vm_runtime.VmRuntime/Create" => { + "/vm.VM/NewProject" => { #[allow(non_camel_case_types)] - struct CreateSvc(pub Arc); - impl tonic::server::UnaryService - for CreateSvc { - type Response = super::CreateResponse; + struct NewProjectSvc(pub Arc); + impl tonic::server::UnaryService + for NewProjectSvc { + type Response = super::NewProjectResponse; type Future = BoxFuture< tonic::Response, tonic::Status, >; fn call( &mut self, - request: tonic::Request, + request: tonic::Request, ) -> Self::Future { - let inner = self.0.clone(); - let fut = async move { (*inner).create(request).await }; + let inner = Arc::clone(&self.0); + let fut = async move { + ::new_project(&inner, request).await + }; Box::pin(fut) } } let accept_compression_encodings = self.accept_compression_encodings; let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; - let method = CreateSvc(inner); + let method = NewProjectSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( accept_compression_encodings, send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, ); let res = grpc.unary(method, req).await; Ok(res) }; Box::pin(fut) } - "/vm_runtime.VmRuntime/Execute" => { + "/vm.VM/ExecuteTask" => { #[allow(non_camel_case_types)] - struct ExecuteSvc(pub Arc); - impl tonic::server::UnaryService - for ExecuteSvc { - type Response = super::ExecuteResponse; + struct ExecuteTaskSvc(pub Arc); + impl tonic::server::UnaryService + for ExecuteTaskSvc { + type Response = super::ExecuteTaskResponse; type Future = BoxFuture< tonic::Response, tonic::Status, >; fn call( &mut self, - request: tonic::Request, + request: tonic::Request, ) -> Self::Future { - let inner = self.0.clone(); - let fut = async move { (*inner).execute(request).await }; + let inner = Arc::clone(&self.0); + let fut = async move { + ::execute_task(&inner, request).await + }; Box::pin(fut) } } let accept_compression_encodings = self.accept_compression_encodings; let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; let inner = self.inner.clone(); let fut = async move { - let inner = inner.0; - let method = ExecuteSvc(inner); + let method = ExecuteTaskSvc(inner); let codec = tonic::codec::ProstCodec::default(); let mut grpc = tonic::server::Grpc::new(codec) .apply_compression_config( accept_compression_encodings, send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, ); let res = grpc.unary(method, req).await; Ok(res) @@ -289,40 +355,39 @@ pub mod vm_runtime_server { } _ => { Box::pin(async move { - Ok( - http::Response::builder() - .status(200) - .header("grpc-status", "12") - .header("content-type", "application/grpc") - .body(empty_body()) - .unwrap(), - ) + let mut response = http::Response::new(empty_body()); + let headers = response.headers_mut(); + headers + .insert( + tonic::Status::GRPC_STATUS, + (tonic::Code::Unimplemented as i32).into(), + ); + headers + .insert( + http::header::CONTENT_TYPE, + tonic::metadata::GRPC_CONTENT_TYPE, + ); + Ok(response) }) } } } } - impl Clone for VmRuntimeServer { + impl Clone for VmServer { fn clone(&self) -> Self { let inner = self.inner.clone(); Self { inner, accept_compression_encodings: self.accept_compression_encodings, send_compression_encodings: self.send_compression_encodings, + max_decoding_message_size: self.max_decoding_message_size, + max_encoding_message_size: self.max_encoding_message_size, } } } - impl Clone for _Inner { - fn clone(&self) -> Self { - Self(self.0.clone()) - } - } - impl std::fmt::Debug for _Inner { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.0) - } - } - impl tonic::server::NamedService for VmRuntimeServer { - const NAME: &'static str = "vm_runtime.VmRuntime"; + /// Generated gRPC service name + pub const SERVICE_NAME: &str = "vm.VM"; + impl tonic::server::NamedService for VmServer { + const NAME: &'static str = SERVICE_NAME; } }