Substrate Bitcoin-Like Blockchain Introduction

This repository is derived from Academy-PoW, originally designed as a learning resource. While implementing a Bitcoin-like blockchain, I faced several challenges that required updates and fixes to ensure smooth execution. Additionally, I transitioned the account model from an Account-based system to a UTXO-based approach. This implementation builds upon the foundational work from Building a UTXO Chain from Scratch | Substrate Seminar. Inspired by this resource, I aimed to further enhance the project, incorporating my own insights and improvements.

Prerequisites

Before starting this interactive tutorial, you should have a basic understanding of Substrate and FRAME development. If you're new to these concepts, it's highly recommended to complete the introductory Substrate tutorials available in the official documentation. For example Substrate Interactive Tutorial - Polkadot Study.

Useful Resources

Here are some essential resources that will assist you throughout this tutorial:

By following these resources, you’ll gain a solid foundation in Substrate development, enabling you to make the most of this tutorial. 🚀

Overview of Bitcoin-like Blockchain in Substrate we will be building:

graph TD;
    subgraph UTXO_Runtime
        Timestamp -->|Time trait| Difficulty
        Block_Author -->|BlockAuthor| UTXO
        Bitcoin_Halving --> |Issuance| UTXO
        FRAME_System

        subgraph Difficulty
            Sha3_Difficulty
            Keccak_Difficulty
            Md5_Difficulty
        end
    end

    subgraph UTXO_Node
        subgraph Multi_PoW_Consensus
            Sha3_Algorithm
            Keccak_Algorithm
            Md5_Algorithm
        end

        Tx_Pool
    end

    Difficulty --> Difficulty_API{{Difficulty API}}
    Difficulty_API --> Multi_PoW_Consensus
    UTXO --> Tx_Pool_API{{Tx Pool API}}
    Tx_Pool_API --> Tx_Pool

Initialize your project

Clone the repository

git clone -b start_here https://github.com/danielbui12/substrate-bitcoin-like-blockchain

Build your project

Let's build your project to verify that your new project is working as expected by running:

cd substrate-bitcoin-like-blockchain
cargo build --release

After build success, please run the node by following command:

❯ ./target/release/academy-pow --dev --tmp
2025-02-10 10:34:04 Academy PoW Chain    
2025-02-10 10:34:04 ✌️  version 3.0.0-3289a2a2d00    
2025-02-10 10:34:04 ❤️  by @danielbui12, 2025-2025    
2025-02-10 10:34:04 📋 Chain specification: Development    
2025-02-10 10:34:04 🏷  Node name: broken-class-8644    
2025-02-10 10:34:04 👤 Role: AUTHORITY    
2025-02-10 10:34:04 💾 Database: ParityDb at /var/folders/n1/4b940c8s1qddng2m8xgxwb280000gn/T/substratea5r5zS/chains/dev/paritydb/full    
2025-02-10 10:34:04 🔨 Initializing Genesis block/state (state: 0x6118…d3ad, header-hash: 0xad3e…d8b4)    
2025-02-10 10:34:04 Using default protocol ID "sup" because none is configured in the chain specs    
2025-02-10 10:34:04 Local node identity is: 12D3KooWQjFVngak2ZeaiTkBonVp5Ju69HGEowLubf7VFWyctFDC    
2025-02-10 10:34:04 Running litep2p network backend    
2025-02-10 10:34:04 💻 Operating system: macos    
2025-02-10 10:34:04 💻 CPU architecture: aarch64    
2025-02-10 10:34:04 📦 Highest known block at #0    
2025-02-10 10:34:04 〽️ Prometheus exporter started at 127.0.0.1:9615    
2025-02-10 10:34:04 Running JSON-RPC server: addr=127.0.0.1:9944, allowed origins=["*"]    
2025-02-10 10:34:09 💤 Idle (0 peers), best: #0 (0xad3e…d8b4), finalized #0 (0xad3e…d8b4), ⬇ 0 ⬆ 0    
2025-02-10 10:34:14 💤 Idle (0 peers), best: #0 (0xad3e…d8b4), finalized #0 (0xad3e…d8b4), ⬇ 0 ⬆ 0    
2025-02-10 10:34:14 🙌 Starting consensus session on top of parent 0xad3e45470dd74feceeecf2e11a9bb18ed97c813c53af0160baea0b81d23fd8b4 (#0)    
2025-02-10 10:34:14 🎁 Prepared block for proposing at 1 (2 ms) [hash: 0x4544f634084a6ffad3b6fa3727ad5710bf28337851b003b4d3d14844e7e33ab8; parent_hash: 0xad3e…d8b4; extrinsics (2): [0x1eb2…66b0, 0x6591…3bcd]    
2025-02-10 10:34:16 ✅ Successfully mined block on top of: 0xad3e…d8b4    
2025-02-10 10:34:16 🏆 Imported #1 (0xad3e…d8b4 → 0xe8ee…1ced)    
2025-02-10 10:34:16 🙌 Starting consensus session on top of parent 0xe8eefcc3db4ef32c68907833966ee0fc128098de624b5589409dc0a50dd41ced (#1)    
2025-02-10 10:34:16 🎁 Prepared block for proposing at 2 (0 ms) [hash: 0x05b04b1396c7498daf210e8aa512ee1878e083e38b43ddac12be7162e28e6cea; parent_hash: 0xe8ee…1ced; extrinsics (2): [0x132e…94eb, 0x6591…3bcd]    
2025-02-10 10:34:19 ✅ Successfully mined block on top of: 0xe8ee…1ced    
2025-02-10 10:34:19 🏆 Imported #2 (0xe8ee…1ced → 0x4481…c80e)    
2025-02-10 10:34:19 🙌 Starting consensus session on top of parent 0x44812abaf4045df92c9708468fa043274bbf94bfd951c20805411cef23b6c80e (#2)    
2025-02-10 10:34:19 🎁 Prepared block for proposing at 3 (0 ms) [hash: 0x04f45b59da4afd41d800d2b24edbaa607d71ab7ee153b92abe6ab86d1d822284; parent_hash: 0x4481…c80e; extrinsics (2): [0x82b2…48d4, 0x6591…3bcd]    
2025-02-10 10:34:19 💤 Idle (0 peers), best: #2 (0x4481…c80e), finalized #0 (0xad3e…d8b4), ⬇ 0 ⬆ 0

✅ If you see the above output, then your project is ready to be used. You can now proceed to the next step.

[profile.release]
panic = "unwind"

[workspace]
members = [
	"node",
	"runtime",
	"multi-pow",
]
resolver = "2"

[workspace.dependencies]

# Crates.io dependencies
async-trait = { version = "0.1.53" }
clap = { version = "4.5.3" }
futures = { version = "0.3.30" }
hex = "0.4"
hex-literal = "0.4.1"
jsonrpsee = { version = "0.23.2" }
log = "0.4.25"
md5 = "0.7.0"
parity-scale-codec = { version = "3.1.2", features = [ "derive" ], default-features = false }
rand = { version = "0.8.5", features = [ "small_rng" ] }
scale-info = { version = "2.11.1", default-features = false }
serde = "1.0.137"
serde_json = { version = "1.0.114", default-features = false }
sha3 = "0.10.1"

# Local Dependencies
academy-pow-runtime = { path = "../runtime" }
multi-pow = { default-features = false, path = "../multi-pow" }

# Polkadot SDK Dependencies
frame-executive = { version = "37.0.0", default-features = false }
frame-support = { version = "37.0.0", default-features = false }
frame-system = { version = "37.0.0", default-features = false }
frame-system-rpc-runtime-api = { version = "34.0.0", default-features = false }
pallet-balances = { version = "38.0.0", default-features = false }
pallet-timestamp = { version = "36.0.0", default-features = false }
pallet-transaction-payment = { version = "37.0.0", default-features = false }
pallet-transaction-payment-rpc = { version = "40.0.0" }
pallet-transaction-payment-rpc-runtime-api = { version = "37.0.0", default-features = false }
sc-basic-authorship = { version = "0.44.0" }
sc-chain-spec = { version = "37.0.0" }
sc-cli = { version = "0.46.0", default-features = false }
sc-client-api = { version = "37.0.0" }
sc-consensus = { version = "0.43.0" }
sc-consensus-manual-seal = { version = "0.45.0" }
sc-consensus-pow = { version = "0.43.0" }
sc-executor = { version = "0.40.0" }
sc-network = { version = "0.44.0" }
sc-rpc-api = { version = "0.43.0" }
sc-service = { version = "0.45.0", default-features = false }
sc-telemetry = { version = "24.0.0" }
sc-transaction-pool = { version = "37.0.0" }
sc-transaction-pool-api = { version = "37.0.0" }
sp-api = { version = "34.0.0", default-features = false }
sp-block-builder = { version = "34.0.0", default-features = false }
sp-blockchain = { version = "37.0.0" }
sp-consensus = { version = "0.40.0" }
sp-consensus-pow = { version = "0.40.0", default-features = false }
sp-core = { version = "34.0.0", default-features = false }
sp-genesis-builder = { version = "0.15.0", default-features = false }
sp-inherents = { version = "34.0.0", default-features = false }
sp-io = { version = "38.0.0", default-features = false }
sp-keyring = { version = "39.0.0" }
sp-keystore = { version = "0.40.0" }
sp-offchain = { version = "34.0.0", default-features = false }
sp-runtime = { version = "39.0.0", default-features = false }
sp-session = { version = "35.0.0", default-features = false }
sp-std = { version = "14.0.0", default-features = false }
sp-timestamp = { version = "34.0.0" }
sp-transaction-pool = { version = "34.0.0", default-features = false }
sp-version = { version = "37.0.0", default-features = false }
substrate-build-script-utils = { version = "11.0.0", default-features = false }
substrate-frame-rpc-system = { version = "38.0.0" }
substrate-wasm-builder = { version = "24.0.0", default-features = false }
This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org>
[package]
authors = [ "@danielbui12" ]
description = "a concrete Substrate PoW algorithm that supports multiple hashing algorithms"
edition = "2021"
name = "multi-pow"
version = "3.0.0"

[dependencies]
md5 = { workspace = true }
parity-scale-codec = { workspace = true }
scale-info = { workspace = true }
sha3 = { workspace = true, optional = true }

sc-client-api = { optional = true, workspace = true }
sc-consensus-pow = { optional = true, workspace = true }
sp-api = { workspace = true }
sp-consensus-pow = { workspace = true }
sp-core = { workspace = true }
sp-runtime = { workspace = true }

log = { workspace = true }

[features]
default = [ "std" ]
std = [
	"sha3",
	"sc-consensus-pow",
	"sc-client-api",
]
#![allow(unused)]
fn main() {
//! This crate represents a concrete Substrate PoW algorithm.
//!
//! It is multi-pow in the sense that there are multiple supported hashing algorithms.
//! A seal with any of the supported hashing algorithms will be accepted.
//!
//! The purpose of this design is to demonstrate hard and soft forks by adding and removing valid hashing algorithms.
//! While there is no precedent for changing hashing algorithms in the real world yet, it is conceivable that
//! a chain may want to upgrade to a new algorithm when the old one is suspected weak.
//! In any case, the point is that we want to demonstrate hard and soft forks in an understandable way,
//! the multiple hashing algorithms achieves that well.
//!
//! In the future, the hope is that there will be a dedicated difficulty threshold for each hashing algorithm.
//! But currently the Substrate PoW crates are not that flexible.
//! We could solve it by adding a pre-digest that includes information about what hashing algo is being used
//! for the runtime to use later in the difficulty adjustment.

#![cfg_attr(not(feature = "std"), no_std)]

use core::str::FromStr;
#[cfg(feature = "std")]
use std::sync::Arc;

use parity_scale_codec::{Decode, Encode};
#[cfg(feature = "std")]
use sc_consensus_pow::{Error, PowAlgorithm};
#[cfg(feature = "std")]
use sha3::{Digest, Keccak256, Sha3_256};
#[cfg(feature = "std")]
use sp_api::ProvideRuntimeApi;
#[cfg(feature = "std")]
use sp_consensus_pow::DifficultyApi;
#[cfg(feature = "std")]
use sp_consensus_pow::Seal as RawSeal;
use sp_consensus_pow::TotalDifficulty;
use sp_core::{H256, U256};
#[cfg(feature = "std")]
use sp_runtime::generic::BlockId;
#[cfg(feature = "std")]
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};

/// A struct that represents a difficulty threshold.
/// Unlike a normal PoW algorithm this struct has a separate threshold for each hash
#[derive(
    Clone,
    Copy,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Encode,
    Decode,
    Debug,
    Default,
    scale_info::TypeInfo,
)]
pub struct Threshold {
    pub md5: U256,
    pub sha3: U256,
    pub keccak: U256,
}

// This trait does not seem to be fully baked in the Substrate PoW code
// But we do need some kind of sinsible impl here so the node can import blocks.
// so I will not use it for now.
impl TotalDifficulty for Threshold {
    fn increment(&mut self, other: Threshold) {
        self.md5 += other.md5;
        self.sha3 += other.sha3;
        self.keccak += other.keccak;
    }
}

/// An enum that represents the supported hash types
#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, Debug)]
pub enum SupportedHashes {
    Md5,
    Sha3,
    Keccak,
}

impl Default for SupportedHashes {
    fn default() -> Self {
        Self::Sha3
    }
}

/// A struct that represents a concrete hash value tagged with what hashing
///  algorithm was used to compute it.
#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, Debug, Default)]
pub struct MultiHash {
    pub algo: SupportedHashes,
    pub value: H256,
}

/// Determine whether the given hash satisfies the given difficulty.
/// The test is done by multiplying the two together. If the product
/// overflows the bounds of U256, then the product (and thus the hash)
/// was too high.
pub fn simple_hash_meets_difficulty(hash: &H256, difficulty: U256) -> bool {
    let num_hash = U256::from_little_endian(&hash[..]);
    let (_, overflowed) = num_hash.overflowing_mul(difficulty);

    !overflowed
}

pub fn multi_hash_meets_difficulty(hash: &MultiHash, difficulty: Threshold) -> bool {
    match hash.algo {
        SupportedHashes::Md5 => simple_hash_meets_difficulty(&hash.value, difficulty.md5),
        SupportedHashes::Sha3 => simple_hash_meets_difficulty(&hash.value, difficulty.sha3),
        SupportedHashes::Keccak => simple_hash_meets_difficulty(&hash.value, difficulty.keccak),
    }
}

/// A Seal struct that will be encoded to a Vec<u8> as used as the
/// `RawSeal` type.
#[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)]
pub struct Seal {
    pub work: MultiHash,
    pub difficulty: Threshold,
    pub nonce: U256,
}

/// A not-yet-computed attempt to solve the proof of work. Calling the
/// compute method will compute the hash and return the seal.
#[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)]
pub struct Compute {
    pub difficulty: Threshold,
    pub pre_hash: H256,
    pub nonce: U256,
}

#[cfg(feature = "std")]
impl Compute {
    pub fn compute(self, algo: SupportedHashes) -> Seal {
        let value = match algo {
            SupportedHashes::Md5 => {
                // The md5 is only 16 byte output, so we just concatenate it twice to
                // get an H256
                let bytes = *md5::compute(&self.encode()[..]);
                let mut doubled = [0u8; 32];
                doubled[0..16].copy_from_slice(&bytes[0..16]);
                doubled[16..32].copy_from_slice(&bytes[0..16]);

                H256::from(doubled)
            }
            SupportedHashes::Sha3 => {
                H256::from_slice(Sha3_256::digest(&self.encode()[..]).as_slice())
            }
            SupportedHashes::Keccak => {
                H256::from_slice(Keccak256::digest(&self.encode()[..]).as_slice())
            }
        };

        Seal {
            nonce: self.nonce,
            difficulty: self.difficulty,
            work: MultiHash { algo, value },
        }
    }
}

#[cfg(feature = "std")]
/// A complete PoW Algorithm that uses multiple hashing algorithms.
/// Needs a reference to the client so it can grab the difficulty from the runtime.
pub struct MultiPow<C> {
    client: Arc<C>,
    fork_config: ForkingConfig,
}

#[cfg(feature = "std")]
impl<C> MultiPow<C> {
    pub fn new(client: Arc<C>, fork_config: ForkingConfig) -> Self {
        Self {
            client,
            fork_config,
        }
    }
}

//TODO could maybe derive clone_no_bound
#[cfg(feature = "std")]
impl<C> Clone for MultiPow<C> {
    fn clone(&self) -> Self {
        Self::new(self.client.clone(), self.fork_config)
    }
}

// Here we implement the general PowAlgorithm trait for our concrete algorithm.
#[cfg(feature = "std")]
impl<B: BlockT<Hash = H256>, C> PowAlgorithm<B> for MultiPow<C>
where
    C: ProvideRuntimeApi<B>,
    C::Api: DifficultyApi<B, Threshold>,
    C: sc_client_api::HeaderBackend<B>,
{
    type Difficulty = Threshold;

    fn difficulty(&self, parent: B::Hash) -> Result<Self::Difficulty, Error<B>> {
        let difficulty = self
            .client
            .runtime_api()
            .difficulty(parent)
            .map_err(|err| {
                sc_consensus_pow::Error::Environment(format!(
                    "Fetching difficulty from runtime failed: {:?}",
                    err
                ))
            })?;

        Ok(difficulty)
    }

    fn verify(
        &self,
        parent_id: &BlockId<B>,
        pre_hash: &H256,
        pre_digest: Option<&[u8]>,
        seal: &RawSeal,
        difficulty: Self::Difficulty,
    ) -> Result<bool, Error<B>> {
        // Try to construct a seal object by decoding the raw seal given
        let seal = match Seal::decode(&mut &seal[..]) {
            Ok(seal) => seal,
            Err(_) => return Ok(false),
        };

        log::debug!("✅ Decode seal passed!");

        let Some(_encoded_pre_digest) = pre_digest else {
            return Ok(false);
        };

        log::debug!("✅ Checksum digest passed!");

        // // TODO idk why this always return md5 only
        // let algo_from_predigest = match SupportedHashes::decode(&mut &encoded_pre_digest[..]) {
        //     Ok(algo) => algo,
        //     Err(_) => return Ok(false),
        // };

        // log::debug!("✅ Get algorithm from digest passed!");

        // // Check that the pre-digest algo matches the seal algo
        // // TODO it shouldn't be necessary to have both.
        // if seal.work.algo != algo_from_predigest {
        //     return Ok(false);
        // }

        // log::debug!("✅ Checksum algorithm from seal passed!");

        // This is where we handle forks on the verification side.
        // We will still need to handle it in the mining algorithm somewhere.
        // Currently we make the miner configure what algo they mine manually with their cli.
        let parent_number: u32 = match parent_id {
            BlockId::Hash(h) => *self
                .client
                .header(*h)
                .expect("Database should perform lookup successfully")
                .expect("parent header should be present in the db")
                .number(),
            BlockId::Number(n) => *n,
        }
        .try_into()
        .map_err(|_| ())
        .expect("Block numbers can be converted to u32 (because they are u32)");

        log::debug!("✅ Checksum parent block number passed!");

        // Here we handle the forking logic according the the node operator's request.
        let valid_algorithm = match self.fork_config {
            ForkingConfig::Manual => manual_fork_validation(parent_number, seal.work.algo),
            ForkingConfig::Automatic(fork_heights, maxi_position) => {
                auto_fork_validation(parent_number, seal.work.algo, fork_heights, maxi_position)
            }
        };

        if !valid_algorithm {
            return Ok(false);
        }

        log::debug!("✅ Valid algorithm!");

        // See whether the hash meets the difficulty requirement. If not, fail fast.
        if !multi_hash_meets_difficulty(&seal.work, difficulty) {
            return Ok(false);
        }

        log::debug!("✅ Checksum difficulty passed!");

        // Make sure the provided work actually comes from the correct pre_hash
        let compute = Compute {
            difficulty,
            pre_hash: *pre_hash,
            nonce: seal.nonce,
        };

        if compute.compute(seal.work.algo) != seal {
            return Ok(false);
        }

        log::debug!("✅ Re-compute passed!");

        log::debug!("🛠️ All passed, append the block to the chain ...");

        Ok(true)
    }
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
///
pub struct ForkHeights {
    /// The block height to perform the soft fork that adds sha3 and keccak support.
    pub add_sha3_keccak: u32,
    /// The block height to perform the hard fork that removes md5 support.
    pub remove_md5: u32,
    /// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
    pub split_sha3_keccak: u32,
}

/// Various political positions a node could take when the network is forking into
/// keccak maxis and sha3 maxis
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum MaxiPosition {
    /// Allow all blocks, both sha3 and keccak
    NoMaxi,
    /// Only allow sha3 blocks
    Sha3Maxi,
    /// Only allow keccak blocks
    KeccakMaxi,
    /// Only allow a single type of blocks. Which type it is is determined by what algo the node is mining.
    FollowMining,
}

#[derive(Copy, Clone, Eq, PartialEq)]
/// The actual properly typed config after we're done working around all the BS.
pub enum ForkingConfig {
    ///
    Manual,
    ///
    Automatic(ForkHeights, MaxiPosition),
}

impl FromStr for MaxiPosition {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(match &s.to_lowercase()[..] {
            "allow-all" | "allowall" | "no-maxi" | "nomaxi" => Self::NoMaxi,
            "sha3-maxi" | "sha3maxi" => Self::Sha3Maxi,
            "keccak-maxi" | "keccakmaxi" => Self::KeccakMaxi,
            _ => Self::FollowMining,
        })
    }
}

/// Manual mode, the node operator manually specifies which hashing algorithms are valid through the mining client.
/// If you would like to do a fork, simply allow, un-allow some algorithms to check it.
fn manual_fork_validation(_parent_number: u32, algo: SupportedHashes) -> bool {
    use SupportedHashes::*;

    // To begin with, allow all algorithms.
    // After the fork height this check is skipped so all the hashes become valid.
    match algo {
        Md5 => true,
        Sha3 => true,
        Keccak => true,
    }
}

/// In automatic mode, the `ForkHeights` and `MaxiPosition` structs define the forking schedule
/// and the node's behavior during the contentious fork
/// (where the network splits into two chains supporting different hashing algorithms).
/// The validation logic considers the parent block height,
/// forking configuration parameters, and the hashing algorithm used in the PoW solution to determine its validity.
fn auto_fork_validation(
    parent_number: u32,
    algo: SupportedHashes,
    fork_heights: ForkHeights,
    maxi_position: MaxiPosition,
) -> bool {
    use MaxiPosition::*;
    use SupportedHashes::*;

    log::debug!("parent_number: {:?}", parent_number);
    log::debug!("fork_heights: {:?}", fork_heights);

    if parent_number < fork_heights.add_sha3_keccak {
        // To begin with we only allow md5 hashes for our pow.
        // After the fork height this check is skipped so all the hashes become valid.
        match algo {
            Md5 => true,
            Sha3 => false,
            Keccak => false,
        }
    } else if parent_number < fork_heights.remove_md5 {
        // After the first fork, all three algos become valid.
        match algo {
            Md5 => true,
            Sha3 => true,
            Keccak => true,
        }
    } else if parent_number < fork_heights.split_sha3_keccak {
        // After the second fork, md5 is no longer valid.
        match algo {
            Md5 => false,
            Sha3 => true,
            Keccak => true,
        }
    } else {
        // Finally we have the contentious fork.
        // Our behavior here depends which maxi position we have taken.
        #[allow(clippy::match_like_matches_macro)]
        match (algo, maxi_position) {
            (Sha3, Sha3Maxi) => true,
            (Sha3, NoMaxi) => true,
            (Keccak, KeccakMaxi) => true,
            (Keccak, NoMaxi) => true,
            _ => false,
        }
    }
}
}
[package]
authors = [ "@danielbui12" ]
build = "build.rs"
edition = "2021"
name = "academy-pow"
version = "3.0.0"

[dependencies]
clap = { workspace = true }
futures = { workspace = true }
hex = { workspace = true }
log = { workspace = true }
parity-scale-codec = { workspace = true }
rand = { workspace = true }
serde_json = { workspace = true }
serde = { workspace = true }
sha3 = { workspace = true }
jsonrpsee = { workspace = true }

# Local Dependencies
academy-pow-runtime = { path = "../runtime" }
multi-pow = { path = "../multi-pow" }

# Polkadot SDK
pallet-transaction-payment-rpc = { workspace = true }
sc-rpc-api = { workspace = true }
sp-block-builder = { workspace = true }
substrate-frame-rpc-system = { workspace = true }
sc-basic-authorship = { workspace = true }
sc-chain-spec = { workspace = true }
sc-cli = { workspace = true }
sc-client-api = { workspace = true }
sc-consensus = { workspace = true }
sc-consensus-manual-seal = { workspace = true }
sc-consensus-pow = { workspace = true }
sc-executor = { workspace = true }
sc-network = { workspace = true }
sc-service = { workspace = true }
sc-telemetry = { workspace = true }
sc-transaction-pool = { workspace = true }
sc-transaction-pool-api = { workspace = true }
sp-api = { workspace = true }
sp-blockchain = { workspace = true }
sp-consensus = { workspace = true }
sp-consensus-pow = { workspace = true }
sp-core = { workspace = true }
sp-inherents = { workspace = true }
sp-io = { workspace = true, default-features = true}
sp-keyring = { workspace = true }
sp-runtime = { workspace = true }
sp-timestamp = { workspace = true }
sp-transaction-pool = { workspace = true }

[build-dependencies]
substrate-build-script-utils = { workspace = true }
fn main() {
    substrate_build_script_utils::generate_cargo_keys();
    substrate_build_script_utils::rerun_if_git_head_changed();
}
#![allow(unused)]
fn main() {
use std::str::FromStr;

use academy_pow_runtime::{
    AccountId,
    SS58Prefix,
    Signature,
    TOKEN_DECIMALS,
    TOKEN_SYMBOL,
    WASM_BINARY,
};
use multi_pow::{ForkHeights, ForkingConfig, MaxiPosition};
use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
use sc_service::ChainType;
use serde::{Deserialize, Serialize};
use sp_core::{sr25519, Pair, Public};
use sp_core::{ByteArray, H256};
use sp_runtime::traits::{IdentifyAccount, Verify};

/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
pub type ChainSpec = sc_service::GenericChainSpec<ForkingExtensions>;

/// PoW and Forking related chain spec extensions to configure the client side forking behavior.
///
/// The forks here are all related to adding and removing hash algorithms from the PoW.
/// The chain begins supporting only md5. Later is adds sha3 and keccak. Later it removes md5.
/// And finally there is a contentious fork where people become maxis.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]
#[serde(deny_unknown_fields)]
pub struct ForkingExtensions {
    /// Manual mode is intended for when we you are running a live workshop.
    /// No forking happens automatically. Rather, you have to hard-code the forks.
    ///
    /// If manual mode is enabled, the rest of the parameters are ignored.
    /// This should really be an enum, but I have to work around the broken extension system.
    ///
    /// Aww damn it! I can't even use bool in this broken system? Okay then I guess 0 means automatic mode
    /// and anything else means manual mode.
    pub manual_mode: u32,
    /// The block height to perform the soft fork that adds sha3 and keccak support.
    pub add_sha3_keccak: u32,
    /// The block height to perform the hard fork that removes md5 support.
    pub remove_md5: u32,
    /// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
    pub split_sha3_keccak: u32,
    // Damn extension thing is so fragile, I can't even use an enum here.
    // Let alone that time I tried to use the forked value feature.
    /// The political position that this node will take at the contentious fork.
    pub maxi_position: String,
}

impl From<&ForkingExtensions> for ForkingConfig {
    fn from(e: &ForkingExtensions) -> Self {
        if e.manual_mode > 0 {
            return Self::Manual;
        }

        let fork_heights = ForkHeights {
            add_sha3_keccak: e.add_sha3_keccak,
            remove_md5: e.remove_md5,
            split_sha3_keccak: e.split_sha3_keccak,
        };

        let maxi_position =
            MaxiPosition::from_str(&e.maxi_position).expect("Should have a valid maxi position...");

        Self::Automatic(fork_heights, maxi_position)
    }
}

impl ForkingExtensions {
    /// Try to get the extension from the given `ChainSpec`.
    pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {
        sc_chain_spec::get_extension(chain_spec.extensions())
    }
}

/// Generate a crypto pair from seed.
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
    TPublic::Pair::from_string(&format!("//{}", seed), None)
        .expect("static values are valid; qed")
        .public()
}

type AccountPublic = <Signature as Verify>::Signer;

/// Generate an account ID from seed.
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
where
    AccountPublic: From<<TPublic::Pair as Pair>::Public>,
{
    AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
}

pub fn development_config() -> Result<ChainSpec, String> {
    Ok(ChainSpec::builder(
        WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
        ForkingExtensions {
            manual_mode: 1, // change this to `0` if you want to try `auto_fork_validation`
            add_sha3_keccak: 10,
            remove_md5: 20,
            split_sha3_keccak: 30,
            maxi_position: String::from("follow-mining"),
        },
    )
    .with_name("Development")
    .with_id("dev")
    .with_chain_type(ChainType::Development)
    .with_genesis_config_patch(genesis(
        // Pre-funded accounts
        vec![
            get_account_id_from_seed::<sr25519::Public>("Alice"),
            get_account_id_from_seed::<sr25519::Public>("Bob"),
            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
        ],
        // Initial Difficulty
        4_000_000,
    ))
    .with_properties(system_properties())
    .build())
}

pub fn testnet_config() -> Result<ChainSpec, String> {
    Ok(ChainSpec::builder(
        WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
        ForkingExtensions {
            manual_mode: 1,
            add_sha3_keccak: 0,
            remove_md5: 0,
            split_sha3_keccak: 0,
            maxi_position: String::new(),
        },
    )
    .with_name("Testnet")
    .with_id("testnet")
    .with_chain_type(ChainType::Local)
    .with_genesis_config_patch(genesis(
        vec![
            get_account_id_from_seed::<sr25519::Public>("Alice"),
            get_account_id_from_seed::<sr25519::Public>("Bob"),
            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
        ],
        4_000_000,
    ))
    .with_properties(system_properties())
    .build())
}

fn genesis(
    endowed_accounts: Vec<AccountId>,
    initial_difficulty: u32,
) -> serde_json::Value {
    serde_json::json!({
        "balances": {
            // Configure endowed accounts with initial balance of 1 << 50.
            "balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 50)).collect::<Vec<_>>(),
        },
        "keccakDifficultyAdjustment": {
            "initialDifficulty": u32_to_u8_32(initial_difficulty),
        },
        "md5DifficultyAdjustment": {
            "initialDifficulty": u32_to_u8_32(initial_difficulty),
        },
        "sha3DifficultyAdjustment": {
            "initialDifficulty": u32_to_u8_32(initial_difficulty),
        },
    })
}

/// Convert u32 (default value) to [u8;32] (U256)
/// in little-endian format
pub fn u32_to_u8_32(num: u32) -> [u8; 32] {
    let mut result = [0u8; 32];
    let bytes = num.to_le_bytes(); 
    result[..4].copy_from_slice(&bytes);
    result
}

fn system_properties() -> sc_chain_spec::Properties {
    let mut properties = sc_chain_spec::Properties::new();

    properties.insert("ss58Format".into(), SS58Prefix::get().into());
    properties.insert("tokenSymbol".into(), TOKEN_SYMBOL.into());
    properties.insert("tokenDecimals".into(), TOKEN_DECIMALS.into());

    properties
}
}
#![allow(unused)]
fn main() {
use academy_pow_runtime::AccountId;
use multi_pow::SupportedHashes;
use sc_cli::{
    clap::{ArgGroup, Parser},
    RunCmd,
};
use sc_service::ChainType;
use sp_core::{crypto::Ss58Codec, sr25519};

#[derive(Debug, Parser)]
#[clap(subcommand_negates_reqs(true), version(env!("SUBSTRATE_CLI_IMPL_VERSION")))]
pub struct Cli {
    #[clap(subcommand)]
    pub subcommand: Option<Subcommand>,

    #[command(flatten)]
    pub pow: AcademyPowCli,

    #[clap(flatten)]
    pub run: RunCmd,
}

#[derive(Debug, Parser, Clone)]
#[clap(group(ArgGroup::new("backup")))]
pub struct AcademyPowCli {
    /// Miner's AccountId (base58 encoding of an SR25519 public key) for the block rewards
    #[clap(long,
           conflicts_with = "mining_public_key",
           value_parser = parse_account_id)]
    pub mining_account_id: Option<AccountId>,

    /// Miner's hex encoding of the SR25519 public key) for the block rewards
    #[clap(
        long,
        conflicts_with = "mining_account_id",
        value_parser = parse_sr25519_public_key
    )]
    pub mining_public_key: Option<sr25519::Public>,

    /// The mining algorithm to use
    #[clap(long, value_parser = parse_algo, default_value = "md5")]
    pub mining_algo: multi_pow::SupportedHashes,

    /// whether to use instant seal
    #[clap(long, default_value = "false")]
    pub instant_seal: bool,
}

impl AcademyPowCli {
    pub fn public_key_bytes(&self, keyring: Option<sp_keyring::Sr25519Keyring>) -> [u8; 32] {
        match &self.mining_account_id {
            Some(account_id) => *account_id.as_ref(),
            None => match self.mining_public_key {
                Some(public_key) => public_key.0,
                None => keyring.map(|k| k.to_raw_public()).unwrap_or([0u8; 32]),
            },
        }
    }
}

#[derive(Debug, Parser)]
pub struct BuildSpecCmd {
    #[clap(flatten)]
    pub base: sc_cli::BuildSpecCmd,

    /// Chain name.
    #[arg(long, default_value = "Academy PoW")]
    pub chain_name: String,

    /// Chain ID is a short identifier of the chain
    #[arg(long, value_name = "ID", default_value = "academy_pow")]
    pub chain_id: String,

    /// AccountIds of the optional rich accounts
    #[arg(long, value_delimiter = ',', value_parser = parse_account_id, num_args=1..)]
    pub endowed_accounts: Option<Vec<AccountId>>,

    /// The type of the chain. Possible values: "dev", "local", "live" (default)
    #[arg(long, value_name = "TYPE", value_parser = parse_chaintype, default_value = "live")]
    pub chain_type: ChainType,

    #[arg(long, default_value = "4000000")]
    pub initial_difficulty: u32,
}

fn parse_algo(s: &str) -> Result<SupportedHashes, String> {
    Ok(match s {
        "md" | "Md" | "md5" | "Md5" => SupportedHashes::Md5,
        "sha" | "sha3" | "Sha" | "Sha3" => SupportedHashes::Sha3,
        "keccak" | "Keccak" => SupportedHashes::Keccak,
        s => panic!(
            "Wrong mining algo: {}. Possible values: md5, sha3, keccak",
            s
        ),
    })
}

fn parse_chaintype(s: &str) -> Result<ChainType, String> {
    Ok(match s {
        "dev" => ChainType::Development,
        "local" => ChainType::Local,
        "live" => ChainType::Live,
        s => panic!("Wrong chain type {} Possible values: dev local live", s),
    })
}

/// Parse AccountId from a string argument passed on the command line.
fn parse_account_id(s: &str) -> Result<AccountId, String> {
    Ok(AccountId::from_string(s)
        .expect("Passed string is not a bas58 encoding of a sr25519 public key"))
}

/// Parse sr25519 pubkey from a string argument passed on the command line.
fn parse_sr25519_public_key(s: &str) -> Result<sr25519::Public, String> {
    Ok(sr25519::Public::from_string(s)
        .expect("Passed string is not a hex encoding of a sr25519 public key"))
}

#[derive(Debug, clap::Subcommand)]
pub enum Subcommand {
    /// Key management cli utilities
    #[command(subcommand)]
    Key(sc_cli::KeySubcommand),

    /// Build a chain specification.
    BuildSpec(BuildSpecCmd),

    /// Validate blocks.
    CheckBlock(sc_cli::CheckBlockCmd),

    /// Export blocks.
    ExportBlocks(sc_cli::ExportBlocksCmd),

    /// Export the state of a given block into a chain spec.
    ExportState(sc_cli::ExportStateCmd),

    /// Import blocks.
    ImportBlocks(sc_cli::ImportBlocksCmd),

    /// Remove the whole chain.
    PurgeChain(sc_cli::PurgeChainCmd),

    /// Revert the chain to a previous state.
    Revert(sc_cli::RevertCmd),

    /// Db meta columns information.
    ChainInfo(sc_cli::ChainInfoCmd),
}
}
#![allow(unused)]
fn main() {
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
// This file is part of Substrate.

// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.

use academy_pow_runtime::Block;
use multi_pow::{ForkingConfig, MaxiPosition};
use sc_cli::SubstrateCli;
use sc_service::PartialComponents;
use sp_core::sr25519;

use crate::{
    chain_spec::{self, ForkingExtensions},
    cli::{Cli, Subcommand},
    service,
};

impl SubstrateCli for Cli {
    fn impl_name() -> String {
        "Academy PoW Chain".into()
    }

    fn impl_version() -> String {
        env!("SUBSTRATE_CLI_IMPL_VERSION").into()
    }

    fn executable_name() -> String {
        env!("CARGO_PKG_NAME").into()
    }

    fn author() -> String {
        env!("CARGO_PKG_AUTHORS").into()
    }

    fn description() -> String {
        env!("CARGO_PKG_DESCRIPTION").into()
    }

    fn support_url() -> String {
        "https://github.com/danielbui12/substrate-bitcoin-like-blockchain/issues/new".into()
    }

    fn copyright_start_year() -> i32 {
        2025
    }

    fn load_spec(&self, id: &str) -> Result<Box<dyn sc_service::ChainSpec>, String> {
        Ok(match id {
            "" => Box::new(chain_spec::ChainSpec::from_json_bytes(
                &include_bytes!("../../spec.json")[..],
            )?),
            "dev" => Box::new(chain_spec::development_config()?),
            "local" => Box::new(chain_spec::testnet_config()?),
            path => Box::new(chain_spec::ChainSpec::from_json_file(
                std::path::PathBuf::from(path),
            )?),
        })
    }
}

/// Parse and run command line arguments
pub fn run() -> sc_cli::Result<()> {
    let cli = Cli::from_args();

    match &cli.subcommand {
        Some(Subcommand::Key(cmd)) => cmd.run(&cli),
        Some(Subcommand::BuildSpec(cmd)) => {
            let runner = cli.create_runner(&cmd.base)?;
            runner.sync_run(|config| cmd.base.run(config.chain_spec, config.network))
        }
        Some(Subcommand::CheckBlock(cmd)) => {
            let runner = cli.create_runner(cmd)?;
            runner.async_run(|config| {
                let PartialComponents {
                    client,
                    task_manager,
                    import_queue,
                    ..
                } = service::new_partial(&config, ForkingConfig::Manual)?;
                Ok((cmd.run(client, import_queue), task_manager))
            })
        }
        Some(Subcommand::ExportBlocks(cmd)) => {
            let runner = cli.create_runner(cmd)?;
            runner.async_run(|config| {
                let PartialComponents {
                    client,
                    task_manager,
                    ..
                } = service::new_partial(&config, ForkingConfig::Manual)?;
                Ok((cmd.run(client, config.database), task_manager))
            })
        }
        Some(Subcommand::ExportState(cmd)) => {
            let runner = cli.create_runner(cmd)?;
            runner.async_run(|config| {
                let PartialComponents {
                    client,
                    task_manager,
                    ..
                } = service::new_partial(&config, ForkingConfig::Manual)?;
                Ok((cmd.run(client, config.chain_spec), task_manager))
            })
        }
        Some(Subcommand::ImportBlocks(cmd)) => {
            let runner = cli.create_runner(cmd)?;
            runner.async_run(|config| {
                let PartialComponents {
                    client,
                    task_manager,
                    import_queue,
                    ..
                } = service::new_partial(&config, ForkingConfig::Manual)?;
                Ok((cmd.run(client, import_queue), task_manager))
            })
        }
        Some(Subcommand::PurgeChain(cmd)) => {
            let runner = cli.create_runner(cmd)?;
            runner.sync_run(|config| cmd.run(config.database))
        }
        Some(Subcommand::Revert(cmd)) => {
            let runner = cli.create_runner(cmd)?;
            runner.async_run(|config| {
                let PartialComponents {
                    client,
                    task_manager,
                    backend,
                    ..
                } = service::new_partial(&config, ForkingConfig::Manual)?;
                Ok((cmd.run(client, backend, None), task_manager))
            })
        }
        Some(Subcommand::ChainInfo(cmd)) => {
            let runner = cli.create_runner(cmd)?;
            runner.sync_run(|config| cmd.run::<Block>(&config))
        }
        None => {
            // Get the mining account from the cli
            let bytes: [u8; 32] = cli.pow.public_key_bytes(cli.run.get_keyring());
            let sr25519_public_key = sr25519::Public::from_raw(bytes);

            let runner = cli.create_runner(&cli.run)?;
            runner.run_node_until_exit(|config| async move {
                // Get the forking information from the chain spec extension.
                // Convert it to a strong type, and fill in the proper maxi position if they are following mining.
                let forking_extension = ForkingExtensions::try_get(&*config.chain_spec)
                    .expect("Should be able to get the fork config from the extension");
                let forking_config = match ForkingConfig::from(forking_extension) {
                    ForkingConfig::Automatic(fork_heights, MaxiPosition::FollowMining) => {
                        let maxi_position = match cli.pow.mining_algo {
                            multi_pow::SupportedHashes::Md5 => MaxiPosition::NoMaxi,
                            multi_pow::SupportedHashes::Sha3 => MaxiPosition::Sha3Maxi,
                            multi_pow::SupportedHashes::Keccak => MaxiPosition::KeccakMaxi,
                        };
                        ForkingConfig::Automatic(fork_heights, maxi_position)
                    }
                    old_config => old_config,
                };

                service::new_full::<sc_network::Litep2pNetworkBackend>(
                    config,
                    forking_config,
                    //TODO Combine the following three fields into a MiningConfig analogous to the ForkingConfig
                    sr25519_public_key,
                    cli.pow.instant_seal,
                    cli.pow.mining_algo,
                )
                .map_err(sc_cli::Error::Service)
            })
        }
    }
}
}
//! Substrate Node Template CLI library.
#![warn(missing_docs)]

mod chain_spec;
#[macro_use]
mod service;
mod cli;
mod command;
mod rpc;

fn main() -> sc_cli::Result<()> {
    command::run()
}
#![allow(unused)]
fn main() {
//! A collection of node-specific RPC methods.
//! Substrate provides the `sc-rpc` crate, which defines the core RPC layer
//! used by Substrate nodes. This file extends those RPC definitions with
//! capabilities that are specific to this project's runtime configuration.

#![warn(missing_docs)]

use std::sync::Arc;

use academy_pow_runtime::{opaque::Block, AccountId, Balance, Index};
use jsonrpsee::RpcModule;
pub use sc_rpc_api::DenyUnsafe;
use sc_transaction_pool_api::TransactionPool;
use sp_api::ProvideRuntimeApi;
use sp_block_builder::BlockBuilder;
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};

/// Full client dependencies.
pub struct FullDeps<C, P> {
    /// The client instance to use.
    pub client: Arc<C>,
    /// Transaction pool instance.
    pub pool: Arc<P>,
    /// Whether to deny unsafe calls
    pub deny_unsafe: DenyUnsafe,
}

/// Instantiate all full RPC extensions.
pub fn create_full<C, P>(
    deps: FullDeps<C, P>,
) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
where
    C: ProvideRuntimeApi<Block>,
    C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
    C: Send + Sync + 'static,
    C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
    C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
    C::Api: BlockBuilder<Block>,
    P: TransactionPool + 'static,
{
    use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
    use substrate_frame_rpc_system::{System, SystemApiServer};

    let mut module = RpcModule::new(());
    let FullDeps {
        client,
        pool,
        deny_unsafe,
    } = deps;

    module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?;
    module.merge(TransactionPayment::new(client).into_rpc())?;

    Ok(module)
}
}
#![allow(unused)]
fn main() {
//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.

use core::clone::Clone;
use std::sync::Arc;

use academy_pow_runtime::{self, opaque::Block, PreDigest, RuntimeApi};
use multi_pow::{ForkingConfig, MultiPow, SupportedHashes};
use parity_scale_codec::Encode;
use sc_consensus::LongestChain;
use sc_service::{error::Error as ServiceError, Configuration, PartialComponents, TaskManager};
use sc_telemetry::{Telemetry, TelemetryWorker};
use sp_core::sr25519;

pub(crate) type FullClient = sc_service::TFullClient<
	Block,
	RuntimeApi,
	sc_executor::WasmExecutor<sp_io::SubstrateHostFunctions>,
>;
type FullBackend = sc_service::TFullBackend<Block>;
type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;

type BasicImportQueue = sc_consensus::DefaultImportQueue<Block>;
type BoxBlockImport = sc_consensus::BoxBlockImport<Block>;

pub type Service = PartialComponents<
    FullClient,
    FullBackend,
    FullSelectChain,
    BasicImportQueue,
    sc_transaction_pool::FullPool<Block, FullClient>,
    (BoxBlockImport, Option<Telemetry>),
>;

/// Returns most parts of a service. Not enough to run a full chain,
/// But enough to perform chain operations like purge-chain
#[allow(clippy::type_complexity)]
pub fn new_partial(
    config: &Configuration,
    fork_config: ForkingConfig,
) -> Result<Service, ServiceError> {
    let telemetry = config
        .telemetry_endpoints
        .clone()
        .filter(|x| !x.is_empty())
        .map(|endpoints| -> Result<_, sc_telemetry::Error> {
            let worker = TelemetryWorker::new(16)?;
            let telemetry = worker.handle().new_telemetry(endpoints);
            Ok((worker, telemetry))
        })
        .transpose()?;

    let executor = sc_service::new_wasm_executor::<sp_io::SubstrateHostFunctions>(config);
    let (client, backend, keystore_container, task_manager) =
        sc_service::new_full_parts::<Block, RuntimeApi, _>(
            config,
            telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
            executor,
        )?;
    let client = Arc::new(client);

    let telemetry = telemetry.map(|(worker, telemetry)| {
        task_manager
            .spawn_handle()
            .spawn("telemetry", None, worker.run());
        telemetry
    });

    let select_chain = LongestChain::new(backend.clone());

    let transaction_pool = sc_transaction_pool::BasicPool::new_full(
        config.transaction_pool.clone(),
        config.role.is_authority().into(),
        config.prometheus_registry(),
        task_manager.spawn_essential_handle(),
        client.clone(),
    );

    let block_import = sc_consensus_pow::PowBlockImport::new(
        client.clone(),
        client.clone(),
        MultiPow::new(client.clone(), fork_config),
        0, // check inherents starting at block 0
        select_chain.clone(),
        move |_, ()| async move {
            let timestamp = sp_timestamp::InherentDataProvider::from_system_time();

            // We don't need the current mining key to check inherents, so we just use a default.
            // TODO, I don't think we need to do any checking here at all, right?
            // So can I just remove the author entirely?
            let author =
                academy_pow_runtime::block_author::InherentDataProvider(Default::default());

            Ok((timestamp, author))
        },
    );

    let import_queue = sc_consensus_pow::import_queue(
        Box::new(block_import.clone()),
        None,
        MultiPow::new(client.clone(), fork_config),
        &task_manager.spawn_essential_handle(),
        config.prometheus_registry(),
    )?;

    Ok(PartialComponents {
        client,
        backend,
        task_manager,
        import_queue,
        keystore_container,
        select_chain,
        transaction_pool,
        other: (Box::new(block_import), telemetry),
    })
}

/// Builds a new service for a full client.
pub fn new_full<
    N: sc_network::NetworkBackend<Block, <Block as sp_runtime::traits::Block>::Hash>,
>(
    config: Configuration,
    fork_config: ForkingConfig,
    sr25519_public_key: sr25519::Public,
    instant_seal: bool,
    mining_algo: SupportedHashes,
) -> Result<TaskManager, ServiceError> {
    let sc_service::PartialComponents {
        client,
        backend,
        mut task_manager,
        import_queue,
        keystore_container,
        select_chain,
        transaction_pool,
        other: (pow_block_import, mut telemetry),
    } = new_partial(&config, fork_config)?;

    let net_config = sc_network::config::FullNetworkConfiguration::<
        Block,
        <Block as sp_runtime::traits::Block>::Hash,
        N,
    >::new(&config.network);
	let metrics = sc_network::NotificationMetrics::new(None);

    let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =
        sc_service::build_network(sc_service::BuildNetworkParams {
            config: &config,
            net_config,
            client: client.clone(),
            transaction_pool: transaction_pool.clone(),
            spawn_handle: task_manager.spawn_handle(),
            import_queue,
            block_announce_validator_builder: None,
            warp_sync_params: None,
            block_relay: None,
            metrics: metrics,
        })?;

    let role = config.role.clone();
    let prometheus_registry = config.prometheus_registry().cloned();

    let rpc_extensions_builder = {
        let client = client.clone();
        let pool = transaction_pool.clone();

        Box::new(move |deny_unsafe, _| {
            let deps = crate::rpc::FullDeps {
                client: client.clone(),
                pool: pool.clone(),
                deny_unsafe,
            };
            crate::rpc::create_full(deps).map_err(Into::into)
        })
    };

    sc_service::spawn_tasks(sc_service::SpawnTasksParams {
        network,
        client: client.clone(),
        keystore: keystore_container.keystore(),
        task_manager: &mut task_manager,
        transaction_pool: transaction_pool.clone(),
        rpc_builder: rpc_extensions_builder,
        backend,
        system_rpc_tx,
        tx_handler_controller,
        sync_service: sync_service.clone(),
        config,
        telemetry: telemetry.as_mut(),
    })?;

    if role.is_authority() {
        let proposer = sc_basic_authorship::ProposerFactory::new(
            task_manager.spawn_handle(),
            client.clone(),
            transaction_pool.clone(),
            prometheus_registry.as_ref(),
            telemetry.as_ref().map(|x| x.handle()),
        );

        // If instant seal is requested, we just start it. Otherwise, we do the full PoW setup.
        if instant_seal {
            let params = sc_consensus_manual_seal::InstantSealParams {
                block_import: client.clone(),
                env: proposer,
                client,
                pool: transaction_pool,
                select_chain,
                consensus_data_provider: None,
                create_inherent_data_providers: move |_, ()| async move {
                    Ok(sp_timestamp::InherentDataProvider::from_system_time())
                },
            };

            let authorship_future = sc_consensus_manual_seal::run_instant_seal(params);

            task_manager.spawn_essential_handle().spawn_blocking(
                "instant-seal",
                None,
                authorship_future,
            );
        } else {
            let (mining_worker, mining_worker_task) = sc_consensus_pow::start_mining_worker(
                Box::new(pow_block_import),
                client.clone(),
                select_chain,
                MultiPow::new(client, fork_config),
                proposer,
                sync_service.clone(),
                sync_service,
                // Note the mining algorithm in the pre-runtime digest.
                // This allows us to know which algo it was in the runtime.
                // TODO This also makes it possible to remove the algo info from
                // the seal.
                Some(PreDigest::from((sr25519_public_key.into(), mining_algo)).encode()),
                // This code is copied from above. Would be better to not repeat it.
                move |_, ()| async move {
                    let timestamp = sp_timestamp::InherentDataProvider::from_system_time();            
                    // set default `author` following miner specified in CLI
                    let author = academy_pow_runtime::block_author::InherentDataProvider(
                        sr25519_public_key.encode(),
                    );

                    Ok((timestamp, author))
                },
                std::time::Duration::from_secs(10),
                std::time::Duration::from_secs(5),
            );

            task_manager.spawn_essential_handle().spawn_blocking(
                "pow-miner",
                Some("pow-mining"),
                mining_worker_task,
            );

            // Start Mining worker.
            //TODO Some of this should move into the multi_pow crate.
            use multi_pow::{multi_hash_meets_difficulty, Compute};
            use sp_core::U256;
            let mut nonce: U256 = U256::from(0);
            std::thread::spawn(move || loop {
                let worker = mining_worker.clone();
                let metadata = worker.metadata();
                if let Some(metadata) = metadata {
                    let compute = Compute {
                        difficulty: metadata.difficulty,
                        pre_hash: metadata.pre_hash,
                        nonce,
                    };
                    let seal = compute.compute(mining_algo);
                    if multi_hash_meets_difficulty(&seal.work, seal.difficulty) {
                        nonce = U256::from(0);
                        let _ = futures::executor::block_on(worker.submit(seal.encode()));
                    } else {
                        nonce = nonce.saturating_add(U256::from(1));
                        if nonce == U256::MAX {
                            nonce = U256::from(0);
                        }
                    }
                } else {
                    std::thread::sleep(std::time::Duration::from_secs(1));
                }
            });
        }
    }

    network_starter.start_network();
    Ok(task_manager)
}
}
[package]
authors = [ "Parity Technologies <admin@parity.io>", "Joshy Orndorff" ]
edition = "2021"
homepage = "https://substrate.dev"
name = "academy-pow-runtime"
version = "3.0.0"

[dependencies]
async-trait = { optional = true, workspace = true }
parity-scale-codec = { workspace = true }
scale-info = { workspace = true }
serde = { optional = true, workspace = true }
log.workspace = true

frame-executive = { workspace = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
pallet-balances = { workspace = true }
pallet-timestamp = { workspace = true }
pallet-transaction-payment = { workspace = true }
sp-api = { workspace = true }
sp-block-builder = { workspace = true }
sp-consensus-pow = { workspace = true }
sp-core = { workspace = true }
sp-genesis-builder = { workspace = true }
sp-inherents = { workspace = true }
sp-io = { workspace = true }
sp-keystore = { optional = true, workspace = true }
sp-offchain = { workspace = true }
sp-runtime = { workspace = true }
sp-session = { workspace = true }
sp-std = { workspace = true }
sp-transaction-pool = { workspace = true }
sp-version = { workspace = true }

multi-pow = { default-features = false, path = "../multi-pow" }

# Used for the node's RPCs
frame-system-rpc-runtime-api = { workspace = true }
pallet-transaction-payment-rpc-runtime-api = { workspace = true }
[build-dependencies]
substrate-wasm-builder = { workspace = true }


[dev-dependencies]
hex-literal = { workspace = true }

[features]
default = [ "std" ]
std = [
	"pallet-balances/std",
	"parity-scale-codec/std",
	"frame-executive/std",
	"frame-support/std",
	"serde",
	"sp-api/std",
	"sp-block-builder/std",
	"sp-consensus-pow/std",
	"sp-core/std",
	"sp-genesis-builder/std",
	"sp-inherents/std",
	"sp-io/std",
	"sp-offchain/std",
	"sp-runtime/std",
	"sp-session/std",
	"sp-std/std",
	"sp-transaction-pool/std",
	"sp-version/std",
	"frame-system/std",
	"pallet-timestamp/std",
	"async-trait",
	"sp-keystore",
	"pallet-transaction-payment/std",
	"pallet-transaction-payment-rpc-runtime-api/std",
	"frame-system-rpc-runtime-api/std",
	"multi-pow/std",
]
fn main() {
    #[cfg(feature = "std")]
    substrate_wasm_builder::WasmBuilder::new()
        .with_current_project()
        .export_heap_base()
        .import_memory()
        .build()
}
#![allow(unused)]
fn main() {
//! This pallet allows block authors to self-identify by providing an sr25519 public key
//!
//! The included trait allows other pallets to fetch the author's account as long as the
//! runtime's AccountId type can be created from an sr25519 public key.

pub use pallet::*;
use parity_scale_codec::{Decode, Encode};
use sp_core::sr25519;
#[cfg(feature = "std")]
use sp_inherents::InherentData;
use sp_inherents::{InherentIdentifier, IsFatalError};
use sp_runtime::RuntimeString;
use sp_std::vec::Vec;

#[frame_support::pallet(dev_mode)]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    use super::*;

    /// The BlockAuthor Inherent pallet.
    #[pallet::pallet]
    pub struct Pallet<T>(PhantomData<T>);
    /// The pallet's configuration trait. Nothing to configure.
    #[pallet::config]
    pub trait Config: frame_system::Config {
        fn on_author_set(_author_account: Self::AccountId) {}
    }

    #[pallet::error]
    pub enum Error<T> {
        /// Author already set in block.
        AuthorAlreadySet,
    }

    /// Author of current block.
    #[pallet::storage]
    pub type Author<T: Config> = StorageValue<_, sr25519::Public, OptionQuery>;

    #[pallet::call]
    impl<T: Config> Pallet<T>
    where
        <T as frame_system::Config>::AccountId: From<sp_core::sr25519::Public>,
    {
        /// Inherent to set the author of a block
        #[pallet::weight(1_000_000)]
        pub fn set_author(origin: OriginFor<T>, author: sr25519::Public) -> DispatchResult {
            ensure_none(origin)?;
            ensure!(Author::<T>::get().is_none(), Error::<T>::AuthorAlreadySet);

            // Store the author in case other pallets want to fetch it and to let
            // offchain tools inspect it
            Author::<T>::put(author);

            // Call the hook
            T::on_author_set(author.into());

            Ok(())
        }
    }

    #[pallet::hooks]
    impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
        fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
            // Reset the author to None at the beginning of the block
            Author::<T>::kill();

            // Return zero weight because we are not using weight-based
            // transaction fees.
            Weight::zero()
        }
    }

    #[pallet::inherent]
    impl<T: Config> ProvideInherent for Pallet<T>
    where
        <T as frame_system::Config>::AccountId: From<sp_core::sr25519::Public>,
    {
        type Call = Call<T>;
        type Error = InherentError;
        const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;

        fn is_inherent_required(_: &InherentData) -> Result<Option<Self::Error>, Self::Error> {
            // Return Ok(Some(_)) unconditionally because this inherent is required in every block
            // If it is not found, throw an AuthorInherentRequired error.
            Ok(Some(InherentError::Other(
                sp_runtime::RuntimeString::Borrowed("BlockAuthorInherentRequired"),
            )))
        }

        fn create_inherent(data: &InherentData) -> Option<Self::Call> {
            // Grab the Vec<u8> labelled with "author_" from the map of all inherent data
            let author_raw = data
                .get_data::<InherentType>(&INHERENT_IDENTIFIER)
                .expect("Gets and decodes authorship inherent data")?;

            // Decode the Vec<u8> into an actual author
            let author = sr25519::Public::decode(&mut &author_raw[..])
                .expect("Decodes author raw inherent data");

            Some(Call::set_author { author })
        }

        fn is_inherent(call: &Self::Call) -> bool {
            matches!(call, Call::set_author { .. })
        }
    }
}

/// A trait to find the author (miner) of the block.
pub trait BlockAuthor {
    fn block_author() -> Option<sr25519::Public>;
}

impl BlockAuthor for () {
    fn block_author() -> Option<sr25519::Public> {
        None
    }
}

impl<T: Config> BlockAuthor for Pallet<T> {
    fn block_author() -> Option<sr25519::Public> {
        Author::<T>::get()
    }
}

pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"author__";

#[derive(Encode, Decode, Debug)]
pub enum InherentError {
    Other(RuntimeString),
}

impl IsFatalError for InherentError {
    fn is_fatal_error(&self) -> bool {
        match *self {
            InherentError::Other(_) => true,
        }
    }
}

impl InherentError {
    /// Try to create an instance ouf of the given identifier and data.
    #[cfg(feature = "std")]
    pub fn try_from(id: &InherentIdentifier, data: &[u8]) -> Option<Self> {
        if id == &INHERENT_IDENTIFIER {
            <InherentError as parity_scale_codec::Decode>::decode(&mut &data[..]).ok()
        } else {
            None
        }
    }
}

/// The type of data that the inherent will contain.
/// Just a byte array. It will be decoded to an actual pubkey later
pub type InherentType = Vec<u8>;

#[cfg(feature = "std")]
pub struct InherentDataProvider(pub InherentType);

#[cfg(feature = "std")]
#[async_trait::async_trait]
impl sp_inherents::InherentDataProvider for InherentDataProvider {
    async fn provide_inherent_data(
        &self,
        inherent_data: &mut InherentData,
    ) -> Result<(), sp_inherents::Error> {
        inherent_data.put_data(INHERENT_IDENTIFIER, &self.0)
    }

    async fn try_handle_error(
        &self,
        identifier: &InherentIdentifier,
        _error: &[u8],
    ) -> Option<Result<(), sp_inherents::Error>> {
        // Dont' process modules from other inherents
        if *identifier != INHERENT_IDENTIFIER {
            return None;
        }

        // All errors with the author inehrent are fatal
        Some(Err(sp_inherents::Error::Application(Box::from(
            String::from("Error processing author inherent"),
        ))))
    }
}
}
#![allow(unused)]
fn main() {
//! A difficulty adjustment algorithm (DAA) to keep the block time close to a particular goal
//! Cribbed from Kulupu https://github.com/kulupu/kulupu/blob/master/runtime/src/difficulty.rs
//!
//! It is possible to implement other DAAs such as that of BTC and BCH. This would be an interesting
//! and worth-while experiment. The DAAs should be abstracted away with a trait.
//! Some ideas: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3410460

use core::cmp::{max, min};

use frame_support::traits::Time;
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_core::U256;
use sp_runtime::traits::UniqueSaturatedInto;

#[derive(Encode, Decode, Clone, Copy, Eq, PartialEq, Debug, MaxEncodedLen, TypeInfo)]
pub struct DifficultyAndTimestamp<M> {
    pub difficulty: Difficulty,
    pub timestamp: M,
}

/// Move value linearly toward a goal
pub fn damp(actual: u128, goal: u128, damp_factor: u128) -> u128 {
    (actual + (damp_factor - 1) * goal) / damp_factor
}

/// Limit value to be within some factor from a goal
pub fn clamp(actual: u128, goal: u128, clamp_factor: u128) -> u128 {
    max(goal / clamp_factor, min(actual, goal * clamp_factor))
}

const DIFFICULTY_ADJUST_WINDOW: u128 = 60;
type Difficulty = U256;

pub use pallet::*;

#[frame_support::pallet(dev_mode)]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    use super::*;

    /// Pallet's configuration trait.
    #[pallet::config]
    pub trait Config<I: 'static = ()>: frame_system::Config {
        /// A Source for timestamp data
        type TimeProvider: Time;
        /// The block time that the DAA will attempt to maintain
        type TargetBlockTime: Get<u128>;
        /// Dampening factor to use for difficulty adjustment
        type DampFactor: Get<u128>;
        /// Clamp factor to use for difficulty adjustment
        /// Limit value to within this factor of goal. Recommended value: 2
        type ClampFactor: Get<u128>;
        /// The maximum difficulty allowed. Recommended to use u128::max_value()
        type MaxDifficulty: Get<u128>;
        /// Minimum difficulty, enforced in difficulty retargetting
        /// avoids getting stuck when trying to increase difficulty subject to dampening
        /// Recommended to use same value as DampFactor
        type MinDifficulty: Get<u128>;

        /// Now that the pallet is instantiable, we need a way to decide which blocks are
        /// relevant to this instance. This function does just that.
        ///
        /// The default implementation assumes that all blocks are relevant which is what
        /// you probably want when there is only a single instance.
        fn relevant_to_this_instance() -> bool {
            true
        }
    }

    #[pallet::pallet]
    pub struct Pallet<T, I = ()>(_);

    type DifficultyList<T, I> =
        [Option<DifficultyAndTimestamp<<<T as Config<I>>::TimeProvider as Time>::Moment>>; 60];

    /// Past difficulties and timestamps, from earliest to latest.
    #[pallet::storage]
    pub type PastDifficultiesAndTimestamps<T: Config<I>, I: 'static = ()> =
        StorageValue<_, DifficultyList<T, I>, ValueQuery, EmptyList<T, I>>;

    pub struct EmptyList<T: Config<I>, I: 'static = ()>(PhantomData<(T, I)>);
    impl<T: Config<I>, I> Get<DifficultyList<T, I>> for EmptyList<T, I> {
        fn get() -> DifficultyList<T, I> {
            [None; DIFFICULTY_ADJUST_WINDOW as usize]
        }
    }

    /// Current difficulty.
    #[pallet::storage]
    #[pallet::getter(fn difficulty)]
    pub type CurrentDifficulty<T: Config<I>, I: 'static = ()> =
        StorageValue<_, Difficulty, ValueQuery>;

    /// Initial difficulty.
    #[pallet::storage]
    pub type InitialDifficulty<T: Config<I>, I: 'static = ()> =
        StorageValue<_, Difficulty, ValueQuery>;

    #[pallet::genesis_config]
    pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
        pub _ph_data: Option<PhantomData<(T, I)>>,
        pub initial_difficulty: [u8; 32], // Difficulty = U256
    }

    #[pallet::genesis_build]
    impl<T: Config<I>, I: 'static> BuildGenesisConfig for GenesisConfig<T, I> {
        fn build(&self) {
            let initial_difficulty = U256::from_little_endian(&self.initial_difficulty);
            // Initialize the Current difficulty
            CurrentDifficulty::<T, I>::put(&initial_difficulty);

            // Store the initial difficulty in storage because we will need it
            // during the first DIFFICULTY_ADJUSTMENT_WINDOW blocks (see todo below).
            InitialDifficulty::<T, I>::put(&initial_difficulty);
        }
    }

    impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
        fn default() -> Self {
            GenesisConfig {
                _ph_data: Default::default(),
                initial_difficulty: [0u8; 32],
            }
        }
    }

    #[pallet::hooks]
    impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
        fn on_finalize(_n: BlockNumberFor<T>) {
            // First check if this is block is relevant to this instance of the difficulty adjustment algorithm
            if !T::relevant_to_this_instance() {
                return;
            }

            let mut data = PastDifficultiesAndTimestamps::<T, I>::get();

            for i in 1..data.len() {
                data[i - 1] = data[i];
            }

            data[data.len() - 1] = Some(DifficultyAndTimestamp {
                timestamp: T::TimeProvider::now(),
                difficulty: Self::difficulty(),
            });

            let mut ts_delta = 0;
            for i in 1..(DIFFICULTY_ADJUST_WINDOW as usize) {
                let prev: Option<u128> = data[i - 1].map(|d| d.timestamp.unique_saturated_into());
                let cur: Option<u128> = data[i].map(|d| d.timestamp.unique_saturated_into());

                let delta = match (prev, cur) {
                    (Some(prev), Some(cur)) => cur.saturating_sub(prev),
                    _ => T::TargetBlockTime::get(),
                };
                ts_delta += delta;
            }

            if ts_delta == 0 {
                ts_delta = 1;
            }

            let mut diff_sum = U256::zero();
            //TODO Could we just initialize every array cell to the initial difficulty to not need the
            // separate storage item?
            for item in data.iter().take(DIFFICULTY_ADJUST_WINDOW as usize) {
                let diff = match item.map(|d| d.difficulty) {
                    Some(diff) => diff,
                    None => InitialDifficulty::<T, I>::get(),
                };
                diff_sum += diff;
            }

            if diff_sum < U256::from(T::MinDifficulty::get()) {
                diff_sum = U256::from(T::MinDifficulty::get());
            }

            // Calculate the average length of the adjustment window
            let adjustment_window = DIFFICULTY_ADJUST_WINDOW * T::TargetBlockTime::get();

            // adjust time delta toward goal subject to dampening and clamping
            let adj_ts = clamp(
                damp(ts_delta, adjustment_window, T::DampFactor::get()),
                adjustment_window,
                T::ClampFactor::get(),
            );

            // minimum difficulty avoids getting stuck due to dampening
            let difficulty = min(
                U256::from(T::MaxDifficulty::get()),
                max(
                    U256::from(T::MinDifficulty::get()),
                    diff_sum * U256::from(T::TargetBlockTime::get()) / U256::from(adj_ts),
                ),
            );

            <PastDifficultiesAndTimestamps<T, I>>::put(data);
            <CurrentDifficulty<T, I>>::put(difficulty);
        }
    }
}
}
#![allow(unused)]
#![cfg_attr(not(feature = "std"), no_std)]

fn main() {
/// A trait for types that can provide the amount of issuance to award to the block
/// author for the given block number.
pub trait Issuance<BlockNumber, Balance> {
    fn issuance(block: BlockNumber) -> Balance;
}

// Minimal implementations for when you don't actually want any issuance
impl Issuance<u32, u128> for () {
    fn issuance(_block: u32) -> u128 {
        0
    }
}

impl Issuance<u64, u128> for () {
    fn issuance(_block: u64) -> u128 {
        0
    }
}

/// A type that provides block issuance according to bitcoin's rules
/// Initial issuance is 50 / block
/// Issuance is cut in half every 210,000 blocks
/// cribbed from github.com/Bitcoin-ABC/bitcoin-abc/blob/9c7b12e6f128a59423f4de3d6d4b5231ebe9aac2/src/validation.cpp#L1007

pub struct BitcoinHalving;

/// The number of blocks between each halving.
const HALVING_INTERVAL: u32 = 210_000;
/// The per-block issuance before any halving. Decimal places should be accounted for here.
const INITIAL_ISSUANCE: u32 = 50;

impl Issuance<u32, u128> for BitcoinHalving {
    fn issuance(block: u32) -> u128 {
        let halving = block / HALVING_INTERVAL;
        // Force block reward to zero when right shift is undefined.
        if halving >= 64 {
            return 0;
        }

        // Approximately, 600 seconds (or 10 minutes) for a block to be finalized.
        // Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
        // Divided by 2 using bitwise
        (INITIAL_ISSUANCE >> halving).into()
    }
}
}
#![allow(unused)]
fn main() {
//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.

#![cfg_attr(not(feature = "std"), no_std)]
// The construct runtime macro does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit = "256"]

// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

pub use frame_support::{
    construct_runtime, parameter_types, derive_impl,
    traits::{
        Currency, EstimateNextNewSession, Imbalance, IsSubType, KeyOwnerProofSystem,
        LockIdentifier, Nothing, OnUnbalanced, ValidatorSet, VariantCountOf,
    },
    weights::{
        constants::{
            BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND,
        },
        IdentityFee, Weight,
    },
    Callable, StorageValue,
};
use frame_support::{
    genesis_builder_helper::{build_state, get_preset},
    instances::{Instance1, Instance2, Instance3},
    sp_runtime::Perquintill,
    traits::{ConstU128, ConstU32, ConstU8},
};
use multi_pow::SupportedHashes;
pub use pallet_balances::Call as BalancesCall;
pub use pallet_timestamp::Call as TimestampCall;
use pallet_transaction_payment::{ConstFeeMultiplier, FungibleAdapter, Multiplier};
use parity_scale_codec::Decode;
use sp_api::impl_runtime_apis;
use sp_consensus_pow::POW_ENGINE_ID;
use sp_core::OpaqueMetadata;
// A few exports that help ease life for downstream crates.
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
use sp_runtime::{
    create_runtime_str, generic,
    traits::{
        AccountIdLookup, BlakeTwo256, Block as BlockT, Bounded, IdentifyAccount, One, Verify,
    },
    transaction_validity::{
        InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
    },
    ApplyExtrinsicResult, DigestItem, MultiSignature,
    ExtrinsicInclusionMode,
};
pub use sp_runtime::{FixedPointNumber, Perbill, Permill};
use sp_std::prelude::*;
#[cfg(feature = "std")]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
/// An index to a block.
pub type BlockNumber = u32;

/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
pub type Signature = MultiSignature;

/// Some way of identifying an account on the chain. We intentionally make it equivalent
/// to the public key of our transaction signing scheme.
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;

/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
/// never know...
pub type AccountIndex = u32;

/// Balance of an account.
pub type Balance = u128;

/// Index of a transaction in the chain.
pub type Nonce = u32;

/// Index of a transaction in the chain.
pub type Index = u32;

/// A hash of some data used by the chain.
pub type Hash = sp_core::H256;

/// Consensus digest containing block author and supported hash algorithm.
pub type PreDigest = (AccountId, SupportedHashes);

/// The BlockAuthor trait in `./block_author.rs`
pub mod block_author;

// /// The Difficulty Adjustment Algorithm in `./difficulty.rs`
pub mod difficulty;

/// The total issuance and halving time
pub mod issuance;

/// UTXOs serve as the digital equivalent of change you receive after making a cash purchase
pub mod utxo;

/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
/// to even the core data structures.
pub mod opaque {
    pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;

    use super::*;

    /// Opaque block header type.
    pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
    /// Opaque block type.
    pub type Block = generic::Block<Header, UncheckedExtrinsic>;
    /// Opaque block identifier type.
    pub type BlockId = generic::BlockId<Block>;
}

/// This runtime version.
#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
    spec_name: create_runtime_str!("academy-pow"),
    impl_name: create_runtime_str!("academy-pow"),
    authoring_version: 1,
    spec_version: 1,
    impl_version: 1,
    apis: RUNTIME_API_VERSIONS,
    transaction_version: 1,
    state_version: 1,
};

/// The version information used to identify this runtime when compiled natively.
#[cfg(feature = "std")]
pub fn native_version() -> NativeVersion {
    NativeVersion {
        runtime_version: VERSION,
        can_author_with: Default::default(),
    }
}

const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
// native chain currency
pub const TOKEN_SYMBOL: &str = "Unit";
pub const TOKEN_DECIMALS: u32 = 12;
pub const TOKEN: u128 = 10u128.pow(TOKEN_DECIMALS);

parameter_types! {
    pub const BlockHashCount: BlockNumber = 2400;
    pub const Version: RuntimeVersion = VERSION;
    /// We allow for 2 seconds of compute with a 6 second average block time.
    pub BlockWeights: frame_system::limits::BlockWeights =
        frame_system::limits::BlockWeights::with_sensible_defaults(
            Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX),
            NORMAL_DISPATCH_RATIO,
        );
    pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
        ::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
    pub const SS58Prefix: u8 = 42;
}

#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
impl frame_system::Config for Runtime {
    /// The basic call filter to use in dispatchable.
    type BaseCallFilter = frame_support::traits::Everything;
    /// Block & extrinsics weights: base values and limits.
    type BlockWeights = BlockWeights;
    /// The maximum length of a block (in bytes).
    type BlockLength = BlockLength;
    /// The identifier used to distinguish between accounts.
    type AccountId = AccountId;
    /// The aggregated dispatch type that is available for extrinsics.
    type RuntimeCall = RuntimeCall;
    /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
    type Lookup = AccountIdLookup<AccountId, ()>;
    /// The type for hashing blocks and tries.
    type Hash = Hash;
    /// The hashing algorithm used.
    type Hashing = BlakeTwo256;
    /// The ubiquitous event type.
    type RuntimeEvent = RuntimeEvent;
    /// The ubiquitous origin type.
    type RuntimeOrigin = RuntimeOrigin;
    /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
    type BlockHashCount = BlockHashCount;
    /// The weight of database operations that the runtime can invoke.
    type DbWeight = RocksDbWeight;
    /// Version of the runtime.
    type Version = Version;
    /// This type is being generated by the construct runtime macro.
    type PalletInfo = PalletInfo;
    /// What to do if a new account is created.
    type OnNewAccount = ();
    /// What to do if an account is fully reaped from the system.
    type OnKilledAccount = ();
    /// The data to be stored in an account.
    type AccountData = pallet_balances::AccountData<Balance>;
    /// Weight information for the extrinsics of this pallet.
    type SystemWeightInfo = ();
    /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
    type SS58Prefix = SS58Prefix;
    /// The set code logic, just the default since we're not a parachain.
    type OnSetCode = ();
    type MaxConsumers = frame_support::traits::ConstU32<16>;
    type Nonce = Nonce;
    type Block = Block;
}

parameter_types! {
    pub const MinimumPeriod: u64 = 1000;
}

impl pallet_timestamp::Config for Runtime {
    /// A timestamp: milliseconds since the unix epoch.
    type Moment = u64;
    type OnTimestampSet = ();
    type MinimumPeriod = MinimumPeriod;
    type WeightInfo = ();
}

impl pallet_balances::Config for Runtime {
    type MaxLocks = ConstU32<50>;
    type MaxReserves = ();
    type ReserveIdentifier = [u8; 8];
    /// The type for recording an account's balance.
    type Balance = Balance;
    /// The ubiquitous event type.
    type RuntimeEvent = RuntimeEvent;
    type DustRemoval = ();
    type ExistentialDeposit = ConstU128<500>;
    type AccountStore = System;
    type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
    type FreezeIdentifier = RuntimeFreezeReason;
    type MaxFreezes = VariantCountOf<RuntimeFreezeReason>;
    type RuntimeHoldReason = RuntimeHoldReason;
    type RuntimeFreezeReason = RuntimeFreezeReason;
}

parameter_types! {
    pub const TargetBlockTime: u128 = 5_000;
    // Setting min difficulty to damp factor per recommendation
    pub const DampFactor: u128 = 3;
    pub const ClampFactor: u128 = 2;
    pub const MaxDifficulty: u128 = u128::max_value();
}

// Helper function to get the current blocks PoW algo from the predigest
fn current_blocks_mining_algo() -> SupportedHashes {
    System::digest()
        .logs
        .iter()
        .find_map(|digest_item| match digest_item {
            DigestItem::PreRuntime(POW_ENGINE_ID, pre_digest) => {
                PreDigest::decode(&mut &pre_digest[..]).map(|d| d.1).ok()
            }
            _ => None,
        })
        .expect("There should be exactly one pow pre-digest item")
}

impl difficulty::Config<Instance1> for Runtime {
    type TimeProvider = Timestamp;
    type TargetBlockTime = TargetBlockTime;
    type DampFactor = DampFactor;
    type ClampFactor = ClampFactor;
    type MaxDifficulty = MaxDifficulty;
    type MinDifficulty = DampFactor;

    fn relevant_to_this_instance() -> bool {
        current_blocks_mining_algo() == SupportedHashes::Md5
    }
}

impl difficulty::Config<Instance2> for Runtime {
    type TimeProvider = Timestamp;
    type TargetBlockTime = TargetBlockTime;
    type DampFactor = DampFactor;
    type ClampFactor = ClampFactor;
    type MaxDifficulty = MaxDifficulty;
    type MinDifficulty = DampFactor;

    fn relevant_to_this_instance() -> bool {
        current_blocks_mining_algo() == SupportedHashes::Sha3
    }
}

impl difficulty::Config<Instance3> for Runtime {
    type TimeProvider = Timestamp;
    type TargetBlockTime = TargetBlockTime;
    type DampFactor = DampFactor;
    type ClampFactor = ClampFactor;
    type MaxDifficulty = MaxDifficulty;
    type MinDifficulty = DampFactor;

    fn relevant_to_this_instance() -> bool {
        current_blocks_mining_algo() == SupportedHashes::Keccak
    }
}

impl block_author::Config for Runtime {
    // Each block mined issues 50 new tokens to the miner
    fn on_author_set(author_account: Self::AccountId) {
        let issuance = 50 * TOKEN;
        let _ = Balances::deposit_creating(&author_account, issuance);
    }
}

parameter_types! {
    // This value increases the priority of `Operational` transactions by adding
    // a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
    // follows polkadot : https://github.com/paritytech/polkadot/blob/9ce5f7ef5abb1a4291454e8c9911b304d80679f9/runtime/polkadot/src/lib.rs#L369
    pub const OperationalFeeMultiplier: u8 = 5;
    // We expect that on average 25% of the normal capacity will be occupied with normal txs.
    pub const TargetSaturationLevel: Perquintill = Perquintill::from_percent(25);
    // During 20 blocks the fee may not change more than by 100%. This, together with the
    // `TargetSaturationLevel` value, results in variability ~0.067. For the corresponding
    // formulas please refer to Substrate code at `frame/transaction-payment/src/lib.rs`.
    pub FeeVariability: Multiplier = Multiplier::saturating_from_rational(67, 1000);
    // Fee should never be lower than the computational cost.
    pub MinimumMultiplier: Multiplier = Multiplier::one();
    pub MaximumMultiplier: Multiplier = Bounded::max_value();
}

parameter_types! {
    pub FeeMultiplier: Multiplier = Multiplier::one();
}

impl pallet_transaction_payment::Config for Runtime {
    type RuntimeEvent = RuntimeEvent;
    type OnChargeTransaction = FungibleAdapter<Balances, ()>;
    type OperationalFeeMultiplier = ConstU8<5>;
    type WeightToFee = IdentityFee<Balance>;
    type LengthToFee = IdentityFee<Balance>;
    type FeeMultiplierUpdate = ConstFeeMultiplier<FeeMultiplier>;
}

construct_runtime!(
    pub struct Runtime {
        System: frame_system,
        Timestamp: pallet_timestamp,
        Balances: pallet_balances,
        TransactionPayment: pallet_transaction_payment,
        Md5DifficultyAdjustment: difficulty::<Instance1>,
        Sha3DifficultyAdjustment: difficulty::<Instance2>,
        KeccakDifficultyAdjustment: difficulty::<Instance3>,
        BlockAuthor: block_author,
    }
);

/// The address format for describing accounts.
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// A Block signed with a Justification
pub type SignedBlock = generic::SignedBlock<Block>;
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
    frame_system::CheckNonZeroSender<Runtime>,
    frame_system::CheckSpecVersion<Runtime>,
    frame_system::CheckTxVersion<Runtime>,
    frame_system::CheckGenesis<Runtime>,
    frame_system::CheckEra<Runtime>,
    frame_system::CheckNonce<Runtime>,
    frame_system::CheckWeight<Runtime>,
    pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
);
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
    generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
/// Executive: handles dispatch to the various modules.
pub type Executive = frame_executive::Executive<
    Runtime,
    Block,
    frame_system::ChainContext<Runtime>,
    Runtime,
    AllPalletsWithSystem,
>;

impl_runtime_apis! {
    impl sp_api::Core<Block> for Runtime {
        fn version() -> RuntimeVersion {
            VERSION
        }

        fn execute_block(block: Block) {
            Executive::execute_block(block)
        }

        fn initialize_block(header: &<Block as BlockT>::Header) -> ExtrinsicInclusionMode {
            Executive::initialize_block(header)
        }
    }

    impl sp_api::Metadata<Block> for Runtime {
        fn metadata() -> OpaqueMetadata {
            OpaqueMetadata::new(Runtime::metadata().into())
        }

        fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
            Runtime::metadata_at_version(version)
        }

        fn metadata_versions() -> sp_std::vec::Vec<u32> {
            Runtime::metadata_versions()
        }
    }

    impl sp_block_builder::BlockBuilder<Block> for Runtime {
        fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
            Executive::apply_extrinsic(extrinsic)
        }

        fn finalize_block() -> <Block as BlockT>::Header {
            Executive::finalize_block()
        }

        fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
            data.create_extrinsics()
        }

        fn check_inherents(
            block: Block,
            data: sp_inherents::InherentData,
        ) -> sp_inherents::CheckInherentsResult {
            data.check_extrinsics(&block)
        }
    }

    impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
        fn validate_transaction(
            source: TransactionSource,
            tx: <Block as BlockT>::Extrinsic,
            block_hash: <Block as BlockT>::Hash,
        ) -> TransactionValidity {
            Executive::validate_transaction(source, tx, block_hash)
        }
    }

    impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
        fn offchain_worker(header: &<Block as BlockT>::Header) {
            Executive::offchain_worker(header)
        }
    }

    impl sp_session::SessionKeys<Block> for Runtime {
        fn generate_session_keys(_seed: Option<Vec<u8>>) -> Vec<u8> {
            Vec::new()
        }

        fn decode_session_keys(
            _encoded: Vec<u8>,
        ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
            None
        }
    }

    impl sp_consensus_pow::DifficultyApi<Block, multi_pow::Threshold> for Runtime {
        fn difficulty() -> multi_pow::Threshold {
            multi_pow::Threshold {
                md5: Md5DifficultyAdjustment::difficulty(),
                sha3: Sha3DifficultyAdjustment::difficulty(),
                keccak: KeccakDifficultyAdjustment::difficulty(),
            }
        }
    }

    impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
        fn account_nonce(account: AccountId) -> Index {
            System::account_nonce(account)
        }
    }

    impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime
    {
        fn query_info(
            uxt: <Block as BlockT>::Extrinsic,
            len: u32,
        ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
            TransactionPayment::query_info(uxt, len)
        }
        fn query_fee_details(
            uxt: <Block as BlockT>::Extrinsic,
            len: u32,
        ) -> pallet_transaction_payment::FeeDetails<Balance> {
            TransactionPayment::query_fee_details(uxt, len)
        }
        fn query_weight_to_fee(weight: Weight) -> Balance {
            TransactionPayment::weight_to_fee(weight)
        }
        fn query_length_to_fee(length: u32) -> Balance {
            TransactionPayment::length_to_fee(length)
        }
    }

    impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
        for Runtime
    {
        fn query_call_info(
            call: RuntimeCall,
            len: u32,
        ) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
            TransactionPayment::query_call_info(call, len)
        }
        fn query_call_fee_details(
            call: RuntimeCall,
            len: u32,
        ) -> pallet_transaction_payment::FeeDetails<Balance> {
            TransactionPayment::query_call_fee_details(call, len)
        }
        fn query_weight_to_fee(weight: Weight) -> Balance {
            TransactionPayment::weight_to_fee(weight)
        }
        fn query_length_to_fee(length: u32) -> Balance {
            TransactionPayment::length_to_fee(length)
        }
    }

    impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
        fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
            build_state::<RuntimeGenesisConfig>(config)
        }

        fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
            get_preset::<RuntimeGenesisConfig>(id, |_| None)
        }

        fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
            Default::default()
        }
    }
}
}
#![allow(unused)]
fn main() {
// We make sure this pallet uses `no_std` for compiling to Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_core::{
    sr25519::{Public, Signature},
    ByteArray, H256, H512,
};
use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

use super::{block_author::BlockAuthor, issuance::Issuance};

pub use pallet::*;

#[frame_support::pallet(dev_mode)]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    use super::*;

    #[pallet::config]
    pub trait Config: frame_system::Config { }

    #[pallet::pallet]
    pub struct Pallet<T>(_);
}
}
[toolchain]
channel = "stable"
profile = "minimal"
targets = [ "wasm32-unknown-unknown" ]
components = [ "rustfmt", "clippy", "rust-src" ]
edition = "2021"
use_field_init_shorthand = true
reorder_modules = true

imports_granularity = "Crate"
group_imports = "StdExternalCrate"
reorder_imports = true
{
  "name": "Development",
  "id": "dev",
  "chainType": "Development",
  "bootNodes": [
    "/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWDqY96nhSh1sahtNAZTiXu1KbeKiwsz9Rwowv6bBEUjvZ"
  ],
  "telemetryEndpoints": null,
  "protocolId": null,
  "properties": {
    "ss58Format": 42,
    "tokenDecimals": 12,
    "tokenSymbol": "Unit"
  },
  "manual_mode": 1,
  "add_sha3_keccak": 10,
  "remove_md5": 20,
  "split_sha3_keccak": 30,
  "maxi_position": "follow-mining",
  "codeSubstitutes": {},
  "genesis": {
    "runtimeGenesis": {
      "code": "0x52bc537646db8e0528b52ffd0058244e043e8a45b61153204c434a070534c63d412249e4094823de82c3328b4264ecc48046290950666699ebcdae36560aa2dfe3f34603e6ef9dbf9ab708ca1987befc032db52b5b8cb9c6f74e54951f04ebfeb6b7dc5b6e29a54c3205701383118610737e4e6f9fe0943847ce915b2e03850cd52d39c130e927fdec04b939b9eaa12783b2d99a602885f5d46d1c5e3827d7922fcf66ad0eaa2def0a6f5aae12a00b21ba60b1186a08dbadd9adf6d960d8df1e9d7e5ec8c5b85bb43f7efa4d8f1f095992c4fef8eb47427ceaf3e3626d6df49b7d61d273d76098f4ed1e751924bd82a114eea97396825eb7a41bb5cbd7aa83a44b9ffed2bb4bb2ea96f449e5450f572fdd48dec87117817651972eddcbeae42e46bd5237ea4ae7377f4e5d060ae31c9b691d53fd752e7ee7d2c3ebd6af6523f3ce8d7a08b783c754fc8a533248bae7a1f5f1d0fbcd995f2c837c78c8facd47a84e443434d46ab9b358a1f721cf092d53fd749a14a6bb0d18ea7b3cfbe6d49cee030c593e60e87d18a7bc38f5d2d9a9f7389719791eaefbf8b92f9c4ffd7efcdb1732d4873ce7a5d7cc56adfaf43bbff8b1b33576b1cced179f3b0df82b2885a93eabde5ec1294c45c18f3fce7906409217291843598d7e6ffbfdc2a1bfceb54b933e3cb43f3cf4de43d6fb388f5bf9f29cc7571fcba01efff1b10ceadcc7c7328873962f4f0649a760d8e479c0f07ae637fb621c4f73a3f6a8b39e7a0f18b2bca7de81a1275fd43939f43c3e3bf0f9988378dcfb988342fb3cfe9d57ef79c0e9dcae0e0c4778ceb7daf31cc8dddaeee7bf7d213f771c509fd1ad053234f4dcad70fe0479e81900596852d7938a2bfd32fbc4bc6ce996746ed715252525a5e77671b742fbe17cf99a1d249dfd5eee94546fa75fc83d289ddba539f7ebbad62de937c2e185f3a573a744f3ea469d7dccadccb95de1fc0ccbc71cb479771bcc9f6e7f0343ead6a3cf764d30bcf2d3a35fc969dfec9674ee38c87eba511bc9faf1db8fbb581bf56c5775e9b65d994be9f4e39fcf5d463d72d9379fbb4a9d9fbb087017427421c457376afa49e1be82443668a7de4ec129dc4f70762b3a0349308a675bc210a538e7b2aa7d4182e74b145d6ca334cff09b2ba0a02385a9a71dd41cf142ea470232780184185ae418638507c513a5946eb4c929fb52c4cc9aaa13ac4415177587cb6aad4e70419d78e3f1ac3309092827cc8431040c6aa420c0549b3b43b001871c4314208d0b3ed284a993bd5a6baddb8a3b25405ccf9cabd58b6c692e59a2892f4aa0e0c68d1f086002931db38617a614ecc051c2a94ecf6b3d73dbb43acf5042cca993d99ad5a6a9a649c0c5094a27cc41061733415ec031f2013abed001468d1c16d034297501a28d3a34e860a60a225a5fa6be8cc1b559a283870e432c31075fb144741e9e58232a0f2d58ec310013b6700928428f24988e8823883a2c29690f503d48f530555956cbea2657748cd8d44f3f38363d434985794a635303cad8638b39646083c311302a803567d634a1f540068b2d98a6903a824c7cb2462989246ad8410b0d0108c01b23ca50a20717c030b3c716464c983161cc844113464d183661b8a04456dbb2ac08309b0bd366946eb469365565b602304b69d0d09921862d80ba28830d56f34314173928e110158494a22fd401bd88a20d1b2ce880e10d0030d99930285936de38c38c2d577461218cedd1b427dc585b3779466ada60c49c4d4875d3193710f1a529aa0e78c21b4b84682a83c39821d2e8d1656620f3061b188c98e2fb020b23ab3ae28cf1069d3b4978a147d20d72b44471c513687c38c2cb88a309292ace400307164094d8d2b0b075549d0d8aa1fab56edb139afaa4a63eb1a94f5cd4a737f5094ead434bb10b1a315bdc446921c64892292f5f842883c60b2a3a9bfa010e2a3030b4a19303055f68f981a28d1930c63871861c5e340b67b2f94292521a70944107531163bc14617a4399cce80250441a43a0b1041346d4e9364fd3afb821ab94eae073d615ecb0b085852e1e0b32b05cfe4053060da8a9a52d550c10a3062ca25eb062cd173f30c090c1d02483c0b054617041b6e1754726a09890aa9ed5329b656d32a629386a77268c0e65ceb461c41842c03143a4c91a2931a66ec882091ce4521d159454585281290e8e020c1d41a410c61e4f380dd1a2e95e4175911801c41b766821468ea51456504c6d4b48f50e523b4c6db556bacdd5d31eab8ac50fa82a67283b358d49c9322d592626cbd4e473789e50e2a43426abfdd534fb713b782cf50c9542172937335bf334068e21c4a0b3441b2d421e70861a69e87005174d5c71a782b183c3161cbae020030e60701083c3181ccc8820c51c534b384165431330ca7a2a8b38c2a74d0f347411049b215ec8828820da90654dd34265b554592d73ac4d0247191fa098a206346808c2044735a109ce0b2f382187993972c698a1696cc258cbc6e9299b323d6968d41c5bbfc439930798357a9062822f7470b2a60729dc6072214e1076bc5abbad3843ad80f2b83553926b2ba4b6356a8a789259b4ac96d14ab78d87a9ca839bca03150f552c1ee6788bce227ea03603a2462be28a1f6fb4b85952410f2f506d0861a28d3be69c80421e5ddce1a38939174a2a5a40072f94088385342e6c59f530460c3bcc01e7cb0c53dc913f74b07632245844a569430b9b326ff8e042ce1cd6c30b3ceea45185068d17490655551e75dcb0041e51f87c01070182b87091861c31d6c88007471380d0f420a234cbbed65ab7ad4c98324e659eca9c29035546aacc1425a2b469d21ae20b4e47ded810430e43a0c1860f1e131dca74874cca21ce147aa8f04297252ffc83131d3a56b4d9e386217ab408c20d3cb4b8828928e6b0930412f18e3d6186384b35142147d4173c6e9a5653defcb0b446197a38d9a1076b5ee62821c31b1bc6c0e9be38e2878baa3ab8d0410733e6b0c32db1003b4d26c4d0c3116dea7031f0c0250d0f5be29011790b2930a8e43c41461d632e53f1c3116b20f1c69a357238e9881f9a769062e1ce9914b6a42f669c720013a70e3676b49206516daa9a96d4e8f284d69243ede2af800a616ad0e3e9841cd460284d53d234fb9aa66daf59eb825307f1933de341b1a47caae566e8a90b54444f29437d26cb5c1b5f1366ad952f02d071051b2798f1c61b35306a9f6e2103c391c6134a7c5115449b2c9a688c7bd45a6badd46badb5bf463951eaad6aadb5d695576badb5d6ba02e27ae6466dd49e7c5d9065d0f40976bd71ca9b991b35cb9757a3f2f83abfd65a9ddb153f036b0557de4ff728e865894959d3349b56b7ed0b93a6cd8ab4030b4f61ecf0c296a6a423ece091840964d430b147a6c5844e8b0b33ab554b0c9a961bb22578a4d9a10e17348c60e3b24973420f46acf145ce13577b3114474da3450c41af1843b34ad3fcd05af4509b0c105eaa9af080a389062091841a1c9ed6a803c76441836a82c2276a090a4fabd9cb535252320166a5a6d530656dfd66b7a67f1122e3403b7ffae4dac55e8d1d05cb6a99ac52cc5307f1990eaacefd321203d541fca1f7b5b2ac66331e13ecccf082163fd0410374c21b20da08428d32e4cca7383673cd66b2882d2b4f61ce1c27d8a023a60d573104115ab050c10919ec10e372ddc1b33ffff63050e83f9dfbc51d149d3db41f9ddb45c130fee6a17d766e57e6d467bbac53b7ed0ae357a7ce79edd29cfaaa9dfa4fbba453772eb24fc1500ad06f3ebb15fdc62a2f3a774ab85bd137d0762bba5173bf8cd040c9207ecdb98b6920479f98972edde2b76fd443625edeb010ffcd3efb71dd9a1ea7bc1b39962fce238fa91eba78c24d0a6cc0a85bf9220198363108d1e60535ce80d1fec2467da2b381a114a2af6e41ae5bd3b94b9281b65bd32bc8ddaa6ed4466de56bd541d3a77bed8a4f9dd52e862ae2e9a9ffb44b3e756f17437dc9e1a903f58b83513fd2af09a3ceed8a5fc1d07e687f3acb177b81860833cc9c00668e138cba95af2a26c8e9c20b3266da9002464156b7a6c7292f5cfdf455bfa292929292126c3ab78b3fb41fae7e3a034d308a3f0320298b130a4e860a6a50b37135705e38262e060e866bc6bde3d6b9765c3a2e1dee855bc7b573d1b86b705a3816ae1e9c0a770fee046ec9b271cfb87968516869b4280d4ad341cb41c3417b426b42734243a32da101a121a199d1a4d0d46862b41e341eb41db4233423b422b4278d08ad8c46461ba30da109a105a1c5a07dd166d064d0bc685d3415b416ec1d4d8b6682c6a429694b560f0d052d056d8bddc3d6b16bd82aab869db269582dec16b68d8563c5b06b6c16b60b9bc64a592a6c9485aa715828ac9a8c857a8565c22261cdd814ac0a56c92e5916b23b3237b2363236322d323132303232b22c32aaec8aac8a8c8a4caa6651b1a870aa14554e65a356552dea16f54d1da342519fa84e5434b5891a445da29ea94ad4242a1295897a4435a23e55226a994aa68ea94354a79a43c5a182a934d41baa0df54b9d21b362cad16b681cd48d5987f432599032cc2e9408da0695a26ea816f406ba454b516568a9a6828241a9a06b281bfa45d64246872ac135d125e811d4886c8eb944c3d01d280f14073a359ba05f2614d4cb6482c22077985ea61c198384a18d9829442c2612b10d15621e61edd02b260f354d5635d150273a89a9344f9077ec10991bce866c8c39439646a6c6849a51778ed944b3c896241c3d05f5411641b19047d036d91d59c66e91444c2966145688ac8e6d633e4183904d370e8b82ecd279502ba452d79126c813fa0efb45e351a728183b85f58256416da03a7415d38bb6a2c3a03fd033990a2d437b9970d813e297d8144d9064aa9769029da2a166988e6a28ac141d45abe934d1857842d4427388334419a217ca0697021d33d3cc37620c3586cac47dc9e4cc39e61c4a86e342cb4c1466125a0d1a0d9269c631cf7032705d26173983b4236b3357a828646cfa883633e3482aa69acaa5a65061984b4825a613768c25422e4187984a4c33524d4607b765aa20cf48212c1959878c42d6d156b8773814b81568940dc272a1623412938e2d63f39027dcf81c2b0b5acb232b4e3ac06404274721306172a37c32e58809934d484852b19523119c4c61424496c14847568eaa8cc004e9e8034224197c84e404c90a932752a080a00356a058399a72a464881c6348be9122c5090852a43871801821207d60ca919430f8e8c8034ca82031410ae103508e441024c1602b52a038413a7ac2e4e8c80303906e988a07a64061524295231090c004ca088f34e54884129c74e0f20b3e02610a95294c9c308132c21f8130858a0490a680800a08207c11e9053f610265842f01490a084080e2010f40c98025bb78420584a3274624176ca584a3284cac3039427252e568cad107985829e188832954a058b17254814f6ec122604285099411beca51942a543030058a931040f08007967c520b3e4272f2048a1427216072048223104cc08327471ff880130f0a20b3602b5140380a018429b68234e5a8ca510853a0b8c4620a140f10916d18042856a640a98274e5884909524618c109932a474fa44001012c0a0854a4c07ee4156c658864c34e98fc482b5804264e909c3c71827414011f59c508a04871020509ca142840e41a8e020215291d6072840402108eae1cf990525c858a03388e47523ae004690a083cc0040984a32a509e4c81c28489100ab238d91c29bc543d275d865252fa98248554a9456a8923c46cfaac7ce69c3e73ae563e73e5e3c30753e6cacd9336b3642b294bca719129a5946b6c2a2b8bc5d26cd632a3b466565259a9dce82669db2a2533d35a2d33ad9ce51eb2b69967e55aa7262be59e75c6586bd566adb5e36ab96b9d9c94b2d2cef2d4dab45a96965bd64e4a2b2b308090e5ae922b655a2b9d927665a6dcccd4b2ac9563b6dc9123b7d56a95ccdc525ad949db9c8cb4a3924a4a9b796e32d62375d64a2311da52fefc74d176b5b6a354525a6d2d0001e6eca993b2adb3d68c29a541b6672532ebec69cd4a0750059045daddb4bbb9a6b1bb69ad1c8f94b625677572ad53cacab54a8ebb878b5256cacc1379380043781a4856e66d080098593273a4b5f654ae55ca596bad5c25a5d232b3a4d552090691525ad99b8f6ddbb6ca552929a5cc2c25d72337592b4fe58ca994cc1c2533cbacca8c32d3cb5232cbcacc928747565969ad5556fe6865965c5972adb1da3ab75867ad1cc771cc5c2995b2594a59abb5d6522ae59cdbb66d5c654b66e666e68c6564a6b4d64a25959225951c67bbebba4e4ac9939b93e3b89ec9492aa5a45272524a1963acd33afdf1e3c78f4a679d929394522aada4952995959bb2566b955c6b6539236dda9c0c1c0dd207770955a8887024428d22301fe0a88a079854a182e404042a52a438f941e22a72858a0890287025c002f72c384008569c84e09a94a3101c496172c58908467c7c808a14261f9802e5031fa0224548152748560610c48a102343a280e0a40352a450a94280098ea23041ba72348582a30f08f1ac20598172e5284302c18995294eaa20314182228208545a14b005503c705465842a4e8ea4804024c8932947238ce084c9d1079c54a1826465023ec091085090a680a00a48e4012410140172e52804264853a0541981090856a088f05304890a952a4c9e1c55397a52850a1357022c6062c1511427523ac0e4084a15240258500500972d787264c5ca51951144a00202932a4721a002c25115264eac3c01e188c901a2b81260c108201c59798560ca9114c2076032850a142b558e42c0a4040f40a9721402260a3840021260c193232654904628a10a084c90ae1c012004538e2411dba5394b96ac09d76ec249591a4b92c49234b52649314b9629936a6d9214b364c992b435e1a4a424db84b3648949b1499698254b379624db242966c992949435498a4949dd84b364e926596296d884b3c4269c94254bd26cc249596413ce92254b9624da242966894d9262962c494933296bc249b549969894d44d922227d126cc4d9262524c4a4a924d3829a99b70525252d26c92149362134e8a4d0ed0559199a308569c7079c0d823947cadc4785384963b33341901638f67d8e3937c2d11632708a82cf6702306c63fd288b114c4144d542401638f61d863137b6462f9ec5189fd0afb08ed42c0b387c0de843d56b54b7bf618a75dedacc9ef9ce2a1c36b08a85d9c536f69e171ea4888b478ea18f48ba1a867d0aeebd435d802a3de41bb7e38750f3e907aea1be802a3fea45d3e9c7a0823b46be5d491aed079ea5868d8d22e204b13c8d024f5d423987eb99292120c30ea514cbb7a9c7a74eaa7760531d3ae78468c31d0b0a0a65d2ca97e0d4db54b88538f5c4437673cf5f8a60518f508a75d439c7aac8a73da45c4a9473ab10e1c4f3ddae9174351ef2dedb24ebd97989aa69e7a83e91960d45b4c3b3df599169e7aa3e92f30eaada65d9b536fa97e79d47baa5d9e536f2eda8d134fbddfb48be7a9cbd152f49e37d5cfbf5cc5c4ceb36a5cd7099b2be658228c26d4a05344d585176f30f51046cd6fee40edfaf1cd5bf2159986dae5e39b232132e137c7a05ddb6f6eb4b906db05bf6dbe817615f1cd9bc857a4da369edfe0b0e337ee370bc061840d3ecc41451c5cc036d6e20a3bd480c9630d15bc806d1cc56f1e99e42b2a356d467cf328a65df3b7375878235cc08c1871ef8d32de88af8cc0a1c41bf11f23fe5dcc88ab91c57b3eed1a41bce71c0a30cf572c22def31f6f8d3dde7320af6aeabd2698e75555bd27f59e1bb1f1f49e67d02ee6e23dd7a08d2def39043a681743b5f1e63df7c0f30fdac5506e10f19e6fc0f3267196def327ed6237ef7908ed62a83854efb994767defb95117f3fa8b48b1020f2e4f67f450c514ac481e64e04c51c70a2db4b10656c45945d4c0e28b7803ba58111fb768b0791fe75480f9f80a8d2ede678ff781b3c5fb78f13e6904f13e64603e3e6978f13e5fbc8f1a64dec73368579033e6781f674017f3f9f9f9f93943cefff802bad88f63d0c5b63a9a78cd354d7396e6ae796ba85d3fae39923aec786d82d7344df30f36d02ecf356fa27908ed2ae29a4bd11ce98ad292e6e39a46816b1ec5689aa6699a11d73c4e69ee9ac737765cf1eeee1774313762c48811235ed4c58c5060470b4f812ba08b51607d7c7c7c7c9c48e88bd451c517f157172be2799ee7799ee779eeea629e16ff43071bffe309e8623f766699f3a50a38e438038a09b6cd110397281fdad8a07406b6396bdbb66ddbe848e33747d2c5360474318d0e2d5b1725d694f1c31033f4f0260319d684f182aa88263b30eb2ceb6ebd3544d4c25bc7a05d3e6ff740838c39527138a17103665d03f9ba600827346e9c00c5431798f50edad580b7fe81f526f2d530eb218c20e6ad235d515a626a0a139d9c78eb714c7cb21ecf588f50f1ad8fdb08b31eddc8d7845925dec77d7c7c7cdc822ee6e325a1a9418535d0c479a20a3a30cf0a1382f07286871cf07001e631e03d3a7278cf0fd0c5bc6ddbb66ddbb66df3a12eb649cd3d04d0a1247fe8e8f19a5760802e66fd89d069f3445ca88b11b1dd0f193264c89021438644fd10673a30bcf579a48b59abb9d5dcd3e8acf09a17c009d0c586105df142cc10e385ac792167887921be6a17035e880b2fc483ba9810d6f62cb7f245c1121c1de8344181c41430967bf255240e0a628250028eaa27602c67b56b01cf726fb158666c79161517aff96cd7d06bdeea629a1d401763110511238a0fe202e86241c250e27b7cb60bc8f7f4f4f4b8f7784bbe784e4ff63d623c7d4f4f121a2beea8630919d6c00006acc73590af2651e041039c2722da40c17a30f89e9ecd7b867a3c847679dee352da25c3d8e23dff01e679eeddf19eafdaf57acf03d0c53cd6e676732fc86fce6c7e73a02eb6b914afb945e1b5346048bd0003e38bd71c680c4cf32350616879cd91b40bc96b51af3900ba98363f38618e309e5ce84169ce08ce4c6186142678a9d2e382b76e9c78eb6017b3fe75b19e3913bc21e22770ef621358206e81b80784c80301e240edd21c0810206fc23c1038defa6c97056fdd4817b39aa6699a53d0c5342fd2c58010ad76f895ff74b1955dbd8f2f5cf8a208288660630c1d301f7b8011e70e36b668e1421d980f67b5abe87db8b74bbe0f076a97751fde925a603e7ca85d9afb7024edd2e668e17d388ff19adb20078c395359c4b1036ff19ab7dac55071d079cd8fe800d31c099197d71c83767116afc901e735cfa05d41af39912ea6d922e2e061460a5438c1a50d98754fbe245027cd19377bc471e20e9802deba67f1d681dad56fbd657dc83a51bb10f0d68db678eb19b46b7beb1a58efc0fa07edaa6fe558f1d68774314b25a48bf978f33fca88f33f9cd5c57e8c41c65f9fedeaf998b8030715e47021e209a43256dc61020b62dc9006d15f77a0766d7ebd25ef7524ed9a7f9d2885bf8e41bb78feba91061db4ebf5d73f68723d8476f5f8752923c4f9eb48edfaf1d7afc857ab071fca8861451e552cc16ed293165b446dc1218b292c60d7f5f77a7eaf8f98e834c65f8f63dad5f3d7e3937c1549c1460b165bdc602307d8f57846be929a90a34c1874409d89420bd84dc05f8f52edeabf7e3d4e9d00bb1eddb4cb875f8f6f6e194befa38bf7e141ba988f32b6bce640ed9aaf794bf321cd89da8564822ea661f13e38bc8f03e9623ed6732b5f146843052832eaa041872798e79e7c3d00052398dec82047135e609eb3da85e43d326678cf575dcc1bf23dce6f7c8fffe8623df60698b56ff478dbe6ed1856bcf59f76fd787bc65bf7d1c5acf69b5bf98a4c6b8ea8e20e26b22803b69901c51031aca1458e345a806dce6a1702de80f19bfbb8d7c52e15d4f3e811c3f3784f17e3c1638ae79e73cbb9c771cf71dce61c676786e77e3cb71931870e526730a9f902e3180ba92a35dc7883c61166609c05cf71be81765de7bc897c3114a739379fd3c384e77c9e633b35e8b086147544ad80058c73b1b1b4254c991bf09882710778ce231337c459e7e473ce4e6fdd5a3b59bcf555bb86de3a4f17b3ac20609ae69e1daf45bd96c799d7fca75d3cc66b78b479cdbb2ea6f9757bddfbf9ebd7b92e7601f01b1e3dfce6b78b6d5b17e358eabb3bbef8ceb52ed655f1d96761d040440e5a7c985ab3042c734fbe9270d80107266e48010713828065ce6ad7d067eef215955af2e5653ed42eeb9923216ae333c7a05ddd676e94b9069977d02e229ff9071b6897e6993709a15d9b672e65847631d41d547ce648edf23ef32bf29524441e5384c1e68e2a2f5680651e95e4ab6e31c10c34496cd1e169a95d157ce69129cad0aeeb99c72699790cd32ece338f62da153fb3e3399fede2a9e7dc7631ced6bf646851c6a9ca081e56700276dd932f8e2306a63228a8b1638c09b0ebac7619e0af18557f3deb62d785fc56278bdfbc76b1cdd2d7dcca57921065aca024c4162f4a5801d3dc93af21718a50d3020d69d84903a639ab5d42af9171e735a75d4cf3d92ea0b750757e78eb5376b1cce99bea3bcc122c7a3bf52b2a453a1ef5d0fb19e6a347ef31eda2cdd4ade861da353d7a8b69d704bb8b047ba9b2e0593df882e6d25cacb5d6dae122fbed764abe7aa9976c2f517dbb555a6ab74ced02fa76dbd46ec3b45ba776f17cbb7d6ab767da2d54bb26f8763bf5ed964dbbe6b7675d7491655996d9e1a2ecdb33376e323754df9e39654fedd999f60caa5d147c7bc6c5b7676cda75bf3d6b92af3867ce470fb330df9e29b5674bed195375c2895a6bad76b8a87e7b8582aa61a5faf65a6b2de3db2b9b760df976aa075f107de00aa2777f187db8f3ed94526a878ba8931375a2134ebfa2d28cd32f86b54f3afd9ab0f669878be6b7534aa9d21ddf4ed9b48bf5ed734abe2253649a91694a59c70e174926a709c3b74f36ed0af2ed124ebfa4c491724abeaed4917564779db6c345cdd4d42ec3b44ba776f97cbb944edf2ed9b4cbc7b7379c7e41804d9c6fef29f9fa40064577f361537d7b9c13ebb4cb0e17c56f6fa5f65e6a6fa67681dfde4ded1da6bd9ddaf57d7b3fb5f799f6866a57d0b73713dfde6cda658fc4f9f608a75f47886218dd7c7b9c922f223942fb152c5ca4d41e97da2353bbac1354bbf8dba3549a6f8f6cdaa57d7371befd49bfb80e8ade5421bbf9f60ee48b2583a277773babdddb5bedeabe7da89da8dda85d47be5d8376719409567c3b04da55bf5d3ee185bdf4d125125e18c9f0c208f5d1e91b2f8c4e1f9d8ee18591e9a3cb20bc90e37c74e9e4855ce7a3533dbc90d97c746ac70bd9cd47a7505e78e4a35328bc90e8a3cb39bc90fbe8520e2f647dd494be9f9e0190e4f1024c5cae6b780cb587d457f00ca547187f7b3267ae22658c515ce8449711641692f2ab6ed497bb24f2338f9ffc6ef611d9407ee6f233d0596883cf8261f45ac6b443ca61219ef352ca8f5d1269d4f2ab2011e9f62598e44a835cb7d89b06cf7f3ebbc7af264d338c21260e35b8f801c6cee29708d6a02186a9349660b20363777e592ada3883c69d35b0f802636ff14be8072a4ea8a14e0d78d081b133106b511a41c68b3edf10c28bce6ae219c67eb98af156cfab37ea9e29c68b3ee4396acb16cc12a0faf6eb437ac852431cd55240964930642c988ad7b6cb7197c5726fb58686e414d1e3a2e8ec377e3ecf0a6290033f5d4616aacedd06e04ffae3af74f3ce5d129e6f55252f7ac89a1ccb57e6ec1e17f53c7bf67932a89d3b20ec18afbf86597ebaa49cc745f2fbf13772f2e379223f002bc8fb9e853cbb0fbf581cd4ce6e845fd6dba3937c59700419d49e79d800ebe1ebc30a360f07b059ab799e65b1e42bf38f4e23b050cb3bbcd87e2be771d18f3a3b6a3ccc42354a973edb452518a99e0190a526d1b667dce837c6f8cd6eb17717e396f287355793d2f8611023ea94f423612125fd918bdf502ceb94f4b75888fd5ace78c2a427b281f621093e7a7f88e5a3cb2ef6133fa02ee6b37bba9c60d8fd7946cddf5f74fa9190e5dbdbe547427ca0f8b99c6178e1cfcfee876a5cddb8acfbb9f7c68d274c7a160bb1c7ef48b7d865176b79b77e64a7243eab5b3de36cefef087a2cc49e442365223ecfcbd387eb1691e7282e637e252486f6d9c6565ebb423a84f3b05dfaedcfe3a8c79ff9b1ba155d7ef1a39217ae3ec6e8fdf1335004a338119781ae94c2c60886524a7fe9310af317fa3c67525613bce8dc92eb272f7ac87d7b4be76e450986f1a547672e8a1f4a9752dec9493cbce81ff2e5cf762b3e7b04adfc2e4f29bd5f826195f718a83bd2136e75060ae3d34bbf318eed2f658cf3c1f36f0f23d3f7215731bdf410e4eb3948fa9a3959d46130948a9885c2effd6367c44263bac5d427e6458d9be1cd27e6454cb7d83a7b183fba51bbb59ed71eb23e64a88e2c799885622bbd0535e89674a32f836e49ef26e2d2b377114d44c8552f3d847649a761b027792143bdf4e94619b4cbba740d36bf9ba55403edc3cc43eb3423420186718e85a160255c2f81739ffedbb18b714744737e0f3a221ad80107b20c7aa3de3e221b4c2525faf3b9db202a29bde6f6eb670d64758be3675ffcfa85feec977e5142201f8812ae6f7f23473ffadc69602a2919f58d4436981f4a19fa26dd62af6095f95298ea3d38c06bd02d76a3ae2778d3afe4e827bf3b0d442525d875d979c05030faf5dfc9d1eff2df26b241382bf841b7d893fe4e291ce5ea5765be1456cd2c57bf70be07dd62bf6cb3acd2293b6a7c79c2a4d78085d8eb67ffb2a41d99f29010ef3c910de89310ef7cf5fe0a8655de8885d8bf9f5f38f4ec4fb639aadb13bdfdc62f668482223f44860861059900c8ea870f1faf87a7e3eea6d9acd2293bb2503b7724c43b0f8474a3ee96607ffc596252779721dd636899d943d64b0e62971e9f3b991463d2f589c5c045b7f8c3e8d52928bd9d3fae5bd3d9c3ea5efd567978d1ab87dc92e8512a68d44d8417723f3dfcf9e93fed9ace6a57f439e7bc94d6e6e817c3f9917efc32c63c46f8e9def34bf3ea965fd62b1846cf9cbfd07bfea6f7d19b6510bbfd580685f6994630ac4e3d8c9e81b35bed37cbc3ab1ebd9dbb25354a74ee56bb5153252f9cf1b3dd6a9f1fd2fce846dd49b4e31d4a27ad734e4aeb182bcb79ab95985abfd95afbfc38793db4a117b2f8e54d37bc8ebbfe356cf2d5b72ab399d52ccb6a0622d1af21a04337ca35385bc130e9abcfaf1b0cb95b2143b919f348cd81fc069985e6fc6abc93d6d6eaa77372bcd05a6fb5a2f4572c24bdc9f0e644c017366aac563fa51a9781423927068617ce8f7372d3a5876edbf0c23927c8c539ad340109933678b366b5cec9030c4b3f63d329e8758b7d82ab6eb127d9d83f5c069af7dbe3376decc6a0ba7de371549731357ad04ab00a5a1934db153f1b86c75164d87c68e4db3da900eaed967e56162062894952f618d5ef8c4778a194929a57fb69ddd23cb2d872d6630bec918bebf1ec20e0977bd02f231954ddbe69669fc2453f9c9d0a5f00c4d94960d7caadf0380abee0d959f245c4d923c0459eb34b205ee0c3d93b68978fb323805f4d6450f51fdf2670f6d6112eea9c5d882fe871f60ad8c5e3ecec6d3dc6568a61229492925212d6af563b6f7529a77df7564efbae7397b9515bee62f5fabdce1d77ebba51d72e76fd669cfda88ce4ab95c2c8a0ea2ccf95a0acf5a8be7aecae7397e48b4878d1edc7e2a2306adf8d31d3beebb73b213121ae5d4ed33a4e8b7f6fffad1cbd423efe2b5310c26d9fd472e9047e2bb76d6ed442bef8f77e52cbf5c1452af9924b4af2d555dc61e4aba538a83a15d512559552951287e930dc52d56f6bc95acb8fd6c29d92c894c417a12954ee7e528b579fa3989e3e4ececb9ad02e0f0c30643f7e0059c92536da103b7e689ce7f9f0a9aaaaaa52b3b1caf0eed5b8ee936b58a8a58238cb432f88cb170560105f73833c473149b5e58a7c1136e49353324806b17ceb48e038215fd64d20c28af8e5b88d9be0bb7ca9f0d8a86fc7dd4fa6d0e5cdbb51df8d13f2c5efbadb75178c663ceb423efeac2321be10bf2c83b89f1cd3ad1a5f3adde0c9290fa51327e4e39752b60ccf7ac8bdf5d5aa5bd6ad5bb0a1ba559db7acfbfa857cfcacafc8c7b0205f683f72ddd7ef7dfddbf7e36b29168a68bcb0a1a0d4dc8eb3137c9a740a235f72a9ab64507527252725272596e7c9a530d67aac0f3b420df9b6fc380a0e1be244be2d4b0e1be228388c48fd1b3d6e9e3003a5d427d9300164457f3839393db1f1e1333db92497e4926452c33d9fac2256509de7936c7a382bffc64e497f0776957cc9a90eaa5e9de3051c2b0865158b55f535943d2749fc353f9f9cea045427f2712720946fbefa904f72d141354ab151739f9cea56f59e0d94da27d974ab7aa4425e1f4efb240a1e47b5c0f41cc5e4f4fc990f17bb9806c6293cebb6a5ba553d8bc9352c543b29c542d5e3192f6ca9af1e4aa9afde52cd868be2575ff9e86224c43b7fdd7e2c2eba20104efba2111e47bd00e64329e7ab478f5d12cee337e72e098bf19bfb705ebbae5b4bdf76311b3f56b7aadfefa75bd5bae69a6b9ef9b59fe6578bf782a1087e03998542ebd9120df4b80a46917356ddf2d250df6dd45ebb368f1e27f8e89cec62d16edf181e910da25bb7ae79685f72b28badbad51eb6680ce340edca9c9b5aede24e498c91309594bc3cd2e6f1bbe320c86f60288267160aa3f679b72c0804b6aa3e6c7d189fb22f72d1ada96e753ce32c9fe493d7138c4fdd6a37d3adf628c66b0f574fdfeefde25eb5ff1ce1a2a8d45093cebd97d3348d73ed5e0e8c725dbb5aad60a77dd52ba8714701866de1729d07e49c8bcba0eb1de83288f38fbb95a593b6be732e038511ea65fd326a67d691747a4ec7e9d6ec2aab5910a9dfabfa49ab9dc043d65730e47e78f595fd6a1d0810b73ec1c71c64c1ea40bed5f7e3b39b6bd57ae54024faf3ba167dfe04a35c70d28ff43da71b18c5f3e99ac76e030f8c129dbe0646b0d5e8383f2d1826bd1ab1825a29df38bbaaab64d3e6a1f719f38b480621d15623f3ea0d275e40d56a745553b51a55757ae60da7a95a8dae924dad06a54d455b0d22f9ba2283a4777e893690e886442ffd7a5cc42f592ccf7bad490649d7a4e6d1ce6396b99739cd588b5d92cd33af3e7e9da577ce9de6990786ac1e30f4be6a3c600443fb9ae67cc57a078696032f18b2a4dfd9ae0a4a16cb56ebdd25d9bc7624c4cf34ab59cd43d65bad3f033d1692dba77da1cf4bb75f183f8c4d1f5b435dd56a40f5b40f2abe5cbff8733aad4b90c0f9f9b38bd1af560b90c82e5665178b6c81c72e4691b0f350bc805f3a92d8c524c3a91f7f7356bf3df429a8c17c0a66209f8246fd14c4203e058986e205fc1444d22da97988e4c3f6e9949d7aa8390543242f9d7649e2d75073493d3a1736c881511a0ce35fe718446a0d44ea495fba05f1820b46d19cf3a97173e82318c110a92d88154859ed9df30b634cc6abdd1beb17cedb6075a3e6beeb4692a1fe3ae7465d9dfd82dc2d8d0b2777bfccb52e769dfbaedfc8695f385f73aebb24996bd58dfa7ed372deeae36e452c5f5d7ee0a4d425120b6205d2a5d72f4cfa3aa773474112e44fe62dde342efbf856dee3e35b6561de9fa396a0fe4a8e87878787c7ab4f8fb15b323d9f39a75fbeccd12e966559f5cc48ce2ec6d3b35d3c204f9e737a77b1997dfccde6b85b729fe70be3f37cd0ad69d43c1f7f06723d6152e6757e00cf512b4c7d0a605ec873140a5bfe4a8ed69974e49c8e03c6aa6ecd0946383c753e523ff5ea210f58c124f12310af60d87e9df9b5f2d0f3e9d57bbe90e17ced71201f77508f275f3e5c76eee3ab8f39c8070c91e4f778f501d9070c7d3cb40d72eed3f9f5f9713b781e8824bf39ef3cf3ee9444a13ebfc128dca47e3dbc20f58cc7e96751787c7ae7b1db80078c429dfeece0fc74d92da14fb3aa9f6088d4df03d65a9dbb58e7dc6970454949e984ef36a3ce321a5b9f3916299f85f0d9e43b77eeecf1d5b32ff40d561f4af9cc8d7a9210bf8253569f8151a85be72e0975abe4d62fe480587218906e023e7ce5dc81b65b9967599679e65dd6f30101c46fa45f76571f7710f5fad96e5107f2711d443dfbc255cfc7e3abef87775ffd42af53629dfaeaf3e1f5eb3cfba809dfb904f26d21c35dfff1ad9ce7eb7123e9e3eb3eeee3bced5b75cb7e7eb17ce6f3038d24771bcca7f18c58c1f4e91975eadcd16eb16799493dede354e7b9a76ebef51ca5c2d35b6f6777db9cb3af3802d63330dcc07ae699c76e89f5cc3fc8fcba9134eaece376f090faaf672e379f9d12ea178c92f97449edd65e66af83f6ba74ea1c92ec4e89f528178cdd12eead7b9b26dd82a195a4cf40d0a97fd0ae2f9e112b9020f7d67309cecfffc2e32815aafe7e5481e9879ea396a85e06353c8e5a7afadb439ddbc5393bb3dff8f5dbb937d0a44a764aa46fceedea8c3febcebcbdbb58cbf075b10cbc43dda25e3f24dda22e3fa26e51f7f1b16410f506bd5bd47f7c401d44fd7295c3e3a815a03e01cf512b2cfd8d5c7ff72275e6ed46ad69dbb66ddb96f9b66d9b73c741b779abecf3fcc68fbefc9872dc656098f499cbef0be7c72ae3ec62d9e69ac74f82e1fce8da178ee0a3d7da2ea3cba5ded24ad1b568e72518566f8f5ffded0baf3c09f28e9d971f92407ef5b38f04d929a11fedb4ab7a4bef50ca23b59d6f0f5bc9a5797b04d39987b1498c0fef0c0c49b0418d1f8f748b7accc1ebafbefcc2125efae4b2afc7e3379f729acb2ff45e36962b3544fa391f46dfba0de46ffdc92f9c2f3df348152f68cf4096f20b635524417e187f33eaad5ba28161ffe61de17c88d479f4dbcfe321527f7b86d411ce47e7d9af1f9e398f67a0ece883078c227d6b8fdaeb47267df8e6b2fbc2f89b94d2fb0be367d1e517a96205fc3d5f78e4a97b5f88e4293f7711fca05b9de4cadd9c8b91eb62e4620746b1be79e4c0fac645e7787adcdbabfbf8f1710775ae7ddc2dcd2ff755bff7e3f7be2131cff3d1b7609a5adf9e8d40da8f7e0cf3edb1a9ebb7b7f8e5e32d8513f3cdede021c98f5efdc717c174506cea56bb8fafc541edda083ea2eff9e2d3f37cf5efc74e6286bedd7e61096ffd963033f7bed6f77cb1e979bef9dd1746a66fd7be3076f9f6edebba25dc473024c17bf59b71dcd77efbcd67703e03dbef10ee074f0af79bf5cc4329dc6b9e8121bff9f621dc0f1e92fc0d8c62bd7ae621927ccdf9e5e399731781ea5af68548f22dd87e7bcae60949f0d663b7017dfbd5e319f102feea5e17ab703ebbc1fd0ac6336205edf3311095495c4f50c49569ac1c237baa966e8f7ebbbb47d2f1a23733737fa17dd99167fc06c3f099853829c65e7339f6482e5ef61cb585ceb7f730173117d5678f9d929a871955743c734b7631ce072ffa6d2e72117d76d9713e7871769c0f5ef43bb9c845f2d969c7f9e0452eea67af1de78317fd562e661d05780e23dcbca1060b45a43903c61c14fdda69655b6b6db4962db535084f88e5dbdb85db23fde3bf930b2f3e43b941f3dc2dae5bfd24c83d945e82b65b71c943c10b198e988217f215cf5ec60b8f3c7b103141783e62b067784ef6396acb0a1f5a29bdbb985c59166a094e1fea73d4962d1f2f68a56fef3c3e9c3ebb25dd7e510e2f7efc683d59c38f387e442a186a8bcf739416aa14a25f373e5eb788785ac47c740834b3f4610f7f3e3a9137dfde41bba2f3e7758b880493f44be728d2a8797608b4ab3ffa4fbf08f004d46a57f423fdfa018b8e640f153e3a1114b0e846633e7a06edf2f97802988fee41bf222cbafc625ea8be580c4a5f2c862df2b5850c0a0e23c3557c8c7981c3ddc5bcc0e916ff8db3394e1e8e538ed4c3934c784ca5092a76dc89295809302101f6e2d92b93f1ec538d676f67af3ebd9da2f1a263f1fca3bb7c0971107b06860978f60a862d0a860b78f609861e183618b2acc78aee1ffa478f6ee5cb7a74e7d71037e4c4d08616304e50c0a2b7f8e56d3953859ba522b8100316c5853637cc41869d37506c408e1b4e6bf830060d3460d1b5cf8b5b78f1a91c4f9ee185f185e7aca91baf25472268c10211027873aa02cf8793053ccb441047c61254f621c7f5f06b88b3201ccbe3566bbc15573fa0d6cae3584e34c4ad7eb2363e0482aa2d570812f9e5f10f7e19b177d02f66a2765567c7a05fdafdd0f3d43c23d1a73e3d4ee9d195e8bccf3394d219cf9d924985b79202f499673fa20f836e45df80379fa394a6907cf421ef3e4729717101cf32017ada17c0abeff58ba158f56b752bbaf61de9a0e8f463ad3cf9fae9a0e811e8a33738a53c0d8c3c56bf1816ddfb3561d1ed198f7ffe8fe7a8139cf8fb1cc5858a0f5b3f73b80c147698977ee7a8a232b24ec572e3493194b7582a36531cd68783a2cb2fe8a395a397a292e7b94bbfd2ca8966e2525c5a8a4b6fadc7245f7c27275df07a8ec752c000e7c306f372ea432bbdc1b42b6ca6972ebd99bac9b64b1f7267b13cafa387431fda97d143a20f6d9444532fa7f7cfe81d464b43f5d26f84c16b7719bdc170fe6ca6ce607fb68bf8d97b09af7ee8d567d52ddbad66aa373caf59453c20cfce61f7ec74d258d927f30a72f49b3ec3fcf4d8c566bbe247e7ce7c748e517ef159be220745d7ac8f1066a17e066ad90414f2d433333333f31732941c4a7041e30c1fba58610d0c50c951040f5cde904385eeeeee6edee30539bca859dac2881538ca8d295c7822d3c41c14ae7d8e6ebd90c59ded1a3cff70e8a30ff1eb09172de8b480c6cb154eb0e844fc4ab2c1e90d2919cabc8006132cba11bf246066061e4c3073471c3060d135e017cb51c208385c8012630e3660d1796aca711928bc2d84273dfa16af9b74ab37d0ad2621def90f26d0b00825833a5ec0a3f4eccd45f1d93de9138b814eb7acf53c16cb7d7ad87a76962f769e4e78e14f3b774a7cbcc742ed33c6f6e122752b82e1853ce723b3774b29bd25c82cd4b35b11b48d86d73e8df0a2b7b327c5189fe61cb72c4bc49ace73a4a88818ca23d55bd64ff7b7d1e9ed6b4a6ffbe9a3c734f8825ee215d678f60fd83b902fa11a5260618b18799c210563d740beacfca0859d1eb678a2010c18bb113b917c2599598a430b145be4b1c21b18fb907cb19a1e96e8220a8e295e7803c6de72961deaec914ebbee3315cf6ee5cb8a19289c79420d1d3227c0f889244c689386196dd2bc81b147aa764d21fa28d3abb347385c349f3dbe69d77496ce3cc5b34729f91a12420633de8439014c5cc55574586bc245f1656b206dbf92c0989186862e77d81025074cb6f1a28e1fca2051450e60c0a4b3240c6b5e4a3094c2555f86b4ad81cc212bf43430b4606859dd6afe70f55dc1d05230f42608932e77486af7603688850c831eb44b108b742ced49485ca0047c8112b027bd3d761c23ca0006f40f99ceb7cf1c3c19be1d094bdc12bb442b83daade7b158ee76ba740962913e414bc403ead32788653a0593be9015b9254f74a3b6f265e41135518744df5df5ed61eb43fb2d5f0cf358fea11d226a309ebf6df7da59fce2286240620a366578e1851958d3d0c60c18e4b820c7863ab0f6293f2b83d8a34c8a4d9b8ce48b082cba06f24584412213984efd02ed122c015802321e486f90083bc3a897a07d82441824213e3bc3a6338c3ffb793228fafce21dcf3ff4242e2facb104154f5257a4a9a0cc983253684144174d30a9307adcb1470f5f307da1f4830f6c1861c60929e0c0a2cb8edd49dcf8a40990778b8584bc6521f6a983c71e02711a4744f190c69c3c8250c2009c3769968640410534435c7cdcdbef2e66bbc55dcccacec6d005e8bae10db56b56cb7d2192eef945e9f3e3905039c1fe420c3efa8cce455f45ff89128736ee57b817f9a24c17217620c20c19079c31c50a68f0900595155060b0d1250f33b884610406ca78634517519421440f6c628c1c46137558f0e2851f9a9e92764843c78d99378088e3041b442863049c2374b882cb0a10c0a20e2bead040c752135674bb7f7737cbafb81fe7ade14dff154b217ae9517a76e7ce9d3a3f41203237ea18104b0ecbc02c4430321424c2c1fc1946a4f8d28dfa935e821ce578a334c40b518401878933a8e258a3852cc66c91030e20def4b09d6b780e8bc848830eda3d6857fdf60fe47cfb06fa95c1da9f7c48e26720120cd87a5feaf8aef36a58fb1190a85b11c9c72024187004c31f9b0104da15329491060cf5ed530c145eee9891c50d67b8c09a0e2f61cc9922ea05396c602dc677140c69bebfbdd53ed4df6dd400788e820187b7cf5130ccb0830b60aeb8e2852e2e748953451571ba2e96049df7bafdaef6f1472d5a0b615ef2e0b5ba55edc742114d4b0655ef3e20a73d7477d635cd4651e1f4996b31ce076f7b8ea2e286d7dc6e9f6997fbb6b43a019c77df96258771e0910eaa8e82c3b81310224912dffb690f1eab5b1aa56f3e6c00436d5d6477ebd8b3b349d82abb49bb98f51b3b6bafe4b2db797731cd3320676d5feb7e9dc74e091094673d74ee7e9d679fe635a37176d7effd32c9c58bcf69b2987ace335816547010fffdf839b0c5402e35cdde56e56e0b4bcf9f65f6665091bb6c3eac20c67bc3dccca9674e37ba755b2edb7cb2bc95b5d6daed2392b90523121e7bc6a5d52d9aa43ffb80ba45dd96e1651e729fd1cc33b7208b7ae62c449df5c345f169b6f1f6c5243cf655bb58f10e8b8b36304c7a0ddcd07c58c153674dcbb26cfb66b768e6d6ab53b75edd6675a862b139f556dbe6600bd2a5c67426bdcdf2d6936c20110eaa6f5e7df3126479ead537d77cdbb68d3fcbd1af7e48c1ac044f9db74dc3f216a4d917a52ea974e885a9afcef746a7e874efbd9ff5cbf57ae8f37c3d14f27cb5ebecb1e3053ef77e21eb7aec629bdf6df3213812c142d559f2159f3aa84656646ddd29899fc66bf1b67dfc3cdce5eec7d3ddede3ff200d134dbfc5a614b4a6f0410858dfe31960570f09f215c2075ce43111133191cf73d40b643cc7bf96b33c5f7c9f2f06c11554f7be38040b55eff962089d57d6775ce583ab3aaef20176318d67fdbae5f1cb97ce39d32cb187cf731a26b670f1293ac531d1a909cfc7dde7149d98aac9136efbb806c142353ac5a5afd5e352171e1eee8ef93062a169f18b1fa7b8f6c8c8b28fdbc1f3bc396917679c136479d5e99c3e27c8e643235d12219f79ec3810229b8946699f524a29b5d33367975ca439fb74768d8b3867dfb8a82be271768e8b7a9cbde3e1221f67efe1221fceeef970d1cad97d701190a2099c7dc545419c1d0817b19c7d022e12e2ec41b86888137176215cf4e3ec43b8a888b313e1220a9cfd878b8c387b112ef2cfd98d7011e84ce9b55fcbd0adeed22dd95ba49d4987c6a970b237960b8dcda6e6a2e1cc746378b8fa45315cfd22986ec92843b7ea17bbc42dddc2d22da46e49e9d693205cfd36c0e2eae78110ae7e1018c2d52f03225cfd30f8e1ea87a40857bf231470f503ea96040047bf680457bf1fa0edeb18ea570589f59b5741f2be7a15ea48f6ad1118beae99c0af57a04005ef7a69e9a57f5f9f50e4b96b138c74ade45fc4e3e70e0aba58a7ce4b37f2453988c451a48b73e6bc740abed8c610367eba5855f5d28b7cf10c216610e92215d54bfff962182c308674d18d74225fd422481642ba3835e48b554cb086d54529a9972ee48b69804405e92214eb8b4cac9698a08b67cebcf4205f34e2471140baf834c11785f011c4aa8b4e4e2f1dc81779f0d9e14717c3485f7dd106ef8b8f2e36fdf8620c3d30f87491c9c71757e051c1ebe292cf174fe89ebb68424f1795bc6f04dc7357024f77a5e7ab729f3b1258488ec0f385db730785eb42e8be0e68cf9d1316924db84f0356487e20fd7e14c89ebb09685d07dbf7802a24359082d1e7ee59481a31549102584812d1cf02f9dc1d807643da47807eee8266d7ca3e1000f1b9fb58483a0b499fdf1016927e81b8da05cc87adc34be7b7425848ba125ee8bdf4565c1405603b5a4a6de69156192b659581c609d62a66599c737e99cf312fb32ccb6259e6b2a3ced4631247ba7524cbb22c034329434fbd15c70b811ee8480b687e441d051a669dbb09449805876410144612e8c88fcf39e79c73d2966e24b33361ea5ca963b7d8922fcdadb373644d102910c0b3f3c41b95b42f2ac9a0aef322a2eec50984bd40c32c7865e8eb570257d03e3f1270ab630d2ccf40a298c2b74790c8c617dc605112bfdf7843dd2ae1cad0f71012cae6c3a84386a5842b75c2d4b659c43a146b0b6fbe59f4fb61591aa5ac9f379f3cebd4c3a1a19e5d75fb1dc9ba24fd15046a45cf3c047a4b67c781101a723fc95c060a235364aa26f2d531a3b62c3956bca03afb90e8b23ef40a2b781ec0b39c022e9ad1b32fca4b9bc40adaedd781d86a9f9f0758a89d255f1fe0a0f6e63b2c0f3d39df2c3be8c7bfea624f78610cd9a3d252bbfc1b663d2227b16b72260419d4bef11c89023ffd3ad034b0890c6a5fc20b89be89da25bd1d83159a0fe30b198b8b5d8c997429c657f9a45b9dc56c661e7f66953a69c242ed5491296b4bc710109fd6c35a9f5a6d12f033b7ed406ea7acf76e9d122146ad751c08d143b68eb42a1dcaacb80c7467bbee75b7d67a8c69edbaeee3ecd7e7dbe2b98f77a779d4be9884cfc730fb01754b73ef6b7502aa5f19954479ac6e9df1f92637b9dbc5ae8c9a7b1fc3b48eb3b7d334cdb9e3ae8b697e2fe7f36d21d3e33e1e3bed6a3c3e1fc3ec27b978fd1c25069adfdc3a77313437fbe2cbce82d18aebfcb3b360fcc193cf697430f3d757ed82e339bf9916c9f57c2dfbf1f8fd3af7f95070989608239379bc1be7f331ecda8fc7bb53e2ddaacef3014579978dfa05395faf53aad1eb16d43a0b4633def5bb71f605371de7831841bcf5ab71917b8e128388b77e37deb66ddb62c6138ee037b0d5ad2e49bf7f40d73530e4fe7ae8d7efedfa813a67a3b69ccfc730fbc2d4f37b1fc3ee9749c981b25b92691ac88a7d2c549df5d5593f9d0b763eac80daf8f1ecc1e232736c82b9d81e6314628e950e245f9b47183b3f21e3c1e6da067a32a86eae75734b9ed002f1cb9c7ef16ff685d0ad18110d70aeb907d7b7eb13f480730dc442663a0712d1ae8a079a5f104b4b06b56b1460d8900c6aa71d079ae621d1f736e5f6314cfb1856bfcc9ff2702c5f0d0ba15bcdd16f3aed36009f7accfcf2d6350fa5495242ea213ce95687d4a3cbacd22fbefda244a73e3f9b394f9434ae3c86b66ad0d1a9f5ee36d032bf1cd75d04b8a10fe10d2f64383f1423109dfa1329ede21e9e0f36e086f33aa09f07d1a79c01e0a9601869f4b8a3272cd4ce70e6647d67581579edaa94b3911b838bf8a35b6bb36a3d1aa3b2d6ea941e89ce45fc4f2965f5a55ff54ba9b5195dd1326efb8d17b4c642b1d9a31c73516c90eb56c72c0bb5471fbcd0bb4b32dfbbd59188d0e3d0506b43b45332dfeb567b24c2e397beb25cfc348f6034a201df2ebd855ef3d83d9dfaa52e350d0c45f036faac323ff4bea5f49b711c2fe067e7eef3335ef4d0198a4e4d10c7f82aa9c7971d07419e82a108be8252764ba64b5a27903cc7b03d2d67a90c178864fdb07e82c93309ebf1d4ef9c5d4c7a9eac403ca1089e82928b5b9b67ec19a3f4e972fa7439794e660b784211fce480a21b97bdf959f9711105ea0c74697420ef212494d6cf28838c7ef188a854bd36791202ede8966e4925f9f58b4a5fdcd24152039c5f100b19eb1c686590a400c3220784c7b00dc6b09b7df1ef87858cf52c1bec7afdc2a8bd05c30e8ce4fd187663b7c4e7a77b1f2d977599cf2f4cdac0c74fafb55352806b37bb558f7c9b678271a95b720b9729b5cbabb4e3b6afced12e56593fb4b2ba0d32bf3df4a5c72d587e7449fa91be2b6578ec21f7ec2b8fab9f45c36befc0830fe4ebbaf45b3ff9f7bbd241d2e987e4837fc40b5a699501b92ffd4ec0d5cf86e1b5c7a8c4451bfdf88974d4ef956e21754b7efdf78b4b5d546221e999166f7b2cdd927ea55b51082f643a2f1d4bbba2d057e95778ba585db5eb470308b0541a1b1db26d736c43e20c31434811220c88d2f8a1e3470e2214705ebba8f374315abfd6916ec95b359f3eab6b9e7d71ac068692822ec957e9985da45b523dbb9ce42ec71372e033bf5cbbee62273bfaf184493e7c361d5c31f98c51629f517e367e1c6db9845b2263d269bc73e310d6edf49e2a29fdc2ea51c09597446334e3eafef83767bfdbd79241d2efac5b9c6062f32bb9edbb5e33c0b00b9660738619f5ad6462fcee62edb76397c400af79c7a380962c80f4f8e46d9ea43af5edc3323dcb06db6eec38a014e0ce836d826107afd5cb53b72fece0ad536f157adaf5a695d423487d386ed704f29e2e46c6e364e74378fc0c6b8f1e7a7ca61ebdd28f55bf9ffb83db3e22ed494a4a4a4a0cbbb2baec92b01406f8eab3db60ab9ecd4ec9500672dd8ae09065ba918c375d7a1ce34d8f5609f5ea961a75045749338ea008af7a07718c9769105a9f7e69c73373cdb71a3dcb324a35225634989ef903d80a088c7c0646b1d5efb55f785dcaf6d66fd671902961358ef8c20602acc6115fac78eb37f3cd8d64b6647b0b6ea05da2b9ede78e9227b4808def36ab5f7c06a260144f89cb40a1f7f15ba90022ed3664929b5ffccb53761d489af3250379b09e4d9e9f7356ea752b5eca655f0fd6338f0508598d154c8f24bf2e01c336f3d3b3af872433d8ccc1c50da9301964dedd03927e7ad639c9206b24be8251aa5ba920088c3021b17452b7cce1763c69bb3abf7ceff5ee62b7a3d7adf58cc806b68c17e5fa1ce345b11e4ecfb80befe6f2c3a225de8191e93ccb0693be0aafd78e034a812f30e9dc7d20848d1a477c61a3c6114db0c9453263bceb5c94ebf35e376a1e100c3b78eebae6f1b52fccb21510dde2a4e146ff91deaa5b1d7a51cacf72934aaf6ea75d450a560eec92971e81f0e292097ae04ac9d04b50080bb5b3bee08f5c647b4e5ba98773ce59c5e843509f8408f5118a8fcedd03928e84618c1f639c9fe5a6530fed0674ced85dcc8feb96e4b853123dab1e521a6305ad1b49fb714bb208ae3efe2b39cfa7377f2c3da9b190b42c2483f0dad9b6aba987f1c6ee94c4be334e963ca1059e52e73c376a5ba387b51bb461bfe50baa9010ef7ce648d6bbe34789558c9e04231f825a2549e94968c047ffb8720692934d74f2a25b4ee3abf85bbfddf19c4edd6b17bb74297d7631d9ecd4997a55329dc66c25e7ec96509f6edb7aa8addac5811676f0b6a95b2d33c087d91b5e74ee94b0120348f1591a9f4de725b22712773a03855efb8c946795fdb3ad53cffc7297845948f3cde3373febdbc72cf48549dfecb14b326713e1807a9e9ba8d468d7caa3819a4361c7149aa111840105e3154030301c148bc5238aa2c9e20714800f7dc04852389348e4c128865110c518450801c600020021c020c3d40cd50638129bf846b091b59164cdf55bd7816e409633528a668b19ca8cca173a1e6d70d235ad3edef93ded8f34bfed0b94f52d7d919f1f32800e7d010649d6e8aeba1a91673b73cbca5835577c2befa92d16cc1c9cb3f4ff92108b9fdf0555e29725d1c6ddd9dcc20b6e220deb64fb940b0c94dfa7c244d29179e76c77eef8db7926bea2635be423334dd30ff1a807adcf3fd47964d269e8412cd87769523c84f538df36026f58d4ad134bf50ccf3ff0bed97a37cb9d8e03085105db019b0652616eb21fcae09be7dd779e5e339facbc7ba62c3735f71d7aca29671cc192e3923fb2133d2a923aa00b660d7130812006385f9a7dbf43aabc032de29e3cf843a0298353b301c22c7f44b8e51ddb502d7afd73fcb7fa1f62cef7e88deaec6e7b1f1e17190078ed9583fc211044f5c258aa065d82982e88530c5c935325882e50f0d0b960a7c4dde6145494cbab47b108f3d9869e6c6c3cd7a0094063d5f1fa54b5d9d6c87648a93f7dc6db9a84fbf580b55f6b29fe7ebb7bd8df0b5a28d4eb95ad6e2c738be38d3a00751248d6ecad434621071560b250673308999bb1614b116cd1300c8682c962d93e42fbf415bfd774de8722d2d29e846c95c418ee1e188be7522f9ee6ab9c696111d47d8906a763b88faa8c1a145ceb7d861167fc38b20dac9cea12ab9c73c0e08f94a62636272081195c1e12eb0dfe96aab227c601ce3efc0f56be57a6f7dfb3778ea8bd9d33ff72902aeff5da2b8b55f4142d27d3407ac4582a602af4bb9d5180faa474ed46e8db823ea1ea978f737c9ad7cc75a423f28e66cda69345f6a9a74107ac710d9be57a25d1a141cc5078c9cc46282d4d4707884b0c75a16b03de4a8323c224ed358dbe229754e61b20a394f40cd84c8e6e8615e70244ff9bbbc57a1914cfaeaab7c08a1334538c95830b4f5e620d6bcfd9e86be3dfa04bda10de6a8a8958d4ec232779775fb7da656273e985946419c9fb2952ad57069ce9c4cadeb4a31d6e95827669647455d5abf7da1b258d467bcbb4f48444b17e1bfdc0afd71f9292d3ebda7baa3169741de7a741d25f08c1cc3faccfdf8acb484c06d26331a90dccacce505a3a73e2f673e6e536c53e1ee65d269a698919c3a0cd8b7a9a8e3476a827d6f7057dd37bd761b143b3e770661fd7ebed402705eb9e6cdf30bee445a9a44364d4fb58a1d3dea8cfcf4e101ee6e42d3103ffc97ca076c4c57336245f9123e63316c866397715acacc007242095b567187f13c3554002cd7ec838b87e4100e27e12b892225a5ac0d5570b685027b2e361c3056be42a65e398bc79e576e45375e4d837f2205f0ef512f8ea3751d87a1703fad8cf5befb237f2603e1cf50afefa53f8a44bc12904dabac51bd42548ef8d1ef7c2bef98f2a4121ce45d2d00a0665178f3159bd95775e710d8ba08c6191b78a0abd49716277d1a1acdbc4a6332eeab51f5bb581a74302a364e7e511867d1198510a0f4d62491e1e50d9bf42d761b4bceea0867e1ada594b977e20899d8043d1558ffb423631e82b969837982173debaf8bad5ff4bbcffaff9235f0f3571dd840bb0d050566757504263713fd5a504aee79eef417d15ca47c4d2b73b65a656845a99c3e3e713b1d4a8fd097105a0c486b84c00a189fb63e6bc6948b1f2615b34e250bd8a686d94ba2b89b4fd786c84b60da3998ecd5e5243766fa29665e14993eb2c8b7f78d44ea5b551838903110bdbc6ffac364bf4d7a802d97e05dc2885ff538124997c92c9af587e9838fa3005a8c869a47063cd165ce0b5577d6b34f470d9d7f54f9f7df5c3d2f2f862569a0085faea8df8111f324fee4e11f56b47044286fb443bdc7dc2b81ff07e5fe943f71b6dea6a9282e201990ef58102656714dcb0cc96e5f0a4967911d29de6213b5f99107abf5a421b7215bc2ec8ccf74262c06c892c6fd5c73c9fb28f69df15f23e2c6f9ccdcb64666780362013db02a23def7233ac1ee8b441ca258ae4b9401a14b937dcb3aed25360435bc3d5f3ba2f6e9e26dd84af8db064f90161394ceac04ad62f885deb412035169301d133eec46dfa44daa218b4740d2d50ee2839062dee18d20f592b4a42628271867997b49c5a246b812ddcb6da91f8220ff581348cdce9e47e9cfb97b7394cd8ffa3b46f4896b5e89a59074026452975dd170a0eb3b3522f7ec4b58d09e28944ed57f88eef2d2d38851afdf827e073c4da49347249683cd26beef12f50c0a5a416a1645813bf2eb618fb970084f1666cb91c1bfc9ce9c3f4b4cb6ad808f4ef27dd78694897d65a850368dd747a2a994fa961786379b50b31e11885ffbe029a7cb9b75980fc94df2eaf4e6f0c0e906842679e90eb67d16aa9ec8a39790dae8338b495526fc17f320736a265824bf5dc84818b8279015092217e3767c5a6ea00e6a80d965860821df01fd57227cc44e8e83be8b0a988cdc06aecfef8e3e41a58063309b959557c52613927ac43bb94b323542846eb352edaf11478b474ab9c114a4995066f428073d8824018211088bb8cfc6477a1c1c0d7cae3c07336ebebbc8975c2dd879a100265a506d4a45974c2b538052dd1263ab20c56eb2053658a59ebce168ef4ac3b947dd9520636606d6446fd5794885225251ab6c0d31dcbd1e0232fca38d93fd42896c37f75cd9af07df6f3ca46c4659cc4391a37cfba6e3f8fdc65f9f14ada8ee685f4806659d8f28f4589bcc2010e5f208dee9fc322c509c356a6c8d28e09f98fc014fd984a24edf46ad6767a838b3b454a7759c6c90467c5303080dbc24352c55c13bade270265fd603928843766331441f04f6a4d22a993366619c58bdb37035a18cb3f66a1d9146611653ae1f8f1d886718e113e72cc7e1cf38fc231d07963582c5f393856881db3bd9efa3da338571fd3d044de17f798f6b3a573e18fbdce386420946121f7c05367d526027ac53d8c506e1439a5d502c830f93f16d462e7a077416c32c156f422fa0c998cbb0599cad52b3726e7cdcebcf82b99039e155e229c6eeb98de5cb79318f07da7d331ae65458aba2803a09219879751c130ec2dfc8e29ba266e129d3aefff9a3db3f86f95cf03cb63905467a14e08c71a50319fe3a425d0c4f41e59bef20e8cb42d18c1083fc5443e2d994fb3effa284b8f6e6cc87746ff511a3146d94660792037d6e071cf17c4f4d9613c22df5620857f9a74a723132add563aed56c4143ea02f42b923ac7565591c80e518a8df85dbbb0ec7320ac64b2c1c600a86bc9a3f81e671d98e0b8dcc2de22c8eac33a9abf1677acdab4fcf54e22ecddbe95143a0a305405dd0456ef600fc895c94b48befab973018e32bb3948612636c588b899b882134dae693aa783034d2ef3ea8efac58ffba823db0682fdd19d9f2f2e6c0b99dac0a9916a2ef476b8efb70bbed1db0d9e91c8942ce393591b91e9e5e0251472ee0855b201e28fe2368ffd7fecfee3635bd627a710def947dacc9175017d023e19390d8af342b5fc2c3937181fcf8e42608d350396db23da07ee46465300a756fb42587c1cfb1bc2d703a6d52da9a33549db6c55d19f6bd8ee863f0bde5fe099c5a4f0c06aee2cd7900e074b240a135e34c9d2074bfc515be0f791d7ecac837a1e6760c5ce2f02298fb7e353bc1d9ccaace6e05e9be5a00a1a0dc59c3f1fd0f0b90ef15c3fbd29bf8e1928f48ff78f57ad6d17c272f4ef0d20d6edc068e1fe8027d5d6ffbd3064d8f934882f8667b2e806eed07cdf9fee34b8338dd826143fd50a0791ceaf8f15819d99fe91e39ad2a8d9e0bcb9f6e3dab3917c638350329ff99e319736bbce66316f7b840cbef2241b5d6d7748f8e2b6d136c8a6880b5c2f353ec26c3e01a3550d46a6cda1073bb37bfe072a83a99e112e8cd0d36ec9daaf7f60458eaae87f61aff455ce1d3ca5d69be5d6b409eb1fd034ae14194fe6802e938cc5556c6e17d507bdfd0dc582aadcf3691c961968593727cf5c5c8875761e5f395111a25bc9267bfb82a1c71241ec29fe99bac35bf7f4f85ba5c28c001d1b93b8d6d5942a8c1d18daa40ad904eb78dd426d50b5a54bf5e2a961a54ab55936ab90a5713eb85a41082a2be9906642c28c0239bcba1afa289565b217a7eca9533563bdaaff0ec66a84034e2041db0c81462dc71690bf8cee2ac04ecac58ee8371f8d953502b778bf6642e620a592a50e491c16a3f57a692061f67599c4b33109daeae529ee7f8fcd6cdddd3797814f0d980881cb38566ff2ffff37025a1fb6855ea031301ee3a5542f9a11846bbd814c74e22e8c9efedbe5f00c5964a09113181f5190b48ce3b2690d422e45111ae05d7bd81fcdcf86d0bf3c70adf940af4c633fe08a5685b148e14eca41ac58f3f194e8b840b3920efd9823ea1d37f7f2f1f85c34353f6593f04d1088c7372addaa68c5cccb17855d0af8bd027d1405355fe481a23ebbc57efce8404cf74c93464d95b6c21b3c955bb4e8ac864216d199074619005db42e7d14eaeebc3507050d2848bffcf098a6bc2dbcd81fb40f121e28602648898d6f5f1e5ac18dc7798566ac4f0cfeffd734df08b2095108ecf3ca8b77f11c94600b731604639d1616631dca4a52e3894a3f8a1dee6d51781f70b35141c1c82cbd2d0fc869cc10c60f5cd72b1502ca7ee3910b8a0c1617ba71e9d04e7776e61e668dc1814918942326d4587771e541ecc15c38db7e0290a6f89ac0e3b60ad46e22ab4bbe55b1c3653b7b9429ef9ae5015d274582318e0f0412ab125eb32d73de2dc2bf40752a6174cea369f62c87c9bd7c89564d060e8ed19e35cf4c96bd7e8a6705a2bb08330d229a11c8522eca270d89031d17484540a1723ec042afcd6380c1c691a067fc2d8c95bf7f5e09ce6aeffb114b4a3df3f824383fddce6b5244cf09d49bd321d212171b63d29d6948b98d924969789d54a0954b4151075f53edaacb86431494182c55562c713b71af935acc893688558f827af037c015a98f67b219763ac9b003653bc0e10e08157e48821cc1cce08a0c58993421e9211fb52ef8379603b7c4223926a6ca50b871e4eac4053ea0575f5828c31d647d7850b36b6ff2dc16689a6286b90fbc3022da39ef2205cec5a2f87f08527a0036c0de2783e44c80894274b2fe0e29bcf0c2e64c9b388d4c97f37062c2a81c8120288543f5358cbb27551750105e5faf07893d10db6a2e10399d21ae81dd65c85051173e3008508220d7b58491578e3ea214e076a8ec9039d3c098df670460e51a6693853a9f293e811af6178cfeab37cf90bbf5d3f34ed3805af4fd49f0dd82beeadfc56bb0cb1d711cc36aa89e06bea40367c2335f67d9c847f99f332eaa8a3242adcaafe823cdb7a0a87359beda1d1c3ad794cdeb3127d995998fa35cb91d896c172effb70bfb3ff028c29775e948b80cb89e7d5b89ed07e0c4973e769018314a6da209622fbb8411add8945175453e8005b5206a899051af0b644e7b90d4a40d8839b7d2578b29fbe28768eb89eeb83cf64633d714e9f00271f435b38c1095272457f28ca87a217230c3f4f94b8f53afd65ed3f949a5f108477826069a8e1b084f673ecc54e20d828a1e611a08cd594599e20caa5f2f631cb60fc95e122a1b94f2ade624c4a248e8e760ebc1a193d8f36328e24c904508436e7250426cb741f1bbcc2252cfc8ce7d70db8bc237803b48958b0e5c42214eecedf244754ea564e68808d003621b56237ae94d1dd5604d7c682905eb66bdfe006cdb2fe9bb8ebd97c232313c8ddd7c9c3cafea0280873e3b107d3c169fe5f8210d2613c872cac44d4abd595b1ab2ffcc9b23a39d7803758e3700b60be17e3513a33c2836063b6449b30ad3a4f8c971edec482ac63cd90c05dc1163af2f8ffeaac533812018621bf25a30652762c1f009b34b8b8126eb1bd5102b3c59e93a49c98255b11ca355ec13e90dcf9ff0a6b4a36f903daecab70920fc3a56be6d80fa6c6627b4d8263b1f2a31e929d1d64ca5f5afdd8125a0fa3fe77c249f10d9b9275161e748f9845924292e6d26ef7b5461e73a28fe8fd3ada7c163241968c56d1ef7dbdee025fb8fd4ca83c1747ca9c6334826d3f6f9bce906d8f38ea560ae1a7b50c85ff976c9d1450f30838209e82232c4aa24882beec6bb45ee593107a8623c4390e448f5d0542f2b466956daef179d34990c1afeded30eada3bacbba3298f597062b759073496495615ecba65edf06dba7586fb4454045ca59e26cef44030d58e92a0fec712b3d2dc78d8705c459b73e8d791959b91b83536fdc0af1b1b9ce8101d5efd96024fe9cabb58e12f0a01167fc8685d2cba09e92be39961f6083d0d9e5310a5e0947d0e644bee722d3038fa7c52556f2d28ff45796d4d26e86a147f89439cc669bef0dc1172e03dddad8c1e039695be94fe8cc2e71fb95d1dc161c5c7db89cb455043ad14b3b106237b79e11ce2161ca663980b5045e39e15e15e21a779e1054950c6b1a4e90c94b4782a51ec367bf8362586f2e60b125f15d222bf20792cb620e41974286151a3a6b4b94e85d57123ee34d398d57b10e04763ddbdbb4716f5189a2f31528587008fbfac6e3a6ee59d33198eec3975ba8abc71531a807b63d2435c04d0c7c6d1d247ccde10cb926241f4058da9388784c29b42321d2dadeb7a612839f9898c09650c612da3579feeb5fbdbdfcc904a9fbb7bb7a56c45793281bdbef5488fee335ab51a54ab22c7e8b2f4d136e6c0732321919aa87c39b08e7053d8183583e49aaf2aafd9c666fadaadfd12bd670c252034c3b082a04c0f2e0b4159dffc393e6eb56031257e310110e93bf43ba8a81792cd5784fee81ef244fbb72e17eea08300c5b41e87bd9a477b8e34f5a9696203fb9dc8704754b86d29825283884383708f7d70780c7a760f1438d9e5c24d1c7f941625b6b900f784db6eb3d72908d63c7b25bb0735a697318031395e9f29d61d8b37e24d6d20247fc0033731b79542e16c3ca24248182b56e2e4db50c7586b50a84e6efa66bf18ff8bbab20f9ec8ec5f99969b43d7dc8f9efbd83beca633172bba8a8c2a980b46b87a56aeaf354c56f36b413eac1311717fc6d4f26c47829829b6904c832750981df69a40404206e0b57a669c77753485b64a999e3559716cf242a7ff016a57cd3eaf74c56f245581708ab4c2c91a80d3c9344e09679de707e6a362a73b9964d24658dc63195382368f573740c745e072946368156c315ff57f02a07dc3c29ce753f5bce36996f0a7db4244a5ad33eca5cb8da76230cb5496be469f230262002b6ea1a0eefc7083f78a7487806c26cee25818e9759655cfec44d806e99999be41fe55ec26e440d7d1ed393a67c65fde2b3b07490cf5295373eefe64af1d1c84c9560060b05da7cb0511df0a4a5e33cd45f12e929f6abcad7635418b39cf292ebe80c4e616acd4c4c50a872375a5417c4de59a11593e1de1cb94e3aea79b3c08ddc1b0f98c4df4633c96905696d8d74a9ce0308f3520aacb0e717e7dcfd594952a7da4f76bbed58d36aa34f934aa2bdf3a9fff39dbf40dea400d2d6a89df8fe6e8696d03315f3ae4c687ba9e45b92f01b5c36f80dc48bad3f246dbfb574a2d19b76d9f309628aa40538783300789136b459e98e4d5668e661d35027b233cd738f882919b426a8a3879993f9db589603f0259ce5c95e525b57dda322580986daab56da2551130d628621d19724cfa3020015df57ba8da43feab2b08c2416d8b07bd06f38d76c716251470cd69a2238b624e7c5b78c8c3c1f3eaa2650aa92a28eec2369567146585c831af5524d54ca9320ac9531206405c7c6fbf1b74345f767f9e9aa926a77f543048696780ba1aaea45fa94416b8ef781d8ecd9d40e6d8209f3c6000edb524797d03349eaa7786d80172000e1ca00d28aa220c35d310e63400e3903a1d5d53713653ba74ddf49fd054210a0545ed95372e7e7bf22e22701901bda43c29394cc325f8f280185686fb372e6454bd2dfc9340d6b738b98d9c73686d0740154b73040d65da7dd5fbe0b829362d806a5a319931573741951c1c88237616248102d4a02b5c0ae4241aa19cfa7094d149f0f1f0c219088181f2a55eb51cacca18dd813d3307a14d4f2eb43a64141f9551dc311460e9581eb24755bceb307c6044284efed1776068be3a5ecfc4004f9233a4f9ad5ae9bdfcccfd1437e9a077ea3f4dd4de75e16f0bb6e7a10c61df022c8b92bd65a0ac9ac0eefe38c47eb2c0d6f8955bc0cd17d50bbccafd18568b1bea0758e82b4448c5fcac95e43a41b96a0132775f36124b429c2367409646ef634cfc4df1c27697dc853dad9a1b1facb11baaa93da50bc825a5997f6f3616550a7d89ca8c111f99897b90605bebb7ce906dd26a133b360fdc82f2e3d84559d61bd10a741ced851da7e3a7b889f6978cda1e69311e67748af7339ec945aeabc28e51c584d10149bb3e84e06d587ddd1220a178b57cbb26717dbf3a6856222deb9d6b9dbfb5a808ebf23445b4b11a29a83d828a405396b599d4db96053415962b7be1efcef63cf132c87dd2d0f24ca4cb01709117be352ab8c6f0ee1ab61ba0fb6f99567bfae001b7cf41f563010239c794047cf426510dd1ae87875a0a10912eab18c4fd23ababb9da6543085b36b14d1640341cbf269c7b4dfd93590e09a9c81f779dbdc161a8d6ad9cfc629de584f0d8ac371be9bf899bfb2548427c8a2fa8a3fa2b1b655b688ed4ad38e193603ff48fc2beb37e9d39916411709c2da206f2e85ce2743b546ffa9339656ac065fa0fd266759cde577cd564923b5fd9a8533c7819c234e31b4ae0bd6ab3cf0fd63f48beda23efb0ece41eebbfec1ec39509235b625619643402b1c58420090d3642274bec21a86429bb74e066530e395488242f42bc882e880dd400ab3fab395ab4942df3b0eee1b79ea5af5ee8435f9198865ad2828895744929c225854e1221edaae0c96a72648d51791f89af6080262c6c4e83830f813142c00080e087aa67910764a2f470a4a4007e7562acaf50ecc283e34ad751b13b3939f0ca41b30491a1140f91d46c631ec7a161e5ad27b0579d24e7f30157885aab8ca6a354331e43e13759956c6f08d296cc348217ad584e770aa4a55219d2b914675542eb966a1c67893795a7745ba33673f74d3aba39b27c94ffab774a98068cb08a096b54546785b8046d4d0941d4a7ca9aa6273132186cf5a7e0d157b0ff98a26f5c27ba051934bd48c4dcc56360704693b2ff9f2c0bfc536d90a25697ce4ad5e19bddfff6bf4cf8e0bb40bbf5df58d27c2ce5ff3536707270a234828bbe48440445246936c3b85f07d3559b9f19014f1bed3427352c5a1be073262bbc22534922e44509ba0c06bb63a792f0145eb7fceb68b09698c8276d074e2dcc50b9ca49700a6a7b6a78135c947db160a9946fb93a97830d23cc1a67fc8a75da26fe45d26b266ed98066cc454dcab90c07c74cf336022fcb0672475974ae54ba345c8a44800d1dbd3aacfc2a93e4aac3420e15527b0a3919789194641072555192d85011b91562967a617d928408cb83d03f2b5905ab26792b423a4241ee09487906ce527d5d2d72b1560801a81c4acc02f56d63145c8136e9dcd55798785e53590f809ac49e50f7ff0e17500398a5d6347f96c119ad816c6f377205c2a1a4ffe108bfd6f73a8a2524c943a9420c1bd10f1afbeb0247a7a61415ca80a6cc413acd89223065c080ac5b53f1389cdf895d9aa38b0cf62cb39f5d0b4b5ee2d5cdf09c4253b35cebb202e04c8d5f328c32cb67b38f5a81daa33a95ac2f0bcff768305c4761957a08355f308c53ba8136c2e09902ca79c968716b09b06b2054aadad4069015c4a4e2a81859a1124618a8b21f9f3ad3ecf1bc8f00d9cd422e57e46c1725076b7653ecba7fee5b0c40b80c310115de0d4f5479a943de9ce2fd89fcaafe21dee5f3fbe26e3b3053371484c78aeb1392a8a7a8a0f06977cc79c533121fedfb2e593fbcd46dffb626e7bd2ed2ab66501e825bd75dd1a666f8f60248e751db2f9648dbf66e06e8367ad37b4fe3cb9c09f5b6378f5a1e8a0e8f25d11aa43b2a2e7a0a980b2813eff8fbc922fc83270a1e32d45a09ea051cc54f4ce2cd780295cdbb27c4c86a54f229a821e3a904cd7ca9a287aec5994a04833a2738b3a7f126e131db70661c08197386da99213e749727445b71b737623ac01ca10f7a96e350956afafc9366f36f314247b438568e4b6aa3a2ae5ffe1ea0bff6c3aed53e8f70f49c6b89862b58dcf4c7f804ffe551e50b71b0a8778389ef034c83886a15e3b0ea9643b2e3cd80b778f07e6087ab740854b44ced8367c9ad3b8f0617f8272477b8cea61423a325878230643bb49b870f1d7675e8e64110f6de79b0c2a5386241f2ceef4b6f783c2e58e511a6a1454f4b2fd375d7d20d4f9cf9b012c5d0c4b8dd2721ad6d883db5a9eff0d91257963c757c8b8ae75c044ba5988bc7d1ea2b989bcf56feeeafed72ab06acc0cb1c6c39a17d9bb33ed06a8da6b5a401710bd7fc23c9ef5c142e7c1c26fcf71f4f2cba0c942fcda52243be7cc0009ce8dfcfce507925dff1e0c385653643def049d2e41486eef4a4e7927c82a648f0f832ff1c44f8bf198865600739f4a74907bd9ee7f746919eea8ce808547b55913cf420bacaeea4840ee31e4477ce70ec172c933fa796623cc224fc0333f0eca48c2e088a502ed404144880320ac8c5fc9406bb5b498f0e03fd89af9d457d6b60d66f388f8ef13043cc0be02fa851a647c803dc813e056def60279a672150d68e8e5b2e089d77570f6da56962dbe65007d891bd1314abca011ccf411058007c40b4369dc6d204c2a3d9f0e33bf6c649c995789fa67ff4eee9640740daed9ec86f64bb67cc8d9d3d320c53193f8e525d0cccba572dea90484260ae322006fdfbfdec9387b49f9206fe6f4bc599e70fb576e34241b1b0b3cbd66c561edf4bce1ced0315fc86095f979075e0400695a0051f581585507f316d690a9b2ce605ea9e1719ff999b8f10dcf5ce9419fe087f6940de04822fb1bce78c029ec6c362fb76e16ee8fd79843e0607928b2dd18f81f5554e4ca374f5838d74420775657aa9b1afc8a0a43eeb93d32f23709222fe95da5f0c7c6ce16c9bde5171baf567b7c162e0b4606c251f76b50f1859da0748be0f2915c38fa0269a0e9d497fc49bf509047749416c3b1eb83df939112048782fc10fba651b5c2faf4103cd135e82271ca5ad26e1556570a56e4a57c6dde0416d7c6e4ac498fde12939e147c4fb6c3266d3dfd64bcbda8f5fd25c864d26842ebcfa02397763e58bebd76d1ef4ac31648f2ac08ee626f35cd2d904368e161678e808ceb5e491c6c65b0087f2dc33e3362d0672c3d2477347df3beb96749853435a46116351611f936d0b323be547048aa45acddba48750aad3ef3e85f5904ef96839983103f82810fc6a53c74e606af37a31a185e18704cfc9e34c8039b5870b519e0b57b31778001790aaa8a5ba19aabac240ba9b1130ffe8e23b44b9e0d5036d6530a75b5b67e69812553755d121ef90044fe941966e8d6ed2a3940b70952b6054274f5094d04036684a1a5ba4fefa08d34c53826dc79f186a15ccf9dbe2b4da6a8d7d1c7643662da0ff480d47a128f1c56f44f69be84a73455167d2ecfeb4250be4a3a411c80142ff38105e72acf1b6c374f4a0b0737e8457f5cd6c6efd617f5593756b6588a43d8079b24021e79f4dad6af51157dad170a2d1cb431b1f18a18147d460317e3caae9800a69340cecc7a99c07eb5118d1484ca4b9be0dadf4cf938ef92708bc2cc2acec41c497211177be427b4fdf54e838db80cb9a890d5b24f191bc6f43406263038d9abdf32486cc81974de297b21b121768f14e41c60bc31d0f75fb50f4cb724b50044d4392684a7a244a3bf41805c9df3b5a63b1297d9caa240a0ed762e66055b6bc6dc0e651aceddf567abf4c9167b2b888d161a3035e401efbd6fb22155fa432989938bfbd1c68687de810d8b57b3a701fd36bcb133b21641b3a5ea372523c0b7314368cfb71040903e26f8017e1a3c20283abf579790b776d56b05e543c1894ad48286edc8dff795857d9254283c27e465075873aa27a6f454d3b130eb53987a090a5ab188e91a759f85a9b7c821451a2c6f043c9d27d6a3ec76f743a5efbe9dbf0d7022556a2726d6918edda93d2e8274cd9141256b6eb8e291f29fe569b52206544a4524111b43cc1ef7cefe8dfe9862bb24ff39b635a754681613d266c3b218edb9ba5f8d74ef3b29ddabdd85050f0cf97cd559a1468f1aa87a988b7d2e08dd66f357169d372087c0eb0a6b86199b0c55287970640ce127c43e380137d6d72738165d5998221447ec803792f3e3e32a4f6e80a068d0bbfbf87a735a379c36f9dfc4d8af4cd24d0d1fa364364c90acb3f64fe25662f7926dce9005b1fb33705835ad9cf5db5b271704989e20ef0ff85bc61cde16c3a67948b1fd651c6e38e3fe2c397630d96a1a972f4af4d54e8df867ec132165af6d1a3bccf19e5aa8d68c47a33b0d051016839502b2256882383785b84ffc498d66e9c006933104b08c3ad32a3f6b0ca05db172787f89cdac930cd923e14263368b4c2e29e91bcc96476b178e833a89aa60aa1c2d49a83c8c3a64d7545b48405808229271248fa95c645f47768fb8ed5cbcb33c141b5b7ed93e54f8fad867319006f8c36965b201fc1d0a7ac75fa1cab979ebff5e4c1c213f8c60d52ad1d39d55377182e24b34fb4a01a3d072497abadea73eaac7ec3a80c1e034bc8c292c57cd3749e3c790250603d144237337c33abd41df15068c64886fe9832dbd6fcb004baeb9ce70e4767f670375a2ea6411333a8661b8363caa74a0a742d29cdccf742102ae0b16e481877a6183ad2d429e911355c517a27ab9aa2f27ea1ff955e63454ab01a186b76804211392737307f144544522e829a28aaed0df80c0614d22f93b4258502d121bef27c1df7f5f26184703a738c7c44d2bca336cf230608961dc025267b5f4b4a3d121cc1dc9ee8e542b182cd1165c237b14f61f5b3cb39f66879fd482e5037c9a4191f30458b5f6235b8fe29eca7f9488f5b31f27dfdb2e9e1b6e8a62b97561c051056b703b7c2ccbe60402f99c74aa30838c5d0e6253a5744f97b45555f7c10bff86e52891c038403378ed98fd1fbb3c599fd7ad997373a2fd0fc86fe3001314c88b9233abfca23103d023a151c9465ba199a65ef1e18f601844205349076f12fd70180590092fb13d98bd0ca948fd8fe151e1ef52ac0990c8f17fcd8e000fe0dba7d81d533d87e8f3442b757ccd038302148cf483f030d0cf8aad4c6b8f3e0ecc8826b219ef7a56ed9401401cfb2f6b52edc0e615f9a3475db59b24ef1380b2aea6a21348515ebce65abdf807677f1f2cbc0ac239f99e5296a9284d0ab55ada680064800845924ecdad8a9f2171b7ae2d866ef1bc523dc9b6e8609abc8e16381f4968302a7365d19ab60cbb3009ccaeeaa0dd815f50c197133d3a06d35b45601a6e022a563b2206701969ddf6f2d605b9ea40e0c363b23c86c8d1529b7a4d7e807390ea78709b243a495965058763113ebc493bc27a3ffa4717de9c27173f4226119d3f17c31c8387f1922cb911a0d171336efd6d38bdbda3a77347f2bbc407c2ad9a679b64fd5f23c8088694069ea204b6d35c29e529df7b0a0f8e562241a2459014b50e4673dc72a096a8b9cbd4df8fcead0c84197dfc22df2cc6f1442646162d75c6e1ebc907be3edf12c9214d9f7f7bbfac1598b2829b4634a8456415a94f2becb1965e83fa83b885776809a0dca6cc7abded0cf018a943b5a1e4408fc6ca197025d673ddd28e25f8053561af713b4cc76d9c6ad58008bad70f3ce3aade67d6dff0f21ac95ae5b0d2b710f6194337e51a1c63c19a19263b6900512510c46f9d77fe5dbd8024ad65a4601c00a068f0ddd4d91030923a93748308d3302caa2677d4d0e7e26d3d518a0e989b9976628146f43e1f0b56ee1aee745a950aced30316e119c7f64af6336b1eb1b16cc17d34c3a310d65989ee009bfbef2a30c1d2f2f77847dae51cc13f129606bb6631476183143305e902c143f9ed89dd7eef7472e56e894c69d2952e2157a5ae18e909186dd91b2eea7aeaf24117df1187db6682f0a054ed409873cc35a494b675546fb1930e3b91164eddd560baee060147d048339f4301fa3abace0fea5e6839573c513f16f9364bde4c425f349bd486a4ac0f7c874b5664733527c0f82b7f69321932886ac046e5a99fab0c8bd5a2997a90e00050494a967eec2470b668a99027690aa2fe4e139a6c1f6b44fd51a6d0608fb831717857d125bc5ff918f906d0e3243f6c17d48f48f667778dfa08c3089bb87004c4657ff6def5b647594141cf66576a97c65967b86925079f2a1dad2112e8514be092ae6c452420b707ad65c05d7a1217d6d0009292d5712bca216023ca30ee9ed2fd358f148c1d9aab444c261a93d7d0d70f664f62bf4e09c4a14e5cde8951cd83c82214ff26bad693cdae51b45bc3f6694163e0817ea867e005937db5a2cac5887a83cfbd4f443da2d829f5e13df353d121dded38983d0088d75e9b7eb45645e6a50f6222f91f6a4f685911790698f581529f4d066948f5acb302162c6a01d41a9d11cbe0b37f0e1d746c6318e03df7c09cef29a48567e4102e9a0b3457126816d466214a16a5abfc355c9bca5066dd9b4f1bccdfaca2088cfdd56d6c01bee455170f13170e1c2d31209e6b6c6aa72c22a6de594b51ce3df1e1aaf2962ea2d75089ba5817f2a8eb874dee115c83317a7e13d57ea98b0e3a91ec0fb937d93ac4a3a36aa0a39b0a90ffb5095d81904b8f969e49253098eec130c9450b24d26c6b00d62bfbf7c6f8c4bf63d65e83ad066d32accc21e5bcddd6e5b9d0d9500ea3f510972e5856824702e7ddc150e310b63e93b617e517d240139bb68e1736f71f4fca4557ef88b32b23b84dc299b43b1f7823fc5d85687f3847d90ff5a0bb48db1fe461324e48c5b8d95693533757b25b7fec1720bcdd5fc89dd99c9e92de8fe4662adaa90eead5385abf99366808857565f10b05132aa3b094c0cce9c17a326d31be0305c3cb690de4c2a0a84b6f66568b0cbe8e04f95851456758b345ea45cdbf66440108154781063ef85b335231d71fbdb7bb25d64fabd985c577b6f8cfc586761f748c042c0ebde70b27e3aa423a8931c137207b21015ec00c9a3650008cdbd6445bc254448d95e12af63f6eb08894568bd11d01c8319104627d9944dcca06532437bc1d430a179e3797cc60774fbec55d63119956b6c69941a0a3e511877ca8264a209bd07af41e2e6fcfb734e0200130249932d7fbce54d8feb3b4a36a3a7155e64ced021b25c5d6385444d6bdd26d8fe6471c49f14e0a24b5a07bb2d63b4bfca68d0805fb60a8c63ea6746a1bc94691b51ba5a36410467d56e082c8891cb0f1d161c8da5ee3f398832648f7260dc14d486ea17216b90af5666c5117e98b36e32e40e4332ad5a06167e01359d1aabc4f926840ff6266d8b11d12a2809bfe643e004263f4faf73f52bb53a1b7094fe51ced18002e568fe0668bc960c0a9adb373564e6687b4fcbd6228863140e7a8672b6a6e57c0a284125f851d6cf2b0d86b5a9525433e85155940d0e6d3339d5ca8090cc4f385d1dd90f3902ab9e57c0f7a374681f61700b8b5e70e09c41d11a6367c71196de9988a0f8ab8d6542e6686c1e4211ea28d4dc2479b4fa39b0315f42f78647824ed9845ca9c3c2277770e97bf295499387584981ddd9dc29073a34a6b3d66f1093e52e7ec496b4e9e10eea14835df2723a71a2b4cade8a8ba5a3dc7e4c8e9d7f6d624b3a8ab2de7513b94ea882cd8a9d00a1d64f7ba6ee11e5b9a58f8a6c7b6b0af7bedaa2f700445dbd1fb5471943a6a98e638f18d8ce193ffec7d7e725a45e5d435b90f8da053fbd8ba640cd90556597d7d55af464aa15cd94dfc8b9baf8f634db942d80be9fedb48d9ec2ce05c573401e1221f4b5dcb3a2a4fe59f54fc8e74ca3c09dc29426d0a0fe8167719499f632a449d8e3283d71aecc5ff31ca8003813927bff6ac1dbe6811fdf4a467e231dd4ba385943f10a1d5855922f89212fd54f0e87af71e5651fe720cc2c2ac2993fb177de209f31defb63b77e31c3a9e7cf106579e04acebfa2dc595710d6d3cb958e37dc4ae5d62f7604aaab1c0a090aa4bda004115641c05dbb5b2b40db6745c7ea9e9809a1027e23e32bf67e10e520dadadb26629dfdac7a4331b395c44bb95cea3e7f40c076dd0de47104ff6c8c6440dd28b49eb730b7677f7f93045635daec75dc5791fffc410490e3571983325384c37e73d4d24359dbd1052d22b35d615bdd8a55db1c31f535de5d210566992df6518f322d0bf4fc340e5e570ad6f6240c14321c21d83760191e067699a412f7df4096458eef87fd6bc57eb12872c1dae93db28823fe46c0a88d80faf2cfd3a09d400ff785b9839aa21d8534cc9852e9c4e1f83800c4103d24e5bc0eb0140480c0bfe451731e23529fc5f8ba14e62f0ef72bf89a54c531c9839afb7cb3044a7ac30cbe2ce6c1b043ddf5336d3806da44dc946a91bf9774e4683676b8ffbc705612c657c4d0945ca8b8735b30ff5332f39c535ee8d4a17bf72564a2249ba81b73fbfc8d2be22e859604b79b9665312bad73ba6a03e9091907e406f7dd7798076b75995d488026dfad781c06e712820643605c09164edef84e10eef6b4bd51e8f24cdefccf09533313600e75dd177517d274c899d71eb89d78d941738adbb17d486b39434cada8c10d3e62f3338960fd3824476a7d442a29f6f551d5bfe24be815471eaba870b35f7c57cc5deb665e08c18e573ed8a629dc3779ff9acab573de96ca178a7fbc442381bd003f46e8a4602f699e59b02a4fce5ee87d56d4be771242ffdf7ef96aa517fdeb69eb3db2a0ba2403d5722c704fc2181fc85d52029fd343b2373c61aaa3873921c021cb7ed2f112ecae9610689558a9ab468b13c8004f9d1f2494017ffdca80abf1225f3532ce022777fa55864342ee16e9b12472fa29563724ef6a989ae99112b8d7b95aaa5dbfc8d28de487e0c1b6dfefbc476b6949d6bb0193557ed820b13a681fbe4afcd441da6f61d971c973eb6ced55b81145dea4fa63e7e22605f5ce9ca6c2d4b6b1bab005b031d7ab406096009f583987fb7fc6b5a7f6d6df8985fc3469a6db47f9ae0b26f9395af960b06619adb46b9f4001d601524e5b7210a0037de9a45cf08fcd958bdbab2557b54e0e1a0ab8322cdaa3a93856d0814b16597c244be100965941880977000f456499e431648e217b9ebda9c079844ec31a88d2d7dde64da05ecd58fb90f1cd49204e91870faa9939cb84ef09cb23e51ba3a15c61a80b24284b4220191d37a3d3ae4be9895aa6f5d3aaaab6e9a8e593b56c070b6174ec606e5779562d306b705b2435ec194c1a68960c1b34345459978b5443606881a66a186bc12cc8b69837922ae16aee4126811d3f587d86f4b8c787bca73a352a7539e151f2a3fd23d6d19af3786c8b643b567db574cecc0018597746c2b2c173901569402c43ef629363f7332b90ca63c0a6d5b326ee206a8ec9720e039ba9f1ffbb4a8674f56b3062191cc2d52d7ff189f8d329e428fd5178d324ea559545fe77272c414a6b61f880b38d90b1f6d421d066c3643f3e5d9617920f9a910a797ef912fc82ce44172261fa6c7732ac6af59871e431178c9919ad7d6030a12ea3118085a2a329a6bff803bf5b2a63fe33649d3b45c36c1bcf88c839f053480c7eb7c2ee4b095b1cd0d0fd0faea3075eab2d9d70684f11c65ca85a79058a76c5358de6fa62f788ba02926a0fb44b5901c0f71fb583579f39593c0a91e3214d3d2e30318f87fc84cac3a10537fd3ba17fac68f2457bf7bbdbd60a6ae89a2a8c53d76b49bebf2ee51ae103417b06ef0ca1f8134db3df3025c55fe0a0af4a7231743a41fdfcd51ba45be78566bc9f53b557f87c0a199e84e7d7fe0f733d8f2445ee51c95882f69c331d6444bd0afa4d0ee5201aff7d2a0e333f30b8647141c90e9181d54d2959bdf92002dea6113f9532abb7d20d2d4f53dd3904c4747cb9a908d878cace3af653cc70da68d6f0a7231fb1436c90166f66904445604c51bc6fdeab92b5131cd951ddba4d0cdb510411f0dd91bf23aabb516cbb582ff42cf07fe523e570acdfff3c045a77951469c4ffdfe0f5ededf0e0961315b5df8871b90c794e5b031b70aae8f3c6447a496e96cb41da83ad3602a3701214caf4ccbb0d938b4264fa014bd52314093d2636f425f31fc56f83b12fbe8e990422d8301a6b57f4e4d64400eeb4b62619348ffb08795567774efd866ee099838b87e80979c3379bb045f6b5f9d3b8a1ee3bcf6a73716971d374a2a142ed0b4c5a7b8b4adbce8cad52d7250f0e88e198cfbaf3fb7cd39560ee9447e7b54871107737c52a9ea0efdc6d93685a8d86fde9f30ec404560502d0afb483de994b0397fcfdf55a04231b3dbee5a71b8fcee6916e56d70c32b43a10eedd2d3cea8f300951c6dda4dd82f3a58aba5e3785a9011ea1af25bf8e137bf3099820651b5a53572bf1789fea9439b0482d96f53b9d2504cbd36257a7d6fe6ab8e16b7cba020c1dca6686b421689d0688d85e9f0f75df6a03789539a17d9c4855756fa1cba40cfc112f410e8e6d495b1ed88aa79284c2e567608940f1aa15ca8420065a114e576fe7c3b34a8733c2e9b8d7ab0cda5ca731fb5bd1de525e3029179b86ca8796b39b285e48e713965d3e24fc57c6c0380c42c3ac406d669ad0b8948a82ddcad726b11786069c23eb5c5a6f16d57c6e0f5e361481826c0e9b67338b555292cee06c3d0ee4746aa4a56835a0b643d06b9194d7eadc6161f233e8cffc06a8131ea7f02124e8dca2652061cce51a0c06e72889cce6880cd9c33569f3429d902f91295b0a9960aebdd0fcbf2a342e329f7832fe904184922e86eab118f725f44cc4d55b679d656b60d9fd814727fcc06feb56d031c331a6840ff75f769c1f0126962062f099aba6bd506ff58e5a5c31a0bde5811c049b1ecf70312ba56177193020fdf4ae4c0b038be0c7f4b22f8bdbbdcab1f963b7e719e0ebfe77e94775ff753abcf38471d6bdde210b56cf3a33c8b237f40a3aedb316aa699cf81f9ec23d3e91a8d79e4540212db720d2b89c492152e790dcbce0a6e49f46133a514706eaa325b0f223e035ded4baeb08fa20066ac6a9aa5c44a0c35743257421720b72becd8873b489ef8bc3509673b17543a30ab8ed8930d7ed80d7f577161ce4db8a6ae5ec5fc380f45a862ec9ba7ec114c5e560c66571e127502211c0a6893ae3313936bc1eb6be52f88170bc9b1d1f937982b16ba9e5e3f36b8a436b722786d156b9f6d8e0a4958c3e1c71126d65c04f0170a8a7f19a04810c1e75c7403fb9a05aae0e1bd08f0ed4009eb4a78ae80be67bff3f3498c3c1d312b7ab339f08c0f76169e3315656d041e661cd98209ca50b8bcd16421ec4d46e7f03c476cd2a757b751987bf07f71f154ee1a336eb1e853c6422e26095a3665226343f59996bafb2d01a4f96c95dd164a14116c14cd626a92c3e8e200dda7137263675585ea74e7126d95f25e90e07141d3b495395f4f29b503f12c4c1ea53a7bd53cad8a80a9cae831f8fa59b06f1f03c3856aa93343b51dd7207d5aeb00cb8254d5cf95b408195694188c1b4edd5aeac49b10d62dac787039d1626b6153642535287aee831c480a4b889e790557b9a113b28b3725c0aef6467bd34e3ebb3614f1de133db519a0c0872a32f48c3519f5d7129a52bd958848b84a4ead9073017ef94e2a1e175df39a741fabcd036339c0891c6c4f4b0fe521136efc8a92a2d2cf5f6d4ea91580158c5304cf76d8dc82587635426500580a78214c44d43c1591c5fc3032d3539ec6b05ac4396e9a3fe8bf0db1c23f35207c628cfd83e0c4c7afa4b984c16073abfcaaf2580d00272b295aa4b11ad15c8c5223de0a2576a58b0e19625fa0a0f3781bcc9dcb2820899df8413aebd8bc801c2bdfb31b0415cb35f36ea2595ceccecdd3d0191a56e1b305e49936372c9ff11900742dfbe503cfefa0daca92a6d05cb8ff36cf94231c22fb7883b8c6e1c666d70fc63dd3d219889bf8290a02720b82aa7352c4068d39a9f87d167bca2f4b6448eb809688dc994194afcdce2af4020a2eeb9d7a3317b9da5db2b784adec2433ab43fcf92a5129914b07d9e70b0e5a89d0805e055f44eaf837121e6a9aef28a7f76c34d83e4116cc9e22a688329287d89018a46f5e7a60d7d6d31de652a4ec3e565ff338af7ae51b54db9dc6ccb769549c593518727f2f8f4b73d6bf9db0c6ef49793656ff9b441440a94ae2fdd0084c0a72fa524c2608d887f02c610ac9430cb0c2a1c5c1f551b0ff3dc47394210e3e8bf24c2b69c4e733d2a01e66253a6e7d164eb717866cd86d1492c0a4efb18ca64a4c0613f7e3818a283108137d01fa8613da7ccd8917b57806793276387362f7c87156e8174f05062e6abc042aa9167b7bdb44706aefa0cb43e76ad47bffc2217108cecab2b4a96f4373236526dc1606143454133d537e48e489b904cbc4e2623519eef7a258547f847ae6b39ff0126a5cf447483dda9b441e245c5d4a773dd3ca782ad51ac3933fa7e27f1479af8583e2c1480aadc5a5aae7f752bbb115e0de2a4da3c8b7cff43d47e6a0fff125efe1ca40dd9d61b1775eabca43e0de244cf30665fa040d8af73ff061851b33d883cbfdc23f6d07700719fd3fcd4d37a8b3ed9dcd6b11ce420e3eebce96a99b7d97dc005ee62f3f0d17b233d6cfb557b809799c95e6c269e655e6bd6c7e6207195bdb5a2faa8f3f533bfed4206763f94760392708a483a3c556b8b498537f1dfb8e1695df90c52accce2aeffc7ee7ebc55f6594b79329770b342d38e627ae6ca5c34b9265d0d8dfeb9a97cf9e3993e242d1f3f2cfedc5e54567fa5a3757f7f5b4c4e8c42d966a7920f4f24cacd2946365c561aed74ab7d61eed451f66c22636ee0022c34061829b51364d5be70977cb83d9c676dc521982b108c3eb00459c277147fa924d0f31984c46052279a8e226be05e580b8482efb78dba4cbf44224d2d040f3a9af8778ba7a0bdba4690353003ed014d8715774c4b39ede306b3091b75bc69f4ad4be7945b09614452bb13f7273164a5c6ea5fa1e951af14ac338aa8d3e24a038a442a9ff24b04e7fd77c179ac70229619694e447567afbc51c6adb8b8701c31cf9b8fed58090642e82ecbb2cfa2d614e5755d921efcbb5c989cea924eb4235195541f83861a51369eca700e5a19fca6f4193f8b5d974d3b0a2193528101238dbf6b9c53c9be60379c4e2c6d6287928cb449da7f79e9ff1c7f30bd92901e310b36130a075c968b9a08f27014ddd2b19bcf94b3b2e9b79770a865ce822044b2d2e1670c05f8de2ab1d8b59bbc8cb04631d1e0f7d9680429a110ecb3e98c53cde65b5f4a4806122e2103a3c9e048bb9c86405c35fa7856907a16f9b2849c92a57fe0ea45a488ab2b358b128cc070c58f31a07d8c8c8d17c05982be10f7795a744622864e88dbe0a5ed0f9e07f30325701b49c2aba271bdbc592db2df4188073fa47e55302ea1a07dc6c687cfb990998dd21b9fd28f1382c979599daa914f0811ffa3fd2df7e0ba0cf491b19c5e684d6e6d9a8b37e5ddf872391d62330ac61a80c14a3c3a23866ce607875ed3651bcf89e78f9cd8582abac1fad93aea765c7e9c0cd217ea3e90f66770f4562382affc382d82afb5db26ba829161ef0405b110f5a075d5f794c5930a05492350c290ab1200d83c221fa87b5c1a9f44ea416219b3feac686fd84a61f0d0002bee609d7d238b157a0e1c07592066841baac41a59e956d6d525130d2b9ddfe74105451b0ffffb3fb2d9ee8f98013392021d5d565602c53267f5d9521b8c69ea376d17edac204a10b6cfab70d714ed00e98ffa51504ea1759f62e518ebd47dd60038926f360b0500fb248cae66da5c3e259ba1da7c02f4a40c343d44fd0fc5d0b78bbca72abedcd0615beb0d4972333221aa6f9becdc676b1cb167ff694e60163a6034bc145f57e0d5f53fd58924962567f21a8c19e009fec5cfa07f8804b10978f1c20f063acc86435dc8fc15b5d8e13838e8bea1cf0ef6f57c2f398a95324bc87fa66591b63818807bc24a04ff7655687947806bdcba53d7739c735425ff441495c15503078db471d59bd147666790024856c4c3aef67a3fb412b2760fbdb0680ddd30e84a98de68724eb40d2820b69fa3d08e4f314280d6b426adb5ccd0d6c8fa159290c282df19abab1dae88a929c40e9aa6259d2770a312b5c3ca6f1186a4fc0784aae13512fad1828591665ea6d362aa444485a15f2666512ee6b2c9e7aaca77ba235b4c43f80a04ab9f44f686ac18b3fed9e1bd0bc46e029427438240d30854beb760096571023301aeb0735a7660c59fb901470d1ac1d57d19a095016f9b1ef4d4621fa0df80670514684f1577130db22b416dfa364efd27f65531870482ba3bf5ef2e362e7ba9f6df4e06cc60768e7f085236b01899e53bf7a941ff263a300fb5c6068ec994422bd019969f47a3abe065a9cb3aa3402b7e2e090c3578acd7f500f13c82b8aa3e2087f46a777ff00b0bb0b78af9942aecb174d4c71f30c088a838307a9a75d004b8b7312ef6f39a7b5060d5079ba5b626e6161ca8fa73596d4bb52c04d2640604064654f82ca2b2e956098a4c563b9cb5387ac0d9f58c060bd580c8aab7a22492e12160427dbc26208bd9954b33a85d27d344352ff8a7c118e813e00c24b2400a81e3d9c7d12eece5fb42b25dfb30d0a0249f673affc4b7d0e01e657256cbb4ec09245c732fc181210e3290db619b371d529a7efdb52de4a36c4d3ec156c5495217e3a95a807d62874d70aece49835c56f7ec186e4f6e2dfb3a9aa7aea871e8e3848be0038df4aeda973dc7cfb66e86ead13930e5d144b1aff666cbf5d109cb8e67a1a392286872ac7d57f7bee8647ef0116698a50d5b8180451f4a8ec46ed2e811f4983320fc570410cc080198ce51c23eb6cb8ce6e7d1e84671d0eaa36b73efa25024498004b6fb6ae8d584106024547ba6d01154d2b9327c2936815ce4638972be41dce0d2a211a97f2843b18159e5328f751dc2ce86daa8a2d2952e6ae2edd299b8c044abbf9169f7e1f5dc36d6e514eb03fb1b0284ca082190b54d425f23944bbfa01574918151472471e35ec17285a2856cb83ac55494860f916b83d2382afa006e3e0157cc26027516e5378e11c1e4dfd5e8c3b4d3ded5b0556e9d5dbe82c2f802cc55183c0392fbe63f45db5dafa6ee6a7ddf1b1b7104648d26a7c61c78913bc87d6b08ece3b685371080dae71ee6538d4c191ae8fd3f9c1cf5a1f3e26d5d1d77d8a517c071a69a0ae1408b03373397aeccffe0809fa9c939d52aff26146b1120889a762542958eed022ff963f96d10b60ecdf3673f8813cbc98a06664e6a8dfb1328158b66c20d457af033442777aa2dbaee7776c575f40117532b134c10627d7a6fdc35950406f820ca8136b4bd77103fa1a7360b33174307154b19422f1572dc6d25e30024d6516576f5bedf603da07cc024fdc9a1ab84cc3f04a95600eaa8bb42a2b8a80803b5b07b1c072246ae31d73aa89758a37227279c66ec1d8c48a560e2821caa5b96deeef4a43a8073e3a6aa2b22a066cb7b9383962338e50ce83786b8c5db418b249dd36594a5d12157443b5c0a9d94e2cf7e8f6581f09b50842b77b291116ffb30ace383750e837290441f4e3c22e31561bf6d7df02b89566efb3390b03deadc619fd17baafb025ab46c0dbdaa489fdb299f5c18c189565358950822d8bc751c3fa6543ec9a1e46b05106a315f3fe060dfcf16898fdb27e8c8c6a9800bc4e25991adcf46d432787655c5fa1be16fef5f740671aea18537c860905558c390f30a32d06badc60791b325512c78e8a4d46478111c93792b1a4187f101b1b172abc0289362f22e98f36f88467a6cdfa08c5175d9cbffdb4fb5aedfa73ddf4e2efad946ee324b079ad1d73fe489040e4884390d56201a16a7039a25227cd323f79f4f79b6742fbe775df7407ccc6f15b52293c239ec4f92245f383fb8614fd718433985ae01402911f5c996a4679834bb375836fe34782227d73b08ebdeba0909697b77db72ef2d654a292a0d1c0df00c53a48c7405574074a67f5dadda63da67da69fa238669199c024406ed728762666666ef51033777b3928ef1d5a3478f1e3500c9a16608911e7c3072e375ab98170cc33429b518334c0bd632d8e32584dd850bd757ca74d8923006c7c23416870049a0766e314ccaf8d9f04b99816d3580c8eed8ba403b6e7c3760bdb0d20033be9d665b0e59ed728814735d49a040f6f696ddb4f6434ef3edb319e2b7ed451d34f97fc031721344af86608008b33a9472c8d65e0d7466666666686a0022a40603447af0e187ce9b01025733bb034a66b50331abba10148420794733a587a66911c36213669d7921a0d4783e72213a2709e1f9c855ec3524efbc66e49eb7a762ba03c93be7814417b23ae76144699cbd9935665dd5198f7654c55425a4f3fd1a8886cba31d3d7124576959d6cf4918676674442d326277172e5c08218e15a43507c3608cda0a52a954ca5f56313a7ad0d4004408ef4ad8ca1cf3f594bf704e601eb1554ccb4097c2c2f11b6f2cdc557b75d111d3ab76fe208e6f672d7b3bb42ba3291f9a557e772a051b7382dbd1dfe8613b84980ac35adb0b957281fe027d053d06ba0ee833b086c622c351532d09134e31bb87707b2d09f367053146182116218429fe7080508ed8e2caf74e485fef0253d21794cc878060540189970b4ae64cc455181826747615e6398fd1ca1cbf1becb3ecdbff61de655e8e698d79ef15bb4baf988da41e7afc6aeae3ec55a4d186af5cb972e56bce4bf6b2c0cf917ebaaeeb50299797558c8e991e35c8af5d4c98d247891efc6e6bb7eb3217044929e544a5fc05478c8e191ade95dbd72e397707d6f25d11f0a5dd1bfb2dab7bb76f5d9926a59649f9c46ab55ac5e898a1a92107213543884033665dad7640c0c6ec8eac6e12a0671e6330fd5f3adb9253b840ca13ae58c10514db8280163d28c18f166900c10baef6156b5b9c23e06965c03746ebfa7cbbc4bc69a490326d0c6bf67c649a96ad564eb2d69ed0a19203951c6a8660a0071f7eb809022749e73184dd370359edde87443e531dbd6229618cf4ce3daf4ba50239e8b01358196ca9ac1810b2dabb0ffac816cb201c698ec6dc9734d609bffd09e184134a29252792d2697ad36272a092838eb402b75869c29775499a1eb0d4aa0ca765eaea9bbd5265d486fe0c42175223d472177422420f7dc8057d6200f4d07fb86999f55102a8bbd52ee859af7a043df4185ec143311e7ab4a27f7d9498e26b8f87be34cdaeeddb6545975f90f9584cc1966c165cd77a51bcc0d8900b6e5fb821447af0e1871b1c01f012d6d14adb31313306b2a4f4770c6cd5d0acf65e29526ad81da36f5fa021bb8345e4ed3ec0d6e6ed3f04c179e759d69e0da3af610893fbf67ca876e8dc731e3af7280f9c6faf728e48c3c90d961821064a34a1401137b83206169890a206ae76cef3dd9c731e44ee51213a173947858052d3b9c885e07cf37571dc719f8a9df31c57f7a998aa76d8bcf39acd3b67ef280e14a63522e7284ee722c7e17cf31cd77add7ddcb72ae8ebf24f05a98dab87b41369f7a1fd87feba5fcf8790240b594cab64c12ccb38cba49665195ca0213c5a8bc2904aa552feb28ad1d183a606204238514bd18ccbbbdeee7641b50b83f97e7f0a2e64a615d3344d6a52d3b06f852395da6c0afcead1a3478f1a80e4503384480f3e18b95996e1d6f4f5ae5ba423375c7747467f239f476fc3574848e443fad2ab1a1f42bc1ffd39e090be85b9dfe3db7ff4a0e1013d16a8f6582c7a7cdb70b479f476b8329cb76b2b2382a7b8397fdb39fc5ac475de68e475dc8723260721353ff4e8c12faf37a0ae43a55c5e56313a667ad4c0bbde2fa58b0c19ca8dde3964cfc7ca928f163479a69246e8b926a516176685a3575df7936db12e2e2f2b1c3a66686a009243cdf288779978fe468f8561bab8406f27c0b676675819e9ed015819cdbd665a737cb3beba7cc7f8c011312c2ef3d8bebd1ffd9bf71ea105529e3f5e8e70b44511e79113c5d5c2b0cb0f474c0e715d5c36482b01efeee82831888787d96bf3ac374f94297aa650f1420042cb11c322532d0933055b2287bedcc72efefa45dfbae62f6cf514c862177df18707b2d835264cf61f8260173b2f81acb3d34f98294f4ff9018ad203f433858779a2f0f0f0c428a38cccc313833618709b9131b70a2224f9ad428aa087f9ad628a2fde7747032d4c7b3bf6fa760e895eed73cdde3fddda5e0dd46004754b00aef61612faf63ea35bfe7abdb8e06a6f345a66abf801145e002db3554411f4edf0d5aded814b9adb0bd20f215ca8458751fb2484ce3cb6e61e2dd59230b9986f775dec9a84addea29bf0ed32bbab6a83f37567e28b435108b2daa5b743bbfa07b2da35264cd70e2594f0a4e795e36ae727232bb850824e9429b08581c18a93d7ebf522c2d54bbeb293ea3ff4ec3240175e088307b6728c70c5d51e81608b81769a0072b5c7a01aad0c45a16fd7a2c04133f6f91b687774cbb7331366ff688efdfa68e18a5fefc7e899f6cfc25461f6cf635f3f438e9bf316635c18f66d19483bade4a30560f46a3f7eed9f6f3ffd56e1832b7cffb44c655ee321d59230699aa6b19768876be65e66516f50fe7a84be9e0dd0bbb12cc3b428e1d622166d52e346bc30ebbb63650cb8e8ab85590ebedc7cf711bae60c3d730dba06bd88166195bd523e742e02a98c5f70db321b83ce5852d7878928bee94d3f08527f93fa7624f26db42b6bbc9e3d87f9489c79cda1d79827396c4d879e4fcd4923ea5109599a6f50abce5a4e6ca6424d3d74087dc2967428010d4c314615b4b8c2043b80c2b5f97a12a040167e9210818a1354a82025fab64f4256e6f29bb0a3710898d3cd4e601b3b0c831f742c3a3b16b908f4a64e6c1b1d028aa67953150eedd2db25bde167ba2a1bf8a3ab8248223e3a7f7cf9506c8a40dfaf395fa3c37d1dda397633914add743f06aff01550a818bb34ba86dd1d81950f5d3ea42a1ca2438fb43b324f9132c64a4ca6698c611fdf6037d86710a0e1ca952b4c060ff150a669317e1c049d90920eb1412e28199f11e34b1a2f2dc34c8a8e41e798eb18ba25e0f755f98b7decc56eee238066c665cccc39e78f9bdbd6759de8e42cdea8eb4c26af2e2678a5e45dd775236e3bcd6d9bd408ea37cfc877bfb577f28de3b86dd419416d9e725971ce0e448ea8731b2d437e7b7139d16a0455512f12d5d95512d7719c11d473a817a1b86de344ded16ae43b23a8ce088a478e8d5cabb21a41bd473d80fa225be7d649d9d1ee0653feb7de5a18d91f266918018ae1a22c81341a394db3b0d492732693a9e4d239d28e4823d25764841ac5de584e24d289c4715fdd1e96adbb9141c4d148c5426fc879169613cb8992485fdd1e9293bacf446bc9db6f92f347722683f38a72138974a23507a7ab28af9d9bdcfb6a918e4e97a7e87da351e725aff3923772cf6960376d702aca4d24a7e9ce063ec999e4ec261429bee7755d7ccf491df53c2775b4fed0ddc813e944f21a0489147be53989e415e73b6fe74e273a62a1db2bcfebbe12add3fbd649dffee8839e73dee7d19f2b4b203109096e5faa7b9ef3e739578928af261f9d4e1c37f25aaad339140b8bc96462992e1de58d7c4f4ed3251bf8dec9fb8a9c4eeca5eff455fe53ec8d8ba81b375a6eb4b4a050dcd6ddc8202210fced39d7d27223e54a6e6ceeb9b799689d71ca0e02ec1e0bad39cfe2a5afc62fe194aac96bc947de7db54889def4979ce492a5446bfc9273de7da7affef0a7343a35bee41d10b0e4d34fde390d2c7dfba7af925c3af7d9e03ccabbaf9a7ce4ebe180f345d83da7e9920d7c9487fa8a78ce3e32d19b7ecff4b1775f8ddf75255a71be648adec9bb71c36b5a6eb4b4987cbd437947bd12ad3f7437f2e49d82f03c8fc6d35759dcf36d9993e72a16af385ff2768ee54332c39f9ce38ee553ed90f216afb9b1c3ba922849790b3db9921b6e833a649d6e7ca96f216be4ebe98052e160f2939f6815e24dbebfde99becd4bdfa495446fbafbd6479ff7ed633e543bdcf094d7d8f016e7b8bb415336680bdd8df61633734d0df9551c26b8a9079a73dd84996d3cc6ccbce4dceaf06dfe55520634d7c705529e7dfa7a3a745eea9cc5ebbad3e974eabcc4e21d8af759befad9f04f2f32bb2526893a47a4f2cff6e6574f3e55277a43ce6f9b57a2153571808ec65c1f1744f131dd8a2ecd054fbce6385ac6dbd36173f6e5724427b7e1ebf96839d1da7f72938b44ce7d95667a9d79d1f41a33bdae2610345cb9b2c69f9ce4a2b936fc54472eddf4d90c51f94fdfbe8dafa29cc55b3e1bfe92af67c356fa8a6ccecef2754b4c146ddfd2c7222f0531b988567f916f5fdd1cc90c7f9252e4bb2d6e731590fd13ed6e307dd24ae4a7b7a9e4eba2d2e7f9fc48b48ee80d26fad6371cbc1b72be7324d81759ef5c762ee59c1dd77d2a20fb406cce39e7220742e4eb1b5defbeeeeb2ce6e622e7826ccf73bdd17ef375d1578d70d06f14097cee3566e6fc517e95483761663a7ccf5a893b2c642d68826806dcbed4961f665ee6cd2209451cc1093e406862c7c53936a0c21786aae069028c242e0ee3b90acf323c634c669d93e60727fcf3e2e9209d1e38e424febc78b0209d9e6cc889f6f3e291413a3ddb9013d1cf8b870bd2e9e9869c783f2f9e51904e0f69c8c9fc79f19482747a4c434e4e3f2f1e54904e0fcb508b13d85a57cb8f134ef0b5f5d18fc47ca436a42b5f973d1f363e1fd22670120c93bde3a2f875301ea500ce869f9d79a8b8c28347d9c4775918de2390760bd3bed45b9834be2e71c657d924868c0a737da080f1b5fbdd010c7607f4766f772cf7ebb303268fea559f80b4b3debdf6aaf5816208bf3e50587100293d0042e9d7e78929587e7d6eb044fe4ad9011a3d40e2092c62cb54ccd78bc82accb9f08b8e7df0374375c30cd5584db9b412988d3c7711e61a41bd119416384a59e714d38ecad4d7f89a63b093a9be024bac6146abff7a16635c6cd29a7a0cc33c3e26139dc330cc610dbd6aafd1338cd618234dc611093f4078750e86e292873e3f78e261377d9c40e3d707073cbf57fcfae0a0e751317e9156f8b19747a49376f0b9e63c3b747ee99ec2677bbec83a8c1b638c2c5ba64a39672ae5beea195ab1edf9e85c246234d29cc8980eb7bbc3eb7639d1eeb6be1f6b1916bbbb7d2ecc76b77777efee2eafd771a3d14683753941afcfc9bebbeb4286cc4c996b04179198ebabc52c61ae8f13afafa9a1af32e5b22e21fdfa9648d7e6da97a48819d7e64ba44b2412c91f545073114857c0cbc408db1d3a15221dd2852c8a750c83c3bc98ebd344d0fb34a1235b667d9a00faf6ce25db79897449dfdde184ccbeb89e15b9e98f14097c2744a0f9e96562840daf5ce1018ff0ef952b2ecd6ffa9dd07c3d1e68706974212ba680db95894d2b8ddf42991861c32b5778b4d7f5b847f8f7ca95f69bc68186cf810c8b80827122acc33e8e963ef0d04b0f310c1b01f6d08fd4f0ebf5c29c137dbcac2c834e836c0f5d588771ce43479d87f5ce499115fa1c578eab5d8abe2422e7be249c774f4c9bb5f2ebda4580e6ce36e43ce634100e117150c04be736ee2ef4461b45d2af05e9d7333d72333f73de1c1127f382c4e77cb08b8e48ca0b93659ae7434a2dc322848ef9c034b8852d28d1b9e8f1b0048acdcc17597d8e6bf3e805d1dca632e6db9764f322a0d8ccfc0d4440e6f1c36cc8f9e85b1da2c6d36b5ec31be5656d21f87686a279fc8e6023883408f6dddd8b8d2045d29bc7afa65fae8d262962ba761150570111e73b48fc1622f2ed5bd2ae24d28b902e11e54500e68b39371424fd9a0d7c0d8a4631ca594722b87da9d9eba17331c6c83db0055d31744bccdef938b43bd8a3c8a37316b677fa041f9b888ffc85cd2bffc8c841d0a1c87b07b63020c882fe0324699d4129a1da3b0f7bbe760f4697c8634350e4333c4663af228d49441fb6588d491e7a8d3adf1c93c4259149cbb0672f8c082e3a87f1300f8cf24f0f980be6441ce79bd9300761e65b96f93a84bef97e36433c7408b5d911312bfffc4621b8a465a447874c5a66f3e85047e4d1e14ecb701e1d36f17cabb8628e2b6e956e4557743e6388d168192bbb236a5276f408ff641e19f4dabfce3fcc23a36d85b9d81d90361816267a6c2fd3bcb6b230d16114264eafa207d1abe8de079d4056f4f67e70ffc3c244d77e8c3ed8e4833a1fdce95574d10791804c8460abad54197d295cd2ab6844c664c2e85e3f99982ff330bd7e7df62c4ce4812dc813773b4c68623cd1394a74ee611efdb104b3eed047efd77c58985817e8238fc75857cf3c30ba6c5ae58c1ee521c88a1eaf7cfce0abc96caf6de5635be955c4b02ccbb24ea35711be201566f4b6f2d3322a1bfee5affcd14a5b890e5fd1e192e850077b8db6e8e9e42e8470f7eb660966ebe8415330d7ab8e974d23d0e4c202b9e22a1bfed4bb24c13ed3be8a99e920ecfa6ef7946f6f8a93354ef40ef28660ce5455c3bcbbbbbbbbbbbbbbbbbbbbbb53fa673dae63ebd9ae0bfbd615bf75c17571cad757eb9d44cf6af103650b3a5041114a20c1133e5c0801075c1c01a80bd7baafcfeee929fdb3de4071883b4b8117cfa9946f15fe1bb87da952e7db392ff4d0b7d7ad85b0279154496f85198120ab9dc463be7ea3d0c2781cc258b02dec09132d83797bb4b23b326f8f5f581e9a4e6541af31da8ef669447cda6b61dab14f7be2096c69496c0cc3b6b4122cab3de66b462b1604c88ad89354ea74fa1a87b8990767279855f3ca3d5a106c693b99f6e4dbb5cc8a9c3d5a500f6c69afcc4a0fccacf42ccdace8ccaa0559f9765ec1ac9811be1d46d9812ded07b274604b3af9766c8c6d694141bb83bd1d8bc2f2e8d996c6035946d81d98b7122cc8b3128441a3756e21d382aa90029a3f5fb129fd647251b68c3f74c6981ee16762761f9f3df68e7ba230211840bd823f0b337a386561ba5d1c779029c6c3aff1c056f604b2dad90ad482608bab5856fbac1a4fbf7eae905dcc27a4c6d0825ec94bca431ff77cecb339dab325337a8d4030ca936c0a6c2dcc9ec0d66a05a7c06cca14a9d12a672a7bf20d9740563b3ff99a7a4e6804b3873a7a61aaf66b2731e7afcf500e6637315ba887dae10b7a2cc1acfc82241e5e839847a4dcc339a4b03b983215cb3c7cc00624e9d9fdf6011d139a35027dbb0fb8577cd14410f785ab3d0a318f7ea6f5480ab6b020c86ae9d9ab27f55262418c053d7449ca41329855aee0bb85dec6870dabf1d5e6a307c18e7ca49e0418369952a7e5889898ddd1420bc3fefb52319d6767eed6b417ba6ad2c20550174ab6b0820eaec4e003202821451323a438829d10b33bbaf38ee2705455d371187430e4ea3cc7e5798e8b55355c1c822c76ef8b4131414e9ef044e99902141413146305bee012a1216c09f6b202a930ab3f735d0de79e7b14c7abe97ce4238a33f2ce735c51063d62608be60acd95a15eed8fbe85634cf6ee9b6bcc3abfbd760d7e3ff6bb1b4cee35df9e35807ebd1fdccff48a59c7c70f694ccf60fad70eeaa01eda560e0fb0d8620b26487022892fb8d8dbcab6828041126428b1021d08c1898b1d9e311db63aa859ecdc415c8d7cb750d55e736c79c46c0e76cd653779b5acab5c61d60efa2017899c77055d93746a22872e9d137df2b7af7bf9d59867b8cc8d8df6b76fbefcb4afe2c812f0fd19417d0bb5cc173f897546cce0c90c9c409e5f691a8661580ceff48a25edd63426acfc8d0ff9f395776470860caa38e66768bf473001d0afe703a335e6355a63b02fe6fac8e089af70870912cfbedf640ac844b7d63503a1af10c219043d3b849bd7dd60aec71fdebed031f8cde7a2f7c3fbb1aafc5914b97cf875cfde0f11e5b4309756ad6a8e49d7707cdcc425939669ca4e90681949631c66611a61b66362cc762c0ab31d0b9ab0e50d4159c210a4d081bc039398d811667b2f319bd6606172ddc4e4169654185369990a31acb55c386182c933a9491464b8d8798a96591f1a80e1d9f4ec2c45cab3f34fb7dac55aefd060688c67874e602b0994f57132c54be1397ae66a7cbb60faceb67a88b282226a00c517bc70818b9d79b69503031ed46005599861c4158ae0ea1bcc0a993c3b64d22d87cc8579e4663e8c41129b83bdfa125264d8e14e1498e8162f3105dc7162e5d9898f93a167e726fc44d3480f771686bd999831ecf4071dfb7e1842e731efaff28fccb585a36af3f32d81762d64b5f6ed67417c37bd5a6ea7572bd8e22496c5be440c0e9807cf2bd85a57ccccf6f04eeb4ce884c226bd62f6686556b8f3ec3862681bcc853c24a03ae7eee829434e983b7a7a4aab6ae442166f9faa66c39190c5a3928a07d1e6225f978a87ce39e7a810d23b5fd7f23ce6952b820511a9826cdfbe7d17d1bc3deb2f125d65c352c1e4e7a3475fafa960f2c4c36ffbef87edd7bb4fc5c3c8a54b2a44e7235f97e853f1408570ad37c4f38daa6a36ce3749e37a43bace2555d54817b988e2885c7a8e2bc735a21108b27a208b9da635264cd6d971f2244a4f0c0dd44142ec710a7bfc61a1a067a067d7a230b7af7f1a08b2d8b9af83208bbdfb5a08f61064754fafd6d57deb5ad7d64da677cad95771486b6d073674c69d659d712f905e41e1b5b3f2548cdcd6dc1997c4ceb8b3ac336e202c80e9d1609af40a66477a6d01dadc069396a92ea5b700750bb604b55469116a196a41a3250d1b2f1b496c2cb1a1b349df59c118016607722d51becaaf2d402d4090055b7a3ed21a23f2ecdb562987d9812c29698d5e5b801ebabaef5b56e6a2af5680f599c3ecc09607b35361762acc4ef76ded0561bd740e2ef76817265b97e8dba0469de03cfbb886e9919d25e98c3bcb3ae39e3395725fd59d22042631a1e0e2075beb6ead9f83dac7bbc29cbd2018c7851826e13ba17bb9479eb917f1f2ed47eec81cb923e4cfa81312934498295fc5d0c0d66e94e976157d2e2bfab26296159d66591148cbb4b3dcd5177715bdbfdd55ac3f3cd6c9f819b5c1792c4631666af60aba3c742e876651205566756f198ca2fca565e082c141ef6eefe65eeeeeeeeeeeeee5ee6ef66daac2bc553630efc274f737d6700a9725616e8989978c0d89f0b2c2a16386a6062039d430efe87983103e71d2de0570342197f48d2e64613618faea127d6c20f4dd5b7b125897a4db2d98fed545873280c2f079828411689023c51a307082451090e093c4d53e5af084cbb6360b55788110d288010c4c30e46a7fd9560d27f881c24917cc20a30aae761cdb0a410f9ae041132736b08114ae761ddb5a32787686a0808211c06002573347d622bb58a95b2dd51b0ea73005c81420426a8610e9c1c80f3741bce0ae562b292bd4aa1b25c6aca88f11c550c0be30d7c541b1e38346cfcb5557efc50432c503a7afbfe5abd3451e3d1bfa4d7e62a12547d18afad2e933bdc94db408e7ec755212c58173e6f7be7d1ad87dfbdcb7a2f5ed798d1641c2cf48f82b12cdd96f348a84bf48078ef0b30771225ef5bd62701c1a62a050d8335aa47f502d12d291f94851c5e3368d4c25dd6ee7206f8f9a5909ec878e856199981f5dcc3a4acc63867d1d14d5e55be2c034af98432ab32f62195df5aa338f2f1af42c73ac33485399c7ae575373cc39f8759aefd7f81a4da182d698d0b5d5ba0ccb6aa495e5316aa4fb4873beb52bdcbe64eda457cd4416a3635f3fe9557b3f91edccda3ccd444f692755f816bbd6470a30bebda370d232fc82d92de9add38491b0c1accda3d351b44c744cf64f34428a28bf3e43787d8e5f9f21e8fc8b6582d0e9553b23d1abd6612566e526dfdea4652aeb20f1af0e07043cb03b9657116098fdc0baca0883977084062cc00b57bea30cb87d592d4c1be09bb5393ad5ac4e311731db6b8a6738c81c312c321b31612b765f573160a0810691294c61b62fc62f307ad080a301387a2c0ca4014703702c8e15cc8ae33ba8833a688368608bab728b0e370a2325224484b3823bd99531db1713123df3e4cac59e40050c843e0ca02853869edb2c8cb93e42087a6e3331e6fa08e1e7395297a17ae55ecce97ac5d1f78b79f9ad2b855a18d8a88581361e7a5500cbe668d7e8230b269096a9297777f74fadbceb7ae5a8a159e78fb9f50a47af72a2af173df2ccb28da95eb9cb9cb8a5752d6e4448a3d3a0f2b0bd8c62f19d58e22ecd9dd0e8102817142c523f783d7bea072ffe420d356ab0341db9e53c11ad3899f4f57c7811c86815b9e69eaf6783e652f39d4ef20b8cdcf36d9278d44568056d282626867b8618fa762134b04e4cd6e48abcf2ec6540b6e582e1046038c1cb083ada7be564d62983b98b4f9980d6c1f946636dd770a44813798d2f696def166d9e51ad0ab3a234672f0829e863d043efcf4884aff942047dfb103d2219cd339b19ae5c49a39de4c8cf066af4db031bf4911679811815bdc66c0fb23ecf1e37cb2886c3b2df601f895005212da1f3ecd15f446041e7256645a55ca0af76477f5019dd42dd420cb5acb7146435118ca665cf4e35adec29b8d19acaea0d967d6dc6acabc54786104aa1d91e9bd0ce71c38869abc66a66349f1009e48a9920333cb3c6ac739f6899908561e736d82710610c064e7bed0e4864617a48a1e2c53318ddc6c4e3388dde195a71926e61a059ec699c81c6739d398391d82a4ce00cf487b4cebc461e80f94d6fa260567ec2685079cd339fa1812cf6ec23025b429ac50e241434d3bc435f67602bf3197ef203f9c94c7b7c1295cc3af324cec099cd86af4048671686ddc90d2a5cb72a88d91df3f4ed550108581ea5cdd1a35f22666d1d1f8458cb62478064c0b3fbc02fccca4e9e602a52a688c28993c856666520ef24a96634be817637354b100359d9e4166230c320846d029dded13030a44900f443600b870e20e911cb0148181847af38a659ec5b8f990c46c83d78c9cccc8c08c78abf24b3b64e94d6691d1d1c1e29c7753b73b60e6409b18e467d681dd8fa61c9b78ece0bed7c3b1761c4608c11760a445b84cd52cb961bd59ceef11f701ac70d31adcbba93679d6fddb60ce6bbcef9fa9a46bebe6a1992afe36899e9eb313ae2c2789ec8510ebd8462c8ad27819c18f010b185175801e50b315c9f476be9e36f5871fee4f033d2bde9642a7dfc581785f9c95d795dbd217d317abbf23aafa3ec9c8846e91d8d50c0c4a012658c5e64a3acd1638c51fac26d730c1371954db4ad6b523af6ad4b2c7a3e960ee915e63450f3fd30ccb5fd5804309e8378cc23642f887ccd63740c5b6aa3bda6c51ffb516e8c45c1c58861910993e7209765beabbdb636da67187bb363be1f631f070d818e7d2c05ceb1dece1e84fc76aed22ba68136da778c391a633a5c3b8a69302bcadb71c4e868195133fb7a4cd3cb6154d3b63a3f85f2a28b6835f22291cb33d32af2a86118e618f47885099da56b996e49855953dd7b45cdd91e63d6f8ddc566b5b714e03792fe235a7b30c2a843dc55868d200816b96186514845105e41e0913ef8e1f5f1c14b66b6d6832176f9a0376cc8914e6ea64164c8912153890c3932642a912147864c25466628405f48bbb1237863b85bc84f439681ce5e49df1895594cf61a31ee3baeb62dcc1ba3a866b5b757120a15c48b45b8bbbd8d60633b9c11b32e50b633eb2a660a902a2b287ebe1d470fcc03f3760e308f0df3f5c83ca4af67dcea38afa3d7d8ab0c1d5d719a8daf2b1b3608f135c789296c2011f2355a3d60c6f38fb562c8060688e1d9f4141f36ebf322e26f34ef419217b936c673e1055a30e3d935cf862d638a67afd20331681046189ebd0c29168c279a10c6662184c5428ba5a2c56611250c3040a0e5355a73861006038cc8918568dbb66d1369a31a64090684b154b280f962a5051ba8149e3d0625a52c6814b42e7a1040bd46eb07bc286d72935bcca8fe608467e744dde6fde0cef85105c18f080469907aa60e9e6fc881c50fb98467975e90fe8a448a4d6edea88ac00bf28b97de0f4c8967df3c1b60148ee33891881389384e2412711c2712715dc6a8feb3b77743b6e40651099e9df382f078d686601f6f8ecde50737c7e62bd8c296b57975a18165a335e65b4431d02b0d02fc224ae40b13a347fcd7fb7180b7d92b6b3c7ba5dcf6f17359175b061e4192d9d0f022ca0ba3f976434e90edd11c7a41fa25258281c640af86ac945709be872f263711203e3c53625638aa98bd35090654b480ca2f152dd031c02f152d7022bd98ebf9884966f47576e955af70446fb325737d78a67c9d7124fc15feeae8d13218dd1c9973fba5e6d7ebdeabf6679e281e0efc90be7c61aed34ea536d214ca3f9ba8dd71647b1e49bf0da7c1bbe30812f998df640ffb33e8fcd9c78f519bbd72e523f5d182259c63d500c2a3d8f4a4e70ee45210a17861de167650e5515de6f9d8203ceae3cfd633cf87f7494df37cacffd85f1a435685b93e3b986207541ed52bd9f1c683edd767074f1eb58d9673acc32df80d9672277283dd60371884ee446eb0e944be63419d44a2af122149392711918805751a491389e4cf99e60de6cf3927495ee788e6a1137108892cf4bca3245ae788d65425e2515a53a91b6ca66e886c708390831ce4e006219432c541e87e83119142565240f3a7ee14af333f6356bbaddddd4db94b1b7f24316cd06f4fd0af6fcf6f907b49091c7b3f2aea453f60dd749092a341a0b743230f5122971c05c10cefb9f4edebaf21bc21e73d2ab7a337e47c46bb25ada5ba79d36ae48da09e49ee7d15f5dec9b455d44b1f6d9ecbaf3b99e49c23a781de37a2b584faf9d512c93323a8afa29e736e0459d856873cf4edab467e73d46f4ed35044ab9187de9c4b88f9421f51cc3d5a8d3c9499537a67ce7d46503a684536dfbac7d6b9c8e5ccc7b85015e79e8f1c3a4ac55120fbd347ee397408a92a73ce37af246f9f1f5565aeeadca3aa4ebac85519b7f9e69273e822177d5525822208a17350f3f51e2b25f3cd4531f5e55da84a7a87a22a4981ec8fdcf3cedb1736a42acea5431f7d1e5571aecabca3aa4cc549e92e4232c30391f3d2d737dfbeaadabcc7af7ea340f66b8f5f5f7d8f5f97df7a453d127e6c94c6179ba39c437d9385d6f82cceb944b9e8ab382f72ae6187fa448ee24acef29150df54ed70c3537e011bde02646fa4e842d6892ab1d1b27dd145175f74d145175d941a9bb29df47e786ea295df44fa2ace934e55e4f0ab38a2205ee428a7e9e9ebfd90b4720e4b2e3f123cf97a503a8a9ee8c825ad904ed7bef8a3af428faaead6b9e6db27617ff715c96eba087741c91cf362d6177973319b8b29a2d5bd98edf2a16b9ffce662425a1ffa6e73312ba437cdc56c0868cf2424fcfd3ca31852e27cc55cbaf61591f4a65f46dfaf7222879a74516f241f798de71d69f3d14617ea80dbec099323adf7a3c6f57ad35007110da2b93396f322bfe9175110ccf022c7f97843ce8b36979ca813751413b9fc6efaa5a437e4bcc8a18b441bac380f2945c2cf0e69c5f91bcf11713f214adf1c9322b951d5ba2a6a32dbcca3a7a48bbb9ead47172ae9a843d6de3463988c1dbd914795745cd33844ccd93a6ec175196b4b81ec738e398b38912aba2af3566514c87ee6aa4881ecc74c6630464d85b9fceed76de22391e181c8f9a8c268f7126bdaf56a61d32862580220d833d50ea3ce6b3c178dbc73259e8b32a939ab761839e7359e6f23251aade99ce3a812d1461db2180bceba8fc02d4742d25f64d959e49273fed6396ee3441b5d0d4a8dd69bf8b01a7179c81b739094520b2db46062647f52d00e6977832cb2c88283346602c47a165724922e72259ccb0cc90c0f7d87aee33acc3757c251872c8c6a5954ed20f2cd6ba46b22aa4452871a75c882586081c510590eecce825be7f653ad2fd5808051c64dd2cd1cd332bab46ecf63746b64e7a632a1578c1a71a991dec4871409fc9c8cd90c6e5db8f57da90c04747e2ac6b0f2fcda7124c6612f15558cf89b2246b6ca47ea81ad52e521e5305e267c19126691f5fdcaafafeb5d65c9330efc7abd0ef3a3c30f49fc48f7ab39af0a22fae8013e8e006361f66337bb06547e7db6d079d6afcf164e7ec2166fdfbec5ebeb0cebf3f382e7badb7e5337a813584d6435a471e30be6fafca8e01d055a08452b4430a7e99d025b983774f8f303041414c4423a30569ca15eb510fc4ed2aba6f007b25a89593bc9b777929659d22d8f2f28842550591f2da2fc6a31e5d9633784d0f3b18e84164c5c01e5e612ca8dca19272633e74387402d087b29b71f9218042efc3423263bff664998f1978a29f8e0d93952968489fd5231851d3c0b00f5eb83041e663a6356f34ccba484718686df764f8183be63d5f8ca2e23ed62d4c15c07435b28a486b38debe2ca46c2648f2b57325abc3e0b2b90b5bf7d2e29396572af9cf4d7a78a35b2e0e26b2ab280db213c33760514165021410aac50868bb1d8c10c5840c5172c60c2135c2bd8ea9f181d2dc3f2ecfed232521e7a842ea728f1d03b14dce0a1bb4cf9824c031e2601080f1d07f498133c741d3f2ee83d5a66490f1d88d043cf418812ac3cf41a1bb8a06380480c1e7a0f2dc3f2d07de079e846a0cf156820e0a1077183878e0377090e1e3a3381eb43458d87ce48402cbc78e8dca46516e8a14f164f3c7466a265460f3d7e7bb09b67204725b874bb3efcd02d040c41091268e155c6145d70450fa25b394488829527869082204ce10a57dc2b1f9d9f1c31c647e72754e08ace51b40c74eee129bb839f8f584214603479011951aab822189898310331a4d8820a44b8e21a1f8fb8f2313a901c84c0d674451f4264598c095d6e6b5da85ea5b2b03f9f5f500a5ec20e908999ba81f90c0d27674ace949ca9de81aa1df31c8ce2883c739c6d35177d423e55cb8f46d5bea99aaa76909e798df40c074ad39accb74cca281dca6ee84507ed0e6c6761a44bade7a5d3c016e682c22e55e639ae922aa342924c37798e8be40b2b0f10c8ca9ccba457d68170947d75e6e593af988ef44c72de65a6aff4614e204bfafc48d893972eb730d745f20959d2a1d434949a919328cea8a9af4bba6caaaa1979fbc8dbd7a5f2a8f41564494c67473ae6443af644fae8d39e409674ccdba15d980e6449d79830e10f50106ce5b8a4432138241d5a5922bdfb385ad98974ec09c6231d8b225ddb91ae4911ad5a948d568de7e5939798ce4b97b488d693b5880b1883c9cc9cc27cb54f155d240428c7c56d9ff6d1a8a28b3cc785b33052d50e9a6f5ea3f9e691d66c2ea2383190057d731ce81a74412626464b0be3ca38961ff6c575710be184ec10ba843e21ec2805d7ce35afb7cc17406acc408c35be18021a6a8421cbc9c111c2a086174918a1e488be428b35d080a202269670795d20010fa080b10434c270a5810425befd654600bf3e5670c18a2990a0ca4dc52c93b4ca8f3146091b8bd139e6604374b7102627352945bdbdbdfa8ef99ee1cc351ab34f661946abfc69209a65ade76c1ca7e884c438c13e2331af654e200dba542a76ed28295d6a1475243e468dc8a6e2e7a17331c0752b0f1768ce2c508c84af2190051dbe608b8598c52ee59c4ca30c812d29e704a240b5a33cf4651ef2b5de10b3b25013cc637b096c710ea7740b1e4e227c854247640c819847466110e7800e1d3a61773085525818e8126817e75008b6f88a65314fe11cec9095f0cc424ac6483d6142a19882871ec9d816f664a3151e462e3c8c6a605e31250fb1143cf48ab9e0a1ef62327888094116f49488d6d49c9810ac5890462b06f49156ec079bc2500a3028e3cfa0802f98d9925ec1ca98106c653ccb821e65a8e7a167531ebad0d0432b0f31a10c8a8581994ec62483e2a1472b73bf664bb8670bdbea615942ccc3029b831d3a5761190b2b133d0bcf2e148687fb042a3ce45ff78865be543c373164613040047eede2c0f819532d53a1b3a37a95aa53ba30adec10621ffff5faed612a3b6736f320e8d9dbeb047a27cc66ef28b3bd6e1acf1eb930db39898443df431d51d0cec118cc211820e2f9d2f99302821c0437e65b054ff8750b2c0f66c22a1cb222ebfb34dd3b369cbe9f28912d398ec24c984723c139da2533f1287c41563ff9f68e56a735b50375bec1f8da4c446927dda47790601e9dc4e6e8182c4cbba4487c3b6682c958e67ded825e0ef16df64a867d303d44e6186f8e8883f1aea2631f4780c9e8b146c8c3b57482db75b93ed753ebeb006f97b5181afdfafcbccce0f6a5b2e4b28fe3c2100f2c7ad0d3eec23cda5d96055dde2588e5978a264d1ed23aa9f46adfe54d9c838544290318aa620d6a25a60aa167af01c89367cfa165e0b3d74448c40753189e1d6532318f8df3f9a5573e45ed16c5cc0973a570610a4ec70dd95e27ebdb4bcb6a395decebcd85e91e33bd5a1ea2d7f3733385b2322175425543c23e9ccc852001e61955f1a00991b9465536fcb2eb05b4af2ba3ec09c1d63553debe6ad8900932c608bbbbdb65cb7c1331c5771361c5f7c8d5ddddfaf614cfb7bb100184ef6ef912615371c5b777b7a8d8e2db5fba63f8f5a182078f3d9149f1a400852b4f744109340882abc1400226bea1ab7b60e2043c6278c1042fc882cc3056cf0cbebef4442b4899d651c3daf908667c7b4c75017e7d8e40851ffdfa50a1f3c3832c06cd031d604f60a532188359d5ba960d7c60c50bccd8620d25b8b21728e9220b662c71c20f5cd917b0a0c186c593a85123339fb98e9f5963626260abcbb038e2b32c662e61c6dd63df0b6c94cb8d5f9f2e88f0f3d7a78b257c7de9c168c02fa8c92ee5a8ae57dc3e7b9ace1f7e69dfcbaa513a7ab44ce557cc4ccb5891c5b747d93ea1155f7cfbcbaa3d86a609df5e03907621ed43da0a297c7b0f2d837dbb0fed3fb415dda15c823057bf3e5634f1a65f1f2b90f8fab2820e128a4258c4ce28a3ab74506ca11612ea253162d8621847c13cb0751a8966d24b5a05add33a3e88be5f8ccb3a2216b199fe623847f4f67c2cc7dd7ed1d7d321019c23461dbde24f47ecdd88849e1e29f4f0f440a1e7a77654e036052511a2f8f591228d6ffdfa4cc1e4d7f39159316bea3b665ee1db6750dfdd55f8ec7cbb0b6ab64c453d3fa0c7caaef6eb1c5ad67e950fe8115ad6fed2cab45b35eaf7574ad7537030c208238454f20da66cc2645f661250f1faf5e9117a03fcfaf4587917cd01d231c7d10ef066618e6111c3d87331c1d468aa579863de987760cc085b1bd3517a9cb477aa7b087d665ae1a1bfa4d278087d5f2a1733f3f18c8f3ed3a365a0f74f8c31462344f131fa7ad0e3f66cd18459a3ecdadbe1c26db84ed3fd2d906c67aed7c8bfdf7eb73b8163df971a0393cc941ca3c52e9f22a4f1cd1be0202c022973106e7f77a9acdd778c47187ecf23c9d80b7a245dc7f7bad1ee38c2afb7a1e191647f84871e89e908fcda7dbf5ecf3ebbf6820852c840b1689a974a2c2cbe9e0d161b9a7736e80d392d5a8b8d1b2c366c9041060a95baa152918142a16ea0503e6a7116161bde6203e59ea76cd838a57ce479fb373e1b7ecfb99467327128efe34f7d35fe447d353eca8673366ca01c153d1b4c269409d5e5600c92779fa74d4e1b79d53cef6b718df35ce35cfb6ca06cf05cf337994ca692a6b9c9860dcfb5af12790de59c7b25f7a49cf354a2de57895422cfdd2879f5dc06ed96989eca739373d4d3386e0c13e71c8fa1611de75a89d3469ee6eb37beaad11bec3b6fa41a2206c75151289d43a91dc939d2181a89a47da619660000006490c1c545a58a21861b3752291b365a5a585850a8d3c9642a95e624914623cfeb3a8e1389b68d85a554a255a2bc6a3b524ef2dd1d25afd8b3b80d12add99b7ce4a96f1766446bf69aa3bed76c5094b37cbb30285ae39b7c57a6e426936b5e22f2f5062b7283bd562a9568f592e6af75ce25ba14878e7ff4ed3b911214aa984c26138b771f8b9b66c93b2f695efa506ec3357af2f8a693c9b9538b9f4eaa1619349473dd953e94afd7e2348df2ce3bef34ef5c6b71d50e2a950caa1b2e275a715e73194a5fcad7d3a1f4d5ce51b45b627654d5b9c935da42551d0d52f29397fcd4cd2aa62a2593a9c8ec26ada752c7c262e3ab265f4f7dd5446f3a06c7b951a5e4fe259f25975e6a69c9d95e95e8ec3739476b7f8ba764107f6271d407046c711b3e2a95fcb43a4d6fa93726df3cf5d96857ae5c59e36db80da7e9966f7f648322e137b9c9d939d357720ef5f173d053ed70c365f00ba8dcc503c2eca7afc56f7c32b8ea7371962f7aaa1d6eb80c5ea37217e7b00e158193b7788b2b51790bdd5eb178bd69d3d7ffa6af5f06bfe1352eaeba21c7e427194c7ec3853a6499e8f66aba2af66a3a4d9bbe52a934bf7ad3122786ef75e3c6a9bd2f32eee32f394dd7b8c3f35af2da2ae870e06ff1ee6bf1d211fe18ba256611cd4d5cf7955cfb6e78ca4b282f995c9bae79f755d4775d37519a97bce49a77376edc70936b5f35f29ab76703ca4b6e9a27158ade90f3b3e426d74a5f35f2251bbe9e0e279fa6af9afc06ed969826aa3279e725da1a55996890934f3ff92c6937fc2cce7137ddab11d49fbc730e0807fc0d7f078ef09f9ca63b16e78e685e62a175d21345c25f6af11a3ddf85a99dd756c1674e03539f8daf96b6cebdcf09112871284590f0102ac7898142e11c4ae51c09ffc83993731926aa0ae26f727f9397fc865f15c4e4d24d2e47fca7165a73bec54b9fe9ab4650ce42ebfc924f477ddbab49eb7c93c94b1e432b0647a16895317cdbac49abfc5235d252a48522e13ff97e3582e2ba3b7dfc27166f2f88f49373a7cfe41cd7de0d39ddf2f1899abce59b0ebd169fb4a2bec56960a712a8740b978a433d0a9942332302000000b314003030141088c482c1584015f73d14000d90ac4a644a9689a32488619432c618628c0100000020003333a40df635ccc233fcc116b719703863a4f80251cbc14e35e72992d4035737703ead0b2e916745c401ad68218c57cca910c0764da566f61a8f401cc5f356334e159ff80f6eabe5b15f30890dc1cda21c5f51cadabe5a45c0a77643d48263140444cda0d8202007e7a89d99dee0e31dbc559238142851403bd2b585ed9dfef6e785c8740c86008c9ee508eb00f8bc36747f9f58cdb1d88aaa3d5d313a73da8b1aa6b1babb0b5833d690ebb694b4f81d847cb2e39ae224ac9cfd2fe886d845c0bed2a1b2366b7514ec9e467df87c0a42bd59af28a280cfee293e79b23a6a9ad43527212b46e1dc1a3392b25c6cc1ab534a487baea1bbff245630b91be2e4a4f940de6b73da1dcac182e0a377c5800056fd98a39f0a98405f1e420bc1b104cb97513f7bf54dbbef1a6c8d97305cfd91a2d62488e4a6ec3d7718bdd7e463d512120004febd1260ffe509c69515d059b20dd428b298e1dea1cf8e8423f361661be94596fb4501eac3f5a577cd205d3fa8ca6f99ebaa4f2ba1cc3ad2f2ddad942f367d5a6b123d4976aa17794a92d29f00f2987e3c01d0f58efa24fb26f01b262aaf4979b91bbbac3599cbb15bee1e7b984824d0c4e03061051afe8fe10fd8b85eb78628d28c678290dee5f04b3a6444eec7b8d1ebf4cb0174b1b8efbaf01fa2c74dc38969e9c42e249c7c5895c99e928ace0b65f9a54e610d20ae42fd8c6a035e6001b3914cd8a5f0175a68a226c318296c91ef37a6cb277928116dcbd02c40fe219aca834d1b2e94851408a6ebffde053fae2a285804456e47ac1599b9360123687214652efe84705e7758785a854b2dafee08736e0135f2ee20473dc8a40eec54feac0d7bf68a59b231104a2998a0904d9e17c3ff679d4f3beafde8b910cf7852c96b9ae2fbc2f9e1604eef8ff0e36f7b06b42cf40fc911b487bba686dd11103f7a506beebce25b9525596c00a160be77db9635647a3d810af447473ebf1617d1cc84b7a48274513c5ce05c2ff9ed435fb2b205b716ba5ed14bd3ba8942823501323bfba2a317c511be1ff4e40a14e01a43e651f0ca6029882bb98d66f0a6ebc9d660134c11bcf8e82dda9ee9e81e6f7498806cfa497d3248d5551388e0f48d098a0dc8f9c04366e680f6f55b62b0fc14a70bc627ba96966f30e5a39f63d3e3c0a1f1b55fa9733d9cfb5bed618ff90bd1d7be223c1ff492604f90e3b86303ec413ee608902bf529ed7895a82e584cb5e06ea66b3b746314537b3198e2e8ad39617ea8e7dca0d7165d3f16db733430aa8a61e2fff718e32197ea9e975a2988d18c16d0aaaf1891099e431e8e5658895b7a62dffac46cba0017200c6a23f0f070bb67db4bc30bb0848369075532a10a66535430e9c98a4e572bdfad0983300803ee8b82daaa99ddf0a7e8e405b64d0403e5d77feae23a6885922b1f23e644444bdba00ec03cf5965d50ac71b38a2d2c042443242d9ba60150d8c8794bcb82cb0402b4b10284ca3cf5e639d627487b102b26ea2f20b6b0803cccc33844a69c676e337b09c6facd1ed31826568c00c8ec1d5c806bd89ef10d386488f254b0386488bdb8463b012881083d3b81ad40fb79d052c5f38d911c9999318cabf8728425a9c44a483eefe9ba4413d4a783a39cbb46ed52a5871210e4035d191ca4e761308db389002b01343a9d6962d81e1a989e6ad551de1f4a3dfe1b432bc510e7bf72a066f1e9ba17ac0ff29959790abb760c063c4a3860419c3df0ad666ca590bcfa87b8e39d123f8ba925f0a92d399cb97b072026bf615a1228a40c3a96e0da86317d3e873abe3f5e4e2bd46acb3e6aa1834869796fe846163dde9bc1b49fb01e847eced7cb545d35188d75c5158169ab061133c89a5be68ab0605d6fd41e3c498c1d899b599aad159044f230a08d7a0bbcacae991c0bc6b8732c3974c0cb6b623aa0da4c397b47730fb280102779ea34c72efb29b86dde28a58f4ae725934bb73e304884842140887ec8421228181676dbbf35d634c786e635c8f5753674963c5db3b8f75305f4e8be5c6a84c662b3dc103bd47a9b2845f5ee30ddb4b9741715fd6383374f5d7a4e12255f85f19ac411959715957b9174bed35900d10a1e22ac66b73d91ce3d4c71671cef116a5a61f0986033a900b7cd3e6af0212753e1855653214d4312910fbaaeee2f5bd21d5907691651068427a83c61a20c3dd15b5ca8833a4af855f3ce98f17e3b8cce96400aa8f7767cd9bcff8374ec7818feaaec0ada9f2c02d601814fec4dd91e3ed098e29f8ea040d7a99f003b50615f8cfe22a14169b036deb5949cb3a83a123014039196c12c00cf2015af1fd7910268f5c3350b0e56806e7700101933f87a291af29a8bdf7f4833263ecce2d2382c3b4c9bbc352ed18b5e1eb7c2061f12af85aa2b83eeb35490c3e0e91ab83d15aad87fd605eed41442264c426ab80d7136ff660f86bb1873efa01ab5846c4e3af78e25754c1bd9a66d682e0cc55a125af968dbc932380bcf7aa69b721a98338da3ea1ecdf45abf6aee73c437cabb3c680b5ae5d7b4dcd95aa763a686836c61b52781fa0261a53580328a1fab6bf61bc37b733a30c798e66f0473bb8c0d830734b5434c2fabe28994a0170bbc97e12fbce47735d0922884ea687dc4c2610018558f2b9daff94847db795afe46f5694082e39af7b3c6a2adead2a7688deb48c0e482f63befc81859a151f1019f2f25a33ef4d7ceb79f22862a28fdf6680dc03c7c101f2858097c3e9320358c33a841662020f2f77ac0ba252322bb93906b9481911783ca6a42cb5c4a567526371021a8a6c9fa1af8ce5e11aa64303c88d87738c81ed456b373d610092e888b0d83ea5a87ffd1e5be52edcd302b61315a90f326c843a187f3b1b6b08fc3a2f250c24cc12cca099e0a84c5e22dc382f9366c2ca5fe07b07e3274ac0b94a555e06bf66ba1b9a497a6bec59cd0aa214ae9d41e2114cae98a806adbca8bf9c08de2f1a42cf3cb4eb55e9e8f75f5e8ffb7fec278ddea403393bc79120c71b1232b4ce06db3cdfd0e00797e9481c9140c83672ad83bb7d89af58d4baecebf06ad0607d26775a9dc29b28754d80590b43894991469ec4421088d03b50392d5010ee1d11c203a0469ed3254a3cc31998465657a1d6bafc638e4a52c8e9143c829c6e93c1cf38eef47da188c28ec9d405b3befdd71bbfb2d2bec2269d54fb5efca708b3f6f556abe711bb4baeec2fcc747e951789ae3fcf51f68efb47fb0bf854124346434a0acc40e0bdad7b20480ba18cd23f84cb241e38f8881330dfed72916eb96fbc79258bdb663350c9a13346557fb4d0ef063b80a56736aa6e47769221665ab17b1581674c1e0cb3863f80ea2715ce2d65534a4d643242bfabb4f2f4f83e27edab1c45e1ba5df51418bfa937a5932db51dac05a96d8b3f8c4cc570980db6ad89b86e51da7240d2828107c1e111656f5f0ba946b62bbb4d3408bd005875890ac041161dc3f50e88f8d32d3f276b61a5d60fed048147b4f5c85f174811eeb50dd3df8b35d9ec32f70f9f61204e21a7f8d826a198968c3cd790daa01457fa33ad001583026428e09c919a13f067430ff70ff6e1c34c0c762040b65df49987ff9af1d3aa9f9fd864b57eeeb1f75ab0a547154181cad43c1d09d14794e8045045793ccb10f3adaebd990e33739c467b7b493c54b7a97a9e278c2b65514aa1f90bb8bebd1112eec40b5d6daa258dbbab2a66f270eb4f8b3c9939c38114fb5ee927af2b4f74e1452ac0bb328902f30f838df84baacdf868a83f5cedb646b95e1b945c86887042085fdd2554d3fdbf6fd69800412f1972bfaef91a1f418858bca71ee52a00b332ccbbafbc44bf12aefa2df1bb722114b63c4814b8a1f30174c4542e8f59f0f8e7c484aa36d07590b4959432d3a17bb682382c38a7c69a26f67af76006f4cb356a636ea313166966726c01004563d21e3136bed7d97b49fda8d21144d63e36594bc87168bb8257343d34d19336e1c90da1f7abbbe8dc6fdabbb009f1759be14fb2bb6ecded1f89bd564c8285788af16205b294ca7fec476b33dc51f1811fea02157393b9635e284a4c6d436d2ea39689441fbaaad07b6047c92aa192b131888f00e21594ccca9456c7d51983f9ece02b25b5f229bbf3ed4e103e2117088cf85771f516eef21e5950866b05f640a28c5265f48bd063f8edbe11488140f977d9fca10f9f09aee586048083251582bcfbed165f61531cae0363fa04632640c619816754d6a84030c0c1adbb320ae6f9941dd11ae1b3554e5b26f492c6d6da2860c32db12c4f68cc304c52ceb1deed04b2ef196dfe7e2ab656ec7bc2f995002916921c8b3b51aff4378600856f4f8e022da9ef1912a1c211645d7a4f08ba6219f8468ca1fbd8617ecc341b7d490dcdb49309576f00a9742a049c6a9bef1b88b1404e0875b3b8f935708011b44085057fdf050fe708bfc36386bc389f8fefe869edc2abf018f927663037d76c043decfd861961defb4ec28d57dd67f51cd0717a667a2ccd80f96a006f07aae4f337f34c8badf5d95a44cc8cf76532a45fc2111f0ed33e02ab1a98bb0d7a17575f5f13940fc2ce0fe76be0633e2ccd279f1c0d933de72452dfc19a489969089936351cfac97bd502c69b329a35a71a91ef30bcb12d625535ae90d5a7dcd49e083d9a4f436ab485bf4166d1cbea53ba22eff15871771979a8611b34bd76bbe0a03862133b9ac536e447bda20dafafa70ee2e82117c5a301e5be8031a4bbf9793827a1dabd0d2ad856714769aaec7094a4dcafa769f5287d16d18a450fbcd9d4971d23d80aefc5b3ea8c0a58303060710fabc0773b754f1683a8abbbcb2e5c0d0abb4e2df5fa425806b38d7ff9f96a627b78ad0a2f79747d42e92a33db61a90cd80d0801a7b702df6044614eac37f77b612ece9f47a4ac8325a7cac54a722d464ea3ffaaabbede914947e13a59a6e5488c9a1c5eb2ee6b89012a0e30aedbe039897c22ea03769cc880f1d0200ba95a6e337e332d82cd272f5ef8c2e852f076b4c3a5fcaa95b9707a5cb689a8028f479925edcd40024d7e6d3b937763afed4e38d2556f1426b81222159f1b3793dd685bf73e6343bcd980dc79d9042417f3e119c1765548c9ebd2ecdc2745c316b5b7a7755228f032bc8e11442d6bf46a669a4a9c866a2884c2cf1db19bbb4481a3a294f0959dc281d73a7f811196174d296a1ed1a1afa315235f99830f658687f35d6e1211e3b25ed58413eb299202e52b26bd55c324ccddf1a9648dc589fc54146245c5a652574295971dfa6f962d6df53757c901045ffe2f7f650a1308daa69911d1d8a0c2ed5e20d7d068676b7d0c4e942d08134c06bbe05ffff23100a840434facbd8526e61c7f294e8bce2e9d472d996adba322ae5d7387e6444f31ae8d5c7e3604f0a61b3d0e635f2108bc49f3f0c5e24dce582b0dbfb40cfc8bfffaf0c0c3cd83291cae8ac7c7df31f61b8c2d94f89dcdca0379c11f59637346742f2b877b88be6f2e552ae3573a50dbe2079af0c25b5b399af4074f408e9ea57e6560f57ed698d40b0f4d99469a4b766ff087ab981c43d04cff8eac13709c84b87fdf0e7a63c4fab9b9c8a683e66790caf1bcf9b39cbae758483af48b7525414229daf836523ffe04a5c1bf4c527384826d910dd18647375c9983456d7bfa120da463ad875cfdc501a2dfdde910c3ce0e8b6a2e7db00c612f3f434d7baf1212ae41c4bf73c9e242d538dba45c4c1126d1f41b17ec398d592f4cbf7c88c49e55360d769c882564d21206fd0f6d66d5163053504d6a17fc95a7e3e4176cf8e102829d8b1b9061ccff25b4c744003c52ae2cfe85d8295d841577a0807fb3515beec912d4116ae20fff2ce3f98bcfd1165af76d28a343236d807e192a59050395ba7140fe2b1a90b3ea4976db411dbbf0ba13b6c12d2c446bf254d66c650544cd06ec361f9c05b6119b299ef61b0976f3179c83e5069fd5116367ea073216e3ab447b586bc3d68f18127dbade2a54a75130450e0da013a90e5cd0e19ce61f88d7d20c35ac78ca2a5d6d2550b096b3142d82094e92f5a5aabd826cf1df81cad80b2acfa800a370d4e0d9931e40901c9e7c13aef046aa4ba2728da74659868da9998e2a44c3e20d532a228367cb4b46af7d80217e6a2b4a97e7315f9680eea4bd08370a621aa7aed83f24b1642a76136aa54425036af3208c1621c05843e049dea603c1e7a87ae4a3f6063c2252802b8d0f774ec25d24ab50999001fdad2a5fb0aa359478f06b9abd9e7644262f48ff5a38734249c79afb866f3043d7a1e2c465447ef20053c85ed5f86cdddba55bfd8c3a4984443afcedc211d86a1e9b57e0d7c6be6a58c2a99a7ad33e98b22e27ca677a621420a6d90ce4d69420d000ddc6cb4d80b3aa0fc9259ba2616dc7468ee8f8e0a1a18044def09e153efb037a9c98a9546100ca77e8c93be081cd97a9451e289311b33c945763210ff990e6cb4532c3992cfbd34ebe1f0d4be3891a60375e15e090070f8bb0f0a2718fd243c1d07ea6b485c2286c5e85d73abb3ccbeb8b90f3ad7378ee97b143de9f81b99afa93b596f58b32e99755d6aad4abc8e19f432263200fadd5fc5825c001cf618db5e883bd8912cff807dc9b133659a44cc9410a17ec68e090dbc0905d640ca13f0b1338fd903b6fad61159e93a0b46a5fe1484aa0033d7b5f44b00ae5bb08f62c1bc0b0ef750b61b814874ab100fd212d1418725cea098b0e4fd5d507c81d4fca9e250466cc811f6e5104c96b13f1facb1f1c4819691e45e52128aec9e942db6253eb0748eb7dccc2ea91f729f1ec4c1a9dc4368075893edc31047b317a92086c9bc293d0930e3ca4ea9b9e06653bfaa9c82517fa8aef8523473bb3cd61167bcc92dc6ff86242be8667ea14c723a2d7ae62d45c1843cf35c745d26b51c02ceb6c64f601451071bc3cce36d3f99c721ff42349e68110282b76904a021253591f9d2246f110c505024568e396694489a0c67dea32611c07da520a71d38e884836e1c75c169271c3ae0a84b0e1d70d005a7ce38e9c8812e8e74e26c0727ba70a68b435d38d881932e1cebcaa1034e3a192a7c773f5a31df2213239d4856ced3deee222acaf2700d8f83c6330f0a7e4792b02dd2cbd8d9d44dae2f85f70ee2fb425c5d478a8ef11d811f6d0c860117fc70593416efee8ded101107bd1810579406893a801bc1affc0c7b772082f73827d01b1181e294b95212407be8d4535bf4627db8b9bc4f0393602d365bc68185f1b01315ce6ed93c096bac21a4cced5bc8eb23b054f4edb80edecab9df07fd9811134a541fbece8862e06f1eac50b2ea090e28aa750363a03197c971116bf58bc8015a676df1a4cabe13cb158364754231aeab5858b626b78cd0501de9d5f2728993a114230664a7a2c6dceb4ea8810274b26bdbc75bf02ad30424762187fef1d5649f1143d735f2845db0681522e3c7f34bf03249bbbed9b0394e6a7f397381bd9844a4456751d3187e02131f452e5b7ee02df48bc56dac29c98d58c480f66cf948558b1945ef334ece3e55b32d2c10053a265035acc222978398afe0e84ca04098889d020b0d33ce5260e992fe2c26a4140e2fe652f92d13b554e5b510042762819b1c2e41edb3c12fc330daa00451121a18c92e0cf773e1bc329f1c69adcf55ffbd257a4fd19616b38574f354ab9db08948dc8771b8047427018d33177d7881ded4f12ab9e35543ea1baae29a9ff9001d3e79f87b0bb4f21d1b8ac7cf02244fedb5c8c0be9d4a0cc9184504c0121f41421fb20f240a1d6d68c8f844ba6d8c601e183c0ba4b8c6a616968c1587c64b34b0c4c7930bcb2c18fc8a07e5efa6d8f8b710273237cb3feb254ce1d00d94118c1b6609d62eb603a85faa46e8420fc2ffe135eb186b72f2d293f466febda5a2ae62abd3d6d77088fc5c9b7ce4d64b4b41de4813172d730a7510cb40e5872832e01d24c283a0defe8c111eb67285451347172a5851e93763c9768cd53377e9e2d0964090d0e42a9e8d3b633ec7aa35b75935925b017f12a2d1d85a092d1c8dc101beb3c89fe3ad4da448b1f375d7e8b13820342ad0617b28a2354ddb40877ab025063599360e0fd60f2ec6de65826dee30a8da5d171e493e66e44f6df6c299cd460408128e85ad007050bcae54bebdf8e17aa0b615fd54d2ad649ac99dd177479c50aa104a802e3027d9108feee31d69b442caa400b42dada68aa1e1fd482771bf1e1dda31cf535aef00cdf9bfa9386b3ce88b68e40e2cf33e9e1dfc95f1843d4957c1f4f1c965479a15434371f5fae75b9cc54566c1dad540035988700cf4516f297b8b5bd052b7d8db348b22386826bcd84457e21313057f208450b93804a1cef661037bb79096b4c3c4420ac586a8e758643268c68b10f66e3ff654e33c848a22097fac60b42ef99143d5064edc303f8afc8a02b80f6a451e1989053e6424ec8660888e752da425af366c732c260388cdc943065a961b2f4d1243906206646d0df7bbca4c84d5cd7286ee0632e1ef76a9e65267bc51178ad92f71e28ba613733fcaefb3005bff4c1382766ef78b56baaceebf2b5c0097510c88074d25212e7de4ea106dc9fb4478fa755f7dd7155e3ba1c11206472a015beffa8b18bddebee45306b7801af04231ff1d5de25a53b61181883f8673db89c23048a6776c63805efc467e31cd4c4f3c8d2184d30eda2ae1a064eace0006d8b13c66963ebd1f7ed64c93981d38a36c1855014629eb0b88995febe15856aaa2096b11813983523513c261d170192e576a3ec78e8a3296c1803e9f01e24742d99e53734693f2116c2ccbc58f572caa48584f06a335e2c627128cfff2e33121493236b3b9c331d2f82560d0800d498428a3199cfcaf1ad151a336afd730585ea0b60a208db198d0e580040b6039619309c88590da1e22f16b4cec1b378e37643f6f18d64e023616a58adc95c33035ff1709a982d8d28c7ac6b9162c9111a40d7eb0dc7d8c39a087c97a6d607f3caa7edc8b82b769997e21a0e20cc85ba589428f821aba4422846197e20f269d0a0912bc098b3018831197a70e3e510e8906450e9369f5509a9529c3228c73d2b06f8bdc38f899725681307f82bff0fa0f1361f93b43dedb32892ed335c342bb57c520d6c6d060dd399197bb5542097f873f245944e7bcace86cd86cf3ccc798583f18cc7119a099302c9a32c9f15bd7f32070a9da193d92a15a7ffd8865727d2cb37b52849bf84702c7102708757689f4a92935b0619c68216986925df826d7a397de6b86b37e117f4aa6a25ed862ab57f34fcd7a49b266ca724eb736bc050b54606b8711a22ab70a01134cd723534c7324a86f82e818f45a7507780366d2c40ba030c04482cfc1dd7c5e54cafa2a6d2ee04d2c20cf6d24d9c59163bebc21ba58e0ab479363e32a5b3be3e5ec59b4dadf0e02d9d8547a65c7862e33149d6a20d96289acf048e848a732d32dc038fb1f5679f54d95952fafc84b775088e2e2bc7c123696290a7a604bb02956c09a697a0c1623b15f874be73763622ea210c5b462ea4c8b80e913878992bd5b7fd9ac386c6e3f35bcbd13fb1a80d773244e7ea50004762fe67e7d899a98da708a473b367c79be95817e520b2652ffea329fa8a61d66c2a45b9dde648ebd9cf638fcd85132071fcb47a167c3740049c85b49532421573f6a79280a719ee9e187448babe9ac30c9eab9889609dacb58add92d702a363750d9a3ac3294de1963d56434eb026eb5bbb60a4e4d01e3443bec6dd02ae66dc209512264c811caaba55d47f55dc6710088094a6bd9dd450fb4b3a452992c1c570ecc693a8817d904d6b9a15cf7e2ee62d98475a8fa8ae17ac9f2dbfdbeaf494c7eedc7e9b7124aaf2604b83ce124a03d88500adcaacd69f533135270164837b579693edccf881822128041969212f9a4f4708adec033865c2421e343d3960fa471246d253e633eab10460a7285f30c0d3bb4d6fbc7765fb379a9ccf1ef0bbb460770d206627ac59369589b4117eaaad67070aa607409776c05073040e482f44cbb125ddb6185a4b5a5a25268a6d20ee754ae8234a180ab6b1e0d2dfafc17f15059af347baa464c568cc44f3578cb251f92a3a50c68437aceee434a1ed5accc22b86a8655cbccf2b32d77c92f251f607ccd520ec9f0da5b8286d0c1b967b587c05be80c17bb161f2f60653f5ef27bd667f5098080ec553850eef6c77be8368c489432c0e0c954c2367fe1021bf9d170339461d7307c61d37b79384413f398e247a956401b3534b821eeb574ae886a4e66a94156b0872bc2e0820c0ec43ab43ea0c786f5e5023323fcd46fc049e914834d1c0aaadf702ca544a07834dc8198c5e283bf99637b6ccaa77dde5adc8d96d178957c8536ef3e9fa4d3ca3bc69161000f2833334a4c2c905d0116d665b9355580aab51958d7de6c55acd4bc30cf28cd60737ff7b7a053d70227208c109bdc609a6c8b08afaa5184b5bdb40a4fba0ef962848162b5a2e0068a9e15a427f4ea2064c83991bf29766f5782ca7b4d19d55ddf981e4b729d5df50dd664eb660e146f2be0be476038120e2ea45ce0267a53f666e897ff54af84d921e1ede6a8581f19757344f0e0c085afab7aa1122470c69192614eeef42e3b8a35ddd0dca40c19143170d5fc008d76323af7930a91d51b0a961e355a55bf8122bec63ea0c051561d0f4d585759a1ce3e618f80878169ffd05411bdeb318ee5cb1811afec9da8ad57a349f982639eeab87774c6d3fbf170270bcdf20e44a1a2d7fc784061f9d7f252f7d3df8f64c91717d7be8f2e9911c1ce10d53de5e9b9e23801a68b674793505008b0cc0bc3453145c65fea0de59897ea5f93b7dff98043f80e7842c9e0ab6132d89fd862733040526e7dbc1658857bf248b97f9a03a3a788b9d43aeb76ac49508b331d4115a1e91dd230b8eca25fb5412d432dd292d1f35d81325dac07a3820621376bac23660307ad6e7101600e1ab14319c55071dd18647f608bc3697119fa619207d6d6a52e75a03a73f69d31acde0591b4068a0b8f092b9bb5637c136ac406342e2025439e09a69d0a94d8b4d8b0d9445805657b160f3f03b8b9a40663c6109a6f222ae546436b4410f624fe80176bb360f3ab808051aabbfb38ce675ac0ec91623951d393fea00455633d4a3dffb806a7e9805fa90fab6d61eb704bf7e6689ef3ba08a1dc9944a18750530238e7546814172a651d2c7a8ce4ddbbc11b3e306db0dd5a8bf8bbf319fa7ae7989703af41086912dafd411762fb9f6e8deaacb777810d64437f28284ae6622b5b518035da643aa481e5c7e6866a976cc16831ee6ad65c87d3d3c595531ff8b3c2545c4228b0091a07b158f675b8622f9647d073b90ba01db36668a452816e63d5077b342c5c5dcf4d4875074bdd96f8e513d6d7b85bca5e0b21212f1ecfe906fbbe83b52e032d6baaae60322c0988a7f2366529416edcc5abd2a3d8c2ceb1bf13ac6bdc49717d6ec28d93921a2359437564699142d87f3a88457b015fc491bf1647b38227a5d4e1427150e9311ed993444838d7d354c3d38ea8e525c18b09db2d4860a2a4064d94b8e46812a5e8e8b75a07b25ee363e56e82855edd322191c5d81caf72c4b103bac8e5fe139c55d84326608d2b5c2b6e3327250976efedaa8b4af3f479f1c7ef7bbb0b63f00ffb7178f29c0c4164b854cca55fff60bed7fb4dedf55315533667cd847a2577d1fd9fffbc60e76f1d125ed64f22358363068dd9fab4d3ea33b8f04da26a1206e505d48af645dc3b217abcd6f8f54961c6d7909fa3182cb14ef493a0840c90c9e05800d2f559c41b15435e44d85e41008b439d9165f14cfdc8036409a3723c9524421ae23969ae0bc619a188723808311ddc783ce8381f8a6b6a957b396cddeac23ad157797ba4c995e7570c93bf5ff160ab16ac25686072f2cee14d1a40a0cd870788dbd743e44d076730b10308104639459938622ac73e243fc6442eee0973d6bde04014963ec4180e9800248d7b9bc3d378040bcd90dc9e2f581fa0299281431037bd06e45fe0f094e744b314122bd8b63c74ed3def6b531884a6475c09cba3f84c27edaa883d47b1a8b3f0f8900fb4039ad8050c12a2f79d6a600df11ce34e4b8597c49c19b8d245d5570a3d89d1d98700819e7980d2771c4ed7c9d74d7c8512db42b557d82a9fd703297c85817edc3470a69e95ebf9e6be950e2669d9f01610807ca590496fd0370c761d5c3e9fa21a378dbe099e22f382e779a0e51fc089d75dc2f92ebe3735ad1b05d9843f160ae42a3548ae15f5eca457b0e659f90177f503cb81cc1e01466d6764ccf636cd181980a68faf99b2337dbf2a0c6d53d535b6dbbcbf8be549410bc41cbdad89381b64ee3e8f9ad8257a17391a9a476857e94b3029bd2d80062d4df106dfc6e2537f131176ac6ac305c686af0d97575fffdf0525eb5af4bd46f7a06289666ff6d02048ecd4c353167f1d2f767f0e739d1254c116e5f739520e6c133c53543658a3ca292ce8d521b0c37552f75e5c711a4d4bd000318244a69f1b8c8bc5ca5b67deaa9a6c0e14b1db2cd017c3e90665f54b6d9a8c03e7737126329ffb166ca31109f4e1e319ea16b657362c9950755d31d7084d2010b1ed007c9d3e3679b8088b2e11a868cdcee8e4fc721a559f1f6032a07a8165fd874604a3227821e0853d21f0104edd08a5eb180e4a20fe2985ced1ce5185c6d3c4ea0918af677868645d7915a4b0453e9c10bdf65cddae20be1bd9e1f94d95b666d901594025211f2a0acb063032dea0a04ecd50df10a945ce846a19e5c954b82952f70b78c9e0ba3a2d096a7dc9124a8dc1b738976b09c710ba65f505429e521d2bc813c865215782506ba51072321b1aeb02f083ceec455005e94439809c4c440540efea96261d8ee18028df768e51da208904ceb547fbda1f91b5cdb85295d5fe15877302fe6077fa477c29193ec397ebd9880dff58ec82c5a086c484c6eb72f7a9ba25e3b7b16324c1fb202a3ee4de1308417d79cb20ca1b4140a601dd246900e4c8c07c57808d2a8567b2ada679827c24099ce9085e0637de75503d7476e2964b2e2841e26c9fd35bdf1a5124b4d139e298fff7bc26d74e882c2fb3d203346f2bbc69a86c2a481cc0b1dc4da4d99ceb3adaf68af0b57c70fc2e4af2bb2e54c7c52633711c7d57a9f2ac4121ccf6e95827c963bc0ac54ca73c0fb1289412283ddd2b78916eedcd89771084f11c229064144cfbee5088f3195fd3c4e1610b2aa99812893228c3ce4a1e8d25d1726e5664481f8dfba85ad3985b67b03cb41f46306a46971553c1328cee96a4b395802be10346320214951e3f373c81e5147584803c0aae8b465f56a3a2a0580204fb9dc2fc02db5f1decd77b28e0c4fa269b8a7a01fc1e2c3a50d55ddb862502a4378a36271d4ed626a6506ae4582c8725b090e4cee8dbec1f19db2fe7852fbce2a917aaca6ebb30a2a22a10ba4f903c8135214f1d82734f5909500f7f52429f6d9f5052934aa08363ac2c7b5c5a2cb94b2cf43153e93f41ec61cefd3f38c832f5ed0a70d7d17f541d84f7de8fee5da71b1872e1209498f13812a3d086b970bb406f8e313f4fcba513875c43138ac24298ebb55e0d466277ebca71ed0bc8f0ab857021b8aef3233f0d3abdedba33e65ff2d822d9966cf3132f11056d4ad94f66281edacd79aa255448f7189db57bbc9eea28e235dc3197fd3635fe30f91347425dceb29f38a405a1d52342ee647e3ad9133d2caa5d71e70764569085933486b3c3efb20587a508f449c2fe9b012da6b2d02109fb4f063ac49b88c609534eef20803c3b7ecf4e484f28bf3b994b86effd1e8de8031e21f36012d3bab71af740f9d3b2639a910b10815ce767613c1e5bfb7484f53bf4fb1e3c00539bd8991a61848ab45b3bc104509598e4d1c13075d8fc8bf4091e195dc18d8102c2688ee833eeb2352ee98fa2a683f011ab7b3f4790f1c70a6f51cad06c4a7ede8007c9f90413c8189d2cc95c449bd45f78832f992851580f8303b53e53558d849001c64522dfbdabf06285feb955e96e1bbbe410a22d842b6780ee436f10b012876688d4d6d5edede6bd3dbaf608ff8a3e4f64df9126237d26bf41935ce30fd7354a904d9c215993d6600d3abcd618c48e04a16e6cc73f14a986c1760df2fc244f6e5d6c225464e36b0f40057c8d86fbf4ec7e5bdfbcae456eafc426785eba8269e58b80eb2952f989c3305065d93906542347783666b83130758040df5ebd6d4c4cdeb316521ff514cdb4cf8a983cfc44d76f402f58d66c9aff8e7e47b77eb986951402303b70e80972d0ae2abe3f29a8a3c5f9809bd133c1f397039dd5b731bec64d5c26605dbbd3f3f781b2fc9702baf2bbd6470ac796533b99bd5a7e9e69b2187a3d6abd8b015b6f620c1ffe7fa5ef9a609cbc3deac1b33d4a6c0e5622c37c75899b1693a997db7245e3f1b5c109728c1e3dc309fce937fef442b9c7184290fced4944dd382ace819f561bd30366358426c1a45b122703be504ae6edb046b68027beb6e57d42d086df6cce1948a862e5cf60107e0f390f1ad57eff9ccb468c0a91cb6572c57a5687e12dee6ef9db98b32f0f73b5fd9c2188eeb1395a6f150c2f31dd25caadf8b083d87d607eab873f2a58f0f4624e365db6d32a474a924774c70aa4b20fbbe6f1339f18c49a8b3f09cde00a838991cc2eb2600c4c1961f80da110a5cfcf4dd9895412d05b21b23604c59ff51386c32224be557ed556b2aea2bfbb538ef76427bd6279f0284dbab9af7386f16ff47be6002fa98cdb84a7561e8c9b770f4bbc01637f9226ca1aa2a1d697397ba5bd66f0a678f1be8d2a8f401778033806b6035cd292b4caec3e3fc43fb3846993d1e77cd3989e825b4f23651667c7504ba0c60644f2652a8db08019d162b178d028bea10c137b8b8ec4a6245a07a26518107e5ceb1a73c94ca3ba5a96c3d34f30c2656cc47e550f1012c2c86b363d74e0e82cd04d44628c4ccac717a4e6a2c05d462a0a3b79944425c92e7e2992ab58d7955e3930dc976a74992812553c1654ea2045a573a4124992236b18087c5832902ba094234efbebc50e9475d3f6c14722f06bf7aa3c8b363d31768ac73953705e6b4ff44713f147291b8a85acebbd84102a1ff619c2da2d2d526aa52fa1a41490dbe134a97fc113c078fd378491730727840e44022d22e715f5f3018580f5e54c9d0a6ec9e0f94fd42c03b1fb5a199a8124305e7656fa2f969c810c65068f3c76c8b369b746f1825b08f277fa779ad055bd5712ca870b906412bb8032dbebf76a9854e54880c7b95003acd43999c60f9cdc7ddb2e60dedb38f07230ec27590c730df33618ac0d28a4012188091cc43f87bdd9e8dfa21610d51012455e235a4760bf94c4d096599096b93f2e0d428c117a3d73306b6034825d084a4c3d1dd625f881d191c2ca327d7c4b4405924659cadb7dc18700d8647c0d3ac241c9b22c094c8d9be099cd56f8cffd42455b87ba6a3de492b4f0f320c90ba88270b08854aa8a9e16f67cc86ac475648a22bdbc6ee90031f512093bbae46c53e8de88d974912add9ee73aa619c100cb96aae6dda1947074b1bdf3eb392e67fbaa6d674729d24868f423b3c337df0468a92255310fbfcdc225f3fe826fe6c39f0c3570dc4800caccf2c42378031d2707545fce0df147bf1f577746bca5fa0704d3e814b2c49831ad5c744ffe904f07cb82ab7f2e0a722b4afb6a1a2bfbb3537e5c2a363520723e1011b73a16fd7782e1d1bcad90e3f874e2a08457d0bcec40a0777593c078293b90411b368670d637f530a3758eb0635b4703bd0eca6f3f08e6f709928610a6669775f188f85cf9749d824990951d5d7ebb86548eaaaeb3d8dfb6472a0a7063e876c9c9689798ecbe36622f0a5f7fca09a2295a5a1e4e6fd128d478a890dd536fee0fc448863bf9f54868b6935f3ddf0ac5d7f18e88756c623d6dffd12aa95205f2b5143f7975efa32a3a3b99bd78600fe9e28296b79c25afc2b49e439c270303a446239f34f1b39adb6c0500afeb5d86aae24d45a319f969fb8e4da2f032e76a1af6091c88e41a8eff3f3c0e1223128bff1c9f0b5ba54df4d66685096f201b3cff91a5295e6fba04f2783e60315d44a06021ef15d4b593a5b1eebe7245e6d34c4c87a35774f2212f00285273455f1cba8737ea894898b75a5d8831a7ccb987ea3e30306ff9632450bd5f95bfc3eaf30f2293043feebf169b9edd103332a85c6fc782d3f0f53a9cc0d0b7d48055458ddf36833bdc968b3fa071252d4087a38f06ab25ad305cf193581aba348a9e120c001f25ac6a463a943a0812923e8fa1852240d4104c27b87ceae373a1c39dc3bff25621297caddc06397148084e080262e04035b81102c40cddf0c00458a444a4f134e86da6b10c4afc372b57061d7dd93019e2a78871be61067941a49ac8f5b7be5a061c793188ce5958d2f3478a2d99f0f70308681fdd98f982835ef4ea54c880650e0f7b4659ce458f884678ee2cedd273565f499ea4675b37babc6a30b1b75018e7ba7b2947604ae878cb059ed6bf04cbe9a73b977587bf0094cf9a46db6a56429a917a361886d45a24e3f27d318d0fabe436623c122eb9e1f62d670e61162d24444e7b1ea2184dadfcae40fea67fc824359d726fae7e4e84484dc6b9848fb0b285111601499aa698da2699250127b176226a791e5980ade1d4007ef4aa5738763fb78d86a38f918943d867dbbe4de99017032900b75c2a64f5fe5523bb7fa5c52f56378b69c67b431e3db21298ce428737fcb31911c5011d154ae862f24eb32d4e23ba00c6c714b1270e8c293727a1ba9063483fcddf09a7dc8aa2cefd4dbd1ee22aac7e7e4822b54c7f0f522e9280aef3c0280f7235e646a2fb644a43070855ed70ccc2f356e89e26f2b332a4d9cebc2fdb57840354e33904a0ac25a47bfb0ed5e2fb7e571bbc2a3cf539acd4dc0a956ed3561c2994c1a53943e387c18eada9520c302caf967a30447250e1384ba1da52b11b70c45c58fa85f37101321c03ae325f43e5948dc815d37946b67d0e86e1f249a20870af0b8ebfde632bfc39f391c04dcafb10baddbf2221170990322b628ca84d1c293ff4b9c9b10b386a2d522e81f51d7d9cd0fb0b34ac35b4b87b7291562e77e7521f689e16d6b46e0df8918a8ffe21745f9a1d6423755c8398a591e9594e55a82839718d8a39f169dc19ae8149fdd852b6ea0c3d4b666f55296e11328661e76a1041c2989c0e6252fe5eeb0e03574f867f078d5e30760f2acce3df26c40b75e7525d0e86f82a25a637b1316245d02bdc7d01e6e4a18c81ce678c6bd1a4afcffe9f7aa001886b218e4b9e0fbc6c5e41a983a6ac4649bf3e15ec0dd539399875de9106af0984566ab780a9b674e56ce41c747893aa127e01e4da7301c56dd6fe284a1b7652c49230a6b2d2c5e4d12d06df661e9090bdb07b9d492c338b0f0b45c9a02c32cbe7c44d9a464ccc8625032e2de989163d1e292c6d0c3c49f71aa1def0aaac15219d43001eb3faab9eff34c21cc0fd6367584631fb6073c8d4e3ac6eba91a601f9273cabc7b8f6a922197b8b2596cf5d41daa736c2bf5f0830ce7027ae050f0d48252230887f0a5d9cd3837a2bf8cb042b101e8837cb098ea289a8b8c0a96bdbaf3e4621c1e44d43498bde1cfde77002cea36ae67035ea139e1fb7cf324c323d0a0c5ac7c9cac54cdc34c89644cef2c34d1a685f6949bcf3b11847dbd8403ff935f0f41a2f7119305cbe37342f3a1c32e92b18fe1f41c8b095615f6c12c5ab535001514fd6357fef81bb236f1430a07445b9dc19f0d0b4da4a90acae6644daeec81e189d3bd407edf5fe5b037e46bfb8e5a36d110a2bff2100901f5bbc7b2f7041cfd809803b006bba7fc5527ced5d640419135f285b2b460be986c702b99cd2a7838f41465cc08181044222b5e44d1e22ff94c0790407bb7ea3fa7204cf522a7214706629f38a6da3ce99135a5b56ee32146098662f480de750974c94e7d5ad9c290bf876a286757f8492a5da9122a1c11430a58eac8169c4d39040f45cb32b2a9d806605ac564d8c9bc7afc7e51681a3107d774789939d66ce254413cdc700338505595b8034ee72d59c29020032d601f38eda2b0bf1547498b9595cca8e8dad09ccf9cc576268dd3d88a11f2d4553750912637754d6bf7891fc126aac068262ae20863defe9f59a430a2d79d39d9cd6c9696be8524898e6bda0c49a8ad60ddb709a3926209186693dc0ef0e2f94ec8d144a323ec704cb4e1a69ac5f781c9aafdf318a17d2f4ed1acf7499e6e62b6ff28f70c3ec1d0ea63f914be60365065a813f30fe2b5ac8c9432be30f722c9c47ec6a0afd755aef4f85f7d3a6275a6c49db304fb730676e51fe458f677a6e6718706c225b34018afd1ac878e0f4128a3280de22961af4e53308b6fcb1435db2df3e57a56bf1452fceed46e1e58f9951770814bcb79eadf3623bcc8050759ef922a9e491b2aa0faf9dcf1b8ec02cf8d78fd2e3870776551bd89d8bb1493cfc74eed3ffb70f3345e82372427a54901119e4942e436c78170f02482aba7d16c85ca7c29ee76d4d82b622656330d6451a45f8daa12f1f19042140074ae480f15c7b4ec2247df0ebc3414c2d749b0df40751c5c59674d5449ac435165a39bfc144aab64f9723dcf1b73c6425d93d31c5fe8def18f6b4d93e5292ab12938f5b5ae80fb054e62675ca45f69378621b6b889383fc9855e234cf81d3990b85c07e09e7f5567c81ceece66fb39a68ab86e30900d7fc4c8de87d133a3e2f09c9bf342e302dcc26d90642f11474ae380cc4f4420f1216726de3b1a2fa5b814e41621e79f61594d5b970769b8169e825ffd33f338ee1c0755c8f1aa88723aeaa14f07c9bc484cfae924e0976a4fbd0e0fa31ac248cd24f6e4bf0d903dc72e6d435971f3f348a9d79ade158c17eaaf626f946be9bcee8fd30c263ecd4be5cbd5767f87abd32b9dc8e3f1a2d2766a0c54566e60108c3cf4f3294671640f1679986b4be3680e101b4c01a9803f4796233986f3fbcb459720b166cc6a08a71615176481499b231f65864a55a4d3d7a6c332134b8a13bde01d31cec9828da817823b8e6e0791c7d5abf7ab1f08bd596ddc3d9151e094b7797e1cbbe1fe4b195ae957fa83586ef3e93a5a8442075a25aa8e1d04bebd80615c5fdfca99ac9efd0b08db9ac92c0c00a8c811d6f5446546309fc7f6f01099ce24a341cc8e2ab3312ecfdfe9bb3c95d924288cb130d3f7ee0473c4c47a2b43b6aec625e78615ea6e817d41a91d65b54b4c0070ab312ec326a838c2f99fe93562c641d09475e7039f4a807995bbe8b129b5f4acb340ee74d4c6a38b944ac8234bfb67fef3985db1ac967c02530b0740d654bb47a6c316193aa8c0117420da4e6c9a82366d982c729cfe450cedb6831490ced7066b27ff53595feccdacac6bff1c45a59c463eed08938797083a62ff58eb80c4a5b9437003a3ca039151e7ac7294cb2c8b0a9bbb42a82fab7dd892cf65f91dbb9c32ce3a4c0f810f6c768fd55829b7069fbdc95abb75036ad8f33faf29b50133a688caeada9d5d3b3a2fe012ad898ec222dfb73a6a504c3d54880fc934eb668c1c5c4f1171ddcb1eb039833c3788077a116a1550a3c7df7b0624509df4f62b008f42716134b58e432007717cd7ce7369a4db881aa348ad5a1322213226935a3e89e5ae7d20f38e2ccf108b1485a84f4822646990b206eea1dbbe711c8e5edd3fd3b0761a4c8762cbb5f6c20e03a5af6e006698845bb7153a23e8394d17b695e6c91be652721db59ba1ab0b9aa79872016f0250815823f6db195161756e62d8f050284a71a04f7f15413c8062407b2813bece3214819e2bd1d72f500ad3e35801a402e31affa1afaa3ec78b18ea6ceb6db6b8c6aad8116c79d0d271bf9ba215e43a13ddce12123d7da434f236783c11ca95d9474d59947ad6a1dcdb2d911a442e5ca35f9c7e9a49528a5fb86524940f79194f3f769bda78019de284f7570f1a89a0e98866820834b00925ee55006109ac7fa2cb9149211b922b5e21fbbd723a2e0de1f641ed401b01bf1f3bf272c147448605d05205ae4e1ce0c998283a4e7892968a54e17580da67e2490631b75a6c7c944a5f1816bcdfdee1fd5491826edd020675a2ecd867f29f5af04330b5abac3cb36d7ac2b3742650570829fae19f642b11705142400be19e3ed85d13ce3d84f84b4ae6dafbbb959eb0e8fc6027b095849159555dcb7c3fe622ee66a977785c8026811ca378a3439864682400847231bcd2ba361c3d056d89833a4151c0b5e06a4559b9f345710b6e80eb4c2dcca5e5acfad111a0020b549a32698d7a98229cea96516ff0460a35f5bd7318c39489ddf04437c3da4502ac3c267a1ce8443de6ed2773e28d512c77b4aaccf0d81c3395c0faa70f4d2393b33b5ec4ce755defa353996850442536e969c50ed4a1fb624a3263c4712142ce426526e6f961f202dff88d608cb1db9aadd757430aa7b8fa6ee1b38f50615b61142340f229f942642b0c290a766e15787cc52601436ab2b1c46db7b5613c7687417a2d02f95490f34c400b9232a2be9cdc82d7175013838c316924b0477fdabdf8b8317cdfe879ec5744fc2bfe01d1794ca04880cd884ebc7d8bd4da5efdca46086f5938d1672f8a965d696490214f625f08f7602997c6b31c1100c11db0f06520525d33b39a0795beea0a5a997648c08ecffc3458657c6c152871f6494bc2e8e207737b02c15a6e600ed31e344fcc142a38c284e616e7b4573903766c2db281e101980b5ccf693a6488102db6fed34c768902659754945069cdd3f817ad25c90216f602a23a788d7b2c8a60369f4fe6c8b0e4192b75768b910099dbdb21a64b441d559a4912c0456e2071fc6eed0862a71826b15f9de5cd38275e3f88a2afebbf18be605bc0b804a3d88187a56099c7c7a932d2106e63b664fdcb603b20b6603c2f5c4c0caaa4f31ff87c346eb149bcbaff06bb9a66939a5dea02f18aa9e35d8308d9bcea8b24054fc621618230b2a066b0673614e60024f813124cc10220712deedd76c102552e98924513d1acdffd11a27230342581c86b16b874ddecca9451e09da6fc10c82d1daddcc1937cb86d1a200a5856ebf796e209ef0c4ede08dac8f8fc52a1ced7afa853843753aac5d45ab2a94fb265f2ad5f0d0dc1ff452b51b7f9d41e8405c20900e299b5115ca84236552119c860a047706c3daf6d88a185db8565ddbf2a8f4b9c5dae30970d413dfcb8eb56da800c9325a1a4dac0d9c6204a55d1f8c1cd285d30bca7f62e4d796b281d2703d98a080efd2950ef483490778b6361c3189d101cba264509ee456e5f2008255977fe506181f57cdd565a277236b3161c30d3b3ce5239fbd2bb201d1a4b51e8a285dab55e11284c192e66640a0dbdbb6d0e386401485eb7f5402acfa352d1e189650c44d4163e0de741b9ce0fe3e50929208fb8cb1c8ad6ac9c84eaadbe4fc85f336b680d8b4672510db360d897ec12dd289339f098bf2c185f4a4a27d16a711e16f27c577dc05539fd6ed85e1e774d8a3c4dbfea4547c83479056520b2dc24dedf643b3195183e00c122029cf09268bf9453d5cdf527e71893d32884adccbce957bcd9640bdf86d715cdd5e74cea529e83787730ea6a6dabccc75e6309a57049ccae63f725ec57161d262ad01b1fbb408db6b4a9189b0ed64c374c2953e5dadab14dc256df146fee23aa1c8c818833f018950f5103d2493a731e642b2e7cf9157c4e62da460448df35f0f26afd61947b182a42882c8aa4c400203426302b943a74e776c3a8c5fcc0357a94608a97a835b762775b5f67ded67cb1234562d20dce64b7904026739b91a64655848c3e8ac34876fa10278b79189fd668a58cba7b804a911b011be831ac3eccefb144987a1e609f75c27c2f83b4c3ed7835921150abc885a5079c7b16bc0641111832dbaa09e1484106a93b1e1b81d58daea37928016de792fe20f7a4c7b3c9a8474cdcb2c63592e20e1b3df3cefb7a5543b85c294de1520d920d795d6bd444ff6509c2f2bcb7103567136688992eb39861956ca1e033d18ed0a0d978c760fccf722098a8bfa9e8d3186123f8e41dffb4cf700c33ac53f954369571abda491f2985dab1c704b5a6ada56723832e0348b71006aa136af004e22e5140d1035517a05d1c4e89696d18980cc061cd2cd52b400dd1c1acf23f197ec354e26c3b8e1c664fed7481b35e827e93f8014047414b2c39a58a7abe2586b5c0efaf77b292066078278057175a448ec9c04ba7baa9ec3593879eda05f8802ef6ffaceba6d086d219c039fd39147483639d39481ec6178adb81a17140e21ace6cdc675fa1148af936fae852a32abb4548e47f2c5a65b3e680a86f527ddf43cd6534620f6a01ae9c86622ce469e98430a036b6eae9b5e9b21ec81c870789b7f5f038e7a5b795c5a17a705443f1404125a5e9b5f787aacc7ac5983f9ef3cb6f7306e51b6125b28eb034a4dcda79025d18c5363d9ac7f6421a8c086a1e3842038689e8456b056fca74131836455a1f1062927d1cd7d4eb8314ecaaec559f6a938f5a49573d6e8f8df130fbbd2bc76537e9cc0b5893ee01f3a4fa0651ae6780439c23911ecf7988d9dfe9e11ed57067a80a95a67de7beb1d863ca2c545392aec0f280fde9994bc19da953911fd351c1ec62b6469bc27897e371a493d45ad343c0b26db47d91f11ada2e83f43b6a066ebd09afc973a53af8e97b65658d5a903a48b6eb66190630b5ccbfba0653ebb8e442e253a70b37373c56d0cdf60e1e34005a27a16511711cde786062552ac4c8c9e0746211275f652f01ad0d49aea33708db1579d31f2208c34c4aa62b4d4c87ec53080ed41b0bbef2a2aa0013184a6c76bdc48a4d771cad0f6eee948acbcc66c900fbd45c239125c241128068cc49e47534c5e2fc13c9c8f5014b5ec05c8287cc8c96820921648c8389f49fafcfb3feb7eea30cb336ac8cde74746a32370b322daaa9648f3bcd5b71193647471580928ee9f4aef623d767d415a9e04e72832dbd5e1dc554c3c3edf2e357a5b870427df5937cc8c40d5870779d57af6010573773119af6ce3fbaf9f584deb56e0ccd1b032f81197f3e2b2074ff004152a9cbf5d48f55f8af4431f1771c61221e60f01efaa06284b8f48c19eda3b66d872fc61c20b8c50ad5e869bd19a724c46db0b9ff87b59f326b91689498b0439a9583eace2c65d15533a8b857e4b281c8ddaa999cc8309cb573bf830fe86def6328378b0853cb60400b94f66ccaac5db9c18b9dfa0af7da3c711e3dd27f91981b4aad7ec6df71d472a5adddd80b8ad816703d95e7a6bc56800772110a18ada37d320db75163ebc80bdcda7c541ad55c4140b33061ab72861654ddba1614adae42216869a6a8adc73c6b4d162a823b1c8ed818520d30a010da0bcf1e518a56ab1c7ad96a497d5d556aa064614fd5c2fe3bc568978753d33ff9184a39533d099c0a5bb76846692e2d3a7453a7d203df2a1e648dd63f64ec37e78a8b072cf80e742c5bfe6577ed941c6e1782ad5f52e1a2952bd98f0277d4b9161e8029eafba4563630332adaf2bec51bd43948df7c0e17796901130f6435d618a6c92c73dd17b032c0ef475c6eee063f5756b7346befe166124a524d4c7a9269dd5a8cdca8f26b1f595059d7f0dbdf728181b6c493f8a14ec97e487cea1ee6cd4323780767160893840f189051a60b51dec87e1690e44523acc2dcd4b7008f386d04929061d7591448327177d5807686af77a83f0131272d69a619efe823f18eec0d864fde2a08f13ec0900a82e20ce869ef06f1a60835aaf9cb225c9c40bc26cb375b88016d4c367b289adf648f64f6e4c909cebd16cbf66bb5c2ec87f76026c87539abd6dbac47a6c4054a39b4289ebdf1f8b818502d13b3eeefe075be0ccd01d2a96b186db80d79358c754b14ed1665f729607e6a429ea3e90d32289d2037a820e3fd10bf42838f551253d99f06e267dfa3210b379e74381128116fc8684b6fb9a0f5944c502a684147dfbe74f83407cd247e337ba131141095e54685a442f3a27ac67bcc32a79d87024b9bd6c739b464ca4e1b985fd088208798eb04bd852eaea0e3ae0c562191c1b86a2c386987b448105b498e64ada3903716836f17918509f24fa25d1f11674e0d4f53a391111058fe3041b958cc4a373c82b95e18a41ea9a7db0447c8bc12b917f575cf1aefedc5dc5207755cb76f56ced2a80da0e38bbc2c301c50855d8153fc4f145420eed62c7ca3366b142ba25e83e7f83083ac49bed7bb31db995b8171dc43a65f09020dede520bd5a7cd46738a8ae9ea4a39dbef6e7fa18d1a9f8a06d6eb1f613d290ae095f48fdb0cbb3127d8b9786dadcc0afcdf1f7912d7b40c36f4737c224b8dfd5f3633915975c0215b93be86a8493996109af3fa0ad71a1489c3c11aba2e86e240887c2019a259526c243f57e18d0d54ffe9c7e84fded5510b1e46b68df2e4f6680f16da790f9bc3f0bc13635e2e9c0c41cd71645e05d19bf0dba49079d7523563440be52fbe432354360f1a1d9085852dce8c67bff2d565f24f0a91d57b5d0fcbe40aa9398e78697217cb45f6963ded43d6086f621967ce6ee8c4659ca07801be648da271749027c332700c0e2560266f4ad94778041028247a8a11a0cb84e1e7f29a3153322b33efcffdf5573f8d7732d6c803c352318b3cf4d5dc8f1b716c4cfd23561a52fa15e26f0afe85407d105bf94926a3113ac997cbd266bf19c15d72a6b3418a0ade70e024d161871e04970fd7715d550607e35ecb6360eef5f597aeace6ef2508cdb9d7488d9a9e5e696aac1bc120773a8c6358a2e1d3459c6433042f7e5028acdcb89129eadc1581d3a2e2d3f84b154d5a3ee469f5dff2a6d158bd2143e55a61d0db50b1c870de5c3c34b19c3a380e28258fb48a08ccb458250e56b8d4897a014289ee36aeeea11eaaae6e9c2644d5050e86fac327412e6183cb45b904c4133b35c1273b35f52393ce28f83f3f522db290ba1b0f6f79d9ca8f5a4091dbc2e8c7e25be09a0be13b3e5d28dc3053fa2a8230b0f04fd155c106816b35ae2185014bcc10e0a990427f96bf1fe0477c6c47c481cb20e5e147ec7fab3c58e321aa8932b50df59fd2d0baae5400c9b527abe088fc55bf76eb4575ac4596c52f400359e65ded269f961b0442b1ab0c2ecce8d9ad079891cc0466c79ccc3c3a323592380cfcabe6de77868414d846e59aa99ea72500a8bee4d7e2249c06488beb8529983ccfa4b0f8d14a793cfc4dae4160397ec33fee08432d77f3d0e3f79717c17844f97047f5ab7cc2759d39753c818de64bc021464ae47a251ddf25430edd1cd9d2c33f3b56f814a8c34b13203743762b47cab28913096042cc25aac55ccd2d72ad3112163a026551e35c9130b5668d8be0f4b7b9aeff97706244746374c3bfa2e1add88ebfc1b8796a16b3b307e394d5d4e759bf1a80d30358c6095979bbb784ff6fafede4a02b03e373456bb16df0dc10406d86362c2525ef6c34fb0901a37c70a3b861b899ab495119d0269ecb04022824cf4f810a750b632032f9de5b02b35fd8c7a4372e1acf0e874f12a7d06c998415c1f15c39dd774e338df5185caff419977af6633188e26a92a01beb729ac90e8f010bed0a1fb65f45eb3d4ba264eca084501d9f41e401a63e51ccbaff324851b8d0a92c9285d7aff3e9775edee00325210e5214b8d4c02f4af13e50021210d6ace834200b4715405b2cf28bc95f495cfcdbb9566077134ea896fbba6a8c3000a59d7b830615b4a2ff9ef8f19bf59dd230c52184b52f466207111af8b2f87913fed05d11c5e19b28de3dd1aab06e13bd529122d0f14d68d5ce86dbada314b107b9bad8c2493c99ce3cd57e053094613f0e02b9ae4772612417e5e3fe08ebd32d089c019ddde7db78ae339014604e302fe742706eea5d83c92ce24b713893e7d91151a49d84f82e0066eb446ca003f5deec166eff1de11fc5cb8c25b2aa03e39b119444aaccfcd6be4191cf5bcafeb7075e863ac28f07c1e61aa4a7e3a0ba9787e9b7c1320507dae6581082e0357838953a9d9cba224b9eff5872a409ade803322e1943ce745f684afd858f5157833afdce8ce7038111ed46dd2a5c1d53f8c26e4010cd709d1ad18eba2c34bcdc6d065a77c1f2469f5977fbd3d3ae36aadfc51723be6cfa9a8f20e1231e43e6c81b843f61af73d6852d2f4d02bc4e9f0879db65470daba140cea661e432ef73fc21f5f4b071b6d2b1d36a03299a45e734a04c440c711be7c7dd6f7df4390a34026e9e2941641505ddb8544259b626dc90938759e969400e43298236ece48a955fb9cbfcbf3bade3473d154706cb331449576909252859c1071d965602823093d0ef83cbabb579c231d33a34bce7e92d94ef263889cd6cb69f9521c216b236d5184902533bfb39fcfdc2c64ec420ae07314be27bd6caa088aba191ba76dc96d8772e59b9cd8159b0b003dd152240182ce29b1c4cfaca71b3fc0391adf8a5185a92afb54c90699c413e5cc92a10b4ce11d3e6ea956fa1785dd7d5bd4d7728d0367787cecd6d0a9ecf1c79397652ba19e2baae4b131e98a037707e2faac581050231920964c6db98ca2279a5b14bd962ccce2d90614ee5d75b99076abb1b3a417716f9a9ceab28d31adddc2508d825823cee80c943040b8c1ecae6e95a6758a702f0182803a8614feec4ec2546792af032aabb222de65dfd83726097c392762aade4e6b64db9922f81a402eae0c4f8b59e987e4d1d045e3dac6f4d3241d7f02d8be3b4824f5552db334c1bc9ae54d8ea11293fdbb3eee5b6f63f9e33fe204a9a3ddd31772b8363e1397376bcd485620cbf09b0350d677fdb90c979c06c580c2ba2f4ea1f129b6953e1c4c5f3a282c12b4384a44ff071d99f9d7fdecc43e0961e7fe99a42fe31b330242ab502697bcad832e0e0775b2e50e956a8bcffacc599072f65b0e1f5d289908058c27040dc5af3bed701828f4aecb1091d0d0a662278fc0901182251d53c308476f2928c691d46d96d96c04fdb25e58387f51a2f5328e3690d80f6bb8215f5c7e74d875aaeca112e98bfb315cd5411c4cbf5d268b87dffdd719d93395602952de4067e2bf1ad63b17da8b77fbc41d6db21b80a39f91454fbaad73a073cbf1a596bf9d006cb312951115733909b208b6ef5dae64d45cac2d14374e86d56025a595140c8b229366811f66394882cc15cc220536caf306e19a23c2aa16726581f1023cd4b42c498a140e07717bda289e6c0c0aa98fc930ec983cb11f795248054107a1c4fa5b9f2e00c4d8fb3e3483a970bb39480792c0159baef24862be36efcfaf0c8ab49a98c1457f216a906e309dd2d069af524345c46241b7910a57b5832ca1b0f12185bc8515a800426ada554c9725723a8ed5d4db2311cc6d91c96516d208aa373ddd342aa09287fbdacf6db91cee6a256d602e8efde60718889dd4bc1fa391c7d10b61a9b669ec11ae3ce04edaa340d1362f7408b11d80e96a2aa1e3997e46ca0f6b80c2303e5277f9127065791f41e1608181c196152e8654a5925f20dc29db2888d44542f3d9224d2928d08558bcb64e5709111bdc8a90eb21b40bac841a6ecf4bab81deb800308348dcb0f7759014a8cbfdc2496d48008fc424cd53bd5c8bb12f00426d465efcc27017ff01117df933c307902c9b1f78ac7133cbfc7c90ce9d1091d866a23ef1c293f920e49527c054337e2e208528e01e728ca7e961c687fd0125585d2e73d4d2e5d7df3e2cff1ac45cd181e9d3c610bd5827df2933d396e8bc2699fe62a47df4b7b8d12250b1ce7fe9e18f73d271049457ade970ed5cc104cc57265f9ba434adb9a643c83b64fb8f972302312dd8745e27ddf13882c440e4f371a5a58d40521b3185e6f485017f08c9fbfe604300b98f65b91228614abaecba29946dc6457feb041529d534f673b204cc23b928d35d029deca04ced28f2a559ca7b17e35d4692baefc34c6a2e7450b25235f2ffac9aa0d9a22fc2b182431432129ff1b3a7e23050b3348e918802ac38cca7eb31db7707fc7123178fdf80a4e4a2470d26552120ebc1ba9d52639d0c0e199fc09153a85aa96dcc3da16d548c2485653793e6f0125448c48dc35bc76900583dcc12296a0f58fa2dc4c0905223011dd11bf62d1929604438a50a53b50ea7b6878cfbb4904d34584fd378e23156008079cececcba84ed657cd5eea3cff2898a0e69e69b8702f51c34faa1d97b9b4aa0bd7c636c4ce588dd62c9058ae58e63123a8e15674851e544530feef100d728dd92482a50128e893e8de94aa0741cf2f6c72f160ee97fddf9eee90103881ef6d452c9fdd371ac0de3c94a80762f6a48366be712a18167b548cd9c36ef02e8da62b5199b57618831c777b6e146ad30b88f05511a35c5eafc6991bbe70dd8f823acf858c6495c359908e0ef0297c9eabda5240028a5580dac2e10c0b866dcfa99d9c2a01d1083a6233c89b3972f3e6716b3d1dc8e05108129d15f96acc17d80a3f2db88f02393e45fa1469ea992cc18af2ab43acb03a9ef935e02cc8619586b5a61f3fceb0d65301a088ab351b5086b69a39b38c9a5f6cdf5b197df13bdbda154a38289bf7511ac7aa7938b659c04064e4f62b3cf0a18b4962f355f2c30ae04ecab0e883103f929eb7ad12c5c6accf38ad87e379e8c6bb267182ce99cb325c981906915edaa431a30d3f04239837da4d478f147e168efcd7567a10c19b65d99b3c0791bedb13c06bf503427f6cad44c6acbf1dbcf0f3f7ad2f0bf73c29e3f554c2c6c0d08339458b24ef50a50a75bbec178c7b122099c66c76da55f7bd385e0a9dbfdd5db8888c00f5e495c85bb7224477a30b529be5ea22315c87bb08dc4ba9e5aa6022775fad43c614ca8c9f221b132c48f0c0cb09b88aaf2a37e823c83b0763fb195dd33f8a3e882abf2ce06ffb7e0127dfef582cce50f8360c385ca924bfbdae1d37286c66616bc52a68d04d9255c5c581ec04d3a79d33d63ca75f834c065a08eab5c8b1306bab19ee1880947350fde58a8c6b1679b97f52d2010996abcfcf5c603e627936f15663113962829c71de5e981e2ed24c27d638e841c20bf50b505ae1ce6a143c264c6ad1c1ac0472e3a0628d90434210fe4e411013d02863c5d7b6ee606b56de43c817073d47cb7bad6fe623b027b380b449762a63bbc0572120720a7088f3e6d49e6f1fdfd3a7f3f8acebb07acd3dd8a7638720d9cc9e9cb6a5d6cec078f21452c31db6dcc89b9cc50a0e0c2f04f7e06438f96d92cd814a3e26c51e2cb3360cd1de21f366052350b26179e7c9c3760e56d4c36bd0d08e0a8bf68ddd3b0d810540ad4e01d06a0fbf08f9094edfd555806d24eeeb2445a45712b74da867b7cac839d5734b41e535dce74dd65b340fa12051af36a80d6649e6760577b8460eeb42d9ab0d6c1664da18c2f6950f4eeeee272a459e42e03815c8997ba9c44891a2adc01ce0d4c5d8781582d0abb4068f53b22a3d7db28ecd97db37cb3f65590b1772af6cc9bbc72893b7d1ee3a94eb2930ecb113cf02ec0ee2b92d85f244d9b31a8831a6c2316c60bd9aefbf168b121c3caa94aa3d94f4417137a16afa7faa85c522d34903eca1ecdc503f7acca8283b0a6b8c8a44d06dca87ef840ebbc4123294aa6247e8ff64051f27849d02856c5c5493e5a01213159d4040092e12bc5dee94c0f123b84838b8d4cce605a071abfd5918395bf426f100683b53b59cfb2d4cb86e722864a27130084e72f21a621877ca148c8dbb07d3bc3cc7e2fdd1c76a9585aac21350d127a13b344a771bf19e4cfb08d7d0adc1d9829375bb6e6373eb26d1af92be8832c49a1c83a2977fd1b85114b0892a826342122834645f258b13454e737286c688dc18a710f18c12210ccf05e012888ec00f76a6d5ac3424e328105cfbdf5ab2afceaab1f4824efd148dcb58026f7bfad7b818234f960fcfba985abfb0e2db7deab62b6576c718aa41cb03cab2968dc91b2449022b16c16e1f36465bbce9b248613134dd1e67de1dc2d88360a5a3790c247e63e801d4a2a7f7a241bb332005e90eeef3d027d85864ee15eecfdcf0f7b107befd584711c4825f2dc4ada607f46b0551669dd850855ec224127138a12e131ab93703829833ca3d93d60b3e188aede330ab6dcd7a024378002b3f537eda5184b4bb25076b66d5aaf594c520e2e183cdc8ee377781ed410d73a783ba98ee462dd9a652d44913594f781d0bc68d49825067e1142ec09c814178829267a07befe77950753410433ac311035675c49018d4aa64b45bf777f6f62d7202ce792ec3e81acd63dc14759e67cb9adc59979e6c1dd1c818a5bbb1aa5c598288e069849b140b27d27182585d9ee6dd350c4500bb4cf890b58f9bfef37aaf3778f217fc5b644983398d3f7ffd43bbceebd3915dc9cfb8720a304207471c7b0030d117ea0302a2df6170460661cdccc72794bd72e8472db9cbd597dc5826703921dbe5dd4f689c207e2137538adc719841ce21f9e0321304bf6dea11619b416c3870a0985d2e5ac356ca333a57efa1d8582e5abfff2807caf5dd562e2107d15d1dfd263dd538ac5431a9340de46870ca01f3dcb2e9c043091724f93171856ee2f75c17b721b5761da1c3ee1aa672d9a7289fa7596a72b70724c320060e5b71beefa6cdc76a9ac10d31dcda1621c9f226511cff4df3d63f61353d74b858ee675e7b98fcb72611bb35fa1f1f1703dd536daff38643b2bc1428d9345db9466e5806cc4a6b4f4182aa29109926fcc9b2d1297927c02b342852415c487c6c9880d4180d2aed04c879275e4d4c713544ba40b3fa87b55573d929a12ab77b05cc17404d939fe540a8130bde1c6fb41f585bbd9cff51df46ee66250591140287240e8d38d90ff4fc3ef1fd95a68ba72a7060e89f8373b97793cfe9d53df9c7e3090fb45e5a5ea6115e40dee700646287ae20146a87fb41a3ee8b0e62bc3d6b331dbcc967ad345f1a07cefe5878379c221c11e21f67a6d650f8ba1a99299dd0e12f73a514e9d9918f9feb905cbb204faed689fe9d9f1c6dac1e91af931810e4641209b35daa460b03e5c4b63b9af3cff40263cb5b6050cfd9d4d82e9e5cd103d19fbac85de75eed398223a73a2cdba173ca1997a397c43b0a0ac4e605fc60565d2fc78a8954208d9a22582bec279c3af916828e2ddd6441fd1707c387d6026a1d3d188ef2643c3a29e68ca04c0dcecb1189348e2679c7d9b9098868b076b2290e6ff451c575480b8c16ad2b9cf2727fa8969f7c497fd249aeaa81a4851ff87b0f4fe82633823ed69aa0f4aea506d869d0897ced1a38a222999508bcd8f15505e06340619c72f0d898070b2d948a284768642951a5fa1d733982b8f7cc102ffc39c20398b7cd2880dc53e90c3b1096aba5bacce28b763408f2b18304794cda8d4a703449ffb3fafd48a42faf9f69ea7ebec9403f083332fec20184374e95d766b810e6edc229f5da965123838d0b93b9a82ed4e2659ba7b4be71fa919ffee6f61b298f7da2058bedca854410cc869289896d6e018c6d5ae41a4e850a9ea016ebf589213e3daf07876b89cf5dd370d23b90ca5d3ec717760d39641297f339781f25213d375aa432bf9acf7177d499730d93b993adc97c8f4fc462780dc0c65199c7a18b47536398ce14b47d1103ea28f8a897ff1b736009050222a2d5d4bcf7192e35ae7947000085bd33637ec2503061e09b3634437de1d822c63db7af7323bde46df43b808ff79874a5cadb80e82ffcd23ff1c76ab2aea15149f097d7912f84f485d10618a4afae7a1ba13d33761f40358434a97d04a301805d9092c51f7c2c703c2b4050f564058018e5b489803c8e0bd6d75b46b3bbe287aca3b3606cd9dae24511c90af8031d30eb3a70a20bf70573d37c5519a28a419524c7846a6d0a7ed2b4029a843ff357c776f7a5a8157041ad7015a21d68a1a1e11bc42aa37523a7301143f8cb2f507b8116cb11e3a85298cdcee4a8bd803db3a3c3d6d9dc9f070cfb3346cbefc7546445c3656a8877971dcb72e534dd94292d85af69d4312b9a318909f6a930cf57935d780b9a5037db0299edd1247d7cbc1580872a424897e482d04636b0893122f45422994e4015a2f994303e82b0980b50f6c923892f665483b9af4f905e95014dc9319dada397cf473b166a030e128de7766de7c1f40d93ac347f9456514c030c02d002de987ccb042b2d509e03a3faa5a2f129251a9f355bd00aece6b456053887ec0376d732e97b40cb361b4d94838a0738090fd20b85990aff1f5d4df4900114c0e1e43e40055f0ff40d4049f1dd15be3b0be0cc026c6d2e2e70c5b08b56437a606f91dd1dadc5fb9cd822bc754415e8bef8a9011da65020cdaa2f0b8244795a50c0c5550f31a9b1225cf78b2759746de6e4effb5719d843af419fdda4dfd10d43449b3a80336ce552b812021de4cfba6b8690e693b889f82a7cd3388c83082acd51d44a3cf70f69152bcd8b0aeb8817cc10c698d2ca74a2b599e144058a4d5475a709c67744addd1d29ea412222678d577fd4b859ed6201bcfb9d10570e346fc175ee094f038b85fc0ac29fd4ef4cf1d8b5ecef8abdf29cecf08b371cf91d581bc40c0d32c7c7d76b231693763942620f12a91222e08fe6870c1e2c79bc3067c74e7b35a0fdf96604f0fb5152c608cae26371a6f2ff066a733dd626ae1b420026222c3a22cfc49754d413d96d1a51b1469aa2e23081a5e9bd116d94803e5b03eaaa0ec843840f5fda33592723eadfb1fc89cba827f63ec834d6f940ab7c458e0f3ddf71e529427b2aa4060e3806302c60aa638cab9b078a0e5f000e3c5ff9cd7f1894b56528b8f3d9c59935ba22a9bfa2011346da1c313dd56c846d62ba11ed35dd376dd9f4dea44428627c650e4bc7acd49ce4960d719954592c215c5f91947c85ce9a0f0dca196c9adc8d9111ccc1de1845a7340a0d4a9d341374a5c170d2e6c221c349a9d66ac54cd923812566431f9e8152c2edd0d63bb6c7336222010c7e40737fc34b49b945f7cd9d1493c273ae96b07e2d164f94fa4e458423afe2ff3f82bc1a21d6310d4dc51f7ea91d412bd941ca42d493c8036735da9841286937910f9cc3889115d1205cb868a03e030e2fa6ae78e2a1a11cbe0a4706b0f6c381c08889698e383effd424881110c58044aaf2e9061e9ca87f626f480fec4f04ea98d3b7572092b29a0e14f1df2691be54a7273f9211fff7b90beabd3a8013d7358a73bd18bda74ee743039f8124b5d668ca5a478d0a29a2450e2b0100ed6e3254b59e5757da31c28adc5ef9c198cdf3877423bbdb967b4b99924c01640bb50b620b344843322ca129aad048a1e50c2d4f5a9ca4a032b31eb090b024f54009e98824248efa91130f335b7ca05486d38c8da718698c92a90a21a54be9b2c10f4e4e5801033ab22c608e18a45839024b185dc8a257014687279cd8418a0f186278e1c11523a878830859740984cbdb2e6aa592d690f59206447031d425891d6aa0814cca99afc272e8d6a68b710ff8f630e6178bef1809bb4bcb64845f6d6485b4f71a953d4a8ea272610c49f0d51281d58d1d605fed3e7cc8c87ca8427d88fa50f5cd51d49520093f547f23ed48da59684fd2eee4840f8c9ebdbed857f610ddb489a0571afa0dcf9d04304a31d55fe5963480117af69a58e34835f4188e1a7a9e17866ed10bbb8a6c4a91292eb122d3e67016a73947b7b997da462c35fdd07c56d6aca63ed1533d8986c54f308cf998673082f27bfdf7c98fa58f606c92a13e8122d7983dbb07238ade43b8960833ad1076f6a589c397a5249eb58ef87ed2292eb9968084868a8c8e94965c4b2ea727a6265eb261555ea286bcb4c437a17b719bf9339978357ec2fa3ddb23c854d8c55fce360e35649f9f2fe6f9a7890fdfb4af83ad3e825906f18c6761aef82c49a7c22f76ad4aed226a7c6217659f98d44e54c95ca48bd230690c3d7b903d9a2509e3a23482e9a48f805fec928bca1e6fa8ec60bc6d72e3d9a5530c83057b800dab89cab3d77839a8a1a45ec8e9f1cb57f6e770bb93804617e728996ae81bd96da4dc4117656b1332126800c9a5a10f25d003c92a9e18faf2ecbcc4e66b13caa3670fa2c518679c1f0c1c32638c73e3fafc6c9c97605711975a430924813ac651f6c54e83500e43ef43e4a19f29518fb41b74dacff3955e825fecfca5863d54c437cc00168a240cf5127c133df6874bbc6f90836ca87ce52395389b016a9f09e29bb087866658886351b65b7a30d43eecea9eee79f60e88af7cecf9b087f88a10c726161ef2893db18735f34c46c7195904248bd8159b427388e513b20805a1a267a10e127af60e6a21af6a3f1b0fba1ea2d8be2b71c2f621ecc27150493bcc0baa8bd3d2bfe8f411749951e50bdc3d9ee1861935f4677679334c460d61b0212b8fb4d4e1ed195a9e5d6a3ce79c923e81c20a6097375476ce52d967667413df84f1e9698ed16e3481994c0d865fecd38a1ac627c6526751c7ea50189bb69bc26e32ea571ff58bbd09c6e48a4ffeacf8149f96bab0d20a31ea174ed3b3e394307ff03e7a6110d6962f41cf5ea7b88c28a4f2ab5b672238c32e76b1b3f71c9d1a26840f952d66143d7bec89f18b3d3eac00f659430dbd38633d370a333c8b53aaed619cb1e26c3f865cc7b34379fa1ea2a63bec9ab102d839196af5d8b519d57086e322d650c37dea5913ab9e4ad4decdbbbbf2e322ea13283b7c135deec42fb332ae3c3b9418e7dce283a3393b8c33283bec62f049fcf2ecf14b749a55ba286322ea0cd094678f416478e966ece24e8ad14f1f325018c17c283fec9f1e8e5516952bece21f312a0ffae7abac5243a642857ff66bb9cca2931e473dfa31b8f06bb7a85d585efc8b0b0cecc770835f4b86d08774b77876a6a5e85ff8a6490cf3cbc5e8e810d4f14ce9f775acf4f0cdd26006a3df3e217e0a85f8ada30313dfb4dae337f85b80f080e843984e9dbf5b7800c3b2ed79edadd3f700a1055efab7af65ba7d3fbd5d82e0eb140ab20735965167181d47bdeb8ad6d65a6b4ddbb63935dfb44939ca1eea8a76cca890d2198f5615f5666043c018a276dcc54faa0714cac9d3b2e2943a15e5420855476ae362c62d5135260ac46a2a156d563aa934d37c50dd346167d0b047695592610e9e393e0f813d0c67a861fd85169e4771f0c303201e08d978f528a595e53c8250995121e73b10c393cf36cf5e43cf9bb94113a51da8da1713a8315c5aa83f7eb7ec208917c10e80de9bd9810fbff6b71dfcf06b3fa4286fa6e6fbddd265c9660641c66677c15851722ec1b0bbdbb5d69aaed6524ac975ccc6eea667042604932e5b4aef4f881aa5f4d8f5491416b2bb89ba5e440dbd5fa75348a5ed3b52925258cc3e1d8b43f109e53164a18fd1a79498f49b149362524ca2cc85b70039895d4d5c9e62130519dc641ceabceb2f826962576c50f66cad29189d36308269aa124abf62ab49ec9c9d5860509fc70aa028d0773a5f59e4c01d0e4ac7903c3d7d442eb4e035293d3b027e5312d09ec812e6eb4c8b7d6528efbe16834d649cb30fb573300bab5fd1b75face8483a86b39b466d5a223e9e888c79eca3c7a6e8149f66ace445e9765e610ec3090284e1c5062fddf5b25372f65043fa4b3738e0a52f69f1d23de9f586973e239da5832e5e7a8d0ecc78e936d2c56dbc741338c6b3d96c66c34f7f137976fac333e039075f3c0e184ccfac2f83ad7cf7b58655036e60c8ded2cd511c846fba2d600cf1548636cfbb4e5d351cb3e15795f95e6079f54e7ea16515e32be700ab6e3da0a807060d2a5f59b7a994f3f858de7d216c27ca643c08dff086f2986f27c67dd8a0c020ec628ffe78cc477484c6592e533ab4a5428cf3f02331cec307b8e3c3639c824778380bdca1711ede29ea9d16a36365097008bb586908bba2525492718619e9f1016ebf68c0ed57b7b2986f653cbe956df593f1d5b7437424c6659c87779bd77dbbe58b3a9e7ea9df140af15b2aacbc3a51e73cc09d1ebef20e3c525d06dc89f19ad2e9f8863bcf6b7e5043160b7476b1cb944e471b6471aa49fc13ac1076af9b849fa5f6669c3d9e608974e013eb2a0fa312938ec5226eae2d674ae3218be5a1fbf0d0f5c343d8f7e3db7df9f83a677d9dd37c3c3e99af03c39c8ee95ce5dcd319a0c80b13c73e197b6c628f60d8a31bb10ebed92d601c3d3bcff8c667aa3a261d0bc139e643d22ff61edff60bd56058db2b82b18bfd8e4a57b0faad0c15c2d743147a3df899af874886a75f68c3ea206a1895664f7d0e15191d2529fd5c7aea32496989a9c9e909e8e58ff491b327a7a6a7de4c1b5b9951d19010d0cfb7cf53ef190b6d6c6543454647494abcf4e4d4c4b4a49404f4e313674f4edb148f58d8d8ca38a147790e77b4b2dc050b71729a7e9c775d93edc3f82d2cd3a336ce6317bee194bca89ca5330cf6a855e87aef5707862857398f4fe6db8ef9ea97924e3f2d453fa6549f4a7d5956200c301991f428650a3b1c1c18cce57267b1288ad2133adfbcaf9d7ed3bb907f366edb569ec39f65d54b5409a6864b602feb0d358c4a5f00f1bb1e97d4a8e192e993677c50bf5ebb28c593e2cf8e19a7f8c304ca12e98ef948e9530af54d7323abb446d825918047d825a5c72df846ba942e619c067bf9dd07e563f2845db2939d6b9ec34c6e3a50765bd781210ae4c027ec92145c0d0adfd4972ffd09dd18bb4b77d7ca951b953431bab509e31153e55f57fd1af9cde717c276a28cbdd3901a8aa338df79299594ae9272ba8ccbda32206b5fd22595a0c4a1288ea2507484d917331447635c4aa95491b0d03176e91d448d1ee230192f3de6ebf9ed5b027bcd67c74c6f512a7c13e24c4a632228b13082241cfb64d29974017ae94f8e64d27796fe7bb9a5cbcf4b8f3ef187e93671582f6378096a9ae673e2e494304745d2dbbd64997e4ac7e9584db554606f27d27ca79dc1d6f4951d59790577d857606bca68bfa474b9496204714312685c59030b994cc18b0d4932b011870e3ac8a4cf125266d8610839e80843269dc9c6645bf824095db1f286914cfada48c9d371375b704aa94c3a0663c5278a6ad4128dd815a3cb396a187f62f46864957e76957e7695a69cf28b3fec42c94e7a528221074620305ea9d1eb7418a87ee494ab54be728e8221abfa06865593015df105eebe24b8faeabed655a9665f90e391c7930e4dd3341484215a63c80a258270854c9b0118375011638a1c51649a94d7b680e3b5edb52dec78ad874cd3342d46796d0b315ed3b620e3b510649ac6d3c41569f8f0823482aa38e2c1610727a87823e98b2129bc70c288057831e48590fcdd72c5173cbc55d43829dba68ba467aff125d2a485531747a1cd1c918b375e4a3248ea68975faf72a55796f36595976e0292152418c7602ebc7c57cc6ca004d734d3810cca48420d2678d0618618e669037fcce2db5bab810e38500185174818a1e00754aae822480d249ad80108556adc162825cbb7d76c3a6801e41c7d2049d9e165a250f1ed3f6a103b441a2fd6f876164f12453c3147962b6198a1034f146fc0b1c4831733e8f872c50a1656a22c9110e21748331ebebdc7d450a86fdf7656bbbb3af601293f3ff0c086208062206b87754cce30458e3994a0a38a1cb2d6e1bbe7d4664be93c523a3292f1ec92eb48e2d90819731d3878b6a388e7c20e379e3d481432f6213877103d7b09ec396162787613380c183fa364e54a0d3df1a64a3a60f0ed31ab74b3f5f6ddcd822eee48c2624418a72bb24622c20c2c946270c1153090b5956f187c77912ed2311637b102dfc49643b2958389672c9e9d25c71bcf5ef30412cf5a3ccfe1c63fe0598e29cfbe4ae930ceaa51451337f8820839a2680303327822630b9529ea4022071f8dd53555d6530d4af8f6544aa763194f4cd43cbb97d2611d8c98d2136f5012290e30dfdee1100710cf2ed9b9940ef300471c0278769ad2611d66f0a3ad121c59be7d83801356b4c8524515550821631b10e520280636ccc0051719ff58d172d37d917e4597520651599105870c0f7efbdc7450e227f6cbcbb74bbef2f3ec26b04f00c90a2ccc31a69406f87e8389a737d4d063d5b8e1c6b3c71913006e68a325329ddcf8f2bbc58da10fa9101f3dc8ef16378c9e0a7deb257802aba96e033d9de1a68d4636d6401bc4db18e31cc1763ab12bc6e858d9e2c3d9349bd8359d2618769940886f0f67934c19dffe256c2a328ddada7c3beaf940fba8b5b4110fd55bedfb9cc6bea203c169caf1314699719353cf5608ffd41976c506c337e16c8a4c3f47cd257a2771ccebc2b13d8ade5ea23713dfac3e7a7fe19bddd2c6d147efa676e298278b2e9b67535ce263f4e954349fe21351f848f1d1b99f190069118a6d0cb9f1512b52e2a3731e5d335ae2a3531c3eba7684c647e7c02a1f9dd160b958aead68336aed878b8cb8888b8ab8888b8c8e929658099ce84570929698589bb9c13721fb3cf1ece9e9e9e9a9632b9bf9c427166a63bf7c5938df14077826e34024fd8a1e515d19e74daffd225b19f57033c0f91ae1c0963693693e7136c92159248de451c7e2648ada4cf3d17e36a7e8db53a43f1fa9cf473afb389ba6d377d4b1e93459d559b3c935a024a525a6d8349bd815dba88f3aa995660065478a25c2de021ff5d16c36eb9945b144da5b706a451f2adf7e799f277eaefcf8c812c694246cb0831843cb0697227c90411d54dad841165b112808287a5c220ab10bcb6cf239a736a34202b801d36e4c03f9099ee0f22b642dcf2017f6ca5a22512af52b898b8a8c8eda3b72d10a6132aa04a9e45d77b5d877a324d18319cc90218e2853c80c85a181c9075594a490ad771136874d388b9ea373cff826822dca2eeed912e9d1346cccc8bed889c44e621dc551e4483c370d517dc8e15903683c976063beaff5389ecd78ee563fc137214e77b483a9a954f1ecfdc3312fb64aec8da5e879f5bb25084653f604f88671b6b8e1d973865079f69e35d00fe19b5532b244da87592b64637c854c2f6689c48f9aaf9008ee14e957470edc31d2afe85d7f21cf9ec33814aed2af52cf8e929496989a9e78957ad6402d34347de60ff7149a403d5bdaaf489d0329b87dad2320056bbfda7bbb487297838db1f28415b6aff58555a4a0177c04c3aa7d08fbf5220b5bc759cf592fd2566ce4286a8ba313cd51d8ef3eb213e99bb7f7d5786b5f0afc382774cf72f2847e084b42fb13d64fb09e5137a9c804f8c6eb3a640eed45da8bf4c228ad95d9877c38ecea2e6a749ea2b61709f2ed0b2e0c27a7088fdf2d40707ad6e20161e9a3c3be617c0383e1e414398a59398b5d7485b00f16e6ac36a774a2c7a50a65876f62bc63fbe2e1ed5f7b10be5179cadb87f08de7ed387cd3396ae57d42ff37f5f675ea06613cc002f4cb442a2c0dfcdea532e4f0428b38e028aa41d64a414a3cc111c30b988042d61ef37943685167d66f5708fbea53a5befacdb0b8ed01ec82d80e6b16cb5dedb01f7aa55b1b56f9de8038fd6a5f810d762d6e31c82c82ab4095ef8ce02b70e53c32d5573f1ac6683ed5301a292df908467a001121c94753c75a4f1d0be1f356293175ec87b747a7687414b544232a4d49d848c7803880c69dc81d887fabcf5df501f12fa502cb69be9575dd9444a6b71389b145faae35f8de5a9bd6db766374c42549a98b17a62f4e9bc6434d3a3a7c8957aec42b57b6f839e10fe34c827136a3a1dee3239abea926146c519c25c279fb023616a3582e1a711e46a368148d8eb8242975f1c2f4a5c9c9434523ee41718ed3b168148db868b4711e53db46b3f9062e7b387cb3a4048e31e957b31455be13f9e136e9386951d0880371e9345f4f4fcb7d78cf0f677907e4fb7c84af878bf0d1b87f3b444768fc73d03b8d9ad4b11e47db12d9b65e3900fcc8ca0100ee106d0e823b3d7ce51b7844e51fb843e3dfca817c2a1fe15b9908dfca6abe95b562aa65a407cd7eca6bbe196f7d3cfcc727e33ebe986d03650f0f8ff11e19af2e3735651276753cea577bfda252bf9aa95fedd4af8e49df4fdfd1885dcd6409bb9a988607c53cb0746bc3a954295a5d3011e88f1f1e55de3ebc3d0e758ce53d53e39df25e79d37887e05076d8d532895ded5064c75cd4d5a9be96a7be1f5ef345daf21fbe291fbeea44f8883a9b1ee0f708df5a0ff10dc76c988ab0a3b5864c7b2c6a99a49d49c77a88da48c74ae812bebb8415d29bd2096185ccac90de5c848fa8f34d35d9c0d6f6c3a51be9b18215d2aa8f05f1d59e8a529e03515038b67714cdee88d1c8da6350c7f41ec52246711d14767161573b8a66f9e1fcfdf0d4e7536529577d3d5360329f2afb0142e957435921edb28e4ac16d8d7a4c694ee7055656a3f9061a69b57e380a786abe9e1e96fbf01e1a5f79e75a22aad6a7f21f5fca598ada22788d231101dc7ed5802dcd6b7c65485a1ad85241e5359e0195d7802f101df9e1297fa1056620e52d6f812ffc00b75f9a8f6f6553c6637ce5e3abcefa649ce68bf199cff3103e1e5e7d155f7e2d232a55ca470fb0a74706cf79784f4f8cf7ac3c15c2b7b2994fb6af84fa55d4af76557b6d97f18ca02039c2ae6e2525191e8e2b12281a9a558f1eab964743a3e2115323c3aa3e787c3d5ce6a3f19a2fca562ef3a9dcebe1345ef3ad6c5b34ab896a71342b54e7751daa43799ea33a94d7a1be2c3d7af86ae534ab1eed9b6a71a0911e349ec35d4cfceadd8c1fc297721fdf8cfff87878fd649cf5d5f9c3c77f2bab3c1cab8ce8d6a6a7f39e2954167d4a95c5f4f8c064313ea5caaaafb346f0114470208ef2adf15d4ad2b1954b87d2b11e3f5c86e0d29174cc5534eec325cba564015c815d7269894e71731c6297f4ee56df08aefa6adcbf28eba2d7e38b719aaf3a6a04af719fde01f988f863a17ac8bcf46e4ea9ec71cc86a9083b5a45ccd628620d19229c58267d361721e2cb1b81d9f0d26b68cdcb1a6e85d015624765e714e7403e220e6c7135fe42cbabf7f85e203ad2f2ea2f88e0311b582132e6e340ec99e2b28d0908555101e196f11dd879280f3c81dfeb1c09c7f60e1beea0b1c1e70c1b7c1063c3eca5479f9549f73a541314d6fbbe88855dd23dceb272fe92b04b7afcb2f850d9caebe75365d563be9e293059f5a9b21588a45f12491d95a754f698a29f13ead3bb1f5386cace2d0e3432c208358e029effe13e7c7eade919e8e1319e011aafded57c2dea409c4736c2d7a2604b8595d7f89195d738f51a7087888247540e04dc69b9ca47701e19ac5594450b49688b35a090411ae20b47618b2454f4237c3b4423f8a64e00e247560e04dc21e27c04704704b045bd87c7f8ca39f088ca6bc09d16d8a2606b822af4f0183f42e3d569bcfbf1f1701f9f8c87f0a59cf5cd5c60653d3c5cc63fc6abb78cacfc022b5b7906ba0d99eac7b7321ffbac6f65467a7a6448f98cf7f4f0f09e185f798f8cf75457d17cdbaf0e614a67a15fd2ebc7a45fd265be38eb97f4992ffef44bfaea93cee3939e8a403f23f3ad6cf5ad4cf5ad2cf5f1cc90e08043d8255d8e191e8e635c307b6a4719d75e613641611f09bbda67075497246157cb51b7746b732493ba7463fc98c9c1924a51e46000464c5c9143ecf173146c61bf78dcddd9f36c4670eeeea66973c266154260f9450202ccc77e9180a8e3e57a32a55d511709882e1fca8e44701983ca4b9f913d9b67b41261a6c720d44dc9fa00b6ed93a01cf6e1a6e13c52caae8361275214c8813d5384c838f7e121a33fbc242aecc399df6fe679fc74cee93c82229ad32798257ab860080392354316c3a5e3fb8a74ce000939d81226dcf96dd261625efa5a01f34fe26b4d3a4c989f60961760d81bfcc82238730986db33cfbe290eec0d7e640cee4467f5ab67fe8d20288480a288c96752892a454821620a59cf142132761f1eb2e83d535846ddc7013276eef371808cee101d61df41d23b444738a7e04e117087e808756ea7bd70cc9045161f849104195dc856d63c3b6c314510416c5972a20dd9caa28738473c87b539a59ccca5f1a5dbc1ceb973fa82ad699ae7b0a6edcaedeeee10b664075eaa49fc056996ea5403598c3a3dce5ebaa7c3627cd85a774f4dd3346d6e2ed9a5699ba6cd293730eca07474524aaec14423727185cb4a33e3056afce043b92b89eceecedd1fb2a7b27b0cf2a136a7e6da0a59dea1bbf204dfa03ad4e7a0c4f4441ee59decba0e0cc39862183e15a20086ef3c3abb949e7b6098f2762d7aeae34f49045d88d343a1109fa25c5a80c8a7ba30ce7eba06475da41c9c5e7ae75dc75e4c31f5a6de9d40b7a553e790accc5e3ae5542af5a54004e5213d81ba4ee7390a0c39e529308c8feabc03c3ce9fd05f21284751efcd7789285942e43bb00522ef04e54fe8ef0a694779b777285f219c6f4a02d2a987d1699c7774d1d746bba2b2c7219ed90a242dcf1b90d24a0de5d3962d93f03ccfb75270d574cb31f24eada7f61b35acdcd3e34f300c9fae90e85bbe3fa41d84d8c55dd6e5cccc5186d3c3deb6cd45299d73b2344dabfdea6eda2fc9391739dfd491389bc98eec918c8b577c7a3e53f966c150bad7ed576bd855594c33dfdc449d99deb395829c2f2520651ddde6beb974f9e9483a42a9f52e91dd5669ee393c37b64a9bcf2e888d722a5140390a44a150a8e5627c448fb27bc694148bd6d96948e8d71986a5465f66a35b1b19ac632da96f655775b9e3c0d855244b0e5145d246a28c896aec8147e1e20f3574d1013ecca1fd308bd48409b00368c4f8aa45109d87326685ac2ce2222a836e6da203ba06783101ede147590132df1eaa5e155d94c5375fec0e05b68aeca39ce7b94ffb42efb5f885503c23aa6f1ccfc7ef496b5fb85d5e7a4e4fd6010f6fa579aceacd44f666b6283154796666e68ddacc546fbd991ad62fd20f0c3e647de8cd1f9cd083131453700102194ef01c2187156d5861031454542124e50d3a983749ca19538a1a7187359c9c60af494b2e58964d0c2a8414247945174647b9a0ac9c4d4a164e4a11ad319a52a69894f5d3c373d720fd04750700931403212464e0c2081e29416022061b8cc088e306190bc172d78f0d3f33302cbcb61bddd07fd2a97d4fe66f921104559e2e670ce54fe9da94524aa56e6bca2f8eaccd295beb3967c775cdd85a6bdaacfc65ab8dcdd79aeda853df9b90e7a3731cc7291dce867af23985e89c8dcd6fee7b139d52ea9dd2a1361b5b80f3185dfb8cb04b73fae93859815d9a236197a6790ec767a0ba044cc22e6dbde89cc49604d637e7efe79f516a8803856f42261df37cfa0edf509f9c4f944f4a6b65b11c85f5cd09ca398faf4d8f3376f5449f48e563d2afe9def4e973ce39e79c737aa86fffbd8f67367d7bce3971d835635004c2f9397d6d26a8240ae1a09bf14d07396a3acae917bbd723af591b2fc908cca8d1738ec21cf776eabf79077e2b04fcc0c635e74f3400bce6df9260b38294dfba340f40075ea6302d209ff3ae37ca96aa26fd1ce85fd5a4f73a6d372cf9662a96ccfc9c93a9c908775a65d78c8c1b6c5fd1bdd0bf73ee5c7ad77d33deb386e26cbc96b27dc9cc4f90763718845d51898328120e3078d42f52953bb098e1f53ef49606f08b84830edefb45aa12042f66bc6e9c512bb0a77459beb4bab809c847d6be622c875fd197db2300b06c6a587e64c362d5e4408726258a465939ccb462c3cb61499901c586579305e5d451608e0a82a630e38d1bd690e20d197f3182888a163498e1c419b220ba6861684b709eba0928e4c4589a941ca2b0e15170d92983351b3804e6352c1b160e4868dd4838342159ee6afd22e150e5b55f241c7c3e842969d1c929757db7a0750ea94a9777fd225559e2bbd59eea2255a1f2ed5c975aa9a429d47e46d9a286975f97738974bea0f673bee7827ccfbb2fc98d6fb27acf3b76faae7ff09d04f3dd54e33bcdfbf2a8140ae077deed945d775dc75d17bbaed3b61faa9007cb778e54a5078ffa785ee521e7ac52323ddc3cb51e72aea95228701e5311a080055460b8ce39a7d3815cb2e8790fdc15d2cd39a7ef8fcec3e972fa824a386f57327d3b999a004f15bf1b44a628c0797360b8ecdcf6a180e7c10f77ee6e17b537baed98f49531166cf810c5102c343cc9fa5b59c7414eb0218301c5c64ebc830b26190c25001dc1854c7a7f3b718a0c86bd422641a256749e8f31980124838184398850da89329c3193c100eb59a30b7ec11c72547992f5276d1043d66d9efc769606464a32183a0699c70a88deeda6452efafa4088307c64fd753690f1179f8790a8ec5091a828215161e299b6435d731e19ca7954ce23abce2393711ed98cf3c842709e09b68ecccda7f3c838e791752b1e190f0fe1dba31a7de6ab3c3e960caacce7319f2b7afd60ab0fa78c1ac2728a7ca9e11e19f990f480fa5848e254c36562024506355ca78f31882906ed2b7a0c8a4131067db41249881e83a252943288637e842536138dca8849471f3d6e11bb708c23d39568c5051f3d5ed1a2952825626197500c9212f4d1a3941a66bf008021864732ada2934a5d971f63ec96991c3439accc50a452f872bf5ba220f986be2104b9532bddd2baceca29d2316d739c292573cfa08bbc52caededed955c6f37ebb2676597a7ed4a29a5dcf59cdeb9799b5a304cf2ebfd8538a871bf25299df56db9350dbbbdbb51deee6ecbeeee0e79bebeb12e512f3d968f9890e33e6a1f085e7a7f51a39ad7ce37bbae9e5be99472a31a1a949b63702889ea3c8f5381f4bcdd9cb7eece43711dddbc0ecbb6ddf9b20bd55e83924a7f916ad8e2819afa45aae1899a8afa45aa21091458630d42743d0cd113d4d52f520d3f23a8f517a986190d4ffddaeeab6151b94b2b0d5d3e64a1589bc2aa95c6c8a3a3491e651e8ca088e1c127a8b543d38f6745088986282b2b4f3fe09103130cd65c88c01ea57576c5e7ca4f6539143faed4b1434f65249fa195f7d0437ba0c2affd9056998f10eab3f1ea51249f590572001b5900a0faef163690c8014aa1c6fc6e61630609d4c181ea3951a076679c50696e50811f5c11a4aa7eb7fcc0e889fcc009d90c4f333431f3bbc58907a41994982fe8c2e8b55f1bc3f53072cfbfdeaf6defb4df1407bcf8f977edf1279f59fd72fa27fc7285acfcd95fffa638b047b266661a77eb1cfc5b21eb524ab969130ca3b6bb0bb2fbb7ecb0b9bb25333333c75f8622f217b2640fdadc505474fccb11e57108d4eb4cb1c2c59253971d8e90b1f350c71608b3a4198060c71251e440167f7876e6c2497ce3f97cc621e3d94b0043e90ba61adc60c411b211a4401ac28e3053b29821faf0ec485660a1d9932c61b2e5d99f40e938eb9a971168c33294c3337d5e9ad2c3143278ba32832519f36411e2810c3070d0069734641c812a752e4ac11e9d60bf4a3cbbb483861a30352185b14610647c864f105454a186147364e981bf73763edaf29e2721f33caf6bbce7214d89e2bd2dde439a4186f7dc866f6adea31f69951e2b3d7d978b0104f8ceb9944ec77cd4b12a830f8ffa1ee5a8940e2a8e7ae4c4affd9c304f4ab3251fa61f7eed8c9d7a70f09c734e533a5c8c841c20cd64dd1b4e4732ea5a4a87d60dcc6fbea574367a23c3f49acb948e26670c50fcf499d2997bc347b3996b369b45719acd64527a7c7414c7906fda458d7ca4f4d28baa1fea2abd7c9c4899a268a17992835451944595ac8e19e957f4caaace72d73e17238d45da1b1e0afb9aefae03368f0ef071d936e93697fbbc24158c2c917ef64d838cd7c1b393f5197f2210bb8238badfb2987993ab3171b4524b347a62f3a845283e118d6271280a4519555a39779aaf40242a90a626bbdc51a1ebe31c4964625567b91c49c756c6d4f484ea58ec43ac5ed4b7ac80e8dc87f36d531e8db529ed3b29ceeeeeeeaedcdd5db93335eceeaedc6eed8b13721764cd14e919967be17d437f3afdf8392be5ae942be5cacac58564dddd85f16ccae508428e93ced9d4894947aba435c992b04aba4e4277b010d5ab880c50fd6e71dbf8a828e8cac6517a5b967b2c11a983efc8c5b7c72c7ec1a8c5888a5abfdddb1b8d0576b5ef4df4dd9bcd4790846709df68ce557e9dbf709d581d8b4ea26b9b11c7e2143f2ec8c1fb41a80c29dfab2f2ee8d2e4c46d1b97a760e82348b2845d1d3f16509d72c3414e39379f9a4fea734a9f934e4e931bad95c5f2a7200dc55160f5139495559d156f50524576151887d8c5fe452c54d4306249aa3731372b8f72876e544a37139459f18dca39c6d98dc459c77878aae3b6982fd66ff5451eeca3028df48b3d058695e52e663dafeb43d6fc4d1591528eca728c98a3965ff4ee8e31ce6ec386b96839fce270cee99e53846f66d75967ad6058c4843d929e6342911967e714993e25e85d5143184ccb9194db2f529096af69706a4c1c29715c89749c1b09525aebcc8ce63925b08b719e59f8d8b587c3b13a9b49ef8a1ae2e08443c219a3a3c39021a95fa4a0a40f6d9e679464381ab22be7908f328b1a5656957383fc22f9f0840f583e74f9a0dbb93bf3eb51c9ca9db1e79c73e39cbbbb524607c2da0b5a33fb8a31139ac6098459739c124ae0823f40e5ac18a98d4308eafc45f2a18637800f3e1fce7cf4992054ca99369e5d3203d5f1ec362e76183b0edfb4dc052406100e66c85001081047d8ab073100f68218c034408080bd0620a87310040dc224fd9c91451d234c21c4121858c4e1344313258c20ced6c7983a414a290550e52f129016432abf2a0b8b97d27dc1904a70a6ce9794605873057735340aa0a30f5d4a41ac840d69a7950b2e8c08864b707ecec99ae2db6bb6c0e21b25eb8ef2b3e90622e2faac07f28b0454e57bfc22f5f024c508a377dc4725c7b9d69582db06d2c9929b95e8561b62d5791e874fbec39d5f7983e1e6332f650f112ae5dd397514b8deb18742a13a507e777777777777b7bff72991de9b3f73ceb11ea24ee59c0eb72857129df30e0576945316f092a8d1f73bf7cebbae03bb18398ea334721c9d1690dfc515c27114e5027fd7711c8feadb94ce72509e7a7cba791490ed318aca72cedf465b9b6fddd7dac01a7609d52ae3a8e1f47d56c2916eee65f140183c199106b624c04ade798b6ef9466a1dcf39e793f99bc7a39fb3a1272127a0a6f8c3c474d49414ee12cc715c216c32f3d47c7bc0f74fe90cb6007b2591478bd2080528404193264d54a00215b8e0820b50a04071e2c40993c92b26d3234b6632a7641e24c77a3666269a3d651c9b8c274f9e84304866e6c8ccab14541758324b3a7b7a136efc6a32186acea02787a8d2956852e3be70032947374ddbbe0d0cd935d7a22c1250d1722441d7ed26e9967be537674a0b4bf8f56dd3529493359dd2f196736a1bd5a8b4f1d6d9b536ec5a4ddb369ad2d98f4be9a050a830c84ffe09eeee76e4a171bb32bf507e0c2b03643c8c2ed497f1b03f469007959e2fdfa4bce3bc53c555ea4b51c9397b7599cfc993ea0d51a3f785ded398989818afd65a57abd54ae59d77aa2f6a2995a78aa98f73efdb25e1e36a4739f084e9d2739a7eedf39372c67338cb4c8332bc75d1c929d967fbfe9c735345e4c6bc499e3fb97b7a0e73d7a0932ea5d87c1794a92651f60f0d4c5d242b5e3ef4e2e6ecdc12d995311a18c54f70865dd16d38e2a05b6da92e120f3e4f977299c50086ed14f4d83551a05a962a5d493b75cdb7467987fa42ea5c0a8cfa42ea1c4863a460c854fba4cde4243a1492bcdc4dd334ba94eefafa6c8eb23f54f62804f4235b4a70f352a3a321638c31c6cee1e698d25aa5ecb8cfa392f31b4e7293d3386e636dca8ed56983382358bbe9f7cc9ced73f6f67cf29af7945dd2c55897ebd34329d7e5ba123933c339e7da7064ea64b7a25b7f2c594a2addaa72ac8793bebeb954e23f88a694beaf494d6ab24d49a94949a5d424953ea5dc99a914e46bd2670b344df3648cde4ad8c1d6e20ae1d8ac31735c5733cbcd88ce3725ecda0f2f89cabe2f993d85b94234163c7b5cf1ec1974f2a4bef4b92450289db2809ceb92cea9e0a55ca96ad24f41b942640b5eee3c7bec303a273cfbce51de754e9da7038f48e7bcebc017a8a79c035bddce0b4447a8a7fc05ce555dc783d37d4690f40be5f2535aa52e7afead4551d73c0352bac6b9d4fc05e95446f77376a15cfb5cfd4239fd50f3a9c694911e09b6d6a5f3c838b0b54738b0b5d28fb4166ca9a0b9f423d337dfbe17524e5d7ed45f50b554e05ce51ca09e92817395cb403d25eb525f6b7d65aaafb5601276a17c65338e1abfe5b9f495b53ce919e05c527f413ae719a09ef214f8421be9e9a931ae521951c52376a192f40be5321f937ea13ce68bb37ea1bca27c857206aa31895d28f7c0c8855d28944b39ea7a188f1e259d73249d65e35f1b9496d4714bc68ea463ad8ebee00beb713d82ad7e21ba045bdd2b7baad1d7e3520b384b70705ac071613e99fe94c6990b93fef08e902dd8bc1229c3cd29e71dfdbc20549b97bff9729f7c492de042fc08d2166c5e0395cc13262875e8e6d2b96dee04f61bd864f5d4672b85289483a7ee04f6147441f6f46e869a5376cdcde536956c9376ae7d28d738d7a84fea93faa47452d9649d66b37f22f39e773ff1de63a27d4e9a3ce07985447fa2bde64e347fa24900044fbd0990a7ae7d4d1ef07185449f00cf537037c8e624a23e27cc49aa6daac83e892fdd666a3178c10920900002b262063db002873776d022ca8c8920263cb05e778538a288819213445504d9e0073d60e1c40c9cf8a28322a20facd7f5404c8c1cbeb0030b2f8ed8010438183dd1c41636ec884b7440003fa8e1a78a272a4360c1b3c40f10501871a921065e94f000cf0c49e0b004972dd020238d2368186369498629d0a84112bb2ba43046186100614b1419e4b0714c010717622069616207487860bd6e07e078238b1a3788b27485cf3e91010510aa1035cde06768c3e0810e292ec8420648080131061153eae8a2258b24b27c80053a9c90bcc85145195dc87878e8c1082c37e8808a133738c203351dd8b8bb82d350d1ed12e1f5402cd2319a03031ea4b1850d68c8604516bb20438d296cc4008c1c46b218a3111f61b18aeea1d65a5dee364f3db6b187eadffa12e96ff72203781681a86190d095d848e3c8dec284180c494a87599800dff4f450fb26c05f118f9d640477d4d62fd20e3d3f01138ab4c3d82995bdd18d7a4ecb140577c768c28b0de0b0820b35c8e8d409311b0c3f4e7589ecb7c76cd7c58f4be96cde812d14f6a3f3bcf685f435289a7f9cc6f3ccb1d0319811101358b820065db8216b67336a18e4db839cc04fc12631cccf2c357ad7f86de093e94506ac93d7048bf58a44623e7acc4c0d810059214fd4e81d8b6f2291d5b36c7a83518d1ad6ef1767d97e0dd523ba6d1b6a28bdf376f6acd832f49af3b78ff27073cdb7f84e9ec84779cabbeda417414f6bf9759cc7290a44ce233318aae051cf838410610ace5fe4a9e21bdc0e157693f81bd215375e024f242025bb5078125f9be017c2f0cdcf370cfda652e06f7f1e549c34ec40d334d7babb5b6bb91a18d6d7b8b99bbba7a6b1767777bb43d8f7b6d2253734ea3ed222fd7e38c24b0f41464dd3b4a8691bc20af9581cd69915f2922c31588b31f627e532a1a6f4604b0a05ffa97d4ee4ec9bec4409b3200afaa32b991fc72e3d7ef1bb04a64ba8740c17c5418d2a54340200000002c314000028100c088422d16834d4d5ed0314000d88a8426e4c994ac42889510619638c218410000000400066666834200b7712133ca5ea8871b595c2851c1ab70474c9f8c8ed29a59f10971cb6a1a30690d6dc14f3de4658c446feed902f5d33884445b4ae86a5f936d5d07d5f42651f15e2ab360b385a7c9c213077ffaa5b86e9a5516ddd56fe2e1f131aedfa323c0764adc2e2366f41500ba33fa34e6b4cd94d3d9173b782280358f3a0ed6f2c2081e3a6c168016dbec404e74017b9c74b40cf2e1b80648716273e20b6a53763f10cd3d2cd475f635a68d42923028bacdbe73cc4333e135d0bea44485a67ad865eb6aed838c823e30be7343eb297d830658ebd0637218f0bfc1ffc78c723a142bcb41bb42a2f3e5835cf116436f14bbc8a80e033f5b2af3a326b1fb52808bf886d97b9ac41e5831586326b1c4356a9f2f99573bad8835edb06cb478685b9ea29f32712610a590a60f6a7367712abf2d3cfa56ea7f54355be73858e73397e967396ce15d6e0e2975aeb998e1cc99e04fcb17ac827c636ac4c774f527fe8571886f3a754e65638e024cf4a4572b7be9cf10fe6f3d92716f306f903042d9009a39b2a5143752a96aca414750a458a1306c495c302fd02c9ba5f65216511c89d5bb46c523cda6cde7b5de32ed002ab8be15de25b587f9ac78506bd1405bceca70003d499874c9fac9144bd2c0c06fb5cd27a7019efbbe5b04c5a99b8182e97cf13148a1865321397d7d7ceb6d572adb1a48f293731c6974ec7c9a49d26a3fe8a5888f7f81a9b8b81516076dff7d92fb2f55cfc2f65e567f5ba65151efc7d35c4efe55ca8827f77e49777609858b46c90520b881a0e8b08d88859544d64c6432f5e36646400b0a978d8c63c8829b8c983c17b381cf42b182d0370218ce52dc5d0eda317dfa0cba4d7bc96bf0c66f36f6af9b231df49b73edc1b267eb90265d2dce58ba48a3702141f3fde113d2995de1a331e39701ed8a595a499dfbfd207fcee048222903c162b13c350ce8c6bab8bf84a0ec15fdf20c3af7f8d187d2936fcfbab8d9f1ac2d53e2fee9ea0188117c16dba93db7956030c8adf36d8ad75739ad09fda1a232c49c9d8318a6967078ce12bd6289e3ce126e3a70fe97190c59cec69fa82c82abb6991f09a22dcd90b2094f98ad43761840183d4b663d66a11108ad2532c8f8fe2fa2a99cfd7d64394de54336ee322f5e539db6dcadb1d17c1e0f9f722ae84a4529b3d8ff2128763e9195bed02356d809adf08e2b581cb4efe32caab832d6de1d07235e062a2dcf3d6ec131abb291d02a2e803e3f5c4312031f455cfd0b677d63a83e7b3b8e6761485b22394e79c60e9d5818649919af855a4451e291a3adfa01dda2969f6cf679eddb8cc5784df65c48617e28cd0391405ebd4260d8f1f295820807f0dff6cb21c354857acbc3976e5adfd5e4d84c2584e14caa3ec11f51c00c22033f52bf86b7685d655c9ad97f31d2f4c56e088e3b40f7fef5f918f6b834558f5000d28fd20fb0b2b0fde7323a37636871174ee774c8c3dff384fc254cde301eb89c1eddeaa0d8a505fb3ca02125567b21cea706b5ed5320c124aa9d7c484f3286636f9e30da6d6772e094d6f6c6746e91fd256c9e24e3c675609b1a626049bfec83ce91703de99125642a6a5363915a1962492fe6e522a3fac914f25cca49cfd96733c619244bf6c68827ecc92a545af67ba2719fda2f365e2d0925c91f4019d1296e9caba15f75f61ed0960377ae8793963905e8e477b74e00d57a9edad19f3b5bafd861eb7226b6f8e3e4d969e2b82fdc08da56b88bdd48339b41ea7281953f5bf9298b8b9414676248cce3f0ea9497b541ab3ce37a56bb66524f2db3152183d3bf6debdcec0620d5ac0cb63ffe28c8e956d25bf4901f42e7d22a055836ec79e9eb026fb3108e4c751bf2dfb20ef8b9e619866bb2a51a276bfaf753c804a3c010a9970f7bd04c370eba47c6b642bbb923612f84e3803a792b551178fad0e8190d621c9c5e3058a5a807f5013f3357863ea8c8b6a9880ab80732e16256c9b2e3c416dc5fd1f558881cde19c73e16f3109a54e50a43890eac2e8ada0fd6a035ea08b3ab9cbdc5755c0d2e58b803d0bbdb5523b5cf03e9611c45282fcabfb532a3d3050f48371b5375c09182c6709791a2c97e0830b43a22aac71f8a14c4759c239e98a07f6d22f4be80dc8ed7ccf6202e73c01cab8cdc285231c13f6151c98e7ed6c0621e666e0b63f7c96f5186c6c236161fbf9704aa484130282783e23a6d4aa190c8e7e5ab9bcda19b8d5b0bfcce5a957246d654098c98d729c7ea83e5c300699df0b19d2484b9d411ee35c0ff1e2ceed342c6c348ce65fc8586a8cb50472a184a2615951269b5e021adc9bbc7a2062f1c6e1ef2f920250ba749b1f784fde8416985dbfc02a8fe4c3e4789d42f60cf36e0644a42edd985fb6af40dc4d82528db4d4cd5c148418282fd9b8e37ec60a7fa2e0555299d1a1f03fe41ab5bff920d7597a0c3e098e184385daf5cf2915ffb9d898e6800a41911890b0b0e86085d6d91fd2548e8ea1e42b2e5d901236cd1b0fa0a08d346ef7c0609c1081713203a080b560a0ecf24e0a05ea84d1c3f9332be07b9e557d8a49f19f5a0cc0529008f5df574eaea3ed23046c2bb1b8800dce60ddddc8e42a72e78ee2f6c594292710e8e62a02e96c506ed9ccf274c902240e04c73f5cc3973f0f9e7d6ca668b60224b7c8208f92646cb0a759bb22373e2fe21c167b7be467c7cd1b288e8000113499ddcfee8426123c6cab47f1a322d873df5258b61ed78d024b15f8c9cb257af7d4189c8cd87b00aeebc1870af30630f27534a5541eed4e32df4ae7d19f6f0c555c2ee7e6b1847cb34ff2ace1d98c94fff3d6d71e758c4d33b2e94478732c79937e62dd10d1c14ddbec6d789b41386094196f4bc63e51feb1f7737ca322888fb6bf5a9f8184e8a064837f2344a3dd2c300f225ded8498fdf92bb5f2effcb2214a8995705711a3e12f21bb122385f870266f612d4485db6a2813cf4d106356033d5198b3c0f59bf999d0d6b53021b57a8f86b532474fb52ea8bacf7f368a98aa55f1b4c2565b2c24966e7338da645acaf5ebc0058d7497824763c88172e0c2e171486efdbb4bc1737b2862eb10cb624c4b50592510be1230ea391c215fe4ec8a46a8ba7a83ff4a82939e6008ae61b8598fa98cbf041c7a06457cf36ab480dc820f616930d13334e4dfa731eaaeee45d9b6c6235a08e8c886588c2aec5836f4c3208998aa466c3cc2ac9af60ec596ed800525f23f7f3e25f5cce6b3420de296122c2080fd922fe239982f9af7e96de789ce534c118403ce65cdce6fd5dc1cc01cc6f4bf3c5a1f132fb9f0bc5ec5e829998411e5cab88fc6d077d121e7bdbf958fb2e90d1aa457bc0a76e1cf25f2f73a00bc233320c15b7c2ab143f36a773fae28ff6fae9833da3804333c1124c0d9aee801198ce251d942b5a4591601e5efb6ccfbd4bbb3aacde567298a00def2b4c591e9f29162e2daa0f425dd1ab782e99a204772aabd4e54761b744016ba377ef66f32ae8c3b1e913ed208da78f20540fc1dffd7e6cbf21c520d1846e49798668033c2878ad539fc014bdf47db8c31a899e91b4f062f8e9d1349879d7f65f150ecbe63666c09e5a5185dd71d18a42cc71154cc713171b9235edcc82144ebd06d5c74c2940c9c1868263af923328bdb15f231774046f5a601eed293c00ad5c3a939b235a5c1f03892c5aa7922e8b538ba1c32228bead6fb22455725d86982f95a28b2c620409529245653171fdbb122b31c27d00e2e2d999d9b8f4bafed0abf50a0d9f7f1bd2ed9e3126ae8262844b2fd9b0861a169883a5424719796520b866104832917a4a2358e082d4ba922c6de7ebe8a69efebaa8a6a730c7dc303bbbc891d6f830d4a790687683c35f6ebe645d119e8689e3a0ed31a03c46d778724f7e89ba0fcc5e1330a392c69b17289e2e61143a85b70f37973ac5474260df640a099e9bc4b42f30a1bd09c1eb4f0f6a44751dc7d787b012d5cf896f46c7bd73717209fa1735fc6110577689eb08cdcbaa3ce684cf874705b0578f2bd9a5c6a4ba512a01181bb3628403a4a2cbe41d5a7b2bcd62d86aa2367e7f9a7d3a4756be5ff1b265b703c623a403802b567a3432727da22a13fba098ec21a2b1eff9f876908800c05b7a5127fedde9720928b23d4b4a0afb36154572504e235b4323db4c7c069d96ff59619413298827f02755f0eb4ba64c99855dd2401d0ff79f7379944a3582d722184be84c5a6a3885b721d221fdc4a8b4db6b2d3c3d22d6bde4e21229e5e22505975529c601d9a00d7b095721f79a49017c2302a5be9ad0b51844e86238a3efdb4d991449968042197a6a7d0894272a4b5aa8152e9aa84caa6ab3fb51827867d1059a2e52aa2d09d5e218dee8b8e5d3aa91b3c13951fda3cb9a7632690e83dbd50430271673b744316337b4663701e186621ae99ec9b70520b74c60e5411692017e9126a8459d840f5447dba25395a974e59f7e808b1d4845d37217d62d52dddaf9ae8046442b76e08275696a6ac7574c26e7937702dd07c833fb12e9c4b1b8424d3dcf72e1a0247b5f70b8d5c689543940d73f8e91a95e745040ff006dfb86fbc3a83ff62ee4099f84e5c0b272363429c54efeda5e343fb2d4624945ee62ec57d72aa7ea55493377501cf82261c7e383b75e1624a58774f6f81c032a498e48610ae7121f4d215fc41a1f97286c40213d65ecf447bc9536e9d56b628e1eb66fdad409bcf1fdb2f49db31eb4d45bd0be9921f42e9bdfec75466b361a0bacbe5618fa74f1af321aefee593bfb020e45e7db62f0426ae042ea4cdab3bfc00f8f81c737779ff4f5944afb0e913e5fce5b79b6d0891cecb8aaa96c8c22ce23af38f2ac55025e2cf40ae22bf4d7e48f478d085e4a8ab4dc30d5268d5964e1df87c3a2d9efdde9da5d0bfbf0a150206dd95c527bd597c99a8159863e437d0785b8a206f15ab68e85cda8b6e25c52a382c90380143e168c6739b899e1b4ac99eb31fa97d5add59fa829e73885c5119aaa153a0a6a09ea3051d6bbbaeb28451fcd82ce519f69cba94da94c6b0821c20e05cc1d45c1f0494c332506ac72eb9708990dbbad63ec45eceaf8c83b5d58d61c3805a726522e36ce830fffd8293dd9e9274f1e8543f8b38884c7f7ae412333712eb97ee48e652eb17e7d4c7a4382700c1c8393b6a70799d8ca5e41ccd163f44ce1be3d4037097e65f05dd639a078bb69aafc0280c513c8dc9c170ced8e83fb91de5ced41f0a07e998a61b749db9efd39483156169d4d4cfa50887b42d84363903d1b27eebb320700120eb8295010b8f1f6b77932fc0416fc87953a91046341818c2b3903070a4517ee586aa31ab9768f5c7a347c006a1f9e3fe0b201d921fe88eeece22945f61bce6adf6e2431db8abf7b58eb5c2a09c9a1a5b6a1ff910fa32fa74daa0f548384377f4b8b9b9efbbc8ecb57dc0cbd7b536ee100f5b4feb1d11283c9e635791b4be028cac2ef821f901c7a08dc40c23042f27dc5f3a4a5f7c4751e9e90c0d0a6be36c2bde385c0bd4e18b9484f3a03de830457962958f4c749b8ece14c6181621094fe21a0302b1dd5ad5653b8d043016b257108f8e9ee485241e8419e49733eb78018aff00a42890f25b5e1ec0a4d248d4f373b86753e6d2e34cd6aa3afa62645232c9e9cdd1dee6eba6f088a3cf7b048962bc510d72b52cf419a626283dc78dc2885f963fd7b5dfd0a1a317dc41800fda0826c3394a990d21746a6648acc7ac734180562e390f12e7d27594ee59f9308a3989824e0cea47a13652efa2dbc9d85c924be27e5a092816c027ff6183fd793c60cbe78897e1cfe360842bfa6c9f10fbeb8539cb524d357691ccb450a4c87366704c1d1a8016d2c2ab480ab5f77053ea023471456bbcd530d296c5d1711c9129c438989d192219a55de85ec19e1ad1b6765a32d81ed44b38742df9f3421fe37ae5bd8088703893f5536ea88ba1b5ad2d6292afc61d7bc5e9ed4d63166cdfda88ea95fad32ec1689f196f0b6802e09c7ad64eafc5758e16c24c1c4c6ee2980cb874705a061093c6ecfc97b08ce77ab11dacd1d76f7be023758b3b43a651137cf0ae903ad147218ffaa9122401f1e00253ccbbcddb04c4b7905f224a51db593ffcd50d6284612cf88ba65712a5e9be7e2cb8e5cab54f4e3b0ccf784e58462c88441b2853ef57ebbd31e962738bb59b3c4a930deb215485e7f3cdf247e412fd0f1a0d575aa71008c2cac039a380c7dd5260b5917da820dabe5ec669fd6774f4dd0881eac0944615c3d68cc8591ebbd33778d04ae3ce6f3287d3773151c1a99131c8504383e9b1f645ca4aeae5c352b589a3bae1b04185732f5bcc0e25e1d8e062c59ab85bd809116236735e751a32f1b13bb96f06c4e80cb946be5b2c43ae7711614fd5a91fd62874fa19c77e38ecdbccede308303789e1f9731547cfaebb676be004f1408de2fd436d630403d716fe7cb66ba4d52ee607d9854ae9f5a5612255e08d5a6cd5aec2b9746770ca92614c16ae1a689374f8596f87f309912d413c5f677fda6ab375672dc71901b6c77f17224d66d641d5e78342d71961753d5470d358b6ff54077f206ef1bcaef132187bd806774904e84bbdc5c8477eb4e63fb5a94673b0083bbe93145480d855af627aaec9c18dddc2eefb5d929290767785c1d37e2029dce11242f00fc8dc91d96e192c5003f622cdda2bd4e92b5c7f98d38294516b8c76ee42c190e2c5b11be12227a96fe21eac0c50e95c94cca6d4c0e42faee43cb3169b5999f9103cc2c0c2a4b25b1cbce67379f19e9c8eb05836cc3710ab54c40a784ceb3b733f3462cdc6e171e37c00ac669383bb41e0c0accf6271d85e924f5890588c09b74411da0b6bfd760b1511a67afc64c68a235a8c868d6dc6d72cee33b15e60bb655f7d364294b6080722c14d203d187a7bfb4a4eba805776ee71e787889982e43d324b8699b0781b81254f85d59570224b31a37f357b20c2ac95ab5710a37e7d47367409202d9ca6605006cb83b10edafda570e0530f266191ed26e878cfad4526bb938e4981f5145413de6d072a5c855f47171eb8c6d7be1443c9ead134ac67983c29bc29bd409a85a5d1840809ad510a7a6727d2f4c16488c78dc795314d5aa4a883503c9d0362785600fb15feb87c36e7bd6176650878b1b5b68f72db28cf6c997be4049223ecc9ee94308a086b881a11aeec49440ddfe2459622fa1cb40c3c78e8a4508dba2d5b8c1b26e32c02c33f7313d089b836e8a1f8bd7c303fd2b3520a16f3e430dbc9f0992647472b025e5c64a4571ce5b58174e6128deee01c00a9bf29980450fb8f4d898d367c805f03ba9b9367ca50239263a9e86e36df944fa884c8243cf1584a188fef0b13da3afe12b20d41c8dcffdd650c0c105381dc9e3b5072426b4bd8732b7b6c017900b3885528df6978f55b1b8fa5f93338602f36b1d392675407a3afada894c65a8c2bc858aa1f8e356752adb41f313a03a42c44cb95245c47526a0cfa983956b2df4219860a1f78c56758d5e5a2f38407588c0c0ea10d42f1355fd64c99b3872bf2008af84b2204b0ef583544643bc80a903a42a4b5e1c87569b744c694025f897c56ad177b2e31dca2cedee5d633264c21cd44501fe95aa68fd0c8674844b2da7fc72e4c2ebb6123ba7639bb0290a07718da0873bf53d59196a34b70ae350f166790dfda677783697d0b9286b6773d885696a444e1ef27fcb0467f64dae8f298888de0cfd9384f1f811f803b20b9b7e242f638706f26f988e8d0a0a64fbec4dc3b5ecf115a6fea253fe360f7b67728b5f79e207705f53f09104e6207110440880634f254252bc8be0a21946bb5d2c630ba89e0b7ae000aaed68593dc1a476f785ff8fc0241ebedc03b81a00b4df49144544e7721642efc2ec93345e2e28c8e39d62d5dc117503aa77f3f78a587ac6f6da4ba1dd04e0e1cde55a50555ddaf8043f828abb2c717607f9af679ea555ce3a9bde6faba300327c5158d56e0ea80d5e7825efb7c7f31df3fb14c4ddce125bf000826faee700ac7d85962106c4229e20b19212fa5e161ea3a04e85b3fc0b39c7ba3371fc560777597c4e94e6dc8ff5083c10dffe763daee77a5537a4872e95fa84680db5059dbdbf40939c69356fd0ec8a651b43202bdbfc9510dba844e7ea0febf1076a01051fde5601afe9719140df30ff20d63bede2059774b903c1f4764dca04b84e93ecc43ee74788a53e0296bc018544de61afb80d7b26073ff0ad608d9aff885c022d2d5973b32f152ef40625992ff98a0271905e0dee14465ede0b1b001bcdf04300d42a65b20efeb0fdd4c13d53dcd0a43aa6d08cc4c7ed270cad29c6820e6759aaa78fb17f9837b60f79b2801792908c9f7dd56acb49532a28b9bc562104b751a8c2e5baaca9d765be319459ecf8cbc4f4fe7183daa93458256a21411b10d1a2e2e2efb55b450f5613fee2d4647d22ea1761684ca9285447b3e4ae55ca1a2528415b781522e4184611562458e294f0e67945fa4697ea32916e937e28c338d9323a481138f7d96a6b71ea681750810d18350d3ff6408e264ecd5c7559f586a30fd33d14452d8696066f7d6559ff4347f4826336289a519d6f822410b260ccec584551e1f4c79628cc05ee4c52f0246255a83caad4f32ac0e147c83b9f4a85cd39abf1a2fc6ab48c81de9518808d896d0a24730f3f34754d1faa7a90fcd4e84660338681e214865a84ac391fc84dc8d6c60098f731a71422d38bfd05cb3b2c1c3504bd93f16c1b25c6a8c771ab841761016098aea7a040b9d5dba8c132cbc3f683441724ce23f68864b24dad7c8ff8de486b39921c7a052ee224206b06310e770b7caf078a8064a0782f4c7dfd40a1f2e114ecfaefcd7838f10b4b32473b5092940a823efc605a503d2a236d3586d78ff12ba5ee9c504de81143c6778e9a1bbbbc105684fa85a411d5312e9442416548df55bf78b17dbf52034c55e0557dbba554dec4c70240e0ccc02871a8a4ebdda422e2302f5b02c862960dac897a751117e4a3e8db78ff0b37253c99ec2b7ba5ea5648cc718a780d38e54370bed84381049570a8810843701677319b84895dbc1b90043b6deee48bd715707df168b451444919f26b2817640f0882a9347782232d50a286a0eeb115f80722c1cb4320e75b1759268c559a0c26b5397225e886a61b8f30bf07e468e449076eaaf4ee6e13d9cc14c98de77f52e20d2a7740df0c8b281ecd4cf8db67fe29234e371b01aaca9752129061ca2f1843fa758425aecce226bb902ff995ee1a2415877dc4cb27e0278d46e8770e803a7c9e2401301524c09428415cab317305a0f106bb184024eeeaea5f41ced6677f8a583e37c8de709035f7d17e017a3854153f4695752a81cc67f85ef7ed9ba24806a0df88fff15672494334a03e5f82bf50427aa850de4e6707bb2f9df6774f69bdba11b5a31b532c2c9b808db9e38d4ff3a8afd62af8552e25989686d34115c2cc198b2b5f620808c47946fecc59ba81337b7d304144015de3a76fc099c6a10f0122263d907f03c82582448257dfc72e7a9be526ade6841ed357997ae67eab1636feafd8d2478a3c1628e7261ede2786b53adb748eb55619039731a1d3ed6a9590d6e328acc35080b62afa582e3e8fcb02e86ba220a707db97c1e0b2d924fadcb25a3a479dd9ab616bb99c6c4fe4549537829ac5cf5feb1768634dfb97d4c3a1691b6d76f719d1ee28dcab94583e6f8984e263a87d214865acc79b8b1356195f43a2acdbc10c6523eff0ff81102ee75697097a6b91563bf741af02309d42a39bc2dac32944fd1a2114818f733e7a6bc275b21f71cc88835a7145aa5e316647f850936b8cdd2145d13fceecbf1345f07bfa8b1c0a9fed446aa8fb3926caa96b07e5c3f1b0d5ffda1bf46a7bfd959ef5dba76e54a75d9b2f8b3b407efdb91ef207eb8aed28959c5bc28a4e8fab3c33797682746c6c6dd1ae8f58c2c33f4fe63625a3470b8692d87fdb5e66c2d742975c78006737bd87cfd45ceacf88679bd69e3d6f9f767d1b473d897a9797f9044edb1e7d726b6ecb68d12292e177894c2245634688b375fd6f84deba14af24911da031341c8ed3e8db8dc76e3193af64e9703d531315e3d95bdd96b39eba1653c2d189c4903b3c6936076a39c609e939a80a804940c96a45fb72dbf37b223427a2c1b9b7ce7efbddebcc0f9c9fae71955fe0a223fb1eb34fb7dac549898bcae9a97ee066adb584f5470886068db6e03f8c1d0b04dc4072335d6e3d50c61f53510634074eb2811e9f551551f6b2e249e3152d83b2828f697dbe25c3e9d045fd2c348bd11b2be14d637d425c39b4425e1624635b5e948d4e0396a878632233835b19365cde5531fa25e6ed2b03f6400bb286c95aec26565c0f81511a516555503700f184e04bfb6ed7aeba9eef7befbea992c0e72154bc88123c0978601ddebe1cc4b54d4dfca8a35e5dbadc1307efee23b26894370b40c9223792340b25519e0ebc597c1da643a8f0b05650f1a82a0bbd9eced4f6e13ca6a52952677474b34f0dc473156d8c8b994b213edff0eb507274485089433dd001c7c2204eb45928eaf4c50fa7929da66940e4071e8bb81d7990a502f7680e67a6ddd565f4bcea0693cece3b4db18c07c43849fed65e34f3f1b8eb69f7c6fc3b872934101a3834ca7fae68f14e960454ec13b135836b00c5fee3cfc9052167ab95186993796178dbef5b30d702d42e757153bbfe0436f7abfc8e54caec1dfea02fbeddd961c5cd74c6ad0ac2e485c40832187de72fc3a102f4a26828f72aae8c282e54b09099360a2790ab098260d868d35648ef092b2d56f06f3e0b1b5d0fb9181276df1c5a5914d4e7158621e5edb16f1ecf85b5043081a04859218bb9126e2411367d529ec71d511017282474f27db8e78b220c07a4cd06264b30d3af1c8dc27bb8866cc22606120ba8fc32e0400af57695d41e1ec44b80f8a142a2e1cdaab6b894a62910361a2a0de0251bb502e4d89252efa87eefe8246312f31412dcd78ae2fe4e6115f32f49df893815d9201035fc4bad0630fad9c357984c4cc165d26d36bfcb388d1002734322d02e7e80ad21a413a19d73d1d46b1f65fe91756764b0607387085dc60f0030685a8ad85812c360344c290983e330d9308d0f1847f09204d97dc12afdbf00256003f30befd575485940b167f5811f2a43c630599fefeb6e3bc483a1872de13426d3d595c775cbd7b625b38611780856a385876db4b85a0e91368ef52ac02e65c7dab56da0a7a91616afaebe4838eb8428aead43b26589bd0d9f0bd64bea688cb2d7794cee916ca1f7ef807be93a6b29eba1e34f402efce22279513a248e263ecbe15bec014cddf4e7decbe30a9369613611167c541f9111d079e12cdbb8920f712a9f4b45c2aac67f21d713f662c59c4ac960b8c6fc2ae84125f57e832b1cce8a3de7c2c319c063bf0030c955341deb318012d3382e1aebfd01d1e2769dda8de97c318fdf8136fcf3e48479fbc7b17eb66bfe845eeab49817e050e496e014ff44949503a65513778469214a01175204d98a491241798152cc12b19a486b83bff2c26520e078b811a8435b09e391eed45858c316a29b11aa9c822d74320f5c895e99582f81a09cca446b50521c6ce5197ef57c5fa5b0592d9834c572b5bc6b3588756822ea214ec6f4a8dce59ad026651cd9dd51f91d4d6ea4fff9bd00579a1f6853a56bd2637d363e916501afc0a8de85e1cf6367264f1fe9252303c889708341764a874ba5c202d1e261b6c8a2826aa458ed7d18896ed5632760adbc9f7e8b5e570befdaea164bda37011d2676fbe0294f29a73408c4551320995ca8644ade70f0cbe72148e8a28f397ad92502f6ecacbad72462391a794fca26e4ec3e6acb3f9c27dfcf6e884eab86ed013ceb7c1d66ea64b5c4448ec0b86a9bc992c812a2f1149b78b3bca562deb029654691a9e9497a298c9a2bd65250c1780d751f177cdace995ad29621dd8b74e040d066071abbe5ae5c24a06ba282fe0904cc8cb2d966f6e5a238956f16a40ab553bab645efee57ec61929f4a31e595183edf1c5fc92c205d4675437741ef133e69e23314ddfdb5cf08b5d5afa143173c3789c8018350011649129e1d80b69ab15337e8173bd4409a978904904dda60d9488fd1c89ef55445eab4762d0b96ea028fd6626787c1c3db73bf02c11fb2eef7cfb70f27d41822f27b7c36f750e2c5049d834638ae2e90596e0b88919e318c73b61cfbe2544c58907bdf8a680593aa1ff15f60030751c43f83e601aa890e091d5469be9e12c5f3f54abab36ec57627ddc2fc97a9f3edbaa431deab958f5b01639424425d4890cf48e5f84c2110e01d2611a730183630f4b88b4d273d7dc5208854d649280982c3bdec693923990fe216ffd47e40b2531a9072a590083c6c69ba80d15698d68f5c260dfe2e3eeba5691d2644c93a7f6b183d10aca9a283d997bf4ec1e3bcca73100770323a42fd098d80b29fdb3c0e2c1f72369ace612eb144f27d122011a6f5c614f83bd3f775caf8846d4f737285ccc396265e3d03a604f183ead662b27e03509bca0b5054e8bec45c369b4b55a1600bd632b4d3ad32123df515f5dc7316e0f51ef8524595df45c8242af19809616c7ce1cf97bb83a7fc43b3cd68324cf0fdd2fbb80b5273a61e9895ba1a17d019db85f572a61c30bab3c2fd795763c8f3b803db8c46e3c39d90c4db1b45be21ff92dc947a1c3434978744bb89772c84ec6e91af8c48732f6a2ab1522c57d6351d4515a088a9d9fddf6c1731d7a7537b7e42226f8ee78f8d0c69c9411846fedea28af44188c2a4ff57f6aed7d4e53820fc3f349acc2007da636a4415c0db71202bbce46e23b89a237659c758a856ba2d2f676a47869390dbe244dc3feff92e8fb9932e5867ed8492d9d7d3f64984492b6a93e167f8108dcfa872ef7b7689cfb6a41a1d393d8ffad8c2ddc7b87c9db074d21c66bfb3eac740a3da145c639d83218372cc8e486e83471182102200349cdbb90b41f49ae500c1401a6e08ab20ce35cf0e240c97e65441f4fd9dd7c9f290ca6f06c6c0b66cfd6f8d979337a42c729e08a4fa8de5fff76fce82d31855f0c531394c524955b5678b7e21caaaaea6944014d4d92e5ca72a331a9163e40041c346b415ee7827678be229d4e8c95762a90c2a3a7001451eb03021d741c4e94af0d5d897e14d7a41f719b7e96465865764d2088ef9c8fd0bf88676365c9a895854d1b7a2b188fe7cc255d83bd72f0c8e038a11147af36984a1315ea397a60f8543a01006a368eec8fe15556e1676161f51e0203e8c4380c45a90bd8c44b7aab34181b32a959b0deffe4df3265e8d7aa687f810ffb5b43e6766f787b5cdccf7b7a4fdf303e106e1f1da99194b7173e266c93d4a8dd2330bb89bbb5a0587c864ffe9f79d27307470e9bc0171cc8e702171bd982a13c245efd1ae88a2e2052f25b960d039d8a449d7c7e5874a099a7cdf8f3f9ac603da1e68933a7eb224722c6ad978ad5a5d4cfd69094aab476bc67bf3f458b5f17dc40b413d17a4217d352840aafce694838b86281a2e74db87c9bc89814d7d4449b16ff2100a34f805158ab3f12d0965f50ebd10d711779b3485746d29311ca91f8ff6e085a70d5cb98e0cc31bf0a4f7f506bb8fcbe3fa8e0337a43538c086608fadc19f9ee14bffcd9152e6c4c7b2b017bd849103a127bbde3072362adc2cc996f072c2d838fba8856f4e948862ab3933ab2cf401ec078895ac00b3fb20bdf3b13276fe9ae0460b3a97f8bffc9298d7cba45f08eac078830259469a8002922b0f20641c59232f6a11d4be527c1e695609e9948af18904107925e39a5245e3c2cc9ecdcf342ecb1be0aa83472dfab615d4e0ba21816d9d55cb7ec1ebee5e37e7ee0fb303ce21e910a219fdd45f7621f5605581cbffe8cf84959b2da4a30741f8f085ced654277a409be4cfd1daf26d53379f4c09680a6d122e47926c403fa2c4ffeab23dc422cc562e253231c5248d7f5253a4dcd888ba24cc6a4187248e903a32218613aa2d6fad81722d4c12ed91da9ae7a3a90f9e58f30e0206cc191338f873d9387dc670461c536bb183f9af927cd91754d7a3abe6c1ee987001aca1425e786331993ba339419d724feaa507b258e19600bcf82fa309cb5bd6e1026b137976f11c89615308d247c0815c2511ec49aca7183cd0b1faac508c0c78e43604f57c5bdede68924015484e1188aa5aeb795d76dab9f544d04ab6a7b61eea4e1721d29a8b5d5fab590352eecc479392b9f3027089c620ac70d397f5b144b130f1f80c084e8a15c07e2ebbaa2b067defdafa44840f734eda233bac36c181dc5219648c29f81829f7ecea48a25b6d09969ec84907ef32e2f05e7ee763fc138c37ee586592cef238cffc69c0f807d0bf1a6c9049cf75ee077d567261ee5ba22348043035c095960b23ecc8142ec102b379cbca5f2588dd6dda28fa23befe0582999a72b9f73147d7e4b4260b30f5d06132b233a424520d81628000f195f2dcc793db3b12b05304e574500b09f4fa5f072761f50b9b2a8ec3d375d4889a0c647221d0975dd0a5e9fdfa64b181951839745a2c3e4c064d80eeb81b6d359f8b24250496e3b169f1e69486b953f7725448918ed3e3daf71972d80e543d2cbaaf834c24b6f604671732a1d86140c732b2159565a0b36c63d3aff19f5c11e666e5169175e6041833f9a6bb2349be120683b693488197ac61962a07495db27b775061487b60558e59ff6b5e8ce12e005eaec4319e656a19f4ee2884ca03ac6a20f6626332c192c71fd08264808b170431b1a21ac42e87217da941b620609e7bc81068c2a0ff6376a4429e00ea11a66f06594a240c4c3a307b2f2326c97adbdfec5b3eb5f530d7072ad94cb2b3432876e190d3c3b67b91c97c0be2533e78d2144e779531aa95fd4075f7a1d4ab37c4a713f4a80e84c912517b4a911525b000c8e6ee012cf931a6d003b78c01cbf8292d1520cbb4148c8edd9b6884f36611a59655faaf24fea1c171af7382297e05b3ab50472ee22c472f9135f1793c324bc3b963405e4249b23e2105cd39eb85c78b6f8e0ec96ed7182951feb08607a7143ccba4d11ffda940ad84a12acad68ceed207999373877780874948441e58b28eef5cde1e4a10db97718d1623819dd17d802b621c84908e95f1da4c7e1486dbd7c537b34f0dcc7c4b1fe0e2199fb74ece00e9798e87b35469a14d3e487d7eb34f642634384a9095b8bb4bef47cfdb363ea2717e52d76f4c8cf929c24cb76b1d9f22346628bfb324805e0977bdf3e401da7ba36f839988d3bb3245905f04923186eda5e998ee1faaf64484ca62576df4e568e3024cd15ef022fe9b9d2c0fe8c834f72795efb80c4957af771ad58e5d98f85b16966518b95ed5f88da2e0931f86a5c194efedd2751aff7923c7638e75b30aae9a14cc7a95e8c1a613c9f4c49c5e49abdb1f283c2127478b9c43ac74b1d0fe270c4b525d9648251895779f7f35b22a38c3346c8f74213ea520af686c979b1ef287239701b2c9089b7a29a53363d460e8a670f6995c44b0baee7652582f5c34b3757c2c8a4985b8f8cd84d641a0a8059c4c99ec5527ffb801432613c4ec8048a41264e1d297732278f28d31912804ce48e9af36fd090687719ca0333ddd16bef675b661cfa1922b918249c0c8026f859b3c9de0cef7f7d783a7fe5a59e03f37aeaf8780558b24c68b83c2aca295d9f7425d748441b91532dda9c11e0bd2fcf01eabc24ed6dbb34c06039b75377010d08309c456bd19840d132cfe782e568b428e79e04a98be8e7268fe782d295a110ceca78a0f0b7e294c2c3c1a7781a0e6324c4971eb8f74e4a2e15e8ebd0f6e2b7836a35c820497968b36954268cd8ec45c9c97cbedbf6a8ebc51d247ecf133d1db496e9135e8332302741e2adfebde882c7a12c86b3953336458b438ba8c85d8ef6d2c626b882f955ea20b712d3c7feb0353e9c65116789f17d3d75a3d17185e9e0f2dde846f217998dd96ada2079dc9a98c705ffc201136fee3cde5d1233d0d573a1d9064031f242a9fb97fc0ea8e96afc43297318b7a1871f04e50f22e0657d24ddd2020bc4450807c0faada72edc2afa3f0ffe376d6b828d68bba5e310a8edda37fd02aa5277483c95ba041a2e1866b6984bc0e6e90fa5189cc5c710f3f55bb83dac52cb6ac5661a98b8affa4257598e7eda68687cb13434b3341cee0411cd51ba33875f6dbccc3e5c5d4ce955cbe1e49897dac6accdefaa5e5e998e8a358bd11796780bed736a0075c689c28a0f1468727489e176df8faab503bff6d1e79ce719649a028e0955447c3d3d06703a1d4050594d98478546a73fde642c81d3345c9f1ba91f8829d469362785a79ea4264f7551908314420ea22e61b3b501af02e561e1bf5cfed11eb49efec51ee07fb43fec4a060493014cdc3fcd15296bf881a11e5537646d0e2a74c4d4800e08716d6a0d674e5aa1355da8094ef2fdcaebc4af35ed0c1bf566b1c018571f18a5b82d5311f51b7883ff0d27df2e0ec21a89ec61518a442e329139fb082e2e1498e45795183bbc762cebcf1d11aba08438c4fff6ec8d6912f4b30feeda9549cb3e348a5919ed38e23b2182866b001f720b3114b2de81e631e9862bd3af6d40c99aa8ce74e38b4d949aae0fedddf1192e3d69ea3348355d257f8ffdf8c493121017589db77ad2c3b168e2c2c493901117acfeddc101598d788ff16a1062654d3cf95d7e87cb801a0a5617cc358ef029712449ba6c4b8dcf84df8c171eddf1cdc4d8f5b27b1b7550e006e1a56dd8679c9846aee63082970e782378d9cba825b8e9817844037011472678d00339dc802c4990ebec84b624a42131e11d34800bd60a78aab9790d165d469ba78ab4e7d795456ea7864418fd195783464dbc73c0801fef5674bcfe17e616af9674851c8ca1b88a67ecb545a60145553920eec380f62ca0c40c39d6999fb6ac240dae3ba4cdf776795e0ec4d503a147f8aa2f781d1805ada39566a10cfa89e7c47cb01bdfa13fd1176e4a898a8ee49df44557fce3209a24f3248cdae83f3e7a6531c3047d8717ba1f0946f1edc8d3f123eef8fd1635cf75f800c6e0229bce2a280577c840bba1e71668082895ae7edab4c73077a2b28012ea01772dea1cea850a2afa3d4685bf50e3faa93c089a1e2b007759358234faeada36427d3ded98747bb75e7983b61e70c7cc6a8e6a4c58f738fb5f068a24ea2de04a87fdc4ae2bf487163d4c39c9e96bfba92703634185327e19225bf38fb0fd7d1da3e9a083bc39dbe7fccd3dd9c017b7c03bed46f7377799307069dbf76b7c62ec6ae920f915a862b8ce07f483637000dd2aecdf9abe681fa49d49f26e4d93d675c27a3c787a5ef88d6196dd7f15d7a876681f5c7b004d8176e59b4c0078f507b05e40e3c8012939f8063a3d0607948a3b41d0f09709a0d090e92b08272d9471af25b8ee26ac8be814b9da1da32e9120b41888895569118b60ce49a3fbb2a5f1e3af8b9231ebe40ba397bd5e8355fa1261be6ef9daa8fc3bcf00cf58cdc32eeaab007338083c6e4f216002538dcefe065450bb5086b25d40e8986240b88bce6d9ca2f0b82d4d90a38d355eb3cc2100374b48a905f78bd4029d1f6ea0384478ca294524da9cc5902e22dcb75f907e84a1284976fd6a9f07ff1500f234fc169dc1c3314ca012e05b0e201eaf8a2e4e5088a47ec24651eafbc2b48a4763c8b7947c0d604456ca70a308a5796673c4279bf8ec8c86619529289e87938d568d14034b23c0464cd15d4f8959cf2d63255d74a008d444b70ad136fe1eecb8c9c8c43e4fc2e5fe56593972b1efa39469a3cdbaff908de605ae7458ad3e94aa8ce85c7f767f848b2290681122398abb84471a9044374d384bd540faf626ac4b547ae0f8e39eb1667b80b100b6f76213f68c7eae908773c0c3dafdf2d8d708cf2f34ea93ce512aef77e6e702993f6ebdcbbb291ef8b499e0278e9772c6c0a193f917f926fec1d7d62dddf7a22a81e54257a6fd9566f479d3ad264b744589687eb295cc89c38685ceb1fef8db5eb61686cdcf107dc13c32ca234af58d97753a7d201c91e9fcfaacf8e0ca60c620de68577c95426f46eef0372a125c9c8829172f1165b6117a0ee8e1d3e7aff791c7e1dce0a553c7e0fe4a0e71dde8218686d277937eebb1f394d25a7bc660ccaf1a8112de3f71255655bd7f1811e2484e6cced8a717c10ba2a1976c9526233efc3d080b091293b083efb6b0b7d04c54dbfeaa9eff9ade1bff49b1daa8fd9b09803de69fbe5abe21531f2c909bcdfe09474d39342a76c3acfa507a113b4345b6bd54e6d48a0f375f4f1ba8840dd6ce4224a28dcf6bbc50e88b85888feace22a20654c0ece3028aae8d3d6920284c2aa335e1e5e0969260ff86bd710967eff71e45ed1851a514e8fa595446ea654032504a106345d97ad12efe7764819e654ca5f4ddad868a3d098734527e06148d48acf5cadab2b6aa4444574542ae1449b00ab8b6e4220de8347680b3d8363368051178ece1e6e35f40e550ce3dfe78d9b19c8df3151f74b388044ca1aa0c951f4b1ec713d08ad0154e8672fcdb0f5ca0b81b23b7a1064f90e88ff9765a7289b48050f6458c09d1373aad91510b38b09ae2ac58c423af53ff698dd0cbf75acce0e3d14d8ab6d19fec1c92d2635666748f91fd9a1fd0c1454d5a0821c1b2eee040f91c22a610d98182bb80207bc2cb6e5ea108b8b44f020131e269942e2dbaf24a159f6d2f0b49ca8eb82ee227d8d15c9a1a3ab20d2dcb4feb5b2233c2af8b9ab555c733976666fc059b1fb39515a75a26c1d272ee5d173411a723b2e0a4b16fb5aabb656b4752f7705971d52296b9400c07908c01406bda1b4e5e21630a4631e71cca55ad9d35bb5a4cd41ac4774bce8ca76b08ebe2a455b1161719e292f945ac8caf54e0ec0aabe57bf9c74cceda24b0753034dc560ad11d9691b1cf9c86a9f3f3153f99092d77e9f1a880dad8799daa172199685322cc8ffc2bba2115ef7ee7adaa094e4f2fbc9b70a6de4e3d8f48fc3f8bdae12ef88664f710a436de7bcfd0bffc58863873205f25c225f5c5120334d08236c85aad2cdac2f01342b0ad4e250fa78fb0d6c3fd7f3e08d1c1e785b38952e6919bacdec4c490dd8052246b6da0387e8db2c600d2ee8c5a6740bd60ba3c89306ff46d4c497aebb64fd0018e7d94e153e013d5181727db668db8b87e90db063a251b61039bb4ed96612766742eef645af236b693b1a3af31168784e0d1e7fc2ad9de8e9c73c9cf907e6a6f38c3324cffbe036dea81704acd8339ed6664a4146fc309dd2c26c208ca2451910e8b759ff4d1b2caa4f3d04a53ee2608537953b626419e55c82443e1340b43f943dc2b0a35e94aa3b0193341cfbaaf310ff55735cee8f43aa7bf348820b264a123e9fed8d01b3317068c8a110bf7281f6081fadb4f5d1d676a983d455ea9c1cd1ff22bc60bf94826c89c45c0a7bfc47b7300d62d5d2b259d1fbd33728cbe75a0f404ee00e8a89b7e13c380abef06ecb618c97d589155aca75e1e590389fdc751d68ca534a4b5fbcb46ec60f7d2ef9575557452614c3e85cde9840c6686e938c842be404f5d413141c382c5c1506d16fe4e8e0bdec126c906d9373291db57e3678bc0021340084fb001c11370e6cd631b9f8e465b380e1efeed31db0cb82e77ee63f812b8e3063d88821ff21fef937b83388a939524bd5ff0d718c8ba5eac2e6352bab44b6550522e4892369ed32b0f82fcb2885085f322c921827ae294ce282b9a1f7422f670f6e5c20173109fe7ff9d55f596412d74452b794f365454722b0941d90f182bbc025140e00c4715692560644c480ebb69e1ff38b8b8abcdaeac5d1ed6340aea581e0ade3f2f3721ce015741b3696fc90caaa8f16025021252e72c544b4f244a50aac5956bd25cb197b6a64423ad3fdbbea6ea4558a91e6e9ad0c53580ac05bf8c27f441455789bbcc6bec039bc8c262ce6f462fee7813b181f4175ef0ec247424591536a2497d48df94198e1c6bd4b771a6f1ae7fc9aad425df187b32c00d45cf04928199fe94aa25b6a0b01c81301737f1041b0d6a3905604b81521fd79041c6cb174a321cde00153732f461adb08d17875e10ba2003042a13ec1f6b1073932210e28843a396baa979652bcf2ac10551759f30be1cd6b5ccd4187af289280bd39773566e04d901db92ea45292afbb9ac0d118831fb098848433cc2872a066fdeee7e492271f6522d9156b7a6d867a04690c83d531724ef8157b866c0b6c32b0a87466d2e7bd1a5db798db3bd242f19b7e2c3fa97c1a84e93a1f2896902c1ae9a1ff45609e269edb0c5fb7d9d454449435c6a2724c70a1ad17e49d787015ef30dc8afb8f8386cb324714c2fa62afead58d41515a0e1081533ed3d9c201f345a0342c473cda430dda7a1bf6d074c4e18945cab26f4f5064ee861eb387af3b4f0bf00e46c01681f418fe4ef9a674b1af2e33f9d3631e486b419d771b4518a8ef554b8daadcf1d6dc89387a956aae35fb70b7264aea5d3f4a7976fd4ea4c0135fa1384145d725bc54328cec3fb3012b92c2dbc924ef49dca8fb0cd8f5aec2c3fc2458d90623cfa64e5d80a3e672af682738b496d621d88d6fe90ab98b2a67380fbf94d89b183adce7759f0b9fc8f9b4b033775f614d39c9842268283c5d9a8c72f727cad9e75debd083ee078e2299bd06db9d7cbeb9fd956f6fa788f3117fd03efd2ab1ea9318a1cc763c15f1e451cebd19bda27e2b13cccd9c03617c3507d92c755fb69648051aa54124ce600fbb17eeca71fd3e0a9b7b1a8a8d07ebc361070a000269378d709285f475407d5f650c2a55b52cc88ec033952c7f9738c52e48cd99567e76fbd763458e1bf4e3f49f171216b10741ceb0f8ec102980a33667c54696a4bccd15dfb44f5bc7b17f9f721a4e1c73e8f7b2a3d42b39c34138106579eaeda974294b2089f5c35ca74968307112073abc16cebe501111bd44c50278e29d0fe16517befdccc0144630377e369be89501e0183bfb51f4bf2482bcd077f0b7b699816ce3f2a55cd1df4bb828f237b9e53d59ad58ab6601ab5f09e7f7c4cb460d6efe0eda6776d5f2adbe8529f617e3ac31a43e6dfd7f69b90f9f10d9dec62307f5d92de16ce1034c446dc2c31408687cf46629a29ae9e2f3b9a7e6950a625cfac5cc062914bcc911cd8bdf202bd2097b64f575a71129980029d42e81f3706f06293619713b631e270bc2919f3e46ebcdb3eecf519e6bafd8b685c6d861d9320aff5359fcee1cc3dc5f922f08bacc274a0c092bcea26c5986b32fb7e39f66f9c58e59070784c15f08387780b183ef648eed74abbfd732e463e7e4f073870aaab0d6cd5b6c45a5d8cfea57a3160720cee1b481ad4b8330f7a15ede0cf3f4feb4383fd044d5c0fea1a6c865741d0c82a78950e786d7251f0930923090c1a70b79c29a01136f3d2f78b67e6ded29c42af5f90b210a75a5d4ed30ade0841384d27400082c72585bba35d4387e0fb1eb512cb483c8a58fa970227127cf274b2a924a01d38b6dd24eb528f2a88785712662e493e398ae18009bb267cd6d50b5eed0120445e1857632df158af32447ea1dab1b3a9de1f39cb1bbcd8d0a912514fef48fabc584a9e70b62c4959434ae98333045f194093e9b4978e5c283cae849071905d9f2552cd9374c460b42117ed74b991686d306213c7aba098818df6e92e281cfea8d0809475fb5186f52358e10fbf20f711f6f6f4fcabd3c55aa703276c09fa05238203821dd466053264f93182a1e29763c603706b03a8960e8e88a6c1ec5edbab34417d8f3a0d0738a187df0243eb089b63f1ef4dee9db01008fd67568a91bede59496709dc7f7aff4f223ed78d1fc5c54da89c18b2a18e4fe36ac90bc868b900975fd8ea40717dd78a48f48e5c4ca6db3b7f0c0d122ed9d38b992279bdd569eee7feb9403c5582bcb011baeb1bb8e464172e730215c1dfd8b72c51e2f786e325bb470e3246b818a51d16786480e4c85ec938703b742a97921681464771f0070d49dc6f6d27f9de6909e6901c5ce0624641006e57196c3a83690c40dbe29c74354b2be41355ea2830f8a37fe25736c8d69ae34a116150e5f4f3a398037d045236d5e1a4811becbe941b39e8e3bb659991c7e81cae057b8792566a751a7b546ebe194d4843c789d9c268f8768b7a01505c178c332e110295839e2fb0229fc9458c6b219bcfc07a24171f04f9f3f989f249447ea19fbcb1318fd74ff1c49274e92793ba6774975ef9c59385760210ade13080d9d009662c7a41d170f3fd298d712b32e544599b77b098ecf4f40efa029866713b8fcca06c629b813d5186b074b951a1afbc4f914f2e64c75d7fa6fc7bd3f185c908c68a260cc78d0fd507a6872b24d0deca6543d733c63a6b31121b02ccc4ddbc9ccb0aefb84a7c15ebd99b00150b7d3390745c3a7d399705c1803618728dec8c83ebac3142ffe1e994481928de878b93f781a9080c999a50440ca080b8f8758039e62c45a0b02403463763268529defab3bd5ab5f77ccc17a6c7530e6514bf0c697fe79f5b496a3b7b3da49dd5e35453417f615f5fb0fffca50e9ca1676f9ca60b06702581e0e2ff797e4e60e25175213c13df17a7151fcb7e7156e5a9ecba9d0a4b29d01ff3cbbd8e61e14d62193d5813cba6e3c09102891e151fdbaf857010d355cf5d4ec70853af188a6a9c39bdc7c4b3100fba53fe6da8f40f0942633a657e74ed3f633b67e4e9cb91cf44b9bd0966803f283913f33b3eb9b4d6509ff0ef65653bf5744ea2ff16a6deb53503a7bdb8e1f62f42c2bfddb86eade0e663b96ff44493d34d57dbbe9d44fcd8f98e766164647ccb444a44f14da7066a53d8c9bdab1352385dd91bcf7df835108f7c9ec18b0bd1b0b75e88b8f710f71def527ef31c2ac36ca0825704bc63fe5632008f6ac078a45a75cc6c180b33ed027cef0030f7279d978df3ad913f06f4c3ac54dc7caa02d6c00cbf5b11ac67b6911f5adf2b61f9428345a7bee5c390a3c362a84f6dade6dde877e69043f0f43dea60e25a80b628d9ae25850f0977fee1bdf660f0548e18c3371d4964003923515628aa355ef916b3ce5b6535ce0ebfe3103b8edd7bb0e4de746ea479e0cb9cf6ddd37ecdb4a870077370cc5dbb90f14527c811a51c9beff5283b30b81aa7f19ab0a578151c3638f72ba950e4c0d87351f37e98e2358d917cfdc32925970439ab61df1830c130076a5ad3586458130884c937cd93a421d8bf1092fa89635f11123cc118bfbb2f7abdbff8187967ed3daa70f0ef99bf02a06355e49724c53cf98d91f044da27e1c32901cfca402a4b7a30e26009e912a38f2d28b5384cb373535395b99e1b602eb8cb36c1a913d2207b9c7a957dbf279ff28c5dcc353b93c75ae57e9ad4f05d7f41ce5cb653e9d2b2aead78561dd6278e029c646c767ce6f3f4dd5a169c89a2a1ae3e01748d22119a4bac914c818bb6bf08329aadb919e544e18027667d01a080f802c914bab87846fa47181435de01ffc729d4ddce0e9772ade3b50adfa0c4cbd3bcd06bf9f4084a5cf453eb786e8397eac67b255a99cf89fc29acff897ba4602eb43009c7d4d31b9f938d5a9002881fdd8f7eda344392163b32a2f3805a075f4641b9730ba99718eb036d0e26694deb7a77a01cf721599739b7a509abf1b31bb09307245cc552e0e706e20177e84382742b82faed6896ed95cf46e797d02f37b0cdf2c3f65c2594001c1404e5f00c9b8f7ada00129570d53dbf93e3bed946100310f507af0d4e8e68bf543e58be6b1b00722ef39e51dab53f7851b803a1839bf81ae3e8e3630140bd8ee08dff49e6c3af2d89a86117b668ce10f543dc9e19c4b6a93139045619e36bf6d6b091152844a58c427cb0c17feeb0e723e6831ceec3309c9a1f3525945d89e2e87e5287ee9602221ae55143d9689db7c6d3e01f4bffc4210260a1127b18a15afa57301229fb78e50b0210ea0094900533045c11fbfa29a0fda065f54ce88270a00c27f970c1d4a638944a0f3aa269d792005222509e10a059069726db11be132d76df393efe38d0c17a7f3d7cd32b03c7ba5f0144b991dbe0c10d5dbb6cb22a293e29c3eb967a616c3ba827909034442f4134c125a92f38928a9691513e425036be38a545e6ee19c6ae091a24da32ed88e578131e4b6fa787f98d628fc46536dd84bd13b25d624aaea0f64575d4c90b3f881d09d3e8d16f67383b0dc374310598e2b4e68add8eb1738d6620651c7fc9c9b9ab2b8eeae4f5913e495780d7771763ddd3e574ee2456c23d9ee4a97871d095a1ab84e39c5e87e90e8592524950d7c64223104ea4ff458c8780c712245ced0c9a225bf9886486c920040f172bebe25193b96bca78deb6fbb2e91ae5cfe1f0358caf1df8c531c4fe70c008002c663ea71908f6b01c3e8c1343c533c2637ccb2e31b6a639a9c7a13433225672d15ce48d953e8426213e18a5b8ca1b21c5f96f7c7c403e55fa754893a9d44b2ac3a4a881aa9fec129f2cc16ae302ce7caeec72004b3be6fb35d7e5af552e49002149bdabebd7355e05c5e9f66bed8255a0560fc4fc6bf5dfb32cb7d2e822429a0a43c6dbca222363d986c5004d4eedc9ecb9e8a72c65f318a22c62e3746a2357ea2d02f52bdca1137988b80b3e507599277a8abba4279ae1c54533ef95fff2fe78cada979b1015b1fb936844091125f5ef0486a81a80b4cdaa6f9aed9fee0d88f037da901c4b44bd6a1973248bf83024ea59e9c2f367bb51c86e9129ac3d93b5699a9b30465941525bef5ac5057888d988cd93734d8199305ff3390a508804340fcdf69191041f02cf3dd43060685f54c4112dd995d6bc8ad6b988cd44f449705a755ea6e87210c88df4dd03a592fbcc516c27318e32b8c108e1c26f0075eb2e31fa3af36923abf13951c20e15601f167dacb748b4bcecfdb0f7be1fe4af430eadad7e10c293ab621ba633bb216e5a74375686ad689a9c6a300f7863605ecda713dd1f633425ea0f1e5e33ecea7308969fa012c00c617ffd007faae06c50b0a1fdec08fdc05e2d45ced12691aaef971e12732f643a6e8a9e290d7167363ee3b30f2fb29ad03f2cace19b6981ec8682d326c875c71b4a14c225f1a98be3a609a7d37d52b0f5b9207f3794a8336c194ae465fb97d903cb07d2fffd2cae528f881aea04065c83d28d6f37c3cd2e79c9c38cb20cc283d2b1c264e7c9301bbad440bfcb801582320497c020d88dbf480fa08998abb78842711c169a2290813652e52183b411c7af822529225aa5a864229b7acc7dcf823a1f1c3f090807396cd74da7527c2b66d5c074d2f81fa95a9ae231d05d6b4bdaec2c72cc57a9cd8cae90863db11457db4f07903280f9f76a8fcc01299d830881f7ccd4cb5939f5b977e108fe89c8ac07d054f59722ff5d5b02f79c9a3aed4240e36bfd008937830e8798c89449c718451a6d452ab953a009cb7839f8e42214c91e8f7fc043a3da5e10f42607fcc26d1b92e60d1992b940112a9181dea2b46a6434cd7624318d313e6af0632030f6e67dbfaeaaf5fc48778e8c189fa879e257e17f3d444346f55dc2c8e53a6b269fb8c3723b542e59a7e218bc010790c9c2d240972a804383f24986695e95276045370c106bcf50cdea0c3f142bf63c0d7de2f345c2e88770e936c7c492c1e06232a4ee06842d393efbfbfb53e83edcc9cd09cbf45715f3183678b9cdfa0fde0767f3282225a7ebc079c34979970754fe31cb5d4bb276574692db260cb03c0033898eb285c9f80de7ee41b62dac2764a0890aac4b03344d524eee1e454ab10dddaa184a37be408c96675ab60e6132a0bd875e4a2cee04a8cd8150264da3cad1eade18fc844ac3d646938af3998aa1d931647c8a085c4d7eace76421f61c758770893d871b26443556b7cf27fb528ebd938883bfcbbd7b038d05bfc28f18905230f27630252714df369ae55b98d488fc792812ccbf8b4cec4b9f7d2311a27150e104bbc62139b08114e500117d56d72684e3e7ffca5a1adc903ff621a61295b30f4b99fba9c706aee725735c704b2fdef564ece9939f6ad3701abe3bc9c55642c58107c19bf7625071298c161d749af99bec60fabfdd60e90216c22e51e008ce0b0c2f158cf38660d7a9b470ce3d18851ed3fa2161b70b49ab047f1af704a9eb22fb10189116f4165d9df3ebf7ec3519c6224afe30fa423c95d1552432316a688f338c3da500891ce64179c24dc1f4dc8d9e8c8527985ba37be8121ebe161fcb9be4c4d33eead0871201d7054bd4fcbbeecc2a686da184c509fc4a3dee2fbb229b5f4d0bf4fbecad7812ca6786e6fc9cb069b794d0af441c31349e5e4e4808cf844e68dd7e9201e6ebc6351abae7bacbf147964cf0206d2e6f7684978bf1599a4ccc2a95667289810206f8ea7a798f1d63c4bc05acaed996d1dd13a7dc01db1fe1113f7fd6933f0be28bbc64d1623ecc75c251200b7d4b3f099f20079459e3c811199846c2e04334f1baf2b851d5b85397a417d3f912c5cbd79239e2a940fbe9187b121af2a271a0fd619fe11ca70da8875578c4cd5b4c43a1080785020d990116269a286a40b32e3c8ff23069f2458a7c98c840bd870bee9cfff318c058103d45af857b7013d86376c40285ce6ba9013630d1548c3df76de4041240db7f230a5476f49d20ac4874903aaec6615dc0eb9018409874521175c561583b3f09bdeac4225980e8a16cdf0a30b2b8a59efdc2acc81e388dd46ddc3a3f9ed18e7140e9b59209c364b131489fb2dd7d5876d4734d1e6c7606e012cb880a6b52fb8e74d388f4d19686e03a9c6a000683bb0e9d93d0cbd9dfd5ed4069740accac76145e4683bc4d0da24cff5d8e999645a7dea2460d7b334dae47a67980fae6127286cb6c62160c00d5c45655c002bc977c17e60e24d269091400a9a0286c8561dfc879fb890157f80e3828f8966481162b4b9522af29f45b4666c421bf60bcd10a1bf334cb1a6bcbd4cd3fe96ca9740302a1813a60568855ce0d49af63b038689d7d73dfa7b43449e0d23df684c10cd8d8f5195b8439f376519cbe039f1dc723506d1d95085a002f213d051d669ed403d4ddf215f44733fbb942c689f555796290c1eb1597b0e83d3c29c3b697e8c001e9c9f9dd280e6b0b266db9ff0fd02a2c1045fc97e60ac45bb2a048bda935b3ead285d3281c58db68540b8c7c09c406d090613bc65fddf1ef858e6850a457d65b3e62cf86119a5c88371b3ae529d55f09dae156735757b282083411e644c91cc8f7884521e8e0e53c7c751bb271a1427da22df2fe082d1a566f4387c199ae442a6f47ff489caed108dbd9c1946cf0d209e5e24865732666521d6c7ce41da45708ac98493260d93e6811c17d1d6240a9c363259f2c6875f03b23c22601b652ef61020065a2616eb05fc43e41bc44f3b62b4e1452902684cea9e7ee6a2c96449772af2888476dae4167f3790449db107f5a304afbbfc51847c0e93155344da5b07bccdacd91dc64f8d3c15e1644124bf709b24db72508bd107668f708a49c784047b20bb7ac09dca89d228b38562303bf91892de1374d08c1afe6fb6e450ac789767cc706b81f7ccecbc92f13a7a2d928eb4f27d36ae9b82a60958fe6e3d6c88c82a4ec9b8f48b848d7591b2a3c8e70a711d982488c66ed4314d64a94be3130a957b7ee3dac8b64f6f31374e2fe80cb46475f970ef7fa1f94247e285f8e278c2a9e786b5c8a8560087935d8fda225e2f49a6fe3e4dc3081050e5b8ffad814efd2a4df54617f9010d254ab37eab8e8960ba4ea49b9c3031a32899ac86e1e5d6da55fad3a2f0f4fdcd8bbc2f349609ec82f4ea875d0476a7288e83239d9cc961695a7008dcad5a92d09b03e3e358d31bfd355b58dcbb99376050ee169b87494063280412e5a458619804b9a04aee3eca07fe1c93a70555f594f34f4ecd01d6a2f0015e7ad80752d17709105e7a4972ce1c1f269c57beb271e3f1ce22467e9ec31e93981b993b6b649338f62b993551a8ba833be7598e77d137aeebca1c54d7b50cedf260312d56111194405d5aad7e4cdf08c5603c054e5235491364aa6b8d8eb02013339649784fba687faf7ddc84f5e47acc1b34930ca38a964d9b23fb8787268b1b48e8eba33dd9b236641091c695e9ba0597856c33a2f652eb9db010e00f6872d1d05ae86b2aabd7c520f7beffae843ff58f50daef662b047dd629fb3a3d1a48703c6f1555fb2d8c49dcc0eb452a65e5e131d4da778895af986cd27ed46ed2e90f448378dcc0827c533b7b14e3393301253dc1be176323820fde6e54d96e72c8779fdd15c2765aa8d2cd635bf21e87083e9ee76b82131f5f3e03cd500b397c240d5e363c3a5afbc7cbb27a8c0bfc23b63124f825839cc48bb54368023dc316689ef78359e6c086dbb4330acce28f30192aa66e30e16650f8aab08a319f3080afb0e4bb580439270e434438a804305255ae6f3b8981b3b8c2ab57aeac693dc63b42bc83ae6dc639f16112a4c7d9deaac6adc913ac5d4a591fb43f32112df83cf0fe849c8ff65f7afdf6fe697d65088071ddcc922d6633cc28d0c363a7ea6c8305ed6991885c8509207190234448baa270705a5a2b0e3581648f7346a5c6988b42dd59568116b13d3ad3244da4275a72444d4c8e96e29c4ea0ce926b510513470cbfc662530d58dba42402af5e033690885dedb270e4a5f501ec447c40a8a6f1dd025a2900d076947dd3a6c78e2a3f704411277e2787e1e038f3a7f4a267f64ca55bcd040274f5ffeed125e011413feec35a196a1eb0af94261aa50ba4db8381e1bca8be9f439c6c189ece18973f77070bf2a9368de35f45f971efefabd2d961dd4b601be969cf881e9484cf806e741f3da7cf3840ac56b1f2911b6954bb92aaa7c52eb1116145f62e09d8f78b7bf4b04eb2bf1e1364b3059feb0120fbc55cf49fe2921edce2a102afa12d90ac5198c36fba21afb10f6809f38ba0942b244c196620b4ce9ad685b2349f012b093edfda4e60fb07f899cd94ed0c939877c142299faa7bb2e0124e4b47f0aae31edccac30b99babf1dac961299e1e3bd71454d3f104c6d45ec03e682984e0cef92bb25d633d15e57282cf6124ad4b656a4ddcf4ca3f2a51880d38454678f213c4c8c4a6c45d51bc205a965a8923a8081a5aa97a2217c0ddae4b83b40b28b930a7abbfb70ded81f125d61009e3e76555fb0fe448de680d19ce8fb0a017a78d25908a76c7cef45412041be44113c1a746a7c28f680f91bbca13584b830c6f1873ea19e468980d7243f0f582be93404d13c9f0eccc89be85d29a870a24078442badafcbba90909530391b4107f271556148de34bdd516dc559b97a9e725160eb2ac993d8f76d53c5fd4788c3ccf6ccebef253f7f1fe2a4bc6ffeab5d26a6d38c0f48109240caf483325093f56cd9b060edf43eb437261b1648a62a036f275c88e80bd56bdd4ebb18f14e96e4eff9501e15364d9a0cb7635d92ad4939ad41ccc3a34ae226a39259df5f742139ebc52f8bbfe903023c6bd7a6c29fff280376ded9dfaf44d47e65a17384a7bca9022a5452abbf10778a5f762b032b280f6aebf4e733d5df9ed223d45f70c79df0d11bb1c6e4a4f9bf33858b600122faecac8590de847a1da2ec60d057800592d0a85de528a30173ba3cde45945216599ee498139dc38e7777a75c981d6bf665205eb5595d0ff8dcd999658c1c38bef7f5be028ad085382878f9b7ae086616111c16c99476848a68c0b088f72af407ae773bf9f8f16ed78eb631eaee87e60617aebaf88ff75ce82db1429b2f4f6836e34d01a1df5ab7b8b652692da1a59113710674e82f3b8b1f1af734bf6a84b82f48520ddceac576bfebb346476fbd69f9831bc8f6fe8cbd820fce048888f5efb4f4ab399ca442022c722bccec2e0b34595f8c554347581414481397e0e565f7daf4ee68741f433d6ce30bc898a601c63c8ae63c319e457278f6e6c15ecaf3695798da5da65ea95f38e2a5d6be9d8276d83681ffbb7a288828aa4c7b313ffb5f12b385cb8fbae2ddbfab2de7c2ce3de015860268cbc1fe3e4da6e7d37ab17cf7f94044c56b70b89ff789ff8049ca883f2aedb9621f24ce74990aaf32b0bc4b46264c06042805f7f86f86d06346626522422db47d268fa840c22e412810dfb8831e3180342711d5671138c800b76848ca8db1cb4b00f3a6932c058b63690a1a9bd2f4a753536a1b19de2827e47e589a827bf2033fb886755f1a0422a5977ed686cb7589c83f39448603fff6dee9f8a5d077161732f2660a5da9dd3a4d71ed551cdecc8838251e455abf493c68b89270c66028860080c0436c6f345e7bdf33dca094c244ee885ac2d6d5c31de5aa4e1f947600be7b35d4a2f137afd088fa84411aef2df49d4f9bdd94f7f37757eb6612209afe62c802678f0dc52b122a30bc744d8df46918e535559af75bf63f47e2c8a7668c8ec66b00fcae92114e3357304ab18a13151579da7fb6b55dddde8faf9fb4799516a99e10c7578a5c30b6e88f8af80271c619b4bd994ae2918bac92fe8e373201d620b8159801aedf83a81eb858db35506ec9cd8f2b586ec7bec255ac752bf5f2a7e1cb959f7163bb7f95dde2a944f0ad3bdcf881c18b5c790e1086f05d678f0e18582e1dd3d0d6d7f886e13b77c01a30fa234453dd6ed6f388899d9dda905fc78122343b6d3c35c63a0af111fd97c2d43ddf0a5d161b719a9b4a6115f5f526e99e16e8c3e8de68212a45c01a5bfc236cc808b2dce2b03cff99e55874cfb7fe308ee18c5354d74add21ebea2e0d16726560ce8cdaf1558aef5aaf7ced629d4733cec21459e18a91ee6fdf24d6913d08d888f2c559661d59cc365922bacb20c424d34d64d9e6a3e45eb5718788bb40cab4ee91a2c691436db5b1b97228f12333b42b1b117861d663b5a3fbd33b970502938b8d05a462332aff6cd16e5a00607d66e0085b639bb42efec6a80f199f69bf70862a50a886c744292d44f0a10c3a680b8cd8b7c4eeec11b1adfada0ea61d0ae1455dbd991278ed6158f649b0e08ddc7c5953b2df620d6c8bff58673448986ca4b0447df4f4b8fd523d000414ec5f3a74d9438773dcc5508695859c5ba8a118defe46142d8529ee471cdf65b64c31e73b232ebcd48f024ff73c5581266ccd47c490ac8fb59ea36089186d6b8889309e7ca31dbf8c9828bcb9bb93dd768737378fb55af07ada1b7892cc2d03ce6e4a9ee35ab91bb5aa5499863cf59ea031e41a0eee168b471f25d2fa5e5c0dba0fbaac0173864c3794630ccefc5731671e6c022e66a40c206ed5b55b31aca0b5963fd3348b586798e5bd5ca944b4b76fb6c54be8dd405777c6d94a6d2e35d195c02315420e7b0354c1256a6cfed21a2e7261838f7b4646217b5cd8c861a5dcce76e4493eb144647ded2ddf821f0e0fd040ee13e3ee7d2678b5d43ef7b7c452988883ae8f7fed70bcf00999d0b12140cda6ef61077ffefdb7bb012c6952cb491f10c7ae6fbfdb473f11d3db2c8cf970f52335f8dcd84472deb50e4defe2fde6e7ff96ce6b4f71c8ec783063a52627ee36489e69f6593361b01e0390f942bb0e7add0b26552e3355074b5b7160518ab66f21c19e22c54577da7b92f6609ba16a16bfd24cd1a4b5da436d9ea13d59681fe39c8d44c8b7a3656db70c87c3c2be877a605e7df5ec61bed3640f7ddcb976c5001ef0f224d1f58321bd264544cb140ea40b04587cbaaa7c2259fc4766bb0a66c8a9745300980c6e4914b9c9c9592b8b11451cf532c166c0176c766c99a8c53caab98f77a7842317c9106d2d111a00c7580bcc04c996e3030c00955a25fc1323edfab91d84bb1210553c9c232e9216c8579188d6923b67322c2a4351008380d295a2fdc685795346725d8d765b49f1a2b8abd53e015e7009e3d76a15e1486d7000df65dc9272b037df73280c5db27e276ca9b289c83359d9f9f91662bd84143c0abb620f2afb719131196e526abdb156716cd6e4094226e2719b477a53fe1169f4cb5521c52720d577aa8e7dcd2d7cf99d7f07d5c16cb9e157caf6357e09b719beaea0e7ad525a9ed0e040e0471bdbddc06f603417e9a7c9b3ba89d29152e439b16801e7f52d7e4700c08866ab9b109014955cff16e8d68ecc8cef0a53281cabec7d283129ef20e4c747ebacc7cb7a77a329e292ca3b848585848fef40fdfcfc68972f39021d4dc01d5475a374f0335be19ef7214e1059695f4e1b0f2f3926074dac489e5c4e7c7427ce845dde587a2dcecf6602bb4ba72df2aa5b50f1e3fa01b685e946327e8b98b04184d8deab0681208c7d85bf708ced936505a5fd4de5b944333e1ebba600a6649f44265e43187f8808921bcd3202c334389cf1603fac1f87bde986c0bb7e37c00bca201eb91cba46e5fda23fe0a209b7ae61ae104f8b3ab1604cc4fade60bbd3a0e83f5037b45eeb6155dcf560b0b96f7187740c06f89c1ada0cc70970e8917653f8bee595bfe06382ab227c4f58e71ca4618459c9a373b65595424d3a816d34f73b5bba7d7c2d336d276e111763e3fa526b1abfbb2faec4984f1d3b0cb78e41af1b818da8454170c3340ec336abf52fa19559c9f3ba9a43c2d825b1036f39316a4802eeef27d54a6baeeebe4726a57052e8e943558656a9cbb1e7d16409cdbec4102d31ec9e2a6b6387efac601e34ecac989913809c2a634d1837af2f092e04c8d158b3606b54752edd9e3b41626ea541d17bfa1eeaa59454f24b3e95594ddf65691081028539207764a40143df5c3abe573ee2865b7a41795113003ec31d531ded76fd67e826f9e35d3fa3b29af1e276a68f2f0dbe5c02ee48b7b8efb603e0a7f626060af541d7f501679c5d018c9d1b4b23da885d8e47816e98f83b3fd306f709f3db5d7b96077f5ac21ecbc4d41ee55a87a19e7db1d0d15fd4ee4adce9963c3e70ff910e4a7ae0e8d6c88bc2d391ea836cfc00aa70beb36525deef65f3bedba7b996b74f1da1c156f119322eebb4043006efec1b1a918aaf27089e61179cee574574c311bfa4f5c54c26ce187ada0988cb18aa6f1bf91c94f02b8e65ff455742b950885c7e2f53ba110f051926f85e04a978b205506528a1d21ab444045aef03c8592092b292742ca671ba88b7d66d18cfcefbd39eb16ae95d9595be995e4b7fff77c7fdfddfc1131a3643eea235442994dc54410520c4164d18fc7be17210f1eef3f74f3fad8b7493d6e85891ad6d23ad114208d964efbde5de01160d6a0c230cd8df8a4a29fa654abf2c32fd2ae2e458fa48abf0b673b7c77e1f667f8743eddaa78aef92a8e2bbff8061d4be9369da3b1ce2308d4c167d2843af28a8c9f7c8ac041581c88cfb7234d54e9c2cd54e349a737eb7e93cd45d7db061f7249637897df697335966d84c9c8955b231f7f923dd35ec837dacecf43b9d897d15835cec71227de1b55659955d7b04b10cab6ad87efa11d335eca3ddf413f6b1b2a3dd845519761fd337acca708fcc118c2076f9c53bf615761bec39d8753013d6705cf56a0d6f621f2bf63ef3dc1bfbf4bbcbb7565865f14ebfc32a3b3f95c5aa1ab8cfef74ef739faa1ae6b9eff4bbee4b4d1676ee8b9355bb6040bdfa6c260b7bf6ad7a855dfb30217a15b4ca1850c61e6b30cc2385ec6d264e8331469c2befc9ae1ec18bb973ccb7752f56d190629d6b93a3a2f73bd9bd86c3636fb2ec43eb4520f4a80884be5974f6a0851c5f466064981c5f51fcc028c70fb24c31821717ae289430d262f49b7748e5f9716a78d3ebd348a36c431188a0051a4d0c4901827544185ce21002106578f922e7200a920ac628c2082a201125c890a28b163368020ab085c0230ca3276a8006192678033422c41157bc0c6189288040e9451ec11a694041831ff8e08b27a0068010841b6b9880042d5842fe3c6184114926e0620955dc00bc000d6c30841a50cad8e28d1bd945eca20233c608dad2841857c0b6c096232cc1842c5e00d404d85c64229660043184b0441366800d84082ee092a4c6101426e416b90d2db8604328ca9313c001760d295842162788a0850a1b60cb2db98de8115bec47d52a0291cf968440024d649cc008440114475b93600c2530c4bae0200964125f3298c11721360490494c0dc089effc2216335c5005dc2a37bfa8450b78a00402a18c2790c00de3e6274df0839011d89fcd1570bb588b2d8a2802fba381029a9184173f67341e62f480470f9890d27ee0427e55c4162b166cb1a61500a32cbc1af419a3496bf801679226ab2593349354c30f38a33459712649ce57234040a767ef543b13d47e353cd35ddcba5e13af158089a33af22c054b60865546543bafc1c208cc700c40958913c1d4fdc16bcd24190d4d1c1f411327366ea5e467b44c1ceff233471307e6f233481367bbfc8c6be24c507e26684668e24470c695e56592647ec0d695499a600d1646a096ddfbba9b2688f226d801653fa98c7057d910414e754482db25b861b1a228cf28cd24f54dc462c550969fe132b33404f54d763ba69f64d7fdd3673a793fed989ee150bbc974edb39265dfb42fb4d2b762a4c3a10473e4b8f659e9a3700873ed3bdd73e010f5ee1bcc37a334b33459f2a66fc6cb64c97b5fca3559d204f3a1be79fa22987d11ec660c3242b931f78556b6670fb99fbe659f6a9e3ed5c4d93becd33dfb09fb8456763a7a53ec62a0a2618a7d0481928aa6c910c9204d1caf6794264bbe9b49ea95bc4c912a004301180a4095001005a0289b499a499a519a59929ff122cf833bc29311caad785497e0b56692fa05de73eb4959fe0ef8a284862be80738a2442fa44411832b4e30c69012281f25144fa703b0fddc3e0de11283479313cc302135042c3789060737c89de5182959d4e505e96a2f5e4f1091a91255bccc2a22a71c7fca5442d05f423315d7bc676462d51114be807d090671609f9874cb2327ce78bd9898f262e28aebc584d052521b1efdaca90640b269dd1c3f310f84bce4beec0f60999a717f765cb87c356f939b5c82e8d7887974885708e5897738917885508e38ca16e49c5f640b546cb588993471640751907e7e3b1e483fe7a4424c9618b1892d4d78c9ad9b9bc8d2c411b8d0249ef822c627a808c2174b1c392183dcbad909a01c7f737c3931841351724c129ad2d3cb9fcc75d4699c383b95fd071474c1fb8c498eaf5ff63dc90131a0273080d88328783f3b95c546b0c7bce381b78b5cafc42657dc73ca54ee5b3f797ebaf2c53e8b65b25c148b570eaafcb584117d2d51d4b2718ffc22230d36c9061d224fb94a69a414cb2c53ac22d2a2997299621db89cd281cb353fd99b2b906d784f70b56fea9053a633ab5443b03c2f73671591ce1377042267ce376f3d6977b794b2bb63777b268ac4bded5d9a948b7e32de1b090717573f705822a86609d711652871854aeea6bc37654c72b95c4168e479ea9520cfc7dc608c3c4f335f444ce489145f4a8c8086e6eea68d1278fb0aef95518aa1200e28344bdfd07c299dd2098f07b91fd32f1b0c91db8a097237e7e140fe10242f9d739584112847b5ccb6f6bb3639945a7bf2ea6fc4e91aeb65c5b77f2893ee36436701bd92538a00851b43502103252011840435a4b862892625c832840bea10439a4e4a051643e2624b504cca3d628b31015b34001088000417003d31a58aba82388c9090c0650b14f60a4f9e46d4eb89245e4f440124b164f29a74f9a08473e5f936ea2e94f652df348e4d6a2d2ddff22ddff22ddff29dc61b4da37cc5af2c1fb344527f8f587c272bceaf1595b28cde125b9459c61738578e3f70e89b56aab3a59c7918e617302f43e344a37923f33b48fa26be908822cf6380762a668a3cbfa2f53d12ab88d0ffe439ffc30518e617307f7b1ab96aa6508c31c6186394b88b40ba64238a86783dc125c7a228454007da3aaff050952e2dfb467533f7556d818704871cea93a8acfc8c70c0407d0e8d0300b03e49fd92c68947f5613de57a099444aeb5b65ce52a45aedf56130787c9aa48d54b45a4d75a8f903411b57e556f539f53af53c1f024f6ec18f6b9c79e611fed59760d5fd50ef6fe307c27ab1babc1a6e44b6ec696b2cd423148d53285a69419a5936e548f706dc28befa489736f27a53a69f5d529befa922df437aa63a80644134b83e6287d73ca3700c8fd39949471a851dfc4570d9072bf66e91b493b243a93851dc9992cacb7d92169249b7bb13bd24793d55fa976b4d491d56461473e59d8ef2b568d1a2787966a45dff4eb51e30000ec57a42bb95fc16836c07ee5d237f1550589dcaf4a358da5eaa5a79d8f37bbf603ca0cdf552b65d32b2cd52bec56edb322ed0fb829152125cddfc9aa92d392415d8da82b4868e2fc809256a9456d54916a5255c2b460476d84256148554b35f266359ad5c8a82e19f5aa8572cfa19aa557461148bf5ef1e467ab1ae53eb68442020039beaae080ca080eb023a68d01a8a0f56d6200b0b2d9bc4489a93c1aacbb6f0d95a0dc8a4631507982a5ba3d2a401e15277d9bec8838726b75c406d6d8105ae44681ddd8a5930b94d44173313455e4568d91edc151aa870655a420430b31ac2803eca035a65c31c55015284e80bd832c5815d8b5980ed868274c482401832684a004294643007bca192888f28415407091040eb04e620649180d6db1a665b35dfb867f84d0509665d97ff2bdd9bd73894d75249467102d91f90615a604869812b83dbbccb1a66573535fb15e4610e5558eaf2943f975842bc7971146b9e5bd8c38caa878034e912267e20b316949be004e2142b610734b47116cd20dab6288f9fe27c7af7573c4b0d71429761e9b723a41a3ec4939131376abd24411af26544029ad59e6e5d54490b516d3b42b60bcaea471efcdb62d4bdd22b9d79525bad7152a39c6c4c9ef75650527aeeb3ad3e974c565737c5d11f25e4cac81e2727c3161060c8742a160b80803c3c41626b8508d8dcd9b928b31c63805ed9b08c56321c72c6244c9b15e0cc8bb9c6c42ca7e41125cb688d94a678b52540c924571bda28f315956f07ac1952a625240848a2280c46041166994e08948842648b8d6d0d2c69333ba0a0c8cb4c0872b8c10842014a0e007104a526e00051a558e9c78a38260285a1ba80165896bf5d2dbd033b24c575aa5f7d2148da1a92e99faaadea63ea7d62fa071aecbe5720151299d73ce399bd65a677d6ad65c6badb5d61b11a325954da4851b34f801ca0b869630d4c40f146f601145880a26aa28a2911882618b121738b072041c4c818512cc38021329b8e275c69530b010782deee68e41b5ddd5f37254a1821ea4808dd7118c702399c8f4296a413a440a315420e50625d0a208a438e6c876f7ff821ae47e4dce737cbd60042f685284cd8d6e94d18411ac208c3674b0455c830b127ca00110406148b1c416b78606c16bd5502a6d88a04fd164fad58c96ae4611411368e00408405cf800c4029c0c95218490124b582881a5768a52155c2a43bc9c479fa2ff0f0b9456a0440f809074032c407a9b898373c611161d10c9a0cb0e404a140596298d1307031db9442e17033950239ef7644ec95ddab469379d3d1b06793bc9ccf5ca4a69b15bb3df2a8f555ba5905a8f559da514fbc9c5d8b7ace52c8d89f1628e99b1668aaf4bc62857ca5d34bc16955cfdb8cae9b48c119531ca4f6cb1669352dee730711a44c00a5625b87c928ac363c384841caf01896392acbe8faf8941b02954c8f19ec49143de9b0b99fa90944352e6ec5812c429b2fd6b07b93ebe643787a4919090a6c8548a5ce314b97ea398a5f4bb7165af7d5c5cd96f3a7de3c5554c161d3c3ae627a754c1724867e2783bd89f2df656e756dc622df065facdce963556d3959adca04859a3bc94974970dae34d7d4480f618e5a5c8fbeb79292d292da91f4c86c691571c19d9914782833c061ac7d3413ec9122959ba302bbb8865142965b284a44b3ef58a578f612ffea06fd1a25e9aae5e9a38d9ed2750e3d8379a656f336c95ee8f1f35354d9369ac9d47d9de7a11b24a6da4d2a2d1512375522b655fb8ddc787ec1bdec2ec5b0d11cc700f6117c09e16b5500bb5941eea2a4dd44549494a4b5edad541444445465a8e90b8265ecb2a65fb162dcaf6d22583a49094228764951844c6b8b2925d9a383fa07df6fd80d68b3de6c282260e05ed31a1184466dacf6c148a9032eb2ccbb22ccbb26ddbb62894d8826d7d7ab7b07d7abdd457aadcaf4598baa0255802d2143279d19cdc6cb26ff3fbe64d9f5e2ff5154d0eb6c9db2a6f9f77d3302797202fc6b0c5b1628a5babdcdd3994db648e9994a3e8157d16a35ed1268ab1d6cfeea25ed1bed22b3a3f9b4420f4f39b3ec8166813af35898866d1349a5ae6d144eaa33e6aa424a5252fb509af3fa72b02a19f6f4dd7d292977675500bb514232d4748494a52488a1c9255888a7a08871c9280412d9b4c6d7274643082846be251fad6bcde2a0619aad244b38bda68b6961844cea4ab844d09768f611fecf71af68b55f1d68b738c60ef86c4203312ec27b30c13a7414b29ae4a783463d866b262d26cc166bff170f39cdce35bf2058973640bf6f65a0cd2384804621f9f5d9c63c4ddbb799e964a65b7d8e224992c9b86572b9137313581574f53bdaa41e6cc37bc56ce0b5a833e5edfd5827ec0165ee496cd023c1b840c0417bccb831e52e8e0654e48c0b34409f06e1519bc3bb4da820504388102b618c1095b00f1f0ee1b3978d81a1cf0608890e34504b240e2693ef8a4608077737c6d7902cbf1b585684b952d3ed82f52322173c24b19399a702199aeb8ace09c08d2c1e94ad1121b13432e9869c2e8158412744b04c13871a445139658ba9ed4a20c1dd2051b9b9c25b4342b5ea90592c963e2a859f16a71f4d2a24a1c589c5957200a2b05f05439bea240812a8a2630789e122ee09dc8d080c7e5f882820b1bbc1c39bea0c0027aa61c5f503401c48bc9f105450c6cb418ea2cc0d04109b2404a6243da929774ceb1e9983326070caadb9bf334e79c73ce394db935e79c1db775b796cabafb6273ce39bb71c4b66b77d3796f2a556bcda194b6f46ed411930306e59d4c1db769998c294620f13f84b035b5a89bc94a0f827a985ca3fc66965ab7d159cf71f25342f3929a6fafe4a722825b9e0b2b55fc4f8e8fd1b2ade34c374e968a887c7f4e9de9420442d3f3fbf2e69d3a21aa483f19b1918a63de894620c5291db966177aca38abe9cbdd4cfa677696c6764d89af2290ac6fada9d4bdf10d406146bbcd39a5774a4d56bcfd72229048692bc6ce14162bed960bd96b25e81a9e7cd4887a528bdd8cfbc43975d2fb641015e9da382ecf2473db30aeab3451bfb62a35db6e842131128fb2adab18699d8466b4655bed2a465a173591d64618c3b239aee3bc1844cb9da5b364a145f0de5d13e7c52059d6d2422dd447f49418e3acd9a6b5d014aca360536a0b4dc186a460536addb4ac85a6604352b02926ced409d96ee24e5ccb855c02eef1395e74c4175a888879b9f20d19198c99bcb410b783da755b8893c75ded743a79494a6c60495d7472727292ba70e9c225755952ead269a62ca9cb92529793a79db8532784fe6442710b681ca965b2fa56e4782d5b60d0391d0c9bf802c41724182ec420264934591b2abe20b378ab9fd6ef621f074617634507860e9e9ce9c8d937d9651533512d128c4e22c9a34e82618153f6cd33e1d861ad13927ddb348e28cb15198ddb88b2181565c99d61140a05c3b5910d72bfc5423e7915474af90f1b1758f10599c4e3bdcf6b1bdcaf669d94d237a8b8d241844c2b774474701d912fd7d6d256749d45cac441455612df0e392493c84de493190ce7c520a6ec62da668a7de46304477859f86056ecbdaa69d664b57ee4f945ab1aab6eb8f41af6b9a7f7de53ac6a55cff9791ce673984f32af95d795259948e8e79cf394da7401e6ef97335973568a53b30caf25916c3a044ab18002233d9963822c0f838e0c46fa86e686ce1c74381242965b96524a296d64163ac85293974592465e224930683c2a42ce4eb33fbb58400cc38e58908af400b9628194eb1360ad150b177c00f4c88a23b8b0e20d24206ce1e20a24f29cc11540c83054c1459eb30bd8dd3229df202e0aae644a4f6f77a54859450b54991ebb4273520144032aace43432bd4d9580522d320840a62f2d4799fe00fc410b324523d3d74e087d55c1ab08999ebe407ace8ba179cdea47dffcc814cb19993ec9f43930e82c60062359dac8f43b3c00e92980854aa6f43a2891e997f44d97e90bcb0e327dd8373f5c3c8802a86f7a042d659a458d4c2fa334bd24e2c5032f32ddf2ea81954ce3174441395291e9cb075a647ad44313410873a0f79a41ee4faf5320a54920c4ddeb01600a3872f7f5b61adcfbf4b1cfcfc7ca4e1fc3a9c9a2f7b98f93d543929ab71be6b11fc9b06f98116dda0cabac668304b3ebb436b30ddbb06cb6765745f05a291b220804a43dbb3dd5322f2dc5b3f9119528d8d376b141e007a48f35cff20b62ca9225802c5b06f05aff4a3e4747062313673bf7ad264905cae7c8c320bf007919669047323b0a49295e46c0352b72114813bc7823da55aa23b30b98c5898aaab9e3254e2366ac7ed8e4c0d0385f401aa82c3f0318b3630f378c2c7b2699f6f51e03fa713d2082f43addc3b79a2c79eccbf964d03e2b5dbd922b29b39fd997898d52492556dd80bd56ec15c32a23f6530d50b533d500b157ac928fe0c52a499fc41ebbec6c90e0bdcb4a8cdeebf4e6ca2106893528ababaad305a0c73e19e6876455f16ab2e8a792d78a4a3ae49024764f4d9cbe6c9a842dc6df782f3e151ff3166b368de6abc9aa666c41b0acbd3eceed9bbf3fd2fd9bdd54aed8f6ee4736ee1d877d38ac56f92555fffa55bd8d86579355536b78f7f34eb2f755462656619f8d5518a64064d909511999efaf83eee777ee67387f8fe19dec19bd0abb9f0a5bf2c9aac7be96e2853da46217571542dca80e497a5092ae1c62902dcf63ef0153c26ee2aefdc876d3760dabe88655b6fbf347b6b9dd673e7a39704926cee947ba73dd4f1d7e771356d9d42ad5610ef79024077a9ff9de2e77b8e31d0d639bc9c2ae7da3365992a82acec10a2dbdc29e85a3f2850eca71be7fc3c4aafbf9ed8d55d90d1a565dacbadf99dfbed3d7ded7ae23c3646118f61c92f440e50b588eb1535d5cc3fcf61be637ec37f4358c64b2b0ebf4d13dda624dab85224eabcbd10899d688333b8b75268bdef60082202c9a68492199383ab375aaab7a6c95e9500442631059f4f494e9cd928e66cca7b2885efb7a982c1a945d6c04fa6b54c4a3bae1c9a7ee27ce9cdd7d9fecf311a436c9763f95922232775003750165919daf49229545f4b78725b2e87ab32f0eb658336fbf1dfb114d3b867dacecd86bf7c1be3d82d108865d75647601ad9c487a452f64a75742a6ec19223312690448d228ed2ff6a9e65515ab6ac09efd88fdc53ed8de273b483f6fb2e8ed67f35dfb45b0a5783ae01c7a45b9c425ea02bb7913877ad49e7ef3cb99ac55b638586bbf8a417a3ee565c95abb5ac3435de6dd1d7527309741615595c1aa5a1f4e9dc6be982b4c6d4a851727eb399365adf5b152ef03f3ee3e32476119e6dd7760b00a3bcce9bb57bc2383551856d50083613e0f83e344fda23e1586194163904c0b6164bee19dee216ae6da273396b5af8dc0a03421303038b4a23da4efaee1701ee63a8dc97c36aa8b57587b40683015f51f70877b77d477baa37068257be8c11c75140e4f87f90fd840645b966d2a0d1be96e43043bec6325bb0f7d07837de651aa1ae861be430f8355da611ec19d7995865535cc1ce647660e837dacecc05ce63e393ef323328f790cf681b9cc23783f0d88bca98ce4c871d591d9058439cc35254564eea157f64296f44a9bb9cc751ae653ddc73c82393ed5c5aa1a725cc78fc03c06fbc41ce63ab08f959d98c3dc47c7733c82323130333a7280325f04757c11cccff0ce3cea3a6d6d26cbfef4e94c9611d367bfeaacb5aa1ae8bbefd07758751fc13877e65517db473035592b7b1bfb1c7b1dfbd81901a296fbb17d8a62e3c1dd06072123b934d4472ea2992464449786ea918bc8260919614b43f7c84594250919694b43db918b884b1232ea96864c472ea253929091b734843a7211c1240919e5581a8a397211e9489211f2f242baf242ca2273f7cd8134b22207298cb20483522acfd1251d58a1832c5210e5bca4a892e55de85446b6db10c16d6b19c9f3f4dbbe4f96dd81961ccfc8f1a50330a6098c649b184cb309de71c8617296f2a84ebcf8786eb3b8e57531f495bcfa984a5dde26474706ce7ed7c166dbb0db1b865676380e87dce3643159caeced75664f489463042bd83d33eb60931bdfb86475b02969179188f34519629054ceb4d31b3ff0a2cc9d29bee33bbe7f8a8fb16d6051df78e24f119ba87c77938a7d648aa50a368aadd4925bca6e866e4eca198af4ef8d50944d9798677b77ed6bf54fb8a5fdf4ed743a994ea779e64d72261a3c573ed1205df9f4f3703f71b862bf91a24c98ebf3dc6b6fddc7ae95ddd4cdf09666327531d4fb38bb22da4d11c8fc290299ae4c6d168fba9ae4d337d34fdebd7353c9129b39259c777a67d3bdaf07857c3af7f524e074c231fe3051aebf9676ee527643221843703e5d7644640c9ae413eeee6b71dfb8ef3cf2315f0c7bbdb218e78a6364f64c120b227677636facb1969f1289b908047b0c31371a160ddac52042b818047bacc1c6d8fa14b7b81de21522c094c21d2297dc3e49b4d6e5d141cb1ade41cbfd9fbcd5eed7dafdfbfe5ab640bf51d9fd222d9ddcdfb2fa2ac395639c2237a6b49ec63e62abaf9708dda86d9d292d0f32db8a2de6b19f4b32fdc6256f9fb9f37619af10ca1ba69437dcb2857a9bab51b65075e0a4e5b138126c9bacd94b5b85279fea55c49e7df7b2ebb917477a31d72b29c646a412a9aff562d7e97b7beb9d3d31cf3cbddffc3eb1cb6ff6c52decf2f393b36dc7f0daeb0f3b86f12082439e3fee75fabe859d67ce244d030ef9de39afd3f513dfebcc63f6d423e98f95f58ccd00db7622626fbbd85de39e5d8bf952bdda789099bbfd626c6a92f81148e4308fbdf4ae7142a24579bdd26e93b9cb4e88fc5a32f3d854cc1681c41c9f7d5eaf6ec624a6bd8a3f71afa7397642ac166fbe53567e97da330db768d666b738dcd2de3d5c9e72be67e6793b8637dfb37b680bc32c642019fb687a15e56d109b14421f69a0dfb6dbbdd23e9fd2b60db7e4273fb9cb2ef62ae3be25b3a39ca6d58fd9ab16f629257613b0a40ae97ba345ad6afe5ed978c975af59d1fcb03df0624465691464646478a8687aec9091c19e78f23dd4e58a57b42b26d5220b06c625ca17a492942f50d70b51b610e190ac298f5b4c72af915b3f9952dc6acc437b1e8a83b93978a0272c4374c93cc464f979aec559383c79ac13d2238958578e606429a5bc534ada52da9549feb68cad3ed6d47a1fb95533104f631997b7d8c664aa43116a9017620aaf25852842a60fe3bdc9a23f28e5837280f1404f1ac41e8480200480a1951df9503eb4b283dde25007875676ec250e8fa94dbe107de3a39b16b14599222c659a1c5f45d0226fa758637c6b56dc33b1acb5c52463b6628be7a572bfed10af106a6bf10e914bdde100404699622a3e4c708c3de4796f68a18b17954bc5d5830446441972b50f93c805cc1edf32a93074032d2e9a2472c9545c2d74f172d90300195d57bc4248f321720133ec8a5cc0782a2e992128f183192e1718b10f93b792eca0c618c2117100b95c606c408edab606647821434a8e305d62a4f8f6b00d919bbde2cd951783ad67ec18f09329fd9152c83644e6fc23650a50c8aa2a52e9abacb4ca8a7948506dadd65a6babadf2f5e391983b820717985c669ce127f344dcc3244fa3795f6f3f9e7bfbf9a98a4c9efbf998e7e5b7b5bd4edb2ab12fa9d8a57dd74b21d2a875df98878acd5fcc5a4ae71a5bec1b2ae7a72a2279eafb53d2d323db2fa9b91f63af785cdff460f962a76f5559310f6d148cd125c7d7185572eb94e959c8f13546517decd5fcedf9c9cce35155f1e5e18ef07a98e496344b9494ebcf4f9e794bc516ad91b79dc800ca3d4f56891e26991e035bec2de64837ae6f5445e6972f799e6749e70df0a0e579d924f7c853fab0c5a6dfa8941ad89afbb6a4a5d5ca66bec240939494e7635a97a78f63a362af62af38daa7b84ad937548c2d1df7c52686962a99364ecce2dade37d6c4ddc4d9739cc9647ad7d16b2653f78c93f49ca53c14f320bb22f4316fb31b626ffaf6a988b46c0cdc6304224d9f4ad3de9d7634d05fa7c528da708be66d360f379b6ec2d474eee3e1666e7b8c4138dce2ae43903c3713ee99d95e88fdb4318bcb87bc9d620cf24b6b7bfd9169f2d61581d4635fab2f3359e3d83e719c9ceebddf09762732b74efa4e76dce464de0914f994931d3884f9e47127287c73e2e1d09b7732f31d77228343999f4edf81fae9bbcc43191ca26abee3a1ccb99fee64e2f0de6313871743910fef4f38ea9d93ee6f3b70888fa5701f6fec3b1ef677e0b0d67b38d4ee3ddcf1ed4ee879e03026e630389cffb687df371ccef970bbea393cef1c0e6bbd86c389c31ed7eecd7b0fb97b38ac391ed6b3aec243ef2ae03026e63a70a8e318f613701873c275603aaec243ec2ae0f0846c9ef030abc15056397098e33a745c9543870efc1434ed27f4d0b44dcb3e1d3b6450d3c33ad364e6dd74d4d357b9be3b50a7be1fe64d4fc3746c9593d92173bf13aa6a5936370fd381e23c998cdb81c2fab676faaa8e5975ec98d7c70aded6a76f3b0b2815341f3e72ecd866c6623decb358998c0cfecabb5f712bacf050fb0a2b7c18763a3e8bd3ceaaabd5c3ef2b1fab7bd2e11d7f851da8af70161eca9c0516ebe176960aacb3f030ab3e7c6cdff15755c757edc3878f151e625f01873e7ca0e6595041851e0fb9f7c88ecf3ae13d529061e1ac873bce5aad00701570b87a0a2a9cf5507b0a0f3d5cf31c397ac7f17df4e8f1144e38e1aaf748e13d1ea2dee3dec77f3c3cfd87b4a1390b0f4f6741d63c0516fee3a1cc537878cf5ad1d0e0d3b04ef3f03b8d7cb89de62aa8544f21ecf114ae3ae1aa87dc55f261bd0a5f3df4be9200f0f110bb0f1c02c0c7310e01f0134ef8eae13c7e98fd070e5758e1353854e150f51c394e83431e3caec221cd73e4b8eaa18eab70c843751e0f39ac1359f2356721050ee63d70c803873cdee31c77fc503bc6214c0ac70f379c24b2e461cec2430df71059f22ce070050c45b2b6ab80434d7b0c0e63bea9f0ed6186916c38d4b6d3e0503b979d7bf8612391254ff350079621b2e45738f4a1e300c021c621be0adf6b7098c28f7118cf006282155f5ea0060a82c02f0b20a260e1461286709205e8e4bbce0e7c3f1c1e5f06a3804fe8b1e3343854a5ce03873f503081c611d211485c0105b8e3c7053e08e1042f2f9880040370c743144eedc0610aaf4e7806cb3c9c3887c89297c1a10e0c45824e508fc1e1e93930141bd0c9fc31820a1c548cf0d2e5084a0067fc628989199cc0055e5e4c009dcc9f1e7a3827b2e44f3834e11c0cdbc454631c224b4259814eec351cc2f0441448b84197202cd500cc3094834e5098828d26a410c21337d0009df4b18717af62687158f1b177262c0904095bb42cf0b42d5a233ccdca604ab430f062a7c3ca600851e4d6cd318611e41586143b64671046508eaf2fae642e727c7d91453ebebcb0f52d7b3f3b034f66d918b69bfc36656c1377b395b6b3ef6e899ce127dbcbae4708112fdb6b97cc8cbdd56ab56c0e495633fb7ac2164d9e9686faf5cc4c55f0c59435bcf8fa224a8ef32f2144c9fd9814841181444eca60f3e2a828c76721c01669c81b534a6c4be8c249115e284109423060e1045558c1020711e02012830a18542aa674544441c5cba690486083801c6e08810a2739b06e2aa4603f80e3cea02343174878c10f8ee6107e1084ee07493da0205d0992224492165bacf4200c25d208e3cb129ad0e9020c36395d18e1d5450fba882288edf64d8c2b98b6767bdddd8f40e4cd280f0f335301413d8fac234785a944ab18332d25391a31ac2d0f9d95d02f99d8656c818695c8c4b01ae5a4f406ed1733d1b40751190500ca6e87821a7ef2c309bc6ff0624abb4822e39a782d1a1434715446327b2a44958837b4495c49a143b40a25a24057b2bd2adceedd8608a6420fdbff80de51b72182281c7ab8e5796fd9543082a8dbcb1b992cabc48608ca1066f888a3e2ed6ccfbe612b3bf4a58a622340dbad18d1702841d34fff01b7ec5b967d7bd65d82ddb3d3a218c42ed599c6ec329766d2549a5c7a6531204c082c0873d9377a652fc54104623f3f9a03d9423d4644dfb46851a6c7a4f44d370e0a7d13b3bded626fbd348eca1e03b2c784e89bf88ac113d9da6351a2c8f6d890ad9416d953a34c4ab6f65826a56fe2ab8b20b27d4644dfa090ed378ceb84b8543bda8f488ed33a21744bafecc140ea95a55a62a455d277a547bdb2d4eb23f94263ab245bd0220691d89ed119c9ae7d3fa0c4996bb2ec65f622895c9f7d59102daa55888aaa51d5625f8f6c9295f677c9fe7ac98482b2cd5cd91e1bc3b34ada617e64db0e837d72982c7b9fed1a0ebdb211b456c97ac9b05deaac12eadefb28ac921e5649895519ba967d422af90d932235cc3559f61ab64b9365b1a06cad976cad1276c2f898c371686a9943b3ca249a4546f4d2d9d1a208c43ed7699dbe6f68349f39cd6768686868349af7e84143739d3e0d0dcda5c1aa22287c3b0adbb6994c720a8f63277cfb09b8b3d0bca57a7feb86ccab64a6f99d69f4a81d0dac99f7f8cc7bb4ba87cdb199aa90a9478fad478f1e9f29ebf1d9d1c0ca3db0aa48eaa6a76efa46f329a199e6261ab3d92b9bc96432758f5d0364b6d784554576bcfb8e77dfba6f3bcd77b31cda5a470f0c8976db967b7c3d52667b9a2f664df5f1b8cee4816de9157deab3445588569855a122abbc615511997797c1d74bafe83b2c8774ccdcc29032fdf58221c57c960caf73cb6ee91b69afe4f82c199ecc96a86fba561552ea1b142afbb2674a7d93dda0d3fd61fc35f7b5962c4bdf4879c26f9d6ec09ffc4edbc45fd0c10f4f0e7f714a3e7d76424e5fcc27dc597a45effd2e2f961f8eb68b20bc642039620942cb0896324e8e584650244451bec9118b10ae208a822022072104943432162860649a1cb140d941de60380fb7c2ec5d7edf177410634e7edc391c7e67a281b10be079df36eea3979edc38ee5e19eaeda7928ff927ab8a78b78fc19b6958895ba19c4b9a0656965855447b77ed1dae4210b1654dda4bee12b7de6a2db275dfd83a6cbafc5a97fb9410e1ee9d08cc394f0911efa81339dd3b875b3098c328dcf270ebd4c9af0701da7b6447032b6b5855642a6944f4cd3d3d8f37e4100feb86d723dd70c30d4f62ec315332bcd64c838725634aa6f460d8578680100317c8842a4d31c40bf40141f803d61c081bf0890d6845be0a21331139e6d65ccaad25d3b715294ca5145a4b23208529b8b3e0779608c0a7e7c12191a9041dfcaeb2df3b4b047c291900f9faf1883f24fef72f05fc69433ddaa6053c2c199e7c7c8ea5d6b44857bd128d668e5880a892e3a3b444f03a472c400ce5e8e539e7c4de5f631c866133688c0136ed197baee4e69c73aea8dc0f59e59af597e974179393b46317a08639e860967137e86045c0c5e13d13ecb10bd03dfdc5df2f82d40a0f8de58997bca4e5d064e589e59090c63d58beb9b606843c7da294edfb1ae190e040818c72bd0b4866d2cc2a7b19ea8dd43cc9f54856ed24d7e3a0bd3e073062713294eb5df8216f5a4a296bb2d84ffb38bfc4e69abea94ae297d82216e841a12701b31b22bb18e4bb634018faf8649b31c12d3bc323cf2d91c62d9f3c5b32cbbf6f540c28322f71116923162029d97ed5e2968423dbc7117fd4c77496f24bfc119f63bbe28f6e92e567658247efbd813276198c502f346398c5a16f5a3918761dec1763c740e34c103b922c19c384904164acf30f4119c3302c2ecd1260f141a9e6079018443e66608b9914dee50b928588c58729b9b1f8e025b72e0c34b7483882c7f5ea2cc4f7d723334dafe443f9231b86a54cafb19194e9b32ebc30caf65b174499be731d65faeddb29deb8b5669f659f19c785793b6dd76955110cdb30cd847dcbbe16f7ecf653697808f7fbc99c653cf599a6651d0df41ae6a96fd17be08706fa8c3b865bf61cce9e7f72fdba6bdf4fdebe96ccded9eff4d98fe3e94ee9e9030202023afd498c0290e0138b25a83367eededa3ebb221d91ed16b7ba6f58b51d7b87551b2e726f7f6f3fedd8c5786e03e6c56e865bb6c57dbbfd54191e52bf3a64e3d1bed9ed34d0db73df26b395198b4166fa937ca19be478938d0b3930f44dcc5b13228d27abe445d9356cfd8e47f68b4751b9754a02af51a69f9fa5c26b5d22cce5d1dcba2ea26b9427a59276b2a8ca7a4a050d52a79cf7d37e3ee7daf93955b6afd06851dca5bd8a52266cfcc1164f63102beb6d906d7a65678bb34a5e8ba3691862904720f7f53ffaa63e47fb6a5a2a1782723dd73831cdbaaf576dd947336ba0d3f693d1de4b831c73afc23e736715f6f8fa3225c7d7172a39e69319a6e9d5ad1148349a446cd1a2bc215a963d23be1f6d49c3867dc3eeb7d96f88963fe34d1fcf7da45f86728d40bed686f4effb59f6edcb1e658eb8959dfbd6adf81881c406743d00f9d0c4957b94701ce69498cee3817854254a10d9842f900faeac33b7d8e1560f797ba43cda63d48e378ecbbe7ede304f96653d32fe70924631e51717378138b6e478a23635a7b62bd7571c59a2f499946241c838769063289db412f1729df42da4e73507dbcc3e3117034f0e65fac8c6d4be55ce54fb5c5fd3eeea1a66bf695fc5b21bd25dfbfceeef76facdf461df92ce2d7f7126bfab0db1f2eb9e6554bcaff2c4adbae3a1aed3f3d3a6171b01281c32393d7601b487b10b30ef7d9e7634ac32f7f53d2bdce5d7e116cd7488d5be7df76234b072ad7828c7ccb55dc14f5e423f89dc28e1e17e09a561955b4c72ed21b7e2e57c1c4ff27cc301465e613e721532310f17f3ccae888f3cf1295e0e2de948bf1e14b20cb37d77457ce4d6b4adfe8c5fd27916590df52ad6ecca656cf7b7d58f19cddf6c895bfdf87b9dd91366f92ba594efa1694c4abca4738f7c23db4e08761ebcac037535c9ad7e0ff646932f99878fe7e36eb7fa3d17c88726d979c0b2077e728663ab075bcaf53d3ba3dfba65fcd1b75994f2b295613467ddddb8953d665f0cf3c53cfd88e121f18d7978e21bf784b965cdb0a1980a262345595ad3ab7e6c967cc7cef1f586520fbcbec7de5873314baef80d306c1a4b1c450d800347be1125cb0698d46882521390dcb0c276f1bc64792e85c3042bbc78e9550c13a4e4d9da62df44491fa7e46e4094dc9f5eaee4fe7cf6d9cdd0d1d09fa71fb5c92d6993b7934d965d0c5200590a00e3b4db601d0d3cdaa73c67803cff75433479bb23f73e17fb14e9cfeec8bd7d22c17b9f2712b4f63ef65887e4dee722b9c7a89c31d8bc00e5f9d0766d74c9f3d3a28ebafd7eb8b7af1f130dac8f3108766b6750f66aa52701b9f5933dcb85a7fd09762bdb5d1a584f7f7acc6d70c9dbf6eda0e5eddc4744339dda64ee2d1e1db673ef3ebb21df0edbbbc37cad9f8ce2913f7dfe031efde9ded733bf7c994162fa13fe80975bd4e592377daaad6b2389fce5f862234b1b44e49a1c5f6c7861434965eabaaec3b8ed536da64fb575dd75ba765857a47b1b457949e779ac2ba2e5798b7fb838fc0135fc04bb042b95208cc3db7572c5a1adc79e59cca4e21fec4326f716071db4bfb5be1eb373ab576d94897743af07acda5eeba5c4aaadfe0ce5ee84cccb8ae36562fb9241fb74264840ef487726310d73ee3edd611ebb1d987338dc11917487f93824a10fa8c23dd0f39939771f6f67e61c0e4df7bccf5ca7a7ac1125cfcf9d1d479df3d971d36b77038f77b7dfce8ea370687a4cf6ad72af7968e2f10e873bce1d4c7d3edc79bce6f3e1f11d8ff97c42ee3b9e7dad9fbc0650deeab7834644cbb5728ff9b6c9ee06d3637efa7c4c3f1df585a6a3ee7da1e9861de7719d8ef9c2d36bce7d11f3bed8dd109e9e7aec76769c070ebd773e3cee83eff33d64e283c2611ef3d00bff90077e88ff3df5f98421f7eea18ea370987a2853f3f98461772fa4f9096fb0763ba6a35e3b24de77e0f0073c7de60b2578c2f5db31d5a3b08fc7cdee08771e18eb2cded901f385dd4d9889cfcc6b8e84c33ff038f71366a281a8771f130df48e5b36994a90e91c66a281dc6d47c3bc3cea3be9ccee93e0110f87dc3bfcc4742b16f3e8509fdd1ef50db76ce4fbf3d9b7433d7d3ff0380a87125401fb84aa873d1ed2fc84d7fcca63e7be1f78bce6335f98facc374b82a11caf10b22418ca760969e49845966a78ad54a6587c88927be488a589ab4b962e5732901c5f5d80d64823e35c61e34abec9f1b5c61b5d320d9296dc23c7971a55b21a5296f046de38ae7e2a0c17c9b2bdcc5ac69472e48229651bb9644bc9b0e2ca070032a26458c9366f260efb541513b1cff2cdb123d242172f57ee881c00c88808a612647a0d0e2518a680bbd3438c997438fc70d0c1136682c2b91f3341e149500240273fe0e9a7c79091e54ff8820ea2dee3a3f998748fb90a33f11ee379984987830e7ae7cee30b7fc01d3d09c83cad285b68c5971192b204535fd0c1f0860f830e32319d3bea335f288399984c8f79a8033381790c0e3ad83d070e3a88c24c6070d041d339fcc3e9cb972f5fc02ebe8c8094255e42b3bcd6d110b3c81277c0bb22b72a15a2ac433ccaff19ca596703f7eedec4e9705077137ed2e11f12009acefdf4b7b3a13beadec441e120d33dfcc484add877a7c7f007bcbcc4cb3c15f340e0073c35683a65e2dd50ba5c5e0fd108abea4d7f72d074fb56926cb1aae21d4fbe854396e74e53b285ee869b5ebb06783bddb9cf6e87bb09873544d02439cae3e7b60746a392a8144c35c6911a668c219a0104002000d314003028141008452291582c0e95791f14800c96aa4a664293c8c3248b51c818630c3184180008001010982919ad02a9650ead843e9fddea2d6141b22cba200ca710a34df86b75054f8b4b534b29509c87fc1d1e7cda2af627d19c15efe32733f74871a2be0b55c1a552728e0eec605fb8519282722a414f6ae02c5e3198d7f0f58883942e4e243003f92e6911a4ce19d0c72301a8fcc6676acbaddf26070057e478e843cf79b81cb6427e2556d385cf23deab577cf622d7e128dd5de3a73fa7bb8e8e3885767fa392a6e051518a3c3ed3e0e011d4878babcf19c2f72ffaca81bbef50d5e09e3236162ee5fa5e454ccae07c8be0b47575d4015decef09627a8b842b445d3d380dbc91514db9e8811bd53dd4562a555ee32c67347b4073c341ff21a984c1602ddacd720b04d8f3367d4ecbce4cdace383f315c5a3b5abcbdddb38cee2e91884143220300eaadc9311da26f9437e4aaabb3f6fae12a951b88367f68d718b2177d7b8f2acbdea1b5bbccdbfba0297cab8fe68e8aef3536c9214e1200878f97d192d1e8d8c64f93aa3ded5b2cd87bf0268c6e22707fdd53a5dcde5a73093e61077960b23b2a37ee4e68f4f2fc4950793492c8bf9f657cb67e6e8b48a3093da1b62f0c281058a65d211e132f70b94501298a0ab12066b81ce8574700a690c0afd558b934750e5544632ebca68b2aeb3c8870e6cb73340d25dbc6e723a25ada293ed67517f3a75d270f4ce4af3c85178af9fc6819bd06845a2a2dba50dadf79064d078a0dbf1d48eb81a27f92221aaf891a1f1cdde264ed049e0e06aa37b75a371634980c4d78a1d2ea45f41ff503069bf0f24b34f8d1a1b9b9d43e999ae09aa02f9f7632f8f81c8c8c7f73e752de2432316861676ef70d977c3c5347a4ef9dd3429dafb224c01faa154ede2c495aded9f2c05c870375911c28c5459cc824d8946e081aa60042fa8b54f2d9243684a6c556e368a5cd74d99464814d6ee9231b51a14c104f52d4ff43052029653945d77db0e62b988d80bc9b1ddbd16dc43e651fd71728e7c46c30d25ccb49a055752db7bf99e9ebe73bbf1706078cda2c5e118df22cd5fe0b98961af7a8c3345af98fb1409033feb53262e0745cd258bf48af716a9774962c718777f9a81054571665226e04600709d6a10e6223899fdc47d7693f8353f6f68a109d322fcd7b021521b51e50b417ce0392c59c7740eddfbfcbc075e7e2fb494cc77af2dfbebdf3fffbe0ff84b5ea3fe81c866801ffcda7788a67c53814220ef9e82b0d14ee9a481844f4f441e2386f51f33dddb29f0a37386ad2d76841fa99e2a5d5db2499bd562ad2ef4988b7e3001df2dbf885a7f3f2f71dc62be77f0e20bbe9dadb601e3768a68eb5b6dc189cde9e6aede1349eb0416000f74c81c07737a24ec2b746f252829b835e12000d024bb34878b0b6f412359934953da0f22cb86ba78df20945d1ff5d8d6dff95003ff3ba1db4bf767dc4c7194aa8a4573a2b283f399aa2835ff31464f3041df6c34129b2315340a1446b6ee2e3d9145c6e877b804c379eebd91e7a0e884faba849910408ac2d184e03aa925d34830ff0ee9352df13589ec846db5b315d7a51bf472f91ec929c620d66850c9cc596210dbc3137396c82be44ad589d8d41cb10de3a2773b476c232be7e53eda288958c65d327fea695e0a4e6973cbe0183b631ba3346e5671d808b4551282e74d53aa6aeffd0de1d33729a531dab19092b2f513d53665e435b3ba8ad4978af9d900622218d4950697d08fc23f7148797ad8e50b42576e4b92e66beffb7883350d615eb10f4294d89777a4b84eae1eb7cede210b6bc6addeb1d696a4b3d1b13e4f9a55c6d5b77a922bb2520db55cda2a2e70058767fdd04b93c74cfcd8e09de4fd38669e53f901f751c4937ca50c1b434c1b2ee1b90ce89416b1865e4cb18b1b71d1b2e7a85dab4a288c77e49233487da2b0458488755c7bd332d194e17e3daa0298d9244859c0ecf28acde02b712b216e0e51b7ba1e6449dd83b701e05c2d809007d52e91f5554c94b082acd02b6dba80e7211d9215ae24b34c49fe26d34349514c5ebfa3208724959413f327ee36b30b3b4201b12ccb196beced77a1502de48f8b0637776e90676d449a561c746d96541203a96d7284548ee158d022f147fc0d6dd0f72dc4ae040735341a7a9b602ca9cd7ba8bf89bbcbae5dbaa47ecd297307679b2b8b3f3d825e6999256c65f86b1f06fe74910eff31a369ea870c4cc3b917ced6dddd23866af1d209cbe56b4d12e6db824d7170a80c1fc25defe5221bce55393f415f1403218c61e28e10ae8dc1bfb6031e630d3385a67bf1bb2beab7765fea18b1b425312d615b4490712a3a8f9490b6d07a604d5a89162d0227f70bd7114e0d67bbec69c34f7247697930640f96d102bd39e0ac98ad2fd40544728a0c38b6f6cf4d4dea0646d2088f200c91c8a702e7b39665a7feba126b8f927200d4e7cf48c5ed094a8e67328396443359a98914c9b6de204ebba70cacddf31f907f6ca259617f5ea0da5e21485ddc893e92d99656cd178c6fd67cc516ea678ea667dc276781de782becf5db12ebd8d1eef6aca34b0af5d5dace0afcfcd0e8e6adc40be485e379565427f2ca3699c13822ce583bae067b5013263eae4b977b7819b3e75849df74f1808e6829dbe06c32656a7aaa56bc41e500e17de6b64c5ca514d33bee0039ae370916b2f7e19f04078058376f624745815cb825c67f66120e0a2e68dfb7d79d509f509479d2a2458194653e07ae3ce60b7e956514fa317a9b251cd46d461265d60ac23c5b5ed22a9ed916a9037394f90b38d032d2fc400753db1749b547cc503e6f7373a8354ac1351669dc8554d0b6bfd7ce6194590f0404e5cc242df0d1fa2c9f71a695a08a232267c3b7a2d02d9a8ad65371d326ffc5b14f9cdb0424d8702e1252b3cdad37c6805e1aa732b0c37bece5554d533781fc7059160b1c8864f0f0a610b43fb6107ffa52ac437a702c7a31075e6082c66d7d92cc959bcd9a146efe8fa979d1d8c5090157b17356bbb21f3dd893dfa019446addc4242e2d1274714547eac53fc758631e152a46b44eec9491d1bde94b53d0342a9b41ec5f4e9f410b51b3d213ceb3966dc89e7be2cdbb9e90a033765decaed8ed094c969055859ef48b0e4f2085a90929960a7a08894e353bbff7c8dd5d2c464ee54c0020e18909d9afbb40f6ac87b17eb8f1ba6c39fb8e58065e2da4ac8b43701f5e3741e60df175e44a8f848007b444e84264f8e52b380a512f936f1dbc102332cd8ae304e28d8db6ce69a6db44e0f5daa3e79c2921f9a979f6c3bcfaf7475a7fc8b51a1a3589a1171187fa9aa7872df1cc57e6d8b0446471ba20e472bf8e00b3fec6e697186c5b8288481ddeff12e0f9f95fc1708ffbb02ec26dc3dbbe68b09706426c17f1e1b1222d9c19e7747d89a71d31a31b56e3fc1a89e4421874093fd7af043c3dac21654e4908c0dc1e40105d6a3ff31794107ba1be7958d57dfb8a2a3f8625a81b6730bf2e4f2c50a59a403ed1a7b076f7a2983cac3a614ddf9b251190af6688f8afe09b52af52fefec3930b84c3d9e4b228234afd0855aed8cadd329c809abe21a990ce6bdbd270beb80b70da440ffd8508ff3f6b5dc0d1557f27cf8ed413a97f037c69ad45e360bd083c2ccf6724bac0c0780f8ed36292e5d45a045924b86e200384e2487db37451817e02ac2d4b9b9dab58fd6ba19573bb32ead29ed528c00f514f25f57abc0d4545796d57b765fbec8ad56e2c511b0950711762654b13efccad070037a6a3ccb6923cabc560b93bc341785ec2896a978db6d9ec962bfbd443a18a8025aac010be503bc5e3afe8cb0eead5a0403236c063524c9b019a1f4cbcd2eb82459d8abc070ae9feb92ba5fcd769d61e67184934b737d3e06fb503e7fa5bf76d03618db30e432b12295bc9053b3249108ac24fa243bb27b3e0e92bc926235a342a5c2827adbbe464dd8c6cbd49257a5b7efc94448686ce92e68a64ff98ce75b1ca7c823dedc8b0b0036e38b6de1c48dd335887a079eecb3245d450239fe30ef651f92d8fdf3af8f298aa1a2a0106dffdc553057dd3bb9d6b5efad94e6eb65782772ae4c31742e965bc42c541638279255a2f29b3be6c1565dd2fd924bc1be32d685066f4277328d75969262493157d87a141768552b502a669e88a2be689f3664e32dae2c5c71029667ce86195cfbe0384ce30284944dde1351d7193e494122adf411d1014c1cc6bd79706978f5a7c17e48d4ab50eb5ae7e3da8eb8a932f332fceaa77e9e80fd0a06f7dc5c8c7376e1d9495b0e98dccaefc466d5aa4c15259f2992f186ccd5d331e088aecd50bdc26121e92fa86d03433a57bbb62a09d24fa4962660ef60ae3436ada1f0fd7b5e193dcb1443a072589240f48cb9fea9bd151334a1f03a1a0c505ba58901b8671877cddeae11d8b3e81d9c76f3518da9c5db365c74c4ee9ad371eaeae2806070d5301d5a13d8569e6b76bca28a5eaa9f23c61ea79c7d209cec31851bf59b3e7f472abdc0288feea0d4b6d33691d64bc5e962d65f67f298c799ac8b344316887a1d0d9e907d6aacbee8f5b5d06f8c66e2a3402f83bc520d03badf88d4e4e42707d95501679b4cb234c2e0885feef82df354c393c81b5aacd5354adfeae0ff09aac0e128557422f676950a579cc8449ef7244cfaf8c58dd48326e22661e06c4414ce362ae03faed44caea93833477671c294143e11ab8b28f225689820df7fc7fed289278471da030c33b4dc0821d06f3371a0f38e0b2927b704ebce0b49e67c0216cfa39f3ad27e6f0e88063e180297a8376a18698466583711fa375b1c7a834e703d0bdb5b30ae9d074e805c3ca26da7bb455ac9db18aed3f4c5aeb877a72ae3db38a8253cd631d674e6156b6fbd443503d2bb4d031053a2360c2af4b0c22415b9d881c6aeaa71796c5b2cd5b5a0001e6e96ef0f012876f679eabd39abbd6ceddba1124bb061c2450fad13c91947d3680850ff548b2aff0039428743a5e82c6a22f6c0b53272bd54505963503bb55bbf9cb4a1bc96f91862c3d8b2c3b823109c90d2cad2156bd1c302b7e01a6bf81f37d1cd5c41f52c80dc54cb23fe38536845598a311cb5fdf527f70c64d505ce7dfe30a8d93ba0d59bfe464ec51d81896c121729908d5305d4dd92f71308e488ed227d43597408831a39d6af0d0eabd91c3833565d5008c41a15b997ac07205ce6480349d3733550b5b8a66ca39436d701d1dcd020fcdff2bce08e8bfcc193631e0eabb9f39870a0f1ddbc84e01dc495a239dd7950b4b4d209b91d3549ea12f031187221dfc5355dba78b304ca46f1489b2fe7ca8867cc0da6ddddba4fba35f465435adf3be210365f1002dfb600947a6a6068ef906667e813f6b9a659cc7e7838fa00de959d6f1a0243db6069c3e459cfdeb41167d44a758f8c7bd671da8dc60ef468b5d9949c7497b9e8cbc9b0c92734d741d7a2599f90b9b9681da7116a82444b8217a854006d2b6dc5d06dfb3a2617fce000054fff8cc720315276bc5a998cef52727881ceb4ea5fc28cecbf5e5f9e0c9bb88be369bb60c323c51fdab623966e7489d5b76488ccb70e891697e3e5403b11e1478078c32ee0722d3eea21be7afd386cc2d941d540616c3600c40802c0d100c834d245d8a7466ef983efe4a30c2646b6266658bb0d3559f00e5e1755483d6e3b86d58683013a9ba38ab37433be458a211eb675a26973e20845ba7c7207537cf10ad6b10d18c86ad18916a8d254a4a7319a49f1f73d602ef6c6212d6ad96f37ad509c66562a14c8df03719d6169165d87409c49a7c65ec11999acb0477d9f5fb305fd24b69f09e4fca7aa4f20a1e0b61d450593e9a58482c7fb7b14665c0e417d161e852c131c752424f7dff90159e313dcb34a945da3922853af103bec2a760ff5972afa57d2177001685534d6faf1e26bca54bb6a11c714573436d2d91ce09e68f4717670d64affbd3aeeef53ec3cce7186b1f77f89c1d8596c5530491e8ecddd45d3457b2176c1f1de528c1282169d4c8631eaa4f2ea036fdf19ae194ee23b76b1fbcebf105e264e25e2a4e2b6da45c929e57fb8178c5f7d2fbb4bee8511133d8ee8a5a7cbd55877bf5ef9d37b1c2b669fce67a71ea136299887b03ff4ddceea69d1bdf1f5063db5df20c1008550c9c6e7d3a68871ee077bb7f1cf9591a6bd42adbef3af46cc3da0fff90c2ea82a19b925d6c2f936383384d6d94f3e0f97e2ec0a70ba0447c01d717ae4ad04a53aa8dd9388c96c7e9363b70f98f954fb73a0d950d39f6b2ed802de1b71dd57554ff5e702150064b432f45668551f61f93e0658f58a23f5b991392ca15620c57dfff45519ff5aa528105b822cee6e6a9d99494f9e1546c9aad0b7e31d31ff4281635d0e642661126d8238cea0cdaa619fb8d1202f09bc74e241ab8804ee594798203b1ed8ab9723d417ba86d9cf517a1bc337ca7942f7c43c7e7ca16e3d9a7fc7b494ee1b80390ad8b83bc36c92ab05c07cbc51520905628d97a0a76a899a6736093973897ba1009282f7fbb0e49e8f867b8e5d184db8c714ec80348945c61f38d0c83d606cc1d7a986e1ef29d8506c376e15531f1ac305024b495a57913a2dc4c380e9408e0b119c6be76d20f66c9b7b186b5f03d8b89090082e37acf0294de800950ad2096e18bc13b45ab29bd09274364b0d1024977e60598818e817f284735171d38c63618506fd9f5d4ba6541c09f1e35950644ea1df0c0addf5d01b7c1d29c4b5cd64cc59348302cfa0e53b9f2a32105c4e12aa411d9219239b34801f3411b255c11f27faa20e6517c72203fa7f9cc4afb7740e953d3a4f874f9e87420206a305956ecbda73763382ae215ae8af2e6471290b0a5c3b3d4ad5b7d8d465f3f8be427a803f98125aa70551014938fc3e829220a7a78a71896624a4cf5b04ce02a453a0bd72adfe89347324252af3a1b2b1cf8d87b0f275f664c1da854547ff5918fe1cd1b0e77f463278d0d3cc6f6ef0033b962fdc4bd539f2910afabb0ca371231d8619d7c7a02cd11d37908286bd8bbf8b8c5176a81ce40bd8db6a51ce20699d9dcedf5bbf6f31035a9ff606fdcb68e74311881d800d8e8027e99b158fee6791c71e90968772fd3ae6c4923cd58f2a088824fe3125583a7674c0cc2f47ba4e99396e0f17017ff91c5f254a6aab7ec05f66c41c48ed869ebfc8ab3c000d6847c6c8334f37c9e32e2f315be0513d9a4ba9e46a7ef38e982ab01b1106d0ca0b12364988ee8b0233b55b934030d22444a83372218561603a939c2c13a52788bc5064ad20a09b5e96ee52586fd2ff95230a96c1855c4bb978db7c2bc4caee635472a50b2c67b2c9c20e4562ec22168ddca7ad5908135c4d0560e594b36272b6627578d75337361b5d364bc00ca589680241a6e900651ddcb96e2e2e53f8dc096d3c3e39b58e5f0b55a5840e686c1eebd2cda4f448215138c91056c3f1e2914ba0732ac0360172a77bc8231531ab818c1de69082d26fa9a33710fdcdd097cc4b29df193925159fa02a022fc82810022da824df499eea2b7ca42d33f4c4d7a52f33d810c142419417548651f0df5dcb0cce5fbefbd8210c6b892430e3a551d64062e2bc1b715d339972a0c2ee0aabe736888551928e5a77762bca4beeb4806669393ad37d298b094f9dcd4318dce90a3f47b2bff288304a8e561443329b43d0e73b5b582d63f1613010f15cc43b645303867ccbef54ed3e80ea0a06df34bddd8b1fcea54b6eef68d798353c4ee6f2a276359f41c981bde4d81abb66693aca3b8d5c2bd37be5443eda8750762c473641ddc43acb9590cb6c3c4567f305c2152fd62b66a42324c86bef68def5f6c0e541e8cf1361bdc604075b251a775faec49a197071f7775092b7c2eaa41055d4e673f54b149807fd357b1b841762f6ef6caf8ea15f32d1a75d703030ac97017a27bffed3e66abf39de42b7e9fd0ca804697a3cb0b842d6c7d1df0036d03a2c83ddb340ea003a617a9173fb382dc7f08d54378df41f33b2b32f234ac5b3e5dae762ebe73950ce68317794fb702572072021e230936ca21a55a4507665a191ff0705c1c656358940b5f79d1b94d5f73c03f644356c230a725c05139dbe1ad3d85eff67749285937beb09ae59998144680e178bf410d4405dde1d159870847fa8c5134ccd15d5373c2c3b6f764202d25b66209aa35eaae7e53bce77dba025de81d557a3b31443f46b99a659ba7389b5df37dfac0141ce6fe4f5b91b95e3baf6cb12d4a7667ba45c6727ec9b2c7f1f02523130f85fdbd76c307e6c3d4fcf803a114ba9a9e19587086a198b4b2fa76349028e01bfceba1a15982deb4652ec1018e2be442122da903a21a00c4eb0b3bb951464a71ee41d7b6db90e4bd1c9a4837302b7ab2911d3e884613c011ff80ba1f5325821e592f075a3d3c19a02f18a177df6447908ab2c9e10f61f596b899b2f6897889cb53adbb65cdf568fcca526eed10f56d3bf8d880fcc86eeb9ad88affd11409d14268ad566852447a9249da46824a6748040fb05cae45ad7738d6bbb245c5fe8e450605128a11065b61d47c8d4e4a794638f2d319b733625c0e68d0392732e0a5d07c5db058a98908e4826157b55dc8213ba7ebdce066ee10829e95740564a56589b8dcd85323175877db384ee63541658d838de83158586f6253522fa986f9032d796e00277fe4936200c811d1aa1ab59e84d0f2b4b00e9244b00dbd1a7fdb15eea02d2f7594f7ccc13841e281ed0b65847ff6c42d6509b831bf16ddf08e85eb04552c229a7661dbed9b4f117f9c1b1e48d5cbdcfd2069ee162fd40283ae7f9041954e2db6c7212be717bd3e5d25d0e7662e11bd97ec58c6e145996abdaf04a86b29650628fc5b8133d4c22a26c26eb2763a61147ce839ecc17b6bf414fc8bc91fa1b4c848a211e33ff4c207c632e8841a2b4067a8950284349968dd2ae3e13e8cf835181b40af328e33806cee366158cf5f97420322a83860f98182bac7051756d8852472f610fb0a563d43098ecd5f534657d3b8fecdd1dc2b6c7a316c5859fd093448db5f3d059c1c71971fc5f921440280e7c77a61aafc05d01a17c931c190834ed4034665770a4a1e1607134f67668cb2bf6e46e8cb84e99ec2e71993ad2f1a772398385305bc91c6a1d886048434a96ad65722131482200c0948ce4477b55a793940f46083af91b357dc2564b1cf949ffa9cc3b9fd842896dea060dc1b63c458f0a836639dc9a2e47fdc5196e6db1a81a8cef57c6567210aa42db6e3b4598b09c39dd4104d0e07838a0771a084edd247d4237576eab3417567e9d61e8854e3d80f2009e0522b5467e54e2ae1ada12ce80fc0a1ae385f425cd980278d21fba848c3fcb8122dd10bc36767dcd29469aae990de96ac25d38788b2aa67953234b1729c12788b94b4a9a075e8c8e85d79e54cfb716b9979917c97a2d447bd89ecb97d78aecc004af488c888ca5383299d912e451af6b237def03eb3c3887b21aa8fe291e494b4dbaa57cc40fdd96fea7a91a6b89d993edb56b6143af25fa739bea3610e42ae1bc1eaf25ca5127cd050590a0b7c63b9c29cbe53b8e4cdca218244cfceab03c707261b07e8667d7a2506cca458bf91d68e90e1a792642755ff74b3af806b084c7610c8732546a14203f0cba1cd6bd44da71937b5f14ef82236636d41da0bcbac16be411df7ee8bcee9d4b042beab81a8146c26f04bfc10c00b984b4c551d4e0b98ec5c3858d1668e0065ba9ca35c562743bebef93d76097db2a60694c80fa3cc3eb3d1384409cae906ebe235203f2499af51b9a2e892debcfdcdd25c86c882cdf1a119a8b5b44acbdcf4a6a2cbfc69ec2b6eac60a29ece33f6ed8c564986d239e71db78124424628649862835ce65c3ae942efce7f129b8046df7ab320101858f5043df98b543d9b96ce1462070345e34ed544786b505685f19593fec78520b32c1c104f7b2c11c9d2dfb3c8a779211da1b1562b83d6f2b84e998c99d87055aac36c215408b91a480e8b48217f2c1c64083939ecbd9387226a4a9006b406e0947766cf9c33b2fa2bd9bf337e17bbe7d7cc1f9ffa4b22716c020d9550e9fa4afde81240066b84bea489292208629480ef7e1524f8aa6216e08a919c970d161f1369ff056d1d7a0bd15c0e7b2edef4b792e41ab158412e2d59821769e10d0d5d79d18c9ce03c9e1c58bacc5eb3e4227c17742deb99175c99dcca5d97304c9621256c9bcddc3e4f5c9d548d52a2c28655566ddac8fb3eff89545602a7336564f66f7613b95aeaf1c6256de6a7644e976eb0f0ba379139ea14870e04c092bcb0b13c079764c2621319bb31e2467ed7a741c7096ac13eca390c8b144c6711158a31a8ee00256b4e0bb2d89011844571a1f2c79e2d2678c748780823c79e9aa1d6c5f76ffc650f20e65889834ec332f1ffa83250ee03c2c5e9c058bfba618043465e7c3229ed643c7e32b30ab57f4515a57a6c3870587796038556085a5756d437c298bdab074e23dff135ac5f2315032e2cfed5f21a6c07e60856a9cb2e441c3b3345d38d3b3c844f7ff6cf05581cec31da28410b3ae1caef945ec8debc63ca2de8e20f526362122cde744db385c061f443be0a298692a7de0a0d62ba8c2eee05926a9888fac08376285c1b901fe39c6fc11aa398314a3b88cfce1582e7a584e25207f2710bda0377960f121fa97c592e13c733128480a1900c3bcd21edd3db5fe288e7ea2791598561038ee1cecef5108eee7d78587c583b4f5bcc85257a79d99e1dee2583db4b007d43a9cf6dc2f627735cdca1b1871d10fa81fa5f6e80fcc21ef302c1b15708a179b83ab8fdcac880dbda337b9113d3dd4c12d12ec98c605e406da9a6c04485ce82453c8ced84fd01b6e62f804f3e789603c23161e0b3273ea8715af8753a6d2a599d2922708f72cd97fec10c2a8c16ab6f03c9374da94b7cc13613d27761e13f45054b4ca7238cf264d9b685a63e2f1ce51ab470e798a16adb0128e324b674d4bab3c618c736ae37181719b9e68d57e18cf22bd36695a633634649021e79a89bc39d76a1a35ab0fca4199a50e9cf11adaf65c7d8122cdf4e0a91f0177099aebfbe7f8b4813d81b3c2ee877daa24cb16bff38d530bee997305137a940018b16a9b6831e186390730a12743888c3be6914ca8f421ee5384a08ab2b0e3bb5a80b72e1b7f51be80316eda7fcc3b4d656b1c3f502333a311c6b584973a2a5d7770349d8dad782d630c9db0b162ef33ec1c528fdffe9d59c57fdae5d01d80daf0925b9b9ad5c36d80a95a1e77a1c61e621b53d066d7eea8e37aa2cde54a33a4c657b52e2ee85bf4dfeee676ab03d4f89e233a8c8b388c572af19a8c3da4f221f09c7a19c5cd5dfeb453a0f3bb681978992437e8030a60f5dd7301fdbcd754fb173b87e94549969d7c773c2ae3a014e9558677f56b122e6b52bae19cd011625abb79de5461696cb5952cca69ccf415e2fbfaa9c26e78ad3cddea162e819833c18e884a64643a4a444cfb58defbe444227765768285c7a4a219018414f42314b3e5a8109b7f024b931a984135b59d5404053848175a9f7411709b2a069108aeacc19190b8eae462af6ae04dda269693ceedb8590396f28e6ae692f2c8851b4ee9d06d1ceb870def04a70ea3082a66802bf0ef9cb252fc9f2314c4adb15f9f261e9bee73bb13b2dc9f2f12936b964d6fea29116159f5537b14afcb768f50bc2d686b24516b81f87692c548d34161b60f87762b88c96767528298263d4c9b33e914d4b4a1e4f3055a006b76b65caa8879e7b3a42dc6bb9ceb012431c7b4410a9c2fdf8d582858634fa242e1487807adbb30917d5f6b461ad3fa4288079f4160651026bb218093c6203b9c0c16e16c8711f144571308242ba7a0dc4cd4b9a8fe8150db576bdd657f3a5e7006b1bbe2cd9b729f1caf79ef30b06341e3e283b0019dc10a83a63f578cfcbd033f2ea6d6c4c48ee15681c1e82abc561376b9572b18c581340f0b6758bb5f1a5defcd590a081d37b4fd803b454bb9dc178e5a271227832c87a8b7f11f6f0ac559da2891d68fe756a6b104e9592a9a4072fd191b137a7ce3aaa514cc174e3480ca520fa5e963497a208a20c9de7e7d4c7dbf5c5b31c0312c02b67f227b8eee6abacafd5f363dcc8d820889a14face9c38a4dedc10f1af2d0b0f950843d9600e87bfbe31862314153952228ee1cbcb57f6aea616235dedec23d155450b4e5efec214635dd6d3828d24a60c71b55697e3ce02d24a139dc231084cafc69b9fe1f4e4ab00210c25c7ba3d53532e989006c4d06a756e3169697897a7a992ebadd657c0009b48eebd8fcd55a2f40b82e7a29cf1c006c89d1c18000f0cc541a7b513281033ca02dcbcee0cb06ac77aa77067855cb8575373d0dc611143c6b3005712e72cd0623c4f63933929aa34704ba5c4aaa7f61afbe8def893a327f2c0581b23190966dc238a72cf7215305874950531b2a7759b5923d2cabb1f2dfecbef8acd100433c62fd138a24a8c2505956126dbfc21ff031eb55c494faab1af8b2c8d0c0c18011090ab45102c3cd27e1c7ec3500a06e9290d3d1c20021f92934a3ecc34d2f5a838c718ceca126d6b53a535e33bb4d2303a05c0fb1bbc141b3d44b4d5520757a2a71d2a4facaaa89de265bc1e3827e74189460231086e699ab6125480906a436920546f2ea492a4921f12054d13ef4b02b3584079eca37e663c889188196c236d10764080efcb29a5f14adf02f5216cd9804ec3c12364f02b71b7fa82857078c226986339c1680b08bfbf906e4f503e83960c119957c4bac485011522d31fb34bf15a28039de7e9a8e3a9d8f5df6df0adce4a2c88d02a0ed864b6828495bf79736801439653bdb3efebb670949f41d66a180b4b9ca5608ec3276ce6753db2ac491b064512a01fbaec5297ca247bd33014fddb68e0ec7eb5f023e6890f65205d69a3f1bb3fc533f86c4ce65d9e406c89426b9f40d981ad4bf98fe9069e95f345daf78828af2b934eaaf62a7cc466bc5b7eb5f3caf158fbecf338d1c3e53e31e432db0bad07df744ca5b5cd880855a457e3aa617723ee40213316d641d624dd816901ff89f2b61c08182700874640e993003e42c2872d4f387737073c83cb7bf1d73e9910a3caf5e267956e7a74e7bfa4f343c4457490955bc9051cd88445c678bfec3a57a4a011fa3ffe24076c12a9a13169065777b00bb4658bc4d71f4bf71d86f9f014f47ffac5b8c45ff3da004082948a3dba41de4e1d77e7bf6cd24af520d3bffd6c245516ec147a4b9438b1f233e877f4b0239ec94b1eb4d39d02bb47a3e0e4b75bafc3c37d2871fa03ad6f42057e8835b80d545944572bed8424bbb85fb1ad37e12d0131198205aa6e17ec00d9ad78be66dcf9538beb44f66ad9a162d00634866118e75c54eed81bb6a8d1345beab0e901c2df1232d7c7647b6b2d4908e8296bc42d8e4a42d788d14ee9c1160ec7a7c24a64d2b948e795e8b7e639b8b41e2cb8bf30f39e89e9395f4d6b5c9b14732dc418ae229fc056502ec8493f5423e9e964b4fb6389534b61ae35f522c2ad15ea752df6143a1b5406ee0b062355243bf1b3d1c9ed2030d1107a9e6dd897896d3fd085d27b34ce7f1f5d8940e5658ad1b33464f7102641e4761c14b551bbae2d82a1f069e4380bb3c69bfecc7af2f715b0c6b049b501f062419429e111bdfd1846ba988217ce5658c1857578a13265f1523dd610334386509ad8234ae8020ff3e5be953c084c2644905de5530f891a62beac380ade40c329e69256ff6023145158db0b6af0b91c4c36deb2dec0b7f588b50c7f05245c7e1c5e41a905f465472593659bf6aa0f2598c259a7d3296f9aac10bc9db2ccc896e851d3529227253eed14d41e34d11b0073675e18653ea8366990d2d330c9d3859af0e75c1444a2c214affa38c0a45bd91c84282225086737c09ceed77bcacbb707580155d0b3487b07a6e11dbb2e94dbc401b199ecc68a36cb8cd460289bc75fb424629f7059131ead30ddacb3965fb620bdc4d4aaa1ea6c6cc72814d2c9c1328f47465960f31b5f89f014652be5b86108ddbf20448537f546f5fbc4f70b3219301e3e28dafb884645ad24604b6519b94249a327aed5b78e350dd816db75b5a223dc27d9e463d47e3df81c5eb1c95f355d2708e90152c6f74cae47b6b526d01fab2a432f7532e0286b9e2fa04bab700bf32bd6597eba91382ecbf75ef2b77fcdc2bcc8ec5d7969095182320796a485b9c7d52c8f91a7b7bbef8c24b0c0fac0587042172532d5ce3801a8828fa0ecd32c45cffd605aaf670b1bbadb4f3a1492457da9e6166dae26394b4e816f991fcd373fb4acfdf0e828a369a4575f8daeda6d596f8b41775e3381258a69d4d1cef9ad0e1002c05ad5ce31059b9490f6cef63d17972b1e92ad454797658034b1ca9f01c4410b7f2460ae00ad380d3ce45d124d9100bc8f4b9872880bf61886562d432c7fadd00170ca21ae56735f27c4ce9341e5f6eeac9be405ab7b14828a12e9696d8e1c6c0ed96c1aceec6917b309ca4013d3a307225a62f9801010356daf0fcef2bcc6fa5f255a80823ff638ef1e33c90ff41fb7d94f3e0dc8ffedbdbf9160a624cdb0d3e687ef7d3f624b010b13f7ec5eb8a7f0d466c3f9671212e83585283e53a72fedde9c18e975d06812b16840319458f17b03aaddcbf2b3a2b862b78b4fb63b164b76e775ddaad2cad2f0d6b145ecb0295946fa1ab9a3e59cf0af0948b7a38bc6ddafe54da2b21ba3d1b83b7dbaf295eeef78024585cd349f4c30cd3ae71c700d3ee1adda893f627b8fd30145e438db1de5be1d56c31a29494343e6cd5062a552052cec5ab6f475cf38b5da1f8395e5fb0019d09f1f7cdc879f0f26f0fb259ccf109725d2098e232ac74e371350c842d169c2929bbc01ef25e6d604177d58179d1828212fd487e17a0f34f197e1c5b7ec514f0517ca09ecafc3d327995cf8a6e6c6b0d0cc8f61d0fde33a392a7825857663e9af2060704d23c96e06a40007580c4074d42bf4c7cd3fe6b47ead1b43e00c96d80db244f0568d2d084496a01606e63dc26fd5700270d4c98441300e236c46d92af023c696cc2a4f501406efdc1fdc6dc326360a73614b63256f2fb4560662ed11d98e209f05a12109733fb67d615c188981222d2f13ed16361da8a1cfa6b228b251648d6ca101f63f1534f8ce8b82bb90b17944452c69b26d228e351e84f12ab036e50858fb835b02585a07074921242448ca5afafd61094692321c47620b028fb4c4bc6c3c14dc4f8f34d2d6c72921191f0e4d50f06a7c5b54f490395b9de51d8dd580cf47e5d99aad0aaa1eef6fe3bd8c820de61dcddb2ffd7af13eb16476dfa7ffafeebfdab9ee4a8ec37cee412d9b24b3805e43b49397d888bc6b720a6a6f0ffd88abd732ba6955fb16addfebff9ffb7d204dc4bf088d029906f3aa930527b5d7ef8ff23fa9e63c2038b16df23f407f14d5dfee48abbf6a2aac5f609c042fa2a55459fd866f7fed27ba847e5ff2692901c000f6ca795d1a1fef718023f62b5ab9a5260089e0eebebf31640db2c74db60fdd3f6a003eaa4ece39773e7fd73ac8148434843d557839167d400064659ab8475724ba80df6c1ea5526c0f8c7f00b90fb7633c47c83c0f78b72d337711b128b830c005f02ad7b43979fdc0f09271f51c7cdb0379646a8d40b6d3430e49341f21c4c6693926f9b62853b4223ac8e7c41fef76ff6b3503a918a8e1d4abb2a958653bff6b2c2d672092ea18536469ef6d3e57edf131295fca0f91436c7281a45270f80486e57f04845d127e551c1b8ac593512e839ecf46cdb1130ac8444249a1a8b5f82662ab188b7374f56c1a244b306277945ceecc6904d53fade92e1b0d5cfe1e4ac78679df7615b108615831f81927c5d562655e059c82acaee7bab30c415a18aafd92fbbe50c50f0e9f3c2204ce23932a140303fe9b98df820a1cd0d72d19172f98b75e5b4c0816c46438ff47bbfe66d4474c8b39b1d48c3ed90ecb9376a31346ae2db642825c6c22358877b0c6fbd342d13f5afba358cea5f948d0a1b3ba191faa4a38221760e39db81d0fe69865a331dadcf0e5fc17dc9f422b358dd6521884aeb7d9ed04882ec38064d7755bd1c38bb8138c371d91848ef4793288aade2c20a5ca9e40dc9a66c6256fffc822cae9d457ec9e3b0f14b067e79f21a73f47281a705516670eed7a02c67c0639189b05ce4a41f30f81cc8b9a5331c74863d243437ae67dc544dd49af217faa3e72afbc70abf6fbc1cf0039797511eaa5880fb43d11a9744e99489081ce0d9c093b86f25e6af81936b10e06d0e787f1ace3ce39de9f994e8da9a64a857a642d53ee64d845d711b7b91c1425039018c6d34a645eb7128582d4b00795e4aa0328232dc4b890b62baa06eb6c7520525b564c4b1b26883d99c96fd9e7181bdca9595f795897e674116d06dd0f192c58605bc78c2d6eb48190ca5b0a2ff618b5d4dc53d0eb1e0fa253501b18ba96a71c1dd7e5ca9dfe4b26fbab91a1c8e0d590d993e415541ca88d4a5aacd40a5e5779fdf089341c29c293f1753085ae32c25864ea626bd2d9898946300938238b2364686837fb1d86afd031142ff02ee1171790fe0aadeb1a1de1c4e858a99090221346a464d262e5fc879656571b3c8160c2e7b75866856de1a8aed470b42d73bb5a523ad819d9c42e1b650af04cfd1540f043748a8551c4404a97179741ea69ca0687085b75784d8fefc7730ecbc8aacbedb170298e609c073133f6a99965187761da024c15136ff5ce9333d1c1980b9de86c0aff848bbbd0cf0be4f23e143898bf132364bbc8bc2b2e06fa4c5ebc150a8be4e21825f55a39aa75a0899aa0b18d29a65c459a5f2c9f5daabd4d8f55962dd748cc63a755c1bdaf1cfe9b73f78c383f12b95c0ea55b80b07b519a91ac8eae5509a161bc1e58e01de33d0aa07fc93a5f9e888491acae7a7535847d9338c9f9d73b94641767c0544751cc4b5309bef123231c7980a1fed97aa1577dd1036c5bf155aae5abb4114d7501c1282d6e02dabf0591571d2ee9381f368d8d507d7d0cdddf39560a076ec9a29b9eca7b6c1e7561a6d2e1720d0c5ea1cf8a1247a0deaf8290c491314a1877346b79fc7d406614381bcdfb9d213ce4bebd8fdb67f0a8c395fa94d1b846b43718f8d72704f329fd3fc3c29aa1ab6575ea74604e1962a833274f114255f1f330767763a24d2bd4f474f8fc28a4ae0f930f11c18cfb3dbc1baa0b98edea8172bb0492b818491670c027c724db122f0794c1aed0447a1242569514d62c97e2aa254581969793ccd15cf355331295502a084962a325eb873a7aeb183aeff52728d6f5c5f1460cb063f330c8ee400be583b273838cf689a2a35c4ba1e5b801d12d5bf0b1b8096eafac28046044913cfd8b3a555d7503489a2c9a4befc423b8c8891750d0d9ad97a6128ad0634ba584f8b9ab7469168ddfac1440d4a7429c12ed527986e19d8505f8a1229a1d9c38b93ae5eba2f5d4c8ca0d9ebf9d45dc711ac00b72732d963f035118a4b763fa6b5d71ebd613179a4b38b3ea912e1d034c10e318498719eaa7a856b788b3e3f0cd54dabb1e336aaa1d33877594511b01bbde2e0e3cddbe77adc8d0ea37534c48c978aa3b0aca7ad7bac0802969fdef492d2993e52c6b2781c17f7e416df242225783cc138dc2405723b7a0c311eef271c09178754f65d204e6dc0d8acbd84a8e79a80217704fb4d20804d375847fffaf5d6631800c7aa89c44f37a00a99ea7717bc168013c14b2176aa4136a4e66a1149d572f62fa0139ad9e669076c2740ae21d79c4418b0f001f8ea86f8b5c9081053e8eaea2109c87003391085632aac26ab0262d22eec16fb7e842e6b99bf1aa20a3ffa812eac83c4c3b647094403c889a40170a3f2d969580533a46f6d3be65d51557276fed2bb9816b389ea23941c2d7f7dd3b5136ff9bb870edb0b4cf5ef9f1ab239558bfff367c5fb13b6be4cd3423e678a8c749624042050fc1acc81adc81bc87baaaddc0655c6048475550a1666c9dc367cef64490803a9f14a32789f4f7b9c760fe6c264316b1ea9c7abe76f41912c1b78ae30f222fdb4a70a16371c55c478f457793958fa764343f989c56950140cedd5ba52a9f922b13dd00f65c35e748ca9f2d45d6b2ee586f7a0004660e2637047800b8802609f3298e64b93340fb824166d3bcbedc32d9e39d5f9540acddc63f8e913a8efa12cbaf73d799fc0ecc58ea0086c129bf1d0fcdc40b253e583c8d331ad91a3e76e22c986148af00f781da6e43978f69730e7c231d6bedf62e89ba02a9e4fffe3cb10e49b20ae90b7e1e522fa86e37ae11884b74f63d4837441bce87395e3a24e33d716463d0a7b427e31bc034d8c9c1dd745d6a83476293d75e0e0c852da4072011375a5145bb086fc611641ddd09c6171bad507b4b4b03a4325cf33c422d4634b7b54f68954d7977bfa7063b3ca986f2d0f3cd25ceb475667337a040ef0f28e368af152a4bb8e90f81ffd6263c38a4598cb0b507aaab4303af315d9370518471f2a580d6b8b825354eac3e987dd8a839a0665b2f9e0af2cce99b48c6eeb7e5c8c12e8d63216ee1a71927d6bc0894a376540ad6af332edd2d42873fee43474fcf25463f0e58035a9d5906ebc8716fbf0f654cb612d6b14c1a57a9205e2f36a69388346d436a210a085a539dd86c7cf7df01ac60fc671d2f42c1939b8478e061cf4e10389cbd6b69b0bf1923a99258588350768fa3750dfa275bea744d4a0ab838ad20c9ccaee28703532a4ddd1a1da1dc5b5dd21283e04c3b92a29ad1e13c6e11cae4a74dfd092031122105515f221d0ff9b09683adbead322fb952b998b1a31859b952b01588704482c00cf0aec196823384502207b4cad0e16b78202b06fc2a3e07c5ac003a7ba4833ad93e4476e1543330aac44a3c2b915698820744b13ecdc72285adb5e50ae0dcdb9ed5d7fa6ff5e9f56a103276249c5d1df3da05e3ca4990340424d9f02c8863dc0b6c51bd6fdf1288bb5f3ab5f010456f53921d917339dbf9a75436878b024780ee1d7f6029d608c8237064e0421906f6f0dae2cbcee954d87b90ebd2bcbcceb5a158274e9f198310351b346325f5754d938366e10d7c529fdc31bac94463a67837f4848bea691dcbae1741d24512a63694e5966197549c560ca4c8047e450a3d0c18c997ef8f1b24e6fc413a818f7ee503ab22f29bf2c538d3e119b06f387a01e1b1a8dd7f49677eaa6021109f8a819a82c18f18035c71bd11e448768710352f8e71a40694e511f595017248ea9798b710e2440b50a545701f1538114d440a776d82087bd8be7bb4b0059e6d80a26aea0f87a021304a660810565575e42d418bf4a33c96c05b0c26b597755b5e4615048a3c7aaf55cc0ea06a03b0dfdda89eeea019101e1e18ed5221b82409961afb3caacb0afd3fd8abe4fdb79118340e2a49ec6d7c6299a5cd2a90042223962f946c17502a3186034211753ac5a6b3c591f0375e4c6289ca0475f03ea2137064102beba97e013068470d044b9624a7dfc99268f963dc16084cc1dba29fedff270c983e3ea61d56b08d4bb80818e5110fe63aa9e9e4508828895ef82e88fbbc2be06abf8a6bd644664a8c730002ce357215cb67cb6a52aca5b65b2e8bd85dfab2c2e726f33863de87e7f59b7105baabd8a1c24f5154cad55fd4d743a653c3c2cd23d5a606f71e255bc95f6b7877d86e80435b5b0160c84fa05921b63e6f429e51dde17f08438496e4b6e3b558df03cb3abc880c09b26ffd0f5fb25f8b6ea63e74d43a64cf47ce5f6ff88c86561a413281dfa49b6f5786efdc4137adff645009f0e8ce1115a62484cee75e1381ae9bd4ccaadc4af5ee3283ae08a2d77d0d41c20cbf54c39ed56126dbafe25ac12f1f58842c2e15fc8f95269ccb8d0781a39fd0904624884f2535ccfa40e9c1b68ad82db0ce89d803280a0d14e6ab53216651da97ead19ca638b5b8ea89eefeaff2410fcb5766cc6a15aeea610f0695874e4078437012908cc293435f1a083ae00a94ed8a9b52a4219e45cbdfde0c33a4aa473ab85bb2b62bb84c1ccebf1acce3cce52f7ed67278a20bc75a0b0bb592d0c34dcb1f9d3c993dc5fcd8764df8423c7ba2059aae7283af23096e9cc04fbca78554eee731a095719aa74dfcf2be1a370a1d13c43ca8b47e721a3be5804f9fb6d7d114dc7824fa716c8bbf0976409590f0895b46d1e8e7af0884cfbf796b96faf3fb346bf02e10de3d53b5115d996b4d5ed2f54319ae4fa5e74ae174df351bed79396faa8f4f4cbad9f58aed7cb778298de1cda7aeb50d6477e935f00b13e20b2336dffe841f6021b531d3524e41c14d783f48c2df0b14922e6d4fffd354604493a821394d00e86f9d80587508f688c562d7f58bc3f0e7a94605c49568a4f4219ffdaebe979f326fde43236eb2a83629e0be94850288f61ea450f5127a2bef8800b993f265c47d7de9ae0cad1c6afa0415987235b4be9b5d76a461d41ea9100e2ee7227e0363db7fce78d4a3a0071700e9063178e0d5c1eefde7c360da54c8d4d6f000d090c4839d09378b390f6000cf74e75750ddf0ea731c643ebdbba43335cf3098738be733f60aa318916d3bce45bc2d376f774e038dde24910887e20b6fb1b74b3cde9d6ab136560922712d80c0f98fef2cfc5839aa8a3d1e84f88a7dc2ebda35c578147d387a92d086eeb9142905b5040460591260c6b857e8adf496811a3e7e536f88151b35ef6821c0023cc19abca67d9d8d1544533aaaa3a5c5033002773ca2c3193bb3d6e973b2aff7843d0339f07fa54adbd778bc20f36d34578398397a3e2363cf8271b16dd2ca7eb3171ee86b25f2dd6fcc5abcec0ec9717d701f65fe745c0bb4f64b1030469ac6f64c81302705667912b2d9c437e4e069fe75f98015818f8b9c9c6f4812cdd46576a57b5b57ac0fb2698f0a7a77c311f1a71ac298fa2ad0454da1f0a249431e78e72944a105304b4fe9e335a55ff3400b7e23805fb0e44d1b1fe91cebc046ebe5643d57b925ebd85b0c7c0eca15f22e670417e1ff3dcc7241b118a090d4c241f1f50120e34edaca5e3b617f683725ffe13fe478ef4d9ad73ae6db21cf118c18fe8414f0c1f379828e8b78a645117c6899c84d7bd982a358c21211c62f7282d5caed3f4872428d82ffa3529526fc89748335a2e1bb7a76d3c3180259acd7b1863d6a7e2770860b240e546b3a7480c283ba78976ffeab77d05e14650cb220f6c4e956d7c6d162bdf5526c4a28b87bd5fe7e1b10d85142f6575e62ba22d34b1486466e9f3829393e558f627a8fa6c60955e2e503273cc813fae0ea396aedbf951d44664267ec36598cb01e508c265df7654acf37f863485937a2d7962a7af4e3513c969136172af3fa59e9810e9ee1ac1eee943d401b56c2b8aba14bbafa46365cc7fa0b35b89c35b98f0b397a9317c8630297323393c5f93e4286e3a3f4b5b3a3c9e63a47de356dc1d10460ea73e206019101b318a8ae303a8f77fb5a9a5c165be836a950521c268a00e17f619afdf686a2823dfb8db09556bf1ac6ff6094ae316ce38524dd163a2ec9aeb6e7ca63c8539f8845efbfda0bda8985db14e3f478b52b4db7151fe97f73a556cddb8ee20fab8a8a8a3292a69e2ad42d74eae146b6a152de8bc14c6e0e90766a0a74e896439fd1ee98d9f6e64609df8fe10b0c544c2b6ae5e995af0e787a96ab4cbc83fe0012dff622fb3647a804a196242e7d50b208241c9b6853896d84815164e53b5cc327054ec89c5805503575f6d47e715775e6db378c985c74ed200d56afe5f56441f3726e48ec32e83a2849170c067606534c26698b6262d61ce11bbc86444c8f1a823373d41bf1dcf7c8391e5bbe85d73437f94a30174438848c571b6c220cb64173dbd402111f7957b88ca0a9488ecb503ae5b3e7226e11cd2529e4fb7d8b5010649e7c40e316f6428024090749cf628aa9251a9cb5a54f70475caa2fc4c1bb19eca3c0df2f2c99069d0c5874a1457d84c1ed6d38a0a821fb624313492fed34b4abac349b2b76385f4ae90da920474dacd5c84af314be5ad22b798acd9a89517fffd1b1209b4523235cd2488142ad55d5a91aee0eae5633d8420dc04a96907377de3039416441d8d007d23986455a3b1609974d9e19ab15b6c37583416831b8f7cbb5c45ec289c4a7835d0c166b22a8af823bd1706e8245196a2a7d347be0407844c58d5332886dee8bb081e2a3d13af95f677630fdd85f1befbf0ecc628fec511e36839695ecf91e46f9615a60f51aa89f968c1a4fdf5eb7483cc6dd737f0d01d4535d377ee864264351eae7eaba9a9734d1d089f108a700d3053aab0c69f3072aeb0ccf3c5ebfe6630c9214c2d6d0f866b0267ea5e178a166657701ec9658871c64d50684fd9af0f48d3f49416e3a5023b9b1ad8028ea2ef6f029f243b0540ec96285c976f90886e9c1d84926d4a3c3085921ebda8fae1704a94705bef3d67ee00bf8754b6a20c87000737d7e9b8505e9da5d34b0a9f41798c408e656fa01fb4d4c2709a3dea9b5c6cb71d648ee64e4fbbdf21728d78bd5f6e2698ade5fb1a889588394372792a238b789a39f50fc04a5bd6f3f8f0d974d94a4c7b2e988839032b9c4e97c99471415c3bcc02aad3b5baf0e7a34135f5be04fe4f739fcb0e2f9f261e28e745088526f554b9342d15f793deae04f41476b19e28e3faae5a81b6418a79a4400bfe3f5b1452e9b491575209586b71ec9430d588bfad0cf46666cecfb69d8b5c749ea5e61bdc3abe2e54f8008610428cb5f086f49b0bfabd9700df6afc5b951afbe2ea654378be33555acff6233d99023f0addf7117589a356649c91181fcf868ab58f94da7f5b5e5ae4fa32164e4c5faaf4b4d0539ec9c1a5190f08357587e040ac7081b018b066866e07cdb7a3ffa84aacc28031ba3026f645f0c162bed82f28a5e95e46106c5c308300d337dc30214684bfc1168d89e4488b89daffff624dc0d6d33d7f68f63f9dd110bd91fb102b3b40c14d7fc6527f358d82af428b119cfad20600fa61aaf6ec75b5f9969b79a6747b84805f949fb3171135c93ed5f10e3018dee74c0176c74464ca1c0c42a19290940b3dce0d02e4e7f8fcf29b61903bf0ea867d7890f7cd214503501605d451a89a45221ddaa5c239f762438d7973f50a9921a685bc485f0a94afa7cfaec8419b78ac695032ec99d36c414cc9cdaa1063763b79165faa0a160bfce8b0c0671111837140f4782f0710baeba1c7be2a7a860a8265a0a349e22b6fde11e7c0010180f263d7580119e7994e9dbb710853ed40b8478303fd37e7a8ebed6049b04ce7029ade2019e7428b80d9c5780f1d3de72510ffbc8c991f940b9f1c489a7c1f3b9642c431d25611d08d91a9ad086573aba1df7af3dcfa1dfb82831992c43b9bc111988a85ce0ac7b3d9f2ea9df6cb7bdebc6dcbcee3c19dee3abe1a13ba2be7af690b898d20aacab840f003ee5f2b491d3853d983925e54cd9fe1c06f15be1c56c9f954a6fc058a53bd27b6fd185afd06e91d91bc8271290daf34d69ccca57cca15e3117b8c94f9b74b31e80b7149c8350b5a77413d0cd26e580712af40a276788c1f37ce3e7e2796621b7d450ec48836dad0d2f7c857332598a22431c868048c8b75e621b8a418c0fa2aadaa42223cc7c66052f9cbea1964e297af59b550a79b7d7f4a22744aa351147b780a6596f2f8cb5d3137f3585227ad8a144ed9c9c71a4889356e1b5dfbe46a9f0eaabeb94c6ac46ae6e8ff421c838a51510117cd68fc0cec691fca7216cc06cdc259d3e2c07a2000308204c4d590ab208136fb46e0da98c8a12f94ab2111771247e390dc74c91c05960afd03bd9fb41dc5876abf3e75cf3e5ddb70c82604f3b068f0818aed2cd7220415e3f7b15ad6d67e95c0073d1ee4040da472e1eac4a61a00394deead1ba8f47aab10cccea2b5d67a70ded1d76ddb6d0be1703f1da34356835ca9fef78e7ee65f92a052f95c5337d62163a47e53bb303c14d96d558143695fb791b226a6c72732d3095fe2ea3f48eae55681bc94f524cf07cc1cabe472ec016d9b3f35102d45298e1156885fecc9804c477cef03b59faf5f386e93b4c93ffe454874521ff50820e8669f286842212f7a494c615bccbe872863bc7c73ada7ce363efb0d6cdbcfc493fb3764fadbfd6c7e2c8978bb62982d53ee5618b045cbf934d50d4f4268e77033aa0872c5aba48da82362b975763a5c3bebbacffcf095f5cd127531bd9badfea31b195bffa9e6edf83846c58a03af2b2dac296203f4d5dce01679f05d3d768709d308735bb2806ea297f6817b304c42fa08e633c4dae9be9daf7b9764fa7e72f2f7a2e5fc2417d756df8853673064f5a911947bbd52e2ef35ed3821532516e97f9191b41546a24b09206e7fb404694b0b50d6458a7f0e55a907b3b36533241612a436832560f258da72e8bd09682da2da4d8e177fdebb4c6707ecd31fb947300310a00cf9e7bd582e430c675500611f0db90c21d4599c845275853502fe710b2b11fa585de6162acb22c1c5432915776f9b13535cd1c0d674b403ad82685256607cf0f15999d0c35f0acca9bbfe4f3133f92063a73fe1691f044b778f69d5b1babed7f154e30fa17d84c4984acb0d723e2e959efee81174f970895edc9902a68d3a721770c14582a0cb6e03a45ddd62511e8da389bca74f630b1eba9645b6cfa0a018b41718059e4970a208f6dfb6c9d26061fdfabb3572d553583131d150e78b7e9864cda3247a5eaa677ab3e8496f3859830391ed7fe6eba169d7d7651c6606ab96dd7c43c4ae02fdebb116309bb8380e6f625bac0867bdb27b2e9553cdabb1cff932c3e3beb0bf50e2029e9e13779b0bc9279e19e4549a78981b1c53d83b01d9cc2f69fb485dfe81c9e803d5bf9ba2af1a16a76496e7ece280322f23e9d24c85d523a09abe2585c3af71ce4cdfe1fc8d7586edb2fa09dd65d791a861b57c243db71fdc7765c047472abdba467b0cedb43bc12db716deb8ebada2e5241dc604ef385b314e75bf6e6b00fe249fa3025aeb27f613b697005baa733eaf3bae1d0e883ab5345201a4a7fb39d61e29bb05a25a542ab1b496cea004e13b01a2583295680e47a12cdbafee4dd14d7b2d2700cea0877201f7f1af56195744e591db3a9a92a46282b60dd6c63d28b8c0335c24b5357f2958248c08dd8208ca90decbb5110ddddababd7e6bb6706e4788448166ff526986856c010d1fa5ded3066db77621c65ed524adc0ed220b196d10cc154537ecd4fc29bb2f1aaaabb3388c7590711b11002f2b1a7656c5505d0e630c5a1282434774c1536395dd85769fdcdba95c7013f03de5ff492807a509d1b55e319ef491537c0dcf663f9087f185c48b210d4e9d71eef6f1ce1721d60895d1129569dc98b8cae696e0472e622babdc0ae56609975be1c193c963724ba6d30dd9e95b849d5b75beb60bc392b1d0d2d9a8d8abf044c631b19d1610af157a57a69ea213d55b75122e48cc01aa3dd306b86bc5f2e94d7554b4a85c75de1bcfe5dc2088d5c7c3b3063501eafbebd08a6374e72546d6310da8a9ce7bb9f117125b4e19844cbe5b59d94145c278a20c624fd8c075dd1c2d61ff155776a8c4472094993a113eb9ccdd9a8406ac8764671b4090de4cf2304682497666b6f5bc737f868ede6cef0b8ac7ce92367e9e786a4f17e539b7b04f0a7bc9c4dcc5f36d80754851a4263ad141ee1fdd7255cba9242bf3e115f0944a7d44b49b3a911e9c4221cf637dc26267353d5cfdb0a63fe7be6bb0903eccaa0aa3ff71839cb511c7dc3ebd914635670a1aa98091da45edf3041224d4a12c58e7e8d6ab6d2a352cf5751883a3f473515f52d836499d10da69df65cb1e84d42daa21b9c869827d58a0f5569c5d91f57beb05901dd420f068cd5467e137d7093141e643d3b169e657b96e7147e83033acc628bbaff808a7dd27cb72e7e02c6cda439cfaa30a213483f41b311f14ee9ba43d762de3460fdd13b1a21eae8e899411bde23274d122cb26feb3217a634ed5d209c61b7a904381e3f28e438932c2dd1922b7519bb44c6d682d13de96a98ca699f3b500df5f5a0d5e8c85a754a448febf163b7ed2cb7ee2c1a6bd846d9b36438aff334d456c5ada4b4c36422cd4d356aae3e7d87a0b509ec3b141bbcb4ebc36e427c7452fac0fbf9b76ea725a4872123aa305bf04b69580ad59c3f252228bcc78d6961481625ed2187bec51a4e18682faf7a97019829f9a2064b392b5c34cb0e142b42949fa2b4e9b108b8adff50e995e202aab3fc16d0eca28ee515529f47599ee5189efb86958a679e198423e577ba58050e4308f98bb4fdbb95c81b536f235755adb495d75d11b17e2e838f2b94516ec1060f1acb507bed965c8549657d127b16974bebe94d67a57a662daf3e1849b51813032f532afbc05289d78fd91cab41deb2f19826651cd64a5c103febfcb2562354f5be37e945e6e55f00ec30f2b525b260c3596653b3d700069bca55bec99367c2eca8de07bc48e240e198748f27e490e13f4041b118bbba3fd5d211afe3975d0672dad75b94458ad1d4c27c541da83fa4af14e07862820e513bcc9e3b5a7776953408a4f7b7ebd639dac2a8ffc5027ef4765a94e34a600625063ddad708c173fbc115f038d24667f919bd39cd64c81383776e23e6c4e8ecd77db29f7dbe6b0cd0988e623c4c551a3379d455fd24fc2e5405d4221d9b3ecbb722158ae8b97ed358cbee622e6d7dd9072a116d437bd974ba00332c22c8442d4bd8b5c6d8548a4742e0d545578eb642cf4292e0533c999cdf2f3f2ea7906039506ff7e214951f2a13122f936dc4b4999979a311e85c60e3c1ae3e6c808455e02672171b5506c535aa23aa198fe75a9227cd31e1e9d28c4336522333fdb6066d67ec448b05966c8fa3bde435a5f0076b09b2771eaec73c02505f9ed1e8ae0b2708d4b8dcdd8d46b04f2d61c5820644c3adca7008e19f2d241ac9320b33a39fd3668052f969c38f3cc480ab2a76e7f915ebbb3918b3bf29650067d550c802e7e288ef3d6e5155a05eb158bad319daa95573408075617023214127edef01f3888469bad81cd2a63fbdf59376e0874c504ca79223ab1e2c7342989d6080feb5494662b8441781acdf366ce1034807f7a256910536047552428a6d647b106311b0bc25d4463ee202101bfa2c60ee8cfe219714c115413020581f9ea8cf39e0a66891222a178a1214b88748c01bb6bd115fbfaddbe58acc60346c94df6f8e42c9cd775468524c4a79ceeab80323f4305282426a19e60865b3b7c864b3e23d19a022fd444150095d3d6ccb102a15539977d9e14a10bed2ef393c734c4724c51ad9cc688c082fb9f6bc4faaf00a5359bd8e390ce68cd4969e58dbbcbf0898da896ed85627cbed4698bf1e9fd084f5d5e164b2a33972e9bf2282f908ce291809de7b81bef360d33fbab6e60610402f20b90fcc2e248e7a169d94b6f54648318bc5a83193cc0b212dd5b740423a723dde5cc98d640058dc0303771e45e302230fe1228d84404d391e9ac01bf7ca924f525516c24195f8b50dca33d25d93fbbc152a539c4597383dd4afddea862341b9c12202e3429c45fa8b1f71baf0daac735d443e6c5c465432c90ac52a507d92a102605cde6d114d5d48d1b6750432f64df3729457a9d11c6fdb685d2b0d0660a6de2c5ee79e223aa2f3fbe08d9e4c7481ff50943e740ef00bdbba3d33dbb133544082e4843bc3ccd2735a751b027ed09d68df3dabdeb3e53e07d6cc6f357fcf6343aa0ab42458752d615c8be990c1fdf5d905c65268541cb402ffac0a0109152ee4914052a24319d3a5e411bd83ca5b63ce7df63693fde13e1e9ded4d4fb5d1d1cd7be47de9b00ec66c47b12bdfaae74bcb371037ccebe5fed50ff4cbd8abb8d3b12816252712794b8c936ee3899bf634529d3c85e6fd4dee2b61ddddf4732007bf66d8e99388ccaeba535489edfced10df4c664afa45f68af14f07d7531d1b035454e26c44d8358aea5a8a94142bfc8deec2f2f0dd38a520be6313dde5dc8f2746da2055ee25794684deb1c709bfe23c85b2b6795233115bce88409d08d2720026c1f74df0b8d4f2b67e5559d0b2dbfe4add101255ae70a3880357687723e8ec968d1316fe8adb3bd53073844cb5dbca01d7f2e7057ea560a8882be7a903b9bce952400e38c95b43bd05d3edc38dd4240adf07cf662f936e0111953d228ef7abe884dce19d6dbdca93acb686bd38f3c14a7515ae51eace8dd5f87b70930bbe3f9885e8b0b22fb58366549929db0ef224a42592e73ff4a6c0b8fc2462bbb8b26d9e79515f5a7912365fed14460af02143576c3f20436d111f94cd4490c38a1597e71ea904312cc5cdd8b00bf9355607d176645005d2276bd31325dc759e75e7557139a38efc16fa343f8c1971fc8ed11a406e57f5ea445b70ae30aaf7409bfaead8fe841f8cf32bebbe857f4134f1a4d708bf7dae09ffb277db96cc4ac0b91cf73576ac277da44ded7ec03ae3e961fd4042cb5e8e5e0c269c6452671999979fea64af07f0df94b2c25e759e2e041999a35b451fa96ea9d419e96d51a99e56bddef5feac3714ba875d294cd59f13437613ff082a5fa01f9e41a60dc4a30bf74023967729b62d28a779174930ad0329db9a38cace7d49a7b6111604d9e6690f4f0286239742fef1ea1142de963ea430d4a1756d40120f2340bf2b9653bcbc0d9aa4cbd23f129b02c83a4024c3745ccb2090d3a25ab09640b931612b585df0cd7ee700031b65e3aa64143e70cd52a9d13a0aed541e4bb6b57bd72f0806204870b8d03a6572e48e1f5696e7cfbb3df7dd63e20b925e0b2fc33c477bc8ca798c18ae4cd2051bee08171067429cfba8d530fcb33bfc8c0ef754fac436197d1ebc6026b15e3240f3b4b8887826c0ca66d13b0f4d81b4c6359ddf5a3ab2c6019acf26b4326c942dbadb68cae526668b89aa2fe585fd888454aa5fe2f0a12e6a061c39ddd1d7862c3ced495add09b23c107866cd8769939ff946b2e5a9ddb94cbee7142195e0c0a6aeade495ba06de65c5a03d445e0f744151e2e8eb2f7380fdf955984e37ee7ef24a6d918bc7ff970adf6aa091a1a673300f00b4233221f4691dd33d8039d591096453846cd008ddde6138e27585f588adbc44d7456f6613da83a8425a42c1d6a22d9e09946264b839b62a4a33bff55b19701f462aa831a443e0551e674fa401790bdce07f33d92e2610d3b21c7a27f02765f4d25d706356034c138cb5ae2a4bcf43bca0cdd0594689512fcbfd0313be47275bea20f2442c5823728db6ed37cba2284765bc00175e3dcc09ace8ab8ba957a299b48651dee52e07f4e3b779a26c952cefc329f638e48c5221f0e256e0412aca0e3e8ffa26242b8125ae1a7f1e99e79f4a5e71edf8c4a39a860bedb2076ce2ca0c355504a66066903a1fe3229a3f1406f993768bf3dc170d2c50b2c357bf9b69c6a089a1179ae054b3d4169224df9a1f90410e05ad6b18a68f966445e52f361de431782a909e8453d79c41c5506d41afbce53eaacc57af55f4d71db2ea2a0b9260af5802925e52b364dfa60c055c4a2b4f457f33d03a923d5dba1037cc3d2fce765471183971dc764b7999f43ff47b1bba9881b520c91c9c455b379c2f88e9896ab8ee6ba07aa8668263d73d20ad08fe61e6d25946162c3e8a4de9c096b618e91463f4586fed87f0183222b07434f86819bb6efd90cb3ee19e5b85062638f796139b2a8572b598b026e0132104947a253125fe8d56c5c342717cce4fdadf2c28034fb2715aa3ead5f043abf5f7a5538c50a08dc0310844fe61488cb3768ae84f2dcb25e1ab2102ad9b97cf80a6ce4ec4ee6fcf5c2b9f1117024d2a51e44364842c3aba309fc317e6cd899453eaf6036fcb8d52a7006209a81fdd103ccb530e8f601990a57d34719ea49e6bb0623456d004b8cb65ebd9018a002ae8f6c2a5f1242cfa3bf5fb2f40976cbc23dfe5d72e38650b2235256c8b41bec418a650e268ba85d2506b8d8b02b20d7a6b96c4e64d6890f6f54413b6cedc90ace3392bc9a0c239068b72fe8bd43d8966198465c0cd44a50c11a1abe1bcc022b3050a3f1261c2b5e9d8dff1b32ebe550e188a54971ce80a31e2a059775f046878b12c127e897320652662224f15cfaa0eeaa21b1f41a51c8b551d381a5a5db9a84b462c6ad52129649d24182a7a49b8e4258acd6b5a8eb4b35664a6ce3ddc8c4e0a1ed0116a657e6595c1952560342ae93823e9472e894325c6ce9bf9b2fd843293f3b1168f8ab84fb9dcdbe3355706016c690a8a4eee2611a4d8c693ba3a637f6a468c938f0a973ef40ec63766cb594801bd0d50be0001bd06657536ed768d5b75c5f8bdd72928ee5cf7bbdef1e6a29cb1a127bf988263a9b59f9e437ec2673c7719e2601d8f5bfd495f711e07e8b9394b6dcc4d4f54284bde98b88057ea1523674eb153786b9ed87873c22c0f29e7cbd9ac73b5b09e7799b63fb161dd9fa84452cf51b6fb66bfb06615162915ef2578d7e065218d62eb5232960bbe76dfae324e1ecc6f47b2945471aa7ed994286d7a471e454f1d32c91f85740135a58a836570ff3af015ba6902d4b4a36e2a3112394cc3e61e55b4b61063a2b41175c3d290654300330faea4153a8e80e15ea4c19c90e65f253647d533c11a44f4c5a9cfa793a67673b4819ade1625ea71de20e689d2e7124da1ea93e5395970ec7bcd9b988f5321850fe6aca923570913b28ded5a855ed0e7e3d990a3b8902167db53fec974e101b410da434d2f41d22da370138545055a2e26357727bc5579c000a87c081d2190181883707209d95c683e633bff77287a8b9014ffca754698a3346c93581a5ddcf1202096a199c0a85d0055536fa1385238a7e844c2bdc19c130fbd45001c5d42fdd1a0b874541e3bceba6de69be3363d870f35aa368e484710f02cd8da644130f2bde7b16678384fc3ef5adcbd0477f18a2e738013b30f1465f2e4e4d6000bab2bb08b0ae8ce2959376a9ca057634823b359501a70e7d526906b4f110e6ef829c12c4f80aabb685f42aa375e740fc2dda7f20a6d8729392e5402cc447e04ad2970becd5889cf7c50893277b9eab4798b00e7aa4489883e39dbc2e8c77dcb993f796304ff402eea52bdcc6a2d0f87c3b89d9d39b1533cfa96932336e2bb2b4cc04aaf80bc65a30d659493afd98d7fc410f1e657a4793aef8277e342675074e40715bfd247a47d59371dc43573f2115df0cacf3a371fe95c0d35bc8076b15e9575c4115e12fce2c39f537baa2b0d7842e5b11531b1b698d1042c8de7befbdf70e080c9b0c380c34f213f31004d7c1a121f978df030f3f7c66bf6dbbb61d74e0b9de52c40e4ee083d337fbd874ececb0818b350c3ae30647d2cc9bd5ea1a71d864c25d1670ddbbe2eb9575641e54311b657f5d67a4997372b37b4b1c9c135cb56238f33d1c08c7958166c79947231ec3a9b882c2c577b3076b02ae7b6148e9661034b2c3861d9f87a56b0f40cf6276f685675ffc4080a484ae35df6ba916422631a57816496bad9512be2bddf9acdade7b09f5bd1d91ae32da4b4c5fab9552decad367999452c6ffd88e3fb0e7e7b3407a24f07dcaf7241676d82270fa3d0929a51a7cd35a58a9acb5d669f18c997d66f17d71f568c0997ebfb6a6eea4f4bdc22bdf9c300842bb67fefe611d4e5fd705d4570f353de30acb37aeb0dcd920b47bec2bf689e5f82cbe589365b750b87b6f76d15fbff3165314642f336120d53d4f755595aff2f7f41366d5f51ea9b2b7393b7c36ff8adf2f2c0f2fe1b57649e7f3aa40265c64efd953bdf7ccebd6877b557d0fbd7ccd9a0ce4697c59e6b7c42eb14b9854f122e7d178284a29a743d3791b030ece34a5746a97d239e79c45707006ac01676ce05c21b20e6620f311de47a885de7befe59a199c0232af56827bb661ecb1f2c199b4da1b57ef10e6f8856697a0a6ee28adb1259839fd673c1af05688f8285eeb05af95da6157c0755a471f1c3a4b7193dacc28562faba1a24d07218419a5c5d66677425ab563ded444b3dfb3d941deba80db8e4842c9d822ae9359657f912822c98937ae68ee525d2afe9d4ad330dcfde82cfb2afbbc37d250abcade033519702a1d78ec30d35fa99475c2752854b4e91e10e22a36c175ffdf748aec457466c2b2bad23d2a1d73e7b302924f7352d4d6dabe525a2b897455d21d109494164521a00c314fed469865efdd3b93c415a552662de21b73fc8bf9515cc6c23a0340a79c31577125ad10d1ea303384cf4ccf57b8c39bcc9a194fcad24cd6834d0234515c26eda1b5d64a29df636683f7bc7ce3e744cd39e7ccb21d6c130e7e02d1a632a928d9fcad99529a0226848031de7b2fd0b4425cb1281e218a48909268c5a2586485a0c24ce99d86bad1dea5b6d7d2865fa4b19acf0c16e50f19cc2586e92eea9dd6956b7987eadac9d46ea6575d6770ef6abad6c06ae4cd4ad2c8d7d4e00b85bbdf116db6c7dbd0ddd40b4cee9e95178cc23c2ed8470bd6618747439ec337e24ade8473e24abe8437ac61edc2ae7d527c705e2035925de2ec1797eef2ed46a8cb9f2e2f2ff3866dd48834f142e17018b5fc74a2d873e48d8b7d47db29367510dadd0e5de2a691cb0c0d5539ce25673912ab5c9c557858bec95e6d2e14cefe7aa75d289cbcc9e22fc7a55256d64c9c96d78c41c8de4c07df93adbe9f370c7b04677fefe7c3d258fabc564308a51c413ac28b222445488a901421b98a905cd715898e146d9bed7154148f6ebc41dd7e461bedf63677409089ae3577401209d111222445910849d14574840849513c42725d441712ecf4461b0e2eddd5228dfd09c36cd4728a8d5a8ec25ca4a1d7b0c472c5f32d24249420211106121256201d8105d20caaa045cc2552494c722488b8b28f44d1c61e298a2b9bbd8b45da69968132ea3577a56f7ff5a77b7a3deabe723fe117694c77c12fd2702dd9943ba0d9d7a99d6db56f36e667738f368166679f401248367c427b3e2281345cb927b334db19445b2450868ac9e9936afb6ae38f9e3cf43cec423793eaee0706523d734fcd51b968638fb56033d1a6e6b85e8f61788bb98a4ff84ac8152129425284a408491192523c29913d2b0417a58c55082e6a93764048d92b4d944685ba392fbea7380716b5f5520d85ea22dca5a5909c447afe6d393c2e58d6c8ca4aa4e5e9b479a866ecd2b5dea5333864838010ab3e5ec91ed6dd137a8fc7e3a26bc53c6428c20db2f4fb7cd75289f50f8ab07e3332297ba5ec95baad610989176f8c6037e2441ebbf03bda6cc05e95a11ef2b12203844ad0b747cdbbd2809cbe971b8f686afb0cd25247a428eec8e9fbb8e9c040ff10d1d1ba181820f482be5b0ea125fdb3038caf54ea882ce97a7b35ece64bc3f063e96091481b55d1f5f8327717c88babda63fec8ee91a7cf40aa81525df3213cfcc42a1edd063abe464a85ccfec0c519f4439281928e30e88704032df4aa1f120c8eb03f709209fd905cd06a98d40f4909183da31f9212253f3a3c553ce94e4717863ad09d0f467802e482ee8086867cb2e80ea868e8a73b20264540ba03da22a9df7f7438d05d064c70d4ef3f3ab02b2ee842bfebc07c50a57f5e962c55fa5d07a7c8957e2f4bbf37e422fba1b7d807d8f6b0271e1e8905617404021f0dfab2743c86c5fcde0c0aed8fcc70578b30bf2939d2dbb16714c3a60ef6edf7da21d68ee1ed71e3711dfe6578ec1aee6207b90d5bc8c2f884cc562de288b9130a72c263edb3a892c0f57a3f33cf35270e203cf53707d5e3f0582949239f13a7b453ae7ae08e13ebe48e1f4026abac31c652bc8c528a2c9394527ae1202754d2a0075021d84352aa83598aa34e064df415870f3880a086ecb21b0efaabd2e9845ed0f175061d339077bd50f6b24b1be2249e08f60b737251fb01ee21ada08b96391e80fd82c0635dd949dc7000410d2c2c675b8f9d7b10d4c0ba7eb1e2c60373229fc54de75431d7f142f03e59ea20d0efd1d0e273e20d3a7437819687923deb010e831fc28b8e3cdb104b3a0058ac5cd8af5c0309709f13c3e0b05fd8eb151c96553a7168a8e5890c0df5c583fecadd4b0799ed733d3b6da0cea6a49d85125e4edc4a275396994ea793a9e519d7722a95b892a92405945d9d90bd992c76d1b5934c49a2a4931c919ac65d155f787681b3af97af8132dccf88abfb558d48737fffe2fdddc2aa46b582a3bfef6ab41260fdcca22594b2b14b55675815afd20e555a3622aa81b5fd212549423fa42458f485e58e485fcf6f86ebf7f79cbc81acd2ef0f69e8b0abb26b604a6ba0075dc2aaec9015591c5665d901973b1090c5fd19d44a3ec0363a1dc39d067cd0d8ecb7e1d8313d27968a4016975558fe31656923a21aaced454c5d60010159db8d5c532e62b364c982c3cb8265a8c8cb826593fde0a58087db0ddc0db2ed6fee7947345223a8004be77e482ab04205ad8ea11f920a8a5041108dfb21093185ce4c6ff64c4ffc94e1116d728f7c3c47d41377553ee69ef8f9b9dd106573d146e69efad714294908ba53328f1db7792edacc6d076c7948436c79434d10603495423f245d74fe813d61ee8a8e347c7cc72a1e540a0d2f714f7ce78350c3cf7e7135347190979e71853b4aa1210ef2d2b863eee23b1d78f91cf032773002991d1fb38a07cc4059bf03655d02230d14816495ce7c42837e3ff56b234890a4e5af7ad4f4d72311d4aeec70eb217764806b08c4b5bd6abae6aa178c5b8febd7150fafeb089696df7e1e76285f2cfdc02c70fbfdf69844e1a545b8915e7aaa699aec4113b518c7106f9b8a045154df48c0a4e5e5a6bd4dd3ae65cf30de345cd2b2ec0518ae637a0106d3f69ca82add4df57b95ea7279215af1824aa552a9f00b5c7de1307fe185d367a81854128b2a866c73d166b4b97a64fc7a4d77322ee3d7e5af960b757ce1f685ed31aa2676c3916932cf892f00d1c9607866bace76ed190cf99972a76d4a54aae744ec07b6ea59ec7aade949f5b9f5a0695556f1486d5b0e780dc6c01d6c197f5b0f9ade8e63c448c5609a24aee861b00423ae4eb80bea162c4125dc0535a449a20d94589a1e4a30a215bd5df57047b54db26dfbc6f343553f1c742106249042022a47ac1ca172444aa6696fd3b463edbf7e3d075dd3b626dbf69ca869d77de9f7a5d728a24de9f459a954ba4adaf59cc85d1888ce75edd234ecdaafeb7a107754c96bae2f13fe815aa9b41d7ecbb0495cd1ff58c89f8f0f877e8c3baa04620d5ec74eea35086b06824dd330d728b61baebe72a781be9ebdb880a167b71e0f2182ff0fb19e8d0071d673e4f163bdbea34ab42c77324b962c551ea34a9adeb0eafb9c88b594af517454494c8a2b4ae193a67f4221134db9bfc917f0d3b9f1e0ff72e3f983f29ff1eb912ad214c95e2d02136c494f193649cbcbf8a6ea9a7e9bea393116a0df26e308aebea6bbd8dce1d643c6bbd85ae40eb1963ba198a362a18658f50d77321ebf5d5a893631c410430cefa2941cab8ee16fe389e199d46288e139d1648201c300c36180e171c301c3b6655936022299c3ec85928c7e38e082179dc9d06270d751f3136a88bba00e7ebbf64d7ad105f5bc56e91119d364cabe75a6d2e0062fb335803680c2bc83be14471d1383613e711ceab7edc0e494a48126219798d22283cf1d949fd126defce62c1bde0c72ca944721ba1fd294a1fec4a83090788005c6c7df292590d84f4e09043650c4112876e45143c753498411a6119e4d0c3f2f4fdf93e59b4148c248b4032f6e0a3a7e07431d8f9a53ab4770f4dc9c6fd5d157baf1903c3a407b760fbd94a73cb0d2f442ad33e9a437ac36cb052e76b75ac5f89720b1ed658e99b91bc49c68b5c07528d8a9791bfec64320d8134a81518a122922905284889291f2830b0bef08490a137dfb2149691293ae3067c2989973c61ca8e04e2acc9c83125c9730b440a7d441113de714b07e485550014a19a90e82d0810776ecf8d8a10a29b43c0f3f2615e6cc8c1a36aa8042cbe7dca0421556320e15b8ae06cdea1d21552184b6fd90aae841772be9832b57eec5c18203274f15495a45f42024095574ed7933593af08093b363e706b3e57de8c0034c42154f48a42aa498a92f383804a5af7e485530e9eed2276c142e0e169c2bd98b3638e26fc7f70c7e6218f1edb75dfaa88ad1e6fa0d763aa326de6837db4de9f43be20d57c21bd6f0bb34f1662eaeaa6c05d1280d8949d37332f2497104d98baf5bcd558d8c5db4567360c346b4b971f58e8e9c102549c78e4dd4af1f15585a867e4854eca0a91c49e9f85a371ef13576ed6057999f23674b492fed1fcdb0c6ff98babeb35358d1416657d9f116cbcee0466f71ec9adfa3015e79d2705e12e1ddfaae74ad38f539f53ba24dd6f53b51743d4fb4b9bade47155daf43bc89c1aae7a1d66a82ae50b4a06b9d41d75ae99411a61fd2145374b74ae24206292663ada852a678d2f7de9a712e7ce51af7fe462ea68ae87bff3783cd5cd448e24afd90a6106246a49932e64c2182a6fd90a6f86166d962ce9930662096380499f4005f952b54dedb49d5c89b0380200649ac776845260979531022932313e3155bd82b20931e8440a22b74844a62db8c93b3030a19ac51c346b4b95c960a5335ec10388834851128e44408ac2419c11545a454014384309ae081134c7280a4488a2834d70f498a2474b74a424aa6015508c1091482802509100000ca15b230050e3ef045122457ae2c6099542a47ce265c48d424605a106614543ad11e81eb1e157b04eec12ce51249f3661249036191a47991c6486924824296c45d19736e5c716fbca39cd494aba405bda1093092e8c114b0608210106882132068c205110a9a44123c01657b628a92164fb4a0f404125ad45c1c6421ebe83bf96ebe8b87efbd1c4a29c5c9a45c49199f9a1172d9ac530230274ae042b823695eac31d65af30e49138940211ae91119921441c427df8f2c84e0c512296841022958f148cf277ee889f404d18b003cd004234f3c49810aa0b0e6cc4ae6ee3692144974d60f498a18743793034b8428526c1cb2542251150ba3ecf0a307c8040ec127906887b88af49035f1ce10fb995714fb9034390cc93e33a8d52022f6f35826623f331ce42407f8450d7830c4ca3e1f442413b1c7e6675c1299c89bf926110154aa5c1926499ac824aee0e11024923442244d54e5406f57aa1c66ac4b240d1349739f54255966fa0192437dcb7178acb7f908d28ed95b78646f6114f824ae604b864958e2d02943295b8654ae54b172da7eece063cb5ecaaa7921d6290b59226998cc2df7008760124814574592061ec80f901ceeed73a83f1d888f20cd4790e9d9eb331c28777a20f23f407250e57061a503d929654ed2c04b409543e92d6fc943b22021d695342f26894b8a9838ac8a1762d56712e3f05846b61cb05ff791bdf4b7f9d07c9872249234f0a5ac921762c158b4e3c22a99b3500d8ea48127521292d1ce00070707a78b8ae4c4142427a2c02b0f9d68c2b455ca57a3051caa71828bc905d769574a2427b65800921358d0219ee54206098a15489aaf165c18b60a5b85a5e2c805d65a6b8df283aed5a278506b8d34d04e815303807e48518ca2ac6042217bf1d5232ac5083df802a98b1b80a00ad64492c4942ab8200a2d8c90248ae088abc4a4d907a7653fad9c538b24b4053d37d69c375a5cf78e7216d0508ed4134c3a7f5b55eb871405c951762305c04c2aca0f57f499e97999faf99a73e46c39a7167acebfbbf18e72e20a82d173ce39b34caa46cddd9ad05d4dd213b218694cc3df78fd909e84d1a77e484f9ed06fd3616f20e7a5945e649f99869d592488b484135ace6091de118d47484d24f5ec87d4c494ee66ae90c1bff7e6a3737a80f5bec3d3e4acf71d9af47b484d28e9f7906ca0a4df7b74be18827e8fa8df2d10b8d80fc9061fe8ce46bff8de1f13b04832415aa28b3b97905937ef25cc3df2b7a3139e6a52c6083f7f82ba3ec31dbded819fff910d51dcf577c54d87feca97c21ef96b1f8f8a4a58f17833594850acdd74e87b203ddce429ee991adc2a161607f7e260c1b1388054989999e939dfd18cc581a5a2266e39ba546f97f749c91e2e5947fbdbf0760de70cc4d0d9b54b5474716180506759753a719bf6ed2e7f4fd5a242714771cf38d96d8f77c1dd96bb1ffde4b9671cd64e19e2ee47976ad3b317b91bed33da6c1dea2e3c1d572dcf7097eacc45477614c7a1eee2824d4fb9dcbee4eebe8d7b8ff6ed9cf6ed9ad6928d52cf8937a9bc9d5ecbdd967d527d3af61c79c2a59b300671aa29eeb4a7da5c605edaee826f8ed462c3dca3b04faa4bf2da6c1b0527afdd4671af659fd47d7c898784b75270f5f6f3f4171d7c916880a5610f171717ee27eed8e33817972ccbb89f5c5c5c3017dcd15f47dd8deb5a6efa767813d688e05af28fe61e31976ff7deeddebb645aa671f8943b2a371ef2900656fa34a8d2f632ab1e37db84b41c0383ba8637dcedf4a671efcef900b36cdba66dd7512df7d4025f4ed927d5f7946aed8796bb546b31b4cbb76f5785da8edaeeb269da0f9f9486f9a46eabb6f7dc6bdfeeb55f2dcbb06c89e0ea9d88b7a7e892856cc77d3dce535945f38ef7f9075f56d9732a7bd57d54dd7bb3ca66f9a20f422db32ad657dca9ea9f94ae6955b5efa9f594e629abf79a7e5272cc290c4e25f6092b05770d73323422b81eed2fd909db6b38e636c3dcbe5c3b9d5a605aeeb2d24ecf919aa6bd5cc3dd8f1ca75b98bb3c480cfdf216ab6936ab60320384fa25ab60de633519bcdce69797bfb872f98b2bed2d2eb8fbd136f5b7f57079cbbb9797ec936aedaa979f6eb396552f2d77798b8692a2e5b7529cfeb61f784269a8dcb5681c172395b252bcb4e44ea85b7e7a41f529e6e5056605933bae5fcee11718989717dcfd68f9cbb3979e9654bbfcb4b560d82fb84bf5098563fe8261ce61b9a1def37298a35e0ef397c3a01e93396ec76b15cc7b5cfe721897bfdc259ffe924f7f71958aab548d1f2a1d64286e35b39a31d342a5bad930ca49371cd31a713670a6b5d6ceb8b2d7464e5c4108e1ccab193a23f39ab8a217ea70fabd27d32f8543f3e45036e0e0ed7bd9b68083c792c8de4c66997096055c87a3f934056afaa0a891d75dc5ffb8d7465ccd68883b8ee338881d3b762dde64c7b08b5edcf1599689a4584e6e56f1984d3f9b66261cbc95554ec439c6f1115796051c7c8753a390c1989a31573673dad3368dfe409ab3cf88ab591357731557d3e62ecefcba33669c133e5a9a89136e90c680524a93b8586cb032d871c39ac0aa808349535e0d726cb49070b066467c351e8d279689a41d382bf0c1992a1df8d71dd0ec977588abd769efec6b763ba0d9427db34ae725f5fd9581ccf6c1e9eb9aa6699a9677704e5cbd63f8c217556db0f7debecf7923ae2aadb926aee08cb87af3869725cb0a3656e9ccdab465cc33421a9c5534f8f7eb5e5a1470dd8f3da25232182643e77322cdb706062fbaa961835d451afba7dd18d453dca9c5e5ef355e9fb5e2ca5a38a5ed2f0b1e8558c495cd4631fee091bdb5968b51af232535da9e87acba6ef395e76ff0603496f085c2d1c360da106d3a207a6347b4d95e72e28ec669f8e24d8c6fddbdf085c2c5c80f8316daf8f20ddf988a7909fbe074cce3860305343b2615937fc0e01de22afe05f31057f1283cdba5a5e6c4d99bb0cfa3716d79a87b495dba4582eb26b4d84b58fbb5dd090df596816c679996cd67adfdccc5af63114684d6cf47e3c193f5bd6769c0c15f99540fac13d689235248a09aa4a0e1514d5200afa8b5d62aad11463c3ac3a16c7833043d1af0a6072924aea0892b9d5a60fef27923e3ef36726eecd0f085c2f58d9a9c1c979cb8a3af5f6b5fd062682a2da5c95c6b2d77f6308f81a192b80a22d2c8cbe01769b6a7f085c2c53c66197353a9ed4ae9f218fc823bd8416477421a4876cb5b7e6160f0ec971694cb6df199e996ec33232557b051d10625a5a92403efd8f0ac507956b4ec0188071f3aec60c30e0fcf0e31f1467933f4f068c0b75cf9b878e3a2bd66f74969c1b075883637e20ad6481af8fb1c7989e5146cf6846db9bbdd825f6f76b33cfcd864a24c818b0dfbccf4cd3e5ccd8d68332367959952a57b33e7827fc476757b36acd6661d116e38ecab7dc5218aab187362a5185523a58f0e2ae9f8e2aaa6a3b5b1e6ae87e6361c7165ed4c012773772da45164997c58e4c322b108e15a4758d139b4d32d8790aea63b9f1a3d5bd3364a350d8221e9758977845c57e20a5ebf7cc4158e1e767874e81e181d7762b4afbf97e352a93f55938a3455cad24b33ab784cd972096ece348c4570f0d7159f6968a219a52999dedebd29bd4d73675f5f5ce1eca56726ac7dd20d9fa39a9651717587e020662d3c9da2294a21dcf7ef9ca89e33775523c2f48cc3d7ef33139ebf2639b5b8e250291920c9e3aa97f1155309299e4054c854319c1614f6167cc2a6d2bd8ff96eb9fbbc96bb95ad57c7902c59b248690a44bb660ce034cd3db314651062207f69f8bacc50d35f4b5a5ec5e3ba7de9f2ad195cefd96e5bfe1e8dd32f7cc22db8bbce3d5eb738ea2f9c1d156d2cec5a1e3f5b72677f9d6e3de8ad4cd5b97eda7ec26d7a4ebc3afb7853e9f43cb46fafa8ef14812ca2f70ad05d2ef849991e2c7336a3b428af983ee20aeedcb89287f335713573726eec7834a0ce9b0136a491c9c8f00ac1c90bf5cc85b761b479ad193ce979a9bd197e60fb2044b71cf373b6ec8b5d62bf2e7ba0dad7815c07aa8d6117fea9a1e1a341731e0df8b7951e0d5823ae646501f6fb1aab199f91b9b971f36406efb1dce96014bbc52a18147bc5e85fcd6a1553d15e5e32ea3bdcf73d58bec7c11e6b562b0ce7caf38b2ffee8c4f30b28837c576a0bb2578be0e6959e4d97f4a42d7dbdd65aeb271835ba7ed6449b4d877cacd0befe625e8936962e89112765e26e31b4820ac422c30f83b9ecfc02d2107318e35dea19ccb31933325996652fcfb2ec142303c57ec93db24b65a0d835cbb22ccb321e3127dcc1bc40976710d31f34661583b2e3fa8230885874a4e133f98c12356c29656d4b5b12cd2f88babea3476295482526c528f591896a9fb2b9eb409539c3a420b87a7aee10cfbe9d8c4142ae2b8ceee0b1faa61790867adb4d30e4157322767a9d57ba038a5ce936cf9891417dbbad96cb3db233e52a5850b122698ab5d1f68fd6b49587275c71296ff5043fbd8032d4db73d884250a7730a9e95d7007a9a4705abb6f39dc745c79f343d2d0df52ee2e7d5664ce5a20841042d8527a57d3b0e52f6e875bcbecebda6bce54da2eed7ac99a86ab8637c5a54ea315991413599458a5ebb948a5eb4da5eda8eb2f07a256a592cb58d9bc9041c823d2481860d46bd8fe87bc8149240dfdaa7baa44e9ecea538389ae578dab7ad3d6438b46224d7d93ae3fe56e5544d773b9bb92ae41747d29775c3cd2f55ba69f5ffc7a66350dcf2f24cef517a55cbfe495ab4f8dc6def9d4f0a951d3f5d1fecaf2cdddecfae6179086d7d75b361cd795f9059401aea0b0a4b59e43bdead7920195b63769987dcd9d8e7d7d523ff385b9a7f6b0f4a2592382bb57d2d01abb32a1c3bee7665bf3fd8c44a2d015250e64d092811049fa76ab08a2ae2da70c6bec3201bd909b8ef90c3e2b119e70a0e048cffc6ead77c12b9cb86a1961a511d0af65c493cea606b77bedb5d75e7baf3d96ef7df639f1da6b2f8ffb09338c9fe1da17771b68fbd9d0ce0d07f69bbbd971a0e1bcf7482432d2d73e8b4373ab8d0ddd5b6bb7db4fbb236f5c501da0f610a74ec0755a578dc3b4b7e9b8f916775ccb182464ce0c4677f0405147f6f6392dee9e449b2a90867b2c432fbafb91ddc1de728f7d8f4c33822bbd333dbb95863234234a192876a69cd9cf6787f6f0d9b35bd8c11963a9eb00b59f33c32da00cb00a94c1fe3e273ef8a465445167d04adfceaadd8ebdc32c866db9e7fa3da6c12d200d2d5dcb99e89697724fcb3308af672d2df61d6462da63d95118672d187b767a55a67409d3bea450e100467bc787bc9152db6a4470d8378cc22e7847d2d8df77a54d18267509d73ee137c5ca85bb0df4b5817b0ebf2429adb6d770f7a4b47d862f86bd6e37dc6719c3f6eaebf00986fdda706056ae7bdf110c0a327a1819f0b8889d84f0f214660cbc2e2284d7e19b81004d1f0d7a0afbcaddcd1348bcef600789a1ebdb1870b564c0e3a2658ffc2d01d7751323d22a1eb2eb65df9e47c3c3e249dfdc4df99aaf46f1ab924477f31d6d807c09b88ebeab97db8e773390d8f3103b5d42d3dc75cd9dd08e53cb77f5f4170b6b1fb6093ede0f4a50fb6d3e2a095ee0430146a8b8738b2657bfcd870c45b801d66ff321b180020ab27e9b8f002ca1810e343090900084addfe6e30512c820881794620c8c5481075498fa6d3e60b28052c40ad76ff301b9a0c1138c18224b161676eab7f928428f9d62203c66d7d3ab72a8768a4016f6e380ecd881f820d4f7465a8e9ecbf49229c35b092b5dd8687b8e2cf518655b86dd84b36fdb2bfec1512ffec9d16364fa6b9f206d94658e6618cb742c0f61acd20542ef000ef39841da087bf6b61c726908636dd947290f612cee591ec258d96353cca300dd196df71152d246d8f6ed192e9dc3a61c38d3b33cf4bad06427db88a806d68d187ce0d178dd3d1a6ec460e8c9f01ac37010f61f84584e4a788893120f13ac2cdbd19e137bd8cb030c31858565223630618921a6306189217cc0c22ed46fd3d16384fdb54f07da6888b230981d5e8da4d9fe24cd96834a197b2f89fb636def38d3b9d05d1097f6793c3002086dcffd492e0765a41fbc2b19920fb074cd403c64cb0769699f69e5062debcf8e36447be919d5e68663a7c80f422c209cccad470d5d0faf489aeca5f8520e82495995232ca9ca12b8a4e81d5c12d4c407a1a6c7b4259ccc3ebca3fe79597a82b8b44f0c35300294b6db4d37e5a0b8e53f56a94a6fd94864617fac1e997b7408b57c1054fb3c00063fb4fc43c2424525af8129dd69a0071a2e0259d9310c44646559259fddc83dc5407462cbe3f058d98f294bcb673422308d886ab0b06718cb52bc2537be1811796f06204257c3dc1191f233a8c727521f212857e06350c38c0807a60c6ad822224aeee1fda0a867c68051d03b1153129329865836e6470c65d23d728fdc8b8305e7bdf7600c2e92a1bff7a605b27774010060a10b47965085298260650557ae932118718229529085122a4358b10208193cb4893d934008951015112d69f97824dac0cc34849e27fbfc630539e129d98d437da7e6207a5969f97b1eedf4f4fa4c4af6528658b21c344dc77ecf53fa3ca5cfcee3727a2d0accb55f99e7e5f5a70c935c3fbd25432992e694836ad0cd414ee6bc769efbf9129396976eca904a90139ed34d7721aa77394c862f39881e65ca41252aa567c7f28fa0df8ce5def4960c99481af9535ecd7339c894e5a0a0ecda4bd987132d0761399585c8152492383089a4c12225490ac74a1448c4ad2e150b99d43f16cd377573ca8acd1c953f56cdf749995912711182f146b928cd074953b01042c112466001116a20042414a1829e3ea87271c03092740516229020e292c0d40f690a932952928684e2e592a4ee8aab226924c4468000925578c88e3c6443d914cfce9110c38ec1456a600d91d991c1127305c64a15794314c355aa9cba1786e352a92b3ddbf40cc7f512c6177742fa76a76353a5628a5a11c872c261979881f0cc3ce62f7519333162d0cc30e9f7307bcb3397ec2ecfee12f10f6cf8fc727a07afe01efad7998dc14e6606c2137319e789f118274078548f790c19790e89c9413157a522a616f7fca8745a8ebde5d8df53e960773976975cfa81dbe38643a5833d88ec9e535eb5e9918abca992b4c315293d481af9981c2453392826c3214923ff77af0a7ef7aee4777008e68f058067590c4e1d629e98a772d00b8f390c0e1262c11c6e2a07a41ef31c52f912804b5430fcb1609e2363f010f844333a8247f0c90b8f79c3dc118157a02dd430779b045e380761b010eb6d3d68c30c6fca3df574c35a0e22bb5b3500304cca1852c156248dfc0b180621dd753009c34164775c0fcc3103c9a63189bc79ac2449e0152c712812c5227923e3f2990a07a90e44911a583b324fe1a0d48188390c87c141300722260f89f963bd50430ca298c360a298c390e7559828e62fc8c0aa1cb36f268ac94ee251c3fcb16092bc8951248dfcbd416acf67456a60c5b88cbfbca37aea2f1cfb9337414431f21019188e00440c8ff1577324917a80a5e56314d106b67c94126d9e76793344f527e32fc67156dc5357bde364e49ae7481a79194fbdab317a920626c77c089198c7c843318739cc65644ed2a4f0dd74c8bea7f8a7868e8f0117a98125938190b98c5f190899a71ea36420641e734cf6cd416ac76c249337a0ba5cce416a774249f2261573af0c8e9333f718a53e9fbda386afc768033191c6a177d429bc810dc43c9b180e35dc766202d65a2bf4441347f84194244c60640b4e38010c2b6444822d9618010b1f98c008266c21b3c4576b34272459c1e22a81c5364a5bdb7282176dadb5c285a44643c9b4983084cefab59820a5bb99a3212624e9db8f8b56bf1617443d807e2d2e92747db1898ed10691094f3ade4dc7bd6f46fd7bc7d5563fc0bd56175674f7a4d8faeeb56ed8b0e3864be1e04833ce8c5617ad9e33d7d4cb772b9b5a6bad3932dbb857c0b1916382ece2604d439c7e477289a491ef082e91371287e6ae66f589e58ebb96b4bcac226f706eee706a72b7ba22699e4a71505669d9c9243df070e83962920e7202b34cf268c8c7a2a424db3146180487583940b6ab2a1e0e7540b66beec11173100b828e87b9ab4670190eb164161afe69e1061390bcd56b696d6e30c1046ff5ba7b3d68f989b523b8970520a4000b2790c2fae58d3c8ebc61cd2a4a68716185142aad2dacb4b6c002c605e33df5217888131e7bd387441ce48467c33ecf835d0f8ac77e651eed3207c16b9a1157394ed2d8df84c36319893f718ff9839cf0c01cc267e771027f659ed44d39c8f454de8139a846d2d89f1e934ff630c83ee6a089b14bacbd84b71ce444e58079ec3cf3d8fc95836091a4b1300739e13986c51c048772517ccc4130076d8f790749631f54fa9334f72d352e7fac5725be83432f7f2c8bfa63b1e4861fab5f7090931d540e822ceea7bbe021d910273c59864b866846a7cc65f844d2587bcd491e12e40487f758581e426f3f6fc2f2252d1eb6948045978c543bf53940d6631dc9686770c5c297c988359a8ce8df6644c409bc5024022304e35e1c2c3857e69c096306870a970aaf6a5346814bd96bb7d6da56152b6dadbd5298b2a505157df56b696184ee66ae005b55a8b4aab42e14bcd8b1e363072e742d75b5336ad8b042d7e7dc2fb8ae460d1bb5d656165e74adf78beb45ced6af9585166dead7ca22a9bb552b8b28f1384e2d5b3d30d232c69b2370f1ca04ccc84109afc8b69beccd741c6c1d75d111d200ff2004f22001e4a3010fe44102dc06d202a38160eb088c06821a37a794474143f94ea83bfa17bb6220391503d9a183682d0fe5df1086f7dd1ee8ccbe62ea6ac62aa6a664662aab1c8ad3b697664d5cbd1a0e7523a7bd49ff60cd40e681b0a4a196a747433de7b3425f7b7bd03cf3a623b10c754fca500e1965a87f2496a19679062843fcdb70a00cf14ae0de3b9c777429c9b2ecb5c5afc544ebc80a2d2563b21caa6625086d5763d65aebacd76697b66d5849335d4e869376b168d16eb4a93183d15e361c36df2a5c3c7cf6a2bd68a3b5bde93330da8b36ab1959c4e00521bc16425827a43ca58e02d9acbfb64eb9b79bcf386ede8a357aabbd68f36e70228db420e07ae6b377355a5e9bceac0f8bae592ea2e9ed6db4a99f6db3f9a9836ea03bfb20b28d38a0ed68b988d0d0d1922222231ff0c010ab88918745122a1841155b4c210a162ced46822a20052c6c810b5dc842451596f6202259a8d0420a58d80217b2b07ec826206ac1c004442d18b0b4ff20c4d2f27b34d9b5bff366c15dc75e710f967f8474cf756deb2888a69f0f8bb6cff3f45e89bf6fce09ef03b2196d7ae8253c32d2f1940a303a5ec6dc057594b1cbf113d415cba61dcd3d30e6b8d7e24e888edc55b8edb85db37d8ebc5af6fc3c87b5415de3760394504e1c147129a8342aae52b10994424ac727af9a97ad925835f30e15ad92190242acfad752028a7e2d25a2f42de256107859b050e465c952d07c8704412129a3944b857b0d121d8f684961e4cd26a2e8f937ff66b48b9b13357ff498d4f2b74acbecb7892636c842bf2cbb7cdd74b25f7b4aadb5f6945a4a71cd53c700fa6110a362a8b76b8f508b259ab74cdb6cd0344dfba663b351e9178f9d7e9908c67272bddece07ebebd6e66e67eb71dd29ae5cbff8decf393559ea2050df164b37f760bfbf9e414d628f1bf6bae960bfcf4e9b8e3cfd8629dd28a53477178737c1822488c085143958c2c2369dab6d3aee766fb8781ec6b7e9d034b831607e62b9bb3acbf70281831708dc83f6c2b32f9541a4e9699e9b0d4254cc8cf6f5a01ed244fa6d3db8a1be84ae0bc84f0dad1da8f68fedf76898b4217d2ffe89a1b1bf0ccb7d2fa16ab57c232715572fc0f068c07357b8ab5f2b8aa1ceb344053c420d9ef46b2d81a56ffab598208a3390d2d146b47105d73d291d758836b15b4b54e9d8eff81f366ebc2bd189ec3dc5a4e3ff56af154510f70a4eab6141068515997e2d28a640e1041448ccf46b4101821948a8d1aff58451eb09142ce00a1950b83029adc089234e0c51a1d445105ca6d09488d1af15650819595a4d985a4d4c6919d70777662f150313a314057c09b83db853a21577b66c0086e98f36a6431bb44c973765c944d36356343d67832e5ade546fead96e4df31cee4c2f7d9a7e2fb71ca663f7d1861e5e87e92d267cbd055f3765d3b3aad9adde84e92deee1de73b9fc741376c12db8333d9a1e371cdc73a4e9f698fefa843bd3332e77426dd2d17e5dfbf5ebf7267c5fcadd9334c7aed35f37f7a4b6388b9648520207fd5a787079f07210a069a6109499e27a1f840e29a573ce5af3a387b2523aa794314ab9c99c83003ce2e984973df3315ee2207b50aa74a95febc9143a8b45a48ae8a80451c78c6a376a7a14ae39e06acc469c74a88e31e8185b50ae749c36db7e2d259634cd28d8b234f3ab913fc86436edd1783050a249c7a32c40459197c5031984252ee2460469d2c1d4a0a0b3892a99b0b7c92db9e0d24e803d216a9406712b89301aa545229e0c75dcac9412b05a326500ef9929be806b72d2e07541c3160d8a6680cf5e4b101482d12a91a1de0c40b21c706658218494d2f91e1fe214a26091444f28a4950416fd7210a06ba5744e29639c5b8e997310a079d4bae52040f7c4c7c31c9f5529f3cc90c2f981ba030e66c6978ad1c875892fad6a554bada28df628b59c8a2b793ce5cde566ccc193f8a66469c34fd260bf6e865d0b44e3155a4d92d87ead24ac682581d44a8289c6d24aa2889ac88296ad2482903177f7be80a355be43b53cc4892be9022e25732d42d145aa6dca5a6baf55c275a94e5dc65a6bad1d5a42cb8915fd5a4d9ab401fab59a44d19f49c515a5d7e20bb80a243bae055c771ee20f48036cfa1e804e5faf3461d2f31ad4342d7740f3c2807b58366302ae9be96acc6b79a51d9ebbf2e690896843af6938342d2e207e1e2517203f9f7dbebed54ad7b86d5955ba2a0779d371903765a12e65550ef1a6e3106fba506bb8e35acb7a68ec1b3661f519d0ecabfe566e62793335b2526afecdab6e5326c67c0b6700e6fcd5ea86e355b71932e69ab89237abcf58e10aee109cfcada59bf08d34d16a5b49ceed0f68b6965118a6b1d6473caf272b05924deb172fbb50380a3194134a4129a41b8e6cf18dab253e33fd88136f6e441a592f14dc6decf0f8d0e1c68e6823e96c1843962c59ba86c027fe88ab78e7bbb0eb0fbfbe2aacf4d27734f3375f0f3c3c1a7127aea20d71156fc455cc39467049ae124745449a6873145c079fd83925dabc274cc028308a0a8be838e11168448b3742244d8cb7017765924542f6b0b4bd8ac7bc3dccad95b6974850e9ebb309917d9d53ce9c9ef9d97a6d76e9f4d057e7d67bbaf5b04f7de2ebb097587b34649ea547837ee2ece513bb5ce2895197387b346eb65b8feb9b36717cdd74d8bbfc62979f70cfd55d377dc3aa97bfde52dc5358f5f2edefe52d8f46ea13a770375fbae9d8d6c3be9bbf8f81790c56f1b80ef3eb3059f572158feddcb773f2f53126bef7f72f3887506f47e10efbbd0beeae9ed35f67579bd8de9f70cf3d97b9b8baaf2f619c99b8a2572adbd872d8df2c1357af51af70331415ad115927a4e33bae53dc14dcedeeb7879a2869d8ad3fcc3c4803bd2ae0eee3013e99734e3a218455e013f828a574b68cc2b832e0ba9a7ef30aa594d65aa717afce2f26969a51ecde7b5fceddfbbe55df9a9abf5a6badf53575ce8b8299d65093d39e69da75c46b427d7157a3af761dbb5057a0d8d7c5d21e6532a9ecbd2ae5bd62c4f79348c729a3b440347731e2ee1dcd1cbe37b388117733d28cd24b1fad124729637e94ce78652a21e21271efc432df110666342dcbb2ac5bd1ed4a534a7734bdd174fb21d2d829ee5e17bd6537ae320d0333d8fee26ea6ef3d2ada60a5ec94eb6674dc36ed36a8869fa984539166a6e9e1fca5c5b9851f1cf2f5a702d80ecd103f47eac89021f4827eaf4f8b7ef93d1a517bc2c57ead191c0d2132a7c4387ebaa0cef13edff33e67e7c4f8deeac1c725a2b5164ed933f76815c2254532326fe6d1d61c145738ea917abb1212575a53acdd6e75abcc441b683f6dc5281eba038f742b8e0b8733574b01773fc306a95ba8e48cf5c4991e758a6804000080001314002028140e874422a1603822d696f10314800aa0ae466e4615a85912c41042c6184300214400004000606066d80024132398c883c31950bdf94ce8a706ca672932d2aa80d63f9df2629f587f04e79a563c0a6cd8b1f35f1b6f525fb94155421c6c2989f6ba392c8b41c550801451617286d0b3f73a29c7c4795f52d7803474a1959b744f10548fa9b08c4d153fe02f9fbb423823648398a69d2e7d68d8381561586f3c3166e14f964644c22e3d9704fe5e124693c4afa97de22f81004cef947f0ce01a31abbcbb27a1e971ef76c1a6bac6434f5e1b964a7a79a1bcd61723deaa4bb4666b51300bac1da751cc696c8e66801309c5cdffdac6de0ef181b802822afff89ab8cb0ada58c93c7dd6272718d09668dd4f02041670517327c070c72257199139134e4bb4be71255a99e60f245402a4b11c679d9b02a9f970ffa344697c6825b34b5002d6a75ffeb5871f7594c1e454363ff9d70a6859f0223a20f6448762a25c4479b935edc7cb94443fbf1e7aeb6db43082b980ede54350ce310da94cd54fcba12c890a6c4e5262698e93bc9bbfe91c37e88f175a5a2e927f0f18772008dddd7239fa160c7b9b3e2127de106198e3f8151b83e3a435cb1bc2597b6a03e26d3a2ac6b5673c3b2833f897f44e8f505c7475b570679a071d70b933185ad2a2ecc408b9c8f31061e20622a165e3d0df57df8a7a3b7f21a1b50a48aa36925ef06c7b59c7587c21b095b727a23a7405eb98911788a60a3d4ef782801065e57e1806cc135740b428f022f4ad3325b04026dccd26ca219390c2ce3b64b87620651844bee43c6c947c28517d43738111644b871c8cd9a6062042cee6a1f1665146e8f2db408425b080e1a2a887f8413ad26b003d20339a4c5f057a71b7ea050f3d647ab6e9a3ecd7239296afc961a68c46d76aed9b747fb6041fc241284ade634d9b46dd6849c22a732f040eec10396f19240c0c22ba8251aaa220de4428a0f984649c1242543592f53a807196fd2900c7869be0cf7f6d47b856e2ee514012c58c93a7dd085513f3bd6a3fe308ad671a3ec1cb386e949b9f4929f07d4ef709d71216d2ecad7fa28e207a2c191f1994241ff99338a11e2917e051dedc6e7d515d719998483a8d311e484986f70571460b2b5aa636c83e19892cb59cac0d416aa3f9f6659e1151300e8cd95865ae9124b94f28001d2aefb5059ee78d1d3dde6c3ceb94f689f6e22095ce6e316faa55ff1227d2a26723bd614bbe93e71776ab960e93ee49f121ed254619ba29cbb3d4a6ef822b435507e01a074a781bab9169a2236ea0680f2b148cc6abccb2604aefc1e50f2243315dbc68f510b59ffc6a6faac89d2b544c72268ec14ae337e0c30761cf2bbe231dbf81037902d7dd044c215e25566d778f80840e508755aceb7717157650ae078164a744f89cbe198b4572067ad80adf71a36f395b9493a02b2b19e9a6dbc1bde0e37707f90bfaac856230af17607a62ad193d41bbc1636d838f188e3b96eb0df0f979cf3d2c4a2321a4b1490690c42222eae21aa034367bc27f0d092083c5630f1ec095280532e0aaf5ff310f4588fc0579d87320173b132cca50ebee56953d48b1a9022c5a44c7d150d2224ac34bbcd9149016413f375773b7c79ac77d40371edbd0de553088d9c6366d257cce33061ccb1f571ebfd9dbb9cedaabc440f137abd34d50d03aa2271236a721c0966e269d32d806416624c4740aa194b0a49af5eae4fc14b4096ada91041711214657076d400be01b6d5d3a5791eabc336340ff3d739c9c829f4c30e9c84d7e1293d4b151711dc9e0c89cdb735e7b130c5ce3dd912410cdbb7aa0bd5ace880af8fe6503e0b336eab976733029900539e2da0ee633974db284965f480f2f0f642501fff4bb55e464b80ad9e71f54535cd013b68cc0e8af5fca84256cb670dec00c0d4c21ea23113ed12ea602f062a8b330f5ec20dec0d73929fe9ddf836eeae000ee829429b6a85bb191d2d3ea8733117d6f3fe4ccdd92afd896d36f97163335829ed319a606273997d22c708241d339049c48eb4973e7f7d33d12f3f23ca34d2a721eb89b97fef943490e1419ba54f90b0303bbbdf0c08145f3b0408b33fd31ea101d3c1cff2137f2bb91af1d2beb12f0cbd8e2647af20c74b73c33b5f1c8dbc0f7a5c984ea29e6cd3e656a06f301c6f6f36176ad4f7ab055b5f14c904baa61e5e72430724bf5320d80dc01f1a15e7b7520b0d1c06d28b165f0b9492d462f57d41ad83f04e739291c0471010c787bc57d9503f017824625e837f5aa44d16250ce6a19c1bb4eee8092fa4c9b14f4af9128b6e6dc3ebb167b2f7b23622346a73f4fc8a111f3b390888133dd6b1967d41006b154176f6f6fb75568823e8d3d6340e84d2416d65f53ad2e32a5ba86434f101a263b4dba5d43f7d61fbd1ff56bf3478b4e27043a2294142750914b2982b09247a5fcf18d90d4e8fdb328cb27c7cc7c0d6298d16401dddd57626a2080a0415d64c90c6c9040d24c9f8246ac25f760516aa8e0c01e9547d4b5108a14fb17554cabde961741c01dd84742bc7526c69bae8361d639342485160dd23d41832ab9b4e7b713ba1372b022e3d342da14213341484c123233f9b090017f9afcf830483ef9f00dcf67a9aaf11a74751320d44e0d1fc3e90a522c37aff1a134a141a3ca961073d06cf063580c2e6abe6c8e54650141633002cdb9c7627534b7ce5e490d5949007662a8bd9e28710cf74b29d4be3611cedb4e593a8508120121f32585189c1cfab8daec1e472d80f7b81efefff8bf00e88e36cfb570b386e46b7eb0bfd3e820083a7de5056affb4fcaa082be026b61786140f71e99625713447a6034e750fd0b5d8dcee8b71847696acbac20a44268d34612a177b077b547f02003188a2c7658ef56f8ccd0b2146a13de0a287e4ab2a3328087a0d8b4f47aaf81baf08b3f8b36aa254b4252aae05ce01294b2fd3f602c5349b73cd48051cce53e15ae796a816e8f17c8560812a4054080520e34066dc84596a353ca0770de3ae070245b191ae3097ec212adee19ac3648d2fe00f95d7d6db454d11c404c6a089360151a379f839ed3a5b5434ad78a6812c9aa5903bc07755e11d868d514fc42e15750b148a9ae55127ef3d9374df5c00d902cdfb6bef4acac82308a51923cd19500149c16ea5a2d10f74c79618e313331639cd84ddd4a22d0014bc061360793e9d1a894f37b9e3da6724cfe23fdea8244c429fe5fad8ab11edfb1f410271330d0af46818c9a0257c68e532d72ac09ec19341adfd2602ba39568007b55554f6f119b2aacc405fb36da46591a2395752dc2a26c5f50c3c09c1f6c647335e3fe1405ee2f45f155b41b83809c76c3957b7c62dbde18e72260a54e6128a4d132146c19974262d608980542b97ce099995517ddad9bd7f2812fdc378c4eea942b093f454140a735973413175697206635333480d18116b1124c4b2662bbb9fd5b4b968c6fc2ac7a4509cba3e236b924d624ebb4f1932314feb72e5350dd02bb0b6df1f0b7fb3a2102618fa74371033630fb01e50988dc809bb763dc8eef8925cc1eb2e39aa084765e3bc3a4ee3c5c86c87bb70abc3b61af77b6cc63e79d0674859f48935fb0a3e931cc15cb27940a6aaf5cdf75e06454c07860d6ad4784102b2a5635c566487191ffd55f50c1d4fd3cab89e8d74d1b9fc49f21a55a1598a1876c6e1e3a189215ffa8b477549113ddcabf19e7094b0461fbc6e944e09340c24a82038d8972856c4509bd025b9cab12cba0839db06ba63c3699df3a5388a3a4b61cef22ba16f125f1ceb2775c73d48f379eb855450e2d86b462e430391160b8dd00ca100741e5a48eab8e23e43cfa30c32fb53de0d46b0e7a36f52cc2692d3d5503c9f49c020828273c8740361480c2893af6ee602a1321ef99aadd04687975cad3c2144ab13135847096fcd258f291921850004108dd3952cb3194d306ead6ce7a9be0107be2ab7c04ac0b665551d0ed188e6eae8f8971518bd27a97603fc61daac09b931af9ef86ba854954aa84b63b582dea6c4c0068fb3c37490fed1b4c61feda700335f2a5e4b99af6f10abd92a2f9790521f24c5ab87677188695996eefd47cd88c45a1e75ac7e12b45f51398385160bed9217ab8e1bfd34d7162cfbaa7554b968107e00fc83c73930a90619001f287ab6092775ff7c8516a783c096704ac7dcb0dbd6e36f0c62ea03d7784d956e2a4aa67c5b5138afe04317bb6e41df78c7d6a6c4d0feb4ae895539c43245b260d270b1d79f11dcd2ac2672f8524b2768ced5ee35850c686826c170a837b9cdc69ca013ba42a438a76c835c23223041ae8e3420af9e4573d819b1e2c0e3c24ba80c312090f20fa8544f6481a1976b15d89245a9833ed9820535baae355fb459851348b6287b36df1223e189fcbf84078f06a8318f6695f8b35a05b1d1684b01c59be1e9a1418e9c624de331a23bd77c8a09ab5ca0846f10d884bfcaf184f255dddf0685cb0a5f9214cd36df0310ff92437e9a9861f4521155d7426b536df74442ec304ba6b659df83013ad04a61808195c60e8324b685f7b03060a3d7fd7d94eb537a5d3656cae9615ac99bb6f708e1f6715f393d6c6181bec19ca649d4b0fb4c1dc86bbd6901bbf1781ecf050380662ddce0fd8284f49ea097b0a5947998e95174ddc829d34386a402aeb912486813f8a16e5225c2d702b5570f0b57a5291ccc956c202a2c6c56c24e9d9e6df90fc008333ffface4ddb3a0b1acfe70aaf53abb3fa52c6e297b81573c42a35a6c4767cf5c69e9ed79e45a0200eb1b99841e90f644df93c1492cb4f8c8e9bb7582d245da82f839dfd97be48289d4f7424970ed618b27d48507938ecae9ad0823b1d1e2365b161abe7b416145491a076ef848dadc3f48a52d90fc9a64071ce124a1518e8a76776db41f6e4547ac87d743254663032ff59200c5a44fe9ff843ffc1f2e7b2dc2a6b6efc09a90bc6b88fa924026bbe662d72225b111d082503cd08a1260a5e5bb389df4824943cb032a190658708450743d0e6178f95ba85a9cff7187f6064ab9059b96b9824d4bca2d815bc5b8a400d82b3141438819b84018a99238d3284a1ae40e55c9f9cdff76657433b911c48aeeadd0e5f39fe1bbb5f8f935c4ba3351fcc3139bfbab50b04c6f3613457e57028b6e003729f1d41174df0ec932b13cbb3f617facbd08d18e63901e7371b1ce13d834492c6cf9e1567e83a4ec326aef803eb464bbdd57a024970d1ca697b01769319a6551860e7dacbae5d1995f27fbc435a940d74b003c2292edfc95ee628867f12d942fc7ad3584f17f814ebe7ca781e5d904ae46ba54292b8cf27cf5ec0561234ee603d400302547a6b663de396be45e1d654c76d287ee9d3c12a7c47bb491d18a62acc2489945bc65fcd9bc34653d515fa08ba34ebcae3dfe76680b0f8c69541e3a69ac440961a08426f10f8e0b1b82843f781cac5012e68ffd90b7771b95fcf6fa5d4175fd2473def8523fe3f9602385f5f7aa2b67a501e63e2102f60b550d8bfd560677569d088080f4026b306e2f7ffd2998a0d55195493633632f7e49412bf5fe47041c8039298d9779dcd828999a8863189416897d5f407d73d966543ccd76a09a31f6277e20a5cbfcc50b18ae543f68f846636807aea9226f1b36031ff022beec755d6ca75a7bbf270cdaa9d6553471e30e4f25d55a820b8a61357818fef94c812e9f7b2a2122381c18304098115e45d0aaf1d4eb0cd50f9bf9d3e9706deb2567cac9839dc55abd1a0bdb85b320a274c2dbe99394e5c06bd450e6d72b840c10deebae2ab48b570759dd18a8b587e72bd03ffbe0192d85bb6b69d296033bfa32f3a937d1e4a7374a42b48152749911804763cf221ff390aeea30013a634c39729cdd713ecb82d6c9ef2e5273e530813fd8b285193854e84d55adc3f6ab673340a361ddc474fca4f833fd81769a21db4e92ffa79f6a106b2d02dba0705528c6ccd1d470b68cad5021a3255ea284d8e52bcffa7ad1bdcad6dceec9439988b1ccb8334b71d40a15f561d48ce8d0e38df71d9a9eb954c70e7da1c912c6dd66717f4ecedfae1fb8d70493af7f64c2bd57b32826973d663ab39703e30b7829c796ec12a236b665472632403604045e5d295b59bdd930ce0c55651657cafd0094fed41955e6b3f30c6b6871f165f4bebda8d6835935d3817db9cfdaa5c9247f07242c319f7bc7eb52029b7791f97f14ff2728e74434fef49f428b8861529f0a7eafb2337899b8593f10df0751611a1a7aacc8c6e6065c0abac1849ce7f30763f70e30605aebeb0f9f84f845c141857e445465a1f78b10f868d0554f95b03f25ca823d60152f1b0b3de3ade326ffd2aa6c4c6a7d24723ea6f651e79c82c7a3382feb0ee13e04d1417600a59ac878675ec8f0d833c18e4b0d63b2184504cababd2f080003d49a8a818f625023c7b08c80deb93854715db4b7a26cdd2def77af4c06a2d9e8392ab7a8501e38603fcc2fd9c17520bb190135537ea4bc49767ec731f304250f47a6c8f775a71624d36f1228918e77f497af80972cc65862e01a8e3d71c449cedda82374fcbb675e2a52e38d66e9e0a0afd66572208e99dbe2d159fa3f4de19b45a7ea2c37ff2bcaba265878dab586f7bc377f68f59039b2a64c0dd60991f37ce33b88f73e94b4d7d988e6cdffb5624f05f29bfcba82040cfcb92fcd2f1f89e05f57ef80ab1cb3bdde78110c19426b3c004c52453bc5f3d0147463c19850642560ea3a2a315d70936e006ba5561dc1ea308b1f313918558093928f48532a3267e9c2e74b3375d26f60c7fd75659bd7f3c414406710b9448a90a39b8225f0d74e44ac4d42512a694741fec9a93f87e7ac6c0e5d81a8bef378453cd47955fecd31da7ad3ac288bea380c9f2e7009fa3af0bc7fdf348db9b9184abe3d89f3b86855a43cfa90e7b9c887796f37ca203e418e791294874e56af19712aa22edb76dfc95d100d9cb8beaa2fa25804d62f2c271ecf2ba0e15bfbd4514aa0c368f234008d87750d8e4a9f3882cb53e639e86561b7ba9100cc384713427e675ae8d211fbf29ddef8782e3909091f1523bdb4f6081598b7ab2d0f66ffccd9c8d998275d4b8a6a3198335ce3724dd88c808e876bfb141512a1784916b26128918ffe74834c928e844dd6c3b35d21e15f0dc1e951fbd9c79392b0267052878497e529a336ff5dcf39a80c9a282c1e1524b6136f7c7200c06f612b5a20ee12730bf3e47c9a1e28d15af56931ad2114233d6587a5ec70c1377dc89a0ad334c232b1b0b918acccdd01405ac684beb45aa655b685a8dc237d06448f89ad067136cd77b67ab4e2f6e7e8b0c8a5c12600c259fd2ea231bdab6f62348ff07abc367f95af7ba6fcdd3ed3be00d6ddc4ffdd0ed68d6fe35955890cff8909650248bf6d2f7f10d4087306690c130b60064e3a8fa01727eb65db1fe265009c1f9f0e3fa99923dd6c9f2fb880ad082d27c41e677c54a71373ae15ab0a1494e5b8eb0f419075f0592ade4307985cc3cca3a047aa606b1e41842af55264b13ede73b4dba2afbea12702b80f41c9dc145ca4454037300a52f3ea365ed92e5be894b36bef9941950783a9b367b4919b7bb4f07a6db6a37a49a9f1411261d80f5b1dad5a29b3f07df6fc1f9c19604447b463f96fe0c01634f71e350911e6a4530ca6ce009ec0663cbde31d4b427ffd1cfece17577a93d409499c51c7f1b67aa17ddabc01370380f638724d7b768b118cd5d879ed82608420395fc71465844c4a646fc9ca6c66a72d0fc9ef2e49e3bff2f8b87ce319435cada367394b1c09747a1134c22b391a211a619fc28327580be676131e89cf4fcffa9e44d7bd482e1280e99a52a8c69cf220e469b49da93fe43446170fca09a334c6629303ca81f1356c2bbeb9134de0d8c65007d7890272c6bde244a01638e2341da1bd661473bff8b0b5c704104b90215162646a7c28ce6989c38d8bdf504dc4d7b6b243c155d431c4bb6e5c575dd32271715d5e01db740eb2f37b55a49b26424fab49c0f8fb929686094a79f61789c3e0295211890c86e93a55eb086ef133425f80b513aec6dc1f6c9c191893ba538f16fcbae02b7d46f1a90124b09f96da91d7a4ac2a78e315a5afdff68dac77f50b3f9ded261bb06ed647cdeb4bdf5851b5537169fa66bb24d031713c35b39864a4526074e6c7d6ec9f87fe11f478e5096f745e1055fa3fd4d02f40116dd35da9628c14e3389691685fc01513ed37d0f4af51178f6e62d545b6a194e229b0fdb17a934754d94f8d92e76c21a663b76959e87aa6992024fd81499351569f6c852e5ee045352bb3197d04c24344cdfbe27e23a5c085be4f9b77d1f532b9a974008f0da5677a46e6bcec55898ce7b80e74c1efbfd2050a4c12716bb689bd1bc777f5f3ba440b07dc026374b570a0f8128aaf3fb227e6ce234e68013fb47cb0d5c22d3073863ec2331d96f92fd929bc497c43981b17a97af3d1bb90a971f1718f5ec39c7ee899ae7fcea58b63cad433fe0ae9babec34f125de5cfc5429eca217fb0c96d2c20834f9d6cae1446e2fe0f68b4d812d74aee7a6d705d4f40b2b517e8ff5672e8bf423ae895f1a322b9dd784c084ab9a315238b223b7249de2a9049f6374d203cccd0c1183a5808b51b2bc92d7266e827e9f2b35971fb7327d7e82b88f36e1454a322cb325f85cdbebe25bf72ca9d7b92c559a1b2d01c8bb415b0b815d84ad76b5a16bb98d2efad2eeaaffa667f99e1665dcc111a962a5bc3c61ec20e3a99113f159e97e0650b25bacdccabcc8b702ec732b9f48e2f79a20895f94754831ece7a86d7851a2abb2dced64320c02e10b0f14d569b87af2d3a17440dc296f87612be60a84a76cac02d2e3944240595efe8a792049faf9d5a8ffa5d000ba1b54c21de932ae0b3b358885cdfbd2dcaae02c0334df33e79fe9e6abff8533a72cc76481addcf05a90717327e854bf498e91483c870a1104930c7c4a7b0a2c38bdf74e10fac0e3471abc44ba90e4706a64a31432d7a64508601008b5a2d91b4b74c09ab8aa8e3ed7b46f340c6f324c79b6209cbccc40aecb7c16e53a2e9400436b03afad8f3eb617fb7f2104116a4b5bf9637ddeee9c1a8d50a709f9b00e3a58d4c38a581090d6080c71260a819fa1045542051ab6faa62ee222d89fd68b05bc0b08f15a2ec26ae76719d9741dc167eabb8eaf472e667ee818ec3d802be5992c5a6c428a71460b84dffbe4eed726cd8b85d39a5274ebc053998dad98fc269faaf072390eaf3913b3aebf5552eb26795d6c84eb1efa7c296fed60cdcdfa843c7ec948a6da7486727208353292f37157b96d08b8d9bf48ea35c404491816108acce63d4e3a68472337374744a44ed653e41d7d6593ef0a03be5520d8ddcebc29dd0f86487c7e9d3258a8cabf23401dac4a61fc2c9cc1e1c34994d768a4facdd38e45f6bc387ce7e6cbc4523f42c68780bf23b0ef180d5dba121ee533604091cb77def840e47f5491d50a6b7c2adeaa9b2140f5a53adb2856f270eb1470e7ddebbc884f0c0735458a0e26e58c555917d3b35a36123a16ae41b3386a83a4e49ba80c27baa5a78a6e3e1ae31988fec1eb7934374b763b1e53c6c18e2086a95f9708d91d15d4a5a1b83d1b863a80ace10dde2b53e7b8c94c23bbd8c42b4c3c2c3560129fd56d991731c6225019ca7a00688f549d9ad08a57adfcc2942d029f6a198af4d9656c9ebedb340ab2d3ccb3a55476d787eac4809990e80ad4772cb178cf8be360d23ae025c109eab5b30abd17a0508779c55fd6a40ab7e8486c1c2f6a754792f537ad708ec708d1ebb908caf9b9218277e225a787ac476980e50a99251b59a0b4dce5e16b44176984c73e4c245080601603bb0d056091d649e29200b245cfb166c20766243a4fbe777911bba9a9a4737479014dc5fb003fc96b32961ca405f68e205ba97fe0818868a40090c903dfa429e647f118742d6d12fd089784b3e6e84abb8d5e75bf9de74586ac5ed92c4b6d53141915aa46df7eba1809f8baeb64baa916b8f48014c6ca7955e9c908c808927d32f91f13342ba5a469bdb1c799cf14a5345864b5a52707b7f06ce1d912cbab734b5ac1a3ce8f0fe54fdaf1c26fdf12b6e0dd85480de4fac4e55a58a696a3398d18aa31c87ac2eebc5133a7bc2514a130ed1c466ee718b0996e27d041838544a1a229c7299a422a5cc23a8a29e4256d4683fe01a47306e5d0ccf9e103d389584908958867117a956af4aeec589ebc8406fd0821bcb8d722e1ca0d734a438eff0b05599940d4e94a299dd39c521bf1e1d99a6ee41dcb293e3bf40cafbe08dfd07e145231d1b03461b76d3f157e28ab2f08f5fb38f21ce173c978776c436585ef4f6f071ea2900743ec91f2f482d2a0ffa258da1c3540e59fdab53681ae18321cdc0dcab87d2d8b80611d251c3b662a43879fcda4e13f25856386326367de6bf313ab5b4111fa6191166692138a579108dc7cf2bc37054dc8ff41d40b694d45fd2ba886eb017c107c2a20f1ac2cc609eb8e774432ee09ba209f6d909ca3da4598a9909f43f133c248d801cb4147470a7c74421f4a40c678aab771fbbf3b6d4475f16706f98e1b2545f41007e482f0930a14b6eeb6724de35532ca1114876c81b4c5e3dc4eac47dafe2a257c5f83651eed3ca038ab363d8191826a7e07c6a74cc54e00e2d99c99a865949f79acf7d03fff309e07aafe12c0e9d7714349c8f625a6d29e15dac4181b71811cf5d8aa9ad7669967e99fac8f3d2efc7d9a2d727864b6b2f5e5a139405e09d18e7b6982620d6db0de0b710f14e987305e4478c32fb6653ee1959ccc4ac585a054dd5608ac261e50cb051542667ab4b5576a6a5a66d957cba07e7137dfdba290ed86a9f826ecb8dbae5a0361a7bfb7dde4cf22454f6d3c1e3d5bf1703eeb2122ff180c5330915b252a8cd129c8825003fdd00aa5448ed5b1a126427f82d645940aedce6c84544bb21c6891cf9c8ab5ebf8d32c207801c872ac25b51f4fd81ab6fba9a04cc9120370cf67a8eb708ee7d82860c977025ff300b503002f9d2a32a25f154464585741b8dd594b350ea4123b9936a1b089911e02aeba38e00346d2468ee495909e03e8ccc10e4faefd70793561aa51d6ca3a7910b441f77811df148555c71b2422c451e12a207794f623112af4092d74dca27412ed9454fa357af5a0a1c9eda58235dd295af9296973ffe13fae2d087b91ff4bfa1bb6414898e56113456ed0fca7754a3529eeceec7e76949afcbc440d8b1f1582cbb6fa24601b871adcfdf678b7a46d0199f6f5f3328f5a337d4ed78496504b5046a9b503a284b6bd9bd5737ec3e5ffb3e29524d2664e8cc919e336561c0aa358b3be7ccfe98562f28674b6ca02740525730357aacd3562a7c61390b6785e15b4301cef1ada47cdaa6474da633b30a79e59b92e4c95885fc89c455df61b9fbcb4e0e79be6242e3c18c6ab0bfe28efa8ab269a6000e4725591561953b73c952d895388ef2cd3d6aedf52d47e714375a814b1c8709fef3541ddbee33230a36fa5d341be70520e66e0e22c2e018ed0dc01addae70a4bbf2b186c0b4d4720063de304aa7a1c615e30b9c21def94bafae1abb477e3f91e45cfef9ff22f9906591cc210578d61df5be2aa31b1aebc7b92e3640b3a3a272c2c407390254320bc9e81cbb9e24d566abf73f1853c377ed310951325199ca95dc8ad5b95b495ca301af36f98d6998195250c0b668d45a46813817d818b02fd5263ca83f081d14a4fe4df656405d1b181572706ec726ed34b2f5ef499427d4de91c388ea66a41fa53155a0e39881cced14679828601825c04722064913630cf2e27fab4f3d827123f542aaa04f514aeabdb9f68c04474c3a781e18b0b898dd2b57c643f55494f7eac279f657c2d44caa89cb55c5e61f987ab0b64b8667542c4d11a84a34fbd81aaa6ac85db7b9fc73c9f8cd88768d68392783646071d5a04c471b2a48064fa5ee0a8f14aa0728ab423df88328eb070cac034e7a529e683082b89a6cbc36515cadb97b8480ff0f4c4e67e25fcfea841176f5911e2bc282f6b17fb6dbe7101b2b34dcc7bfa3fd6bdd8eb368531d7cd74fbb3d539e234fc7786f40a32537efe5c8c54b1fee58177897dfe3813767764d2ae40114d03c5da8bad743fc4c6153b1d95b883dc3a5d2b212db15e64cf2e41e779e61277bb62b4a1132708d3d9eb3823bad9149c03721ad9b42e405403f456a14e6b3d75f89facdfa68571ae057497a1243d98938fc2068f1b993f2aaea882504f673564e63af88f9211bda915bbb459d67bb797be080e86eb3ea97aa4d3f38bbf74d7779d2181e456f93f7743107631d09de8ecb154804d777703c9d2f2af82b2834856f8357530d02c2bb927324bcb82bfbd8d34d819e3a13453ed0e363c45ebf7a5bf6d105b1153e781e0f9119505b30466b41bfbede4fa4c1c0df014ee7c5af7e7b07c5174dcd6983d9cbdbd848f431883e28d186f96c5d9673cac4e9cfb492bce0b1b04a0e3b5739d8cd4e8cd4a07c45eade122a62e48896b165734891258735ae2b355932938a940252c3efb8b3c72e58ab40d9d065556487404ea593ad1fdf609026d6838a7d0b3275ead246597cd02d3cb981f4dc759ebf154a5ff235c591044973f7c47767ecca733b8a3da1828b7bd0a950d548ff0bfcd49628cc422eb54baa7cd438d1ed9b416ee6f2fccb6108b29668c1ae1e743599a82609180e4aaba0394bad553d6407a26931b208e9ac7058342e363019bbbdb7a2e498adf88fcafb05c7ef2d8ed09b1ce17883cdedd5462f0d4f192db74f506337463f3a5819b0512e5671414e731a7fec56900160e9222441760a7eef373e00d90e546b34c94f4d5e837173437d3b163a727d17d344c304ee7ba88024904e5f3ae7e2b184928b50c5daddf13ce8ebe6155adcaac74f844763bf15ada6bc5378e36f117f9e92e29990513ed215937b19ddda3e7f2b67d8c7e741193caffc8a072f23c21d4feddea5a5a02492321fbf84de8fd2702c938dae4c3014ef7a514ab6e00cb879fe5cafb76639e512fe80bfc1120c3cfa762e0730a150fdda057a61d39102b2ae580d5f2a40898dc7fd01da8b416bfb054162ab248496a2ea2c77d2ad63f81c38939f7d09d7a1465467e0f15ab956ed0e2ea11cd0fffbe0261b618f7166b76d8c213e35e06e26b53b05dcda687b72ea1090420ec7e1a3437568c3bd41d8bcce9aeb851810b9985d161bf49c99c8321d66dcee3b9e29df735012de2f204858a634b3627139b9499d4199315897ac396659145a632dcbabb7a96adcbcb3c6a6173e8db21b17d4627a6c989afcb74e8564cf9cb0b5a3f1a66c5fe7dfbc508800120090b281d9e2411165080c4fcb32470e68bd63e5cc2f0ffd0d0179343c8d603af1503340590ac930516878cb2420be37c00e2e119338e72081ad239f64d878150cea5437e91591f1fe0b24f7628cac66757ae10ff6b20ef4c1a8eadf3ca06fe767c9e701c996828d9b4715249d98fcc7531f0a1d3885ad7c09e7de5a318b5f7e1edc417e14bfe27827f0b054ce09c1ba9d0d39ee22f6a273a0abee078a6b9ad5192099946af129b1dd484d59722a9c83341401198ab839a390b3e851e6ea01384dcb0f75e029a5816dceccabeb2d2ca8ba4e1cf272d02bee3b0cf7ab5f4fa5fe6b554016bee01aa68083e883e21ed8c45e2af6fd268ea3f5ebe15d1ce816a4905807d94c8cdd7f747f89b6c1ee46fabab32f38d5e03200249e76a75e763b8023a5caacc72b919e1bec147e8d567d6991714863a2470c323b811dc246487a46fc085dc01526ce8949c6d6ffbbd3c6864b21e4cfde2012e28bde8dc55fed540a54887d625f7ce247e21fc279fd34587573a0e278c1443b0e5352110fa2d1f118a45cda88be3183b27fc93565a0e0f2b683f4384aa61a034458b424f23a65a04f11e7c651c864458ef5885411eb59a0e4059010bbc52da451abb458e1c44f0d5813ce5500bd91602a8fcde355246b432acd73c927cb596c7dce73d8a6b9f3fb9eb4fccd806eb8f877310419c9cdff6358101c5d782afba906e77c9a0f3fc8c4bba01f8da385e07e2cd6f31b083632c12ca51a1c8918c71796b3060d99c0ab8f520d94fa9b98a2581d3a44504f6622179d113d3be2807e2570e9502c8326ebb848023f4df7adabab2f68374b5f10692cc48b5f2e2eae04051df751a0aa3645345220f6b19344d97e60b2de4c4a825488324446ec0e22abedcf19b91cc05eeecb24205856fe9d6e041b3e7e4df0aa61805a87d8e4874bbde77558f0a5b0ab869c16a31dfabaf36a2c8a664011ec89ad04053a177d822f991c9c119beab294d7ba984ac0829d03d8d6c9f38c7459d1d51292ddbc3ceec758e02b87783daa8105d65ca8f2b331ec5ae0df043bd6c0677ea08da510b6d5a1cb70a8234bb83a315c7ae41e280b213830b5d383293ab93cb86be165342e9d58f07714e8214faa951ba2702e5dd735e241216ab706cade05cb68519f99c6ebcfbca274af9e3b14153a2c427a7a449d39129513ae65110a9b90c00223beaac12fe548b059085b8b8454ab4e8216f24a405858f55814023c0514709e848cccd559e5c94c91b44afc2be7d05a4b22a2bc2878b8377f46f75fbc0af9f66e1cb018acf85aa80c6d0edde480665639643a1799ef4481c23ad4b8ff38e13280018ece9983e4e23e4783467032e21df156124a130557d3ea4877bf973c8663af40df06d179b48902353726034bf9a4966e51f55078ab775dcf901765bba7429cbba4ac9f4782329d446ba2e02cd038f462ec353d7914f373b9e0cd2039037729fcc59cdf5edd0a304074b09b7b2fc57130e091ec89ad4bee8c18ddba2ec16aa10564e1bc082be380d8d4c817c2e667093eeb4e4bf4701aa0b9a4a5ffb26124c273720c30c91c05e9fbc4053020bba54a5d221d345834538cd7cdd91597ef24b5898167d599983213be2ec53ea6536eef0301069d1682e7108037fdff469182752cb9ce8200cc4fa25a461d50f83300092c265dd4e9864a77fd58ba49633c902f3906a4c6bb354955d4ca363b8f97d79bd416466ec683a0e9589c5f27d1b2e1d9a0d7db67073dbc821374514b0b60d3c114740c650a07cb2d5a9ef8b67cd0059d1a2741f52645414dd0552d7bf05ff027878e334794bc1ba4d15d86bed4a0c6ac0fc4cccbf9308e6560daaeac914b8fe34f5004112737db5b67025f11fcd4a8b16b6e0bc6345d91427f1f36c7606f94d0ca26e4e0f0cdc775817e80190d327a0a902fd3b68d07ec59884001d467e48d4836c089a8f3094a28ff09a6a6e044f2b76fba5f8bf1d21147fea5b1d41b20ff046a2b689512ff04fa218c6c41bb0e2fbbf3e025de297fa524207e141d0a8eb2c11990460428f63a7328e86e090ca87fcbe2346507065aa805251da97636c08e28e5d5ff0dfda24f549e186bfbc24e4c1938d4c94b02833a81edbd214e72a8e995bfff195f8c5b9f1722df60875bfc1032ed5955a42b448c97c4bb1b338c7e8f42e3585f1cb107543063718d672e0760e1217bf26c002e84d8d8093ecd1a8274c35de1e1fbb8a990db00c70b55949fa8ed5372114804d826606deb2016810debb782457b49639d69156744ea7cf92ab67f39af0d0b67d400a55473a5bcf80e7dc9897ab302f857770496154fe572f20df407dabecdc25903bba241b1de18ca7485e653658f2586062b5a72ec92e0e760a19632cb31037fce782b2c132eb5fac2b91eccf55a9934b01bb5ea93c68213e5dbb41a2b53a6e667457e21efa58e9cb5d379bc29b1ff5e9105bd13a2f1585124e0595fb83986496ec34729a04af94e430ca4890514068234d522d97ae252a0bb43469575314f3838f54623fb6d2b772241e1fc741597f2758cea50add295a39be4aa34d4efa0a38b6a9b9a998285a327121896fad7b6e238a0aada0347dd7f6a098312656091c2fb1f59072b2a7ddcc4a14a80d82376a4c47e4799f67cd0b0802444818d55cc3346015a1188c0d6ed0be54630ccc5478e2e06429884f624e0a4f734203b5b49a1c2212a6498fb1e1f25abfa0cb430b7863631a3f3f1134de7044ae44bd1b9c9a7edbb903885bc2ec468dc00b7a2cf832c785d910dc340b71d1edafc46012a6c88e8c84af2f273d7a5f16669fd082b89ff65b37e1671bbe355a013f0bb7458a84bc62ac97a68e8cc792fa501f198229b86d3cbaea8b6fb365024a4c7c411baba8456311c030dfcff28934e57ecad2820d759787fea87a05503ea818000c97bd7e9eff563ded23adfc35bd7a0beb27e83887d57d31f41a4cc63c67a6ce1e43e6a6a0e82d1f7ac26917475bc91c1c333562b1fecea27a608a3ea761ff2362a0fb5e29ebf090fa0c453d3a76e71b14cf1d5faa58c7724665a3e9268bf025b309cab1a985df0f7b210e37beb02d0214dbc860577a2858f5d000ad75f4eb995d12b636105e85b40d3ec60c72ff8a162de42991c6dcf37f8572f5b8227e8564f0b3514f3d2240706042472ab295a4101ac3c79bfe643da89c9e39403e4a2a2352d36d5bcc9105d7f2ce5676bddae9820eb49bd864e412dc7f26e313bd27655465f2156e2ea11c3bf8ad82284aeb4cae26adca408002178b79879e37bb7a42bdbc2c8d4eac9ba642afeae1b57b1702bfab98ec9c959731b95d14316fcc897d20b1a18c4c2822bc4264e00290038601bfb1bf71491077215768a4d9d6860baf6c30c02ca3e8f2e677fc3f13bad61fd1d48727140dc7bcdf5fdf6816d5874cd1ba5a008728c619ba12fa5aa5f2d1ea1ee619c1e46e33854f42d6b2b15fded4a49ed004440016de8b7fd617fd12559b391a5f2d4af27715bbd6c87de5e55c9631be259d0f4695b9827128abf8d31d069691b887500e8255fc055c66054ff86b836dd3059869dbf45434e07d240e6ab034eec37c85ca926614a7ecb577e60af586ee22c0ddf32e5d6a8c1e752e9ee6620653a42bda4870c434405a3ddfe504f076528bcf9cd1b7447ff847b89a40d717686aa24943ee547a0c64fa90116c3af38840f7567a64986e323295016dd44b09dda9784b7dcd541d7c370064d81056efb41cd85453672c4c22afbd818a03a4be7a3222f381c49bffc0b793488a1edc81b43ab43d385bf65a9363d3a2c5b936042cc31398b711f8799e7db8db44b8677fd3c7d8bdf0321a0a19ee132f377736a0107380da032d9407413d982869c4701cd9b05e1707e4f8120b67bfd2dd5e285e864d436ce5334a0b6afeeee2609018f19fe36a0bf600667a437f0bcc9f6df8f124ac394cb6248f8c398b0e72358df6946bd503140474ccbbe23027bb4c9d666b59760e4d4cd02f6e93dcfe36b2d7baff106eb26dce9ef13477d54c8b42db36cc73551f395868904cb6e551232aa1188840fc905813b1c7aefee7333f963ffa2df3d1d658fbad58d91b840c8f2b5005b90177c20515a0d6db93e2ca6c6deeba96b3f1ad4fb1e708890f89f4bc45613788b124b0031ee4c1931880f92af14be08ae86432b72b10ddaad32f30754cd95d97b7de5b254be18a276f8cde9ecc6e98576742a4e89cb0e47a3a50368b541419d8924e41142e953b5e2aeed6afd499addabfb1460eda4aab89d2d1a33388e629a280c97f4a2213128b32862bfaf3b04b2b48a5b57a0997f5b1beb778bf0a116f7322ff256ff10f0db8038edd29ae84b790ce4e0ec28382d322c19414b3e6364c3f369280b9434a4cf23e34a8a3b428e792706d29cb13d58940cc65912c6f5cc423473a999907c721d2575f9a4164d1b241eb10d4ce0d7266fd18a186b86d30991e159468f8905a0bbed9ead78a796786f101641c24ede93b44057d456d94080bc6fcd0d1179dea03c4b604ae4e9bd3f60e7badf6f3f6637dfe1ec51b6d5bfc10f90e9bf04f220a80a45ef2d56f16eb31d79df495373c6bf99bc5d4777c3b5a9d6df5876b60ed366f70db525c01711f69c2a84736c2a8a790533b4b0bae2c95ca172f28937184e16ed545a5e121183c91515cb984a31c80cf8b21076e545203c934c755c77cc8813ad688ea368d9e385b5d4f0effa3f03ce0d15615a5445166dc61406bf679bbd73bfbde03fc6b8dcc032e1a61880fc59ffe039839b603c748812c50b533264fd6401e92dd0a86d370ddea0b44ec1ef736ca869617fbc4d3939b7daccabbe0e4372a9f3cceb70d7bb000de74851c3a93e7f3da06f1e75008deded2b010b067e2751deab5ae31f1cf160f4315d6073cb000850f8daf481cc726115baf3871c739846e8c27480cde323292f2bafd4412937d58aca8a4a4a25eea7434de4a2cfca1c24f8908fb07b9156b610d9c700dc6df4e572a86811eab4c14edcfccbc125aa42aa468eaf6b32313ab0e5d721fbf528396be2ac8daa6cd59fc24c895ae9e70ac251c6f6c779c433dd112d1ea326affb137995c0898ab255c77c6630bd50c0c01e563d76e7923ba873be2964e2f385694f5a657bd3b6542a1e675589e2f3d9764aae533a712e58e1fdfd8fefa97406ebc748471614345f5be225384debed4d72dae3cc94805f5277fa2e87f7608b917c94a4c6e4092c4d1897656d928476ddd44aafd5345da3cff8846355cd17cf587b43186bff12d44aaede9c4e720fb754e8440532e53ccd919458331d35127323c3020de22b2bdfae13ae44c9caf5e0de979b7f682d63269a30f6860ee529b946d941e20af8075e4c627ba42dc76be452d98a95123efb66eb2a32bbd1142e98d206d73c2dc7d407f0b6f11d84bc8fe74da4130dff8a2423dac195f14daa248b8796d4fde123c24c6f23b4bf4ad20586494014dadfe44e4249a65658f80e3e6d6e0e2e069a353644bfcfc5043618583d7a7b554d16c133ed41b4b484283dd1f241fde6d735f815cc56f297407762d9873729a1971478367965e155db1026e771576a61f86e6d2cded878591b47ba1cf85cb48a85ac904aaac73f017adbed62df98161a0d7c2f569d08e9cbb2d3d51ff6450acd877e717488502f15ec5f3d1c1cad6144ea29265706218ceb980e501c845edbd5ea19497b89d8060b555cc647339be949d240d4d26445e209634c5b6ee4b78c790f72e60f35e50675c3fc4fbe1b9b80481bde448536657a6b40f151a85b2a12676afb2306bf1ced3f6d90827e9a1cad382fc2b0c7c55afb25361a9bb3cd7d918460b5f13475db3e7c60689b1620ead25c4300634a1d5fbcedfe6660c4a5f1c114035a973b420a84b620af886c6bb85415071b03e7337711b9a031daad8266fd8479145f1d6e273d0bba4739b60909ec99fea9ad42e922a8ea4c501dda060b23eaa23afe44c26e46ca6d0ab8fd459245c9d0dc612e87c71f8c13222fd0cb968ecc863e44720a745879a94ff063563ff69d693ebadb1afd52de97c89540fa53b0a2e8f8585231f2847dc6d161ee03bad1a2ad9f86b03774ae256fa94bf2c7f095a0c37ce40c2706ebdbe8d849fc2b01d1ffae18099a9f1f4b0ec8c66a97877c20ef2895305bba4ca4eaf3754f21d72113fccb7b2469e9ab70b6c475a4c15db32f4975b92a3c753b624405359f9ada4050a72bd2222643e830032c2f522e9652a87b86f4a5b637049d2b616b915e05f102628a1cba6da5d81d1c7336fb23c20a7ed205fd3a1edfd4d579d1097be03fbeac8489208b06626b65b9ba63ab12b84a3d91a962c859168c994e3d59c8929673862ac662b9c1b02fc6b0c4bb7693c96f9c64c166f9a4151c67615a3801c22c3e7658e9723e15fc4caf1eb82d32756cd7396eee8e9dc6b0b5c67e1ffc03d074e93ce08ac5f8fcb71d2987bba4c19f92958a17a5d0bd805b735004d9892f6ad3467c8e45ce62e88d157f691733670ac927f9b35a9c8cb4f28c75bc416de9812b642bcfcbc5e4fbc99b10c04cbf524431554bcc9794cf789842007421a7fd38510a4b966dfa453e0a51b91d256ffa35e1975bc44363c189a6cd7836e39e405e37f8e593c987311c20ac0817b8cfbe88b101df9de4f9ab2b56e3ca4b3cb484c2b219db3badd2a99363418719f7ad8709f7eeff91912ddb1b0030ee11ca20f9657e8c8a62f3c9901cb2f33b01546451f2a137c7ed1a115ec708ad0194071adb8c94a9110e49e1b230ebd5eb9568cebd14326998bfa25bd2b0cec31f269dbf64bb885b838684f7d22c31da6369370d1891337de1050a99f2fd57be39c31b54ad95ae56b2d1ac8341dd8229abf3374691e73b61d3f0055e469d2fe4436657f05408260589c9ea02db2e5cd69b32fd82521ece16140aba32333ef48f091b2b0386d892b571c1991fba20e8053014b8bdd44d9cc48af800b50c9454d02d09b3b304d50d7383314250f41e06c1d91246d65d9e3e57d00db1bd5849a4f2eb576146902ba14b07b279535dd8ef4d14eb1900ed3de95975e1447566cd9b58ef3d079743c8fb356bf6f6571c630219f6b8558bd3e11c925f1819a1f33df1dede05b30511421373c39b66cab1a09d2d864a5fc53a4aae346a315f1c5acd6ed289dbfab029c96ace62704c2ad9b879fc171e4d9b5c8f3fe0e61047e26a19c48b92f918e41a53a50256ec551d0c4ba746ffc4f9c57e2e59a9f52dcb3de5af6498f85200cb9ebfd4b94d647b7e6bb25729e5d82915f9bb9f0753140e7e9b2bc4b11cbded1896c819e8322b6c65ddd444aaa14ea06bcb247319663a3e189c391e74ff6f52189d228128eff9b5890bbcde0d2bf1c542658d34237c2a483e45903e66c0fe08ca70319455ff671d353028a18945049a7f9b0263bddff2dc097ae236303594f3540945f5ce0b469c7c48fb4d29e28614d82833928af4c562904ef13a58c1cd8d95b00818f4c15eaa1329dbd7f240451b311b82b5c0a351019efe8f7c49024401ce272360f38a4979fdc0fa7fa07fc5c31b7f3d0b4cadf82d536df0810541b7850f3148d3670b109a78b14ae0b305698947c6294fe7418ad2f920e63ca6ba63010e8a10570b89fbf097c00debe9dec1d06f37bcc35a4987045b2295053e7337cae3fca0949e2e814031c7b61b8bd510599d03a1942bac721c137378172d2ae87d360605e3119bef294c8173f089d0fa6009a5a44daf09efa3d2240c652534662b6bd4f6e32b5156f670ee7e0bbd08f87f91af4606f22d2918a732009e7c53483737ab713df924fc20403776488635cffed51536ca535f06fe7e385964a6888f98aada938d3c2f0cbd60f071259e6da58a14e51244bb3eee01867af3f2d37a88a48400f621ac2e57b807cce4253d211f11590a53d83633e320d40ec01c360d313a3a2ca3873b98093fe05b3f50218c6da19eaa1926bb8bb424c0c406291f0bd5a93fb0e70073e6a6efdfab1106f969d565e518d779512fcc05c345b5b2e9ade38a5c7df2ed9c50c222015dddc0b68ece703c7e7b374c4e0d5767fe12b597613be4c76512a1408f9a2da38e289f69526e7cfff6b7634df175d380c498603059358061a72077fd1cbcb8778c54715283cb2ded1231b8f973dea8c1649e1a05e211a55aa03195342862ab1375c547a95813490a0288f6c60c4e97b254965219e1efd1b8b2cbb60e6c24c621085b5447147f52602d4074eb25be4062a6a6254c3ba0f26f9af436cf6128f6ab56cb704bff1b26354513d60ab31844088c969798c139c9612545fc1b58a10669c10bc38f0fa6702de3e332ac2f8b296d15966589e91dc2a4bcaaa24d61adccf04da16d82050c8669c9311387ebb43da2558f8eeda590f60f82c757d88a26c095fb97b6729a453caa5c7d1a6e583d6cfaaa83699c518bd638423b0ce8039bbc4000984cd35324724f67c98a73087b07513d3c0f7b45199a0458289161517ddfaadb2f0460e9e475787b2356e20b250cc9693c3cfd736220dcb7a45b12cd5768369c8f08dfdb8b359f93b484c377f0720e1ef1370712a3ab8b02a1864b1a99b23fd991fae1527643b21671a6e0e022489ae2069084b90309af9f500806f29af0e983c6236864186edc005702bd45c589ada9c47c97151a6619b77cb231766db850f1eb32d992720d2864b26f933b3ed0b66119a9c759bbbf149e771c387ba039f1b0050f99b2e825d3fdc49d6d316be8f22527bc5baf517eca52c0a106d533892e1287e7cc2f9fbc036f032e05fe0331871c67a5975982e41f21eadea1050093d476a19c0f740a344903eaf561452fc0c9809b2d311b62c500b1d94bf1affaa118c37a5b60c0df1e7b188a85e17a60c635f6c63561dbea57eaf2ffdcd39ca2f5a9b452a1f36bc88db25b0dbf04b345bf3ba7f44107e2bd9eb75791856d6736ac4e9478ceee8e4711a588227e527c14d1e3db4d7a5afd804454b1ba27ac9cd9f9b7cf6e9f2a5564bc1342fe399a9e7865d31060b76edaa54bb76874c31f5295ffc658d3d00d332931af28957daafabec565ace8062cb9d064e8cb8755724f6588189134788349e7f88f502a5179eb2b2adcbb6c86c17eedeca67f15df801b43ae475e0f9cd80c9e8d3e3bd2c7ad3c4f29e196a8a4dc5c313820662bcc29d45bf2893fedca288cbcc3209e24780a47f2aa38cbc05c7dc7e0a52e07f96e8fa6498eb4123a94ce506aaeaff98d3516052c0da704ddc3a18b81dcaa07871e0631094229adb3509eaeb3374c0e1ee659cb6dcaf53a1677c61b31587c491f1515eb5f95a0ddaa22d5d50a956d7afca2614d2d4a9f164f677ea266f0673398393fe71d8e7f276a840de47a87c87b800d1c7ad0abb6dd1464cf61e2cb98400459d0b2cdf15a0d75621eed2d5d31b4226ce0132b7e63853829f09023653ff70d5000d8d20e0a1646b4389fdd1a97f84357c1767f516e44aeda64ddf1b20859711e6d22638e6f4b80b96328bd3a4798d1d773e924cf7ab1517dec0301b0a1f31b69b27020790f650434f26233f5d4e8f1e588bcac09761bc0e7e67063796c9c8de9cca8a605404f1d9e6f0aae00fc72cac1e1337fc6b11ac4fba0d34e00ae1ff5e57bbebfeccec88eacd3041321487bd28d366e3c757c24d747591eacbf570d6d9fc8a522d820e4b7fec63593d1cf4f4fd2eae8799880d160c553802b6eff3e11811f13280d839077dc20139e1ba2c87908f3e5218fc441c6d3d4afe17229f7bf5c4cc96d521e2f7d7659726a1d4aaaaace06697e930f15bba285e1462ef1d1e5ac72f9c3d06dbf6673a9c252a699825992e4a98d6c223e22b0c4281556c44d5c4d94b847e5b68a5d235007891bd9dc16afda97d03999c4e69bad1f602f8a893323f661060659b2b92acde797ec579f932500fcb90f6ec9d03af50ab9e330e718201a60ca174be795e4e11793d9ffc66023a3f464046041629ca7f204ab60f881496bc0e07a6ef17f44199bb06d7a5901d2a8a5d97139794694bf4159bb9712630a1ae32bf64a995f3901aba0caa9ba822abb9eefd04654c1ac05a98d89911dbee44a7df2c903bf720eb7c237d251926d2462931488cdf255ae74819fea9c4c9a5db9057e7ef7cb552483e251c1ca7566d052e990e7501560af69b2e64c0a67f93fda0c33bf41c8377c669d580f8df11873dbd96b73e4941feb115fc8ffa399fd2974a80b16dc7c7efc9c1f9404c5df19f6cbad024ea7b5c27999a18250aa620336a8d6287673ec639c6593da56df02585f01953e4c250684b7f7eb22f4bc0197059d662ea0a2f446ccd4bd4cb7115024d019adf25db7215690c84b91de3b2de55e8b81e5f640f524bd46ac2d7620ce369e08f40f03b103a1a78f048252968835dd9688211d9df85d69bdb8480ffcadfc584fc9929a75cad66e1a45b45a9e4f103e54a53136b52ce8143e293d315b30e0ec88a482c1aa0f5d91ca1f8ca1adaf88ce7c1ade7e78bec50594d85018ef9b29fa5b43cda06c518b241bef7662f0bf0d688213f1a0002acc15b90f6bf244252787000d100f5bcfe9cfbfb0ca04fe0e2b28282ecc35a5263ea47826988a9bd0c7840c77cc0094eb9cdb42f54adceaa52cae5e71068437c1d823d08b7c334115a8662b19210df4d6236b8a76edce508528581e3e459226a8345b810f5a6767feb94ba3425b7fef2f9849f10a29d38112ed0a7f7319cf344295e2d15ad6d0bc5df6f5cbbd9a15efd6a2d2cdf1c0914268c0696276950a845a68dbbaa0ad073ecf18bc82a513bbb41f75f85da2333a31234c6fdc238e0e2333026bfde4f878d0e2a959c8ad1a41adfba34505f9f8180006312c9c76c2f3145cb6a2edb105f576b4d00a8e680e60974204913398b16ff623072a8d74680e506c4c2ce0823a1cf0983073a6a1d79b5aa828b5d46941c6da3becd12b526e05ea03b257694b29370f9c4242c3eba58c2bea350bd096d36ed1bd18814fe8f9d708730f5a95a1b4534c848942b0d5afe6b0e4c3b4e240ab3820535426d9cc91fa768c2072cef6c2e3974876049e5652404a01b1a30d1b6ea10c1b3565676423a35e556e6ff67c48973a8dce64ea2f2b0a85c1a5764d5a133cbef4829499a31eca986c23f747976ae4885d68321a1a3efeb3cf837ca75b80362d44c2c24b35e3027233dfcedc7886454f878c263bbadb9a6b2d14a509726de03d9d5e2697ea29baa90eba97e1338057277c1a47fc9967783e50b9919457701d983f5d975d7e9e96625af4b363b0a105f98a46c7c4d1462e96c512b6eba705b534a2be0072c5d4b79838bc1d00462321f73393a69e9229ad579b0ebd94e684dd1cd17285a22589bac464279606939f7163ff84f23d89872501de8e384c756a870ea921257283441a9d66d73aea27d40b36c175999aa7b89109799e34d37b00343075191c07e2bd0666a4f048aa147176cef496bc217b49e6418e7873d625db27b5024019e62d2814a9b938b38fbec75ac90f9eeb594e114886ef54db031ac8dfbd139a44be78c833edf67f49945641a7c5688b3f7fbb3ccb2d85defd264ff4ff17ea174d4542daf1ba18c8a2662bc24584b6c2318d652c6add87d6838581abad6849d76e161c491484746c1b2af16555e84f043329329ba0ccaca0b9e6318c0e6ecb7f2f1021570a0af49797be983b3e3939d15d612d1f37643be01e2e37a680b69d2f5cef2fa318d206a073ea5490152db827edfb0c728a9ebdb347ba44c5840f4ad2e373b38013fc53030fc7a1070af8ac893f75c50f4030c42842ae213c27d105355b728aca1541e7a1c4e71de0d773b0e5e577fceb291a9c5fdd13a648b323a7720ba895615b43039aa26a6513ad95060f4d115a55ed11a16669c9fc3321008f022cb2214eb7aabcf0bfdd4f8ab67767fa2cae7c8ad368437280187fd37a148d912fe7a4cfcf835a155e430bd5c1d05514617f1ee864dcda9a7ffc47458b04114c125219db72998c0675a001a0e7801b082a90439a38b28252500aa5009add04c98ec9723a858323922bd4f7f02e640fb59086a4b585f90095a46a5fbfd690ac1e09926d14df4d8a35e07c945a7e559ee97de1012d9013d9e94c743ca5cc1fc0036cac060e6f0955a573d8303803d6b952187c899183d23bd44afc00b92b3364c589d81d13d3a28441ce211d4ebeecc5a43b7c1666df2ee0cde45eee28e190eae9c42103d995eecf7238a4e20ca760099fc690ced8838d7c1ff59c3ef8e2cb5eb6c2c90950d5051b5f74bdf1ac58ae0fe9ec34310099221c9ebc793e31e47bd9bc6386ae60bb05351478c1a8ec157fcbdd3f3c81dfcc2270f977b18173a41933e95c34d82883aad2988b34a714aba1d7b68ffc06bc4ef7e0b6f4945d60d912df7627481a75fa874210accdad02613d9bb66e42a12901484a650a638442f3b21de652237c435afe5ac25ecb0d0cf8c155ffed204618e280bbb83602da1abb7c709c7a7bf2a0efe72c5934f1af54cae1f127fd9584ae7eb1c004462469912a9d2ded4aeebf4f8752721e2dafb70f27b6ec0d93f2c9535651f4ceb9a2784199ba86b7237fc076169d9a1bc8ca371087dca46c41f54aa14f2981617350ea4c70a43332683b77a5a3da63b73b5c04fd0c3ae8edd19bd50e42fdefc61ff6eea3f1917774924785af02e88bf11ef566e1c7121722752dbe482e9c5e7e6a872d3acf65dffd6817fe6bc80f858c981425fb2c9b42429cff48cf9521d2e6241a4ca479dd8fdcc32b2c09158b842b1a26a701c0012a00d876fdd1bfa137be9927a907283e912ff7376406568d22bd929d1627393c0c825a40210e0589a560e9eab6c10e980a95d441eccd6c8201a4d90a0a1ceccb5705f16e295e2a20ec0d04eca2edbd549ddb5f711ee1de786796459f7de8eedf01a8c999c4979dd0f97a94e6693b0f9f1130d0716282a384a6beca988f32221479802e0550c75e91fe730290f909f2c6056df2d95976ccfe592e5e3ec5ed34c73013f835b36b4c07bc39390fb2e52f3fc47c9ba14b717130710b7ad9d5bfd91d0120225b9fb5db37129e16f09097c4ff77a95a8f52accce80f5b57bb09502c8cf1c1663abde4eb168c923d076295d75236741e86f4cabc6eb2bcb0a91718f800365ffca290b41834cbff960d8fd81a2855880bdc201297cec2a75faa18257a6db3b82987b58f1296203d78e19c89cbf8d5d487247ff2154274b131dbb060511837553a245c7ca7e94418c5edfaf6c45ace0f9597218a4ec516ff9a04b5859e09babd84f837b635f4784a796f89318c40adf3833b7328ec4bccc354d9d55506c4e8081c87a98f10ea492bff299961d04a6d42761849601f48407c07c1ca4ea6c4fe8804564e2cc2da04745288728e4ba1a839c169ff2ebe787280e0e967c909bc8c03ec9f0903459ad21169210e60afdcafb436a9bb5f7c7eb1746afd9ca4187111754135d51d398e438109a97191bda76a880818c68b801adba4ee9d45b7c0d16cc2bbbef10348c902edcd5159438a3790d68dbc2a4214108b6d0b04672eaa4e045e4165e60b12887a8bea0ba2f21a4d08f3beea31ee02e01714163fba8386cef3be99feca2dc3655240dcb09796e5da7eed7e4cd1055977c115e9d21dfd95040b89f753e0b85be2dbdd5e1de3c0339fc58474c6baca5f265c5ca92cf9ceac076e32610223280778817f0bc681a2ec903fd17e4146b329c50134412f8f49f54ddaeaee7a598cd08f9450dfac81deb463715a8abbe2297a446bc77dce0b0fb1039f79efc0ddc8acbe2807aa8bd524650f7f9d5cd0c6707ea5edb3ab6e5c3fc103c87172c1e5e16bef0643e73af523ecf12cc70ebcb76c63749c8cace408b74620f5c9c6d1d6807369a89e1cda6ebd8186fc6e0029c28a59d086373e00678dfc456b0c410bb9bff42ae1c6dfab45f691f19395001c47bfee1f3c4a96211ca1b11617ef9d0d3dbe0e773ba412cc42aa21248037406ebc6492d824f99390c36b43bf561d23f0b6bf808ac48c0e0fe93f281c382c180d38f091c98352e26378ec5cd1a82b1762d17a50ee2b15f201ea2abeee659c3cb3fc58d51c177a3adc9d4b438edc2e9e5e9c998b192295a6ca5c1065fb4767ba8d66bb95b5be762eec4673ac0e0ec265e09a57032e4034b15b43a26be53acc429b64e8f42b55fafb88b6424c9ae7aced63e4a7d058903e07f406537a22cc0a951ca90f658756b5e5fc6a972409c6c108808b090487718c19da37c6ff60fe854bebfc0945ba1825c06e8a2c0cf9ad7cd8a3620d26c22e88233d35e0725d2adc228506e29e71f4f3582e1c6e1ec03ab1011c8b77b1575cbe4960d0dc08b7c590c73d3538b25dc0587ab723c7e216208541357d387c058f3e354cf6305ee97a8e6d215caa90ba49fbcb8c836d41d28b404663fabef506708bafb6e3090147a205ce2170814bbeaf0340c2528e2b90c0a91fa505aedf22831b1bd279ef04ba48fa2eb4a8868ebf6c74ed374ea5f31a17b61765d193c2cecc79ddb13971600e5298446d1d633641114db0366fa1842f9af55d26fa8bc1c0c77f23d02ab7095312326b660eae8a433a622da2199948d9e1073e61c558ba5f01eee817e1dae4486f4bf917a1b83ba65db77566e8733a2d32afefed93c71f7715b5484a2ff315f93babce640cfb10b343cb19e1cad5f97b37401d11fb204df467eb76dc04246080e241609d72a08e05f1bb21e89676155bcb432735fc14414522893ce28f9b9197cb938c71d1fe52e0eb8ea45bcea1bd3c27845d3a9eac1709684483859227969c1c839ee918e0bb3f915586a3ac14354b408ab4688491f79b59be2fb96268e719e27bb60700cb76b8bdbd46b28a4ce75b2ac7f5c3b8c1f9f489a791873bd0207c3fa7abdb55dedca43831ae7e99e1dc12d2aafe51e51cd3e98f504bc960bbb075d7831777ee20120f89965cc630a0d80f0b59dcf410dc4ad8f2d0b26d0f83b080d04d049ef18001ef7892742915151b11774a22d809652ba051c119b63a996dce93d0402f02a30c0670b40fe760404cd96c4a7b4cbd710f05cb429280269ce6910c3a6d05802b7819291584e8dba94e4237255991d29e37dfb26d811a54aba3dc2fe22adf1d0b7d8c017600684a29b612209283f48b904eee4df4b4576df521b267b0d6dba3c918d20212a83da454569bbafca8819f8320a60f1a63e6dee47982380a2da0600d85e0436e37dc4187c76d3d1e4cf6231f5284fec560333da6cfc02895954e085d43798cd51850d479d09414ae4f4d43c43c7a221b82e71faebcb9c9759c5945285e6e14f7ba43f06a136edaa15efaef059e0c91c36c6542ece8af3837e7197fec4b8403fa61175cf48fcb8a82f9edc0fb15eed71177afda0cad4383708b38f42bf7f390f93161f6814e52d98abf2a3c2ca5552c8915a8b05b46ff1d04ecd5c9bf264c9b4a37ff2f6c84fedd443da6c7c7eb92c2264ae7d8391fe4fa5bf2013fbd961d196ab495c7ee144901b01635c6360de04db600f7d28dcba2ca01ec3e5384e31c24d3681d4fb284b1c1aa97f10b6f68792f134d7c4850960000e031610462fbfb709a70aae77024a5c608318d4c753078d2d81465be9d01dd2cdacff8ac48200f3fe1de830550045f1310d362a3bca4da51b6b13affc2cd425e9c064ed6e6dd6d314383d0198b76cf8c4e8a412d1ec180c3b719a246ba9a383a31027f2bba2663c02b93731b446208e14351339b225243a3770e0adf8082739699bc43210ec5662c7043421bc8c484518a2005f020b50885a9e1fe33ed783ed74fcc486957535ef099e6531089118419f83041244ad877f8617bb7134ac76f6c1e6cc1feb68183b816853fed027902de71c430264a9e22659fb0d764321d08e27b0c964fe047415890752c1b3534f49955d899ee39ebccb67aaa3a8af5512c727a20e73e943bbf086740ff298072e8464ae57693cd8a216a2b2621bd835b6cfa4f2839c80873e5e951a3c2a4f4fe4fa6bcae62b5b4dc734efd0cff06f481bcb8e595061092d08f255987658173898fede807681f84a2ac8d607dde53e1ea4bfd5e337d7efe1c45a030e51e17a3d73e5b2104284887b56db065e51fe6715ceb424cc861c24ee50ae16091216a1002bf10923f64779e771650ec0c5d77022cedc2f062fd516220716dd296b9ba76e67d5b85449ef42a5cf5ba20ee8b135bd99af69854385341676b1d89d55dc2e5c74cba1187ebe25e52017b1eaa45dacb596ae8c72277b164804b7dc86a85b10fd323cde97c9a8912e69d4602770ee69290724f7b645a5a5c29451a458aa653a8f609bed9995ae4fe69232bc21e9c2a543a7ecefe3815cdb2793edd39343fda8505bc39fbff5742aceb492bfcbf52dfb4ff2bbf927ca50b38efa5af882b7bba76c83c9997d3b19353c373fefafcf7ab5cf4721a6869605fca576dcdb29ab4c76a05c2521960f58b3c44313e109969a44596e757a8c2995874dbaf3f22f72e3c0cd871fea973dfd4f990e8012f44c5c3b0234fc8a84d32496124673426e2b5ed98795b43b577b9b6510e8b5b9b8d93dd641226241c6d82600e01d7d8fe01fc64e9a3334b608488bbf8c2a4a7239e35127f3dda5a9792574a669ffa73a706b5292b2f0c27a17336b0044677328549a74b33aadee672cee3fcb45ae84f2ada1610f3d7329c985afb03c170e0b17a68f1d07c582f05dae2393e9030eb349f0061b29753a039c9077a1c54c20f0f0fbb6560c7bcc82012d789206ba62645cd4855ef6294ad7fe5e18469f2228df149a00a5e60cb7836d32256143884af05f7168ea61121d9fa858c8fa1aac9037ce8e365bcc0029b20f9b42f6ad90bf666e8d11ba99aa83c7ecc2a5c4f0ddd3369eacf2c0550236c1ba170d7e422245514f19a8b1ebf8682fc1e62209bdb27efe6994f6a18ff27990ed420408b0f483d5b1270ab7b641ed662de19eef79befc3ed86f9f872733ebcdc9c0f2ebe316ff1ecf20271080593264476141d53b526e22a2a594c291be3d937d4513247d92ba646623fb28c7932d7f2a52b82abb16cb3002657d617bb035cac8905b454a98cef9390e6639d8645fa6b595463b642b9642e1bdee69746736fb740eeb16378d9db464d462ba1345aff928954c1ef04b7578e5cbef2da90570fd4dfab9ce076b007311bf37fc367fc86ce17494254c1c1c6279c38b86d5ce3ca516923d3dd99d8c2f638b16ca324862fe08dcc44ae3e5de22e11e8aa69e57754c022e28f012f0b5e2d8f1137dac298ad551d0f1dd0b2ba2aa84e611a3240726450fb8232a15a6c91637bca17274d471a1da645b7e5334b38f00e99d83d710988bc4948b6d4638109f1525469791c5524a124b3fa4cf0ba648926ebe4b177f8e6aa5c8a852f5e69f6dbc4f2499f53957d2cb6a23d4f30a36a752111c7545c41a9cf3f6e6f94a0e5337c00f0c0269aa1993d6a6831e26a905678f4229de74a43e3bc6015ba63f845308f6422b9f8f26838140b342183e40e87d17f875cab1f5b1731802edcd2e7a3b26b27ceb11a1239a767880f0b486e455b83a59bc5928cdf42d87589c90f63b160bb7460f330cce2af6e00aa2362b03f26de868318adb405a942df57086973e6620b48ca294e7ce712f98c3f4402f9b7305dda0c1928fba91261574d7cb6f7bb502e3f62bf6b55bb8a7f13e4a8576ab88fa36b87c59fa8e29730bff89f4f563f5d5a444f13f48a28fe1b36983804b02ed14acc9f2b9931ded1299bb47320e8c1d64cd9f15909fd98a5ea7ebbfa38dfe845ad0117cbbc8c2c932ed07f5c416facb2f4cb38f893e58a3f0de4dc0be4ab446be4033d1697a89beb5be983b8d6fb7a7b51c3139d0c2763d5c29a340479b1a9236a3f4b6c526ccc6521d78a6fa07d4b42c8c42ed1b4d58b9c5c84a6badedaeb65282e9506afa24e7d01652dd7d73cfc35b5189c7eafe98b55bfc97cb1224fe830513201a6e562804f609fca4deee154426e50405a86aaa2f00d7c2dcb76993434a4b54265400adc0da9669a85c98206e869248e87cc25931c6deeeda994c9effbfb9c45903bcbc5f75e3a86a45a4c7f425e9d4af374a85e36f3b61231c0d420bf2d04c6a428497bd2912f21e8164ba1ae8dcf58464c4d049392ac7f989ca134b4c8ca3b7555aa9c242220e18422c4db78cf60302ee88cd4a0dd57beee5c0638330808f28926f262af387fc2b088eaa70996b5d941bf80bb44b45ce4b567cd3f81680d7a8f6414e8db07e6133a4bbfdd464b19c3ed84015a63564dd90295d683def6bdc61f49123842e4823d2556644e4e09bfc5b97e9465748324098246482932b27a523dcf3957799df5d71a058bd708d8aae435ea1e45a82b8f80b694a95a41a3f47e62da48acf5208a10b92d7cf9ead0a34265fc4b013c7fee5f6ec70c7ba4bb94ae7dfd8cd07e06c411f81c0ab49728b7bee34d233fcba7a33e7602884997f1167843d45c79ee8ee780e9747b37a2a775f8ccb3e47e1661fc0ac75a404a3aca4eff6bc872986b63f817950dc9a96ce4fe8e34097a2427b4bcbaf7e80f13b11b4f3ae4e88b6e275f6c078f9e90274235bde105f2e91ce16e609e803aae0e8e42482ee1eab244c1c4a1c179773e935b3d712e1c88abd7cdfa5e1bfc7a44856754632fa8085ce91d9e3571ed7a9068fd1b7a0f218d5c602a15605ef918f6d0404fcab28161a51ca5d505899b3669f4ad2a4a2079da3148ebab6c5ad0ba5289dac1b3a0dd1d70ab9db8bf2d69daef3d0cead8b4058eb4d1d1c803f7ee71456de60b07113a27783c36440ab21e0b5b94cbae909ba12259e3638cfdc0644fca1ca0de0bd3f7ab8845a2ece89782e9901b407429fe79fe0615c79373c5fd7ade7c631f110b031fc5c9332fc6af0fee2b7bb56890f4159959463987ce52878b3970a32453430f7bc894affee31dacaad9d7a78cc07dfa5c07709e951812cc75ac6869ce5c4704b6b6aa5964c53c247b315993ed35ed66406dec7eb31db250cbe776e52fb38558925d5b195b9b3cb33930b7f3018a40917203763db6f7ad63aaa2109a21d3b791b4b899684fa1404860d531a886dfa72391e76c40724367319e59f05cbf4a6d78d4b195cc9e1d4274d3c6bd123b98cac064c5817db589368de54c4d7fc07bbbe63b64821a1700f3380b647d2615e771e16fe0014a27864ae02dbc2314380684f12b8731fb5b54ff481946c2d9a924614200910f90b8483cb34b00fe06df70f3fe9f2b92cfc0589248c02ad8f51f8011337b4abfaab246fc91cc358e82c32a1fba965438a45d91e5f7a5f047d5978805d873e171d1c841b34218ec8b06020b929ebbbec1f61bdd2da779484df01fb26b553536dd05ebcab1100d0857885cd3363f4755f910dd2dc192cb489ebc902a85431b55c9b8f18870c706586c077f41d67a5fc30cf19e432ae9cc1ab07211c2f9889e883a860311d2fe701511368772816a8f0d350c610e1400c4f1c4c5786aec72304c810786e81ce0e1de0cadd97e8b3f54538c57827d11b2af32834cb69b894f6cd9429cfb5002a264f7c11a6c48e80df02373b294b1219b1a9827314a9159f0bc8ab85862e89097d1891b214f58267ef01b6c8f35c0d10738c159230be0a78b7c90d8e6b05c645b631cd29781fe7068dfbd00134b3254b18797d4c2c4e9051857d9fb918abbc8398b6710f477b7816cf59be770c233a47c072107e27310358a82eb0c1b0fd1b428e510fbe37a9906b5cec154ebc07a40c07a12f8ab62a5e96241cb4c1f88ff2ea8d37ae1da956f25e7505f8d03778aee2e097e4d7de40247265966414fa6501f0f50c69a027e4c82507aa3450a9df1b2d250def1d0ee9b91e1304cde10633078f414f3e64ac41bd16a48aa61e920daabc2c839126e5a03e5c169cde08ab582a76321bd2f5ca6b74c7ec7ccbfbe2cc9f630bd8ccaeb31648804fd3898a49d1ed07c4870b31127aedab9c375026f2914f9471ccbf0f88f7e4f7c45c0651a8cb0480bd9cabc82d8b9590d1719c36070ae4747c3cbc57f1865677f61c2bc900580ecfdf6ce15002c59af8fd319035d8b44a007ef40720ec25d458c0ef75d1f8dead9515e0759f15716b5781b1b3ca9eecae5fe4442d9abf6d038f564044c84ea9b47968c01fa05836ae525630648c0986ed1d50f2120d46d8fabd683aefaeba65a68b791b6aea7bbc397a4cce34c95f1cc7bbdedcd498ebbcda17a30867c87683b36e712ce0ec7826bce66e28e4a3fcb30d0710e9470e614fae2be19f6ec17c0316e5fa8a28cf995edff4fb64baec9d9f4e9ac3cd570ba187718ef4102dac37ff11414b8bac19a84fb50ca43e52e040c71ec67a82b089f097417451b7de57efd746622e4cb63284cdf39510ad2d888cbc8d5599ae6e8a1d7a1d25c6b1a29c64d7bd9e9f465546279845b4a72aa9641b121d1a271a0855241e50d4badb7ddedd11a7e114b765592c3c740b9b549d852a4eb512ccded1dd65b1a62f6d8f00e0443bed2ef7355c26e91f55dca89d0b09227511c9c43c67663d905bf086c356c930584724318673256d0444295879c84d89f28ec24bee85342746c1e6ed21c60e24656497f531334558516a3cbc0eec8cb7b147c112fc240da2a60808444c7e3d96cde202f2842e48f2a7c5507950db503d92a44e449c4a21fa0196ffbbb99df1990f0821125396f58bc957fa7e2100efe8ed5a088fdfd973d60dd186093d7d4ebe3e64049faf238a8d331134dc5c34ae5757556305c39fab5f979282b04c1499f3bf2325ea2da6c74d8ab18337b32ca464ac7a46f732e723a73f17765e81ad318ff4b3b4934f5c0318200843e4e2290d62dadd8fba5cb7c7cc139e6b806ce3fb0d15048db9781f8431ac2006b0c43942321d2bf9195e021b76587551683bded0baab9966e1e3a23293a8cbaf00c77f666fbbbb414ef234e711259f1db83f0f5970750bbb66b33ae505c1f95bfe1e69f3a38712e61a0e0f879649a0b52c88bb8ee3f537ebf31b058bd161437e57c94eb5c089fd96d5a89a0e69922f891eaceea6edab8e7c1009f945446f6284849019e411b94a8f2f6c325a448407c58d69c69c02b39d156ce67cad5f478bb0f747eea6179989d552ae972c32fd7b7fe133d0d788fc044931f5b2029f2409e9407631244388b885b4fe81f97098b37c14f5e4e1db0299314efd2cc58ade28a8e280aaa8094611360df81914217c8357f03a8cafb9e90d427b138210e73d6bd0f248d3f23e4d6185e13096082159bba9a935c17b4585f9ef5b125dff8a57e353ba83204dedaeff55d2dfa7702d68349032bfb9f1f7cc8e36b3cb486c4efde6e6286ea686bd1fba0fa0dc747b1bf0e1c992d7048effb557e0157b28af8ba920f462e25767d984474d5a2b62f5376363d40fec8329c442dba87fe21868999677ad6af85c002d8a9ff78c6a064d425514e5f62032e8f223c9897a6a7f0aa9bd115d8c5002012359f25f831baab4eca06748e5cc1241ce99c6d6b233d9a2b278dacb5a041bb5e379e47392da44fb1e2b45e4b930d968abeac38783b39bf2bb27a422888ebb778d1dcec9912c71f9701692722baf4a611ca24e069c2ab30e7ad1026b515ba3c7df8905044da273c07a661e949e6db95f21ba355050009d2adc6d5761f18d806566f49f4de5558c85204f6d2622f7340b79bc155f1eb407b05cb95efaeb3ea028e3aae015a9e067e941fa80cf135cdc28ce3a544be6782c21dc134f15b1623231eb7876a70f52e71c03120c67555410e2b2867ed09e7a5d4e4476ab76255fa79618eab6f112b9be95c5c9b39ee38f6413eede1b7e5ae3cd8ecd1598697510526551c76345e637a08dea75a7f5c001cd802adf3ac57f4ec012218184581319a7e85cdafd602555c339a6dc639f1454c9cba8f3425e70d6264cd31282010599c0a20aa2e37f4d16ba02c209dcc58727f6a74bf7d493ddd5a0349c1808b52daa39c9f5e65a04d8543bbb3c85dcea17982e741aee1bd9a7bae7c111e490ac37a8ff2b9221aebf7a4acc87120897d69faaac2e9333bb13fe7a436475cd0a41170d52dbbfb83fcd5c9857039b8d4605b372c59ffb01f8b95f3a1fa85bffe1a8b460bce6cf4a2b1e74feafc5d21e1baf61f0f1880f4edcb08b198f43f756950469cdff627db6c9147158a4d89a270d9788bc79debcb70a963bbc22cb4c32146a2126d34f48952e26a7c4646edeb11737a3d2cc1493ae6e83089c79b41ee35a8cf9e5cf485827d18473fbc566cf73c050690f05bf25439726a86b73c9bcb481bb8d9fef0ff78cefb1ff6a0b55dedba125c0ffaac43d9301ce07810015058fe46946a203e0506983f299fe7561769ce5eec80afe624fde66ec2928427a3b508936de1addae73b3e2232aa6d3eccc5b65d75eb3e2b391b4b720c2699c59e7200dcff3642a92d2bb737204ac7941defd91cf56702494a4e0bb41d4445b554a96764836b79016462011eea2253139702ee70714482616a6ee14c8bb5f58e21d225095d968a39256606cd66b860060ef471b496bc56ef997b85288ffaed7c61900b9d8d220fc3377434fa9920d2a855526e2afa92eb85fdf78892eb976d145decbc59b011987264a51273041cda9d9023b22745ccd34a600179b222e22d5e9fcd3f7e4940b20f56e7bc4a15658db069ecc6cc09ff4316b56e01280384ffc260f661849cd15bc2e43240e26f63dc8a61ae186a950cd0b5191b2ab1c10b36f93145c022c5fc3c8b0aa51dd6e2911837bcd4554159e3c83c9b8fdd60a9da70987a9bf3388e6a531d51821bcd66f5df8e5a331c80772002d64a2eff042f82481e25c91a48bf1d6c0f6207a25410f844a9e12f36d625e9ac3e015d609e74e5e9036ef41a66b2d4b5da49602c58ca359600c8b75b49c92915500df61b5bea557afc4019c11a6308133533c7e77d0e7db7ede19ff38dd50223ee977b69d001a641116c8050902fa558809169acb1608a4fada9949db8fb6c5ec09aa183157c2658e30a49d6ff670a50d378ca01acf5c2d9470f8ebdd6d3e8ba0c7309b98776ff9561ae28c9948e77ec6e90bb92b9216acd22e38f1755663d88bdbf3e653258656b7cc4b79c1355d3f5ade82ca2938bac8627d81329c91b7e05e72e8dfea43b57aaee4882bec1e62b8a5b56cbc65a283ddd5b09e67aeadf1e584ec6fe6f420d845a4fba72d7e2215551ac84b3849f03967cc1bd14b7aab55f2b82958457f3491b17cb0e68b4ecedc2fb7a1765d540551d13ad91c57adb267777cefdd1af3e8f29cfe94459372384fb3380d3b9910fbdfea4b771ee8e6060f500a20997b904cd68827868a29e33ff4bd84dc6318bb8fa0ab844070e577bc9af81694f0ccb7b44b3e40d0ff6df5bcb53e038debbb79bb920e1e2f7d4cf6cfad1793c9ea2ccfaded8ce80da13f99b8e2883028a840df08595442dfb3e3c0ec9f1021638b00c0cb2487e6ef3c18b51fe1ab28a0aa400b0add28c8744f5a34cda947bb1ae26309aab08947b9185894155aba9a9388858d38114df15fd66f48114f04134316e60a27c3c908ea3fa60cd386212f41ce1b1809808b00627dfe9490e9f168a62ad44dd9ad1518dd866ecfc89d3be0a0222f6a669dcf36d63c0439d752032ca13672d773cd7f41106125580a8ede918eb21a1dd15ee878a33f79980ceab4006e00d0b42e141a0104c118016a7de90ac10df954ff40a60cc65e211314bd11bd1d788f09184007a2f979e24d674762bbe2affa53a4c1d8c6a4c1578c4b2402bf0a422e2d45c9219b93c67b752c5a6f4821fbc5efcc13e2c1c7171406704f62ae547ab3940988fc69839d8dbbb59a939d89b146b1878705005bb685902412bc7630f6d88db7579aa2bed7629bd6c39c9efd74e1bfdc5c0f8016f3abf982d67afb72104bc280ef5cbdd16407908042ca3e5aecf531a012cf032242081c543f493c2e888477079dd3fa3e105c4b9d765183f410d471b92afc70e64cc850b6432793051b40a513827e6a010a1f4ef56000e6b43f43aa660616c904053a04efcc062e1f6f55fd1c38509c238dd1514206478227d077f01ecb46a004aadfd79d8bef133ee8b5c713f262fa546316bd981cd69de2b75dfd3b754ce3130d58b7566950600e0185d339ff0243d5c82bd393ca096b30bd451f544a3ce98087ab61feb0fe99fb4dd9274ec59ebc92de760c9250533c97ca0764bc0e1fd47fd13d8e8ae6541945a3059bfc3216f73b553bf4632df5d38426d2ee21a6fed78f7c518281f6804d7d9d78a44e06ddebec1a27b9875ce5e5c694eafd4d92553a00522d01f3d014cdff52599d049c53e021434020a091e7256208a526e0e99fc332019a40ffecc08eed5212f9f5caf0e864802f6b367adc680d45530afa95ff00f7213244dd4fedea29735fcf1bc80be431c6ee06359fdef1f6de5abd0c9bd625bd98e2ae7e98aa3979696966c29530407cc07bd06378932390fc308cfa343ae830c706da0c815004766882949727572624491c34990859a1c0374e068c88db8207c8d106e1526f7e44d07ee927b04cb1c1c554e4d6e0144b8c91100f7c25d2898c8391b28aa1c02705bdc277f628b9e1c6e157e759988e363e4ee1730bccd85e267dcf0592207430e090dfae426c06d20a744aee84c89a3e0f670c4009c4f550438772786b8c34709104e94e440e78e91075698a2e42a8b1773e05c59dd3e37cbfdc10b2a36e863e68ed4132839578cbe39fafb961d2cf4571a7ded13304f3ec8f1e2c20f570c1cd709f10152725ca8d143a60731e4e499e175d0d4d064ea861ae6b401dd0a1e46d6f78d3e862cff5efce20c11c291b2a385866b267e9fab05a43d0fa8bb3326d7441f3d390fc78599a9dc1a19b84b850348727b9c0a3a570acee9ecb96cd0c029ebe04a3add8bba9c81e4ef7ef3845de7799ee7795fd7b966ed77aff0eb5ae90002ce91ee007f0cbdf2bf153ed275c116100e454d732b1d7a2d1d82ae7189fcfdece5fdadba735cf7cdf7a674104b065fd4dd97b6b04b9e7979b44cb9ca73e55145751e656647d46b87a765249367de1426ba7b0f0bce83abf0ab7b3c07bf70dd5567e53d7991f7f7032f08766ca2cc8c99755330951046835f6b1c47f7a2103633a6d381ad74e974e0249d8d295da2b4ec98f27af2dd774f38c715ce31e2ba247a1493c3ef92e82ec46fbe63827360176e835fdd77df3dc139461766835f18d74de9a61cd1dd7756380708d58126e8e8ee4b1df2ccada67455d21d9a29fcf1bbbf91bbd7c08bcaef3a2ce3c30f47a1f0658862f8a0d0c8846705e748dd4a33616f4a159c63fcee4bec43f40074d17c14c23f8ec93284bcd4adf48f6b5c228f3ff384f882738c2e2d3c785d700ed075e7dcaa4b75d75c366d1c479e6b75af2e95be9865855f7930c61813691e9dd5bd5a4335e7cd5826cfee1b2c63b6ea0fc7ba33de10f1d24a5f7fb75d3c25c66bf40dbb230fbd68f6ca1dc6186949b9a365f32290c729a38142441cc79d3d51670393203800488b478ff1c367099df8953fb86c581f0a8163904e93e3b34a21da0e4dd246978ce8856dccf8b1891c868fc2117e5d0a601b178810080e88f2bee83c2f0c3f9a0cbfbc2ff4c047e108bfbcffbceeb1d841750f8a1d49de1b86611886cf0313899e8ef2c3ff11f23ef46c7836bc0ecc23eeae943e34bb6c527ff38561188661e86fc671fcef297822873f732bd2351bc7ff5efcee78b19df2de7bef05efbdf7de7befbde0fd527636fcfa64f8f5b9bbcb684740fca9d0f89823fcfa5000d286da7b2c24d44cf8af788558dfed80c0b995169dc8b38bd314e056f88e6543be382832f922cb863cceb2169fb4504ed0cafe0e02604882562b82a35214813428dd451a3ea248a9aaa2af1e89c8adbb46df5b25c5835439c1f8de7befbd33c0291964a24a86051a7f34f2775ecec0fed1a8f1fdbda3af9eebafaec35440717f78bafb1990aef1d5f85cebd55d96fb6e1890bf3a5a8cbe1b5779d6c2d75fad1ae07a83700ecf95e57690e48deee37fe10b3466b158f88583f00b8f5af27f42ebd59e97e53e0fdc81ddbd3f45bb149d367a36433b9d3c3ac8eda3af0b82ec3cca07f213972ec8eda3854a1ad9bd32e7272eb8557a8dfb598eb260d78c9c817b759432b27be50844fe1983c82c0fae2e3399dd0b4721f2989fb8742fbe9920fad3f97229c5fcc445c41be0cf71abe070e785d05d3a25c806e708435628f4e38543c0c0a7bbff8b2fb8ae11bc1e897f44087f58e0f5ce0d8b855f9d963c63b132502b08cc2c949f979fb8b80ceff3fefbbe4f1473c6ae2ed7005da2ce7a268e54b2a7c50aba74308de7fd0afab62610c76f46a7af2b040f1e3f16018760019766f21e7718cb70c731fbf1d1b9b20b0a1649dd913e7b3d2349b7d1bdd7b9d22e55c7083dbba1bb876997aa5346fbcf0758938ea3cbf8355ac9b31bddf7254e7b42ebd518bbb280cf035f2157220b29fa03b54bd5d1a241d735a2f4e06acfdd3f71b911740f82f9f3be10ba07bdef5d871ffec0230ef96228a50f7d1e166a3508e4799e9783d04c1c73c076becefb843c31d86cd1a3841b2f3818c5f0c506234a7628c2c6a81be349b9f85bf8ff058d7fe845b403b75ed42e4587c916a30c5ed7e1cfd6fd904e8328a8581e8f7089729cd2bdd875497861765c1c90762939793c1da4e65c49cd4962e7053051543d79228b37461e114e30f9a14e982aa2e618794b68ef5b30d091417b0330f2c6296f344bbb949c35188c58817bc5e83ba5ef05d3aae187382c447921cb9d2780c05161c41548204982a5a4e49411c110f5e4a4ba98a3072715876a8e549c373080e143c4020a0ab54bc581220e989c1421a4e23c49c5e1221507cb7ba393677d19bf8066accf053442e559102b03799e1525f85fe720119cee843e386cf4071e4ebb0b4e9bef809eb8cc5851da7f7e8846b4e7f2bc305d5cf5a067a276c344bb1b1ddc5461c5917a5346bb949b2f526ea4462858881b2c393a0c87ea60282d46d248fed13e0525c5482793daa7a0c8e8598b035062a080c8601d5184da527e5032d0f0c62a28293e060a6a5cd287b564cff7e3026b083ce1d412372cd61229bcf01d2058059e3002d0000cc133180459af21a0cc6a3d110b28a8d43eb5a4093d1b8aba57ace44ffbd492293dcb650790d0e49a2541b48072d0108fdc7a52fbd4122e5a86f6a92535e8d92b0ce76247f86288a7081ea830a413865c8c5e00f5f0281e2d2b825ae1876228d1442896744431ebf05b59eef8a0c3300ce964ed534b8a886544708f88c1f1c33154f2c5a7c48b506cb5fe4543fb94122bf48ce86363263b38d6c84140b9d5461445b11c620a3df3a8f18b1c6a9f520245cead6f699f52128436d3bd295dac918380722b03056940ee518205828ca40b1650ce4a5ca8e11b5b435d287e1806e1571886534a94e83074d1867418927a201831188725b6ca2432a87d2a491bcda3d301bace804ad0f88810bda0568b0707beae8747f168f900625204c3508b0e431d86651d563895048b1789411e05fe0d10784c2579d20f689f4272a70c63fc6a1c915f96415e8e03bf7bcbbb2022a4ffd0d0f84343438f5f415a74cd444c6369f08140a156556669cf73b54057febcbba1ecfede7bef05fabeaf736f8917c5c144294131d9f1cb1dc82bbb7851008a99b13407f78b292466583e848328af766f0a8995dbc170ffb29ce47befbdf7de7befbdf7deaba5e462831dde40e1828f9a303c1885be040d71e680a1414b14401885797468274a87a11d291dce300a4b3aa0f629244e3ceff415122fc642d763dddb798ee7b84b2c4521f03bfc75da854416f8422ca1fc5ddcf927a3fb30bc1e665d7625785b3a48639f3ab247e31f0f3eb8feba7ffde55ffacfa73f2196761708031b3703c404d7d1e386f6a4d4b819148070b0c3cd1c51a0038202ce01d40ad2a0a57dea8816bad33e75040b6d640aa0324e202155421591e487510a1db6b0523aa1013d479cc0708405ab2bb20378c839714a1eb2288f50810105998498f1ce11639a2f3a6cd1e186286228a160e1490f2c2021958c21c617e3167348315bc85045f944074822c68c689228a100415671c98365644385ccc105294f4a4a2a9e70641630463b5e48e1829462cd9333e3184d2801868b1025113e90567220ad9861f4424ad98411a830468ab809c385aaf18d1b12c9153929ca1aca94478421bb1041e236505269298ba8817c0206168a3419f7147922c3a7ace20e16384ab0217fa082fcf24479c3d4688511a4132fe5921d463c3690b92925935c0b53e48ef011a3f492678c2347035a9067d2904c9829c52c31e641e2050e20c103b9c395196448034588295c92f24a9f72093d40d021c768436aa166bc228ab20a13e41751608230d30379040719aa8c5451ca267d9650d127076545fa50876cd3c5182b4a3268ca2bc8903328c1c310250c5da2b28c6b68d8f2829a319890318c61a464614f19c60ed9c21b23b018bb98e2891325165264942246ab1f46353a94b1426e40036413319c8c5c88c142d9e58a6c020f4915a7481667a8d04051da20468a23c629be9453b6906e6e20a1c4304671f5a474e10ac99531c0f882cc228f73482679dcc20835650b674a2a64481ac2906114516ec0cb28678b972be41054de4429b5f081aac2c7c858051f120b3c75e48c67b658a2863ce28c1d32a31661a68a98e285ac620be9c49512072a5fa29035ec812aa3ec315282e12307cf98851cf26a8b3b6ab69c3143a6a4218c10459063bc90386c297db8e284cad8274a19061489270c2341f029a5f0c491f3b4054945cd1267b2908113a6fca108d20b2f639d2de5d315920e152ea2941ab082b2c1ca0829c587bc01cf18869c12882dc83e6a483e67622053e2c224298254e305cb9612c99592092ae35594226040953b80618444c3872c02cfa8474e99c31656a821d99c79814cc9254c0f458c587829956c29a3b8328a91452a649a2c462139a0874939a5878572cd18e41560905aaac63670462ab47828d468b28b1c6a97fa028dd6525f9471b1d8e07052ce191af23ca02ba0728e17893eae78415616b328e67b2ff87d9d57c6c93351eb081f7f50e5f7df9e2e04b37f5348a468ffbaae1bb5e7c275343879c6d2dd1e201d4408701d432c7df1a7007dbfec22cf88761005611bf7ed4cb1c382f69f0f5a6d86bcbf4fb423cf101a7fd07b91e7d280a84e9e116922ecda414e91bf2f70b2d7a58cca9345cf86c63999d42e95670622bc03e7f01adaa5f214d1a476293c567ad6f2a2ac1a42c5f0e0430b575de8d172e749111bb8483326870787e3947bc4c831c94180bb2cdc22ee0d60d2f8e05e7895db61e1ae0d1a80a385d5184d72657235704e723568c9893970456e14be84175e1ca47c8ba89c99fbd17901cc1850a4a802e7ce9d171e5843851eab2c90e0f0248b0db9040ce1c215b07891d30354146ea4a2b063270eb965882aee2001650489219ac871c95d80bb22f7458e8319b87c27a7444b4e2e0d063820275301ee5a01a24e0ea709234914397cec50855185c74b7e0147e7ca161cbcc8b3e54e79d4952b8367715f10f2393694d0c0dd29c6f81b2c2e1a2d720ac045e992bbf292fbb1200867e71ab9811b9bd2941983c3153e441c51074f170fd48ee0dac4e043981de4f81d31b917006e86db8554ce85a3c28ec5fdc2bb002386dcb56207cec3742077851439d80170787262721b10e1aac8c9c95d03e05a08a34a8e8b07703e05ee092ff0b4f040009cc891383c39173cce10a1143900e0768873f338188c0bad3ac2c3d8df3533b5d5cc217b5595fe46bb954cf69d523366d26cbf99ccb635652c8bca8ebee883117e8c50828e006cddad493b374ab3d96e6cec8f1e66beaadd7d02cf5f15778791e0f93380bb8fe0d95be34d7177d86f93768bd1ccd83bd1766baeb758cc7cb5fda51415a2d6f6ba9b7e08aab4ee33bd3debb499926eec2ba9cfdefed5f65b552dc189b6d7df11780318a0c8c711092318c000b076355bd66933b1b5dda2bf97cc556dd9a7d1cca7d1d010dc5df4eca5ee7ee4d9a3c003cf1d1a77a1a514c5d1aae99b7f6e25f4d3dbfaad9ab2ad3a022cdd42d025f559a7d4fca51455cf6f6faaac459b7e9f6aecdb6d82bbb73c776c0fcfdd05ee7e82679ca6c833aec1dd4bf08c458080e76be5b07337a9349af97b359f7d1a4dc368b773cb62ecabedb7b6da6e5bf357f599622a2de977cd64d1a69dfe96b54e349bcd7c275a1bdb2b7abe9359fbf5b6842aa56aac01ed36212501e9d902a4ea2fa5e8996edbee013b376bee3596a2cf9ab23335ffdc4ba9298ba5b76753d4aced75d7ccf463dbc6ae3736dd4fa3a14d4fa399b1675159fb37fecd3ff78ade82ecf553156d4da51fb0735f005d55597b333fdd3be95953f6ad296b7f9fe6ba64bb7d6afeaa2a3dd23ed518d2db705acd144dfad7ef25b386eed5f65bd63e10777779be46f875770a3cdf1bdc614829ba84ae2ad23bad5bc87ea7a43f7f277d6a3600c6b49ab5bd7e8a9ab2188e54fd5d53d9df4ca60832d60481a6aa494cb12d8b75706453dbcd9a32209b3565361f6dba856cb64d371a4395946e2cbbee1315a2ae36b3357b98ad79ee58aaa66d7a531ba0b44b60d75dbbb1a91a33571f3b96aa2314151dc9585366da766bb66c8f96dd4be8d9de6ced8d84a222196b8230c2ba936ab7b4031f1cc4f6096c0c6553746d876c10d67d9a5b765620030474b0e3c6416c9f5001a20c5e013b6e1318b2cff487bb07c0dd7f70f724cfee7eee74096559f35b357d596b026157d849436f493960186000cb0087aa94a23836cd8cb11728614044b4010666525206199c3a3050ca81434561ec6ecd35061bb2cf14bd20b6b21738ad2d8b2eedf50275693563b00b96d25beb74935dc0ae9b85c0051f142d4a8fc2e1b4779f9422650d576e17fdb5f2e846acee9f587fe48dba1f859ef02779a3ce7bfc2c219c87f37e743d2579a322de630fab30fe7d961091158c58e3df57a17c225c8ebabf2e22f7bb27523e7e098c7fbf7411c99d8d2cd98d58ef46ddcff2f8ff3fba888858425c42efafe7aa11be0a35429704bcbfef461e10968bc835eabcc746f8cb22dde3babf3eba0722c275a9c0fafb4ed8a5029723960b49856fc47536be27323eeeab425710efa399c40fdf8d58ae925cc1884879bdc7deab40bee722e2fd2844c44584f5a50a3f2a70095f05f231f9f88f4857e83afa71f1e86c7cac2cd9637dc912c291cff2018474016159c9a1f3c0acd0c514fefd9e475712b946d70adee07b96952cb2d1de771f53e85830408410df77c20fbabcee9dbc1ffa3c2c56951ea4739af85424871f7b451c28fd5e26f25d83413a3d7a1e0e452f24bd6e0c433274cd3a527431759ee7795d5762cff3baffdaf0bfbfe07f427e9f88fec4efaef898145d33f13b261753f8e0c7a3fbf05f26ef89648fe9be2751fabdb7fbee1b7f786b2b04bf2714a4a599c0774dba821009d2d2a0abedf49d797f5f740521a24317d3ec82a0678d95c837b07460fade7bec752b7437049c0427f91eff539223f888106b86fc94844b1006e8fb47bec77fe47371f1e151bac34029763a887039127f7c22449e92bc117814e2ef3e03f7bd273fd0452403e3831fba321092422c1a72064697e8ca40e8323203741999d1e58b2f0c254b4bc65f8a8e2577451f6b0b079d8efb9e5954c41d563b4451b4e2b3e24be39150e8195147945ff8644c0b684a220d04d9117545a06c11a178d1dd0f755ef75d953002ed53506080f224aa744fc1cc8241ec9274df3de9be9b82735c9c9529dd7d8705e7f8d1dd775aa2d0dd773c745f42edb9427d1f9bc154980d7ef383ee1ecfc13920a8ca730582fa0a95e1a3a44d12305ff018758fad743a7484b961082ca620c94109a32ea7bbc75db2e84e882d46601da1d4f7b179536545e50ae3f01366e269e9fe761122aa8516a4700ed69832683a5b101f1a532d30e9ca3be30feb8572cd38e5848b9f26503401a367af3137e564aa499a0ef43ed07bd17322d60b9fe745c5313305a7e7cb0f675690c244ea0a2d7468e2e68a11c67da77daac9115ace569fa02456c852858a0c513838c112c5a7a08839020f0b3120a91ac3025de783d5244a932e3f4daefc48a07daa491339665a4d8e84631886f123c2c9e1152548057e4ccab03c2651acae63f285c5440b93299989133a3c7a30c1c9f809c32fca2a2de9d76dfb1d4bd5fde7665285a4e8efa45d435bb53581bdb566cba6d0b4d314f65e956aeaaa74d2d4b7a1b637083cff9373db60acd9f44060ff0eb3800a6663555121a66c27b168cd022160e76e329b4cb000c93d699f2178b64044cfbdc6fe0612d23b257dd35100dab8bb07804a0040b039b5676bc6d033456f4babf93433453d80a56a6cb36adbb22baaf481e70aac2a3093de7678aee009ccc6a9b6afcfe1b90220ee301b2c6c09b65f7fee0a2c0832e3ee30965569dfca96d0b5bda99f2ea5e88d1e3eda5b5213abca82acb4295a538380b4e8eb6bea6a636f6cd04b5537ab6b54a5e89f7b5559b3a9a69a5043087798ae817ba41f34b3558f907ecb8e6aa0a0aefb02664bdb35f2eda4608c3b0ca98393a682505474c48112096d6aa2ab79c249536508f04c41126785f0f04c010f21681b33f7f94ea7b9575a8bfe8ea5287baa35354dcdd8961d5120bac3904a3877cd4c09e079022a77189207434c1190fedcecbec0deabd2081368912da1b257d596dd27b8bb003c4f3004c75e6d4eab89c650a59d6ea33c011077d8abafaaedbb7b069e27c8ee34b3c95c4f165d5b76afefd4a22d36eeee4ddfa6bbe664da2ee8d1a6bb96aa68071cc4f609aaac69df68a69096dd6707471c289160bb31a9aa038a8a8ef65e955268da69cb0120a6e519003d000005d8a9cada5d1300add6ca60eda6d14c20b036765b5bf68bdad46cfa9beaf4bb86b60948009379a30213307fd74c1f9e25a842821e24984950c1069e2378e3b05565d1750b41776caf7fa6487baf1e20b1486a6abeda16c073041e54b9bb099e816600fac0dd5f9e812c20f20c419dec19022cdcfd019e217002818e07b0784089f6fc0008ee0eb3b16f6bfb7adbde4cbfdbd45ccddbd2528aca5a1b2ff666c6fe066bca4eda4d95b15bd6a6686ddded3ecd4d53d5a4d75f8403d6a61bb5a1b1bdb6ec3e911e070c068bb5fb6fb037d8753ba5a6539269dbad6c09adfd4d75ba41a3a14c6faa47bfeea41b3690f66d6d915ecfaeeadff81be7668aa9b4774a4d3635770dc6a6b06949660a0f5b372dc9fcbda26dba8f1ee80ee0990695c3905a555d919e4565474aea6ad26e4b7bade19906961b9e690c71d811092494b063abaaf44e49bf6ef6f6660a01771f3dd3f041038479ce54ee3e5e003024b3a5ed13e9b710f4cd679dcc269ae994444b5527b3e997d2d664dffc143db5bbd3f09cbf640ab83bccc9acc5d69bca7eabaa6bed5bdb8e0dd97f0349d69afb4ca169dd4a48cf9a437cb83b089e675431e3c88c1eeefec3b30c3e328c7087a5706ea7a41bcba24f335bb5fd1dbb9d7b7da474bd2521ddd8b424d44cd1cd64d676ed653154d6f4375876afe7697e0ae97a4b4ae1d933bd29b1bf99505a0a819d7463b33453e959f491b6109466a660db9b09295d6f492dedc6eef5cd67cddfe7d34cb44d77cba24376934adb496fbb3d7ba6fbd90224fddeabd29fe82d084afb73a34a68bade8c646c1911fc44fd54f959e127e6301be97a93c55e497da716a5a14928cbaab6269546fb14fd96bdcd7e0b3165dfaa69bb69bf23f0fa73eff4d9011061f0ed2da965cd4dfbd67c25f4f7567a21a8d95484a4ca9a901e070cc904a4df49dfb23711be0807ecdc1028814d55d6dcebba5125b44df7f98329a63a60ef55e9dc42d6cdee955d32691e986b3bc407bb64d294d27d017555a299dba63aad6a6b9ea9593b3a7f9ce88ea526cd346ad39b5a3355a5f487aa94a2abbaae3e7aaceabaee1464ac292b2a3a5af7996e9665339b340b88cddc6bca22f220cf2c31dd369b29fb9404771ff25c5239d168372596ddb1d88dfd73b79bf6a92ebbec35f6acd9d4b4d3520aecdcad79da6ecf9a4db122a492872cd69ab5ad9e4aea003c97d9cfddb6682de9268167b2ca1d76aa23904ccebdb2e752aa3e8bfe125ac381b6b45bedb5bb03792665ee0ec433d94af7bade62bba9dd49bfcf57db67d118aa841a791e8b5080e711e7ee30a5473aa1042435b6cf5fd54742faa5145db7ac457dc0da98b9b643f6abed9f9b869a1eb8bb089ec7d7d27ab3fd528aeea4dfb174af5b69afafaefb02385216fdbd6ae0597c736e59ac356d2c7afe4e7ab55d6dbfee96862a6dd991bb33c0b348c56ccdf3778bb2aaada6c6bea5dd4ca57de248d5d4dcb27da231f466420608b839ed103a70da4c1ae4b875b06f34f304a71d0207b17dc23ed598bbdbf02cbe7f8bd6b657e039a4aaa9ab52d8c5614a6a079e43993bcc666ed9b30568d35d4bd5151592ee77a225d536cbeaa41d01762f99360b3c8721079e4132e0cddd23e0190c00e8196cb93b0a9ebf2877187b043bcdddb229fa482920fd6621f0b0cdde9e66d656353df799ee5a4d8ded359216a8c42a98b06a18448a2912810c0000003316000020140c8905c3d12047c258f21d1400086dc03c5838118a678220c7300cc4300c022008800000000010820008c418431adf00f1132f97821cddb1b6c9d055e3138c4f244b021a92b74fdc7d247fc7045c98c1928062ba87e31a60e135ac952acc9e6947451f5a3769ddeaa685a7c1a437336c708281ce24037c91651f6133d237bc470c85b7a8c2743ac50682394eb77fef803bfbebe8c95425fcb690d83a4e70d6b28cb7a1f54b41987768f827ae1b1427825fc9ed0d557ba1eaabbb1cc4f915ce5f86769df48e81db81de511f6f4d5788adf53cddadaba6cadfca5c4d7589417c640f96e725db33506ff4851a66d82a15a82f1a9803cf0f64a7961f7c43c9b1664bb932f32aef3c448ba3274fc92a49186a35b07b3b10e3af27ed3a3420afaef47a88edee11da2c79bcefa13ae8506d7f4ccfad36e8d897b675ec5bb38996b6546965b579b613c2868c67b2dce4816a599bf8787ff760c82498080af2c359906a7ade5b2937230e08a477b8e7d87cd633db85419b9b1760d35808502e00391d8c938ecb7eaca83e95fe74381eef2029dec3c51c2661831c431d4808a742da6cf01642b2f3917bda41ec5d05d3bb2a6fccd878766de3791f02c7749b8f6d9d52dea13a5dc7b38439a25ba52c6eee2165e5fdff1a35d7607f9ff804caed527000f62291c03a92f925ad46d3600ed87256b45a763887a36b52627edd6c49e7943eec70c11b1c89cda9739229f12de4e87bac0242ead50e21d1b1e4429741f06cb77fee7429ac72c98a3fe6ec9de819b466725b94d1751f208a25007fcea655379e83a9d62609ac0aede6036afb723a8de72e02773e4b5ffe1347dfd945808a0394e0cd0f95671b7e3846471756459d1d452df0d247d9343e35a2ea936022966d92f1d605c22de913e881e0ce0e56ed765ad9ad873ae7524331dcfc1d5dac7df7e4dab413ee608aab3fd170a4d9363e0f672f90bb1d825366a38b5612054d3e024e975bbf17c72eef901523f92af72fbc121fcd5431a6a14b787158770972ca510cd379c76b231bca9420275ce4331a2d3e1c0cee4f829124fc144d198250a4c9cbf82a93113fae307889851b35f34d2a348800c7cd32a2d48b03db7ad82a7cbf50d35038311144f1467fc4b1f76a0e350a47ad8ffac4e6a1a2048f45989e9ef633c3bbcbb1f417ee5baa1705defd4c3329992323247dda967e4c692921fcfe59bc418d847f391114a1e15bbdbba817fb22b029a86f67100e48677229661d800c719f388c1d121b28d02f519f543e139997fa1a965227d5768d5ed72ee3b5d0bbe85fcab65def5575141ebfc6c0f218f3451703e59d8593008b7cd02dac310f123a8258cbff90ca1a73a07013caf295615be5e953e4ec3f8a245387f755cbb90480d59103da90460e71443bd7a603b3ee4b67d42089f58ca504371a60a366e32ab08d56d92547884eb88dc0224d7f4d9f932f3db07a6af9781abd99e2453e276985a3cbe1b758ca628237b8b296277ef926c09d99a4e225d757a690a045d2f2f72407cb5a9a73e4fbdaf0065c98f0195bdf1434726c3433ff9b8abe894d6b6309c0df156dea0115aefc5dc71742cc9eac9921a8df6358935f627b29579f8c79eacaf25e87d88998bbc3eaa3ce44f157427980a4473f72089d3f203f977d56a1a9aaef691a9bec85a697575b3abaa762cdace3bfbaed834a49f2ba143d418a0497394040545c95683de5bf3f2749af88b0f79d80edc6406bb3fc69704a1df6f6cf42aca1b2ade49cc7108e699c620b200e6cc45f2512b96f8151babde2c4d42356c5dad184f657c701c2b0adb64a45f73272f7a4ff3fd1c702850bd6b0f9d11d5b90ab19012f6a69e7c3c897e810cc59f0b14f488200af0cf75f33df642023946ceb189708d59d6a7837b7c279e6dd5d9ae68089f9cacddb4092d6a9bdac628973cde29ffd8f09f7e3726d4a7efe75318d0573e2497edb1fe605939f02b94755fc3dbc75870c3f683eb1a757c9f6dc563f14af7e2b38c0cab918805bdfa6780d9b96154e889eb7913378408dfa35d14b993f5fad0cf47a51a5661180b83bb2fdd246d4f4ed9abcdae999e64230b7e11672f6820325ff2ee763b6b91b0e0f19cea1e69c8f5a3c1524c99c080ae1b76d7c419417917330c1958252f172c20fbb384501a12c3f658ed0d0ecbde56143ef5a9ac507d7540bf7469a2f91d63a867e6a9673b58c404a6ea6586ddeb0c21ec11b17b8bd34283259402a1a82289f23850a0f2d20e9978c81f732bd651ad3c3d7f9655ad66dbed573e91ad4d3f3a237d9929910fc3eb601b6a511c3f59c1c005b06be4b2c2aaad55023605f638fbcfc9553aea87e2db532d93dd5c3cf028bb9a72cc2883f3aa240f72eedcbd3bc686b34caa9eea78f058b2d23bd35839e57a927ed6f21e405607ff20247c9d1e9dbd573bd256b7b650fdeecbfb94ffab0ceb67849d89030d7af32e33ebbe9f45c55aa814ec4be5fe13df74d957ef810c69afa4b463d3a09be97557a9178df4ecf958fe1b2e0a2bc4d0d989c4b8f5e2c4f5e36be426ecfcd1e9c74f1df8148f816ffcec8014a52f4575bf4baf093ba8b952ea9b1a602ad9dbb1d0c7db8d0911e2144b06f67e453837739f4e03dd93a46cb78b1075c882a0a664f5666cc6fc31a6dab8d454fbe6190d2a14c83fc3feb34551b3b22ac416edd88ce19511c5cd0c397ebcf0def5ad643cf25fb760cf9ed64c1d4ceed0a41412d9efe71459a5ae8dbd33f77d4a5d7dbae59865773ec9a607f4fdf57a5b1b282b0041e4b59b27dbf101d3e5830fe414b968bfcdaf95da9f51aefcbdb5ef7e829f1845c89f20ea53522338da95d9c2416243facc505ba7ac050eee4a82e872a4a1afd4acb733c08f05defa2e32ff1b8a50a7d96721ada3c42cdf3702f65339a633dbba3ea894803c35c9714a2233b227d763176154056905a348d80a5e78690ac443585566c0b85c7f49d5b4bad1671821a084701385e95eb88269718fd786a125542a3fbc09562d48650441538bcc412b069c0dd1109f97686aee57deb6c4f8c88c1043407f4415364f6169a7c18edf7b0f333baf1cd669b63b94c8c0bfdeeb3b09c4bc61a384f1f97ca9cddbe73712066f5640e905574c6446eabeb771d158796910514011e341025d1b0d1185a9423b4b72fdd2994afe0c8cab57a20ebeaa034c92a43bd05da170ced98c947510dd37e772a15688df239c446bca73408dba41c979112751ba320663d127230e0dc110bcf92048545169da95a01abe638f4bcaedc6335861c192502e84cf7d352ef152c16dd095200a1d2bf88eba53267eae60e5e9616f0a1305384b81b39a5392dec27521e3dc57a4fbf944634aa793010dccc3919e957b9c36f4fe65f5d802e369982d0d89a4e0438b24aa72d9c5cd102388fd91bc2e0851c672b6837de127812bc5b95a2009117ad9941f3110208c5b9e4bf441ad075a30152551a37411b7a538dddb5569d803e573cff46ecc7783d2eed83abbf4ffae89afd46267875af6c266eb3eea83dd7fe4c45cf65293f7361d86356edca982995e206c37bbb20e215ab4480d7ff7840525ccf684410a4ac8cc888576648e1f786bb5ef97d58bf2a96535c554f6d8b290cc748b998252aa0c29554eabfa88712a5a705f40f8af03ec542873f2c16d9bedb1abfff11e943f5613a2c2a04b1a710f73907c2ec9f66ce1c3b8b4df0a6f77cf33ffe40e8cb05be7126c4be441bccf7a37ec74e2552129066010a5899eb635d07487ead1d04241468533a1fc375a3b24c3c8329648bb69d459f573c4ed26abb90f7923331a26bfd785658a4093b13b6968a19f30d1e78d2b62687ed275d8bafb2cecae9115d3e190bdf1dc2c4c7462fe890a153c2678d0a998a8f4f039137ca1ba178d2370733b94fa5658cf541c83b86fadabe39867c2557090ebd671944e6f61456de21aa28cda09c9472a8f2612199186a11f88ae281696260e178aa7a270f5638de2b72d65b2a8418a1a17751204e2a0cd94a5837fbae000cc35ffd96dcc07c9ac581524adbd35e79d3f6875d05a15a74b3b11c0002f82e7a3c0ab84d3b6000406cf747eb06ead1f4db23c5e2b7982074fcb726f5ac417e680d420548779d94cf83a78e5bf154d3663b94231c3c55435306904c661394441b1842de53649026e12cbda1953df1ba5b42ec9c730d3235988150061f247461e63ffaed0f0224ea9b2b2af04aa07556010b693560bf642224e592c9f6abfaeecde8e5b678e66c20609445ed795664f3aa6b16ce6c9345ba83903ae1004e78dfe87ab9b54704765cfcdbc8f1d2d0257310f4dcf8e939b580300ad676145e0fb1e1d5201643d3815469eb55076b993b918c98a5e78007fabc61cbc9c1da7968247e99e5789cfa4f226163a3417083f57fae72099c01b234214ee2adfe8a2703f968961258b29eec356fec3ce7b65b5127c9a19d1b777fe55c2cab13588f0c10f749119c34e64afd3f86ad8592c9cb24260d24d8d6d5af6af0c3251cb1db02131db782fdeabc0c9758911e140538c6697eacf66d3ca0cb9862fc053deab492b7aa6149499d565cc94780bda05d85a5cefc5b480464cdd92800f2a3c9582658d58183644453b0ca3ceff4ec33af7439bd5c8e6e019f49dc92608b4322e46281342ed6c6352cfc668401cedc94cd186b6b1cec1701fa7adcd954c6449dfe5ab730630ed6a2fcf76cfc6b478114c078af7a485739c1adf3c236f964e936d02b9a8c8161b6cbdc38c5a71e9f3e527a0a5d92e095d7994e8985590929096f310fe85049d577884e7023196d8c394ea159a329a7caa81459ee4697ffcb28a7211c5812f1582d3ffc254627d050563b891a701ae721a50a48a49e6fa318078fdec2bda2b68e8e291cfa3374e7908145d44b32121bb48791164b46d8307b4ab425470dda8c73051ccc999c1cb3ac269d71437df9ce338ef529ab5916624c83aa965ef0806b0b45a164a6717118ff14838c28cfe0f0cb710612f8f091c1035bfedb34de174038c2674a16a80b94719e9287c2b7be0b7ac73e8a183372e564bc6f3ec11e85b8abb525342f29ccee26b86c633427ebad6cd5abbb8f875bef419f70ca4fb148933f368eaf3b8ddf25dbbd04ec6362c709d74841fec93ec01696dfce8e9e33bb5faadce93dbad249d0cc2cb12328bac946bb08947d57938af68e987d64905034f78b85a42b256ed46f07c5dd3596b5c8bbb8299cf6872d524b2658908f24e1610957c6c4c67911153de9655ee4ae8c1a6a2b0bcbe230518fc838ae400fcd538579dd12a2148980a590cc98da56a62d1751220f71cbd318e02d7cad667add9a2684a05f2b993cdbeb4a2d5d8dc12dda6e48dd0a8780b129822128518b5035394730ba49a8a2be53bb735ac86a528b9b1775fda0a37d90a6900a691344ecb4773f09623986808b8fbcb6ecce6531bb64771f5bf8d4bc661dfb128a89e226b8e01994e9c7c16caa11d64efaf7874c949bd5fddbd4a6a7d6d8c1b6beebff83207dbf85b9c8793381fd94809c1d149a230e4b25ad054c0970b76aa3f54df806090eb21ff77762ccfd02637d800cec97a2d33a057a1b0af5fb70377ab0c6bfae55f75d20b979d35663238666ac174c81f87641e33e9b3edd75818af069c3418ba4a17d18f5d1bdac961f109f892f6ce62f21255a424c01e804258823e43d87cb7247daa1d0c2159ca9e2c3288811a90c2951530f44dadc33add189e2706d199b9253ca101e50f367cd74eec279c7a8d05bf1714f3390afbbc56f13a8568d3337f914cee5a6a6d6af4929c68cec4a30ab756ad639c942b43d6738a20ca67ed20cd931e6160cb45b0649880b5c259b3ab2a6581dabb2472c02b0b36c329aba3434789df273d74820f3dd7cbf4f589c240e6c135c6ec41ec2dd3becc2dbe21150b7f121987d3e13872209b192dda06943cf4b450ea0900e377b49c2d9109b130e12311149b273b4dae8a084274da0051fdc2cf04339e54becbf314f23cadf509867d3896990571777f405aa787e498b5c9c2484e844f71c31250fa138cf988c3c878db2b3bb5a4c1e475027f70d8581ab374f342064f32409c1e9c23d76f9e22606ed1de7a0cbddc8d75068b519568f58b2f63a515ed80ae14146bda2fbcacf54ee97077d1468b972bf5fae2525ad8fe00e00645ee1f65daba346804d2e8bdd835c56aa8b8e6f0b1bd5df86d13ce2c2807deb082aab166b4888a301152668426fc20cac8831d258906d5dceb45738c117c1c46782b88eb616d6a9de67828b32a3e5ea8e2f468de51aac6469967e3dad6d092d18e1590588c09ed1990079f1f4d38b0109bf373f152be0da8722af3a1ea4f5632864a02be300c4da5fb8e30a39005e0671be5256e76b6bc9e5779605f7c1e7732f084106a3a0ce51c92bbf2a702d8a6cbe77e926a56f566acad276b174d5db1332e29e1f010149ef571ea00503dffe0071bc5c2f9740a0f1d8a9cf03a46588a5eb569aa898eacb61a77c5dd29a5800e0554ce4a51980ce0758d33380bbf5adb1db1fc012c9cce3b8680b9852ba3efed17650ad913121bc915995f07226e4bcf6175280a18620de7f2280d7eae417a7cec0477da4a25e4b48de8a14e6329d7eb708174d408186d9c0e46651e77473924040fdf5d34a717f713e8a1bd7ed942a365e6f27cb28515be95ab556351c79144170cb0061a7b45de846f238ea68ce17f8c2169f9f8039c32037b65fcffabd358692c8bc789728d0b2a0d88fb749dcec9416d1eb11eca8d10ced0e50368b86d369f240f2ec9675a3958706511ca93c40345a776f01bfb1bddadbb4386884edd9aeace7ee0aeeffd9c360740da19a782bd8486173b6a5c22937b4024053b35598daa0a4c507e497fa4992f74ec270298b3eba1649de9342330f84760bcc6560b194d022e78d96ba7824b1b519e4dc0a5119d89648bdfbc3754767aaea88d214e158ac652da2ddc40466d4c1c35db877123d116bb63017bab0eb2cbd71f65cde79affd5295af2bd433b66d668a1c8eee26c82bb29a080bce12189bc145753c9833f76c505ff5cf8a3830a63edda9a01cfa2584f510dec380b5183053dacfcdbeacc3912bfa5c9558d63c219d794f0a3ba7ee8f9943bbcf545c21dd172a1047c1be9eb1cd67b043842a3938d4b75daf2d8fda2c1d4a7747ea6b9c3d9a339b2c5813206b5d12a9a0662c1b5934f3626a8e79246969622d99d3707caa9f35d0782b5273fb7d0e15aa807535b71eba2657e41c8416237ca9235b11912b4a3b5a8b5a1b281c617b48801edbcf9ff5f1682f5af2db4552a743abae48f392e0c3aae492533b1bddadae590d665750fb98726ba0235dbce4e7b532ea39b005e770b1120ae48c1ccf5f6aee4f5bd78af8d90ce352ad0c59be4d0a3b072f178d5c849b03aee92cfd51966c6dd75b61d745941765565edd17b3457b73bd0bb40ed2d1688d6acd68b27c70925de7685a918c54c256d4f1c8f70bb0b79273e9e8e5227e364177b3562163773ebd75fcadc97e8aa034bc68c4e1ec3a064013cd94eccf60cb9e71c42cd9162f212fdf6e2c4032e576b41a1af33c9f310965707947c8ce48444036111e638be700137776b1a5f22ece8b8db7d1c477c9c02d582095132f310925bd5040ca734206a78597543f58d2a4ccd2109d1e50e3d639d2f1274a24c407b4818bc8d163956ebe0fa2142ef9cfae6b344092ce31ccdf7626ea6684b83bdbe666ff7742d239f0dc3924988d7251d191c4fffe923736ea8d0f234b72a4ce2b8ccfc1dd87ba9b2f570671a4faeb167838351e5938739f75cba169ea99f8f0ac9f7e8f0cea5729f2e42cb9fe8ccef9b721b387db9dc51a9fd2135a80c82d78f185b5eaa0c2046cae8b80077748a0ef299c082d5ae9891724cc86bece795e3f8721cbbe2a16741ce1117efcb787c8cdf872586d44b7552defd1f92ccf25f5594ebbb7f4fef58498590f35f25b64205259c3c6175b750d1bdd7e2ac911b6700f14e3b371f86ad5adf45ff9f0466d2af820c93d0ddd5f0a790242b5b37a54d6e91d97af01321781ce70eedd1ba24f850f095a192f769c247d59521dbfd550ae9ed6eb6d047a4da8c53268773534d6cd10efe92de7c5b40b717940b5a6cc5f2122f5193a4ae9593fb91b2b601e02e3c06500c4f37be224a744bbcd7e909a9f723ac24d2e7e425089a9ad0de36c7c713eaee2114d7358c852d016494770efd934ae0cc0f627a0f65a87342965512008b1fbb886a4c9fa106c3694927611c676fc59d77bb1c15403588d28e805848ca906ef06868a3eff1aed68b84eba54f7fff9160c95617418d5f8f50e0332fe2129a3a7c0b9b25210515a74e16e92071a31fcdcb9f48d0218b0644d641f8a971e6e0a6325f002cc5440e336e4b1525c85f447faeb61aaf067ac7fffdfd9dfeabfe08fda7481c55701a364582dd467ed71a3fe924ca6d1fffc7ff3b7fca3fc1bc04ab63304ee925055c05a32da12b896d0e6fbdfc054c9524ef21790255326e097f811dc34f003c4bb4ed4b8dad5a1acbc16ba7b84127e2ef0bfa0bf9f7f027ec9cd3a3f269ba9159418912f9cc622413fc8e6d0a9f458bb980a0a55062ca5a9ba8cdbaaf24904080bc429976ca143c947a3f85eda54155ca5453183abb4e8e631bb84aeb5f90fa4259605e2bf50b92435d19fd2bf84a1d2cbd4e557f894301697bf193f824e8945a96e4ad06fd4ff15b2a57dd501e3420543e4198b2ab3485453ffe9cfd44fe5174de015c41fe9eff5fbff3efd0834253565fdeff3efff79fe634c066eb790da254da902bb846e6aff1324255606f2ff50a1645a821fe6fe0250c9dbe43635e45cf3ee3ff89618a5c36ceb95ccd83a3654a460a9d1fe1be84aac0a9dbf802b61335d7f732603b51b427bc9bd2ac82d79d3de5673b85057498ec8ba45f85eb8510e4bedf975fced3f2b7f8355096fa9e14770969c29d1ff098c926ab3fc6f602e092ac3fe02d0923d36a1bff45e53f89778163c7f01af927966d02af96b18c02afdca5afe02bfe46eba7f992603ea1b4879254c63e747805de257cbad27ad3209340b4ad5660e99ea71edd548e081b0b82884498ac61f81a9e4a62a5897666e09a89253a3fc4cbc602a5f72c53ff0aea7976ff34365b639602f19bf0a7a2586e9ffd9fd9d29cbc2e647c02f695fd6fe06f8255665fb77fbd9fe3742595a9425fc056809656aff6b0029f1751594a56523fd8b7fcaff066169a1b6115fc96bebfd3bf029fd4ddbfffffffc4bb829a9952bfe02ae244da3505632a52a484a4873ee37fecffd49ff1f18946016fa47ff9ffcbefcef3fe31fca1a7842255481a644e166e0940431097d4bdef2f9dffb6fc02fcd7b157025692a045d894929ff37d82cf529fe8fccbf035dc9db55b029f14dbf9fd9dffd67feca7fd91fd76febbffd93fbc17f647fffefee6ff657f62bffd93fadbfc1a5b4045b382e991be8d7e88fc0b7246f156095cc6f06ed927f7b88b5f42bb63f7c7e854f89b56cf9bbff863f8a69a1a292fe8df03390945c97094007516ca90eb7680230e27305f60fff9fbff6fe4df6dd345603ba151a80adcf0b924290aaa2638c6c5d6f1268cfaadeaf5f9a3aa6495b0eac3a7aae35269a6115e3c97d7ea2bb4eecafbf3c3119249bcf933ec791c7394a741bb5027f2a54ce3c7c2887975f445f0d1c0afa1a344f6a49e0504fee385d2a7dfb36c18f13b146f047ee0af794539c9c4cdbc2be48053ea76312219f9ddf2e4a7b75820035d849e0c6929bd8a8e49d964eac4e36b9d8ef79bdb7f20cb97d88bc3431e19fd2bf03e1523eaac05d72cdfbbfceffe25649cfccfb1168977814f74fc6ff81aed4323bfece7fa33faa29225eaaa8b988925b5527a054b548ff597ff87f509341fca6cfc7ce1895cf3701cfbc3df33c0ac848787a6830691c30abe7f3bca30cd3dae19658f0d0fc86d254308b8eed018c482f0252aa4612cf8a85f5f4983eaddb879ed35bb4c4b6be1d6605551d7a04658ce16446b04e6cd326da5ad06b7a9705e90f48740fec727c93318d9bf326936c36d228236c946ab4bc2c474d77fed3a500a474a2d64e9a547f3b9341af74fe6fdaaf28e706737ecc6c9a81a98047be46dddf566e8c71b0dbc50362a578aa55f34faa79040fc609033fc73c607ac7149a4acd24b228e7a71adb10cc5b92235248e80b57231d37be270cc5eb44ca2d0aa5ea8c021bf02d2089808eefcf8287bdb3230e43f7f072992c1ba4cd4fa6efe668dbcd0d97723907343028bf65bd8373875f156fc6a780586b3a85d2dccd303c44bcc6bccc11c1a5243c5bdeb34cc353cf7af36461f226ff21309b2109071b327112e44974772e937bd3d0ed61e3888cbfde93619bef661d1dc75bd32b51bed73e7d67c307661c58ab827199806a1525e3c96e270841237be7d506dec990079c2d020f97169483cb636d284d7517761b769aa38f408b0cb7a64053416f45a22eea1e0c177a81380d3b5e14367339bc9fec281e9a8492df61d6729d95201df768c1d6729db593d6274186a67492295a03ce100999fcd200f1c50def717ca56176b9b9c7f8a57a465e39e6f99d36c03c18184c323f4592f4e9e0be535b3ec2b48552c63a7ee9356a5fd918e18c6bdd334ff9a85ca9cddf3d94c0ad8a7793032fe0c5dc8d1a45ab351eca3ad906b8d134dbf177bbccb20d3567ae93245cc49bea8007173574f2d9260de9be91245044fa4d66c6e9c391f086c5432d84df6387f7ee9389b78187ad545da8fa0231491f4592294cbb1c561a624ca266fe16dec98b8bbd685f5568eabbcd74e858118ac7910da203bdf7406f18f37723f8fd748ef6b3634a77800653182e7ef9a0ff6dddde3a10d1753544852cbd528839cbf38ab8779e34d6d305d4ff9a66ae7ee3c419126ba9837a8075f2fed3dc84d6af27692dc25acb26652413bc0608c0e046fd6a56dc24690bc5f98318cf8c1b2bf0b1f978732649146ec87d3142c82af7618a6c5211734f58b36f54da81732060bef3201d9e58ca941e13553a76874c2f801ed2df2b68ecd0548b97fdcf556ef17cafd1fed4d901a8dec91aed130c164adacbc37994bfa74491012292f4abc43cf9acf48d12e1260d1918821026b20f3a705b529f2f166e328887a1ec306d7a273a40dcd7cc4921f7de71a8cf9eddfd0986f42dabdcc81a2fc16613b5da8f955d67d3294f876beea4da85c8b88e78087c379da38f66bfa1059748452a2b8c21354fd09b7e10c133e41d14157a4441b39aec48f255189afa25e860f246d80b52a8f9df5474088918c3945e32b3daac187b7cf5e68603b1daa6e921ad6e7587c523aa59c62e51fe3c4ed1e557a5ae658e0f8e5bf764a71e2c1094704e490c7fed309fe3426acfa1f399464def788b5f6ad70276b7fa5a6df97ed4d64fbc29d02fdb3394fa9b10f4df1596c3763077b17ce617308f4914f9406d722e25fdbe5b32d26150dfe31105dda3f607bb2135997ace2028182e07d668abe402134050b87ef5dd5e824c3252eb87bb8292c62983987ecace121a314ae07fa6572c5841cf35ebed6327ed8c9e0e31110e376a2f69f6a9e76a0358cf2643245dfdf0f212a270ef27722275f49019e6cc1658fd11382934cfb2b94852e999e0ccfdbe63eb396d8cf570bd87e8aaa5bef798678a475aeb0e09addbd0c7386c9f097919a4cfb1e714a28726655c8196257b02c693a92d6f975754c2db7318c67527321008a165bb00d1aa46c71685ce963b0b4d013b1c897c11b80f3ca428b69afe4916226c76135213e26f1e3a4f5c147ceffc12aa450c50dd42c325d4ad0b0d55c69bf90d72e4745e6323a10247e7fbaf58d2d3fc2c53cbe4057108f45941f092d379ddf2e31b88146a10f905ddbc39b0f051af8894f3d603e4d69b6457d641e66f53ab781039bff5d7fcb41127b9b8f62824860fc073a678493e0cb8adc73d3835c4909d92f28c7ccf5c1c8672b3c1e339804d2e50d21011868637903f1430d293886c80c50d4befa906315bf0335f79214f7e7d46fd0d3579d1341975c4118b328f573fd140040d3fd5c6286c6303d44090ecd069a10acb7c6c33327a1f9ab18e22e02531d9276e6980c758d74bcd2c4bcb4fa5c86b1219ecde21bd3de2250f857dd54316e132bbb5da4903a3ddd196d7770901122e03f89f777352a70034a5a3aa8ae3254e545cca423d31d63c79a064e974a480008fcdd1cc8ff934ef1c7af066a5cf35b1feb908364696aaf373538d93c0ac3be3b9387e7c5d7c04ee838d42b5f546aedeea14e983c89fb9bf66eab48d2e7ef1d59e9a131791ecd9eba7ecadb5549e59282651493e947d0f511831d4d0da29f1acc1d120c15580ae301c48f8b619493028961d2276a4d471c08d4ea44a9f140369bc5b3a5f15a233aecd7b69ad3d11eb48350d00dbc5f2ae77244d389b19936faa5b81226b044808b5d2a26f7cdf16aa0bcda3aca6602b130578f47ca7217b430d147fa90142b96820108803f2355eee20e3ec6e1ad3b98093ca700e1d25593985950ec1e9988cab174c5c4d1d8fc16482228741c7d18b7b23976a2dfa3f1044399c811433ee0e615e914a6bfa457469db937f46eb441b75daf5fb2023f9000741d472ee520b1867c6124c0d396f09e714bf6ac0b2e5f5e0869e084fddcb8e9287b1a10456243b1ad8cd0ba1672e6d6528f06c55cfb70cd4d33755782f098f7079042e8192e806aebb93c9b85813971252cf71bea92360e7305d2af144664ffec334f214caa91b6022cbe1b568e0f3402eb911a8ce19d9b947aa5c6c2aceb6387d94f8bd6fd126abe196d582ea764b2c17132097ba4da3981f4df7e5ca967fb8888201e8e535fd5b4719fd575326c6c187f7ae164169ce8164a2cfc9569138328d45e531790df645253e4371a6c95b683717c1e910d55b2b008a5b3c6a53734328d0225d5d77757fc6b8eab27f5470f659c692f975e34f1da73f2e9ee70a057ac4c582306eee73320d6db9841c7528da4fccb2bb081507f5ffcb774eb6bb52b87a65f673bf12427e289b3e1d29ad7e0d0215f655b358cee02facd3f351d8a70192d9eaf5a129a1ee9d42875792d168fd8b84755bade6e855654086d892e350cdebe0a9009ae57b23a705613bcbaeaf413604b2c114580c9be83633c4679f01ca2e26185082063c1146934ec5edce40fb86e1be2c92e64c38049ee0a1f47d2ace0be01e095d21f6021a9415112d0e24ee102998d6191d0531de26bdfd6dd802484ec0ae527148a3aea7382c45fca03d620403c268d822185c9b222048287863dfcdf86ccc14a28a098bc263222560a0f847cbf4d2fe8da56d80c629d964f1a476661aa57dfb58bf181edb639d364fa8bb587ce07c98a68128a867e621a36ef0861ede223b5973143d020e0f8b220e63727f38bc03c2903ef264b1528f0561f561ba61da91dc0b38ec0c4bc29f6b010a21e0c437cb42962eaa5a1a03b9327872f431e9ee1837fa108633a1d8efdf0c4862f09ce9466b398b83949228211e3a14d998624998988b71e2bb8a483f285686f87bfd1d850a348016ec7ad884ae9799105d4c1b941b71beff34f681276148a51940b398ab15ee24e751b457f9acf57b8daac520d8b063cbe75613519923be516a85591bd2384f6d7aa220ccc0f64a7dcc43f490d83d2d73f34f47c6dce57427e0dc9054045e368ae0b1e17f6b783095488a7956782bf53c93853f51f2282968f30045c1fa378888e2c661b24ae76887dea357a7993a7b7e633b0484ec516aeb2a57735ed63223e195c0126e88a492163ab1ec93f33a64e87d557bb8abe8a134a4d72cf9d1b2f743d4c665e104aa9f96de8347fde21b22d568da941c1137915781b5e857c13a2928c2513ef00687b7dc07648f56f4710ca22f85337c3125345aaa816b96825d12c3aec76e3b5086cd8b7425ebcedbbefa0e992d33d72402e6cb7e521f22ea544db40113f037fd74d21d9b8d0b33abd25447f2566e209e514804bbf34612fa768b1c73a0dcb38ef49b614dd47b74666014a4d53f143661a445edf4e15b944d00c869627ec8445a5772ac4520c0bb3f1c4546aaccc0e712673bd04a37e717299e0de08110a30e7e6a0c46e402c3ed3d9d195e53679466245a047560f82ce7838ecc3604ed7a3c0ffe1c41579aad3c72faf9f6b6232e91f07199f1693338696b3f9c10c8d766712290567db5a8fd5ee29a2abd9eb2a5dcb331ba15c56086215583ed953797f31690cdd1783c4ab8bb54e1c4649c01b1fb141f6a12830732477e367bb4548d52bd20398c16c8e1cd95954b12b4c48ad93a50d478104cf50dff7832179c2c3cc3eda16d2a0453460d4e91b24ee4c1e4a51e783451d19bc4355f3348708e3132f8afa15f98bf7f12029f62b1b2ee666d7c4c380c1572102dc81405864f01873af3be6241a28ff34e7a3bafdd30060ce633e59b488150375027b12b38521d859436e96942fe2e86f8a2aa0a25cb4f1c698eec7aeca2679cf20758a19d3e5d289b0014de67e96883b240850c7091d34d1cb4cd0b25cec76754371303cc841a5342b612ed4a4a74b435badae9b0c35c4a7111cee4d43b72129b286728e8ef18fe8bb6e0376fd2d6384568143ffa5b6abd9c4e490ef501a5d31700662aa461c01832b5d446a74aceedca731551bc625fccfe2a07d3915dfa5411d939cfc71dbc10ce187b7f0e982d7bac0185c96b9c3d3f5a57ec04d9a04cf3031c4df23ac9cb7ce625d66024ced0bde4f58ba5a24152b3b62485736f3f3502738ada30903022ca7439d777e126b317f984ec7a7c173f06bd68fbf83a762ae475be9802d24312e6877e1944b1cfce55158851b7a790b12edd9c8b7f53832a5c0f7f591adbd0a5d89e618e7e3bdbd9b94eb9f91abd3b9e64b953bc29a8b2e53b0aff1f7fc6893b6a48db35d1adcef55ec5162d21266a0f514c388ab92e8d67dfebb63825b082b90689868877a3c68bbb22bce0d3ea5099a3767489bfe06e0f785c59c3806855a0d546ade91a73345125a844741b68cfe5124d8e0db227d419db1735e2e0bd7db94d998106e6e91c69d4539640ebabcc851870de8465563d780cfcb6aba69c061cfdce350802be0ea2f65953ac3462c9dd5d062a0d00174e45fcd464c5882102bf5b11c75e07a977070e6c9ee0cd0cfcde057e7908211f3d1018d4e601685f76cbe68fb7d02ee0939897ce42fbb2799eff8f30ea6eea1e6bc7865ba9fd1f30b5f20612b8428a10b923802818806128fee788b14652b21d1523eb203fd3ca6cf046f8b9612948f033e7ac05583f738599659ac09f59659a30c97ef16f0c689abf9f821f569509b4029ae66b02cd333381b9c0344d0e66d94f0b88656655993fd35c33cdabaf5f9759f533adaaccf8a7c004feca4c20f0f7abfa5599f1ef678a6555fd4cd35c33c97e5a5840b32aabca34cdf734216848c001b8c1ca049a09cc2a086682046b0a604428332b5499bfdfd50feb9b412f548109d3fc993fd334d33a564f76193bcc4e3136f53386bf140806a4499a5e4c8864a68596479dc50445dd4e8ba06fe701f53a2fe70a1da45b059da7d1690e922f93d3c286808354f6e904a431348604412df60dc6bc901898bd13b44c179279cabd4b25807ba2ea698f4a95a13d0af343bbfb726fc8826ad870a2719270772e90708271f52c0f64f43bab26fdacfad13bb0f7fea2c305f15ceab872f8eb9b2e22970d1c74f3cdb481987ba692c10253419f8d5f293b37f8f6bade9d0ebd2b85c81bcf2b6bab395143469cfe80423ac08807a33ca2eae49c3df0497102eb53871f40a7a26bd06104a117645eae59193c369a0b04d4402e10059103402790c93c06e2f07079a90d4194088bd2004243604c11e2307bffc13520e102f0cbba234c8e1f348aee5431ca22042894a60af92435075ef029a0232a0984513e981d820a60032048815204468a0348d8819a0e0d0966ef559bd28e22600421c3a947efbd829007ee3abd7bb233aa77658edbd163878a9d2676f2ecdcf50ce7d979164f9c439fd22b3d913e7dde37db016147cdce063b64777745239ee1f4d0e13cf3d0e14416f1fe2c432814c2d0c4a8f773ad0e9c3a5cea3ce9e79ad6b996dbdf789e5a676e7fe31dfe8974ee8f1e2678f0d0bb8915ac435787edfdc48b27dfaf911fee2d78c0157f1bed615fb1563b2e911e3efc3ebeab1367562c8274e220953fcf7d524d99e3326068a165d03a3bcb71e6d042d3ba719e6b27da79c3fcf56e9a74420885e8f9e144d9b3c389e745bc627d23c5040da081579cd58e4ba4d6da991b10c280b16e9c7dbe3c1a60f673adfe730ae5ad54ca7bb752798f00fa3974bd1b8dfe88abd55fe98973bad1e7c81b2f2a7d9af2e34b398c7aef7df3f9e51820274c3f737fe6fec4e51039f97efde5d8c9693b95b77d7e3ca457f639d1fb8fd34fd2cff8737f2b870014e856a120f53e05001eddc18810dd1492a5770cc1de81977aefb5c980d9c8647436c48b427b394f207356d7be4c86b37fbc717c892c1e85f5d9bcc48539d28760606a9dc990ba67870e677a7676d860668ecead845bdbb084dbdcb0858814a7870fa7bd9cc7189362d0f3c3892f91c501d0f3c39923fd5158e7e8bdf7e8c13797fa122f2af1d4faf0d4e85fabb9d1563b2e916f550e3201400709c7d15ea236602801c21639592329c2001d808a0aad6057ac20792382051ea004cf8ada8cb6544bd0805ee84c98140248a6519a19f0088f3614336c800114c41c0326c99c9d89660ea032985dc03a4bc12aa5b4585970c55c00e45025d88552034dd20c6615f00c248153f00b0b2068a6805747c628e1d42684153150bf4c71f4dedec074690b6afa052a550547a22e60da3a4cfab5099348d05c0c496a0060f4ab12290b1b465224a06b857e3da67cbdf87463c29ca33e3fbbcff9a70aa1187c5eeefcde8898fa04f600051191e4fc52378ce8ccd13560c09f35bf2f08f004a0e432054b0c32a6292f55ecb08b622416ba9890182081650e952c434956cc3c5134ac891181942c6aa09864f4b47309e80140860724a61321308438815125013b40ccbd357493b4f43582b087c38cf14002be1b6b72e40531476c3972a11200a7bd134613832273532d964c82c964e0244511ed4b044b2d7a7fe08e0c3252236a9005d03ba21f79b294888df98b7a9f8386810f23d153264cef5b1ca0b7a485ee94c2d03b112c2a305c000b8082dcfb7181417097310df020f63eb74487fae706a618c9dee103a4fcb9b107cb4b4def653d40c47ca3a02400d23bb00c5fa604c8cc7d41aa4b970a7909f6aa547fac8430954a8d2037602d22857d3450a9a82091d327c11d47a48fa6543ae450caaa9d6c89659a948a3e3584cd033fba020d18a57213636646a5883b2154289570528ce01d0d1b385cf549d5450544243c816eec20730715293f682cd4fd346d2307952323599d46d171e095b706d59d02da924f9684a902880caa01460d30044424cf01a50baa255f1ccdc1f286d29b255650e58e48ed992533e8980305d50b00e082206902e7421d125420f6c84975c7d641e780a0b230641e5a19719c38820395161b3665c28849c5e34d7e8ad3a748a39e308080a70bc6530b701963b760305404417d0ace223246b31cb31720314e65799287e54f1c0b7b00a03b152481466d18c408f981f3762a0f889e428e06e101c1a1ed541c01305e290d2d014a3a9c6a39b15a53c03490a1c49e8a904508203f52e848018576aa1fca83f0b1e0632d8f99a94a4c00c074c326a6a81833c5c74e108a9ba294dddb652a8d8f0e5c7d32dafc61b1c0140066fab83509c137774c5565ea06262b14f62a6c3ac2c794297fa506992565beec6103ca1409422b629ca57501fcd0640a2d4920096598ec30d56192a92d03ec9a701291676801a35210a4da4b63ca00398c54142ac5684c1215589e00f028d07befa8fa94aa53490c10d08398ec280199045cd484e87fa9cc71a5b0be8f2888383d3f9c4ae592d6c087da69881c9748b5fc68df69c894f7ec7befa67aefa57aef11f4de49f5de47752bb96ed5260a8250bd7750bdf74fbdf7077aef9e7aef9d7aef9c7aef9b8497d0b405d19838d7f01ab9bcf3615e3426f1d3438713570a63619ae640ef5d53ef3d53ef1d53efbd817c79f7f93732e60167de3a84a0993e5f6fb8e79566d0f44efba4a72df5de2b51d211342376b46fe45917ebf3e8bf32ef334eeabd9b6bcc36c13266c13256643af5de7b97d47b8fd47b87f4a807c998f52099b11e24f3a067c57598b095a669bf95ff45df08e45dc48b7ac5b6badb46bab5fd4fe2872a3846ac587f5a7993a0ab7bab7f8d2cd2f89773fb72732352d49f887be31c8bfae7bea8cc7df2cbd575fee772fc7ecbf1655bfdf7ee1a298bc11a20ad8769e466347ab630797a1fd2e8977551af58238b7c3e85b098e35f79dbb53ce123ef628df4feb48d1fbfdbceb58f2c1acfe39de7f788b3782a97f9c7ebf3477c79f7cddd6da7f2a6e18fa73f93cb13f993f75a1e5e549ec8bdbe33f7e78d9f77adfc7a7fef36710aebff954bfae3c8e2ddf9edf37be43f919e46bb95dfc6a9a1cf68f45fa9c1763b27a890935f9c70224cd09d72329d0859aec4298f38e9e6ea529c42e44fde27dc79a796b6b19aaa198dcbe4ddf9ffdc295cde7adef6f45716eb901e0df9e790f789e7d1b7b10f29e214d6c5bbbbe55d9fd22b73e44dd7451c0f791bfddddd89a3e1b67dffda2bff71c429bcbbbb71a35fde2e729ca7cf7ddb89569f681d8e45e25cd2a7f878dec3799ee78df33cbfb1983cdef48dbcbbbb3b4fa17dfb1ccf97f769df423c2f229767964359306038d7eae2100db7bff2a4c387b7f2db18226f24964158ecf47eaeddb98915c4f267e45886b3bc7b88178519729c19ce72e3d20b8527da8df3d442bb897b67b9f2e3c8e2dadacfeb4a0701bc740160cce1293d910da95cce43a3cfef7c880f8d463fbc52650555efbdef14e2bf6854fa8f8617711f77e24aa1d1f7de090deabd67f57eac927ae557a38b425418af696949fcdb28e243fbbe95c97f2ce643fb2b7bef828c43e5ad54fe3b1f2697c3de7b2040f97dcb21ef62fd65a3ff4317f37f24e645a588debb9fbc3ef80d87872ccab1f14116f18a4a15b51fd17b7fa3c01e3d792a5151d0fb9d7f7cca1ba3d1b309f18f9fc81b2fcecbbb2e7ae552041af2e3a7c78b79ca7befec331a4f7c89233ff2e337913e95cbdbc529c4f165ee953e99f4e7b2be95c9538386f31373db2ed6275ec49379f74d3c695f23ff89bc93cbf3cef3e83b4a2761edcffa1b45f42ee7c99a286fa220e9bd0b3f8df469ca1fc52eca5beffde4f347bc789e51e22863e787f35c93a398509040c1d13b9461ef7b6a4f00a83f5ea754ca792a64ba2768bf80a143cf6f64ef1d8fe9c18989ded1a4cff163316f6264a289c68b471a2f1ed598c04bdc74a371b9649513a7f70ea780de7b9737375f5e67abb8f9f23a9ffbb63cfa7ea31b0ee154b8cdc9c97643b9840839157473c3e15a124675922b1dc9a3def190457a59efdd469b2ee2dd6fa8aaae7b5eae76f3c77bee236f38ba147df41120228e40c8334206570a4db9de3b5dff659911f45f0ea3d11fe7ee9b6e441cc3f11bbb711bb3f11aab711aa3710cc3f00bbb700bb3f00aab700aa370fcc2effbba6ffbb2effaaa6ffaa26fecc2eeebba6eebb2eeeaaa6eeaa26edcc2eddbba6ddbb2eddaaa6ddaa26dccc2eccbba6ccbb2eccaaa6ccaa26cbcc2ebbbba6bbbb2ebbaaa6bbaa26bacc2eaabba6aabb2eaaaaa6aaaa26a9cc2e99bba699bb2e99aaa699aa2698cc2e88bba688bb2e88aaa688aa268efbd8b072ebd77b39b05f4310599818828fb8f936be54d7fb94f236f2411f726f2e84fcc6328632063d831e6183162508871c5e0d737edeb7fae218b3dab42cf428588c1db3515a2c2340d79e33486bf567e9c0ffd5d5de9bd0779d17b17da5f791adbe450ec7db8fad7371b9044bd7721102be5ad54ca3fd0d0198d9e0d6ee7e6844ae4de8dccf33f899f4a6fa47f7df6e5ca9fbc95c99302dce23885136ee7e6cefaff5a882c7a620916739b109f7dee6b22ee4dd41fb9fcb5f13e3b9ea7700dbf709e77ff78cfdd9d4262f244dec4bbd3be4ffc2b89f96d23ede299e1ecfcb8d193388577eaba3c7fb22fbf3b73bf54d29db83f7ae41dfd93f8ddf995773e770a73fc3612f333bf73e44d23efeca21bda07ba0eca9b441e7d1b479cdd9dc41cffca9f7f1b593ce245a427d2ff78e2218b5fef1b8b463a2d27e2158d277e1b4fba98e345ba9814f181ae43879cfe7aa7cf70769efeee035d07fc68341673fcfcc8fb1f6fdcbed3f2e57dde78677e23f9ee11a7b04f791fff310d593c3f9ed21b4f7f7e3d4fb4bbe36c64f1567ebd7fdbc853782a7d12ed149a3885777773a730438e6348fae3d9899f42fcdbf799f429d0f06ea3cf802c9ee146e327b23885b8b0cd8d3e977609bd40f5af717220e29e585be9bd9b73fac00430a52f481f5fb0af461fb16fae6f455f5c4fde67060b67e79ada99c1c28966e15c4bde279a85f3ec3cd7d0f0f39401e3d737dd47d6073cd7329cf9b3fe725ff256e6c83f54e6c8e21a1f1dbe137c6bc3b53d48bd1e1a8dc5bce170987f7c98f49f38cc3f3eec41bd167a67fd5c5b8e3ad79672fab9b62472aec59d6b4b08e75afea8f7732d47d3cfb51c47efe79a8c1eccbb7046e71a9ea5f7730d379e6b431c3575ae29ef9c6bb8ef41658bdebbd2ec5c0bd67883d7e071aec1e8c11a63693d989c144ca2e9fd5c337924ef7af036d5fbb7ede59c2fe77ff44a9f3c6fe41af22ee2b51f11e25e6da4a5debb100f792bf7ce7fbc711cf72ce2e6900e8e7d7a4fab913e2d477ebd5fc178cc89c3a17279f7a9e1bf2e2ef1d470faae8779353e54fe1cf747b5bc1a4fcbefdae719efa4da5d140a7fed8f1fe973e59d3c164ffc78e63840effb7939fe739f477b258af32e03da997d0f89b827aeadb9ad7aefd1fd3c6f1c81872c26933ec529ec33e645ba6844def589d34562d22bf1ce4fcc4fe5efcb3f3167710a9377f2c48bc2a43f2a3d72791a8d224ee17de2ca1b577ee4b23ef1e392a6bd1b1ef23efaafa43bf34cf47eaee115f1e110cf4bf9721a7dfd5c23e29e581475ae21bff1c46fbe7c99b3f560b105ee89a7f2274fbdd3b315cb7a17aead09cfbb9e2c12f1fa97e8bd1be9bd9bbdd744b7fbdcd77f382c2287872cf6de89f4de4d9ffbb62175d1c7fd4f028f45efc725f29f77421c4f168bc6e4d1ffbdbbbb33795ccea747bbe74e218e7b22be3cffdeddddddc921c38693c3a9e1dc70fe6f0fcf4e0f67b2980ff36fe4902159cccf68a3a7871ece33ff4612a79ada8996e34be5dddddd29ec9b4fb40cc9627edec8b333adcfa8f4c6e2b1b854a6e5c85b69dfc1dd9dfec491771179278bf9e9e7fbbcf3f3eeae2f2f2aefa2327987df378564315716f5289c3f5f268f377d67f42aee4404e92a73f4d71be6f9bfb7b6369ce96f57ff1ab9bc47e4f9cfc268f46ccbfa23ebf872bae3da1a8ebc8b38f2e77c7ff6129cd1f9ec5d889f68c4e279ee7db8d30b132c9dd6d686c334ffa29fcadbbe9167102b91e4b535bab8b696c473e59d828faef727bdf7183d78c7a5e34a612b44d3e0169fef944af9ee3eef329c25bd720fb95c5b93bbebbdaaf7bd8effbc6f86edbcee782b49f4def5ba7db7a0f75e0f393deabd38bc730eab20e9bde33752191cde181aefeece63d7d2bb5aefbfaf197bb46ef4de913d3883adcfd8e78d49bcd876fadefb32efbde3bd77650d197afab976d5bb5e0fca00d1fb4f1a3f71a8fcc2fad73885777ee2c5f3ce7befc9b30a13823188b852d8f7f386464fdf4e94c098c40a53619a66f45a0dc0822ffa7af0c5dd832fee7af0855c0fbe907bf045db832f2ef4e08b083df862ab075d44d0832e34f5a08b473d6897400fdabde941bb303d6877a507eda4f4a0dd911eb4dbd18376780fdae1f5a01d8bde3b56f02a410307bd83752e2fbbb507edce1eb4e3ea41bbab1eac13d583759a7ab06e811eacd3d383756d7ab08e4b0fd629e9c13a1e5bbd2f78d0bb185d971ea47bd283747c3d4867ec413a193d4877a207e9d27a90ee410fd255ddcaffa23626976d2a8879f2b7a9c89749a41b16174c70a5f0e6cb97f99f13d1bb0417183aae147ea87f325954e6f8da11f77b1df2227269b6bddbe8e3dbd35be6b8b246f2461ef368148978f6afe9d9bf70d182855d1ddd9cdc8a38b8146f284e982841426e631b2122865fb765573545d5846968a93668c87086e18205b30a1426a43a2594918d45100b8300f6952a55aade7b83bb1e648108570ad935ed2b6f3a2d899b7dfeed86ab3f91f65f2e2f1e8b6fb5f2dec3711f2722bfe188b98f8b3b2e711222e0169fa351fb1170fb713fa2f6233e9ec7f17f342eeb3b45efbd5845acc233557ce30d571b6f13c83ae4b7712b49e41fc745b0b1edddc63f42d96744aa40d6e1357249e2d35e3dbf8d226e4c2ef3d3dfcaffc2e7c6dfd686d7c6db441fd2a7b86fbadaffb6393c64b146fe249f8c74937b3373d42980d7b46fa3881f8d7e59e39f7fb651c4bfb2f76e7fe40da7024f51ff5bf95f206f38b636e44ddf746e371d5eff0f47ffe4dc3f7a38fa27e7802ee698a4c2774d4b33d2cd19bd77630fca5de9bd7be8c13908354e0ef8adfc36fc379e785e9c4fbb48c471a530a77df278d36a2a74856b1afdeb9b4eebcb8b4a753d4ffb3efbbc52e94fa488140f7af06d500fbe35e1a0a1f77e01acf7f8cd460fbeb13d8882540fa250d48328d0f4200a233d8822af0751d0f5208ab41e3c01aa074f14eabd5fad786366f5deed1e8cd3145c21872f6b7cfc4387bed95dd3d27e6efacf461c91defb79e6fe44debf1a7174c2defbaf07558c8a8bd0fb71893c3d78382e916b6b6bbd77be1e54c187ff258e17d5703522fdf3bebca8f449b5e34d0be725312fe2a9a9ade1c93c279eb94f9e1ceaaffc78784565fe954b63d1dbf6af4fe0070c3da802ee6d24e04c098bcabc0d4e4e7edf731de8f6de7f0fc2b5f5de51b8acde8535beb6862b85f527e29e885caaa54254f8ae6969c01e4c2197e243effd5cbbbb3b737ffedce7c9a55279b3f1a149ff896bc8bd1b9987ac53dec8e589f4776e3cf31bc996e34b0e45e189f427eeffec45e079f158349ec45c599c4fa43f917e26e6cbfbc48b5fb9cc97f69c01ffdfeef3c9f3ce3dd2edcc6f64ef2424f4dedf4e949dc8d27b477ee3f9e1ac8b475c29cc95379e47179735d472e58dab7dba68c495379de27f1239df8743de45bbb96f4c169574c8ff861b8d2244e0f5d72be6b447ba11716f220ef76f7b371caeae75375d8dd74811f82fe23e8ecdad76a3f1e2716d0d47febc3b5f5bc3d7d644d46e254af58ebff8cd97d7f9dcb7119325c8e0ea0b3b172e5ab0b0abababa35b3027a7fcc5defb8a4ea2eeff4c7b377b377b377bffb5e8bdfbe8419948cf3d5e51cf23bb55230fc3dcfec6616dbc819dcc7aafe2d4abce58f58ea596e3f5e9c1c399e10cf98d425a89abf99d49cf34dbf8f1d383879328fc78f57741e7c626224e04dbd9e1e4ab8b668ddefb8f1e6423d371a5b04f9923bf5ad21fbbf97bef3a7a908dace34ae1af6fa4daffca7c56c38dc69ba66fa3d1abf529bd722e1ad5727ca99c8bc61c5f2ad5e6a2510d59dc53fa3aed1b93499fc6ba445ae97dda37ce3ec7d58cf79dab259739be540ad1f3c389fcc673adfeca8fe3bef7ac1cf9f58c46cf161c711c313782c308b3115c23b44654f5de6fbe7c99871f4590e9f93279572722aef78fbcf3ba8823e99fe4fbc8e5894662ef4e0e7bef670f86882084a0deebafbc917845a3cfbd7d226f24daf9956d9d62f5c4b93c4fd31fc5cd97d7a5e8fdad77b3d7205af030c4a9c4a102f61228d57b07ba48ca8d59a02bd5a7de7b55982d03c43d88a3e7edbd9b209cc050c1a4c81539bd7773abcdac8c00b7a4b1f76e1ec9242183d2aac398defbef4d0641e9088623a27aef40af2581364999226750effd2a8028a3cc426ba842f4de7f934235c1614a8aa4b7f76e55e50e8b0a910f0d477def4e6af5de518148802b8573d1a8862cfa631a8b3b2eadeff86b4f8b50c3bbd570fa6edbbb93e7ffca4fa4130aefeeeefc3c6b64d13eeffc947187cfddc1a87faebc93c9255ed4bbcbfdf12b6f36618ecfcbb9b34fe9897745e1afefe3f9f58a4aa23fdd4ea15c4c8a301a3ddb9bf0ee7f1237ddddffb6f0ce68f46c77df46433b2a6f1b595c41ccf190df88fcc69c6f594c8af834f28613fe650de19d7d9fbf84f02fffb2c6a9fcb6f2e7f69df01b91c519af8fc57f54deb6f227718f1789b827de49fcee2ec791458fe74ffc23eda2f2eb9df7315fdeb33f7163d1e7bf3e914aff8de79d9fc6fb4e9ec8bb58dfc4dceee4cb897971efce857d79f2f84fbca8f437f2b4dd4e19776b6bca7f07a3a8fccb1a45afe795e7dddd892cea1571e427fe0c2ebcbeb4ad3c3beb8fa7fc474fc44f3c1bc5e39de34b3a4716cfaff4caa24f9e697d3fefcc50ff1cffc8b3cf7827cffc897fbca84c1e6f3ac3997d9ff8cffbe613bfbb3beb4fa497f869177334bcb8a7fcc45cc52974c3ef3ef286bbab8b77a7ed760aefea6211594ccb8dc5e58c7f65f22bebe217d61f5fdec8130daf8dbf882cfa1c79d34863dc29acbff2c48ba7f2562aff89f4271afe4fe57de6f4572aefdac6f365f2ac91de682c2a3ffeebfae37e4e9353889023717a4fbb9dc2bc889f7d483fdfc6f984533177e2f4777811ffc85fe244de388d62528430bf91c89bc51d777e628e8617cf7c993cbfb148dcbb73e47d24e645e58d67f4a7571697c933778b13c1f79167fef1943e179ecadbf679d12bf3b398f4e79df2d7c6e272049bf0ee537a3d9ffbba381412f122b248e214e637b2c68b27fe8f379d2f6fa4ef332693228a49112c54088b497f0acf3cdce7b63d77e27d1f85b098f473a7f027fb36ec79255e34feb6e1104f983ceb5fdf34f29ff29b08b6b9b3feb947fedcd3c89b3ebf72997fb95388872c2a73fcbc83ed7c7977faf3cfbf98178d1ea9fc39df3f7d51efac3f7e27f9fed9f7f38879714f58ff8f9f7d46a3bfcff3b46f7f9638ebfff11cbdf7aade7bd630477ebd9b2f5f0ef16487b5357cf88f5e69df7c79dd8713edf873bc6fae83f22661347ab66f9cbdd1e8d9d6d6b4d6d6d6d686c89b1ee2bf1e227f5d1789c362d20f93f8da9a6dfcf828e532f748bc227ed645a3d743ba9d21eafd56fe1767617a471a913f899f1139239ec1bdf74f238bf6afcfb27aaf3fbe24d27e410f62e8a4a00731202a9e7d79f2286340d33b314ffe9acfa7e8bd3be8410c53fade6db4955fefc6903cefeef0620a0c71bd2bcffce3dd70bdf7063d8801eefdeea6bbfbf4d293c090759747dfc6117767be9c8bca1c2fd667adf47b5faef7ced5831732f5dee95b993cf3e57daa68415777c14def49356d4de4c9a292c6f18ab8dbaa267264f1be3fe4cb24d22d5f2691c5146d355d34cecbb8b5350ba37aeff92722dd2c0cea5df8f1de3b580f5a10c0c2dd4ddc2bfa24dafff6791e6b9f2ce677f67da2dd2d73dadf9d2258fc6f0f8dbe982b7d12c7bd91ed1bffb787c3fafbffede1c7fdfce14387ff49b87540dec53ca9e27f7b88bc8bf8d248238bc962fe8f778ab535babd1b59a1810a892a00e9bdbff56005b8f7cea0072b6c98d08315b4da5098d31ea49052009b90678293091ebc7a70c259ef42e15dfef1a1f21b6ba427fe21f2be3bcf3c9fafadd5d5c5b63b7ce9e93fd3bfbee9b37379f45f79a6675a06dce8eff23f478754719723fff11b93c7e2d97997213d537177a6b19d152a08f17be9897cffa4f9bed2eff9f38f388578fef1cebc384c313cf1e289e3de480f3ff2861bcab8abefa2f2c71d97c722b298626d8ded0e46df8cbc4f7c7917f5909e989f4abce4d1e7f8f7390624ee8968e73fe922d227dd4e611e1d604238861ae5e920c4108ea1981a766422d7113d632661a1b16c9d0aabc3f0e78a03646472126b53b0d40d400955b720c79e1b60733208d263238c6c8818198db8482934739d8ad3202e55e2c4a04d69748cf5e9b1299bef485a324ab9b522c7a53d79cee6707aa02c0eb13d13339afa8c18f0c413d99740b6f492b42296c6468c2d54d39a5286204c9a41f6098dd70b3d6e605ed8895263e041039326d9f9d46622cb9a2613b21324044860a40559f5e628a2cf20a1280b938d3661395278ba72c7026fd581a58bd0263d4ebaea0f2f26a5e07a130a1525316c168e22827169a4380f619e884a553601d00a33562cac011a61a64268a2830a002b3a2ec50e74411a42a46b8f1f23abcaf5c5475329b3e01aa3b111f243d619a845f2dd490f26313825baa2e4401934a07392a5466c51d0cb0fd26b74ea00ad1a8d44645962e24c88ad080d12d05153d1022a8d9902c4d1458f30434796026b4b8a437a5431c327d259f7a29466d1a2470967d09f2f0bf7a5b36f01c1a0664d16187ac2746100880b213cfad895174d742b1e068ab4d457a1baf4fe95e7a6135b0c016adc581367d524aef72d4e785c00ca812289292621aaf210bd8f11600802087af824a5a9a192054eeffd2b14df9d4759eed81890a1841a3d322278c5c22a89e24317c7c8d27b27a33378422046173a630a08e5c17c0c0165e504994da19486355c7f0869f8d292a6ccc74c8409d81b3616c508353090221e5ca400f59d91da14f14823bc324f0a1f1b862cb95416a80a264438807c882a8580f0451205127bacdc9509f2e00d1b3656c82f3506544948c28948161a33b93d593eb888b320696051211ee9a3082a1d9a80430c064b6a12b87aa044c212d598840a886929445719506e54205bc0110d68673f2650c4f8d8fa125d5973a6fdf2403a01018f602740572916702236c950244e715e67c8f8d82009d162d25d130f11ea1cf1e0f4b02c8220cab28540dffb88c7585ea80bec979c3b654c502b94428841d96242ef125796e149e6e7831d02c215a89701e1d121d0e80f88740921c27aef5dbdf7de7befbdf7de7b0ff6de7befbdf7de7bef9d6bcc1712048c64e82468410a050b648a16b03a466aa04a1cdac4e7cc2b80e9c50005c836cc71f0e4c20f261d55ac82f87020c4c1c5a1cb4a0fd149c09253125ec32d4783af3d89ae0a293973a436301697a20aa31563385498289246cd572a2e74ed7f84fe969f3449ec1c38d834c453562647cb1d095f22c83a8d7142a801516ebc7cc953a0c51041d0371ada233269e96549f04a8e9d1a5bb3a3fa4a8b8d923d43fa6854b5a48678c591e2012bc9fcc08d0658dc09c2b6772982861c0bdc9271ce88492ac3e60b94ba48c10894602853699922f9e7ad0991313666bce2340d953bae2c7e4c476c305590142636440759aa37606e7d040b2e3599458e8250cc0ca243a841922c19f4f094694a90d75580a221779e4169d65a68ef0b180578c22eadc880a2003c734e84d8138549dc9f37c1542d0010dd980b47cc71ca86da63edf2b083c896a1025ba4df151c88e84ce011f6e668c4dc276397a21f6d8c1a6c6ac091842c605c973a9510db32fb7ac025a60b8b07771ae40902002d79a24d123e99c47c7103810dd75502a5dc209151a71f2a4589abcb22d911d9b3e1e5cee778509265ad4b8e0729f4bc4e9001f3c34040a2cfcceccb1f0827a100aeb01004e2c18a08ec9816c8475986ac1e6d65125082a8ff2133d1d7b6852b919738053455e92bd1790c4a8142814a604c1a743905c60e8b290768b97a24c01c2c6439179c872d021cd0d1698f8929788e575cc423c94a1b1c14baed72f819e2a83203fb994921810da13d47d0c842b88161953686808b47785c4cc471409419134a291ebead0820a085c0c36099c3d153b404c498822f3e01de38514c06096aa0abc9da405283b1af0412b0d02eb184d02ed8ec185445d096120e555e11453335a8206cdd92b4d05e9e14f061b585c0f1d12901bcf8302a222702d203052176ac9b0b0f56553e1022b361cbac52fb24d4a33287f054e881d586a28a1752829d519f5a244ae1868c77f39ad1436c0f18356e5035075a2c48e9abf2a20d85a0015981e4749015efb8d141c6849066812e078e54e19175b9d3529ac1c29cc1c009b1330712e041894128b6196c34d56913a551d005942ac92567059c8890aa21c54526a6eb2665e78d80072c59d182ea1465e7c52becc828d591a3335a7e28906380160dee85844d10809072a84a914973c81ef8d8f39d1e847261c9804a755c21042a5a6ae48a0be10134de4c961a3fe0a831c08d0707da7e48508b6143cc44924903dc99f90c8851ba3cc841a54fdcb18599061819539d79194320c8e8206a226614759923f2e181be3597caf2102a3c8851d424059106dc190814283cc80a930a31a22780407e448db4dbcb0e4c81411e2ea5d9a803a4ef09033e05148d219b23c4cf0c27aa41498aa840864e35b1e302200f21831e62494d47049184ccb06108acc3565c2ea7f8a8d48c02aa608020ec089902af2e4d320171b1e6124d4f9fb06ce2bae0809045abeae6ce6c9a2fcc16ea0b4d984b4d52a5fa6c6cf41011e48aee81b1188428b4d9910a048544139a542a8149b80507188a0007a9862cf3ac29a5a6e901195f67403e953d49559c8bb7c4a52e09414520e08b5a2538155b982c2d3d3622ada5d95201a6112749588cb8595dcd79f3539ff1e2d264813c46438c8b48983066e973144558a077020fa1014c7081291aa2a73bb0226869cf26396d6e7e14c05d82d2a84399f39a2087465e5d8c107014b6c0e90a51009e188d0d41ae34a889f3635010a9c459aa13f40163ada0080d9707050e260c073149d4b5c5532a4d82627cf54931a80137795a07617cccecb864a5666c872fd1c542013fb9a084140e3c0197780264a50f1e294fb4e45d18ce3907daf04d6c3f528df2c0574450187a8978290a93060ad5a92078334446969083c20f0a704299b9e900f1e9d10216760fccb44d42ad49e496d964699411ab0d0010a8d88100a7e000880b1a5a201892a00b87b203d6350e303df9770227f2b33e0c4e3c80cfb8220f5891f017c111a1b283081c84abb39acccd8601841c050d741cd198cbb008c871e8c8034f0e2e8861731f6a8b80eb0e20255fda68d21b804f439a5fe9c818981e50195783813267a89541e72e4d12d91c10b8493904f511f9d861a306c731b8e8d434707fb66482b4c3451a0f3f2a28fa6a00848c2d3e507c49e4082543224953a0312e4b5a05141860c2c4ce9459a7b14b555b95e21e1742f1117be1ca90f2c5b505fc1ae6819454e3e151270440995a044014b608a20a48d4e711031768a01ee8c085630dca968d4267e7822c1672c2c0fe91245dae78252aa29e39d03a8e9120e3c3a61a0cee4450914907015c7e12785962958861b082dddafaa4a686e2000b65d0f048a4c1845c1d2fbb3b82526568d4c2c6b438c815e1d51023a38054019562ac39a2f7ccc96d9929826386e0e85223d5858f00320a3d3891255097a1228c300ea318a00a12ca0d02995b95d802601a474620d8d2814159658659153958c2878a0d6d1229b00911182d6286202de872314782a00b130f6294082ae29150810bbbe3545993624d0a2f3548a60238d1d922818f181f5afc84bb173b30d861f2ce1879e0e844932e8cd6308297f065c9c096a20d8443646e8307911e905063a7678532c14cc282493f9a4c513405c21d9a8d107d198e0f880d06ada52282c54187087d88280a9804610497903d7468e021a480021d1f33c2c82893937286434de61be227d33d432097737d12a02fc5952379748fd458b892e85311303442c0b4546d22a10182234e5671c93c322b60ae142191e1d01a2c6098f074412284abc7253b4b3e8a2e0492847c40ce854385c028cc9f1e7c088426c8d889337968123d63984a9d41d40008a32fb40c18b2a9346b5c5c8d52584af020812554622e14ccd994c09714285aeef8b0e8e34f65e104578686de9887be3d6f50a5d1b19123c1060a2d1278b0f5c558f640004652c828b10027d4de0db4af20968529429ecc9192e64c06021670212a0294ac4da8c2c0644e0920064a821134cbad0e41a20c33543096f90884e8491b336e5e47be44d0e693b1c4850a411abce9e26291d8262605d4684ab4e044c696b3fd24e5820b88e10c6c429312850f9d4f3c42d8ab97960f1a1ac0cd9c1b1fce74ba8bdb7180d81ba9ba057416c8286a0043135f8d054d301961010c6ba420c932410ae7f341d29f2e241414a8a165cead05e30d6440032b76c2ce6cc8d1400b4d813e0f58dd71c009db0341063784677860a03a008cad4ad70d1a7b5dc144a40810f500aa2459578f4401c85e615e413e096c3819b0c0ccc596b86ee8858417740060e0925766495a526b92a9c0d38329792344782abcf5e1b0affef000b3074187132f385164244859b483888f53105d99006e005bd848c19063d090c69601ac06784021d2e9258d0e3e335c6e6cf1320017236099020803888c812f456f2f8ea8e85a6024abd463ee47a9ce0a1347358414123918c28526480812a0ba1e8a8e7c91b3409e01d880c5f0ca52c4a621d20a2113a382180a05b2550c459050a80028d9608734c022a5810b44272426207d3c0019ef0a11ef9482f3054893112f16a4400296e84be00382b501c67e582a03873c95a82d8c050a496af6cc6d0d4af6596135038c024b0c2d41c6c928f4556241aa4fa2cd8a396b9fd56dd2d22d02a240203e4ca12ba1f1a013624c86932a5b783e300c91f0e15e14688fc8169c1b5abceacc6988961a281874270a8daf0c624522a4716420700a52926709e74e15357e433095971815503e487518000a1c48716371bc3e28f2216a7071738410a906a874a980494c0913524c942cf082d433aaee0cd02605a9885589a0451e4bdf43950f3cb23a38e8a2e3478cda440ad28724bf06a7168a07619ce2276e34bc71a1041dd124cc82468782ed0f537236d4bca318c8502541961698ae11934ae185dd5989f25a63f239c1202e6c4e80b5108ede60e58b26fc3e8c31e922214c103d82c0be2490db6a60841f2e6bfc3cd83377c587993c09104291ee3940c88a0e214e1820925ef4b9314186aa030a865288324c4ebe8ca5102c8859c8c1a7832006983c90ab0246900067c05016482c57c00d6210308c6882e7ea052353c71324f2fc0805a92c7de0be433c41e140c40aa2befa930b2e06c89891d64060ca4b3b63a17004010218002c7e306636ce1f1f708a941962808cec86263b0facd5c164a74271838d248a17ae234eea505d805a80dd84382758a32160598146a5f0606907de1831192e91156a608c8f957b97c40f45000065cd6ce144852d549244986a1163111154639de6b080b3fbd26185eb0632e7caf3d0054d53990999c6cad8c0c44e6c815d316000634044c3de72d2c0a624f284195acf191b044b23787889ea42634191462e4cc151e71c4d787046582601b2840c1d9a1b970cb864a8011697b632f02913f159b329458dbd15425618f2e4851b5ac2e4c3960c8ffc2c60c152a5b7326281faac39dc89352ecc13b777e40851d0ce8e2c676836a17193e54f902b1b3259eafa248188da48430c4a457e18aaf42a411253b3440304941c5459a61168128092854a5046a72d7872f640783297c0cc0d1c93eeba96463ee6985233de60e8232616838c2fcc499e5376be2270ed94ce99e593992109a2fa4ea956de2090ca00e1a53d6a9b143c8880cc07105a3ed9d861a8d18a1c7340e581408a450a4046922e24f481e2a5515a0d5212de3213d88e0b6e3c3a0500a2e3fbb3f7c0471f5601330c096439546802143e3db420d03b44982a93ba49c0604f0652a87c8a321c43ae1b887498f159c121e7cb412acb030671f292e0c1194ac595c0191f3839556082349048d6a180c480437a4a5414f2acc812c8112df094a7b629099d833963acf070552962657d453a150a025d1143462459011bc1664281b12a7394338a64ded2acfc20e32a24668a8b1d327f20a8021bc6402e5c1bee306954c90519d3851d25557e6c21f1d5860d1baf61273013cdaa8ea88d201aab690a2fdc681ab3330602d5a05365946c193027141f019f9a905a0126151b0348fabe8447a5214768f4f6be6ca5ea32a42625029c2c4048a45881e2b504001d8a14c4c1b14527f770c3401d4649fa0c7060a2449dd06b00bb48160c29e7d0204a7b22e642435f8407640238f3d6e0d29506b0a8479c9660414d281e95595264c57c2629004d510650f3c2300311a24f795ee0a819eb0126ce031b6235dc250e50124b320c256dd91a00918ba0103b61451d68617d8b36c928b430c05d6194581068e4460222b9060c5de993e62a6cd092126b1630b3f407afcb9b0ca2518960052a480459bd41481dcf99312530bd75a1ede8644502c802612146c100206c92a3b0178ba6ab2917b4864d5ce58d2c33c02404196229eb831a12514b200ec4882caf3c509377fa171abd111b40592419c5cd07842c72683a92512e4c9803b4a10f9c2a92caf4d86e045800e71e208c1d08e8343062d1030f21543b7940055120419fa2d7d39e3d1016300181f77902d3e108a2b8043675e050e6608d8ab816c82d0566fed4a28a7c4e70ed0994c6c9dba60098142152896d91d0000c475b230812f03ab5e26cf201d2892f83c860d879e57a30707821b25142e54a9c102e175e7e887b48a559f235face9f1cdd17271821ec98daebf3b19f43c45fa506c6c6a8c14f71a2b02880888814238059b86c614a75624a9d073b42a1ce02b98d68b3bf3e1db20f34909021f2005e05c3c9023c22a4124e5262a576688c9a8304947b461c6dedc8018708010f951438555c8467a44d1f2f4731b62801c5e02e879c3b72228ef58e082c563e6a9ae09b2b1b42d982f4cc1160eb8bc78c5466c4e03387be3b3632bd1f5e314e3d3a01d405d71460f1666e522133313567506e1e98e8dc7038f085c84002b4e01952311240e3242fb3a98b88692401395d8b44a91135e6662b51918a18d381bd0d625ca1b2809234c9908a3bbdcb07b150a8208a4440a834b8ad3c29e2b140508f20625d330051a223a79507b9e20c5a41aa7417a6f7c391da85247d6e94885d582f86a324143233144127f490951976c212a0a220783049ca550c436542eac489557831208008203492930794822f674a0d585c960845bc91e0b58194a7064b0850b2a6081225a941171e1c39e07007080344055d40541e46155a4030610446dbdc1ddb8e1c0a960510421396bd20f3801711a61bc6809b3b2b212ae61a45062c85afc0c6a182e61329b4088080b539447616603431f1204345f1c516c8ba209944b494e7f74fb31cad5d09249710440dea3061e477b05f7f44d469f20276a684ab46a8077d8eccb11e82c6e0fd197b208d9406ca162decead05b487c89a8c305660655116bef756106e43c3f0d847d5d09c000a05b9d15308f97213c75e8e1986c1e81441043a2edcda237be1a72dead31e72465931379983e1571c0a784d7962faf06c896b457ae28a1c99b3300c2220511aad0f5276095092c6342ceca60d9f2b325a24c0218a44865e81a8412197fe49d5e4dfe97468a60b490036702509e2ef225b150748251e21e1066f28b8005246131071349a121434e8a8c39b2b34873a3ec04f07270aa0d14180f2c9849b8d825088cb2d89c290052410b7a086ab404121716cb2e98e768e4880218411534f43970d58100d0d5e44a9d5da61509e48582402cc1c34b9cb0365562c87cb9e0e27960860f1777803404b7ec601a63e950a40e2c6e6ced31ea71a3eb6bf56207c98f223e47170b2c40484ba2b008072821138088153a4ca04181c284111512663404b038409097468a18cd28132323e9c11533b71ea21f5862c2ec81332810990610828829a053c2654f14395319860039b455f6e54e490602dee2440026ceda80bdc0d0030ca65a28727087c21166815ec3919e2b304fa5eee013140f2c22a41542090b3858649b6c9c28f4a68c93933c7d02a571204c112e360b90773e3da88b23e7d1ef668bd881cd2a8ce8a921daa0810c04a00273cc18b23549c70771feb4a1589401fdd8f98ac2d5f6c70cadee0e5201764a3b7754e0cabe0c99655e1a05886120e340398a8e162f63477c400822e3dda591f240451b4e461a6c1d4a55cca1b8b3824465dc1a54d7c6edebed1497b33218012306607d91c854615184471e143c60010fa8e391c822445e340dda325ec0b0c7c24a8b3bf5b2081ede1aa0571eb53475693f90a17238c954478496aa0870a92b62f8269d208091a82f699c2490b78057461839a2c4cc1905c4f4084bc97cbcda803c49132a5fc090a3c5c61a1cb00f6251bcb81965a341a707c6ec41b487788541f0ca1027a5dedceca48c99812107a4f9aceb4e037b7024c020e30180368d0c1770080883a0c20261c0a852de4a2140b6064d86613036f48b107708c084ccc5034c36852dea32810255263b5884b06668ee364316b9b01733507d515302af4e1aa323bf3c0b4f021a080c88bb0b1391a66fae0c025b5a3c1efc09c07da083833d0d32157aa382e90b13087642dc31c3e7411cb92f7b8607fc38b6ec8140a114e540240643dc0d3768747411f180851d2a619480a1d1c2490ab93f2a2e0c00214d4d082e0256b46d6af3084c8f489de6cae23308368312001aea2982661864885c92d66835a8a22287221d8e7c34ea435107cc8a96054e465490b1a24c0a0de5900069c87eec51d1661019d68beda1830d064264702965081ac436268ba56125b98f093c02b006a148902804409109afa343205e30213536880029888ac8d9500c72c88f83b47db9806704b064e75565c2a72f8f32e8a8c3f605a48a102d1baa9898924ca6ac0cd4783266c10ed14daf879dbf608d01210c3118b525854a8f344c5b613b307482e052103d71bc4eed80d457471932e0c901760b98354c1170384a74680e1c3786cc107bf05991a0cb9650c1a50b86a0105029cd5c2181eb0b96579f92482892d811963722bcd8875410113bf4400072ce986031e48b5c83039254a011c4232a0b1b0792b86bf27c72835bb814ba46b1212289d8098827d529821024db18313752a63136342f36f88c1488090a01109c530cf23440294bc6236c517a5c9931d065035209335e61540290c1ba32d89303eb2e61543a76356d4db8ad6ac26dd5ba0b947ef461a59fe743295daa55a19a0ad1b4b4af57cc8bc7a232f9d9cc32c149a67afdcb3389c9241b935cf47e7ae8709e6b77cabb33c77d52aff6aa9d88d4eecb8581d574294942efbf8dc68b29fe27b17a22eeb66a5d5b1ff7eee4b036de44fc2b897491da9e168484a6e34a6131e9873ff77a4565723854f16e23a418777a7977b5b1a8fcc9decdaedecd07bd9b5cbd77f391a9130f59a495f799213feb9fc6879ec4fc9ecf4e1f7cb4e851a24781649c1cce1ebd09127cf4e4118e33f727dab9a6fc39edf93ef1c48b7c680cf70f6caa96c151ad9e1a369ce9a9f759219af66be5c7d38cc963f1b6916e24e8d6d64c158d3acde14a738e6d6d4d5d971f943f0e1f2a7f92cf1f713ff3f9e3870e7cfea8aecb0e7cfec8c8aef7ff952496b9cf6f1be9d6e7e31641585465f46bb85268f44145422186fc1b8d46cf626ded86c3bf0be5ad54ca0c0625aabb5e8f11051a2a7f5e1cd23f89abd15f0f511bbccfc7fd6f0ff13e445987e80e19c293a51b5a508881aaaaaa2a20f0f7334d060e80118006f0a84ac2a3eaed4ac3696285ea11fcc2c3ca6a01d605453daab4a455600bba8cb932c2a3ea2dc197d618841f3c12b8a87a012c53905f2dc82291055f6901397835e291f58647578c1e095ea0000f2480c4c32ad843cc108f05390503782480d0e087c5c14acd0a0a112f055f01f8a842c2c3c104071380695b6a5910b652f9b0da90055b7d003a0076c802c52355bbd2ba22c303a8e04aac0a4d410a34ab1654a16991b0da80e5e24aec4aeb8ac682ae055d092024f8c272013ce5e34a0c88c687951e1e1668541dcfa105b2aab5050eaeb6aa4c601a90ad2a6e01d8d50f8b0556042c382baf06e69502a055d5022010f8036201b38009b4c6aa805875585c0ee2b4b6b0aeb04c2056155ba55665668501c77a6449b01ac3a301991e5b575511b2da7c5439f2416178f654a82c25422428d01e3d4bbcb9264ce411203cbc3792d326350c41075958305ea8804bf5a7d020407f242c41a74809d103707408501e3a6ece8051135e0060992fc195a13c7562b440a104d8ecd03123c68b162ae04a90905006f625274e8a336674e418928ddd48090d1c3150e3c823152a5110c48001f6b575280f9e3a74dcb449b3444991e10c172c54c0b901fa83c7cf9c29261629029427013a067ce97224c80f4f9d0e2d40c700390400e1f16b37798b41274a931ced49200e9c35033449f2ebe18c183058b8c91cd6326c3100f467cf952a4d80fc7ac609371232874e6912a03f0ae08903674d9a019c280122e3849b070e6b2f9b66e0daaaeaa9284d6240813d7812880327cd004e9a28490224d250460c106a4253a5de503868d0688c0992232d58a05b921ce9e32b93201510d5ef9455a95f045963aac4fc06a80263aabfb40a35850ad2801b80e79784df9819014b0c186642a80233bf123ce0e20206ab1c2c68106420b6204cc198d65602acac2bacdfd5959515d0ec574022e08195e06a0c0bb6d202922da0ebf1e15785967576a59505572d7060562db81a56ed011900b7aa10fd0880c755831f56822a340664b0191e5a760bea2ab4063d7e6c04abba2af3aa831d1e1ededab67efcaab4aade3288e2f1a88759b5c1100f0d817a98566b5b1242f4f8558901d392e6840f561b16e0717525210e889783114180257a0ce1119680c582ae055d36487825b3702d087874c81394785bd3e32a021e774b825809800cacf2aa8a20e99155d5e08acc74b0f6b0b4452b83212059a3a434f829b00ab1851557a1f830f0f05843d3e381d5991609ad0b5731aa3460c53ef008592b2080123eacaa2cd1fa0aa24018d06f46eef050b0b4abfc60a03a30ebc8801cb0c2dc1e5a58f195565603e0eb560248a645e24aab0185363cb4b0dc18cc6599882093d04a6062c15cdda1001e605568635d575a576b0f185c69299029ccf8c2432bcb44d94cf6cb72a1c00a18b432af565c695971b8d2f061848265020c5926aeb4b0c218b42530ab824b00d6357641ec4b4316da0b0cca05e2f1cb22035eb8d2ca1262ad0cd6d72d0e6b41159698d51ad04db0a00ac319022b019656959a158a2a388469150138c1ea0b4d904503639903842cadaf046f8f052c104e019b7556655665762586878606556d561bacca1298558d394881643e7808d54ca00d4cab025adda030e309038d6ee41933810e4073464c17233b72f0e179f6a7ef66c478d1c2ae6e2eeeed848935783dbb60a1c259852781549c345902f1c10205b130ac2c7efa80f9b24206b146e6b540c1d51d3970ca8401d3858b962c57eace30a809ab04403797ca14a8f905a74d7486f796932545fb03072dac304d98bc0912211a20cc5aec827529d0cac21a8be0a64d0c437cf0dc41a04e9b25499018f9b50ab8136e24e43536cdc0b5d5804195004a8a0ce17ad4ce396346cc0e1676af0ba1ab4a50a04f761f3cb809b0aed2088143c016009e1cb98145000196a880fbc001c302b3545504bf51559dce4dbf4b55967e90ac1e998a7e877e86122cb0a0d04fd00fd04fce2f0df0cc2faf8a8669664ac822b31a6310f603fb79995d630facb87e5b66b0aac14f8195d62f4156d60f0bcbea5765024df3aa6b75313f4070a510595426afc6fa800af64173d6c8e56d9f69e79d0c773dd154187745e35a8e2c0ef98ab5570e95393e3cde4afba783cf1f7f2f501b5984f3701bd28a2651880ae7b078aef4493918500cf3f9e19481c2b097731c054a75e271d7b18e58fd87aaaa5779303b5616b3b6da32b1ba03d3eacb6c6066a9556f0742a92ac3fa65655d01ad3ad84fd87ffda7c05c5105c2ec581cac3a10b8a03bb832bb0906b4b2627f0a7edd344de0cf846962993fd3045ed9f8993f13ebf725679a572656ff990c84c0dfd5d599d66956fd7e554cccaa2a2d33d4cf4cd0adcc9ff5334d93c6cf347f5975bf083ff37755f53333fdccdf0a13cc3481bfacba5f03d30456014df3679a573f93cd0a88d5c02b0b685e317fe655d50f38347f5559a69980fd2d303f64995666400f26d6ef579502b57e3f338303d7bc51952a2051a5e2d7ad4454f59f17b30a785665f53381dd2a8a19c9ecbf1e0c06bbd9cd2af3676e32b37e1a4cf367f5fb014d7335d5cc2c73c1eff7fb5db19966e6eff7abfa992810cd341584655d30197089fda49856bf30b3ca049afd17f73bb5ccaafe2b5ef5f3ce4c02ec1310307b083c3fa079655661990c4ce094df2f0bb632e1ab5fd5f95b90e002b04a0bad4a25a0e64feb2aebb766fe7e8b805766825f1550cfa4f05b9a2630cd4ca0e067666199bf10bfb21f1970acaa03bbe9c0bcfafd4c06554160d52fecf7fb995766956d263033155805b04abfeaccdaff136577b57d0bbf6bbbfe9a66eb8f27d7b0fbfa5aa5bf9f3f1dfb6fcbb3faaa2ffae7d75e637a55ff976defe19a76e355fdb5bc7e77a5d9d74ee7d8bf755dd3f2faae71eb536faf6accbe703dcbe9eb5f7b6d53dfd2e8fbb6b597d9788e679f7af4a7ed57d9fa4e76513475e137456dfb6dd3991eca735dc3ec1cc3afbbdae967e919b2fb5798b6693b6ddf7576575a865cb3f4cb7a34b56d1fcfb64ac790633745ed798ed9f6dbee9bd230645bb553155dd3f9b32d1bdbf30b79453dacd6f54aabb51bbbf5ec42a66738f6b5eab26bdcce2d3db7903d5ab32abcc66f4cff5ffb99858cb2eef7ffa7efeaaa2edbce76b23dc3b06bbf9e4d5d0fd7ec5c27a3a97fe9954d6b77765f569de9e4989e55b54d55fbbbaaedd67e4eae539a76e754f5f6eaaaacebe564745ddd38fd73fcd9d4a559bf42a6ebdfd6e85cbb6bcbb63ff57172bdd22b8dda6f6ad36f6bd7b10af95d5b1a46dbdfd66c1cbf750c27ab68bdb2bf8655f6a7360dc729e499a5fddcb6746db7aeedbaf19b0cabe95cc7ae3bcf6c9cd66d8c424ed5d4ae55d5aed3754d3f1b9f90d518ae611bfdb11abfb6cbc66e321ab3eccbda2c4dd3739caeb189d4bba8fbd357ad6d182e21a3703cc3ff75e99886d5f68549c83f46ed1a9ebfedff9aa22b2ccbabcbcea8676bd5d7703aa3709bbcae1fa6674fa3ea4761db7ed964d745d5d99e57946dd314f6ef085975e11476d7da7dd3b7a5db5784fc6d7a9e5915763f4cbbb3ed8690db184dd9397ddb9a56eddabb2064b8feee8cd2bea55f745d61f7831cbf9f5d63dbff5faf30ddba1ee4b9fdeaaaa66c1aafec1aa36e079956df945551b5667fbbbabfe520b7286dff9fda1e46614fd7ed9abcda35aafaf5fb786e7deadb584e6958fd2fbab628eabeecdbc2f24bb3edfbaeb46bb7a9edd9f69567fbcff5ea7d8baeadcab2ad2bc329daa2a9afe1b8467f8ab6ad3cd3353cc773cdbe350ca768cbca6dfa7ab5b6e1cfce2afc6b76955bffd1b57e57dfaef5ff33abca36abbadff628ecb2b65f5b369559f7b3afdabaae1dbf6fcab2a8fc613a8d6bf8a7e9fcceaecaaac934eda229ccb66f0ddbf69bb242398dd93a76ed3676bdaa7e944d93e796a667f84d51afd229fc5734195e511786bf4dfb759e55bf6e9061177ee33a5ee7b89dd1d65d35c8efbcd6f4cbfad77d67d7af6b06798ddf9fbe1e66d199a53fac9ec96e8bd63f8dd7b9b667d776550c72eaaaaeddaaed77ddf97d5df582fcc2b64bb3e85cb7aa05798d6b98addfefc2ecfadbda4ca65f3a5dd3f4f5e87fd3b7826cdb2c8db6f487db36765d9a82fcae9eb6d9d785d7f8fbfa9d20b72f3abfad8baab6f72d8aa6a7dca6f1db7ed6566bcf7ed79620cf709a7ad47d6db4a5e3992e936738fe9fa6d9b6addfd87b32d9b56bd656e7d6db2cfbd5784cfef51bdb360bd3aff77e7e23c835fcb236fd5777fe360abb28f14d5f33ba126624cce8deccf0376d87680af762d8261636068175c9c0cabebc72be7f763d08e352fa1cc7b0858705d55bcc818606650cd2e1c70b5b90e2630ad2e2f178d3675a2a85045958576456e9f013c7aa3400d59f59a12f30a385259379c4fd9e104258ff478facd2ca2247414fe00923119d8867ff9a9e61bc70d182855d1ddd9cdc8a381570297a37519827dc20b529304729f87951b957fbaf9c5977a9ea0dd78649dcc49e89e296891619ceb513ed5c3b2b41a9c34bfadbe1c5a408bc98f4784863f25824812989d3eddd6c789f11a9e2d7770a8fd7b43c27cb464fdf6f48b7b9bebc685777c3296b3f0279176b3f824d0e27e6cae208fbbe9571b51ff18d3e9ffbca65be2461347ab6bebc3824e2de8489a377f346efa68dbede4dbedecd3dbd2babfc469e5ef9bd526edbb66ddb9665599665599665d7755dd7755dd75555555555555555d3344dd3344dd3145551155551155551155551155551358ee3388ee3388e61188661188661f87ddff77ddff77d5dd7755dd7755db76ddbb66ddbb66d59966559966559765dd7755dd7755d55555555555555354dd3344dd31445511445511445d3388ee3388ee33886611886611886e1f77ddff77ddff7755dd7755dd775ddb66ddbb66ddbb665599665599665d9755dd7755dd77555555555555555d5344dd3344dd3144d63f8755b7655d3a35b77b1b526f789b90aa3ff73ca3819f20bb7b9619bdca6820d4e1ecaa990939387f25b5d9b8a14c316225278bca6bf12af7feef17cf25626dff43e1ef2367ec0f37432f2e7dd74f0f2c3f1e76e1de86f87e3ddc6daed238b7848996d0bae90e1ac9bfdfc4a7fd7bb3934678479cffae6218efb24aca67ddadb39d2238bc7a292c68bf511f77be76da2775346efddf4b96fc38779f78713ad83cf7d6d8722e953fcafa41be186e149dce7bead4df66eaefd650d9f5461b28d608542e116bbb5723241981f4c0f260773ad76fbc93ebabe8f821e267175dd5a356cad67198442e1d9d97bafebfd37d765b9aead3452ef66bb856a52811af3e20cabe91077d5b4b4e4965aa4deebeacf5724315c5bab3f5fd13e95b76d0e9338dbbbb9aa3b20f5f91424939e2c3bc8dc90d0814cbeeed0d34349810a4c32ec18b1b602e923119c1d0c34449854b584898e437492c6022915e9d82246c589103022e938364221a63f01ea78277520d297567400c74ec55444a1c9f1078a9e181990bce598b27785668207ad1cb493bc03c4a470c8a11647c666e269140e520cecdee0a0f2e0b8a335060f021a601c4cb28ae401a28b00870b302348401802010eb3207f04b07135bcd1294f419a52f0db0d386d8e7e6c4842e2461060a55f110f836ec401cad4ae49597443ac923c41948b19362805a98a805662878d34af8ba382f1dbb871c4c81d5ce6b6412201071e692c90d8d8ca62ca364226d9c788cda3b5672345df1726583838d1e3a14fc9e04d2d4c96b4af43a4073bf2d5471f5684117d624060f20dc2d1264fccc0e3bbf284881a31a8173ebc01d632d07d7ac3a73aa06742d00ea93d546e21584b02c4d8d3b34605014d3ad0ec3d99bbaccc512fec0d817469a57e24f7ce00e91d51b3f242ef53a20d5b90e4f0d2a353c7110d1b3e8e5e113c4a9bf4c0a9e9d1cd95b5c8f20189de39424799375486969880a7227529e069b906102ab8bdac03963cbe7c054e8e78cb135c0a398a3ba360e9a5a2d10e9c4e871cd28234aa9d54743ea6440f4c82a608902f07fda9cb6d40c8452c6b3482404f57ae80d318002cbe08c10db59034a64fae0ad7f2a80d853c7920dc18c09c2a255d0fdc8d840682a1e707ffc125c1710c1528fd9cb8912982748c520a724f1128a08a28673a585ad82028a44c43a5ac82c5d35c0d51a8ec7c8525615403019565c0c621493594b48173aa898bbc1a2d9ca8a522baec6a540863a14e6fb495e484df5558280d240bc870c10b013174492067a6362b44d89271c93004e4f0d01363c73dc90a007e8e5f7d6e3439e41a665c1e6e1b73169bab1f506e39c29a863c2b7a773012944d7272a02117554dc811817784f462c59294523d76206b9c9073640a8f0a928398b2354db9047935218d1d2376161c05258f56e8bee2389154e9680f3066cf0815998eea04bbb52a7805e3a95f0526a3debcc63c788c4e98c00900ce23c828638d0c04942cf061c480800e57818736efd38fcf8cbbd69067401e91ba1da99a17276f6e6f0aa8333b348fc6a54c261c2489160d359cd8b4b74b168d1d944e132eae701a6e34ba8a6646e8b15b507c44778498a5cd5051cce988819f354fc5dc12844387e617c5106f1e91210377a6a85507cf46991369880be0052935678117442d12049851b59920e611db4c59680a4039443489106291b5f700af4f83324f60cc32e101508380179ac88ae079504ace543851080f0d4e0e4a566d426c084a49c144e30a6cdb991d6d8a8386949d8446aa49c31e4b6c1644fab421e0cf029b022143a39628f0f0374930e0850e3effdf847daf94d4a5ffa3049020a83c9a3e1c2242707478d787506689886d095b2d698ea847ee02b73e03800b5bce23bbba4fee9243d5f0d56d7510ad15958188854ef4c8aec58810a8e82e6af84854c153e9e49227796782d4a1d776c8c994b600a2add4302fa64b5ee64073150a65a928f542f35f43890a903ec09cfa527a088952c32ef078d6d8d096c430e49be869e780c8c1e76380f217ec14b2709b42e0ee81560f880b29bfbb397743e0c8088760487327e7c5ee0816395077640bb090f9b8716068a991a3bc04434f4335609438ada9c130d481840b041999944313491f7d93e4c018ce7064a2eecb128b1d3306b812c35700579f19b9555ddadd22433342cc4890e57815c973c928c48305cc466c29238b4d264d86993b326878786422caa4a30c96858cce27390805de174301476298b8e460c488b2c3441c118b70c4f06a96287fdcd0181b52c0800018e3529bd3038c3a564eccdda92405069234b60238682181610783c20b4d8a662b186902bc70e315e1c561a6e3850ff5458a17605b34dde9ca02c2452417665cf0b960abe3a241db02510b2e2dee16715e8baa146bf0550627168190b0a0f28845cd83056a17815d0227d01278a0a0b26b620783cbce421f541e5a440dea3c25f9d41b1e80a88b5327448e13a33b085bea562cfaf4a586c4a53aba4a8c202049818a4147805b190b5010c8419783ae04f1089bf8cd021d179c0432f224cbe61a41b09c11a9a1e7c0a898c317cc7d3083c4cc03becc5c96991c2132392c72453956aeafd8636305143d2bee8e2b34c030db58d5dd880b1577409c91615c5ddc042a2a32a968f3a5a2878a37157091e0c82c80dbf30037a2866390e2508a2d299029e0502980cae210db37790344b6f492b412e16dca1bfda68682148a3b0f50301900c50b1128ccfe9ce87402ce89202756446890808e3a80136e9470b73431dc70b891707b33c1a8cfc4176f4269c984072f26b04a0c2a214009a2a4122b095424f490780246624822032619947c805ce427d3b5f2794403dad9af491ba636366d3cda50b4b141621bc3a6c726826dc1084323b68c388a41d9d27b1ff19ad0bbd47b1ff1cb323c7bef22fcf8f922a41c022282e60a244208844788513442204024c49210215c843003d1a9c7582aed25329f97bd537fd403f5033a9a9e8549e7d193fdaec7f5101ded670ff6de1df4069d415fd01574ad043dab63f5ab6ed5ab3ab0ffbad9fb8ff84bf0039aa9cc08cc32ddf4d2cd2c5b1298f8affc39f829f8fd4a99a2b6ca18755c29341a97c8b23b656b7aef775b65507a99de5619b1affd645f5ed6b655b6a696a1f5de339c6b6868675b6509ca3af2b834def4797e6471497f25ee8fc79b2e7a65eef16ea572897fe46dcc60238b696a1b4ee57dc279b833bff1cece9f179145fbc47f7e2f6b9cbeefe7652091a2e832461a8aa2e832c6d969bc7fd2d3f8bfa3904306daddda1dfd69ccf789c4959e840a39cb011990df38dcfbc8b3a1d213e9215e14dac6ffe04a82d8015b6220cc14eddd54ebdd149a695c5b61343aae14de451b594cb3914578890a4f34e4ddaffa5658bfcbcab4056147fff59baabf56fee312f993fef8e99feccbf73eb2885c6e818dea5b608cfaddb90526e7eecc91c53b4beffdee547ebc9f238b5b604bb6c084dcddf9de4d0ca685b9144cb6be40295f6c7d2189b94faaf5e5b8dc79c4fbf849cc7dd2245b5bebdd1cf3aab7baec5450bec999d0adf46c752dd87ac0b7c505616beb4717a210d668c16962c321c7072945de75f9117c800007a59d157a99c603548b14714445120448e0c79c3c56444cfc993be0861a451084a110e4a6c6aa239602bd15800c374675750033234927a01163820d31f826a84510448350fae0c20a524e210a68eec490e809b3d441cba91869392270a02a85cd045288ae37a7e06ab739a866166e1739063d7af0c92944716ba87e04be513ff24301d86242e64f6a9a48c9da00ea804174483478f08255648891f311b29381d7404c823875901422072431b91b606b929c728296b94d840c30be604b66831f5798e25a40552cbce09c698b400eef0320380e3e03844b666bb610488f084d2a88bb28a126a59ad12942a00e3d4214fb1a48d539712ac4878fd8570814cf869367d30fc00512311db6dcd8eaf32948263d583c618204c903dd29b83d633724742093af63638066a938c249f9971e4a0a5460722649ce0fcf54143a641ab8d656207d2482a3624f1521b49854278890698830a96a09931d61461db262e0b73100a3933416489928159c3b325569305939c42546c58910302051f1953a01eb10c9d147d6088598fee4b704a8200c8b15065194804dea40a42fab78b19205e90dc72131881e8c9d8aa9883ae3060d961817295c9c1e9441d1132303923717615d4419cd3241900061ef0acd040f091e418a4ba013199147610f9ce41d20268583580a45efa713842ad9901047c666e2699486af0c9fca18907048431803bb3738283c44b6e29c51d2b1c3115d97d6183c0868808d8a4c9d6ea6d86f6cc1ac227980e848753a838aa1f5654aba61604690803004821494c210b011634ca5395d41fe0860e36a461737250045f9e2944981609e8234a560146d485d8110c34787d302626d8e7e6c48227b5292fc8d92a4aa44c10b58e957c48320250a92949d38942a135c1050a6764d8a2244093ca459a08f4a11056295e409a25cccb8b054f3c1e92c54182eaf205511d04ae808a2010991ce9ca802c26cbd2e8e0ac6ffd67938a93820e5e7221c31720797411ab0490f7b16b6e427e12b01071e692c8ef079204660ae84972a6f5b594cd946c8dc8660f8a20323101c1ec6d83c5a7b36de8c6c00d4604717569af08b09160e4ef478e06007e2439fa0d51c03b818bca985c9829a6a4bf5930b04d553c6223dd891af3d9e6899b2e50d920aac17601146f489018139c25219382e969446135c38dae4891978c4025828c70a38b3cb42f684881a31a8971c069db108ea28325bc10658cb40f7c90d13b78f464f95ae0610e07240cf84a01d5221d6dc1c90054730ceafcc2d046b490018544421c1c343b3d4e40a84352a0868d271c6cc904b104d1534e53a1ecc5d56e6a8172c84a910c0ee470526b504205d5aa91f490e300800a093a0413cb44000a47744cd8a8b3d5f677c0780591480d883441bb620c9d19585012179ba1037135e12ea38a261c3c309e054971a012497212884e151daa4074e18a9fea1c4ebc29d15ae6baeac45960f472ec5153fecc9b94b6a0447e828f386cad01c3ee4a3894800841231e0a9485d0a740a12c40bb28c9bf5d174014205b79775000d412b2cb098712cbb10fcf2153839da71148159c195a6d3a44c625c0a398a3ba38547831738202a2c1522e3a5a2d10e9c0e074171dc2881b88446765b0bd2a87652d10dd412000568c95b1aae08257a60123445801c611de05022a00bee87d7a03f75b90d0875171a0588123d2feed6b2462308f43cf8c1f662cb4534035393089cc60060f12588008332b0314b528bf1f1d542d2983eb9aa1d0d86dc21f38089c26feb511b0a79f240df4b5c44838aee923916c09c2a251d8f2d5a422d2d9da2fb52fc8a840682a1e707ce92a826426ab637745c7049701c432d2f428660046863e5891ed9891b992248c56c495259909aa5bd990386dc53040a28223d3e95e1f2e2070b3ca8b8e8606961838050950c2cd844fa91c19292a15256c1e249aec9223a458a571ea16a0386cace575892456022a5d2320185d89ff1406519b071289226365452ace9e04546a9ac0d9c534d5ce475d5d9f172006d13001c2038514b4574d50dc000cb000b1616da4c3d0863a14e6fb4459706014a5c64c802ed9180df5558289786f8209445f6486d8d5e58860b5e088899c35285d1958eb70720b8d375666ab3426444a52f3701f824ed0c8141b1ba40396240657c6b94ee24c4376018027278e889a143ca853b5bdebc703282baac00e0e7f8c5878c04209b0462ec740213cc21d730e3ea508480a20c2d75c4038488cd596cae7e4071f063d19e1f0511ac965784350d7956f494802461b197d80c5a8291a06c929363c392056cb0c810c264025c84aa093922f08e50942082ca94168fd6cdcb8a2529a57aecb88dc7297bb6740d5ab64ec839328547c5422716659011d6ba1411c494ad694a255cc42c44724ba06c93a4af0969ec18b1a3808d19206cb002513a72696b8d9296c39ffbce912b32b0285ad101ce18dd571c27922a61c97aa2f461d2230204be0618b367848a4c7155963d438acc2845ae09766b55700a50806a9e709930dbe8c87e15988c7af3cec51256b44954258b1030b68110784825c0288d003009d88854691017133801c07904e1f004a3001a7ad8045992ad91818092053ebc0f34180c30e0c4611318023a5c051e5ab13f452441506061cf91073f3e33ee5ac30d44481524ee15c80465341838b5e34accf000343a0e41f0e1160642dd8e54cd8bb3c38f8b545c36cc42421eec4d017566a746a546579f067a4cbd41122cd411f2a5d3dbd99a4d0f4e24aae2290e4226130e9224011c0d2d1cdc5d38ea3078c0894d7bbb60e999f068418b4668004909944e132eae948900f579a444b846035c1890304236f296747df1c0a386011010f9d0553433428fdd82201054fd45aa0d59d420dd1162963643f89529dd441f0a9594889d8e18f859ebf4c6d4055bd1a3f7d0892e4b100e1d9a5fa401104482170f34321c826f1e91210367c60803812889e9d3a9c81eb13a7836ca9c40c3400ad7a1ed86985e032fbc20a5e62cf002c58b2ea78051ccdc41b425418019559b890e267e9cb2b24707f828c257e03db5c6202d0421b53b3a53ae56af4c59680a4039c402cf810b31f55115045b4408b1c8dae32223a72c636649d89526630dca3c8131c35426ce0d8e133a96cc3ebe6a10f042131911235f48a11ca628d9b45ba0949ca97082d016096907a8953963226a0c4e0e4a566d4102a591fc8479315843e7ab94144c34aebc89eaf8f050464c0d199f6b76b4290e1a52374c169519911769cac868a49a34ecb164433b01802c8a34ac390546a44f1b02fe2ca0c0c4d2183590e220708a8b90a1514b1474b8846b2a12630d006e5d26c180173af83caea94c182874158cac4108fb5e29294b4b3a1971804dcf47a1520f4a000982caa309bfb080112b330005f79421220447873fc854a34ecc130526590a03a1cc1211db12360a75b6ead8b2dc4880f3608ea847ee82960d9e88addf71f8064502002e6c398fea3829a80247c3c4141b43c2e42e3954cdde03f7991a9bb2f495c2d2f5b2e59fece0818104090c0b298473a5205a2b2a035180335cb8e0203bd4424559d823bb1623429ca234080b9aa92307e890d2a5868f4415bc1448981d2cd0db8fca155cf224ef4c903aae032a990b740ec11821b6434ea6b4e58f0126563ca8a13eb0e18a971ae6c574c9cbbf0233e280504a8a9c08869a1b723a81c40d92400c6086022d59112894a5a2d409adf9f1730d285795105e6b285101d20790d1624280eed3082f3f5b3280d808d487e4b81307d05e06738c56043d8444a96115983a9242e16951cbc0ded71a1bda921886e82369866078dd49436a4b4f3b07440e3e155b8e6c45da0ba4e46e0c2f22e453ea130157c6a80844670d98f965a79085db949d502738e10cec0c644cae560f880b293f190b2089a1f566821d1e1905166b679eaecc9c4890127340cb4201181c19e1100c69223c8045486195e1a8039717bb2358e4407dc120e008dc121d6f28d9022c643e6e347572e2463eb103edb304d6c8515e8261a70396431a5a52b92825e10118254e6b6a3074199436594a7543edad0c0917083232d50840cd108a057c46a1280321e9a36f929c1790e830b025c9252d018b07495a611c0067c45251823bc08791a3230926eabe2cb1d0d1840a7212decb162955d89518be02b8f88029f3409c9c132b6ca67459d5a5dd2d3224c10018f872c497a832c1aa36b31438c6bc4d71cba0a18aecc4535896e35524cfd57561d13238ea5ed1a38b070b988d58ce2853a43b0c9e2011c1066d326932cc202089d3252b8706f0d0458979786422ca2423964a212278208caf62d6852ac5150371769556f889a2c401b1483f827c928350e07c6f44d46853b230c1c615732486894beec50144366b7147c010b1f3da61228e884537fc9c4c4ae15b341db9b6d42c51feb8a91d4a11624f0615158c2c23006129480af376c4cc9f0661746061dbf4058c71a9cde9a1c311440a0a40450990a72d2b27e6ee5492427379d0010a9f4c0bea8ca5b115c041ebc8200182a4c171c4800d405f46ac4051e3c0a501a597851e351066105c5939d85a98f2a18c23f5e02a5499087f4cd16c0523edca8f3575de28a060c6490730af082f0e331d3f51e65dd6a5236150ae3d13a450b2b4ca283f958e420c9d17c88e800915a647c510140e2e916ad8513904b645d39dae2c207640a0c0181b0c7c371e705d9a531413d6c71e667d8992c3a38751990835077a4bca24a72cf074c44d97fc0904d68297514a4f171e69bd3084f683c9f2410c4c99d2ce0ec8540979666b8ecb604359a92d3e132258325c26a15011a5828936087a14e1c9c26aa8d026ae0308313eb2bc0f084582796488a3228105a652c5a9a26628a18022a83e228137e40de11f45aa0c55989fc0a4b734b81c8962809b08ee284de94ab1065f656c6aa0c31e1f3cde52d983e0870ca1eca439e2c01e52b7204b9a2038083be580d3954b8e2231b2f3f66301994f6f5d0ae017c01cd871094d9524d150273b5c825a42bd796066cf1d80c385037c0754692366458e8b376b1ee4fc3c41c04b492755c1eb045a020f94538b0e0d406440c11a818fadac0b580605f97c919870a6d9b2a4549508213cf4f901b735c783e9a781aa30274ebcfaa0f2d0226a809eaaa2e00cd4b51cb195e4536f78f0218994331dc4420465fc8960690c21be32057058a08406419f4aa6727cc971627407418ba94c64739c78080280025b8b3e7da92161e914914952c2a4ef9805c69e9419795303571371a483f778800c912f461090a440c5b0e0c7d387c054d2e9c8e556c60214047064528001c89d3f0a3e19211b6166cb102cc23606bc68599344426e0f8c78844dfc66014869450a3d6c042d72c20527818c3c49322b6ef20f6b1b1ab88d20836039235233436951c0a90c0ce41801041b25e3529918708d1ee439150742cd027a9006e6008b1c0a26392094ce7d0d2090a8cc0c12330f783259c2565cbab28491710984235ce89cc1555053228703f6c5ad93f2c196067e0188c6961865783241b03e299190e72041061779503c8a52ecca5af066521805e5118e9938018fbd216c31973c645d11941820f49467cd0f9ab1cdd3069e14fc52c0a7451da39a56914e1bae36dcb50993e3684c9db66f52a30178b4191ae3a7539794303b56431e4c2736f597ab82020c413e485b08d419e3dc667d462d52d14182180cb38d559d8d0474682901ca09843bd5cb2b8051556df33ba5c7950c1165c2ea0419f07ae25e89302cc35a81e1cd31c38a99e2b4a253a919a96e08411e49a496e3f49262611106b51dea1eb8c5fde80105786cc96e2205a13325d4114f990b299664d911b6d009b4402a1814dc3c40321449077ee82b421f305b54bcd860d56bc65cfa19fab6ce18d2d4a06b4b06961f08c82900d31028636f471eb815c0669e3268509e258dbcc0f9e2b26559084a930865964b230ee6460fd7580f518dd8c0b8b168a261ce99233cf158044524516205619044d88bd2403564277911bf93bf4e97c006e4f9b75ea53dddb2ab8daaf17c49666b54f574eded97653f9dc296e4375dd5b6a5ed564de3f94dd34a32ebc62f4afbb9756dd5ae614af26cbf6cabc628eaebd59d5794f8a6c33e65fea6499fa21eb2ea0f0d7092fcc2734ba7ab0bc3331bbb764d7c53e40dab299b192a7f6372496716f766f60528498ed1f7ff768d59964de3f8d72930120cafa9eaae28bba628daaa6decbe705bc3ac8ac2b5da022145003e0a033a62a011a345404589862710d1a12104a0a1058613808586138084861b808304e12730500420a0e118f08f9f31601f3e5e4005f62c00ea916d38455fba9d69f7756796ade301807964b44d5197a6e37665dbb5855b3cf2afd7d955df1865d1341d2620bfab0baf73fcdaa99dc669bade91d93985dbf865fffff5ebff8ca64304e4794e6dda8d5bdb7d617b65fd9ada91bda7eb0fd7b0dac26cebe1e11a601df9fd281bb3764a7f7b4ee3b97edf000f9051f58ddd1a46eb597dd1394d492055a8b10af762f8e303a423bf711bab6f0cc7f6bbae369b1a20b7685ab3f36aab31ccaa3fade7c86bccb6f63ac7a8edaef367e161edc200ca9161f765fff72eabce6a3ddb9ff8a6ac0b601cd986fd1bafe9a75f3a85e1d755e1c870cb7e7ba5ed368ed318b655780ab00019fe701da3ab3bc3f00aa76dfabe91fdfbc6f3fa7adaff799dbd97037423fbfa9d6975f568bd7a7b9ded763d00d846aee714a66d549de75fcf2afd6b201b99ae51156ed9f77dd1cfb6e94a7cd3364e28dc025c8303a84666d9f9f5f38baa745c7f7a6e8104c436ddc26cfbcef447d3fa7bb817c31b9846b667fac7adcaaedfc3291dd76674255ab4702f8643201af9bfef57d7d7add51a6d6736fd368ab8dace009e91d3379ddd959debd5b55d3465ef7b3623d7e95bcf6eec7f4d7bf745816564b77e5d357553b55653cf7a380e908c4cfbd8a6e93665e9f6afafafdd00c7c8690cafbeb5d73465ff8aa24331b2aaaa74bbbe6eeaa2294cab339edfb46a0307906336ae5b974eebfabbb5eda66d1a46b659da55e3f97de1556d53b7351a3dadaa4e8060e4145dfddbdaab4da3ea5cab2cf14ddf24c02fb25da3ea6cbf2b8ada7ea5e799f8a6b78d2c7a595b15756d6fd72aedbfffc437ddf3ca16d8458e63bb653f5bd7f05f5f7856896f8aa66674255c571502e422d3ffade75fb7349aa62c5a7ff514708b5cc768dcfa9a46dd8fdab357e78442a1d04ded00b5c87efd7f8d3feb5df6c76fbac2648059e4f5db76fddaeb3acf76fc69144dc700b1c8705bafdf4ee774a5e71ab55da000f25bfbd94ed114a661d8b3714d7cd3373ec02b72bace71edaa280caf2babda30f14d5d2b358055e4d45d69157ee715666bd5865fb74de700039069186de3d45e6196ae69d5a53d314d3f8df4398e746bd3392015b565dd988563b56d635655df74756d155deb975dd7afd629fd02a7c8b4fbd670dda269dcaa29dbd2c4373dceb108b500a014398e5bfadbb047bfedfe755e896f3a2cd6b57fe51a0c1000d9c369bac6eecba6ef1aab2e3d4cdbd70c308a0cc7ebffad6fd3d666d7f7fd693a4c5b150f108a3cabea1bff16565196565bba1da668aa07f8444ed38fa6ac3aab36ece779b65b01804ee4d6f5718daa2e5c7b754dff8f87e9156013198e5d1446d5396659d7f6edec95399f6cc66666c666c66626824dd50099c8b1caa675fa61b4b5db5fd7f312397dd3348d5d167d7fea7ed62b91e7effad45dddd6a6ed74052671eb358eed76b6db3d201239555dd6d7ff7f3a56ebba858fc8a98f3fcab66c0dbfbe85632372eb6b775ee39a4ddf975e5b5706b088bcb671bdb23e4651b87561741ea6f9c7537a3aa1106ef179061291d139b567755dd53a66d737a6db1738449e69d4ae6b1875df977e53f613df94758142e476b669f4add9d86e5996ae7f10978ed11fa7df85dbb985896f4abba90b448ed797ad7f8bd268fbaef00aaf69db027fb436fdd2315abbed3adbb0ad07f491da710dffd8a3ac676b4fa451b8857b31e403f6a8d317fe289ad6efecb6765bb7702f8679401e724da32cccbe288dc2f18bda682a198ddbd4655fda453fec63d54525ff75a6dd1a56eb5fc7b48fdb53f247519476dfff6b777dd79826be691bff4cad331cafeffafa148de73836fe4ac9f6ec57d4bb713ac37e4557b88d405d591af628fad634fbbe69aab2ca3cf97fa4643aa6ed36a669f6b57d6ac7ea30fe7951c9a2cd8ff68afe46c92c9cd2a84bd33f8efd3b7f1ac44f94ecceeebcbe2e9aaeb4ebd2e94b7cd314c50f02b94e5d5a655f75ae53b445d154554ffc42c9e84fe39fce2e9bd26c3daf2cabf6f981925fdb665d3ab5e1f7d3be46eb4ff21bcfaa8bce6a9cda30ada2fe01778e5b14ad59746e634fb27fd9b57dd5768de17686d3b7938ca2ac5fdd96f52b6cc35ecd8b7b6cdf47f1a6b1891fa7b44655f6abb10ad32a1bcfeea6f655617aa6dfd6bbef1aa3b003323cb7714aa36f6bd770eceb56d38ada36ddfedafb9f49465f8fc671fcae36fad3d4a7985e1475d1975557967dd3974d5d157d59ffe7d6f5290ba7713c13df1459f4c7dc2e2a6b366d4046e76fdb68cda2aff72e8cc2f99fcb3fae5e92e3b44d67f7853decdaac675118cfcf92ecc6f4bbc26d3cafaaddc6ae4d7cd3b492ecba73cbb66ffb7ed5d36a8b2c1259954d29c9e8ecda30edba36fddf188edb25bf49f27f59749ddff4b553da9dd35b59b3667425cc92b7b24d284cdeca5a28c493771cff24c9ef9cce6eaadaab8aaeecfacec4378de9dedc95cc2f926cdb76edda2baab2a8dac2e8170a93fef842925dba65ddf5b557d7bdf9f2a5bade7cf992bdf37b24a3715dd3b09ddab347e9d5fb21caaa0bfc1cc92f8aba31eba2313dbfe83ab70cc8351dbbf05fe3575d558faeaa5098e3d7484659387d63f49ddf7a8669d425be699abe702f86c71f23796e55dbf5b19fd3148661ffd5157de15e0c8bbf45725bd7efcccefe5d6794465154286c5db817c3193f45f20bb7edfad6283dabaf3b7f3a91ecb6315bd7b1cb7eefff7f6144b25ac334fbbe6becfd8cceef7b48feb10dcf71ea3dccfaf7c32df14d8974ee9534ee95b9f2c687e9eae2674856d7d4abb08da6343dc3754c2f20b774dbae6eebbe68ed69ef63e29b0e8dbe38c7297e8564b7fd2e0cd3b45fe7759d5f42b20da329faa2b09fdbd9a65995f8a6433657deb89ac68364b84ddb9a855bba46d339feb620d946dff9f5739cc2b61abbee4a7c871fbf6f22adfe02cd6d4caf2b8bdaec57553fdb80d4f7755d967d63d49d7dbdfa3faffdbe685aa7a8b75db875fdc431fb616fd7b3bab634fd95c315e98bf53fa6697eeb15936d1f1fb76b1bb7e867e1d68edd9ae8b2347e7ce4747553746559fb7d5b9af631bc648f4be49a1f6d183f05e4b6a57f6db3769cc2706ac3f01e196561d66659d77de197a65d578f8cfe76a55b146d591445e735cd23a3280bd72a0ba73e7ddb7ac623a3a94f3ffad675add676cca22a9b801cd371cac6738cd6e89afe96be23cf2eedd7f58ddb79fd6ffb6104e4f7fd1e756b54fd7f46d5d98eacd66efba6afabbe29fca22a5b47ae6db7aed53456d5559d557f805c7fd4af5e6dd3d68edbb5457f74e4d555573ba6df7475ed165ee1113f03e415a65f1a55e9f9ad57dbb77e8e3cabaffd3fdc7ad8bb6d5bbf257e7264949e59b8f5a9a7d9daaee91495336333435798b199a171666c66a80a33363314ce8ccd0c4d61c66686be99b199a128cce2deccd0d4983c1687ca8f4416dd39bf38b2a77fbbbeed3aff344de33875336373d596cd0f8e5ca3ee0bb330ea57b665e9944d53571df32b404e55d5a3f4b7611b46dbffaa683c4c8ffcdec8688bd22a4ad7bf7d67dbb3ae919f1b19ae6db8f56dacd630bdd629dd464ed7d8756b15b5e9d5665b356623cf6becd62afcfa5aadd9d9bb6b641fbfb55bbbb4adaeedcad22b1dfa53a3ba6d9cc66b1bc3eefaae6d9bae6f4ab7b6cdbe6eecedd9d36acc778f100aebcf77cfb831792cb6567e04c86c8cb66dadaaf3dbfab9fd699be49746f6704ca7683dffda5d55daa368e4d7657f9dc63f7de9344d57575d972c92df19d96e63b86dd11fabdfab2fcdc26aaa0ef999916d989d5bd4765d36557f5bff32b26f5598566737a56114fd9e7597b44f51213f32f25fdf7576698fa25ea561a3d10f5fd58cae84d9d075e15e0cf97e63e4784559d67de9b4b563b48dd5017e6264566d55f5dbae4aa77e56d394f8a603b0f88591d3b5555b986e51d7c7a97f57e29bb25c7e6052d7ae5d9bad5bb5fe2a3c7ce9fcbec828cbba2b9b7eb5b5db3fc335f14deb616dbce9218cbb877e5e64f4d3b64bbfeef7e9fb69d713dfb4edf2eb22bbe9fa5fd8ad55dac7b05f57e29bba5e7e5c64ffc6eb0ac76b0cbb2eebe996f8a6eb96df967646e3d94661d466d99a6d896f9a77dfc4e137d6c521f25655b011f3220ba35184199b99199b59cef773e4cd66c66666c6666646f76626b368daa6707e5a647aa6513fb7ff753febda3fcfe76c875f1699555f96a5dfafd6de45699bc622a768ece19af6f4ea63556d6901647466eb157d51b66657d8ade72bf2f7318dc29e465db68dd1da5b91d198b63f4abba8cda2ff8ddd2a72ebdaab1bdbf67767efd3d40d407ed1d6c3708cba714b45f6f44bc3af3b7f34856bcfb253e4996d67d655d5ef59dbf6f12a4586edffaea9da7a785e5777550190e997add516b6e1776dd3d6a351dcd74e5514467f3ac768fdda4221eac2bd182a7f5050375e5b585d51b845d91765d1559d63359eebd846573a8653146f39ff36a1303fda4261ecc2bd18def83d91d5b665e3946dd70fb77fb5692732fbff9ab6ef6fbd5fdbd4db4d64bb5e55167d69f6a72c4ad32a871f13b9fe6e1dbf765dafa8773d5a2f91d73fa31f76e3356ee94fc74a643ba6d734465337f5ac7f93c8decf9e465bdb5d5fd7466124f2a7d59876bdedaa696cd3297d44b65dd7bb336ab7b41aa3703d1b91d79fbaeadbd62c5aa7f4878bc8aceb6bb6a5d7d8dbf5675b4f44ae57faf52d4afb19fdf39cc243e49fc6f13bc37e4d6314adbf1039855775a6e7d4b7ee67bd7783c82acba22a9ab2705da7ed4a0391d9d47bdad3abed6314b6df1fb25dfbcfd6ef9b7e14fea9dbfa90d91746bd5f3ffb531b4ded1eb28f5b1b4d53ffce6ababaffc743fee8bbdaedeabe350dc370fbf1569883994af66eeabe709aa2306cc729cda292630fdbb4adda2cfdce2bcbaea7648fa66b5cdb689bae2e5a7b53b21acf1e7e3dcdd63e86ddb694fcd6313dbbf09cfe765555558d407ed1d98ddb757653f47567352525bbae575b1656d5597d594fcc8b7b6e6af46baac21c25bbeefb6b9766e9afb668ddaaaa6ac71425d3ae6ac7bff5ad7761b7aedb341dc2312190e754b563ba7ed1d8bf6a8caa396e4642ce4ca8a6a88a86926d56ad63d785e15fcf2e3d839251f6b3f64cbf6a0c7f36466be36d0ffb94b99b50981773b73b47ba0985ca9f1787778e2c0a85f4d743d34ff2b7e99a4657358569b4fe694b7c53e2b046fae1f0ae53f5158144baa1ea0bf301b9fd1efd2b6abfb00bfff6fd9ee4effe184de7f58ded574d7d27199deb3465e9174dd935fd71cd494edb744dfdfcd17686e7587d37c9b64da728fcce360baff3fb5b076477f6dfaedf15a65d5aad5356933cfb35b56b96fdebfcb6eacf24c733ead6693bb3b53aaf33bc629255987e63f4b55916456b5b551b903fbca26c0d7bb87de3194ed14beafaba70daa6a89ac2e91bb7ecbb7e369efd87df588d5fd84e6de29beedd4abc21112f228b766a49865fd7d774adfaf9fd1ea6eb4a72bcd2f6fb59757ddd79f5b5a7247f97f6744c7f177ddf5665db4972edba316bd7706dd7af67ed94f8a6b19b2b6f9c6d479892e43945d3985ddb4fcfa9fb5b37921cb32b5bb72c3aabe8eceb9f429269d766edb86dd9b66e5d1b7e24a7705bbf70bddaedeadf584d1dc92ebcb61ef5749ad66c1da728f14dd9b44f992365a40a3336b31a594461c666c6662614be874c06e478b561d746e7d5557fda7abb91ccaef04bb3acaba233aba628cd4886eb54b5d3164569f46ddd3f2f92d1155d537bfedfa369bac2ab22d98d533b4dbd6dfb165de13625bee94f24d7fe6d535a7d555bb5e3d89d11c9f1aaae6babbab08daede5e5b2214f390aca669fd5dfbbbdf9e53df7e43b2add21f9ebd3aafbf66dd0f2f20a32cbaae74dc7ed4b369bdb685e4d94e67efb6f3cca6ebb7d994906ca728eadf3a5edf7786e37590ecd6706aab3ff6a867e7174597c912744ba3170a85c2f72f8d5eaf55deb98fdf26a620f9a7b13ac769fa6b1576dd19790ff76e251e6c4657c24c84199b19ddb7dbf37271fa06926d9585693b8659374de759fd80e41586d53a6ddd0fb331ebe3d48ccdac7633a37b33130a85693a4c69bc78645ddc5d5339e61fb98de79fc2ae9bbab15ba3df8fec631a6d57bfb6b3dac2bfaefbc8f55abfe887d7948ed9da4d633e725ccfee5ad3ab8bd22ccdaaa902726dc7b45bbb30eae9fadb34bd474e5bb5566156b5d399f6b13aeb91e31486517b8569fba3f3eb7d1ed94ee31766dbda7d6bafa6738c477ed1daa7ae1da72c9ab6734b2397abbac44c4086fdf7e99ac2691da7ab6bd3cb3bb2faebb89ed7977657344d631501d99e59b88ed537a5e1d76651637299bf76e415a55df88dd5f6fdab4fe93a726ddb31cdbafffd9fb5d903e4b445dbd97ee1ba8d6b16855d3af2fbd2aa9bbebf55d7f7cfdf13dfb41d621a20bbb0aa7eb5f6ff5d51fa8d5be2fbce9163f4af28edb6f14f571faf33f14dfb7e9edaf7f3d6a44fd1c39423c7f33ccfafbb7a56b5d33aaee3c82bdbce5e6d633865514fb3351cb9757d1dc7f44ab3760d7b142e404661355d61dbaed5da7687b827ba69fd3f3e7c5333ba1242e1afdbf78dfc57bfbeaf0babedfc63d44d896f6afc6a2aa2c69f8b7fadb6702f86b0e946feb13dc32fdad2b05f5b7aae896f5ae3e36d647b5d51d8a6e33a4d7ffddb97f8a6497f1cd6c8ffca261bd9bfe84f6d9a75d538b659b425be29f236def4708dbcfa79addb955de7189dd59825be69cb66aa61d5747d5db44d537685613665dd9886d9344de3f9b5d935a5e94f7cd361deffc9b7681220bba9ffaafa67dfc6aefbaa7f55edcc34b2f7a9fdc2acea559a8edb14c643de4678858946fef4eb553a66df389d6dda5dcfc8f5bcba6b1dbbefbbba6c1a7be29b0e55b5ce3423bff3bcbe36cbbef53ac7b167cbc82ceab2b3edd3759d595a6d3df14df15ce993ac6bb3294c3232ebd6ea3aaf71fdc6b0fa6b9bf8a6467f2cd2bf1e23bfed3ab3b6adceb377d5b7fdc43755519862649785dfd445d515555f584561e29bdaf71f2aef01e4f9ad574fc3b38763d86df9fefa668691e3d4c7eedab2f19f5f766d67e29b0e919ec6c1c82becbe74ede9fa85bf1dbf34f14d871f57fa649aa6ea09f38b1cab703bafebfad26a0ccfff13dfb4c5953e4e5d33bdc8f1fcb66ecbceb37767db7d6de29b0ee1d48cae845cbe3c9a919033837b31348d985d64b8855fdb8563b8866178ae57e29ba2e9af55d5e422cf343bcfefecd539865b3aaeb7c8aa1a7bdb7b4fb375bcce68ac45867dadcef5ea55f4a3bffd6d16199e698ffa7a7e6d369dd3af12df94882f93c33ce3728ecde84a2855d41fb9a7027e53d784c0c4227fb89d57954d69d5b775ebb2c437b543e1a63a3105906dfa7f9fd6b58f53afceae4b7c533ce4d04d3f5e2ddbfebfb199d999b199a1306333cb97298442e5cf53faa3fde57e7dc3098542e16d349a4053f5d737926dd3b4857b31fc5931afc8b5ed7feb637855539a5567f6ad625a915bff53f6db1e9dfffba6ca1c1fe645bca8179bd195c88b78d1ae36fe2289e15028fc42619b50f86ba170d8c8ac227ff6c72b8afe744e5fbba567e29bc66b0072bcc6715aab6f1ca76ecd7e368da3985464dafeeb9cbaac8fd1948ddff88939456edbb48e5dbf7effd268abdac437550e87ab8abb299fec73df26144a915b1a9e511645ed9af6e90c7ba2195d09a110cfbb6f229a0220b72bccb6b41db3349aba33fa95b7521945765195aee1d9aff69cae768be6c8af27b3b012138afc7d5cfb9745dff57f9856e3f82d623e91ebb84d7dead3954dd13a4ef6e5f16d2385c2154e623a91d1387ee9d4b7ee3cb734ead2c437ed9b87aa6a23eb84c21a4605309bc86dfa53bfd6f3daa2693c7f96f8a6356c9c3d0cf762b86732916df7a7f4675dd57b1fa7314a7c53a150287ce349e612ef5597fe6d1cafb64da7e9fc954bfc36d243583dde4a9b557ea3d1b31d6f2509a130577e3de44d0b855f79d36daac75422bf6cccceac6fd1d4b56dd87be29ba242a1195b6a574ceeddc921cdbe41cc24b2fde9788e59366dd119b56b94f8a6a8badad51f0fcfe7c5a437de775241151389dcd26c0bab6b3cfb5fcfb11b13dfb44d8542612e140a8542a1599c9c9959dc9b99199b599f50684657c2accf2e2abf9d19dd9b99505827140a856c66eaba34a37b333321142a7fed3f5128a48b42d74e79db4323fdeba150981cc6ec9ac2bd186a79328fb4b01ad374fcbf3bfbd8a3c4375516d3f475611a715d947eeb8fbaf55acf291d13dff4c633fa211eb2882c1e87f8d055efcc2232fcb2f17feb36b5551fcf704c44b6ddf7f5766bc7e9acb6ac7787c8b00baf293cc3e9ecae2bdab2c4371db6a9195d09b3b93936331666746f66357229142a3f2e14c2702f86260f53884c7b16a6eb154555f88dd73526bea92bc50c12fbd49d593b86bfadae2aeb896f4af76636441687c95b59afad324fde2610d865d5ffa62ebca6ebbba22af14dcdea7769762c1271a19ed9fc2ecd3e8dbc51f6d348154812aed2fcc1a22c1bcfe81ac36afa57787984f3650a248916c693f7fa9537cdc2bd18c6993e64b7a5d336b65ff845ebfa7b96f8a6f9d15ecde84a98c942e1af85c25f2b3f8ed3a52cdc8b2109b3079baa28bbc6eafbbe2b9ac62a9a0a8f7a46a350b6611875bdafdfd9ab6a4cabc4377559983ce4b64655dba6d3dadbb00bab9ff8a6776e4657c2cc68f442a1f2b68542a1d00c559766c6e4b16846f7663674e3611aa7702f8666003b641885e7f4cfb61bc36afcbea80e996dbf9fd99a9edf95b557fbcd21fbf97b3fbf769ca2f4bbda2e0ed9665d0fbb9fb5d7b48d591a25be693dc44316f1e59aca6e891b324adbb5eab6a84ffdb7e9d5b621a7b04dc7b61ac36bddd27f9d6fe470d827c3718bd2e857edd7f52e8cda7c725cb3eaafd3368dd7b8b5fd9e6cb3693bcf6bdad22a1ac7ebd793dbffc66deadab63bdba9edd24b594d69377dbfbac674ec5918ce657a76551a866d0f7f169ed71797d195fd6d8daeffa5db3a8e95b28f5ff87b755ded577d5596ad21db29fae3d86d571585515b45896f8afcc621fdf58671da0efbf2a2d227611249d9b65d14b667d6bb69ea55dbbe65ba5e67d6db2eaac6b00b7f1b297f745deb949e6bf46dd9f6db4799fe6b3ac7b3cdd2f51aa7df36caa8ff6fdda2686bd3715d7b3b4ff668cbb6a89dbab49fd318b669c82bfce99af5b5abce6eedae765166e3188eed98ada8442e4ac6537114e4308a840c21ce4c4502005000e312403038281c8ec6c211d1903e6b3014000365aa6e8838170944812c87711404410cc3401001041043080106198f6cae04e77e4d80811c7d1fe40f7cc85ff6c3f37782dc0047833a10746645300de89382d487f9cb7ca4dc11c66d5529cc7ae340f2a5a12c6f2ad7ba45fd533110985591b8d18e8901b21d0d193d6eba46cd82c91a6d6aa245dc6b655bcae59e419ccc6d50602061af2f81bfb98fdcde2cdbab6b526899a39a5fe69516540e8def993f178482799cc71cec79deb7218fd60217d409440a16a555bd93ae9bd101fdc59fa2b70bf7a8e8edee04a317a3fb793bb247dd75bba3cd5f34c718f510686c8cd07c913056f476257307c2e866471ec37a4857f4b63f20a68a91eb10f30c8bde8e2feee80545317d4d3d8f1db97d742770151a972f511bea4576c5c804da9c93ab0ea3436dab8f2a42d49e74a451e04e9667c5456f072393de525e5e515df456b4201d26e4e8ca8bdeae38fb61f03b694e8716b930cd333ea2c801f9b778b42def75fe9b8de2fef8a643848c93d667ed9259b7a6b0d3de41a078692f6474b07263e44bea1576deb8ac62d49d9eeccaed6c11ecdee9e1be1b6200a5a722fb9798fe39ea75bdfa6fbb20bb16f68e8393d4828107efbbbaf4899368a22486f65991cffc8389618f6f0e4bad0b46895b19301314108ec7d59aff24001eab1bf80dc7121e43fe4365db026bd04e198fc576776a00ffed60af29eda7972bb02ff114e41d3c81219a83412f0e084dc3d119f00fd71736281b0fe393b8e89b7b5f41bf9332eed765a358c99387f8181ef7f5e0b25c92563a9f143f30385add0004ff4d226c168ef8e5fec8666fe6e330a47931ba227f1f863a8fd273caefd4eadab8d03bcc8cf3bc4f52981737621e9a07853f7ab6f01addbfa840e96fa2660af8f44921bcb8cea30023ca19a9308870abbb0462d3fa32efbcc54c14f5ab4a78f75d4a3fc2a64d4d5f27d0c71024f726557538e9fd339541c9c8cdac83dac1baf5676022f10ddf86eb514094942d20df63eb74b3f6ea209d970ad278c37a8258f19929c1131f55ea920df13aec87b57a543f1b8cefa5374441b5b082e45e26d7d31ff68efaecd9e7285552e01ca27f3008d702098dbcb03264abdf0cc23b289d0004ba9c1d02d628564e4218673525b5bd47107c3862e3ad3a815feb067b53f585f3aecfd843e629e19234051c450123da2122cbdf2039b0d36e87c5fd8538994465324ea84e28bcab96f140add54522b82b8c14172ce191d0895c5484981efe6f71298f75ba2634c88a5207ca22603c1ffbc34719ef2de1ead2477892773506fec083bd6c355cfcf25eb308075c235acc3a7ab1a0652459c03071d82e36c68be7bbe9bfa496b3725cc07cc26c0e7ba1f76d4cd14a046626fcb1f87f8bddc8fe2c94e80b1ebc8e57ab5caf6b2aac77f688e3edad8811bf2a81336a69b3a4edeacb21831e923ed035029879933df0d7ff8546ef40dec44f4fc6bc8e61705ccf91b12a9f65df69db4df9d6a3995b635452dc18f3119755bc74c12b011a724dc0b16155c5de714399959773473c7818ec730e991c800af0375f6b03861431e31bf1af1b1f3bfb4ba72369f4beb1a59bc2779aa13910d1c5cba09ae2205e685c2cfad7ea3bda14c14f60f7ded465e6f0cfbe5e2eb2f5cb094c62d55efe802751b4f7c8b0d359051498a4e091dea776e46fbf5c35d20da22bea0a6ccb4ee2d3dd1f7646975fec60d71957009ecb06ea4d4b504468024e2b9cb2bfac935de803b9c83f7dba59ff72b05c29184d71b86e08880dd4a04051287b66257931109b218c640f6a69f0d05009d46a261833a2a573c486f383d0912c3879e3c675c09dc8dbe11b102d3c4d2a17baae5b76f7817f749bb48c445b61971cecb21a065ab9debb7117c66f3248c533eac480c0f05f77b90de4b5ea9a6913b060a10f1071f46223ccb2567a453e79456c13deccdbbeef7079ca41f6d3440280bb2b73f1e813453236b584c068a656a127dd467400e2aa542ae2a0c0841351b3c77354d4552cb92b9a5a34c29bafd6b6e56af98f64044d18b57cce482f2eae55a589573b9730894ccc98d3af10d14c0610b4eecb21ceae77c48561c9218b523073bbec061dfd56ee448c065ced9f97a2ad53431b612e320965fe00511dbcdb51b6ca256cc91207d347467810cc2a9e447c42c4f41f80794194ced4d2ef92c3d9d58308c8268dc42d696fe091642a26574a54ed390495dbc46bf71d2be3b2b761743c5bf1d965c76ae6134bf5fef932bca600c24612919e020b450d4053860d8f0b37e9a235503786f43f64ac621ec483cec9722b638687699adf91cf75c201c6b62e78e66bcaf375f5424f6439d8ced43e220233797cd74e15bb3942834dfc62345f7a162f69856b938779c27064e48c1a93c916a8d1866e668345464cec00a16168841b51e49a57d5621b9a2ef47c6b35e750ef0462bea938e725e9271a7c980c8edf2f7180b4be2dd4a4c533405f8af226b63f08480e4effe818258cc2a87fd71fb9508e2914bd82a7ccb4839502668f302ddced92bee47ff65fc4cab327dd1d78ca0cac143037c032bbd4fc0d2e57258177ec93ffc89faf7eec0579d5f733f712f024d6659fe98e4c4100330806d8daedfba56fab0344b9ce344c4261e6cec911ad2729bfe6d4e28d2ad3ba8c2bf974184fa58ca1aa03152f41ab2c3e00bb24848bd5a949852e32a5c04a251fa7166e7a813bbffc9e6b210ab0f0345805d719502bbfc62bac014b81089cb6912bba6aa67e9f2e4d017754041de527ed94a9bf4196f0cd457c24c537fdc2cbeb00ed2af2109626e0ba95897df7b9c80e94e06b666df6a0922af82aaa49ee8af65cd673004dcb7db0f6479988a3b280988e7205a69b988797f45e1d076fe38c8ab64c39495eb211e1981d257a0d6a0a48a23891c649602927e8d0e26820adc5d3402a5b08bbeeb5b60939ade00b202a108d645fd354398f629d273636d8b146f514dd6cc2a7f9241330a3081289bec6a00741460a2cc1c69f0008ad6f1d6b3637e246d2445c2b2bb801ad21c732bc1d124ec549330197d6d4a9352a4332ce30053957b03643706d1638597d2c43602b361ef4f33627a235d547675b63907c5991a0f1c15ed886b4a69206c47be3f6ce5c2d2e0aaeef815219965aaf7bdd34e317d1542323fe2d93dba2b03b61d10b42a017e0158d1850ce8a40608c402f64a88a024ef70bfd11c1b278ff17158bf59356eb5e542c8e0697bd012bd3481562a30ce527b946908b0a42b78e00bd43e0482f30cc742ef02ff31fcc7cf6e3dca8fb01d77672fcd00f3b4b3a039f504f3aaa81b71115268f90983b09275c45f54251e8d1b172d8e5f157c0640d498f4f3e16b3d5e430650c24e41ff440864ed58c182afd59b0d1b736e8fe754f28881390067595981df2c08a1f02a1043aa615eda24c05f3132b67ff118b9145fb118ac0b963f1407dd0796d59cd5a157a59955a7c0dd393a58d47b1e37d353928a99cdd80d2dd197beb9c6b6377714a159e7853e28a59263c2c946c293e6c101c5ff5ded3ed149eab75c1145be8235de4fdeabb554a2d7bd1b3d21f556f2b5aa26edaa704746647d45e1f146e1f68126776e0e8a92f8171bbc2808b08605040533182f8eedddf3435c6e5070dbb24778dfcc80d3cc04eb982548340961c5a52981cd585e3542841fb13adda66a228284d45b996e329704aa269d44e08bce6435814bba7329c1f256ccbf5a8d3701247f4ca2e587ca1f2f677a14aba35515e5f3843b85b73d1d384a8a7ec1856f8c7bca1cb81e23610af12651e5c69bc3725ca3bb8d678af94287bf0d78da551badc8372b5e174c54a4b27bca4c4f563a93d5f21e4d5036869503d25c41db4ca06ab5525a87ecb19834d4bb0193663c271a301c686a109dcd7c56a8241e8593a200053edb8fdfdca02173fd1cc020cd76bf3dd5efb8bb0f616d1e8de2cf4feec1b5055c05d2c1b17fd013f43e87d1150f9f2df938cd4fc28d0a923c416c632e05154460200088324ecd5a44ed3aae40b5020edb0d681360682d15792758536276f27c6115428ce23d2c5f6e858231ec96608b549898bf23d0429615ca23e490049a50749ecc580286ba91e348e6130de8198231043ad02f9a0b322e7326a1cc2e14261bc5ed7e8157ad191e4ee38cad815ccbe16caeb3e53ab6c32dd5aae039841036dddb5f8b03ac44b09e88ada6f3b6bcea1c309b9235e1ed7a5c44403a67712e43031468a01bd6e50bd33d0bbe9564dcfb0218a505068b2f20e36bf8a7bfbb88c8500de14807b0300bd26a0dc9000e69e0682313031e34cad0233345bed64b97aae10dfec53aa5782839c74712c99540d40afeca464250e5e7378cfb430272bb65a0dab4378bc7310c9f68aa179c772a133449cac61e72f7ec13c2b6f4eabbdb0b061ede78fdb938b533f1f069f045c2d4fdb2bc65bd0edbcb3ae4ec60d32afb41cc92e93496e2d8d3c841beae78a4bd557066e9991f157f46d3b7140376ee23fe32672bbb272985b2e4eaef2e24a11cb6d1684acf5a823408e98c670e6c141634ea91de815c8f53c0a60ea06a568a13495cb693bf48a57441396c2c2d3d544d9ec9cd58cae74e5e1c482e9805692f48a8b1a7b109ded25ec703588f81abf14c85eb58c46af5c405cdcd427c4fc143760664379b4c985c38b23e884ba85506a35bd217ffd4f774a56a29e5876356d0da86866bb379462e264410172f2126ad518277aeba34e2c5dc6d148184b120fb3f6b4ed6cced9b3b7abb9dcfbc322765039629192eec990e10056ad5d8596c9f28c62971479f0962ed00ef1d1f20ec2d56a8d1d4a3740817be1f2a2f8b438553cb50f5e28ade5e8a14db26b01f55474ecae4d6a14feb7a24c2acabc7565e81d50b95ffa9fe8531be4a4f911ef713397e5f0e6ffcbd51f1983bb5af13e5c679d58148cb19909dda076c462008bd3b85aae1d00be57138fe6745d469af577e9955e40b408e7b66a5326f88005cfd01b65d1966fb845f814f7f176cfdcd0965e16c3ee970ac1c77a0704cd4c1b0bb2ca8baf505574440969b34fb5f043ca346c29b8f47076a7a8b5cc11308a2f90d44d4f012d6457bdda0c87244b894e0c01fda53d4b9537ac898c24b3b9dc07185072c7b4434bb92fccfb0bca122ad413aa473022c741b10ab5d03c4293471730ad56495673ae17fe625d6ed3da000f598e7e823b1d8bf42b05c632ae256e702045b74ac1c7591fa6425851092844b951ff89e52dfc93f5c34fa7aa4c32aa014faa5b7a3176d2b43212ad93404509a918160b07af25ac6502ee608b38f7e7859bf8b26680e49957717089370322343420ef2cc9ec9a73f45abb101dd7e9313f6020c0d7e6d2c9515d797bc5753bc8838736c24145362b3c17d8335300630862e2e19029a18320031ff911c63e2efc58ae5aa94c081a4e7498681fccd833c8c1f11b2763afcefcb5ddc88d66b66cc4ba8da0926138ff51b92a5ad1c477c10c62bcbc74267b49e8b91cf765b18e7bc43aa903079a11628b0824c05ea5f4b25621adf888045eada5fa002ef107913e0f3c2952c7ea54be3d38645dca5cd970e863456ba91bfa031dff7295cf1a7bd368b867c46a2126a31fc84e5f4066578b35a7da462436e121289b914a9c6e25f4ad7c720ed521f9c979a6758f350280946bbb14b9a9d0986064e6b6b41f312df142c8519af87fa7a415b1efd54d7851511d659e11e535af7f2fc1c18f131dbb4a9ac45a5fdd51f8e2fa8eb5c61c0b8345222b7504e45a1b1956ee789e622fc4a121025163134ccb9501e0d45b443156c63d721e0821a20eca2a5eca0cf759bdeed0d66e01e48a388a6d1623da962969b59f6d456a2dbf9959b04b4c206d108dfe4ce0bce671508aa5f7261afc0ea8ac35ac87180dfd51caf581c60c5c0f470498b8533d7e30aea32c175f1048d08cedac230c04fed9f8d9d066dd5899749fb529d8c61877e34174d13536c96145e300f380457326c3b30f507ca6ea8a7ae12b2d5b9cbf8aa36d522d63ead258b4be370fa6ead2edace8f55161cb609e9a44e9696166ac0895816c5a641f71f87e48521a197b0cab46ab483b4bfe2d0eca82f1a2c81b1001fd8908b4ed9ffcc26a351133253683b2c338961ad8167394ed5b156973999e8e873c713cb4fa4d17c64929c85e2d7926aa5d2427964100b5d43051eda62796a22296249b136a90112d492602bb684e5c8340b4543211ec4273420d12d132c924b08bcc89358889162493825d3427ac41205a924c0676c99ca8069128960562b8749898b0f095822752ad326292c422508a86886b158849251641293444a8552226935802a5c810b156313141622928454384b50ac4248965a0940c11d52a12134b2c00ca52501c0347e465dc0b395d8f97aa7a4456cd9038855c2af05a335465452a11b3bdfafab0653e694a2a21079e5035063669d7afd8a46d25fc2e3c7d7dbe8d2bc1b3497576d17ba84dda612c34d7d926ed4c0b1597caf53669d7feb849d38d0270f4ac1b63c8ebf35a25ae2716f2bd49fbcca019f29bb4f9504cc2483baa615b2a5c464926a0e93a98fd381451e9842538c6ba7c018529ad3869174ee3a45527f83a899d8e8f93ea042427d5850d0adf3e73e334386937952e27ad702547dc01fa8706afe29cb41bb8e7a45df93b71d23ef02fad22e17417272a807556449332b041d5d8801736c670af0a098b047574d5649920907ad2b3c833a346436ae8f8a6d3a2823d0abb694e9fcc6910ce603da00cd87211c72c5bf68a7afa9f3c7d7dd35231b5cc23b5cacc946fe34f4ba05f25e003eaabb8e3e9d29ef14e9c8c95fa1461dbe8eb739c7e8ea42fd313a329b871eb1742d9ff2f9bfc892bbfa6d5a8ec47940bc0f7438d75bec4ab1ad2baf3e224f15bfc4963cf502b7151516bb3fd4deffbe10a956c15b2b16de6ea42c3b613e466e6a80d70e3d8a053b1ba3d59d6b5eda70a97100e52154c9301304d834165496007be8f7a70e9bc07ecd8a5d6d8c477cb14dfab58c00de63b98484819e88602b986c2fad9e1ba62212bc129990396265bff35d2f492b04ba647fa7c0918c8ab26001544da2ae7a3b0fe7f508074b77001cda582f7e35a6f54adeef62e8c0aae63598e45a8b0644153adae11f4b644a8ec46869cb05aabc2764b51e0498124b5394652d915a5b58d8d3a60375581da6bf89aed73059b3faf09a9426e808d9538a0ebd6aa55986e298a7d29101237c44829bba1b636b15087ed252b507a85a8566541a95ca85113f6836cacc4019d3655adc2ea4ad12eca035138a1454cd90ab5b51583ba6ea85b82d12a43b92a054ae58a8a9a5527b12ef1b6940c374f6e0baa6de36cc7c216e7dabead9daf5aa8d416ce3826e993260bdcbf228a94b11dcac6463cd0f186ba55485a25a8b7ca80d039228e90b71bc8ca463494cb96ba45c81ae568974a8190b9428992b719d8c25e2c90d396b255303ae528974b805339428a92b62b10a78da570454d20663f8239ef355e334c58440d2723d94e7ef6021186528f369b91f86bcc3febe8bd8b9e249f7c6cf95c518ef14a6dac3d171fec752f569095148706025b1a3596041077fa33f90d290263dc9dda44fb0ab5a8a016b28e75c2e40382f8f7417408afea8b9f8596b84923b3c327957e5fc3dd3aad48056ce2b2b4297b1a358352eb30de177c1d6743d8803cdeb5809054100849f841056d13321c6ef881604b2c1d0ff9ccebb70038cf2c0e9f43556962fd7db64cd9219b0edce61db78d625bd3d707f48747ed7f7fe596192be904b399fea6028f81882bd79bf507515832181f91ff5c4ac6561c8ea33daf6730ae3302f4879834801cd9ffb385c820c24b04e2abcd43d12e40e47ae96b9fcb86a056852d5536ea3fa45423f22590a4d67524fe0f22f1ecd6e18634e5bfd97b9c3f7331a31979e0d8d96ff164951c704ce3793ab0afe97c9a16fbf6563a04d5a14b875afb9d4371a9b18cc028e50644ba2ec7ec9fa459831fa52f5718b81774d159cb072de9d4a0655baa4433464f5bdc136a6e47934326eb9ad97c0fd59a096ad5d140874c88ea7af607bdd87dbca01d90694becc4da9fde2e3b6660ad8b895599f630055927758cf537b4ba3217396a3fd94f1e1808897b43b906b239967863a2cb390576d3e56cd92a9c5f530f03ff2909f67f72a2fcd7143d455961eb15a4c5e7afd1186cbfe88ed0c90f224d0522af0a19dfa71061fb1524ed0d8992fe7fcac4fe5f9e9c4b14486894d03285f4e91429a5b2885461af551a8b95c66ac51eb9725eafe0044b82150beb358b14d1b2a66a61902dd552b734542ebe972e0757bd209480493e350c453a46f4426687942159cb941133d5d58c9f9cf941cf60099af0150d35248d1ca2665cd5f02d6bba754d2f858d8bb2b94cdab0b54d2471c345dde8296fa6eb1be602a77385d34be258d73857450eadcac9fce9915fe988963a44b48e6cb1b35bed702d772ae99dc282c752c57359f2e04cf324a67ae8ca1ec1ba6756e143553e85913e2db58f9be2e781fa41973f99f50f19024855016d2a810869a0ea22a84f05f951067de9204242285b09312185546ba1e916437c72a8503d544310b929a26f920892264a218a585591b2b2685d17d11346657494517def50353403c0bc9433696ae0a954dfb84a3e5f63ca3bfbb42f81fb8c14deb197de0e532a7905a19dae48b78eff0e3a807f333ff928520e9c9d465a90bab10f33d211d11e3d0178245fc9f4741e14858c9e58dba0b74ce5874faf08eb6d6fefa44602c65b441b5cede74cb3e86430f3edb5f0e41c55d0bdf49a3797ad1a4c191407f1e18362f7fedfc8dbb7cd50d2aa8f136ef40be0d4e9583d5ba8e8cb4879d9cdde86ffa3ae3bfdaace15b721ed4afc168be9513bff3a43409f480ba2cbf9ea13eee905d84a0d6c7cb5d5d15372c1e9ed134b1425231f799e6daabc4ccac21ab1b5685608d3c249ed63193116c435896f62de0e2ee730f7bd3f4761320f0534382c9edccb390ea1f85536dece8144d116081ca8cd7e9a8c15bb26b8dc2216c77f83576a51b306d333f335ad609147b00a3453506206f2df65b91dcde919e16f35bb1e6eb19abdb11e84fb1fcc902c7849a19f0c629121001c9b6e8c31bf094a92af868d5fc172b2580fdacce96151776d199293724b9bf0f7c6e5c9b20a03b16d58521c7373e633240c24676eb6ae61cde57cb1bc0e342c0f2e9efa0099c76fb015912a872faaead311ec2f146e149fc9b9b25744f5da0f816d43585d72b0ed589fbc6ea9418d5d72826c278a51d73a9202df751faeecdb32fe933d822a7b75c3bfdf7cae26b41cc6b6961dc49fc98b763f6502988164b2ec20baec8223c264ccc42ee1021e40e531213bcf73f9c6fa96ae78d0e39efd7e65b74b8107ed42466ae1998dc2841d51af5d6c6df21675ce4397a42e92401a22120048141473125f8c47468bca9e0042d89f4f16e7e967e4f789948cf94171ba0558b184606f46a9fd5ac33d4f4353288153cc41de7d422033a99cf13b3c7c53d41d5414d42eafb1784939dfc411d13697641deb082e85ad456562d0b65b38ad38d7b8c829769caa30360520b24957d0f2e8db339262069dede6b4b59b7cd39cd5bbb9d88a60e02cd3a1f9688682e2d3813dfe2e528e5fff196e0239dc0c9b2e5d52aa75a9480d52c414b174d1091addc5f19dcb5aeef0fd255d2e12554adf24d0aad32f59225c1d2d1f923c5bb0e4c3aa70a495836f2ccbb650055854868792432e75bdda7c65bb8e8ec99ce3bdf5fe3f32fd5e6f75f7d8f067b14633fa9d2431cfa1a661973774dc013317ceead01824e6c759b8589a08cdc6fba0aa52203a07f9baabef270e4517eb728949b63d4ff5c5dd9cf851ec553a1ebb29f161bd3324e4f5b4b3d52985fc8362340f4af2d962481c87d142528cd6a2c11c198c8ebf5806bba3df2e4b536b77d05c1925adba4a00dc6468820b278860183488105007220ae78d8f790e9111cfcd0412b3148751f3d76d562cd43dc3639120982792c117d9aad19612492dadb32b4d0f4484ae4e8a4f6aba78a6a1ae41ed2bd1eb28df0eca57d8f9a8631b4cfa4ea0fc92911d2d9a5e8aca992a26a321e38354c503a14a7e9cf01a7f016ada3fb1f069b3cbf0ec935878c8272098180242303b4b0fda253b1e84ca4ec48d495da34fc3d067e9828ea5bbc42a4c73f9da75a22c872584150829844f6ff24f4cf4f1483bfdca0e240d8ebe934fe610e9e4c01626c22fcea12204e43b49a6e933fb291d1aeee43d9723b88517730cfd1524a7a318d79ecd2d45c78163834b08527163a57a332b21310c9f55ae1a7e945d8d4ea73f0e7a056efc86ad6847676d516062e7178116ad02e6ab8020cc5091cb9389ac910e17df882363c5da6245fdf21734fff00d2f3f3a94fa4262aeb607ed46701de141c0b903434b0d88f2095d27b6b8b2b0288ae6883f0b40cade38a90f5b382c6d6dd61198a2e498eb354c6fbddcbad1548137ad88765e3ce2e5b891614f6e04c204f0aa26be503416261c688c33c70ff4c54190314f3c60ab6c185f488afcfbe9e567d192783ac1d1ddd4736f6389bc2e164b4a5713ff01359d6878c6f46168a0658bdde89ede74ea4d75d532ab7e4cfeb8529df1b5fe495a186aee10c643f8283646f222a00365fa94a0daf2cda69fecf517f29e9af5943b6d019b6bdc4df96ec123f37bdd34e29e2e1f99d340c88072d4b5348a379cd55abf674f62ef099cbc2cd5be2f46c349fcc38f5cf4bc24f8ec38843c0192d9514def90f9734b5e22b4507186e1083b21208ed42d141455cd03ee424a887a1cd3da2ac1feee94fed322bf3cb490c62ecf09f0ae361ea70d063f2d8b304160d2a37ce9415f2c4ff71f3f58f83f608ccd4f6046de5a76d929e3bf93df393ea388f9d36916e5f19a0714d910d3c968dea18ef78786ef2721550728fa307cd69dfde4efb6e20a03728c288303fc8eea84153f94d9c4f7ab836e83931bade5e2fd21f06bb10fe2003716286bffe59fbfdac74bfd8a496a39b260f84fdbaafdf71d0ffacc19e912b5de95a28f1b666a105eb9d5ec40e011fa34710899c8fc3f1fe03efda1461f671b61d165a6e7095ab60ef667b7f3a27109a41eac8bb817c0409c52b914dc917b00710fb8bdd9cc7ea8c5a99e9e1e8d1e46fccb717018454b0119c0eb72895ccd75c5adf833b6b9223efadf5d7486a5c1d19ff6ee7151f0826d16fa10a221ade0d44ff66c77fc1a325a1a309e5db733d80c4bcb7606dc6b42ba8980d0bb40882a912b13c94016fc38c0da030ce351d6752bed4c3d220fe5cd9bcdffd1bcfa668ae6d2135f15fef3ffe065e8a7b897e2c0fbc1bdc5e79debb4228be30716e73a467d1b287b4c81673284b5611808b6b38352224ef74e069f8f7846f6b147c98ff1c6ad0ef6ad754ad012ec6fd51ed735ea1e104c9a6f7cd8911801c716f946a0ba2b81a44bb425fb5dd4a3a3f7fe2f0ec8587fcce06fefeca15b78ae1c21a6225896fdc7f514ef76fc71bece7ad40d3a696243865186b2cd39969ba247028ef512e71bc5991b23c2add8e7d5493a01858c311dac9b7ce1ec47efcf63e4cce111de30738bd9e17736a1bef361df1152475210969354448d88d1155905d4ba4484b5c4d9c806630eb4ddbbfaafd09a6d21acc8f0d69a8efe6ba83bbaf7c4cba0dd736b32a93bf13e9f059eb2951e0ff4bf09f4c3f86e77bccd728ca2c060bf2e3b11da074338960e8d7d7d0024e3c71cc1583777893d7ec546b9072162698d1f2de9a698b0682a97e5b2b2bdeea63bf7e405841fb8b93c4fa388337bc08b2725369bc1799c61c98844716f77a51a7c12fa1c908ede8954f3f919972f81464fbe5af54e87cdc6dacdd2f0d2be0eab956d9c7036a79ffcc970da7036837dc04cb3c5f31ef48aa71ee5b157dee885273ce3798f7bdd53bc81f6f664f0894fab789a236d5b1d73b61416da2a66caed4267abc7ce963750b7c878d8b2547d4bb0188aa51ac62f7acbb7dc463bb7d1ea56b6a6c5b66abd652d6ca31d6d6975eb5bdf425bb7d2f216b6d1ce36b5bab5d6b416e465e8211f72180879ec8f64bccde4bf10050e8fe2b24738965d90d2e4c4d5719edadb57e2e2cb8ba1e8fff84b7c345d7a3428dbce3e80719dcb4d398f9837124cb60156c72139e4d3c43e060b5d06cd3ff69e5e30dee69fcd23793075d27b8ebabb3abe16b4bcedb80d8d233437f5abb4cb86b13b04c625fd80a56959285749e0fe66641ba69b54443f8f124a75bf5b0d43d23eb47a91a8b1e7344045866c9fbe48867a0cf71c77d7fe0d56fe36e41880d5dfbd915aac34056608d3b76de4103ffdf9b997e605d7b27abbcfe1f745d344311dbd701fbdfda05676dbf93c0fe5d44e01da858ef409329660ea0c649fc01c3893397166034ed6df61de6626d731682b78fb1cf080f0b674ce3b182e479a3ff4bf08827e0d41ea38dad4e38bc80f21db41cba133140ef3c6d62f9c04ab0d5e3eeeac74ea48afb03b993af442ebaf9d1d539ac8a3c03881e1d51424b99866b0f392811db731a2b0a361819b43b13b678020ffc445696ac141a28ad740c781a7f8e616ef06e448115c81dc23d5ebe498d07e0f0f2c12886ce237e93c2bacf892272eba3d0d3434525602e8ff4a11ae042840ce952937885967c76a363840adddacb93521cb1761475e0ea27f691c9968e1147aacad0f878dfcc9914e542c5a2a6110267b0906017d7686f3c493eb0979dbe66a588ba9b0dca809f5c4fd50cc6e5b40cf4b5240056235aa9c84fe030421696dfd82c0f702fbe2248308b489b8043974606d39334d6cfd9fca9d9c0bf9e497f9c9bb24694bb1cd345e292d5063d30ea9692452f29edec32ed9f5bc1548d044365f7d5fbd19b12eed23d8fb1b94b34b6ad3e09523a0c518a7c790c55172af2138373f6c22fc1c695bd791676e44010ab91b14cc87a2a27e68ba812ca82e7c102ca45c7b859089a8ec8ed84a37ae88d025d40012433331c533e8afdcb86e9993efe5b6d2cfe28071d99b2f1e8c352925493c835e3908707b210cefcf760dfc28b1a0a39d5ec77e5a0e6c31be62c88fc296a0460aac05729c9cf2a5d7e5a7e299e14d3d58edb872bfc039a6c4a28cb89a6750e70746eb8127e60dc9d387a421beb4849ba58a098f7d451174179b786a5defd29978705324368dbc81e7a8a7729b0be8f492490a2920e141e337603effd18ee2636ad7370a8e42742d892c8c80f0809e30b60d1d98ac222fb807f9828f8e531a2b0632f8e6675b40c162bc743a83d621506610ee0053a82c645fa68c33881136b908f1cc82c61616ca375e13bba40ddc30e6291224d24496ef775a341b669b0b674a55029be828341d0670facb68b9984356a0c5fc7653095c225abb201fe2e48804209cb12cac8ef9e6ad7c4b5b99ae9be2a7dd47015850c156f81186b1576642a3f593c19d777c37c24049daadcd95ececc3df9915a7a7e84b86a386e568afb0f81cca7eee1a222ecebf73b640ffbdcc83e3b7e236904f93bef1c40f4742b0af6340906f6f4bbe12ceff05a473a4fe3dc1e945aad64411b2c6ca48a0cbca024760e9134eb04a5038baa2b9c44dc8078e5d2d2be1362a5f2fd4f31fac997c40a537348842e366a65091d364b0a00311906078a0872b50d5ed89ab37438811d1b238a603dd085fef79522af9c1082c6688fde3e21e7c1334387b02d5de9fca2539ff7ed6e0079b1120b360cd760444707fc2a20f53f009b04f1aa5558439de519f5c20fea5345708397c3d2201bfd3ec9b2d8e43f9af679675de6c37aa1289abf9451132525c698d97d8e1bd6d3fdab6ba8c6da526b50f1d005f5f4761d8b02782a5b1667c6b470db7cfe1547fe63eaab30fcabdeefcc76b8334421c2c785811398160a1561f0c9dce0ffeca023dd1c008bf72f4030181027d8f114691e7873e65fdc074ff8d0167cc3811051e75388ffd464cee81ebbef9f8e88dd5427d8accd1cce9c9ef5ac9b193a00d92ad1124da16ee30271ac3e7118a5da220edb95d70e51053d1f480cf4ee38f5ccdbce0c1e07e99722f48407e0a76eb671bb423c9163316cbc2ebc4c6702a5c63721a446263bf904cd5fbebb1e683f026e06cb198ac3c2cd1cca5f988ac1b1e725d188fe738b830d4231ab5202d5dec724afc48bbcb1732dbbf425fbf03e968e85199085dc99e6a4727528cea924c13fe5d6bbbf17acbd519aca91f879f9e7590808f003e90bf302fa06904749e3a2f1428fd5fa94eb32bb7e6aacf05683396f769470d9beb31d7bda913a8d8f24c8893ca0407dbb0c0dd0a84bb3bd2fb3cf500b0771d8b5d7ea8192110e6c1a17e70e4ce1a2222c74b34ab71a266bfa35971476ccb4111937639a3617b89697e107f9a554b6ef7beeeb8ff72fda871c9a54e2ade207f936909f411915cc6451920b854dd47c0bcb33509a4b2160d99a6d6e04a6d7f4ea00d4e249a68d6251a33b6fda1358e3e439e51e30f91cec3003fbf025e7b741a0229fe9938c2ce7d0a87fe3bd1592b6bc082db8c9b6f205b7108bf02f38290310e031418adb8f0054048ec5c180b7c49cb8f95bf61ac8700deb80a01bb5aa428e8cd7928488e11f787ce5ac7e631c5a2a78c1593c31c1973b3c742a3234c602dbc2b3b41623d236664848a589027788ce015c06b6fef22ce0f6e7a9782b37f2d7d0c523990d1550408f3143065d92f166070f24dc6422f570e59ad0fca122d8e49db50b42cc67d5a6e56a46562d8538aa654e34062a97152c2a35d63871846e5324c06a1c94f4877a850a0b19329cf95e6fd796c6e9896c2b0866120fe0e152ff4e8db3ee4e36b5c32555d978a595c91b370acd4234d326c38bbc141ecddc5499f51027fa4aea417d620f848df04569ebbcdfa841e93db7d1ef7fb1ebc8a1edcade78757fa55012638c014ccba0b6776fac4a9f4611b63f9e6efe3ed74ab65ccc37137a8a8bdf110befdd71783a26ec8366075b9bdde6b646193f27ac893f2b127bece9dd760186458c2b846fe40e68c884676fc0144572669d195e01e7cdd580c4daa36c087939b66da6e4e592a13fa49809a228259e92f0903618c92ae0b96f8f9475fe8a29d5363de33cbf802d044016278a7161d85c80253e400e1f162d78261df1f3111cc20a0fdd31b68d50bb990b7bbb33f0e200e73b83162a0e85d57f862ea720e5c9a355a16d6162976ba7e1a1a997a2f74025fb2a9d42417d4cacfd2d06a2bea7b349debd69622d885ede98f979cec5e27d744ff7d3f34c362f547bd898dcf645dc1215034b446ea7a2585915d4b110836b3e6e0a9dbc23938e3c0a3a0b0351ee02db3c2da74a57b518fb7557c4f29851f74a84dac0be3d51e916d10d4da460301749c6d89cd120f7ed9f3a04ffa4a839bc6a78dc7692b45b9707698a94572aa7582422ec1aa88fa63fb23d6aa8d590652dd8565954ca1d3cc4119922f876fd3f5507f04a81146563a7cb6bb1df7d2e85ccb7f19017ac71626b85986327e602192bf23c88e653d6a99f10d71e865d96a4c69966ebe9e6f2154214067865286a526bcc9186661d0ec02bf4a345c7db655a942d11e3696e4ad4f9bb0a943abe5c9effba2735303b096b0bceed0054bb174aac0754314d968f5a0ec4d1b9e3e6485d7d32850deac12a108ebe54b4a395417f3c33cb093795e69c74998b5b5403c8af03b90c1ee9bff53a3efcb13587c4b3d469f9e43e98260c9a31142c3eca90182f498dfcf19681212e1874e8c7dd94f304cd5703d415cec4ee0afe38b7ecf04533550f792eb16228ea936f2b1b78b76bf7980c4407c69f8a96c9b5272fc7839653b97600bf26e33269d80a0232de87896d01815ef40541c895064e8ff221029c88224b874ab03da6e74a1c5bc0c20b0c2816734803145ee6ce277b8de5a6df8797ba3ca44bc38b4bd10b6aa982836bd062ed2279bd34338d6b287e837c91c0f4a13b87c8a7ad5dbd162beb62ed54e9a935b0ccebb1a0334d802b0b1686e07d049b34d9f86b1bcda3af24fc18d4a9e97e7ecdba0ba1b206911c740b6e9085c2cebad0f1a6d3a70d613c667b96c8a2d127a61b7d0abece9e28b5a955bca7257bd446170256db7f2d79c7d2bc4af5bbff88b1bfbe47d715a87d9b95817364e9383c294956f2addca44d55a1a692dea7c5165f64527aa55cbfa20df797ba2308c96ef278ff5c71e9ca6b8f3807b5b66c8d05d3c91ece6ba44119d7ca9055ce9bcf9c7e5677a79c1645b550e1ffde7e5f5773beb5f9a6ee1f84c0852a1b22e8468f82dda2a2bbbcc32adc3732c0d7bc9ab798e05265680cc94bcbc3e3ab44ebf0209632211b671bc573d543f5fcc47b7612b31e830674858dd46c986a3d14b65e10deb71d1f85cd1e2daba4a4b8d9975be1db4788531eac58f20d9d595589ddfc566770142412f7496283c109b6fbd2e6a1636a8dd63772f0c0d9ef4aeb59b13b2443aa823e2b993a8fbf70bf3ed9d997c11643af9399a53bf6c78fccacca6694cd77cea6cbd3f98ade9cbaf6ff6c76a29d73fcd4bea0b7b13e27e478ad31774b04f7ba5ca922608ff73f0b3f42afe9bc56e549861aff406f9958cbbe6100b1e35e91f1a0aa4e6e43baba2edaaab82d714e05211a73424efb7f9f50c1dbc1d39637a511365d67ba4e682be7f1b9413b7c5c4a609d930a95f396d066545019376ddcfb35d2bbbfce865e60658cf5798c41c28d3a27bd7aec3ef506f6cdeb26f635dfa0e64d4f36fd59713c55694ad6bd37b49cd6f11228ed3b3426fc12e47bf388c712f990c34d18b3b1833bf5e3e1ecae4fd81e082a5c9f0fd767bbf31fca3952ced4edee0cc14fd232493d3004999b3872b0afc837aa0073fa2da9eca57e523d61843b55efbc07a6fda3614c73a08ac10c32fb9c0d0bf18d41f986e6775cb7d287282417902d50f65b48021d70e561c7e2894def3774f1e6dba73ad1a7be8c47e661d2e3875c94e457e6b6401740080cf0d894a1ba515f07c60d5b4fb25ba1c59aac55e33a4937172b91ae0c8ac7d99004b3daaff098b1cc97d8f8c3759a94a2cbbfeb5ca2b9bd9fd764383a882ad87d75c1150003477fdce79fdf5d00f140b12c55de60cf9acaed23ea58ad4bb1c5af3d4cf19e3c216d1aa176f7f50a5c1477afa82c08b5ea54c8530f78cbd3d487c6882230c482fc38ecb07624aa036ba5ba0d03474646dfceb4d03b280711548a60b54a73b24a151b7018be841b478409bbd728bc77b1186ebf2641c12669383f13553133d4326a3f700e911a8a582b47f65e2ad7c93e7ed23171cf1af8f805f56b3b88c66ed1accd0a1c84343b0fcd54e1ca9205f2748d9336093683d7adf3dc4877320c09e9db604f64a3df684d22d68a9d1ef36d4d2086972d39cb8ce97f88e3fd82bce03277545d18d3c91696d76e6f5f151ba740bf4f58afc375b0cdf12cd3a4ca71d771a392c09e01d31492cf43ba648ae56e18f02124ad9d301f1d6b6692f9388ab564c0bd913914ad044b80f3cece413921581ec5be89699e0ab56d2c1b1ac1f7dbc9cd6860739fb605d4fa535b6cd2680094ae72fdf7e7a5636b9426009ddb0c3a09717a257f9ca49e481fa075d2f8469a86a1bd33df4336fbe10a256689d2cf0b91db73ea8ea0db06e4c37eff09f559846183a5224c0f1ae800d100e51b03b15f76a9aadf1e9117209784c8037e24f29a2f12f1fc605df6d861e319c3470fb4c40436aaed428f682bc962a023f4e3fe6f516aa8f13bb8a10778f19aaa1092b87acdde7bec77581656db2dbe60d51c9cd1a8b4121306af0a7991bb2cfbc3cf4bba74edfe935a73fb3216dfba5103156f530174bdc48a83f448cb1834237f141f54cb52f40a800fa6de481d72780e92dc46deea408be02e4015f9fab245d1c7005d681b1f918493a8b02ce542a1f6b664f7542578c158948a6904155ebd3692304ddaca005129fb327c2a26071bcb9096642671062175d6b2dbeed119c23b0b638d515b9b2054dc404dd3d7d95048aaafb2ba8094d3f6c1e36b9a613359ee6b6d35ec052d2fa5a4698c4d13d9f04b6c0d906cc88c690f66c79108a98989ca781a4be5c700779c893f7274acedca3c20cdacd0c80155d9adc7c5c956addae7e05711f8c37754bcf888568786f7a52dc9bf6238e903f9086f0e84390990641c55afeaf57679acd3f9436692c5126b4d7adb548d01c13accdf7f0477e8d1b5552b6be38209c9943b805c6c3d58db70b8920e47563a684f93f37c9d09b5e268a2ae538a9fba472c024b8986aa102d8a209dad70d17daaafb0e672051b276114b441107abf2c0d693eaefdd63f183ebf9e084dfaeefec891ee0fbe172be1c2ec047ac2b7cc2a4bed2f9468c2bde7c096587f957addabc314206db04c5a12e6641f6c16ffb82b5a58cba57693353cf64299f40dbde9d2d7f38857b84c273975f0937a883e9fb60f4c4f389ef008b506af0b0fc2d304e244a975c6d5fc03d62d149ac12c92f899417c2e64d12e21793e51d74e6e455c6d5ed66e0605621ec7c4fc7dd74b4dc47023c78abc4216a1759cadd9005e9e739b9827b37e942ecde5bc95f8ff57cdaa819b09e7ff21c47e0368b5954c33e11642a2d7382795b93f80e55e386509890fe8769056f5489ffcaa6fc888ea5fdc6450a2d1db1dc75818101d123adf5caee99728c87c88d409a248f94e2ec541300aff7794bf49cdddeb18a481b4eed252b9576836cdf35d001eda8e77cf61b8cc3200e261bd8ed5e189748126a0c5fa59c5ff5e6ffc22d23515a18382ed6cfb6a4de8afdae7e9d28a5e0f1863c9e1f99cdedbdc212819f00d5cab6f6fbad087b1a7ee6cad5f71beba79d3103077770931e3c946d25a75d170e2a0880167bc6fc26d013dcf5c40fd13ad7c9065cbaf38a6333aa2be3d25f24307d01d10b02c6d1815556765644a483d1c8bf5b46ea6f70ea65c4546aeb162f978fb00f343cc4a61be57b4429cb254f0ea3c21b4a62d922c016244711deaed83845c8ed25ed69b64fa555cad09237f5757c786ec960f620ce3e37a8c7b9546f8ac3d3da26f9d487e8acee48ccd268874b186e4c2d05a687adecdae1cdd20e680825ffd6ca291fb1091a8718f2a2f5ae541c02627979aa646fd0f70a6c563587623cd3d5f55cc03756911de1f27fac26dc61ba7842fbc50c3509819cdb735d85f61f69b02350b89c4a39a846e3fb3a1880bd6365fede07809bce1205e60bcaf707543b1c71e2b40c159cc63894942ec44b481ccf07195b469939c86ed5b4d927ab7e479de7575cf30134e5dfdcd7f0d405adae4d0c90cb0f060fb2932cf05bebf0cd7a28b9b2911dec346c951d03f837fba520f87b8af38d30075e432c8498e79917af3243a96935a775704ae4c3055f89716cbb8d913066127590b5c674c3f8197c2d0457aee02c6302a03c50e734b1682a7186c4f170db293e4665e03a89b17c13d86cdc2b79f3da083282ea1e008339a784ab93c231ee8fb2644023a4f002d3d77f46284ccd9a015630e172e249ab4daa0a89bf6ee5b20c572f0f252039b1cc7834e5cb852295d4818d266749a424ad520ed490027e85d408c5a110f7b0a2eef17f74ab25c284eab9d4cb2a2537061dff55e5ae0fb17867646bf42b20f9cb0405f6306ee745881f4a83d558b68ac4fc2743f551877168693666e23600b21a6aa40dae111116ade4f74509bce47886bd3057dd23889a0e2fdb5183be9e2c9cf78409e5e166b790c743d742d529f266b384647ae924f3bbb21159c7152174fe07c4771b35ae4ac65e7b305440c0ef1fbc5383dfbf29ec4bab7bdebe001c57b119314aedcca2f7a32d3e71ff22cc4cd9771fda989354d5a9512f38d4576370975d09285a32c440febd1341d40a6cda51911766044c99823654712cf87c53fc6b320d36a74a2e9c1baf8234a6b6b6f56552497e94887636beddc855fc375617cb1b9a7d1470be5e6c02ce44f91994ed72c88b7e3f3f0f046eb32f5ca960b9681ba9b29808b374aec5aba3694b0b037e6a7d750b583bfa05783d714c329b85f27e1248aaa72518770ce1f8d1bedbf0196f894a2ee51b79e9abc20f743201165e7f4f01f37c41745f41f2db4bc706054fdf75733c05abbf6fd1316399ee76cecc3c39e17d26f2412b1f2e97f7deb847db5771bf36590c4c2d298a9ef60c8a44ad986b19c1e119a0b6641ff166c68a59ded4b8c7504be8500d9b45f0cc8257cc2d28794900c3cefbfa19f1b2e718ccdbf31efee3405ffd3052dfb7e8ffc4f726c9834df51211cc2ee21b75dd60ad15d6118247e928b7b61c9895992768fa6ac5ed8e43fb7588c1178b93d1e6d83ceadc40aa6a1af4028c3fbda70725c022d7f701a20108a36f7f2bf46402e07a93aefbad0896ec7a6023c3af3fddc1c0732a5ba95076a8d2a5e19fabf62bbe58fc2e5c2e2eb029e6b8441b82fa7c417f4418ada475af13dd60d8f73f16ae51d67808421f768360a3a5f3d480ef3d35cfc2c126607a6305d002c13c3229555b44cea885e08e93d0e57491f54d9073ca705f6d18378a0fee1608e5a84e908ee0fc4e70720f6c63038c348c181760410693174068e91e77a28369ad98eb185d15170a2ee18ddaad8aea14931625e79b5a0d44b57649224e030fd4f52c3c501bef8343242894712ad343300a6205593c8b3ed02084d9599535f8d967a72e0e11723b9c799f34aa2b2f29c6d0c218189763c67f03d5660f283d92c100b4401d2170365eecd3246c223bced650274a37c3f890f6a1081d4fd09a48fd311758ac35d7b15ce1e75f1d2c50676fa34b6535e0c014a8630bb34d518d45684b1540f60d7a48c3c0cab56a2cb0a0365c87459f780cf7d2fa5b18e4368181d6688881ffd7da0838ce760807e351a405ea177bd62f16d8413db17656cdb11c19fdadf140a75f9175d9d0451990b9a0964d5db7594877f3cbd61d2a63c908b5403b78bbca2918d4860b3ceed76b28ce90dbd038e9da66f5bc3aae57c8ea3beeab0560a4d7f9f5b30cfde6d599d9b6252d5118aac668f36258c034025b107863996dfd15b2528ea5a12072b40456f6f11dac6f68020a607fe3f253c95121be2b17a302d78201317cd17fdd80dd2b5372af870de3aa86dbe6030cbd265d6253a54537a6813ab206ea596790495cd18da085a9d3ff4a082a9fdb7edec9a71006d80a690f2286f47c3612062c12ca0f3896c723c35fc1e6281d7f52ceeb5e2876a0a596b456addc9421251ad0279449d143d3b0343207ae60888ad1c83001adc08e3487c3768e60bf740c3c207de456ade621e3ac5d79886863207d88d41b9d3ea509bf4064bac0f8cfe96cb4fbd85a838f537bc2286b5bc0148411ca1516e87513e52c39d0d6a87e6506add5df8fdcacabc94f5c009ff4a2b7af4510fe1562642e0b8346c5208277404a6108744d6646320e22def0b8490229da1b1cc579579276d9defd7de89468d56fcf0368c06297e9d1dc12705c73300358e728992e9526d2f326997b4c920cb598eaac3f02a778afc4f58680803dc1bbfff9a8f023063e60de1af393146e11a53cc2d5c123004e116137fcf0101173efc03c6b05e0d5f5d82e1bcbf7006bf9a9a1950087b324d124e5804eb3b944919a89b891da7617fdf1d0036554b599dbf410d1ecf4315606a802a0b34050d32dea543ba12a5d322f638d1090047f03c5814fd95ebd6d7717eb0e0be04079660d4d5a398a0c602b85a7f8749f2ed684757d82c8ffd07d487ed38902a8dbd3c3d416633892bfb97a2ecfd11b031ef06fe5f22d46906823a05786ffd432f010a012f5006ca7b8fef95b5c21f9d54206c0af687b267dd24cfc851f1e3ab843e3f398bac24051adbd337999c760eddf06fc5f779460925ca5df1e4f9914f38d2cf64ce269a7b5f36cf5c4516f8baa07bb1eb5e91109464eee4516a4ab6cdcbcd08de55dff247a8d14feb11606fe5608fe2c6153e0bda747a32005bff3a3004cc9d39b670b0acdc6440d8bcc44d0ce02b8ef2bc0edd45aee99382434d51e658963b80cd00626c6feb566b255c960ff74733ec9e3c9b3c8c6bb31630687b916d134542ea0e19b2f0f97ac896e65d8a2504d144643c73fd0d1c9b399aa601f42cc4ebb26a00197d363a722066848c52b74e767771af28279491380bcb7874c502db0d5bdabcd58e671e33146e9a265501debe10e033bed2bcd035017bd0a12dd61f8b5037a2528ff611bb6778b9c6e52c2136595c590cf6da47cd9657bc34afaa97db343e1348ff58e387f53a042e20e66540d764badb5716b8a2d0e2a9860afc4adf83e213f5c4016da19e0c4e1692b88b76965b988acfaa5abc7a15ece64bb23529c54515f2f64a31be00176e6e7d4b0bb015742f2065b1ebd0ce2f273a320d22ce2e0571a619100c9f56b1f791f57e52c54793d42f7eb7ab5006bac792eeb5a669626b4a8dde122e57646371777d712ae1cce6b0037b202e0e261cfffbac412b044460f401b960ecc4fed8947d971c7e4e601836f595f0cbdca7e40fe944891a584c3b29096b016f641280cf1d12cd9e6d23bccedb1cfa2bb8b0b1f8579043d96e5c43821d8d0e0913921dfcfe2e31b1df65859a2dfc39e0ff5a1b17c43fa0f7c7a758dd6162eb2bdcd15b0605a573505f15ea3d86ec79f03e6ce1ec57850d464719e6aafe9663dd4b88cc75c79fe9a02d92c2bbdaeff571c22cc86c74f5bc27289bb5aca93721b6c3afb02cecaa836371601c33666b2efd8b04062d9a71dae8168e68603b223f88ae218243294b3197927cfdf6b2e721071bce1506a6dd647367eff7a10a3f046262df0dbf8c8c6968406735fcdacb4b43a520144d2700d7df3ebde10c704664d26a70a55e1029e4a85d00d3540b026c3013c0c3c0c3c0c3c0c5c751e8d1a7db2e224414a29a5a2df0cb4e7324a29a594524a089ff8dfeff73b8e5ae7fc595b9b61e10dfa0db20d62808058198609347231796ff4aa4bb4831a155c4cdc4ee1c24573b80edf62927e51fe39cfde4a4511b61e3e7e1467010d5ba85fd7a6f46b648911dd40a31693dec7d46993efdd7d1161db511019243d4000020202726802a8020d5a4cda54d197931419a99a085ba3922ff941825d018d594ccc97534725694907dd89b08d948484f485a1020fe8781f2a28a4218bc42e44ab756c354cbfb425d088c52495d44f5e5f0cb3dbc262b2c864d2ae2eaf98ec3dd697315b909d6b2fd070c5a4f9b1be58b11ff53e1b684edd021aad98dc779be799e2d4aa67564cce74196ae2d28adc7488d95982c62a26a70a39bf1762348cd40472a0a18ac9977f2da64be6fee37f200c31c2f040186284d10131c2e08018dd041aa998a444c978dafc74a98b172a26bddc2599694c895ad129268fca86cb645af4d4668ac91de377a523c372be420a41032b5779d3332a448a494a65bcbed83d72b33b8a49316f4c49f8ea7ad05010344431c942f4e5df5428267fc6cd94b4d6998a15504c4a2989ae14b35ba770178e018310015482c6272675aa60dd223f2c8893272626cb70496c5062cce44e4cfc4faf529a4f6c7b754e4c2ed98e99be7278aa4c082a29630323256494e1430c1090ee316010c2031a9b98a4b4fff552e34951cbc70404e47d204d18c8a1918989a72a747f7edcecc95a00020202124203139798dca5b473d219a3c88f2c31596676ce2dd6eec67025265965f7109b726d1d8246831e3a6ce04a8312067233a03189c9a952feaf98feb772878624266657780aa13f07696624265d79a7d7f20bb723484cf6302b1b3f27fd79d32326693769b6ee1d634691232698d4d0acd1a7648e9f464c0c192f7758ae0b1f7e464cb0d89a73ccc1ca2def8b98943e8f873fef5c8db32226e71cf3aadfeeab3a9b8889d61d83c5dacab89e44c424d1a9c4c79c36b3987588895fb23ead7e47c310134f8405bb1425934a9e2068146262beca9553fc8ffbbe126282ac9494deab2c3d4a3988095f567bf137d8b886829898d3abe51272b37e6cb140231013ef366dbe8d97d4aa31a00188c939a7c2a578baa41affc3c40e42894bf5624956657e9858fab36e26911e3be5fb30c9afa25a099d829acee1c324e1419fb0ca231675dec34437f9bd4b49cf35b534f43039f4a73af579ea4e4579989832e6dedec77bd1c1c31d26a795d968ba62c16bb337d0b0837217ad73ecb8c13e11b6bb22d0a8c36131c868335f1068d0c1408ac61c2668ad8e416bc5f5d2f618300829a1218749b2c9c2c89261e4e558848d64840c341a714864cfa90b4db33b0a19396a75773ea0018789e222eeb631ada90d85d8f581c61b2658675c1a95413dfac70d93425aca2addb6b374db3029a6da4b0b9b9a7236d93041e8cdb1e4d3beb90727202099041a6b98d82533b37bef359b7d76a0a186c967ae791a642a1841184a42230d93323e8d698785a6ca4781061a265f255d51b5ceea65d138c304215b4c4d57d031af98a170afb12fd14cad3a1b71a6d4c96c3e5662743b060c424868946172baf9ebb5a0e2dfeb4e8609ea4ec959ecf3bc9b02020202d263c020040734c690031a622883461876d000c3e41c9a1fffa53fdd3d5f9864d7994574f0af4f96f2a0e18544a30b13e49546b92ad1d6cf120434b83039560e953a27ab1b3f6d61e2cdf5a88e59f8d6240d2da0c473da5c29c534751626a99ff59f1af7ae74c2c2a4f4a2296806933f9bbfc2a4cbdbdf9dba39d7ee5698a8d1379e4a96aec2e4d1dfcdac544a630e53a1b49311d5dd6c1b770a13bc2da6e8a8d8be47a5808a62b59effe45e10088841383073048d284c4edaa163cb29d3174b284cdcfe521637d66cad4f981c2bed7c4e973e6a874e98782652de936a8abf8c44074f8230c4280389200c31c2f0814448fe03aea0d184c9235a7f99d2690d3262c2844dfa64f6c5f286679630e145c6b3518da3f9311a4a981c54ca9c419d88ccd968246172aad71473f2fce3c6d040c2e4a4316851b3179f3399000c348e30316ed43f59da4b5ad68d30c1db2ae7d54be249661a459818948e87d433f5ae9408136f5449d5a46ea1f33f8409d27f33c758d13b8f2c8449a373ae59b6752e59348230c983300d0f9a6e4bcc54a00184895d6ea16407f9a5a3e51713b46cb8126b71637772862f267bb4eb549b5e4d8bc66098d18bc9a15436b1cfaedd55f3629206a1975963b3e4c744d8cab2306317c54e77cbd8f46139ab0b6e8318ffbed964f25c204bbabce7899323272e0ef1d0f5ca75ef4fb936d3d9dcfc4dc6db9591f13cb08c19b79868ae95dd64790ed39c76c40c5b4c3abfb79cfc5ff34d4e34c48c5a4cbad6e4a1d6ee77c773ce42ec2c0f336831f1947cabe49ea3893b8b097ad942c611ca42288b2c267859a6e89a7ec54d8ec544fb8e9f9ef7fb2b2f2c26df879ae7b691165a55bf62825e4a71199d514c75574cce2a7df5a4bbb3c56ac5c4cbbe7e9bfea33c848c1593b359c6759d4c8b414782305430823040400e31631513d784886cf114e4594515933f669f713f99544c0a3284b436619b93deba08335031d1c4849af55c7afa924e3139c7cba262b83ced9937c5c49017a33da8687d9b9762d2e9109aba9f3332a498f01b63ca9f53ae908b4731419eca4a2df2fee2b5a2986c39ab534e79e3ad77a198142be43ee5ebfb188162c279cea92e65f060b27d62828e1a93bae9b00ebd27269d8753dd3542bbaed59d98a055b3f62859bf22837e5c8f199c9868232cb75f7d8e952a9b98b89d5378fd1c3326796b625250bade5cc764b4d2332313136dd3c8cf2996b54146844d7b8cec10030404f518d961181393b77469ea53a6513665c625269adeb5b80a193c6c3dc312935ddf66eecc77640c89b0cda8c424d35db313f57d2f22a36307c9e9814a7480d8d60cc20176600625268dcea1edca365f681506332631a9e53a6452930b267f494cb2b4d4fdb17229c62e12135fe4c7d4696aa262161293f3a5b66b7cd89fdbbd30e31193c487f56728fd95bde28889d9fe35c724328755bb11136654deeeccff7e93996004613062724eb2a3d5eeb75785125e0956508230c408a30364fcd100da5174d0a0c78f0e8080e88c454cb4b04fcbb94222bc821e2538ebf123a4c7081a0f1d5e83198a981caa82a6ed1c2db596444cfa146c4fc90e2262f2c58b5f624a9fcce71944460a40400e31d162d48fd5d2a482c544d8748044ce43ca781f3e1e64862126dcc7f1d9f3709b3ba910935cd7630a329b3cb3122126c6fb55939b46ff47348889b295ad6ae79db27c0431713f6d9397efdec6261093b3c7a8416a0ef7b117404c0e0f16cce2a56ca3e47f9894cf65838ee3a6d2cb7e98f041a7bdef189ae2e53e4c8a1ae44b887d69062d1f26a70b573168103aedb37b987caa796fbbde355ed5c3a430cd4aca64f230498bdc87d3b942c69d789834aeb71653aec368f10e13eeb734578a1c592fda61522965a136dd43d5f87598685ebef6e9dd63262d0361061d26095ddf50717e3b4cfc31630e93643c699b2cfbad9545844d0e9384908b8d9f17b623e1384cd88bc9939d8f97103a3dd08e101f0306213f980187497396c32a09cd196df4864996d77226bdcd8a39e386492362438ef586186969c3a4203d778cb9ea92669c0d9366c66c64e9b398cfd730514f657f90391f2ab46a98f01e52c4e765ecbd9b8609a23456d67d3f1d648a8649a3e4fa3ea96b3113ea1967989841ce5f105a4353986698fc2642e78cf18eddc1324c3eabb64d1973f8fc906162a510232e75b45bca44d8caf051d20391f124b80ccc18431647b673ecc39ca533c430c1e4c83caf753f52c61e3a5a49ca8c304cf8a066dd325ffdb80d860942c8ec269d437e6bfa0b932a6c26d774756ec2f2c2c4516feac4ebc9fc761726a76dc6e54d7a93d09c0b93825992e964d2ff55da8c2d4cf66c6951338818ab2c1c66686152fa70315a327d39a7b76146162677921b2d29119e325bb030a9468fc5edd11bc5d531ccb8c2a4a42c636dd02654a9a408db977c7fc973e0ec665861b25c8a5a5a45e768aa7915265690617378326d3acc549894791a4fdf4aca299d30c408430523086324f5c02dcc98c224dbd34153735516a5224618933054308230426c86142608d58abf39c551766f14265690f2222753e7389d085b57610614266599509ded251ff624c2867c9071a685194f989c92eefdbfae94d35cce0e339c3071574ea7a77c71542867346182f88e391f5e5452a7313dcc60c2c4f55152e39fd4e0f14340cc58c2e4912f7b4a2977513f95303999eeec746de2bab9244c34d5de763aa76c1973f447186314fc11860ac228fa837d300309785da6be5abc9ce78ca595a8b13c5f1fc4bc1b08438c3034108609461046ee13661c61b2450dcf1fba4cc6934548fe036188b16c986184c941db3f6e8618b78b75000561288f19459814a672cec164e88cf30969f38148b00233883041f59cdc6c6a39655f4809a24109f2c08c21941942987499936cff505eda99118492ec20a7839062af081b83a0113380f08b89a32fc32fb5083399b730005f4cd2a647c9142f29a9a20e921e23cdab89778b01f462726592695feb27674b5e4ceaeb7062c673fad729c2e66503d8c5241d47ebdc3b65d4e5ba98a0920e7a97bf4da971b530805c4c3e8febd87c423b5e0717134353a9fa48594b1ee54b27f5b5ff17b40d8501d8626212ea3b87d0a2da3607ed4007492d267db2ce5729b773a5fb0b03a0c5c4d0a562cefe460f7a76c100663141994eef778f7d623b2dc100643149960ca6d34e25c2d63418402c26cd064d5f4153f0d660192367773000584c2e9d3934cba9150b721136927cc5e49493b66f557413a2523118802b26670eaf9fe2df843ed2e3ae1513be62b6facd3acf3e8bb091b062d25f5fbacd07cd503a3dde9ced18c02a262615378a755e69acac060350c54455cdc13fb788bf6b253d100e50489e2e25b48bc52dd6312f9eb2e966627a36e7d47136981a161363aca791b3255abbc221e6af98a4824c9a8330e53972bb62f2969818359fa7e43667a31513935613f24ac8a4339a6830b2a391157c388f11cd1d47df9174156a5d988cd7a5a7c1c80e54056a9b6916ba26aee9a9e5f1afee238f8c8006341819011923638080d0606447a66272c5f7acd325b7e65134021ba898f461545252c46d92293e525265a79814cd74348e4a62e456820d534c50ab15e743e5e87773889561a314933ea5a084ae50212284a498e81d5407d99a49dabea368d575e3e5446b66743cf3ca6abd7d9aaa38896262c89d0c32a6fe4abd7aa19864327aeb6792b53a0f28267e8e574751f9b6967e6272586b17ddb451d47a38061b9e98a8c9b299dbee8ae9533b31c173f2e4196f7f33a87062a228b93f99cd9f146c6c62b2c836f5f0a0cd2ac8c1604313137f4e4fac7583e65c666272aa9f7de75920214eb081898997c334dd7509997de303f92526a7ffd812a3f4cb3d5b4b4c5cad9227b795a27eaac4c4730b4a3e5b6e8312934da94ca773644ad9b39368cd36674aa3b1b327892badeae6f55b5eebad45785e511fcdfc6e292fd888c4a4586e9bb26853e5a56303129336f8d57b4ee972336ae31193638efdeb9c62ba6c77c4e4cca829983e1d5a4d3d748484ec0834b081128cc0036b42d61a31a9f2e39c7dd02d6d7a57c1062326a750af6019c39756915bc1c62226865fbde88648ca7813808034c1862278d7efaaad5313b7cb41fdb4621561a3811d0f1b89381b88b071880932bb745493a7de2463884949474ba6f8762126780c9d31da290931e1469c38355ff6db978d41b819a223e75af6b59bb1b2ae5fa162cc10521b829818cac3764e5644cf2810134f7f5d3e7c65396f01313964435444c7f6d3fa0f13dc722a55c26cd5edb4e1878951f635f4ff4ee9bd7d98d49a9487117363bda70d3e4cd04e3eeea929e6a42718d8d8432b23b69eb19d9a76af9e237e2ca87899ea7e1b7a98641f26c2649ef330d9479b28ed156b117294061b7898a8eb9d4daf2ac8cd66e30e93afaf479508ffddca4418052e031b769874fea6cec6d3e468490d36ea3041b78db50695af946c9a0e136efc82acbfff168bcf61725f66edda8c954f59351684c1861c2688bcaffa933e9faee37198d41fbf1baf979f628a2a1c26b867a9b47a59df3f3a7a6cbc61629261e27a964f4c8c6744a404914007191ad05638d870c3c4bbb652ad8ce1fe82011b6d981ccbf2be9b55c9186210109215830d364c9072eff13288cd7c695d43ea6153ce6fc212820d354c900dd2c225133a63f8692c68316ca461e269f2d7d0f9f5bb6d344c4e412be8f40b52337c6c9c6152f86d18d1e6e3f5296698a02e26e55ad2df64b836ca30e1a388b40aaded394d324ccccf9f964d34853c4d0c37d818c3841f5f8f1dd558779b1826aa9d07d3ad98a196db08032a36b35da1d7baff316f29265369ad0d304c0eea4644a898f3c55049c3411a0ef00b93773fe9d3d0f726cf9246051b5e98f0419e92a696a4ad076d7461c259a95a8ad2d464bd0d2e4cf014326557120dd69b1e36051b5b98bc99a67683c8a7c6181965a8c00420203e46c8682ed8d0c2c40ea582c7cad1b3e56601084848192567061b5998a07bff17df6e446a8e09ca28010129a3e4b660030b932ac714f71dec5684123fc1c615267cc99c8e5e9add632a9960c30a939469f5b18c6ea61e5485c929997d0c9d29e869850a933a63b66dd69655f9a630c15df478a794aced62529820b53a9932a52c79a6d20836a230296adbc58b6ed053591b509838da6fd3680cedd5a5274c3aadbf95b2ad369c305135e7f7bbe95226f61f4d406f079d7de7ebe3371326668ea7ccf3df9529ac6309ad9ea7c69cbec875ea67e92dedafd9e2aebe49060f1d684309934ce8b014e522d5dabb62230993f3ed52ee13a192c14307be0d244c38d335ffe8977310a1085ba7921f4ed23e4a48106d1c61a208f531eecae2a6648ab08590e8383302eb16aead1df6a61ff26f1d6db356d56ea30893649f8a499e1e4d514f84ad53c063c447077c9490ac880d224c9011e2b3bb6975eb48842d4d078f1f3d6c0c61820aa753989dc6d7f288b0d5ad0d214cd878315cb73a9fea13cf6d046182ba700b7263752a9742464ada061026968aebbfece19f627ca4447f31c1cb2d8d7ac857c5309b2f26bf8916b923e3315767074908193f6c3032b2c3ecf4403c90da19f76252c6cb964bcec91cd3891713be428d7cce116153dbc5e43069167bce749097f9ea62d2b8a76c16cc7f45e823c4b5462e26fc9ad0a4e48465381df3514282b898a083ce7fccd1e12928f92d26a550263b3473e6ce1d42628b49a1e91737bfe5a6364f0f1d39e8f163a4472d2686fb7cbe4e9ea4c69cd342abb8af7cb9aeda1811d395e25af486b39854b953d0c162aee84125c2a611a8218b496a43555099c2950c3fd588c5c4ee6c2fe3779e9303d4037d2011e3e3510a7c94a4c08c7d9490c022d32e2d1bad1717190bcf1964fa7861f459ff8a89e77731e3b7c7ac3929c276e88ac9f9fcb372923921968bb0f518e1c163c4848c9484f8692b26574e11974f08dd5f325a42a26304ce8ac95e9534968e9ed44b57ab98182b9eaccb1171997935eb121e491593bb72c51053c92ac957478d544c74af9842e8d3cf7bf3bc094040487ca0de31601042831aa89864bba6d5772f97aa94534c103336fa44c8302a42534cea984f2ae9959b2e25b42dc5041d47d57f475d322debe08080063d1e052020202024a498947745cf96997dd01611b6901d3f789459a0c62826e9b520ea528e5e8e1511b6cbc10819213b7ef0e84a1d1cd240c7067a79fce881a29894257a19ca736bd87dbc880909193969eaa384241413c7afa2893a7929936b74f478138080f018300849354031493d069349d9eb474d89b085147e62f27a9eb8a4f477ba213b762093353c31499fd2665236bdfac9ec18300889418d4e4c3e35b2d2d37ee56e6d0320203b7620c38909d2f3857fcfeae1ee31a2a3e4778ce8c041c8f13112d263e4aec62626dacee5efa83da733e203ed20a48c1282031d2704af84a48769627292cbbdaeadfb40c7c7c865a0462626a78c97f4ecec8fa5743950031313f653c4d25d6c44a745d87aa01d21a7070a4146c70e923cad718949a54efe9b6b7d5ca7c78f111f2165e40b6a5862923613b3bb794d8f0e9bd701da4a4c741bf9e0b631f55dc81809292141253e46444842dcb499c78f1e9498986262949fd61204352631e97d3ccd2e28158d9e2426f68dcafea9b1484cd039e7e52cd2b3dfa52131d13e4c63b60a5fa5648f98f41eb7156c2ea57dab84c4119366d367ce8ea7dae98f0183900fd468c464116f39641af51c743aa9c188893a32cffc74b02cf5d869a0c6222609353df2cc647ace7d50892b625257d660e9727f5b3611b6f36420488d444c52f3b0d5983cc6da5084ed6a20626210654a888e1ed6def3719e8c331fa8c40f3131c6f7f5f20ccf51b2089b96f0480da86188c9315e0a9fcaf54c7d4834e03a060c425c50a31093b2c924d4c42719d4b7226c253a402134f851d009597b1143c23e5ec4640a6a1002cfefb12c3b8f29c2d6673f424a78a41ec4a4b0e9e275ce66a3995341dc5a752d9b55fb5a7939bd2fcffd31468d404c0eef61ba729af4db527906d4004439c6e8a89ea2e978fd1ffa1cb425994d4f49a7fd60dad31aabcb7d7eefc3319c282f753a98fcf0a111dd294f5bd638ef1e26f5e53e9d4f5f50979e1e2695ae98332995c7fd2ae78c78d7c8c3842f1d3be820548ebd321e2696cf9c59d22eb3183a237798a4a14fcc8fd5a699e59c113b4cbaf479c406751fd4a5ce6bd461828aaf1b839fee986845b8e4078f90919290a6c3c4990df931447aca67cf6172f588d2ab205f41fb7715a821878939e5f28d5d1f952a2907231c87491beb61fbee6ecc54233c467c906147811a7040a7d5bde65423fe59086abc01a1e4aff397452b7fdc40478f1f21243ab60435dc3069fbd6c5e35fd65e4e1b26e5bcc982b9f6874da7088f94a0b1013bb578759d640a5b88d151f22524676b98983c78a732d589b0f5064850491945c78041c8d550c3a48b395c9fc5a072aa1e04a4e4c74819bf0304a4461a52d5d58b9bd58abdf67450030d933afd67fe54364f3953e30c1394d4db4d22e46c142511b6463e46c4f0f12c281b483b6483df51d60c3e5009c90f1f212109a8518609ba67f2f9da62fd77da946b9061e2a735755abd93d0a9c1a0c618d668c232060b35223722a82186c92d9bd26ec87c083ac31a6198745629c7f424776d54030cba555da7ed95cc5a6ddbe630ea7173cce14711b6103e418d2f84d4f0820c6a74610435b83029fc64ac990819fd926a6ca186167ed4c8c2c44a1f4ab54b4d5f6c45d842ceb68447da1a58e0313212b2e3f80809c151e30a35a861056cd434eb4bed2a2de6f27daafc246f999444eed4a8c2a4e8b549efe5b3f76e6b506192cfc9e6efbac61426e58a85f5bd065d421d86187e89a8218589a397da95a3a73639310f35a230495909996c3e4b782adda10614267c967eef9cd46a4c17421d30448d274c1215ce56c3e59cc457c309932e9f9b8587eff890f550a30993624a41a84e21136163c224a5d22995428fb80eb741516309934fb6851cd1d1c414c2aaa8a18449225d46889339c8dec614359230319a8a90dfe13d9dc7bb14359030e92ad9c8d7cfd2333a4798609d4d748c375beaf6166a186152d5fd657511f7589d6ba1461126875abefcd3b7db681261b2b88e9b98eead969ed3506308934aa3a96895f1196a214caa6c2d2a769a4d9de545438d204cb0cfb2a4c4b4652165a8018409a6d59684ca2957ee2c038d5f4caacf20facf6f93aa90fc382134e8a123a40b0d5f4ccc0e71236553fcd3ac1713b3c8f153a7ffa9a6e7c5a4d361445dd4cbe2fe70b4a33cda51feb44063179335e5e5d77b59d35517933227ed9f7f0d1b5e0c46f3bf3121bedf2f2689cbd61d946953d9cf1713b32a8bc69fc610f1f5628287c94baf2f2f26a5dc9fe7d1b9e3de5d4cf8645f555a429f6a4f1793cbca449412131aa3978b49fee935d987da28eae162b27b8fd267da693a79b7981ca39ee5080f9f3d79b6985c49ca66f711a6f7bc5a4c507a3475b2dfaa138f1693c7b3854e1ae5c452378b49b9721e1d4c96bc5f278bc959f1d4ea7ee6f9502c26c9ccba9693c72aa1038b4932b24a8a578a0c3aaf9818daf6afd4856ae6b862521255bf90316695a615eec6d7daebbcb162d2a68dab7fb6b5cbdb2a26be8ef61d9d53ff7a53c5a4a8b5d1f4ddffdeb6544c8c1e9f4b670b21621b2a266fd28c4184670a22db292676b0f98d29bf266dcd14937275b8fc167574572bc5c4cff59a326817254b23c5a48c226485176d14937392318de216a264268a091f3aeae70c323e6b168ac97ef5bd295812793aa098e46ad5b93f85d794f389c941d3a5a79745511b4f4cbed12973de54ce6be9c404d59c3ffc5ffe879c139334bd8ccc6fbce97d139392b21c6390cf3e62d7c4045d41fd7d4c9e3dde9998205e594a788e10d2c684a9ddba63947d894942580c4a69b6244cb6c444f9987477cca65450252686a8b5bdeb205410293131ac879d8ea5e47e6e129375e6fe6352297a563824312988caa1bd1d72feb42e1c9198746183a7c62fd3a79533c50189c915db4cae32091196537dc4a41dd3335762cad2b939081c8e9820727af5594e10f8d0114206491a8e464c4a31e6ce79d1d227a5c7c18809da1a2cbe2f874f1eb388c997a2e71caf9f7f55e350c404bd41c7a4ebd3dac850098e444c8aef23d573fc226c213d4674201af8184987768e884922a47c32f93afadd1e62529a4f8def3bb159321c869818d3780a5ebb29e7301261e3b18598f425da4bee6d9a8aa38f944e88495b6234ba8cefdacf3c88895639eb89854d9e16c4a4ea18dfd4dae2c72c8bb0ad5e2026775b8deadb77dbe8978990bc0809700022c40038fe80c30f38fa80830f38f6700aa6d2856605a51511de000e3d9cb66df2556e19bb326757599f6e53b08af330397736946e3cf5551d3c4cd89c493f6f89731ff91d26d85697b65f5a3b3bc9e0018232364042f2260001311c7698d841dc8d0aadd9d4421d3c0f17018e3a4caeec6bb9dcd483cc3e1d26a6501e455eff68904d0538e63069b3c9e5942b68c81549e43049fa677ebe3ad5351a19f1911dc011874969436f8b5e0787c9da59932795455d724dbf6152e7a07d2b7f2f9fd1090e374c8efb368fa73c9627751b267e7a940d4a835adc2bc0c18689b152f8937741e6aee86c0d934653e7509f9272918f473b8caa615278480d57973c698a49c3e94ec9a446c3643d9972fa6e7a8fb7e238c3445321a372dd63860927dda486bd4ced201c659818ce628aa894c4bd2745584b80830c93cb4c86caafcee86e978500c718266c769edcd01f4fe73ec490e8e0f1011c6298b4a6b46465dd7a1d0fe9f051922dc01186c92986fda93b0fbb72e106c3047129e61b3ceb83e40b93c3aad43ae6cf8d4945d8120f0e2f4cce7d277adce5e53492901292119110b437a223840c12edc2c40f25366d0a5a2b87100717266d540bfd5e119971d691521a083ad001903b1c5b6836064b2144838aea7168a1a03f89d9f3aa98c5038e2c14a76d5fea6e219faea3b4550e5f6943888f0c706061729f29954d46882a9946028e2b4cea154b9f84dc32d794152627ed7c2532da559898b6c1327ab638a830398e9cd2bfce62173f38a63069345ef49c826549704861f2d9979f850ce2fce238a23041e89f68cc65b5d0100e284ceaa45e2bee06cf24354f981c5b1eac4d63703861a2a98fd12e8511d9418ea30913f75c6348ebdad54f3361c25acea2dcfc726d8e630993edc63db7e90d87580e7028016780230913c5c4b3928e9b942c150e244ccc8d41ebb9df7d8ca3234c4eca57d64afca8a917871126ad66bca08416131f84701461b2e8974e2e426e8a31a903f40110101d20118383083ac03184c97a9dd25a6f354f0787106ebb38378d4dd554cf2c6dbde9e96e5387ce03471026a5df1863b6e2e779cae200c2e498ce736c7f99d022ff62b2bca55852d495903efa62c2a66c9ae654c66449d38bc9e927db4e65d3f0991362bc98b0fea9dc3a635eae2b0043b8b18b092b7b296544250fb1eb62c229d9d59e5bd397b79584a497c78041c8046ee4a22fbbb8ed3075b1719dc70d5c4cb4ef2f555dc1cb64d08d5b4c4e497f8c5b22b355f0d862526caf70b329c98ccdb5b054b6532e2b09db12328d4af9b1d06282a807a1eadff2582a89b0e140c7410e789fa11de5c7c8f19cc5e4bf329d155b1b7d39594c8edea35a834547082af990327c94a8dd8845315aa4854efaf7864532c6a5acd326b485f5156ceec876b57d587c5605a9a376c3b4a8a6b862d2e76f1b7db27c2d07b56272124a88eb66f80ba361c544cd5a22d7298fac6a5731b162f2b0cdbf30a63396851baa9894ed2ace85bd0faab420201d6268a93854dc290ce48629266c8652f1e6c44edc5c8a49d1b26d0eab8d1493f37b438cdf7ec8b24731d9ce345c5c955ce89ce41ba298a41d459e4ad53cb5b00e9088f9b8118a492a5999c8d4f4bb3d45d8ea3070031413d5b3ea8653aa3f4201c88d4f4cac3c115a1fa32a6f1432521242860e1b90b827baeb4e9b911bb3ca9a2dea22639e15614b23216ce7110a90d1b12305de89c936329ece1e8bcb41e3c4842d71dbae9e8305f17b8c9084e0d08d4d4c4e2a4d484fb93ecf7567e7862626eefc79dca4de3f8b6683e751968964b436c3e2d5e332dcbad4c7fc7a716a377e72700313933ebae9bc7b34bd25bec4243badbd6e52369f6e2c3131f45c582c994c8988e88c8851894959273b4476d753da44d84674dc0d4ad88d49d8df90c4e4ee0b96abb6dc333d9140c10d484cee381a5f62b9c36303f325c46f3c6282855bba18eebee188491e2b3f6e48eff86891c1430708c8888e1b8d98ac31f7b5eef79cae20464c4c8f95577a54ce56cf22eeaacacedc76ed76d750515ad3686b3a2584aa8849bd1a6bc55654eb06256252cc612e88f5274f9963861b889894c35cca318f675eff7d8c74c00623232320c38d434cfae06ef9b18225e97709508f12a8e08621268be5e8b41d552df3cd370a31612cbdb6cee3a950ea921e3a464cc00191121d2db841884921a4c6ccaa8a16d3786310133683f618fedb9478bc6e08625285b4fd18dd39540c076272eb6f6c9efdd6967a031013b4bb4b8a9a76fa70ff6162ba942dd59c96694c2ae1861f2665b9a439a3e2c8afa03e4caa1695f770dea569e4c3e4d67ceafa792bc65cddd88321466b55ae89f82225254fc60e6ee861928cc9f64dfce7fb5c3f76201f6470dfc8c344f9fccf996aad193e11b6901ca01e6b1bb8818789252d84698b11297913a448c9939165945cdeb8c324bdc92d3c83ced7f10df13112d2c30702019b0fd4638c1b769814d3cc28e9f122a6536ed4e15a97d735ed0e4f8b774f499adcf8bfe13f3c831b749874a65e627699395c90089b8380808090cc618287d5f2689bb229a59310077070430e1375c43afff8956efcf84068dd37e2304198dcb4392bc60a9b8829791e3c74f8286983c344517a3799e5a47931e564dc70e3a8d8ce12a5b96172d5e9bff9f8f04159da303955b4f22b95fb394d64c384f7ba98b2bf7e94bc2d6d70630d13a36877f7947354cb086b70430d1354f20a22d5db63328f6407193c74ecb89186893127a39f2a6dec73d03079548c07d3b7614bc98270e30c13dd2ade95ccdbcc6cea91f13c900537cc805e5a778697de75c73a9d4aa8a464744598878f910ef0f031929ccb3031ed28b154957baad7126e906192df5b57c8d2fe98496398a02d74d41453fbaefb6248c7ded6f4f3d435deeb3fa95132c970aa4f178649957b4525bd496edaf80618267b3e19fd2ddeda4b24c2a68344471bc90e1d253ff40b134f44d496100d1a4eef85492a4b4be9d7b8e3a2eec2e4a82f6ba71d979349b930c993d78e5cb8aaeef2c61626fabca94b21c3e2b6a38549faab7dfe63775bfe6f646192e8b134a394c509b1e10616265efcfc1d7e644ea2fb2b4c54d34fbeffb92abd5ac6b76024072ac80bdcb0c2e45c31e6fe6861c9d2d2f122628080f4d0f1bf49b8518549d253e5ac6493f0cda1c2a450552e27740eaf4c99c2c4ac1861aa54cc6041e68614269c88edad4b31dc84aab870230a934a881295cbb0d81a45d8722170030a93de7407a56b5d42674f42a2a3a4c7f3e8324a4a900f32f647193e700c188464e0c6132679e718dfc2fdc46cf2861326e8e916cfa21d316e34a1b356cd9337bbf7ac4d4deaa3568a656cd0cf0d264cd027b76a2a67b58ab98409e3f9f5ff35bbabf336dc50c2ba96d2ebd75cb98b4950537a5132e58c93f18284eb36e33c543e34eb44aec3d2c95a1a994157b8718449d23c8f38a5e6a22c7ba64698709a3ffa594ae95b471f28c2a4a815d46eba30b9eb032db84184496936cfda6dd48dedf8c1e3c61026590639cf327f1a9476f5560002c221e6831b429894a13dc7d7f0ffd6aa08db19e11182031d87576f05a937823049d6d6a9f174f97f2b3a401ff0817230328231601012821b409818ebebcf82aef86cab8d5f4c3eef4db7709731e515615b565f4c929bf4fe76ab67e38f7c24482f269fdfe5cabc1da47950848d0495945142f8487cfc1083049594b101e785a741d7586767f9243676616d8e8ac9a6b68e7a76d88f9ab3089d449c4c176723179362f7375e6a18519363c1062e269edeb9d9caefa764bdc5044b3bab9227b2be225b4c4cc992bc68139e63bab560a31613e3c99c637db61c9b3f8d820d5a4cb0b354be723ae5dd7ccf6292a7f14aa32d3ec52e8bc9e1729266050fd893809904f2ea1680b7af58ca1db08002c10631059812921f3e6804a08c220132720480c407c27101121d647c8e0044210005a0000048480ac80c017cc91f101a01f8923f233e406c00600008c0e10385d8c07c094948480100108003d8c091a30d3872b06152c533113a7c16e13efb71c603f908c1818e1372dc4a7ae838418e35942012354c3a31eadb314ce5f62ac2c69b230d93fd92da3c65ea73a52411b6e58178680e34dcc871068483111e3c100f1b39cc40068f324cdef1b4ae3b192647f3386697bcbc3a1721f990102f493a4448140339c63041ac5ec45d6c5c0b43427ac70f1e58811c6228830cc303f1a891230ca8a3c48708c98e90101c39c03049fe7fbef5eee5709a081bea28c1818ef32324c471a0e3fcb8408e2f4c76cbb12ee728f56fb71726c78a77f3c9c4c64a8748c8c88e921e20e04096f4d081243d7494ecd0f1a384f8e01c5d98d8f9630919511dbeb339b83071bc846b7dca31b32e97630b935b36e93ca295f3bf1262245a98789fdd4c48bd2c236ccf918549c9932eaf24fe1c589898e97286ac129a465639aef07a4a15a3db9ac30a78a7d6e6b866d7dd9c65a70a1fc35e5ba5534b0639aa30b94f87b2b51cfb6352a930f9f673327d39a3f79a7230220608480f21c714269dda85dd985cfec3490a93b7b34fdea9981c5198a8aaee39969272406152feec9ddb3dcb821c4f58c4e978c7bced4892c309bb5c5859c7975d7ece94b4be7fb5d89ba30993d7f2eda79c62d01921811a21071326a77c41e57ad6980bc21de458c2a4d3c92e07af51fbb1b3dc831c4a98d851ffcc36e48bced88e17428e244cb6d79c2f37689ff9377990030993ccc2544ccf252e57ef831c4798789ee1ad4653949dd2da90c30893b48bc91c45ec73438e224cb2ce7932c8ccdfaaa5d721071126e9f6934b5af392d2ef1026e81ba9d93125b1972308c81b720861b2aa8b7c05b97ae8283c46ccd9be2047102667926279ddbb4b4ca63980304956bafeca24bd1f60fc62b285f498533a1f4f3ae68b49e2f4d56834fd25966a1e80d18bc9b1f4e7b2ec7ad4b401831713ddc782b668ae3d15c1d8c524cf417ebc9710711d81a10bb5946b78ee051dfe008c5c4cd0a8a923c260e0c2115715113b33931bf1b7d624a2d5bdeb1d01080218b79874399e7ad217ca846744f89490849041a23801c31693a36c527ab4c824945ec0a8c5c4550d9683dccca8f905831693729a27b12a565be95d2b80318bc999bd545d28111a343f6e80fec70d26258bc9a92966f9c8b6bd9803462c2655f077d1fc2e5f3bc3000c584cb8d1592f4e379ba5d22bbab47aa6846200862b2606f9a6544e4237dc3760b4c2b194395b75cd8b4bd74ffa2f299d6263aac060c5a42a7191aefda664bc51e0ab98e431cf5b767bd1397b554cbaf93925cbf3de28cf3700462a269ed5bdc79a7d5f52a36252c8072575e3af86fc24609c6252c51fcb2aff76db9129269c86bda46b3ac3e94c29269ab9df5dfef3187c6d0318a498a4f252859754bf2ca3514c0c3f4a57cc38f3db922826ed79a8ca8ba70ffdc108c504b99ec4b3b9dac5e5c100c5a464236a5352fac4c418cbedb2625ab89127269c8cab8f59e7826d3a31e93e7da8784237c9144e4c32d5215c3f672b5c3631e1f256ca99d9529c8b26268ddb5b4ed92d5df69998e4773ae3da5bcaa5c6c4c4b4943777d0fcd7e94b4c529b7d3732c5302b5b62e2098f513fe6f49acf4a4cfe985bf99483bd9d9498586a5b57d5941a934d6272e526ad2965929818adbca2f87e529f484c4ea7f3578f6c1eb712242647d151754a74885ae9119377fb2dfe9a902326a7cb31efd26f12c2841a31b12f78a9c710232685c5cbb92e74d4f42c628232d5274633e68c8d22265dcabcc7cb9ed197444c4c974383eb4751b1206252f8701b3ffbeeb47e88c9e5267cff63c7ecda1093f3ef68cc9fb3869a0b31b1727c56513696944c8809961ae6f7e5fe843b88c92b3f67a61573f114c40411ebd4395a92ed652026a68c9733b2dbb33d04880933d2ee4c6ea8a037f487897a57ad7bc9d7fe427e9824b2c294e7cad677a13e4cf6ab18627359e48ef83061b3e8a052aca98da13d4c10eb24727ff35b85f43029284f2a4b2c4cf9270f93ec4fe4c5f3303b193c4c8abb389ae24a64de7798bc315e73b3ada9b7ed3049870d9541c347f1b90e132d9d4edd163c7498f09a93dae92725763c739860a55d2c6f3e990f8f1c26580abf2946e5204f3b7198b8512ff6e9ecc061f2e6532193481593a9f38689393affc9b0561fade38609da1f75ac4d3e46511b2669183fd5a2ceef446c989c5984a9d9144748cf1a267ebc606a339ee9a5d530e9d4068bd1392c9fd4a461c2dc07a52cc86455aa41c3a4dd145937b3ee5e9a334cca6d32055119e3a768cc30497df84a3907eddacb946192c5e0afaf5d757322c3a454a77d27437b4b670c9365749c6bcc9c23376298bc3dc2f24bf86756c230299c854ddee1eda20d86c9495c28a1b641ea69bf303184fe56f6991115f5c244ab8b3de2dfc3c660172698fed41cae64bf472e4cda949545bea40915b730494dc7183b3e669b2b5a98d477a593dc14198357b230e9a38fa52c9349cf56b030e12ed445ef346565e50a13bdd4da2613fafdaa62854942a6e85126ab5a4f5598245a2df662f01337a2c2a4f2f6cd1d2a77633485c96696f246e5aefd1c294cd41c7ee293a51cad446162508f1923bae2661e0a93d7af94a88eff22f5274cb418a12f84ed84096fb2bd2adb7e1a7113267c578cd0db2c7d3313267996d239b23955bf4b9898f97c7edf82b2e02a61925690a72c2609136374db93c9bb682b1226e5bfac9f43c7ab108f30f9747d49cdd42aea1961720c9e74a8247b308a30717449ad4b4184d0b107830813fb75dfcf76e497eac118c2844ddaeb84deb7f4ebc110c2a49f37d9ce77139d03461026095f3f8f7bdbba1c308030f992998d142b3be9f9c5e47b1df7ce29e2b3f1c5e4d818a4e7c5b7e0965e4cd0d8a0f205f9ba5ce1c504b1f1a93a263d6f71dfc5242146b95c7f8eedb7eb62f28d8cd8d4f531d3edb998ac723af5a9fd8f2b3b2e266915a52d6b7b8bc915c6d2b52b4dc91693baf42ad4d959b0d462825efadfcdeb9d645a4c1611b7d9369fd7d4594cb0d490212d4453306531713d7a5e3ab99c3cf4584c92d12d8ae851b9ba048b4977414ba8cbf7a939af98f8e29fd55c73d218574c188d1f1ef4646cd4b46252ea14fd6a2eac98b027b4e767cb2a26e5e93953131a33a6553161d39d12ef3946935331493ec8689d5da333544cd6a01b4e5bb89cad3dc544ad5232770ead6a32c5e4b8973bdbe5ed84a598a4fe92aa0be25f5e9262d245190defda79a1514cec2c9b3d7ac797184531497bcaab2473a79d178ac93e5f26d7e2658a5983626227afda94b24c531013e01313c38e909529e489892bba83066ddb39c67462f2dfcbaae6b8abbae1c4e40c2a07e126cc42359b9868d1b3375a5c4c3ac39a98204a655388c7fc7de14c4c0c99c52dc950bdb9c29898f431efd54afe2b7cbec4a4dc19530e25b6c48411b77d298d8c92722526a54f41cd534c9531ca94986cfbf9dfdea9bf294f62528a26eed736fc6bca9298706b29691139ed2d722426ff26a1f92d9dd5a5181213f6f286cb1c4b07393d62a2679bbe123aae7dc91113ef35553c6daa31083562d2982ee99936c9cc318c9834bec98447cb222686cb274e6c5bd29a57c4e457b98c7742058d3f11134eb66a3ce6f4b247c4a4906e1d2bc61c3cda8798b0fe6bfe6a1b6292dcd84967adf33571212656b96f0a67f93ab44b88c99fd252c59fcb15a33b8889c9daaab5475bf9b98298182f76ba9dcc4c991b88c93aba62fcba2c72840b88891b73c65c1edb3f4cde0c374f953286d7d60f9374f8d4a2f43255ccb60f13747ec372f68bc1abe5c3c4ea1cb6993fc5d4b38789df9e35b6a585cf317a9860e6a9632c95ca65c9c3a4d6ff8eee29a246c7c3e4929e57b6bcb46f7e8789b17599f2a7d50e136b533c345f554a5aadc30461993cc5c5ad3eab7498345761f229e95019d5394c4ee974e7a56ada56550e9344fbc5fbd77fac54e330d1bed5f45d985f4f2a1c26bf657ad80ab9d6a7be616289e6fb6eb89799ea86893e27548acfeaa14b6dc32431dabdaabfaf5d54364cb48b41dbf2829cdc740d932ac860f952a66a987c9552d6f4207ecfd2344c8a3bd72a4a8f8a3e42c34453bddfe14974d89c334ceadf1d69f163153466989cf5eec64def8367ca302957efc84ca6bed7428649ff2947d45fce1d2c6398b47a6a3acf736b55c430b9e3c3af09a5f3c2cf304c764f5f492d891cbf130c1373505bb2524dfc68f30b13537776b4e73ffb35bd303987b2641b45c8b331bb3031a57cb39663362531b93031a72d75496899095d6e61722cf97db247c6b7975a98243aef4793f935689659981c3276ce8db6d4b8120b93d2dde96cd1a7d397ae3041e50a97d496ac30b175464e438e27fda9c2c4312d8ba5c643e5870a13538afd0bbe9fff54a63049e9d4d1f598a1b2450a13531ee1397b6d66ce4761c25a655ef89de8f55098143ddda612a6465f7fc2a4cc185de9af652ded84c931a86ead92cd96e6264cda974b15c364c2a45399a62ae9281d2f61c2088dbddc0e09a084c9f741c5c9d196112a244012262993a17259c693498800489868f9f2ee8bd28b318800479828a2e4b252e7110d11c00893b42a645cd7df52320428c264ff14f54a67d3541b0210615295eef0ed63ba9a21c01026255dd284f60c5a2f4f00214c3a21dc4b4bb8a8dc1f018230793ff437b85d76de8f004098a483028d62a8b48e0523a2401c0c8402814018100a20ab670400a313000000101e10c6a2e188485c673d0014800348463050322c22301a128c0663b138181004428160280c0883c18050280804c2dc8c3ace015d6cefcd66e8ad4181d1da5306d43d8dfc5c104f75c9ee458db528b2ef2232f41deafe957a21f3f026d350b911c8028481e8557b1addf8588dce9ba26b257e5ceb4ffa1d712d00560d7f736e5e16d3ec1b5ea5e9a3ab71618ca02b411f1a23c53c432418987091143f54a38f93602ac6637221f49d0f09bd0dae49c4f61524200a5de12f2ad787c0d14917128d44ca24a325884e9c0229329f4aae91dc1e0af051d1c0aad17246d0a9cf02b12ac3b0b14c78247ac8514428a763905ca06f69731eb47159275b88092e6fb89fd427c7d4d0978b2e6a8f9dfb4a4d51d74a441914f1ea6a01ecc21f60fd76cb4a5fbb7d6b9ddb3ae564fb6fb96983063e4d238c2db2bae010b87af812b938c800578fd300cb58cee4b97362c2331598120b434a8f3dd54c5d80b994150366162be96ea0c76b2711dcd377002a3986a8a1392804712db69b829da6d4902ee089ce018482e803280ccd1cc52108512eab23628103efc0a8a923848e592a17003648225b0a164068f05c338bfaf94f54b6fc3fde37f38ee68ac2d4f0762d1ea2527dc34674d3e2fa50043c98e83526829b2fac2a74040c82357da1d5a2d94c3a633372c19133446eb68d5b41e7a1a38690eed5378620a53b56a62cc09dfa00f0822b4d9131ec4796cd6c36789c82234060c135c0e02f4cc274da4df366db50afe71c66283d74b68eda83a2623e812b4c14df42a2d79db9794b8120700a9711a5bd6b9206c15d246f8893fb179f1b2de84713a7eb7b5acc571b2ccd7d11a6c6e183e7a52aff2608da9a0e6f08a3e764d3514a83a8e0a2a481f056e25148730cff0283f7416074a22e7e1b9a9c5398e90fc0a359868a7db295ac6f46d547cdcd54ab6d94e09593e88ce8e16366906bf3368d7d4e21f718c75194ef6a9ad12e8e3d6ab4a1e26eec12c952a49624316590b9067a1300c79c40e8301d1e026bb2cea8f3479bb4a55dbe9141a27a8652f4d8ab13713853fcc4bb40f953ab818c3980f0085586f487703bbc2efe97142c3e7c1843165b68525a8ce33369764459b97ac38b614c9212e9297c143e4e82336570687057463e7fcee5858f7768537777ced4424f85407329c1a17948eed353e3609e89cbe1ea9f84237ffb9daad987d9514fabb143dc43644845b0281afba69a51ab025ac6c09c47c4f572520fc58d3c591c83337f1d2efb733722fa2219c4becc5edfcbf43939a2f7e36479b4f03e1a60eeec2062ca44c188e2024bcfe69c9ce940e9fb209fa20bb4cce44484f42159292667f47a5c96e7e208dcff93c1b13f73eba24ce42072fa51b23a4667e8fa5ea6cfc9b1a86606ce824cc41e8627e1d8df06bc8f23a72dfd5e5271312f149e3240110219cd13358c324041a9c245bab2a7cb68699e1411f92a889c002f1439ad8112c40f29fb633043d5e1b23707c979a6c0fb5e051b945d0db66d59f8398ecd1232cab3a6d70825955a88ccf25c8c03299c17e693220d141dec737c811684ec089276b820de89ce28e9f7df46129a842903b52d73c7edb63ab56a660e36fee3ebceddcc0ed6e9eae80954f3e43d47687c6882a41080d4ca2588e6dcaabc110b01d1a0abc6c5bc1297c389fe5d053960ae153aa71f928d18c9409d949d1c8888be4819418f6543a4110bb5ac5017d4553a4947f6767daa064fc6948b2a4942a4b483d4101c19aa70c09249b7aa99f4bdb802c7ff3638ed8fdc79bbac2e571769a825a13e0661a4727e7ae5633c490db1d281f4271852a090ca18d721a01f5236d31cb9e45ddb6b37110aa05a922012da472a0942862b1757e5a41e89db9e09badc9c0e148891cac987b0d123291027a91d5da55193622379a39015e055b8f867ee70bb5b27d6113a759a1925747988dc137624753db23885ee1346f87a19927ad0ae37e7f37db95f54bd9c6fbb1b893a18bb1a8b900a0df79208855a27ec72d3efc84dbc27c1fff99fdd440afef84afbd63b98906e2fdbbb29777440c3038442b153f86283c96856a97b3ed81ce59a0a00d725d4a8167b41b3c3b3828b36d41355d87dae8e87f3b7df46affe499e68ca420c61005865c33f8dff3fe4171881792bf91ed4d0d756768bea1266b0770547bc2c47e0b3e13e9abc6ac3ec908cb31d2a198fc93c3187d1c17f1920e99d0026265033ae103e76e310319b70b4391421590d6da7a45343bc46e2be6c77aaaf37c6dc798c150da70caf2a4a5d4089392360f6579542f8d1d07960b28d63443676ff38a6c99d00c71fe8a45d7a56f93b4d5411e93cd7967e940a0753098edf3dad41be21c5a730c024f6b6d60082461b6a345d8d92a8b4594756408fcc13ac0e0f9dc2a1a8e8a95df93a7505b3f6b6d0d2d9702c087d94e6f111c1a0ff7a44a3b9b0814ee3f0bcfd05ed249293fcc8a6351a79ffb1a6dc313fdd8ec7f4b0a132ec9264a090e1a880705d17ba25b40f849adbb93ce1a066c60bb45240b1787ddf04e87022c147cb124a290896c1a8167c1d576c0e2471e624f806a761cc931432313b9deac129ae9746eac4c1646d17705426abdcb441f4f1d767ae42ebd6e0ba04281ee21ac27280182c89843c7c933171b7c94459e023abcc84c8578a0f91b10d5073b6fe6368cfc2a273a17110dcb47db3f5d3ba2f706e392caeced9277ac93a82b81383c64fa512567f213088443eda2a59e3ebe7428949ca524e7298256c0c3aeb95390df69c73a066d512d404b2122514b7957e4148b1e6d00b84a80110d560dbd3e5f60fae4eca1b65d5304898bb4a8a31102b159d9086354234d69e5be0a9447341a269be00f128fb71c8bbf2a55b0438f98106fed019a7b5a505d5d5c7eb7f4c6e3b8cb88030704bb6b088273060845bedd40602a60aa87cc4ada05adb2aea397c4b805e3cd4a3e0ab681a5b0f283e582708f18ba4006d197b351bcd7531d2e5ff0a1589f4e3bc697c81ef097109ec9c4724d1f5bfb7c7effb3d9bbfe92abdac9e663c0c65d738b4af73001837a65471876c0065ab6b967153ad6b87b765465a356582070d7735d83a20f797ebe51b0c78bd515d751ccc196a092324ef9a804f742c496bc3e7dc6b2efa69c24b7a1c160b9216742436afe3329ef4722c54864694568698fd727837d2e75c07d296071b2b410dcb1c6a1c5649d53b85294926883b273d7c833901ae1faabf41170e47f4cea2a5868514a32cd50147f450140720c86a82e071a53ce1be308d9c5a10fd6dbc2f087283d971b2840bd3a0d49a20e06a598593e1a92170b11a1e9fa26015f81b24781d4876befa529c2358bd0a753c0ce0e6b77aadd833a0df3cc958d052433fc5bbe8681a684c43bd558a535596e2124fd160e3a461cb4555e70d4085477446fa230c4a4b48cfb791461c307038160ecdd7e12404efe8ae0f4b714388c14c7b2470eff826a22c18446654a8ea536f74009c742849cce32f2b58fa4ce272ae2c789997deb4edecf9910b7e5460f1c963a3d434fe0bfd19899c26aa02295607da39b88d9fbc9bd9c9568082238058721064bc073f7a62631116a796b68a3ca9e4480b3901d4a390d01df1e24f3ba6685e56adcdf57415836d764845b8ffb72f51cb3819478b90dd1c0ccb8e514c923381abd94e4aeb11a2d60a2a55bc5646ea596e848876bef7bb5e4b612e3d49c27e263c032b69423640def1c3a97f443158a4b30612a5daf0da4a14d807136ddf09abb97b3362a37f8792f5ff8dde651b2483d8a6837729078d24d4b4825f2c1241b8e9118004880594e529586a885ad4ff3cbe40a00ceea7da3faaf147c65756ea4f86422ab1fd32e78e0c80b2a151d2dcbbd9ba0e44a14e17589a1001ffb363d28ad92d0b0049970cf803680457f6e3bbf768379062024cd372b77ebb314d9bbc634607012aec177a79847e1d273137a1a60cc2eaf77cf0afb6a6c9aeeee34758c6e1ba89aa24450c04f18485f523c297f3a71a30329f51ef981bc94195980508b4a73fdea70ef240d950413c5a3ee0f6008958ed4e8fcf5f6cada2c76a839bfd77d7025d0234a63f84da93249ffa3f433f7884d681d5fcaa0ddb4ea79a234887fd8273f6aa7f2f3a88a50d8e02f0af895eb665e040621ead8836afc4227b6887d8a58e9d2d84330434028e100695119541596db44739059c964ec2ab6b4b0cf8a724fec3cc5110f0fd4eebe4804086853c5e66935bb72624d13cd267037091aa1d9794f738e25d1bca18ae81c0c4c9635e59b06e6afc30f3db9975fb3c47f0558ec28ea00e5b2acdce2201d6401e9ced523b5e643415722313e437870e75be2dbc8e3e015a7cfa44d896f008f859f0e1bd8e08efcc13fa7e663e95624d099a111d59dca9c00dad633153eca51d64d7807339c140ef1928f2ff90997a222b52c7f9fe0ac30fb8c014347076fe475010f1530d2e691d614380c37981250830a6aea24783bd245c553aa7fd2f4c0e5d8a035f6a999adb36e18db154c1092f04c7ef0181aa45e2824b8efb39d2527f202f530d17b02608d536a16c2535a507dc4de220efaec6e43c68d277bc5ba07d4912e251edd121401921ea74427108a0bfd3578392f7594236e1f12733ea3f94e6a2c264306c14d85e1f6cbd2f801ccf8d1dfdbed58f4028ff7038571b885f24855b911226d95b7be25c061effe52c0772b7b22f9ee3e4f61462f4beb807b51ed547dc294cf82a800829c0feaf851cfc2780ff3df6b23426a0a31b69f92f40083946ed16f1e99f71cb9e2e16cc381ce807159cfb5351ff017ddc137d4713c4410c07a36aa142846e11ecf26929bdc4dd3cdd02a03a5daf6aaa47c9d5813a02126073d5f27aa82a4b19e11d5b22c040b5f236611580a7d0065bcd2f430c8cdc98d1e548108d34943a9a80888800b3bdfc99652ada3aee38fb3c63c16348a83b79afe9e9264b0ba4fef9a1e444ca5f1de061cb18426a3db46018d0a203a8736d201ec76fc48ada0e4542477a391f50011a758268d557f38a708b67a5576c7727787e17a694158fbf2aca46620cb279983b1a5118d705fefb6079214c67abeb4874a52fef90680a09968397a01e23dc713043d07ca0a6c5b6a7c66a22197ade75c144af18212e18892451b05ccf90b2a564286befdb1d02cc7131ad641e6c166554054a0513d0b25c312e1b2acb2c2becf7b9f39ce6322a4b6bb9aab9b21e536295816892c3be2213818ae1a0339193acfa51df79a9c0aa499d9886b5243076fd2b06170425d6b1040fbf088a20d4051351355b2848294e63611435480c55439bb01a19bd5ecd0d1f0be0312e54cd883b2b02b1082ec9d2cb8b264490aa60b79c9601bd0b0af628e5ba9413d8a2875c6aa8a8c9c1490c1381996659a4518742418a6d8954d05075da07238390a73039cf15167b863d8392e80fd022171318d17cdff3d78dcc22a18832e81a4f4438926bb66ef96a7dcc2c396ba961108dee98fd05091c4d196a0405c7ef538083b399a6a96d8c7b3c73b0d514c28746ca64d0b3699a8529248ad1722b249573d047a9786cb5cc183b3272e13b2062705dba6252a6a2a3b33e417deaee51564c665a8856b4f6b1b6018e8332799b5071648946f12f457fc3498d56dd9dbc31131b9eea89dfaab6c6a8be340c8f25881b340e05de8212be80447d57352766c64ec5527a9983f7921fa8f74974813575fb8ada5c5229f4ec88976a42cfdd12852ecba179ce4a2bc77e8352d99ba64f8397d197a02aa1aeeb698c09e88bb5feaa58a791ee37739ec6a8bb3215d0b90593008280a451702130ff1a991dd129fec206459669f23eb17710a94a2abb132b7e6416ad46a57636ffa99b1bee6a202eeedbdd191845a177da18346d215ba5d700b1ea14ce26c174000054491a8002fb6b51524be2a7aca6a65644b0b21feb3fc58a99564213277be7fa8e0860c7812d9e1387990a960bc092ed210cbdee28391e41f8e4b32a68d45562b8aa6f18246079f58b76579106e98fe5be281c0093d49627b96249781dc6d9b2db024f427e7c077168a71727a2d3879fa176a3c79afb6e53ce485fd9210e51fbccacb62ecf411ddfa9ba14a0c9867964978aee510d811f079e673ecc440b21580f24299c9e1729e64e2c1fe474e041fc54f95a93808a2129e59e4f42492484bd386b359ad92c063bf9622ff2d0233f0d117a9e0e3f50d06b34fb3f634bfc33bd723bbebc21750d37139eba63d31524bae1160145340bcef3f243270d01b1ab3b646853ed9cf15b9f352860f3c3fb90cd2d2dec5ff2cc1c8c1639bf4be3cf5eb98a63b53190608a1b80f2eb7903f529cb07ce1230bd136c1a2d40a393ee91075847e8c98ffbebdc6063a4edd8be2553dfe943b559f04e3e921512f5705cf2f24f211080f9ce9a642bc193af5e02a47662797b0ed1686ffe173c42d137847c38f15ac3f5c7a2e082035bfa3499d4782642ea4fc44f1a11be1307dd835478b97cfcad231fae3ec655707bd39e61cf097061fb74c424aaac6f6ba206c75b07308880370d7b9a2aebf0ccd520c1c642d06d71e99d41e1b40cb830349f45b7bba3824ba545656d92482814a678e512e7c26b4745a2eaf66552cf31127b1d4882507a6b6f73c8dc725bb7e31b90b1b5ee9964df8f28ff0969c5bd67ed87a734e3478402c5ddc1ff1aa402291db31034e7f475a53892792d054084fcd913d890c6357755b74931173f09ace6475b937be8ffadabca6956ad02e6218be9a287c0e21d11da0e27010b82cf00206a111a31d0fc621e6d2234841595ff7d1c53c13b96e131c7a9bb256388a98decc3687e39e841556c79d2719a4d0d81b3a8965f3a529538b5b39a966ac374da3262dd5b868ce00326236ea10ce5482856813527db59f51e191a9273f24afc7b12dd847ed082907805b4ed2ade98922c0f7c66a62509d00067237676cf96b0813d89f920acb3f885274e6afeace4e893dc9e0a86a130a5d7004536043ae4c33a7b76ed62f3237598fd59a8898913a7a4ce5e4074b43f066f5a7c20875f7a097de408d6f09855d3c3cc24ec1edd83defc973f8ca376682191de86b8354d570e6edfcc7694651bbb94febaf056e25c72ecfac104fb412c48ade12d79058efeae386e71c6f0cfa0802f020c67bc4fcaabba10d9eda641c0c456dbf6e0e18ba1123641d31fa7cfdbbad0b0f1e0722417e9d4877fe0654ab1538d065030146ce1f3ca3b227460546485943c144e7b63c9b0875eea9cda66226ce4b1de6063a37f45a2327eafe5476f21472a64dd647f4bfb71e724a21de027b8096992850075091722c50ec23845b2ab390198b28ee64c906af530e12108b4656fd237629459f03da108c34e6222ed74f51b280992f622588a381bb4003efe1f899119f9b7dd202ef81dac419740b7599e2c9ee732822709977f69a4adb91c7abc3bff9cc686d0d7c8fe13548e6b01028ec04c3660c28db39946f493b89d7e5f681b8213aeaea89ae3e1def114c5580ba073f205b21e0e85b41402842ac91d89af616a09ca22edbae0812f60b2516eb053e400fa4dbe63fd34c98d478a4a1f434f8b30a665708d4c12d458605ac1b2babafd3899e5a048312c5ab9f3d7f43331f4bb25f198629702af2ea9b19206eeb6bc5a93f28b8128720c6c1f55a3e594d5cb33e196b418d46de3300c157c7f24a13ea13a7dc12d181c5e83c109acffbd232dc6a449730018b47edfee3850d0773339f41d2f50c06066a7c544834e8397febf22c1f644be9fd930faa93eaab9684d6e50aaa141951ec632ec254e72245cf9fa45c31cf1284bdabcf2acfdd04d1885918b6bcce50f5e599d993655ed433d841a9e31a44dd354c31c1f7805ad44079085f5e8a4f2a3a576cacd61f1609d01bdc7ecdab2a0f084719c37a4f6a6362fa6e311a943384ecb4cf93a5aa6009be40d83dd4dbfd9a02eba28c75480e32616b4ebb70ca2b219d3ba25eb3e72beb3e09120e3c1d8188bbef0d31a074cc672aa0a53fde59351df76571e389cb359e94f9f216547f82d204bcb8feb6c3de07c0fc9ed8a27b77df0684be2010a605ad0a27a6f5fe8ef23706bf9076b370fc3864f3ee053dab13e26fa44ad3049980a9ef58b0797e6623704a8a2eb6e217b00f05324a4ecc3f832319d15e1fe5f4f43cf0db54dd0a045ed3e70dbb0fb156f8727a60a187647844b25b981d05ec55a723104ec1c23ac5a62816bbcba99220e49cd114cd57258ba1fa71fa612517cc90fc2c0f2e8d87b84fe296625998e6aeaf864eb0bb10670d5cdbbbd9684538d5fcda1d9df41a1e12c570e4a774763e0e9d511ef0a20e71828476b03db2ef6db3c5c50d2e464c50e749f84aa4b2369cdbd315f675310a1c8202f511066e90d8bcea5a16b96ffc43a6d605439f8781b37819de677c96a01fb6957c2bc11273474695dac888ff6d09118efe125e950489e2be312da0bcd999726149f3cf15284f68063ec0bfe3a0b2cb7edf18a71f4b80bf733404ace30c92384a08dd8782226f91c219a7be5376afe76e793b4de4944f2942c225a55a35721be880b84e72253d309a10b4dd380c48e599cebfabb1c185aa63562ece4325558c1884ce4897041f47092b0df29129136e4a0285f830e385ad15d9710ffbc0c4256c0454487c5680f2853856caf2d822d81ec5b1b4c22cc18015861d8aa768e81a22489b9d17a060b95cb3d18167252125431932a80e5fd392798ce55750ffcc3964501919f813c6e1cebc2043709ea8570f04344a4fa2e69bcc64410400cbc5794efeab6215ec4f0e923376c021540467da5efb41daab987ec1ca1012c8e62d5c7b954f90e32e3acc99dc5f24322f5d93be462eb72cdade889c8b4e6bfaac5d66ebd547fa43af4c9121195572fba48556a6b7d6a4f0ddd10cf77d87d935482dbba4ec6ccc0b7f97a0521c83d6bf949621a2d32211b4b71a3c0c9c62814461bedc89038a34b500b4453b6c3ba7b6077882c5f850afdb189212a10a74a2815e44803949b1577510c064c5d110ca128aeca7a884bc6a12aa0c1e1de2d5eba1a913376de8dca58ac1b284c6315e9f4ebd3c5a7217ce849e34ad4a4d1bcc7809d5531c9d5f6d09f4752488e107a041c056e119728c1f450ba2f4d52d8af911f181735e57fe0dc45e8d8e7d091b2bc05c92025b967d46479319c3d9b6772e1c484b69e0ab5019a8f86c09091b5ae6bf85b72e728c1fc756d6c364d27704159021b9da665d1f53713eb9eb67ce8f165a3c6d04ebf8c6d28ea1f7bbdd508cdff1c8380303fb0be9281ccb77ad084a216242eabcb1b064456537405a7e330b1815353d544f6353e1b3acb869dc11989fe474c609c98fa08eb1c71d3b545e8837d4035e6316dc44d06c3fd717ee872e010e41b674c621b4a85a5ee504d0a83975c3453d28d8c0f0d7e0ca65a368d6cbdbf06da3aeaf9e70a268e7a010c8ce8a782f792982f00345e00e43ff74cf5ff77716bfec3d3e0ba0071e3cfc447f0651315191beb78c64a860bea6c207e283a127315cc2f238c52a80c928a41a81496d1e7c9bc5998f723a384cdd83a401b98766ba3fdb7c50c05a04da448f4bb5ca9055aadd6fd0cc6f08a73ef5562ce8cca20be347f5641b6843b04d7cd0bbb165f2130410b7bdc6902108dd9bd9c4e19813bf0cadb0a358702f87fadcac8ee904641ca67af9bd8a39c13b48ef31a2f014f1ef4fe7071cfa74298f9397f148f6567eb86b49c6e8f69ce06e72fd2a70b143e4d47ad9e5ca91807bf876d2007ca1efd6fbb4fd280b77a63b48a8dc6c40a19b2c5eb315d88ca50eb52ef870f0e3d5caba6a6c8e7b040d3418fb18df3bd546e002fe50a778bdd3ab164f4966f0e571c40d01a9ff490fa21ea481b3e45f0ff88b8fae7568dd196bd34edb64d938458bf3fec0d38cb182a85120bc41687a63e5768dbfe0041b1cababe1fe3da48241a6415b01c4b6e0f87624a0f5f767136ea4d84bdd4ed4e0d8dd6877e2890a18fe0d52fbdb99d82f2042ac5ad35378e426d6ca261d19fa4128a909de414bddc200f18c4bcd3545df7daac5bffabf4c2262b6d296f94906ef6a209c43861366270220bcb8d4ba2d9701f7264ecaa03aa8742a99306b4bf0aa38d1cb29a0a09f6b6ffbc29bfa0c882df5f521d6808b9088a23028542667700271b256f4787ff4b96b4fbfc4daefa17c3d0cc569dcdd414c5af3e40f23da66a8b5a9556cb0811338855510754672df0e1574c07028ace29e8dbc4eaeb1a1b02dbaba7006e985e14a9c0302e17907553064759146e2e32b8102ac652ff79073bad19ca780d7e7033b1459a0b90a4a7a8920872f02f89f4c68c4678e3dd6c72c9e2d0421a94b8d3027c08b79731e13f3db1512dfc4dcf92b6d67f169f8f0407f31225146753541dfea8013cbcc0158d3525e6e992ce95b7cb98ae28ea7de8d4af6745a89a02540f74792d3ee3e79a9a8e3d9713d595f2bb9d940a88362350a7a4937c4f91b1da21e12e6bc8e1707074720a043a07adc1b9bc05eddd9fd42efac6f2bea9c3280cc1dac049044312b76cf1ed20fd694b1940fe028a7a8466aad463b802c00377467c77baacd0c8a40ac9df750a698cbbd0e5bede8428c488b614cfed40c137398cba3b93a37ab1d2ece639eabc615d34786b688c8ff55f3f8f08c862c4d995e33f47a3d2bc962749030f700d7f193c4a8c24879bdea3c4b460b35e5df813c62a481c8612ec8e43d0d665fac3bcc6775e421241d5c6e7cdef7bb768ba69540d9346c5350bc5a02092a0d9a7ffa68452e2087fd2525322cfe6870495a5004c972941b6761efebc2d635413955373a522ddfce9bbb920160996d9d0b73ea64d6e08fb8ec6da0f4bd013096aa30d294e81f109aad163dde98a5237754eb74e32955e45d3cdb55bdd6eb4091b1d1f9dee6a59a2ff58d07fbb9cc9b39ef4dc2a0c4910b1abb0db93308c71566767d8295a5b46cbb19b3b5ebad1ad077ac5a320825beb8b98714b3df93c9e4acdefd8cbdb512e42b4d45a7c73c706f0639ec21e74550055295bd444abb87388c8b6b28f6fb4cbfd46a623dab2250596cfa7478369acf7ce5661f4817eaa41f4186cea3f85394b8a67b990be62aabae005c008692b236b09378ea313bd3f39b0271f1c0d8e00d9afa2e1cc176de734e0a144e41f5f047430ab2de4549a3e8bff69afb002b420460dbcf19340f62f18a8876c26819c68ef59909d20dcfe0d1ce5a56117048841e4ac794667380688a2e7e9a3836842838d8c11cb8466c7fc9e617993f46031e9c722ccb4fa7e31aff4d8cce6c133a733010da67fc792c8ddefb00f0e8d219963a152d34b7fda95eb2c6054204a42a4836a73b1bf4fbd8d6a1e8dec28035f4abcd435266a329cd99cfa50816a0611095b7895c93ec3337ee7f60e5ed42217a3962f719ad105ab96ad046af0e8dad3625f96df4f9bb199a627c6414b9960629521c72caf808349b6688767819431a13ed830caa883e8cf1f0c22d6b51bd712136b11f1fbf0de8b61c3c58d638dc36196ad061779596bfaf1bd016dc32c7d7c713378822eee0a25b0ba37844351ce6934c2d8a2c7d5c044ed246adf07eb6b8c8e937be9cb5eea6ff5cc4afe8ed208220e2e47ce70f33d1800cf433834a84634f3cb8915cc88e14aa7f449b92e177ee1ca90847da8d850a371f6accccb09dd95c671a121e5b5190b55f4aabc8ca3f6a4b97716ba3a9980bea418bd1422a010ccf2c4f95d8afe9dd9e776d7dd7577527ef5bbefd2e7e76f99d880963e6a60d77b2a075f86e80b26552e665b47c495dc62c72d20cf41593cff74854893a1f06c93828f5a726bc0bd93d1fb0c8a81bd6c4ff5bd7a816db0100cc7a149b54e7cc18543f3559d5e4ebe6cf7bf69fe39f3f68c8ba7168f94ea6666c5b8529b7a4d82d5cd43f92d8a49cb62ffe37bf6a4cd0c175ae909c99bcfabd96bc62b8bd79fa7dd83d05bbca7138fecec2d94772fda2f087cef80a2bdc10ebcb233fe410c05872a453379924a83dec583425ab799c23c9363d014c907ee6bd12964096a3c4b2f5cf234c3916355e578f99a50c8036337c510152225763bc1435fd74281c5902fc0b5b1c6c367b4f381d012d3bf7c81fa435a23939f7cc1f8c9a8d9292b719e08f18754d44a06ccd34640aad2d8a3d19a53da410cdcc0bd7fd2810da5a167bf0755cf40f86a0eb2480bd259ba2c3721636a219103b912058f0127fa60ef19420589b28260d9f8dae09c9ae9050fe6596e390f9a2b0104908d82f9ffce0fb8f1854c068f7ccd3c4f95dd21bd23e33a4ce7eebf8b3d5315623478a4b1d548b5c526a3ea7393ac0f4558d3da3808832312943ea7761c09a57725e57ebfb1cf628f3e300ef362cb3c69f5d29c512bcd46bb0b3499750ab85863c22b983327991920fd2075593092d3af384f006a42dc722a74d488636563b392f12b9419c4730b6883d8147f91162c125b49ce966d2db0064189ef4e94c8367a0f23a7cba39ebcda86e8564cd9bddc454beb9157d2c8984fda42aca9880658c860d8ecf20dd3fa6894642b86744d0ad259f8204646df50b08d904f85527c812078c7b9a0fe5b7c41f3c2d3081eb8f6b1774e0da71dcb5cd4b660295ea750258fb15db4b9a1779b17caba3f58af683e24c34ed131f99c1160c5eae5c66994ec38d0f6ebe5af524c4a20357eb61cea0d3538a5c78707a3d065d6164903632c831b6ec18d84f2d7109daa0bdc79e64e1fc1ef046556de2d27ebbf76f16ad73456d4245990fd208948254390ca88d5a01b5a2091cc6a7758c6b41a52ef0b7e87b17f97d4a1d69844de16c0583adcd11a327e7e2963990d711de0ffbbba94bd003a7d2d599438a121926bc517c411024092ef48c216493de957bc9d05d345bcf76265e22de95a759303d0915c2bbb5ae0f9ebe87a043d195bf1d6040d2ada553703c3b229142c16821ad50871a68a83438a02ff1d04af13c24e3a0378dc41835b206453dbcd576d2215784062ff6462ac3cf31e13f61e42085feeaa855ad60329bb73d6bd70108518dc46d9bc3e12a990210004267d8cf25d13a1bca0aedc603a356f58cde0d2ce2cb155d75d582d2057ceba20c699c0241739fc4866befbe56c17eba78e81c98c7aac44266013fc59367489514d58cc2237ef7a2194ef535a2bf0ad00cc6375cc01ccac1910c8abf353f92302fa3a7239c2f41a90aa2d26b05b6f466ea685594caf864c249f2e6eef29aa4d73854d12d4570a7fb5d6a7bfaaf9628c232b3beaafa99bf46a8e130c41515f73655cecb84db7732372ea37a1d43d15ad02",
      "patch": {
        "balances": {
          "balances": [
            [
              "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
              1125899906842624
            ],
            [
              "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
              1125899906842624
            ],
            [
              "5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY",
              1125899906842624
            ],
            [
              "5HpG9w8EBLe5XCrbczpwq5TSXvedjrBGCwqxK1iQ7qUsSWFc",
              1125899906842624
            ]
          ]
        },
        "keccakDifficultyAdjustment": {
          "initialDifficulty": [
            0,
            9,
            61,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
          ]
        },
        "md5DifficultyAdjustment": {
          "initialDifficulty": [
            0,
            9,
            61,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
          ]
        },
        "sha3DifficultyAdjustment": {
          "initialDifficulty": [
            0,
            9,
            61,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
          ]
        },
        "utxo": {
          "genesisUtxos": [
            [
              1125899906842624,
              "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"
            ],
            [
              1125899906842624,
              "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48"
            ],
            [
              1125899906842624,
              "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f"
            ],
            [
              1125899906842624,
              "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e"
            ]
          ]
        }
      }
    }
  }
}
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..57ce217
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,35 @@
+root = true
+[*]
+indent_style=tab
+indent_size=tab
+tab_width=4
+end_of_line=lf
+charset=utf-8
+trim_trailing_whitespace=true
+max_line_length=100
+insert_final_newline=true
+
+[*.yml]
+indent_style=space
+indent_size=2
+tab_width=8
+end_of_line=lf
+
+[*.sh]
+indent_style=space
+indent_size=2
+tab_width=8
+end_of_line=lf
+
+[*.js]
+indent_style=space
+indent_size=4
+
+
+[*.jsx]
+indent_style=space
+indent_size=4
+
+[Dockerfile]
+indent_style=space
+indent_size=2
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ab80259
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+**/*.rs.bk
+**/target/
+addresses.json
+
+validators
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..6d62aa5
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,10605 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "Inflector"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
+dependencies = [
+ "lazy_static",
+ "regex",
+]
+
+[[package]]
+name = "academy-pow"
+version = "3.0.0"
+dependencies = [
+ "academy-pow-runtime",
+ "clap",
+ "futures",
+ "hex",
+ "jsonrpsee",
+ "log",
+ "multi-pow",
+ "pallet-transaction-payment-rpc",
+ "parity-scale-codec",
+ "rand",
+ "sc-basic-authorship",
+ "sc-chain-spec",
+ "sc-cli",
+ "sc-client-api",
+ "sc-consensus",
+ "sc-consensus-manual-seal",
+ "sc-consensus-pow",
+ "sc-executor",
+ "sc-network",
+ "sc-rpc-api",
+ "sc-service",
+ "sc-telemetry",
+ "sc-transaction-pool",
+ "sc-transaction-pool-api",
+ "serde",
+ "serde_json",
+ "sha3",
+ "sp-api",
+ "sp-block-builder",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-consensus-pow",
+ "sp-core",
+ "sp-inherents",
+ "sp-io",
+ "sp-keyring",
+ "sp-runtime",
+ "sp-timestamp",
+ "sp-transaction-pool",
+ "substrate-build-script-utils",
+ "substrate-frame-rpc-system",
+]
+
+[[package]]
+name = "academy-pow-runtime"
+version = "3.0.0"
+dependencies = [
+ "async-trait",
+ "frame-executive",
+ "frame-support",
+ "frame-system",
+ "frame-system-rpc-runtime-api",
+ "hex-literal",
+ "log",
+ "multi-pow",
+ "pallet-balances",
+ "pallet-timestamp",
+ "pallet-transaction-payment",
+ "pallet-transaction-payment-rpc-runtime-api",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-api",
+ "sp-block-builder",
+ "sp-consensus-pow",
+ "sp-core",
+ "sp-genesis-builder",
+ "sp-inherents",
+ "sp-io",
+ "sp-keystore",
+ "sp-offchain",
+ "sp-runtime",
+ "sp-session",
+ "sp-std",
+ "sp-transaction-pool",
+ "sp-version",
+ "substrate-wasm-builder",
+]
+
+[[package]]
+name = "addr2line"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
+dependencies = [
+ "gimli 0.27.3",
+]
+
+[[package]]
+name = "addr2line"
+version = "0.24.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
+dependencies = [
+ "gimli 0.31.1",
+]
+
+[[package]]
+name = "adler2"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
+
+[[package]]
+name = "aead"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
+dependencies = [
+ "crypto-common",
+ "generic-array 0.14.7",
+]
+
+[[package]]
+name = "aes"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
+dependencies = [
+ "cfg-if",
+ "cipher 0.4.4",
+ "cpufeatures",
+]
+
+[[package]]
+name = "aes-gcm"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
+dependencies = [
+ "aead",
+ "aes",
+ "cipher 0.4.4",
+ "ctr",
+ "ghash",
+ "subtle 2.6.1",
+]
+
+[[package]]
+name = "ahash"
+version = "0.8.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
+dependencies = [
+ "cfg-if",
+ "getrandom",
+ "once_cell",
+ "version_check",
+ "zerocopy",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "allocator-api2"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
+
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "ansi_term"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "anstream"
+version = "0.6.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
+dependencies = [
+ "anstyle",
+ "once_cell",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+
+[[package]]
+name = "approx"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "aquamarine"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21cc1548309245035eb18aa7f0967da6bc65587005170c56e6ef2788a4cf3f4e"
+dependencies = [
+ "include_dir",
+ "itertools 0.10.5",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "ark-bls12-377"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb00293ba84f51ce3bd026bd0de55899c4e68f0a39a5728cebae3a73ffdc0a4f"
+dependencies = [
+ "ark-ec",
+ "ark-ff",
+ "ark-std",
+]
+
+[[package]]
+name = "ark-bls12-381"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488"
+dependencies = [
+ "ark-ec",
+ "ark-ff",
+ "ark-serialize",
+ "ark-std",
+]
+
+[[package]]
+name = "ark-ec"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba"
+dependencies = [
+ "ark-ff",
+ "ark-poly",
+ "ark-serialize",
+ "ark-std",
+ "derivative",
+ "hashbrown 0.13.2",
+ "itertools 0.10.5",
+ "num-traits",
+ "zeroize",
+]
+
+[[package]]
+name = "ark-ff"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba"
+dependencies = [
+ "ark-ff-asm",
+ "ark-ff-macros",
+ "ark-serialize",
+ "ark-std",
+ "derivative",
+ "digest 0.10.7",
+ "itertools 0.10.5",
+ "num-bigint",
+ "num-traits",
+ "paste",
+ "rustc_version",
+ "zeroize",
+]
+
+[[package]]
+name = "ark-ff-asm"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348"
+dependencies = [
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "ark-ff-macros"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565"
+dependencies = [
+ "num-bigint",
+ "num-traits",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "ark-poly"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf"
+dependencies = [
+ "ark-ff",
+ "ark-serialize",
+ "ark-std",
+ "derivative",
+ "hashbrown 0.13.2",
+]
+
+[[package]]
+name = "ark-serialize"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5"
+dependencies = [
+ "ark-serialize-derive",
+ "ark-std",
+ "digest 0.10.7",
+ "num-bigint",
+]
+
+[[package]]
+name = "ark-serialize-derive"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "ark-std"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185"
+dependencies = [
+ "num-traits",
+ "rand",
+]
+
+[[package]]
+name = "array-bytes"
+version = "6.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d5dde061bd34119e902bbb2d9b90c5692635cf59fb91d582c2b68043f1b8293"
+
+[[package]]
+name = "arrayref"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
+
+[[package]]
+name = "arrayvec"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
+
+[[package]]
+name = "asn1-rs"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0"
+dependencies = [
+ "asn1-rs-derive 0.4.0",
+ "asn1-rs-impl 0.1.0",
+ "displaydoc",
+ "nom",
+ "num-traits",
+ "rusticata-macros",
+ "thiserror",
+ "time",
+]
+
+[[package]]
+name = "asn1-rs"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048"
+dependencies = [
+ "asn1-rs-derive 0.5.1",
+ "asn1-rs-impl 0.2.0",
+ "displaydoc",
+ "nom",
+ "num-traits",
+ "rusticata-macros",
+ "thiserror",
+ "time",
+]
+
+[[package]]
+name = "asn1-rs-derive"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "synstructure 0.12.6",
+]
+
+[[package]]
+name = "asn1-rs-derive"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+ "synstructure 0.13.1",
+]
+
+[[package]]
+name = "asn1-rs-impl"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "asn1-rs-impl"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "assert_matches"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9"
+
+[[package]]
+name = "async-channel"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
+dependencies = [
+ "concurrent-queue",
+ "event-listener 2.5.3",
+ "futures-core",
+]
+
+[[package]]
+name = "async-io"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059"
+dependencies = [
+ "async-lock",
+ "cfg-if",
+ "concurrent-queue",
+ "futures-io",
+ "futures-lite",
+ "parking",
+ "polling",
+ "rustix 0.38.43",
+ "slab",
+ "tracing",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "async-lock"
+version = "3.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
+dependencies = [
+ "event-listener 5.4.0",
+ "event-listener-strategy",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-trait"
+version = "0.1.85"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "asynchronous-codec"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568"
+dependencies = [
+ "bytes",
+ "futures-sink",
+ "futures-util",
+ "memchr",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "atomic-waker"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
+
+[[package]]
+name = "attohttpc"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2"
+dependencies = [
+ "http 0.2.12",
+ "log",
+ "url",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+
+[[package]]
+name = "backtrace"
+version = "0.3.74"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
+dependencies = [
+ "addr2line 0.24.2",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object 0.36.7",
+ "rustc-demangle",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "base-x"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
+
+[[package]]
+name = "base16ct"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "base64"
+version = "0.21.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
+
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
+[[package]]
+name = "base64ct"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
+
+[[package]]
+name = "beef"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "bincode"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "bitcoin-internals"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb"
+
+[[package]]
+name = "bitcoin_hashes"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b"
+dependencies = [
+ "bitcoin-internals",
+ "hex-conservative",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
+
+[[package]]
+name = "bitvec"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
+dependencies = [
+ "funty",
+ "radium",
+ "tap",
+ "wyz",
+]
+
+[[package]]
+name = "blake2"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330"
+dependencies = [
+ "byte-tools",
+ "crypto-mac 0.7.0",
+ "digest 0.8.1",
+ "opaque-debug 0.2.3",
+]
+
+[[package]]
+name = "blake2"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
+dependencies = [
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "blake2b_simd"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780"
+dependencies = [
+ "arrayref",
+ "arrayvec",
+ "constant_time_eq",
+]
+
+[[package]]
+name = "blake2s_simd"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae"
+dependencies = [
+ "arrayref",
+ "arrayvec",
+ "constant_time_eq",
+]
+
+[[package]]
+name = "blake3"
+version = "1.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e"
+dependencies = [
+ "arrayref",
+ "arrayvec",
+ "cc",
+ "cfg-if",
+ "constant_time_eq",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "generic-array 0.14.7",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array 0.14.7",
+]
+
+[[package]]
+name = "bounded-collections"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d077619e9c237a5d1875166f5e8033e8f6bff0c96f8caf81e1c2d7738c431bf"
+dependencies = [
+ "log",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+]
+
+[[package]]
+name = "bs58"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
+
+[[package]]
+name = "bs58"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "build-helper"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdce191bf3fa4995ce948c8c83b4640a1745457a149e73c6db75b4ffe36aad5f"
+dependencies = [
+ "semver 0.6.0",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+
+[[package]]
+name = "byte-slice-cast"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c"
+
+[[package]]
+name = "byte-tools"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
+
+[[package]]
+name = "bytemuck"
+version = "1.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "bytes"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
+
+[[package]]
+name = "c2-chacha"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d27dae93fe7b1e0424dc57179ac396908c26b035a87234809f5c4dfd1b47dc80"
+dependencies = [
+ "cipher 0.2.5",
+ "ppv-lite86",
+]
+
+[[package]]
+name = "camino"
+version = "1.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "cargo-platform"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "cargo_metadata"
+version = "0.15.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a"
+dependencies = [
+ "camino",
+ "cargo-platform",
+ "semver 1.0.24",
+ "serde",
+ "serde_json",
+ "thiserror",
+]
+
+[[package]]
+name = "cc"
+version = "1.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b"
+dependencies = [
+ "jobserver",
+ "libc",
+ "shlex",
+]
+
+[[package]]
+name = "cfg-expr"
+version = "0.15.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
+dependencies = [
+ "smallvec",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "cfg_aliases"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
+
+[[package]]
+name = "chacha"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862"
+dependencies = [
+ "byteorder",
+ "keystream",
+]
+
+[[package]]
+name = "chacha20"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
+dependencies = [
+ "cfg-if",
+ "cipher 0.4.4",
+ "cpufeatures",
+]
+
+[[package]]
+name = "chacha20poly1305"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
+dependencies = [
+ "aead",
+ "chacha20",
+ "cipher 0.4.4",
+ "poly1305",
+ "zeroize",
+]
+
+[[package]]
+name = "chrono"
+version = "0.4.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
+dependencies = [
+ "android-tzdata",
+ "iana-time-zone",
+ "js-sys",
+ "num-traits",
+ "wasm-bindgen",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "cid"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9b68e3193982cd54187d71afdb2a271ad4cf8af157858e9cb911b91321de143"
+dependencies = [
+ "core2",
+ "multibase",
+ "multihash 0.17.0",
+ "serde",
+ "unsigned-varint 0.7.2",
+]
+
+[[package]]
+name = "cid"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd94671561e36e4e7de75f753f577edafb0e7c05d6e4547229fdf7938fbcd2c3"
+dependencies = [
+ "core2",
+ "multibase",
+ "multihash 0.18.1",
+ "serde",
+ "unsigned-varint 0.7.2",
+]
+
+[[package]]
+name = "cipher"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801"
+dependencies = [
+ "generic-array 0.14.7",
+]
+
+[[package]]
+name = "cipher"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
+dependencies = [
+ "crypto-common",
+ "inout",
+ "zeroize",
+]
+
+[[package]]
+name = "clap"
+version = "4.5.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.5.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+ "terminal_size",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.5.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
+dependencies = [
+ "heck 0.5.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
+
+[[package]]
+name = "codespan-reporting"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
+dependencies = [
+ "termcolor",
+ "unicode-width 0.1.14",
+]
+
+[[package]]
+name = "colorchoice"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
+
+[[package]]
+name = "combine"
+version = "4.6.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
+dependencies = [
+ "bytes",
+ "memchr",
+]
+
+[[package]]
+name = "common-path"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101"
+
+[[package]]
+name = "concurrent-queue"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "console"
+version = "0.15.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b"
+dependencies = [
+ "encode_unicode",
+ "libc",
+ "once_cell",
+ "unicode-width 0.2.0",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "const-oid"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
+
+[[package]]
+name = "const-random"
+version = "0.1.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
+dependencies = [
+ "const-random-macro",
+]
+
+[[package]]
+name = "const-random-macro"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
+dependencies = [
+ "getrandom",
+ "once_cell",
+ "tiny-keccak",
+]
+
+[[package]]
+name = "constant_time_eq"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
+
+[[package]]
+name = "constcat"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd7e35aee659887cbfb97aaf227ac12cad1a9d7c71e55ff3376839ed4e282d08"
+
+[[package]]
+name = "convert_case"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+
+[[package]]
+name = "core-foundation"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
+
+[[package]]
+name = "core2"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "cpp_demangle"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eeaa953eaad386a53111e47172c2fedba671e5684c8dd601a5f474f4f118710f"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "cranelift-bforest"
+version = "0.95.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1277fbfa94bc82c8ec4af2ded3e639d49ca5f7f3c7eeab2c66accd135ece4e70"
+dependencies = [
+ "cranelift-entity",
+]
+
+[[package]]
+name = "cranelift-codegen"
+version = "0.95.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6e8c31ad3b2270e9aeec38723888fe1b0ace3bea2b06b3f749ccf46661d3220"
+dependencies = [
+ "bumpalo",
+ "cranelift-bforest",
+ "cranelift-codegen-meta",
+ "cranelift-codegen-shared",
+ "cranelift-entity",
+ "cranelift-isle",
+ "gimli 0.27.3",
+ "hashbrown 0.13.2",
+ "log",
+ "regalloc2 0.6.1",
+ "smallvec",
+ "target-lexicon",
+]
+
+[[package]]
+name = "cranelift-codegen-meta"
+version = "0.95.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8ac5ac30d62b2d66f12651f6b606dbdfd9c2cfd0908de6b387560a277c5c9da"
+dependencies = [
+ "cranelift-codegen-shared",
+]
+
+[[package]]
+name = "cranelift-codegen-shared"
+version = "0.95.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd82b8b376247834b59ed9bdc0ddeb50f517452827d4a11bccf5937b213748b8"
+
+[[package]]
+name = "cranelift-entity"
+version = "0.95.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "40099d38061b37e505e63f89bab52199037a72b931ad4868d9089ff7268660b0"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "cranelift-frontend"
+version = "0.95.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64a25d9d0a0ae3079c463c34115ec59507b4707175454f0eee0891e83e30e82d"
+dependencies = [
+ "cranelift-codegen",
+ "log",
+ "smallvec",
+ "target-lexicon",
+]
+
+[[package]]
+name = "cranelift-isle"
+version = "0.95.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80de6a7d0486e4acbd5f9f87ec49912bf4c8fb6aea00087b989685460d4469ba"
+
+[[package]]
+name = "cranelift-native"
+version = "0.95.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb6b03e0e03801c4b3fd8ce0758a94750c07a44e7944cc0ffbf0d3f2e7c79b00"
+dependencies = [
+ "cranelift-codegen",
+ "libc",
+ "target-lexicon",
+]
+
+[[package]]
+name = "cranelift-wasm"
+version = "0.95.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff3220489a3d928ad91e59dd7aeaa8b3de18afb554a6211213673a71c90737ac"
+dependencies = [
+ "cranelift-codegen",
+ "cranelift-entity",
+ "cranelift-frontend",
+ "itertools 0.10.5",
+ "log",
+ "smallvec",
+ "wasmparser",
+ "wasmtime-types",
+]
+
+[[package]]
+name = "crc"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
+dependencies = [
+ "crc-catalog",
+]
+
+[[package]]
+name = "crc-catalog"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
+
+[[package]]
+name = "crc32fast"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
+
+[[package]]
+name = "crunchy"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
+
+[[package]]
+name = "crypto-bigint"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
+dependencies = [
+ "generic-array 0.14.7",
+ "rand_core",
+ "subtle 2.6.1",
+ "zeroize",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array 0.14.7",
+ "rand_core",
+ "typenum",
+]
+
+[[package]]
+name = "crypto-mac"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
+dependencies = [
+ "generic-array 0.12.4",
+ "subtle 1.0.0",
+]
+
+[[package]]
+name = "crypto-mac"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab"
+dependencies = [
+ "generic-array 0.14.7",
+ "subtle 2.6.1",
+]
+
+[[package]]
+name = "ctr"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
+dependencies = [
+ "cipher 0.4.4",
+]
+
+[[package]]
+name = "curve25519-dalek"
+version = "4.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "curve25519-dalek-derive",
+ "digest 0.10.7",
+ "fiat-crypto",
+ "rustc_version",
+ "subtle 2.6.1",
+ "zeroize",
+]
+
+[[package]]
+name = "curve25519-dalek-derive"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "cxx"
+version = "1.0.136"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad7c7515609502d316ab9a24f67dc045132d93bfd3f00713389e90d9898bf30d"
+dependencies = [
+ "cc",
+ "cxxbridge-cmd",
+ "cxxbridge-flags",
+ "cxxbridge-macro",
+ "foldhash",
+ "link-cplusplus",
+]
+
+[[package]]
+name = "cxx-build"
+version = "1.0.136"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8bfd16fca6fd420aebbd80d643c201ee4692114a0de208b790b9cd02ceae65fb"
+dependencies = [
+ "cc",
+ "codespan-reporting",
+ "proc-macro2",
+ "quote",
+ "scratch",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "cxxbridge-cmd"
+version = "1.0.136"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c33fd49f5d956a1b7ee5f7a9768d58580c6752838d92e39d0d56439efdedc35"
+dependencies = [
+ "clap",
+ "codespan-reporting",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "cxxbridge-flags"
+version = "1.0.136"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be0f1077278fac36299cce8446effd19fe93a95eedb10d39265f3bf67b3036c9"
+
+[[package]]
+name = "cxxbridge-macro"
+version = "1.0.136"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3da7e4d6e74af6b79031d264b2f13c3ea70af1978083741c41ffce9308f1f24f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "dashmap"
+version = "5.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
+dependencies = [
+ "cfg-if",
+ "hashbrown 0.14.5",
+ "lock_api",
+ "once_cell",
+ "parking_lot_core 0.9.10",
+]
+
+[[package]]
+name = "data-encoding"
+version = "2.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f"
+
+[[package]]
+name = "data-encoding-macro"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b16d9d0d88a5273d830dac8b78ceb217ffc9b1d5404e5597a3542515329405b"
+dependencies = [
+ "data-encoding",
+ "data-encoding-macro-internal",
+]
+
+[[package]]
+name = "data-encoding-macro-internal"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1145d32e826a7748b69ee8fc62d3e6355ff7f1051df53141e7048162fc90481b"
+dependencies = [
+ "data-encoding",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "der"
+version = "0.7.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
+dependencies = [
+ "const-oid",
+ "zeroize",
+]
+
+[[package]]
+name = "der-parser"
+version = "8.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e"
+dependencies = [
+ "asn1-rs 0.5.2",
+ "displaydoc",
+ "nom",
+ "num-bigint",
+ "num-traits",
+ "rusticata-macros",
+]
+
+[[package]]
+name = "der-parser"
+version = "9.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553"
+dependencies = [
+ "asn1-rs 0.6.2",
+ "displaydoc",
+ "nom",
+ "num-bigint",
+ "num-traits",
+ "rusticata-macros",
+]
+
+[[package]]
+name = "deranged"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
+dependencies = [
+ "powerfmt",
+]
+
+[[package]]
+name = "derivative"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "derive-syn-parse"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "derive_more"
+version = "0.99.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
+dependencies = [
+ "convert_case",
+ "proc-macro2",
+ "quote",
+ "rustc_version",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "derive_more"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05"
+dependencies = [
+ "derive_more-impl",
+]
+
+[[package]]
+name = "derive_more-impl"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "difflib"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
+
+[[package]]
+name = "digest"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
+dependencies = [
+ "generic-array 0.12.4",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array 0.14.7",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer 0.10.4",
+ "const-oid",
+ "crypto-common",
+ "subtle 2.6.1",
+]
+
+[[package]]
+name = "directories"
+version = "5.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
+dependencies = [
+ "dirs-sys",
+]
+
+[[package]]
+name = "directories-next"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc"
+dependencies = [
+ "cfg-if",
+ "dirs-sys-next",
+]
+
+[[package]]
+name = "dirs-sys"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
+dependencies = [
+ "libc",
+ "option-ext",
+ "redox_users",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "dirs-sys-next"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
+dependencies = [
+ "libc",
+ "redox_users",
+ "winapi",
+]
+
+[[package]]
+name = "displaydoc"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "docify"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a772b62b1837c8f060432ddcc10b17aae1453ef17617a99bc07789252d2a5896"
+dependencies = [
+ "docify_macros",
+]
+
+[[package]]
+name = "docify_macros"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60e6be249b0a462a14784a99b19bf35a667bb5e09de611738bb7362fa4c95ff7"
+dependencies = [
+ "common-path",
+ "derive-syn-parse",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "syn 2.0.96",
+ "termcolor",
+ "toml 0.8.19",
+ "walkdir",
+]
+
+[[package]]
+name = "downcast"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1"
+
+[[package]]
+name = "dtoa"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653"
+
+[[package]]
+name = "dyn-clonable"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4"
+dependencies = [
+ "dyn-clonable-impl",
+ "dyn-clone",
+]
+
+[[package]]
+name = "dyn-clonable-impl"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "dyn-clone"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
+
+[[package]]
+name = "ecdsa"
+version = "0.16.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
+dependencies = [
+ "der",
+ "digest 0.10.7",
+ "elliptic-curve",
+ "rfc6979",
+ "serdect",
+ "signature",
+ "spki",
+]
+
+[[package]]
+name = "ed25519"
+version = "2.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
+dependencies = [
+ "pkcs8",
+ "signature",
+]
+
+[[package]]
+name = "ed25519-dalek"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871"
+dependencies = [
+ "curve25519-dalek",
+ "ed25519",
+ "rand_core",
+ "serde",
+ "sha2 0.10.8",
+ "subtle 2.6.1",
+ "zeroize",
+]
+
+[[package]]
+name = "ed25519-zebra"
+version = "4.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9"
+dependencies = [
+ "curve25519-dalek",
+ "ed25519",
+ "hashbrown 0.14.5",
+ "hex",
+ "rand_core",
+ "sha2 0.10.8",
+ "zeroize",
+]
+
+[[package]]
+name = "either"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
+
+[[package]]
+name = "elliptic-curve"
+version = "0.13.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
+dependencies = [
+ "base16ct",
+ "crypto-bigint",
+ "digest 0.10.7",
+ "ff",
+ "generic-array 0.14.7",
+ "group",
+ "pkcs8",
+ "rand_core",
+ "sec1",
+ "serdect",
+ "subtle 2.6.1",
+ "zeroize",
+]
+
+[[package]]
+name = "encode_unicode"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
+
+[[package]]
+name = "enum-as-inner"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116"
+dependencies = [
+ "heck 0.4.1",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "enum-as-inner"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc"
+dependencies = [
+ "heck 0.5.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "env_logger"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
+dependencies = [
+ "humantime",
+ "is-terminal",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
+name = "environmental"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e48c92028aaa870e83d51c64e5d4e0b6981b360c522198c23959f219a4e1b15b"
+
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+[[package]]
+name = "errno"
+version = "0.3.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
+dependencies = [
+ "libc",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "event-listener"
+version = "2.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
+
+[[package]]
+name = "event-listener"
+version = "5.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae"
+dependencies = [
+ "concurrent-queue",
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "event-listener-strategy"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2"
+dependencies = [
+ "event-listener 5.4.0",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "exit-future"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5"
+dependencies = [
+ "futures",
+]
+
+[[package]]
+name = "expander"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2c470c71d91ecbd179935b24170459e926382eaaa86b590b78814e180d8a8e2"
+dependencies = [
+ "blake2 0.10.6",
+ "file-guard",
+ "fs-err",
+ "prettyplease 0.2.29",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "fallible-iterator"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
+
+[[package]]
+name = "fallible-iterator"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
+
+[[package]]
+name = "fastrand"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+
+[[package]]
+name = "fdlimit"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e182f7dbc2ef73d9ef67351c5fbbea084729c48362d3ce9dd44c28e32e277fe5"
+dependencies = [
+ "libc",
+ "thiserror",
+]
+
+[[package]]
+name = "ff"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
+dependencies = [
+ "rand_core",
+ "subtle 2.6.1",
+]
+
+[[package]]
+name = "fiat-crypto"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
+
+[[package]]
+name = "file-guard"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21ef72acf95ec3d7dbf61275be556299490a245f017cf084bd23b4f68cf9407c"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "file-per-thread-logger"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84f2e425d9790201ba4af4630191feac6dcc98765b118d4d18e91d23c2353866"
+dependencies = [
+ "env_logger",
+ "log",
+]
+
+[[package]]
+name = "filetime"
+version = "0.2.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "libredox",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "finality-grandpa"
+version = "0.16.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36530797b9bf31cd4ff126dcfee8170f86b00cfdcea3269d73133cc0415945c3"
+dependencies = [
+ "either",
+ "futures",
+ "futures-timer",
+ "log",
+ "num-traits",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "scale-info",
+]
+
+[[package]]
+name = "fixed-hash"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534"
+dependencies = [
+ "byteorder",
+ "rand",
+ "rustc-hex",
+ "static_assertions",
+]
+
+[[package]]
+name = "fixedbitset"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
+
+[[package]]
+name = "float-cmp"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "foldhash"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "fork-tree"
+version = "13.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6736bef9fd175fafbb97495565456651c43ccac2ae550faee709e11534e3621"
+dependencies = [
+ "parity-scale-codec",
+]
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "forwarded-header-value"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9"
+dependencies = [
+ "nonempty",
+ "thiserror",
+]
+
+[[package]]
+name = "fragile"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa"
+
+[[package]]
+name = "frame-benchmarking"
+version = "37.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48554572bd164ee905a6ff3378e46c2101610fd2ffe3110875a6503a240fb3d7"
+dependencies = [
+ "frame-support",
+ "frame-support-procedural",
+ "frame-system",
+ "linregress",
+ "log",
+ "parity-scale-codec",
+ "paste",
+ "scale-info",
+ "serde",
+ "sp-api",
+ "sp-application-crypto",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-runtime-interface",
+ "sp-storage",
+ "static_assertions",
+]
+
+[[package]]
+name = "frame-executive"
+version = "37.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dfc9b1cdc305826ef1196675a53ef7f2db8967a6cf5632775119c41d6f4e299"
+dependencies = [
+ "aquamarine",
+ "frame-support",
+ "frame-system",
+ "frame-try-runtime",
+ "log",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-tracing",
+]
+
+[[package]]
+name = "frame-metadata"
+version = "16.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cf1549fba25a6fcac22785b61698317d958e96cac72a59102ea45b9ae64692"
+dependencies = [
+ "cfg-if",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+]
+
+[[package]]
+name = "frame-support"
+version = "37.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "847939177e3637c1ec2f78eecf0755910763b8d6c3dfc04aea2efec33823b3af"
+dependencies = [
+ "aquamarine",
+ "array-bytes",
+ "bitflags 1.3.2",
+ "docify",
+ "environmental",
+ "frame-metadata",
+ "frame-support-procedural",
+ "impl-trait-for-tuples",
+ "k256",
+ "log",
+ "macro_magic",
+ "parity-scale-codec",
+ "paste",
+ "scale-info",
+ "serde",
+ "serde_json",
+ "smallvec",
+ "sp-api",
+ "sp-arithmetic",
+ "sp-core",
+ "sp-crypto-hashing-proc-macro",
+ "sp-debug-derive",
+ "sp-genesis-builder",
+ "sp-inherents",
+ "sp-io",
+ "sp-metadata-ir",
+ "sp-runtime",
+ "sp-staking",
+ "sp-state-machine",
+ "sp-std",
+ "sp-tracing",
+ "sp-weights",
+ "static_assertions",
+ "tt-call",
+]
+
+[[package]]
+name = "frame-support-procedural"
+version = "30.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e8f9b6bc1517a6fcbf0b2377e5c8c6d39f5bb7862b191a59a9992081d63972d"
+dependencies = [
+ "Inflector",
+ "cfg-expr",
+ "derive-syn-parse",
+ "expander",
+ "frame-support-procedural-tools",
+ "itertools 0.11.0",
+ "macro_magic",
+ "proc-macro-warning 1.0.2",
+ "proc-macro2",
+ "quote",
+ "sp-crypto-hashing",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "frame-support-procedural-tools"
+version = "13.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81a088fd6fda5f53ff0c17fc7551ce8bd0ead14ba742228443c8196296a7369b"
+dependencies = [
+ "frame-support-procedural-tools-derive",
+ "proc-macro-crate 3.2.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "frame-support-procedural-tools-derive"
+version = "12.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed971c6435503a099bdac99fe4c5bea08981709e5b5a0a8535a1856f48561191"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "frame-system"
+version = "37.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "043790fff021477061b207fd6b33743793b63fc64a583358956787229d039717"
+dependencies = [
+ "cfg-if",
+ "docify",
+ "frame-support",
+ "log",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+ "sp-version",
+ "sp-weights",
+]
+
+[[package]]
+name = "frame-system-rpc-runtime-api"
+version = "34.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "475c4f8604ba7e4f05cd2c881ba71105093e638b9591ec71a8db14a64b3b4ec3"
+dependencies = [
+ "docify",
+ "parity-scale-codec",
+ "sp-api",
+]
+
+[[package]]
+name = "frame-try-runtime"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec60be1ddc39bd312496e58b2dd82e5f3d1e0609b69f9586ba6967a36453e495"
+dependencies = [
+ "frame-support",
+ "parity-scale-codec",
+ "sp-api",
+ "sp-runtime",
+]
+
+[[package]]
+name = "fs-err"
+version = "2.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "fs2"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "funty"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
+
+[[package]]
+name = "futures"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-bounded"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b07bbbe7d7e78809544c6f718d875627addc73a7c3582447abc052cd3dc67e0"
+dependencies = [
+ "futures-timer",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+ "num_cpus",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+
+[[package]]
+name = "futures-lite"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "futures-macro"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "futures-rustls"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28"
+dependencies = [
+ "futures-io",
+ "rustls 0.21.12",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+
+[[package]]
+name = "futures-task"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+
+[[package]]
+name = "futures-timer"
+version = "3.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24"
+
+[[package]]
+name = "futures-util"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "fxhash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
+dependencies = [
+ "typenum",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+ "zeroize",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "getrandom_or_panic"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9"
+dependencies = [
+ "rand",
+ "rand_core",
+]
+
+[[package]]
+name = "ghash"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1"
+dependencies = [
+ "opaque-debug 0.3.1",
+ "polyval",
+]
+
+[[package]]
+name = "gimli"
+version = "0.27.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
+dependencies = [
+ "fallible-iterator 0.2.0",
+ "indexmap 1.9.3",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "gimli"
+version = "0.28.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
+dependencies = [
+ "fallible-iterator 0.3.0",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "gimli"
+version = "0.31.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
+
+[[package]]
+name = "governor"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b"
+dependencies = [
+ "cfg-if",
+ "dashmap",
+ "futures",
+ "futures-timer",
+ "no-std-compat",
+ "nonzero_ext",
+ "parking_lot 0.12.3",
+ "portable-atomic",
+ "quanta",
+ "rand",
+ "smallvec",
+ "spinning_top",
+]
+
+[[package]]
+name = "group"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
+dependencies = [
+ "ff",
+ "rand_core",
+ "subtle 2.6.1",
+]
+
+[[package]]
+name = "h2"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http 0.2.12",
+ "indexmap 2.7.0",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "h2"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e"
+dependencies = [
+ "atomic-waker",
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "http 1.2.0",
+ "indexmap 2.7.0",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hash-db"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e7d7786361d7425ae2fe4f9e407eb0efaa0840f5212d109cc018c40c35c6ab4"
+
+[[package]]
+name = "hash256-std-hasher"
+version = "0.15.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2"
+dependencies = [
+ "crunchy",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hashbrown"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
+dependencies = [
+ "ahash",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
+dependencies = [
+ "ahash",
+ "allocator-api2",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.15.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
+dependencies = [
+ "allocator-api2",
+ "equivalent",
+ "foldhash",
+]
+
+[[package]]
+name = "hashlink"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
+dependencies = [
+ "hashbrown 0.14.5",
+]
+
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
+
+[[package]]
+name = "hermit-abi"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "hex-conservative"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20"
+
+[[package]]
+name = "hex-literal"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46"
+
+[[package]]
+name = "hkdf"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
+dependencies = [
+ "hmac 0.12.1",
+]
+
+[[package]]
+name = "hmac"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840"
+dependencies = [
+ "crypto-mac 0.8.0",
+ "digest 0.9.0",
+]
+
+[[package]]
+name = "hmac"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+dependencies = [
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "hmac-drbg"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1"
+dependencies = [
+ "digest 0.9.0",
+ "generic-array 0.14.7",
+ "hmac 0.8.1",
+]
+
+[[package]]
+name = "home"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "hostname"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
+dependencies = [
+ "libc",
+ "match_cfg",
+ "winapi",
+]
+
+[[package]]
+name = "http"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
+dependencies = [
+ "bytes",
+ "http 0.2.12",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "http-body"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+dependencies = [
+ "bytes",
+ "http 1.2.0",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
+dependencies = [
+ "bytes",
+ "futures-util",
+ "http 1.2.0",
+ "http-body 1.0.1",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
+
+[[package]]
+name = "httpdate"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+
+[[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
+name = "hyper"
+version = "0.14.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2 0.3.26",
+ "http 0.2.12",
+ "http-body 0.4.6",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2 0.5.8",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper"
+version = "1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-util",
+ "h2 0.4.7",
+ "http 1.2.0",
+ "http-body 1.0.1",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "smallvec",
+ "tokio",
+]
+
+[[package]]
+name = "hyper-util"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
+dependencies = [
+ "bytes",
+ "futures-util",
+ "http 1.2.0",
+ "http-body 1.0.1",
+ "hyper 1.5.2",
+ "pin-project-lite",
+ "tokio",
+ "tower-service",
+]
+
+[[package]]
+name = "iana-time-zone"
+version = "0.1.61"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows-core 0.52.0",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "icu_collections"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid_transform"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_locid_transform_data",
+ "icu_provider",
+ "tinystr",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid_transform_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
+
+[[package]]
+name = "icu_normalizer"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_normalizer_data",
+ "icu_properties",
+ "icu_provider",
+ "smallvec",
+ "utf16_iter",
+ "utf8_iter",
+ "write16",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
+
+[[package]]
+name = "icu_properties"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_locid_transform",
+ "icu_properties_data",
+ "icu_provider",
+ "tinystr",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_properties_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
+
+[[package]]
+name = "icu_provider"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_provider_macros",
+ "stable_deref_trait",
+ "tinystr",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_provider_macros"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "idna"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
+dependencies = [
+ "matches",
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "idna"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "idna"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
+dependencies = [
+ "idna_adapter",
+ "smallvec",
+ "utf8_iter",
+]
+
+[[package]]
+name = "idna_adapter"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
+dependencies = [
+ "icu_normalizer",
+ "icu_properties",
+]
+
+[[package]]
+name = "if-addrs"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cabb0019d51a643781ff15c9c8a3e5dedc365c47211270f4e8f82812fedd8f0a"
+dependencies = [
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "if-watch"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdf9d64cfcf380606e64f9a0bcf493616b65331199f984151a6fa11a7b3cde38"
+dependencies = [
+ "async-io",
+ "core-foundation",
+ "fnv",
+ "futures",
+ "if-addrs",
+ "ipnet",
+ "log",
+ "netlink-packet-core",
+ "netlink-packet-route",
+ "netlink-proto",
+ "netlink-sys",
+ "rtnetlink",
+ "system-configuration",
+ "tokio",
+ "windows",
+]
+
+[[package]]
+name = "igd-next"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4"
+dependencies = [
+ "async-trait",
+ "attohttpc",
+ "bytes",
+ "futures",
+ "http 0.2.12",
+ "hyper 0.14.32",
+ "log",
+ "rand",
+ "tokio",
+ "url",
+ "xmltree",
+]
+
+[[package]]
+name = "impl-codec"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f"
+dependencies = [
+ "parity-scale-codec",
+]
+
+[[package]]
+name = "impl-serde"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "impl-trait-for-tuples"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "include_dir"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd"
+dependencies = [
+ "include_dir_macros",
+]
+
+[[package]]
+name = "include_dir_macros"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75"
+dependencies = [
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown 0.12.3",
+ "serde",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.15.2",
+]
+
+[[package]]
+name = "inout"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+dependencies = [
+ "generic-array 0.14.7",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "integer-sqrt"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "io-lifetimes"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
+dependencies = [
+ "hermit-abi 0.3.9",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "ip_network"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1"
+
+[[package]]
+name = "ipconfig"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f"
+dependencies = [
+ "socket2 0.5.8",
+ "widestring",
+ "windows-sys 0.48.0",
+ "winreg",
+]
+
+[[package]]
+name = "ipnet"
+version = "2.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708"
+
+[[package]]
+name = "is-terminal"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
+dependencies = [
+ "hermit-abi 0.4.0",
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itertools"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itertools"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
+
+[[package]]
+name = "jobserver"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "js-sys"
+version = "0.3.77"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
+dependencies = [
+ "once_cell",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "jsonrpsee"
+version = "0.23.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b089779ad7f80768693755a031cc14a7766aba707cbe886674e3f79e9b7e47"
+dependencies = [
+ "jsonrpsee-core",
+ "jsonrpsee-proc-macros",
+ "jsonrpsee-server",
+ "jsonrpsee-types",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "jsonrpsee-core"
+version = "0.23.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79712302e737d23ca0daa178e752c9334846b08321d439fd89af9a384f8c830b"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "beef",
+ "bytes",
+ "futures-util",
+ "http 1.2.0",
+ "http-body 1.0.1",
+ "http-body-util",
+ "jsonrpsee-types",
+ "parking_lot 0.12.3",
+ "rand",
+ "rustc-hash",
+ "serde",
+ "serde_json",
+ "thiserror",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "jsonrpsee-proc-macros"
+version = "0.23.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7895f186d5921065d96e16bd795e5ca89ac8356ec423fafc6e3d7cf8ec11aee4"
+dependencies = [
+ "heck 0.5.0",
+ "proc-macro-crate 3.2.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "jsonrpsee-server"
+version = "0.23.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "654afab2e92e5d88ebd8a39d6074483f3f2bfdf91c5ac57fe285e7127cdd4f51"
+dependencies = [
+ "anyhow",
+ "futures-util",
+ "http 1.2.0",
+ "http-body 1.0.1",
+ "http-body-util",
+ "hyper 1.5.2",
+ "hyper-util",
+ "jsonrpsee-core",
+ "jsonrpsee-types",
+ "pin-project",
+ "route-recognizer",
+ "serde",
+ "serde_json",
+ "soketto",
+ "thiserror",
+ "tokio",
+ "tokio-stream",
+ "tokio-util",
+ "tower",
+ "tracing",
+]
+
+[[package]]
+name = "jsonrpsee-types"
+version = "0.23.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9c465fbe385238e861fdc4d1c85e04ada6c1fd246161d26385c1b311724d2af"
+dependencies = [
+ "beef",
+ "http 1.2.0",
+ "serde",
+ "serde_json",
+ "thiserror",
+]
+
+[[package]]
+name = "k256"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b"
+dependencies = [
+ "cfg-if",
+ "ecdsa",
+ "elliptic-curve",
+ "once_cell",
+ "serdect",
+ "sha2 0.10.8",
+]
+
+[[package]]
+name = "keccak"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654"
+dependencies = [
+ "cpufeatures",
+]
+
+[[package]]
+name = "keystream"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28"
+
+[[package]]
+name = "kvdb"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7d770dcb02bf6835887c3a979b5107a04ff4bbde97a5f0928d27404a155add9"
+dependencies = [
+ "smallvec",
+]
+
+[[package]]
+name = "kvdb-memorydb"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf7a85fe66f9ff9cd74e169fdd2c94c6e1e74c412c99a73b4df3200b5d3760b2"
+dependencies = [
+ "kvdb",
+ "parking_lot 0.12.3",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+
+[[package]]
+name = "libc"
+version = "0.2.169"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
+
+[[package]]
+name = "libm"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
+
+[[package]]
+name = "libp2p"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e94495eb319a85b70a68b85e2389a95bb3555c71c49025b78c691a854a7e6464"
+dependencies = [
+ "bytes",
+ "either",
+ "futures",
+ "futures-timer",
+ "getrandom",
+ "instant",
+ "libp2p-allow-block-list",
+ "libp2p-connection-limits",
+ "libp2p-core",
+ "libp2p-dns",
+ "libp2p-identify",
+ "libp2p-identity",
+ "libp2p-kad",
+ "libp2p-mdns",
+ "libp2p-metrics",
+ "libp2p-noise",
+ "libp2p-ping",
+ "libp2p-quic",
+ "libp2p-request-response",
+ "libp2p-swarm",
+ "libp2p-tcp",
+ "libp2p-upnp",
+ "libp2p-wasm-ext",
+ "libp2p-websocket",
+ "libp2p-yamux",
+ "multiaddr 0.18.2",
+ "pin-project",
+ "rw-stream-sink",
+ "thiserror",
+]
+
+[[package]]
+name = "libp2p-allow-block-list"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55b46558c5c0bf99d3e2a1a38fd54ff5476ca66dd1737b12466a1824dd219311"
+dependencies = [
+ "libp2p-core",
+ "libp2p-identity",
+ "libp2p-swarm",
+ "void",
+]
+
+[[package]]
+name = "libp2p-connection-limits"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f5107ad45cb20b2f6c3628c7b6014b996fcb13a88053f4569c872c6e30abf58"
+dependencies = [
+ "libp2p-core",
+ "libp2p-identity",
+ "libp2p-swarm",
+ "void",
+]
+
+[[package]]
+name = "libp2p-core"
+version = "0.40.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd44289ab25e4c9230d9246c475a22241e301b23e8f4061d3bdef304a1a99713"
+dependencies = [
+ "either",
+ "fnv",
+ "futures",
+ "futures-timer",
+ "instant",
+ "libp2p-identity",
+ "log",
+ "multiaddr 0.18.2",
+ "multihash 0.19.3",
+ "multistream-select",
+ "once_cell",
+ "parking_lot 0.12.3",
+ "pin-project",
+ "quick-protobuf",
+ "rand",
+ "rw-stream-sink",
+ "smallvec",
+ "thiserror",
+ "unsigned-varint 0.7.2",
+ "void",
+]
+
+[[package]]
+name = "libp2p-dns"
+version = "0.40.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6a18db73084b4da2871438f6239fef35190b05023de7656e877c18a00541a3b"
+dependencies = [
+ "async-trait",
+ "futures",
+ "libp2p-core",
+ "libp2p-identity",
+ "log",
+ "parking_lot 0.12.3",
+ "smallvec",
+ "trust-dns-resolver",
+]
+
+[[package]]
+name = "libp2p-identify"
+version = "0.43.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "45a96638a0a176bec0a4bcaebc1afa8cf909b114477209d7456ade52c61cd9cd"
+dependencies = [
+ "asynchronous-codec",
+ "either",
+ "futures",
+ "futures-bounded",
+ "futures-timer",
+ "libp2p-core",
+ "libp2p-identity",
+ "libp2p-swarm",
+ "log",
+ "lru",
+ "quick-protobuf",
+ "quick-protobuf-codec",
+ "smallvec",
+ "thiserror",
+ "void",
+]
+
+[[package]]
+name = "libp2p-identity"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "257b5621d159b32282eac446bed6670c39c7dc68a200a992d8f056afa0066f6d"
+dependencies = [
+ "bs58 0.5.1",
+ "ed25519-dalek",
+ "hkdf",
+ "multihash 0.19.3",
+ "quick-protobuf",
+ "rand",
+ "sha2 0.10.8",
+ "thiserror",
+ "tracing",
+ "zeroize",
+]
+
+[[package]]
+name = "libp2p-kad"
+version = "0.44.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16ea178dabba6dde6ffc260a8e0452ccdc8f79becf544946692fff9d412fc29d"
+dependencies = [
+ "arrayvec",
+ "asynchronous-codec",
+ "bytes",
+ "either",
+ "fnv",
+ "futures",
+ "futures-timer",
+ "instant",
+ "libp2p-core",
+ "libp2p-identity",
+ "libp2p-swarm",
+ "log",
+ "quick-protobuf",
+ "quick-protobuf-codec",
+ "rand",
+ "sha2 0.10.8",
+ "smallvec",
+ "thiserror",
+ "uint",
+ "unsigned-varint 0.7.2",
+ "void",
+]
+
+[[package]]
+name = "libp2p-mdns"
+version = "0.44.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42a2567c305232f5ef54185e9604579a894fd0674819402bb0ac0246da82f52a"
+dependencies = [
+ "data-encoding",
+ "futures",
+ "if-watch",
+ "libp2p-core",
+ "libp2p-identity",
+ "libp2p-swarm",
+ "log",
+ "rand",
+ "smallvec",
+ "socket2 0.5.8",
+ "tokio",
+ "trust-dns-proto 0.22.0",
+ "void",
+]
+
+[[package]]
+name = "libp2p-metrics"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "239ba7d28f8d0b5d77760dc6619c05c7e88e74ec8fbbe97f856f20a56745e620"
+dependencies = [
+ "instant",
+ "libp2p-core",
+ "libp2p-identify",
+ "libp2p-identity",
+ "libp2p-kad",
+ "libp2p-ping",
+ "libp2p-swarm",
+ "once_cell",
+ "prometheus-client",
+]
+
+[[package]]
+name = "libp2p-noise"
+version = "0.43.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2eeec39ad3ad0677551907dd304b2f13f17208ccebe333bef194076cd2e8921"
+dependencies = [
+ "bytes",
+ "curve25519-dalek",
+ "futures",
+ "libp2p-core",
+ "libp2p-identity",
+ "log",
+ "multiaddr 0.18.2",
+ "multihash 0.19.3",
+ "once_cell",
+ "quick-protobuf",
+ "rand",
+ "sha2 0.10.8",
+ "snow",
+ "static_assertions",
+ "thiserror",
+ "x25519-dalek",
+ "zeroize",
+]
+
+[[package]]
+name = "libp2p-ping"
+version = "0.43.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e702d75cd0827dfa15f8fd92d15b9932abe38d10d21f47c50438c71dd1b5dae3"
+dependencies = [
+ "either",
+ "futures",
+ "futures-timer",
+ "instant",
+ "libp2p-core",
+ "libp2p-identity",
+ "libp2p-swarm",
+ "log",
+ "rand",
+ "void",
+]
+
+[[package]]
+name = "libp2p-quic"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "130d451d83f21b81eb7b35b360bc7972aeafb15177784adc56528db082e6b927"
+dependencies = [
+ "bytes",
+ "futures",
+ "futures-timer",
+ "if-watch",
+ "libp2p-core",
+ "libp2p-identity",
+ "libp2p-tls",
+ "log",
+ "parking_lot 0.12.3",
+ "quinn 0.10.2",
+ "rand",
+ "ring 0.16.20",
+ "rustls 0.21.12",
+ "socket2 0.5.8",
+ "thiserror",
+ "tokio",
+]
+
+[[package]]
+name = "libp2p-request-response"
+version = "0.25.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8e3b4d67870478db72bac87bfc260ee6641d0734e0e3e275798f089c3fecfd4"
+dependencies = [
+ "async-trait",
+ "futures",
+ "instant",
+ "libp2p-core",
+ "libp2p-identity",
+ "libp2p-swarm",
+ "log",
+ "rand",
+ "smallvec",
+ "void",
+]
+
+[[package]]
+name = "libp2p-swarm"
+version = "0.43.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "580189e0074af847df90e75ef54f3f30059aedda37ea5a1659e8b9fca05c0141"
+dependencies = [
+ "either",
+ "fnv",
+ "futures",
+ "futures-timer",
+ "instant",
+ "libp2p-core",
+ "libp2p-identity",
+ "libp2p-swarm-derive",
+ "log",
+ "multistream-select",
+ "once_cell",
+ "rand",
+ "smallvec",
+ "tokio",
+ "void",
+]
+
+[[package]]
+name = "libp2p-swarm-derive"
+version = "0.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4d5ec2a3df00c7836d7696c136274c9c59705bac69133253696a6c932cd1d74"
+dependencies = [
+ "heck 0.4.1",
+ "proc-macro-warning 0.4.2",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "libp2p-tcp"
+version = "0.40.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b558dd40d1bcd1aaaed9de898e9ec6a436019ecc2420dd0016e712fbb61c5508"
+dependencies = [
+ "futures",
+ "futures-timer",
+ "if-watch",
+ "libc",
+ "libp2p-core",
+ "libp2p-identity",
+ "log",
+ "socket2 0.5.8",
+ "tokio",
+]
+
+[[package]]
+name = "libp2p-tls"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8218d1d5482b122ccae396bbf38abdcb283ecc96fa54760e1dfd251f0546ac61"
+dependencies = [
+ "futures",
+ "futures-rustls",
+ "libp2p-core",
+ "libp2p-identity",
+ "rcgen",
+ "ring 0.16.20",
+ "rustls 0.21.12",
+ "rustls-webpki",
+ "thiserror",
+ "x509-parser 0.15.1",
+ "yasna",
+]
+
+[[package]]
+name = "libp2p-upnp"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82775a47b34f10f787ad3e2a22e2c1541e6ebef4fe9f28f3ac553921554c94c1"
+dependencies = [
+ "futures",
+ "futures-timer",
+ "igd-next",
+ "libp2p-core",
+ "libp2p-swarm",
+ "log",
+ "tokio",
+ "void",
+]
+
+[[package]]
+name = "libp2p-wasm-ext"
+version = "0.40.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e5d8e3a9e07da0ef5b55a9f26c009c8fb3c725d492d8bb4b431715786eea79c"
+dependencies = [
+ "futures",
+ "js-sys",
+ "libp2p-core",
+ "send_wrapper",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+]
+
+[[package]]
+name = "libp2p-websocket"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "004ee9c4a4631435169aee6aad2f62e3984dc031c43b6d29731e8e82a016c538"
+dependencies = [
+ "either",
+ "futures",
+ "futures-rustls",
+ "libp2p-core",
+ "libp2p-identity",
+ "log",
+ "parking_lot 0.12.3",
+ "pin-project-lite",
+ "rw-stream-sink",
+ "soketto",
+ "thiserror",
+ "url",
+ "webpki-roots",
+]
+
+[[package]]
+name = "libp2p-yamux"
+version = "0.44.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eedcb62824c4300efb9cfd4e2a6edaf3ca097b9e68b36dabe45a44469fd6a85"
+dependencies = [
+ "futures",
+ "libp2p-core",
+ "log",
+ "thiserror",
+ "yamux",
+]
+
+[[package]]
+name = "libredox"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
+dependencies = [
+ "bitflags 2.8.0",
+ "libc",
+ "redox_syscall 0.5.8",
+]
+
+[[package]]
+name = "libsecp256k1"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1"
+dependencies = [
+ "arrayref",
+ "base64 0.13.1",
+ "digest 0.9.0",
+ "hmac-drbg",
+ "libsecp256k1-core",
+ "libsecp256k1-gen-ecmult",
+ "libsecp256k1-gen-genmult",
+ "rand",
+ "serde",
+ "sha2 0.9.9",
+ "typenum",
+]
+
+[[package]]
+name = "libsecp256k1-core"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451"
+dependencies = [
+ "crunchy",
+ "digest 0.9.0",
+ "subtle 2.6.1",
+]
+
+[[package]]
+name = "libsecp256k1-gen-ecmult"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809"
+dependencies = [
+ "libsecp256k1-core",
+]
+
+[[package]]
+name = "libsecp256k1-gen-genmult"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c"
+dependencies = [
+ "libsecp256k1-core",
+]
+
+[[package]]
+name = "link-cplusplus"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "linked-hash-map"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
+
+[[package]]
+name = "linked_hash_set"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bae85b5be22d9843c80e5fc80e9b64c8a3b1f98f867c709956eca3efff4e92e2"
+dependencies = [
+ "linked-hash-map",
+]
+
+[[package]]
+name = "linregress"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9eda9dcf4f2a99787827661f312ac3219292549c2ee992bf9a6248ffb066bf7"
+dependencies = [
+ "nalgebra",
+]
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
+
+[[package]]
+name = "lioness"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9"
+dependencies = [
+ "arrayref",
+ "blake2 0.8.1",
+ "chacha",
+ "keystream",
+]
+
+[[package]]
+name = "litemap"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
+
+[[package]]
+name = "litep2p"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f46c51c205264b834ceed95c8b195026e700494bc3991aaba3b4ea9e20626d9"
+dependencies = [
+ "async-trait",
+ "bs58 0.4.0",
+ "bytes",
+ "cid 0.10.1",
+ "ed25519-dalek",
+ "futures",
+ "futures-timer",
+ "hex-literal",
+ "indexmap 2.7.0",
+ "libc",
+ "mockall 0.12.1",
+ "multiaddr 0.17.1",
+ "multihash 0.17.0",
+ "network-interface",
+ "nohash-hasher",
+ "parking_lot 0.12.3",
+ "pin-project",
+ "prost 0.12.6",
+ "prost-build 0.11.9",
+ "quinn 0.9.4",
+ "rand",
+ "rcgen",
+ "ring 0.16.20",
+ "rustls 0.20.9",
+ "serde",
+ "sha2 0.10.8",
+ "simple-dns",
+ "smallvec",
+ "snow",
+ "socket2 0.5.8",
+ "static_assertions",
+ "str0m",
+ "thiserror",
+ "tokio",
+ "tokio-stream",
+ "tokio-tungstenite",
+ "tokio-util",
+ "tracing",
+ "trust-dns-resolver",
+ "uint",
+ "unsigned-varint 0.8.0",
+ "url",
+ "webpki",
+ "x25519-dalek",
+ "x509-parser 0.16.0",
+ "yasna",
+ "zeroize",
+]
+
+[[package]]
+name = "lock_api"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
+
+[[package]]
+name = "lru"
+version = "0.12.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
+dependencies = [
+ "hashbrown 0.15.2",
+]
+
+[[package]]
+name = "lru-cache"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
+dependencies = [
+ "linked-hash-map",
+]
+
+[[package]]
+name = "lz4"
+version = "1.28.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a20b523e860d03443e98350ceaac5e71c6ba89aea7d960769ec3ce37f4de5af4"
+dependencies = [
+ "lz4-sys",
+]
+
+[[package]]
+name = "lz4-sys"
+version = "1.11.1+lz4-1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "mach"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "macro_magic"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc33f9f0351468d26fbc53d9ce00a096c8522ecb42f19b50f34f2c422f76d21d"
+dependencies = [
+ "macro_magic_core",
+ "macro_magic_macros",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "macro_magic_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1687dc887e42f352865a393acae7cf79d98fab6351cde1f58e9e057da89bf150"
+dependencies = [
+ "const-random",
+ "derive-syn-parse",
+ "macro_magic_core_macros",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "macro_magic_core_macros"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "macro_magic_macros"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869"
+dependencies = [
+ "macro_magic_core",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "match_cfg"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
+
+[[package]]
+name = "matchers"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
+dependencies = [
+ "regex-automata 0.1.10",
+]
+
+[[package]]
+name = "matches"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
+
+[[package]]
+name = "matrixmultiply"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a"
+dependencies = [
+ "autocfg",
+ "rawpointer",
+]
+
+[[package]]
+name = "md5"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "memfd"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64"
+dependencies = [
+ "rustix 0.38.43",
+]
+
+[[package]]
+name = "memmap2"
+version = "0.5.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "memmap2"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "memoffset"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "memory-db"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808b50db46293432a45e63bc15ea51e0ab4c0a1647b8eb114e31a3e698dd6fbe"
+dependencies = [
+ "hash-db",
+]
+
+[[package]]
+name = "merlin"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d"
+dependencies = [
+ "byteorder",
+ "keccak",
+ "rand_core",
+ "zeroize",
+]
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924"
+dependencies = [
+ "adler2",
+]
+
+[[package]]
+name = "mio"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "mixnet"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "daa3eb39495d8e2e2947a1d862852c90cc6a4a8845f8b41c8829cb9fcc047f4a"
+dependencies = [
+ "arrayref",
+ "arrayvec",
+ "bitflags 1.3.2",
+ "blake2 0.10.6",
+ "c2-chacha",
+ "curve25519-dalek",
+ "either",
+ "hashlink",
+ "lioness",
+ "log",
+ "parking_lot 0.12.3",
+ "rand",
+ "rand_chacha",
+ "rand_distr",
+ "subtle 2.6.1",
+ "thiserror",
+ "zeroize",
+]
+
+[[package]]
+name = "mockall"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96"
+dependencies = [
+ "cfg-if",
+ "downcast",
+ "fragile",
+ "lazy_static",
+ "mockall_derive 0.11.4",
+ "predicates 2.1.5",
+ "predicates-tree",
+]
+
+[[package]]
+name = "mockall"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43766c2b5203b10de348ffe19f7e54564b64f3d6018ff7648d1e2d6d3a0f0a48"
+dependencies = [
+ "cfg-if",
+ "downcast",
+ "fragile",
+ "lazy_static",
+ "mockall_derive 0.12.1",
+ "predicates 3.1.3",
+ "predicates-tree",
+]
+
+[[package]]
+name = "mockall_derive"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb"
+dependencies = [
+ "cfg-if",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "mockall_derive"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af7cbce79ec385a1d4f54baa90a76401eb15d9cab93685f62e7e9f942aa00ae2"
+dependencies = [
+ "cfg-if",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "multi-pow"
+version = "3.0.0"
+dependencies = [
+ "log",
+ "md5",
+ "parity-scale-codec",
+ "sc-client-api",
+ "sc-consensus-pow",
+ "scale-info",
+ "sha3",
+ "sp-api",
+ "sp-consensus-pow",
+ "sp-core",
+ "sp-runtime",
+]
+
+[[package]]
+name = "multiaddr"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd"
+dependencies = [
+ "arrayref",
+ "byteorder",
+ "data-encoding",
+ "log",
+ "multibase",
+ "multihash 0.17.0",
+ "percent-encoding",
+ "serde",
+ "static_assertions",
+ "unsigned-varint 0.7.2",
+ "url",
+]
+
+[[package]]
+name = "multiaddr"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe6351f60b488e04c1d21bc69e56b89cb3f5e8f5d22557d6e8031bdfd79b6961"
+dependencies = [
+ "arrayref",
+ "byteorder",
+ "data-encoding",
+ "libp2p-identity",
+ "multibase",
+ "multihash 0.19.3",
+ "percent-encoding",
+ "serde",
+ "static_assertions",
+ "unsigned-varint 0.8.0",
+ "url",
+]
+
+[[package]]
+name = "multibase"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404"
+dependencies = [
+ "base-x",
+ "data-encoding",
+ "data-encoding-macro",
+]
+
+[[package]]
+name = "multihash"
+version = "0.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40"
+dependencies = [
+ "blake2b_simd",
+ "blake2s_simd",
+ "blake3",
+ "core2",
+ "digest 0.10.7",
+ "multihash-derive",
+ "sha2 0.10.8",
+ "sha3",
+ "unsigned-varint 0.7.2",
+]
+
+[[package]]
+name = "multihash"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfd8a792c1694c6da4f68db0a9d707c72bd260994da179e6030a5dcee00bb815"
+dependencies = [
+ "blake2b_simd",
+ "blake2s_simd",
+ "blake3",
+ "core2",
+ "digest 0.10.7",
+ "multihash-derive",
+ "sha2 0.10.8",
+ "sha3",
+ "unsigned-varint 0.7.2",
+]
+
+[[package]]
+name = "multihash"
+version = "0.19.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d"
+dependencies = [
+ "core2",
+ "unsigned-varint 0.8.0",
+]
+
+[[package]]
+name = "multihash-derive"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db"
+dependencies = [
+ "proc-macro-crate 1.1.3",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "synstructure 0.12.6",
+]
+
+[[package]]
+name = "multimap"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
+
+[[package]]
+name = "multimap"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
+
+[[package]]
+name = "multistream-select"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea0df8e5eec2298a62b326ee4f0d7fe1a6b90a09dfcf9df37b38f947a8c42f19"
+dependencies = [
+ "bytes",
+ "futures",
+ "log",
+ "pin-project",
+ "smallvec",
+ "unsigned-varint 0.7.2",
+]
+
+[[package]]
+name = "nalgebra"
+version = "0.33.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b"
+dependencies = [
+ "approx",
+ "matrixmultiply",
+ "num-complex",
+ "num-rational",
+ "num-traits",
+ "simba",
+ "typenum",
+]
+
+[[package]]
+name = "names"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc"
+dependencies = [
+ "rand",
+]
+
+[[package]]
+name = "netlink-packet-core"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72724faf704479d67b388da142b186f916188505e7e0b26719019c525882eda4"
+dependencies = [
+ "anyhow",
+ "byteorder",
+ "netlink-packet-utils",
+]
+
+[[package]]
+name = "netlink-packet-route"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66"
+dependencies = [
+ "anyhow",
+ "bitflags 1.3.2",
+ "byteorder",
+ "libc",
+ "netlink-packet-core",
+ "netlink-packet-utils",
+]
+
+[[package]]
+name = "netlink-packet-utils"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34"
+dependencies = [
+ "anyhow",
+ "byteorder",
+ "paste",
+ "thiserror",
+]
+
+[[package]]
+name = "netlink-proto"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86b33524dc0968bfad349684447bfce6db937a9ac3332a1fe60c0c5a5ce63f21"
+dependencies = [
+ "bytes",
+ "futures",
+ "log",
+ "netlink-packet-core",
+ "netlink-sys",
+ "thiserror",
+ "tokio",
+]
+
+[[package]]
+name = "netlink-sys"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16c903aa70590cb93691bf97a767c8d1d6122d2cc9070433deb3bbf36ce8bd23"
+dependencies = [
+ "bytes",
+ "futures",
+ "libc",
+ "log",
+ "tokio",
+]
+
+[[package]]
+name = "network-interface"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4a43439bf756eed340bdf8feba761e2d50c7d47175d87545cd5cbe4a137c4d1"
+dependencies = [
+ "cc",
+ "libc",
+ "thiserror",
+ "winapi",
+]
+
+[[package]]
+name = "nix"
+version = "0.26.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
+dependencies = [
+ "bitflags 1.3.2",
+ "cfg-if",
+ "libc",
+]
+
+[[package]]
+name = "no-std-compat"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
+
+[[package]]
+name = "nohash-hasher"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "nonempty"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7"
+
+[[package]]
+name = "nonzero_ext"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21"
+
+[[package]]
+name = "normalize-line-endings"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
+
+[[package]]
+name = "nu-ansi-term"
+version = "0.46.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
+dependencies = [
+ "overload",
+ "winapi",
+]
+
+[[package]]
+name = "num-bigint"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
+dependencies = [
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-complex"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
+[[package]]
+name = "num-format"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3"
+dependencies = [
+ "arrayvec",
+ "itoa",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.46"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "num-rational"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
+dependencies = [
+ "num-bigint",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+ "libm",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+dependencies = [
+ "hermit-abi 0.3.9",
+ "libc",
+]
+
+[[package]]
+name = "object"
+version = "0.30.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385"
+dependencies = [
+ "crc32fast",
+ "hashbrown 0.13.2",
+ "indexmap 1.9.3",
+ "memchr",
+]
+
+[[package]]
+name = "object"
+version = "0.32.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "object"
+version = "0.36.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "oid-registry"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff"
+dependencies = [
+ "asn1-rs 0.5.2",
+]
+
+[[package]]
+name = "oid-registry"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9"
+dependencies = [
+ "asn1-rs 0.6.2",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+
+[[package]]
+name = "opaque-debug"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
+
+[[package]]
+name = "opaque-debug"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
+
+[[package]]
+name = "openssl"
+version = "0.10.68"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5"
+dependencies = [
+ "bitflags 2.8.0",
+ "cfg-if",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+
+[[package]]
+name = "openssl-src"
+version = "300.4.1+3.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "faa4eac4138c62414b5622d1b31c5c304f34b406b013c079c2bbc652fdd6678c"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741"
+dependencies = [
+ "cc",
+ "libc",
+ "openssl-src",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "option-ext"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
+
+[[package]]
+name = "overload"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
+
+[[package]]
+name = "pallet-balances"
+version = "38.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "267f2b4c64e06d340fab1e48267e815dc2afaf8e6da16369b26b5c9e1e65f1aa"
+dependencies = [
+ "docify",
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "log",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-runtime",
+]
+
+[[package]]
+name = "pallet-timestamp"
+version = "36.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14f264c80bef4ac3180e5cba619f319d7855cc89ba91b28b3f752620d9425b88"
+dependencies = [
+ "docify",
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "log",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-inherents",
+ "sp-io",
+ "sp-runtime",
+ "sp-storage",
+ "sp-timestamp",
+]
+
+[[package]]
+name = "pallet-transaction-payment"
+version = "37.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1f02a44346aad9f3d24f2f4ae2bfe81bd858686d8c243cc77eb0ad1bf97cb04"
+dependencies = [
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+]
+
+[[package]]
+name = "pallet-transaction-payment-rpc"
+version = "40.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2496ae1bdf86dd0aeb213d33dccd0edb4abfcead660ada070c81b254ea2cbf75"
+dependencies = [
+ "jsonrpsee",
+ "pallet-transaction-payment-rpc-runtime-api",
+ "parity-scale-codec",
+ "sp-api",
+ "sp-blockchain",
+ "sp-core",
+ "sp-rpc",
+ "sp-runtime",
+ "sp-weights",
+]
+
+[[package]]
+name = "pallet-transaction-payment-rpc-runtime-api"
+version = "37.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1879d1f608f565d590fc7520a8d9977b868a412910f6381a5ebfa45acf8abcfb"
+dependencies = [
+ "pallet-transaction-payment",
+ "parity-scale-codec",
+ "sp-api",
+ "sp-runtime",
+ "sp-weights",
+]
+
+[[package]]
+name = "parity-bip39"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9"
+dependencies = [
+ "bitcoin_hashes",
+ "rand",
+ "rand_core",
+ "serde",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "parity-db"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "592a28a24b09c9dc20ac8afaa6839abc417c720afe42c12e1e4a9d6aa2508d2e"
+dependencies = [
+ "blake2 0.10.6",
+ "crc32fast",
+ "fs2",
+ "hex",
+ "libc",
+ "log",
+ "lz4",
+ "memmap2 0.5.10",
+ "parking_lot 0.12.3",
+ "rand",
+ "siphasher",
+ "snap",
+ "winapi",
+]
+
+[[package]]
+name = "parity-scale-codec"
+version = "3.6.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee"
+dependencies = [
+ "arrayvec",
+ "bitvec",
+ "byte-slice-cast",
+ "bytes",
+ "impl-trait-for-tuples",
+ "parity-scale-codec-derive",
+ "serde",
+]
+
+[[package]]
+name = "parity-scale-codec-derive"
+version = "3.6.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c"
+dependencies = [
+ "proc-macro-crate 3.2.0",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "parity-wasm"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304"
+
+[[package]]
+name = "parking"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
+
+[[package]]
+name = "parking_lot"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
+dependencies = [
+ "instant",
+ "lock_api",
+ "parking_lot_core 0.8.6",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
+dependencies = [
+ "lock_api",
+ "parking_lot_core 0.9.10",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
+dependencies = [
+ "cfg-if",
+ "instant",
+ "libc",
+ "redox_syscall 0.2.16",
+ "smallvec",
+ "winapi",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall 0.5.8",
+ "smallvec",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "partial_sort"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7924d1d0ad836f665c9065e26d016c673ece3993f30d340068b16f282afc1156"
+
+[[package]]
+name = "password-hash"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
+dependencies = [
+ "base64ct",
+ "rand_core",
+ "subtle 2.6.1",
+]
+
+[[package]]
+name = "paste"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
+
+[[package]]
+name = "pbkdf2"
+version = "0.12.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
+dependencies = [
+ "digest 0.10.7",
+ "password-hash",
+]
+
+[[package]]
+name = "pem"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8"
+dependencies = [
+ "base64 0.13.1",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+
+[[package]]
+name = "petgraph"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
+dependencies = [
+ "fixedbitset",
+ "indexmap 2.7.0",
+]
+
+[[package]]
+name = "pin-project"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkcs8"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
+dependencies = [
+ "der",
+ "spki",
+]
+
+[[package]]
+name = "pkg-config"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
+
+[[package]]
+name = "polkavm"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a3693e5efdb2bf74e449cd25fd777a28bd7ed87e41f5d5da75eb31b4de48b94"
+dependencies = [
+ "libc",
+ "log",
+ "polkavm-assembler",
+ "polkavm-common",
+ "polkavm-linux-raw",
+]
+
+[[package]]
+name = "polkavm-assembler"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fa96d6d868243acc12de813dd48e756cbadcc8e13964c70d272753266deadc1"
+dependencies = [
+ "log",
+]
+
+[[package]]
+name = "polkavm-common"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d9428a5cfcc85c5d7b9fc4b6a18c4b802d0173d768182a51cc7751640f08b92"
+dependencies = [
+ "log",
+]
+
+[[package]]
+name = "polkavm-derive"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae8c4bea6f3e11cd89bb18bcdddac10bd9a24015399bd1c485ad68a985a19606"
+dependencies = [
+ "polkavm-derive-impl-macro",
+]
+
+[[package]]
+name = "polkavm-derive-impl"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c4fdfc49717fb9a196e74a5d28e0bc764eb394a2c803eb11133a31ac996c60c"
+dependencies = [
+ "polkavm-common",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "polkavm-derive-impl-macro"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429"
+dependencies = [
+ "polkavm-derive-impl",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "polkavm-linker"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c7be503e60cf56c0eb785f90aaba4b583b36bff00e93997d93fef97f9553c39"
+dependencies = [
+ "gimli 0.28.1",
+ "hashbrown 0.14.5",
+ "log",
+ "object 0.32.2",
+ "polkavm-common",
+ "regalloc2 0.9.3",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "polkavm-linux-raw"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26e85d3456948e650dff0cfc85603915847faf893ed1e66b020bb82ef4557120"
+
+[[package]]
+name = "polling"
+version = "3.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f"
+dependencies = [
+ "cfg-if",
+ "concurrent-queue",
+ "hermit-abi 0.4.0",
+ "pin-project-lite",
+ "rustix 0.38.43",
+ "tracing",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "poly1305"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
+dependencies = [
+ "cpufeatures",
+ "opaque-debug 0.3.1",
+ "universal-hash",
+]
+
+[[package]]
+name = "polyval"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "opaque-debug 0.3.1",
+ "universal-hash",
+]
+
+[[package]]
+name = "portable-atomic"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6"
+
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+dependencies = [
+ "zerocopy",
+]
+
+[[package]]
+name = "predicates"
+version = "2.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd"
+dependencies = [
+ "difflib",
+ "float-cmp",
+ "itertools 0.10.5",
+ "normalize-line-endings",
+ "predicates-core",
+ "regex",
+]
+
+[[package]]
+name = "predicates"
+version = "3.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573"
+dependencies = [
+ "anstyle",
+ "predicates-core",
+]
+
+[[package]]
+name = "predicates-core"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa"
+
+[[package]]
+name = "predicates-tree"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c"
+dependencies = [
+ "predicates-core",
+ "termtree",
+]
+
+[[package]]
+name = "prettyplease"
+version = "0.1.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86"
+dependencies = [
+ "proc-macro2",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "prettyplease"
+version = "0.2.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac"
+dependencies = [
+ "proc-macro2",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "primitive-types"
+version = "0.12.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2"
+dependencies = [
+ "fixed-hash",
+ "impl-codec",
+ "impl-serde",
+ "scale-info",
+ "uint",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a"
+dependencies = [
+ "thiserror",
+ "toml 0.5.11",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
+dependencies = [
+ "toml_edit",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-warning"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "proc-macro-warning"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.93"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "prometheus"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1"
+dependencies = [
+ "cfg-if",
+ "fnv",
+ "lazy_static",
+ "memchr",
+ "parking_lot 0.12.3",
+ "thiserror",
+]
+
+[[package]]
+name = "prometheus-client"
+version = "0.21.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c99afa9a01501019ac3a14d71d9f94050346f55ca471ce90c799a15c58f61e2"
+dependencies = [
+ "dtoa",
+ "itoa",
+ "parking_lot 0.12.3",
+ "prometheus-client-derive-encode",
+]
+
+[[package]]
+name = "prometheus-client-derive-encode"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "prost"
+version = "0.11.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd"
+dependencies = [
+ "bytes",
+ "prost-derive 0.11.9",
+]
+
+[[package]]
+name = "prost"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29"
+dependencies = [
+ "bytes",
+ "prost-derive 0.12.6",
+]
+
+[[package]]
+name = "prost-build"
+version = "0.11.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270"
+dependencies = [
+ "bytes",
+ "heck 0.4.1",
+ "itertools 0.10.5",
+ "lazy_static",
+ "log",
+ "multimap 0.8.3",
+ "petgraph",
+ "prettyplease 0.1.25",
+ "prost 0.11.9",
+ "prost-types 0.11.9",
+ "regex",
+ "syn 1.0.109",
+ "tempfile",
+ "which",
+]
+
+[[package]]
+name = "prost-build"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4"
+dependencies = [
+ "bytes",
+ "heck 0.5.0",
+ "itertools 0.12.1",
+ "log",
+ "multimap 0.10.0",
+ "once_cell",
+ "petgraph",
+ "prettyplease 0.2.29",
+ "prost 0.12.6",
+ "prost-types 0.12.6",
+ "regex",
+ "syn 2.0.96",
+ "tempfile",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.11.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4"
+dependencies = [
+ "anyhow",
+ "itertools 0.10.5",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
+dependencies = [
+ "anyhow",
+ "itertools 0.12.1",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "prost-types"
+version = "0.11.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13"
+dependencies = [
+ "prost 0.11.9",
+]
+
+[[package]]
+name = "prost-types"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0"
+dependencies = [
+ "prost 0.12.6",
+]
+
+[[package]]
+name = "psm"
+version = "0.1.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "quanta"
+version = "0.12.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e"
+dependencies = [
+ "crossbeam-utils",
+ "libc",
+ "once_cell",
+ "raw-cpuid",
+ "wasi",
+ "web-sys",
+ "winapi",
+]
+
+[[package]]
+name = "quick-error"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
+
+[[package]]
+name = "quick-protobuf"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "quick-protobuf-codec"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8ededb1cd78531627244d51dd0c7139fbe736c7d57af0092a76f0ffb2f56e98"
+dependencies = [
+ "asynchronous-codec",
+ "bytes",
+ "quick-protobuf",
+ "thiserror",
+ "unsigned-varint 0.7.2",
+]
+
+[[package]]
+name = "quinn"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e8b432585672228923edbbf64b8b12c14e1112f62e88737655b4a083dbcd78e"
+dependencies = [
+ "bytes",
+ "pin-project-lite",
+ "quinn-proto 0.9.6",
+ "quinn-udp 0.3.2",
+ "rustc-hash",
+ "rustls 0.20.9",
+ "thiserror",
+ "tokio",
+ "tracing",
+ "webpki",
+]
+
+[[package]]
+name = "quinn"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75"
+dependencies = [
+ "bytes",
+ "futures-io",
+ "pin-project-lite",
+ "quinn-proto 0.10.6",
+ "quinn-udp 0.4.1",
+ "rustc-hash",
+ "rustls 0.21.12",
+ "thiserror",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "quinn-proto"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863"
+dependencies = [
+ "bytes",
+ "rand",
+ "ring 0.16.20",
+ "rustc-hash",
+ "rustls 0.20.9",
+ "slab",
+ "thiserror",
+ "tinyvec",
+ "tracing",
+ "webpki",
+]
+
+[[package]]
+name = "quinn-proto"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a"
+dependencies = [
+ "bytes",
+ "rand",
+ "ring 0.16.20",
+ "rustc-hash",
+ "rustls 0.21.12",
+ "slab",
+ "thiserror",
+ "tinyvec",
+ "tracing",
+]
+
+[[package]]
+name = "quinn-udp"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "641538578b21f5e5c8ea733b736895576d0fe329bb883b937db6f4d163dbaaf4"
+dependencies = [
+ "libc",
+ "quinn-proto 0.9.6",
+ "socket2 0.4.10",
+ "tracing",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "quinn-udp"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7"
+dependencies = [
+ "bytes",
+ "libc",
+ "socket2 0.5.8",
+ "tracing",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "radium"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "rand_distr"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
+dependencies = [
+ "num-traits",
+ "rand",
+]
+
+[[package]]
+name = "rand_pcg"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
+name = "raw-cpuid"
+version = "11.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6928fa44c097620b706542d428957635951bade7143269085389d42c8a4927e"
+dependencies = [
+ "bitflags 2.8.0",
+]
+
+[[package]]
+name = "rawpointer"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
+
+[[package]]
+name = "rayon"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "rcgen"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b"
+dependencies = [
+ "pem",
+ "ring 0.16.20",
+ "time",
+ "yasna",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
+dependencies = [
+ "bitflags 2.8.0",
+]
+
+[[package]]
+name = "redox_users"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
+dependencies = [
+ "getrandom",
+ "libredox",
+ "thiserror",
+]
+
+[[package]]
+name = "ref-cast"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931"
+dependencies = [
+ "ref-cast-impl",
+]
+
+[[package]]
+name = "ref-cast-impl"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "regalloc2"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80535183cae11b149d618fbd3c37e38d7cda589d82d7769e196ca9a9042d7621"
+dependencies = [
+ "fxhash",
+ "log",
+ "slice-group-by",
+ "smallvec",
+]
+
+[[package]]
+name = "regalloc2"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6"
+dependencies = [
+ "hashbrown 0.13.2",
+ "log",
+ "rustc-hash",
+ "slice-group-by",
+ "smallvec",
+]
+
+[[package]]
+name = "regex"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata 0.4.9",
+ "regex-syntax 0.8.5",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+dependencies = [
+ "regex-syntax 0.6.29",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax 0.8.5",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
+[[package]]
+name = "resolv-conf"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
+dependencies = [
+ "hostname",
+ "quick-error",
+]
+
+[[package]]
+name = "rfc6979"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
+dependencies = [
+ "hmac 0.12.1",
+ "subtle 2.6.1",
+]
+
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin 0.5.2",
+ "untrusted 0.7.1",
+ "web-sys",
+ "winapi",
+]
+
+[[package]]
+name = "ring"
+version = "0.17.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
+dependencies = [
+ "cc",
+ "cfg-if",
+ "getrandom",
+ "libc",
+ "spin 0.9.8",
+ "untrusted 0.9.0",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "route-recognizer"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746"
+
+[[package]]
+name = "rpassword"
+version = "7.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f"
+dependencies = [
+ "libc",
+ "rtoolbox",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "rtnetlink"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a552eb82d19f38c3beed3f786bd23aa434ceb9ac43ab44419ca6d67a7e186c0"
+dependencies = [
+ "futures",
+ "log",
+ "netlink-packet-core",
+ "netlink-packet-route",
+ "netlink-packet-utils",
+ "netlink-proto",
+ "netlink-sys",
+ "nix",
+ "thiserror",
+ "tokio",
+]
+
+[[package]]
+name = "rtoolbox"
+version = "0.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e"
+dependencies = [
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "rustc-hex"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
+dependencies = [
+ "semver 1.0.24",
+]
+
+[[package]]
+name = "rusticata-macros"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "rustix"
+version = "0.36.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "305efbd14fde4139eb501df5f136994bb520b033fa9fbdce287507dc23b8c7ed"
+dependencies = [
+ "bitflags 1.3.2",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys 0.1.4",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "rustix"
+version = "0.38.43"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
+dependencies = [
+ "bitflags 2.8.0",
+ "errno",
+ "libc",
+ "linux-raw-sys 0.4.15",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "rustls"
+version = "0.20.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99"
+dependencies = [
+ "ring 0.16.20",
+ "sct",
+ "webpki",
+]
+
+[[package]]
+name = "rustls"
+version = "0.21.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
+dependencies = [
+ "log",
+ "ring 0.17.8",
+ "rustls-webpki",
+ "sct",
+]
+
+[[package]]
+name = "rustls-native-certs"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
+dependencies = [
+ "openssl-probe",
+ "rustls-pemfile",
+ "schannel",
+ "security-framework",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
+dependencies = [
+ "base64 0.21.7",
+]
+
+[[package]]
+name = "rustls-webpki"
+version = "0.101.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
+dependencies = [
+ "ring 0.17.8",
+ "untrusted 0.9.0",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
+
+[[package]]
+name = "rw-stream-sink"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8c9026ff5d2f23da5e45bbc283f156383001bfb09c4e44256d02c1a685fe9a1"
+dependencies = [
+ "futures",
+ "pin-project",
+ "static_assertions",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+
+[[package]]
+name = "safe_arch"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "sc-allocator"
+version = "29.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b975ee3a95eaacb611e7b415737a7fa2db4d8ad7b880cc1b97371b04e95c7903"
+dependencies = [
+ "log",
+ "sp-core",
+ "sp-wasm-interface",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-basic-authorship"
+version = "0.44.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdef7ee4dd39a41957eeafb99c55749f8065a72f46c12e209ed15f4669360a6e"
+dependencies = [
+ "futures",
+ "futures-timer",
+ "log",
+ "parity-scale-codec",
+ "sc-block-builder",
+ "sc-proposer-metrics",
+ "sc-telemetry",
+ "sc-transaction-pool-api",
+ "sp-api",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-core",
+ "sp-inherents",
+ "sp-runtime",
+ "substrate-prometheus-endpoint",
+]
+
+[[package]]
+name = "sc-block-builder"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f666f8ff11f96bf6d90676739eb7ccb6a156a4507634b7af83b94f0aa8195a50"
+dependencies = [
+ "parity-scale-codec",
+ "sp-api",
+ "sp-block-builder",
+ "sp-blockchain",
+ "sp-core",
+ "sp-inherents",
+ "sp-runtime",
+ "sp-trie",
+]
+
+[[package]]
+name = "sc-chain-spec"
+version = "37.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9149a7ee8a4a799feb3ed581a288a0ce6ede42fb8b1997806f6a29997cdbd9be"
+dependencies = [
+ "array-bytes",
+ "docify",
+ "log",
+ "memmap2 0.9.5",
+ "parity-scale-codec",
+ "sc-chain-spec-derive",
+ "sc-client-api",
+ "sc-executor",
+ "sc-network",
+ "sc-telemetry",
+ "serde",
+ "serde_json",
+ "sp-blockchain",
+ "sp-core",
+ "sp-crypto-hashing",
+ "sp-genesis-builder",
+ "sp-io",
+ "sp-runtime",
+ "sp-state-machine",
+ "sp-tracing",
+]
+
+[[package]]
+name = "sc-chain-spec-derive"
+version = "12.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b18cef11d2c69703e0d7c3528202ef4ed1cd2b47a6f063e9e17cad8255b1fa94"
+dependencies = [
+ "proc-macro-crate 3.2.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "sc-cli"
+version = "0.46.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b37e08bde78fa7bdf3e30682a6840236de49d2c11960535eb9a9a1a87a0fd3ab"
+dependencies = [
+ "array-bytes",
+ "chrono",
+ "clap",
+ "fdlimit",
+ "futures",
+ "itertools 0.11.0",
+ "libp2p-identity",
+ "log",
+ "names",
+ "parity-bip39",
+ "parity-scale-codec",
+ "rand",
+ "regex",
+ "rpassword",
+ "sc-client-api",
+ "sc-client-db",
+ "sc-keystore",
+ "sc-mixnet",
+ "sc-network",
+ "sc-service",
+ "sc-telemetry",
+ "sc-tracing",
+ "sc-utils",
+ "serde",
+ "serde_json",
+ "sp-blockchain",
+ "sp-core",
+ "sp-keyring",
+ "sp-keystore",
+ "sp-panic-handler",
+ "sp-runtime",
+ "sp-version",
+ "thiserror",
+ "tokio",
+]
+
+[[package]]
+name = "sc-client-api"
+version = "37.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e73f1673cdfe658c4be6ffd5113b71c0de74616717e604455dcfd29e15781729"
+dependencies = [
+ "fnv",
+ "futures",
+ "log",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "sc-executor",
+ "sc-transaction-pool-api",
+ "sc-utils",
+ "sp-api",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-core",
+ "sp-database",
+ "sp-externalities",
+ "sp-runtime",
+ "sp-state-machine",
+ "sp-statement-store",
+ "sp-storage",
+ "sp-trie",
+ "substrate-prometheus-endpoint",
+]
+
+[[package]]
+name = "sc-client-db"
+version = "0.44.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5517718f03357325c6f51a780710fac652f125316f3577d1a25a7fbdc1816db2"
+dependencies = [
+ "hash-db",
+ "kvdb",
+ "kvdb-memorydb",
+ "linked-hash-map",
+ "log",
+ "parity-db",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "sc-client-api",
+ "sc-state-db",
+ "schnellru",
+ "sp-arithmetic",
+ "sp-blockchain",
+ "sp-core",
+ "sp-database",
+ "sp-runtime",
+ "sp-state-machine",
+ "sp-trie",
+]
+
+[[package]]
+name = "sc-consensus"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "502b55375db80dea8be1336b203eb96c1e22e7c4fa7782dc775bad71688bb91c"
+dependencies = [
+ "async-trait",
+ "futures",
+ "log",
+ "mockall 0.11.4",
+ "parking_lot 0.12.3",
+ "sc-client-api",
+ "sc-network-types",
+ "sc-utils",
+ "serde",
+ "sp-api",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-core",
+ "sp-runtime",
+ "sp-state-machine",
+ "substrate-prometheus-endpoint",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-consensus-aura"
+version = "0.44.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cde090c64dfcab34347bd5472b40cc608b7395ef2dd1a8403c6c13dbec74c80"
+dependencies = [
+ "async-trait",
+ "futures",
+ "log",
+ "parity-scale-codec",
+ "sc-block-builder",
+ "sc-client-api",
+ "sc-consensus",
+ "sc-consensus-slots",
+ "sc-telemetry",
+ "sp-api",
+ "sp-application-crypto",
+ "sp-block-builder",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-consensus-aura",
+ "sp-consensus-slots",
+ "sp-core",
+ "sp-inherents",
+ "sp-keystore",
+ "sp-runtime",
+ "substrate-prometheus-endpoint",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-consensus-babe"
+version = "0.44.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec4aea13d44497edd2c240c85a3722c2431eaabf7f6d172891d12908504cab1f"
+dependencies = [
+ "async-trait",
+ "fork-tree",
+ "futures",
+ "log",
+ "num-bigint",
+ "num-rational",
+ "num-traits",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "sc-client-api",
+ "sc-consensus",
+ "sc-consensus-epochs",
+ "sc-consensus-slots",
+ "sc-telemetry",
+ "sc-transaction-pool-api",
+ "sp-api",
+ "sp-application-crypto",
+ "sp-block-builder",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-consensus-babe",
+ "sp-consensus-slots",
+ "sp-core",
+ "sp-crypto-hashing",
+ "sp-inherents",
+ "sp-keystore",
+ "sp-runtime",
+ "substrate-prometheus-endpoint",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-consensus-epochs"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7258d517642944d4e39d11f77a413825349089e01b6f27819f4349932ff07ec"
+dependencies = [
+ "fork-tree",
+ "parity-scale-codec",
+ "sc-client-api",
+ "sc-consensus",
+ "sp-blockchain",
+ "sp-runtime",
+]
+
+[[package]]
+name = "sc-consensus-manual-seal"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc77a432b7bdd979c9f72820d214efd0eb0cac102a7dd9e23a4e0e77e5737171"
+dependencies = [
+ "assert_matches",
+ "async-trait",
+ "futures",
+ "futures-timer",
+ "jsonrpsee",
+ "log",
+ "parity-scale-codec",
+ "sc-client-api",
+ "sc-consensus",
+ "sc-consensus-aura",
+ "sc-consensus-babe",
+ "sc-consensus-epochs",
+ "sc-transaction-pool",
+ "sc-transaction-pool-api",
+ "serde",
+ "sp-api",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-consensus-aura",
+ "sp-consensus-babe",
+ "sp-consensus-slots",
+ "sp-core",
+ "sp-inherents",
+ "sp-keystore",
+ "sp-runtime",
+ "sp-timestamp",
+ "substrate-prometheus-endpoint",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-consensus-pow"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa2d6763ea4d0f7dbeedf7522418ee3843fb7c62712e4b8bc75cca3bf8cd0e5e"
+dependencies = [
+ "async-trait",
+ "futures",
+ "futures-timer",
+ "log",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "sc-client-api",
+ "sc-consensus",
+ "sp-api",
+ "sp-block-builder",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-consensus-pow",
+ "sp-core",
+ "sp-inherents",
+ "sp-runtime",
+ "substrate-prometheus-endpoint",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-consensus-slots"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97f4aab75d55fbeee7437ed6a127a749014f831f12a0b409a71cfc3a42453ccd"
+dependencies = [
+ "async-trait",
+ "futures",
+ "futures-timer",
+ "log",
+ "parity-scale-codec",
+ "sc-client-api",
+ "sc-consensus",
+ "sc-telemetry",
+ "sp-arithmetic",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-consensus-slots",
+ "sp-core",
+ "sp-inherents",
+ "sp-runtime",
+ "sp-state-machine",
+]
+
+[[package]]
+name = "sc-executor"
+version = "0.40.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f0cc0a3728fd033589183460c5a49b2e7545d09dc89a098216ef9e9aadcd9dc"
+dependencies = [
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "sc-executor-common",
+ "sc-executor-polkavm",
+ "sc-executor-wasmtime",
+ "schnellru",
+ "sp-api",
+ "sp-core",
+ "sp-externalities",
+ "sp-io",
+ "sp-panic-handler",
+ "sp-runtime-interface",
+ "sp-trie",
+ "sp-version",
+ "sp-wasm-interface",
+ "tracing",
+]
+
+[[package]]
+name = "sc-executor-common"
+version = "0.35.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c3b703a33dcb7cddf19176fdf12294b9a6408125836b0f4afee3e6969e7f190"
+dependencies = [
+ "polkavm",
+ "sc-allocator",
+ "sp-maybe-compressed-blob",
+ "sp-wasm-interface",
+ "thiserror",
+ "wasm-instrument",
+]
+
+[[package]]
+name = "sc-executor-polkavm"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26fe58d9cacfab73e5595fa84b80f7bd03efebe54a0574daaeb221a1d1f7ab80"
+dependencies = [
+ "log",
+ "polkavm",
+ "sc-executor-common",
+ "sp-wasm-interface",
+]
+
+[[package]]
+name = "sc-executor-wasmtime"
+version = "0.35.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cd498f2f77ec1f861c30804f5bfd796d4afcc8ce44ea1f11bfbe2847551d161"
+dependencies = [
+ "anyhow",
+ "cfg-if",
+ "libc",
+ "log",
+ "parking_lot 0.12.3",
+ "rustix 0.36.17",
+ "sc-allocator",
+ "sc-executor-common",
+ "sp-runtime-interface",
+ "sp-wasm-interface",
+ "wasmtime",
+]
+
+[[package]]
+name = "sc-informant"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6dcfaffeeb2d662a26f84706132dcfd294ffd71c4077d0b4f92a6f54db184f6"
+dependencies = [
+ "ansi_term",
+ "futures",
+ "futures-timer",
+ "log",
+ "sc-client-api",
+ "sc-network",
+ "sc-network-common",
+ "sc-network-sync",
+ "sp-blockchain",
+ "sp-runtime",
+]
+
+[[package]]
+name = "sc-keystore"
+version = "33.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ebd4b5b5713006117641c049cb082e8a439dd6ac5e7b171e5cef5ce1c9f8af8"
+dependencies = [
+ "array-bytes",
+ "parking_lot 0.12.3",
+ "serde_json",
+ "sp-application-crypto",
+ "sp-core",
+ "sp-keystore",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-mixnet"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04ac673840824d0357dedee5b952440b469d11f48314ff52ae59049aee7e376d"
+dependencies = [
+ "array-bytes",
+ "arrayvec",
+ "blake2 0.10.6",
+ "bytes",
+ "futures",
+ "futures-timer",
+ "log",
+ "mixnet",
+ "multiaddr 0.18.2",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "sc-client-api",
+ "sc-network",
+ "sc-network-types",
+ "sc-transaction-pool-api",
+ "sp-api",
+ "sp-consensus",
+ "sp-core",
+ "sp-keystore",
+ "sp-mixnet",
+ "sp-runtime",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-network"
+version = "0.44.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "efa1cccd2bb93a008a471944f6c27cf5d0d4edc041a46f80cb440615c95c181d"
+dependencies = [
+ "array-bytes",
+ "async-channel",
+ "async-trait",
+ "asynchronous-codec",
+ "bytes",
+ "cid 0.9.0",
+ "either",
+ "fnv",
+ "futures",
+ "futures-timer",
+ "ip_network",
+ "libp2p",
+ "linked_hash_set",
+ "litep2p",
+ "log",
+ "mockall 0.11.4",
+ "once_cell",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "partial_sort",
+ "pin-project",
+ "prost 0.12.6",
+ "prost-build 0.12.6",
+ "rand",
+ "sc-client-api",
+ "sc-network-common",
+ "sc-network-types",
+ "sc-utils",
+ "schnellru",
+ "serde",
+ "serde_json",
+ "smallvec",
+ "sp-arithmetic",
+ "sp-blockchain",
+ "sp-core",
+ "sp-runtime",
+ "substrate-prometheus-endpoint",
+ "thiserror",
+ "tokio",
+ "tokio-stream",
+ "unsigned-varint 0.7.2",
+ "void",
+ "wasm-timer",
+ "zeroize",
+]
+
+[[package]]
+name = "sc-network-common"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11a8bbc9d2600f34d021796bdffbb20bdf4723f98ff3126c765b4c9363bef564"
+dependencies = [
+ "async-trait",
+ "bitflags 1.3.2",
+ "futures",
+ "libp2p-identity",
+ "parity-scale-codec",
+ "prost-build 0.12.6",
+ "sc-consensus",
+ "sc-network-types",
+ "sp-consensus",
+ "sp-consensus-grandpa",
+ "sp-runtime",
+]
+
+[[package]]
+name = "sc-network-light"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18efef00b71e1a7060fb92dcc433ed4bed625a803b074e0bf4b4cf6e1d90384e"
+dependencies = [
+ "array-bytes",
+ "async-channel",
+ "futures",
+ "log",
+ "parity-scale-codec",
+ "prost 0.12.6",
+ "prost-build 0.12.6",
+ "sc-client-api",
+ "sc-network",
+ "sc-network-types",
+ "sp-blockchain",
+ "sp-core",
+ "sp-runtime",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-network-sync"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "628881aacdd36235d2725a7ecb13d6445c76ad470ed6e6473fc58c6b98a2417d"
+dependencies = [
+ "array-bytes",
+ "async-channel",
+ "async-trait",
+ "fork-tree",
+ "futures",
+ "futures-timer",
+ "libp2p",
+ "log",
+ "mockall 0.11.4",
+ "parity-scale-codec",
+ "prost 0.12.6",
+ "prost-build 0.12.6",
+ "sc-client-api",
+ "sc-consensus",
+ "sc-network",
+ "sc-network-common",
+ "sc-network-types",
+ "sc-utils",
+ "schnellru",
+ "smallvec",
+ "sp-arithmetic",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-consensus-grandpa",
+ "sp-core",
+ "sp-runtime",
+ "substrate-prometheus-endpoint",
+ "thiserror",
+ "tokio",
+ "tokio-stream",
+]
+
+[[package]]
+name = "sc-network-transactions"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8661c677deb9159c291a4dccbdfeba3e1fe5106caea0936fb70d3765a163aa8e"
+dependencies = [
+ "array-bytes",
+ "futures",
+ "log",
+ "parity-scale-codec",
+ "sc-network",
+ "sc-network-common",
+ "sc-network-sync",
+ "sc-network-types",
+ "sc-utils",
+ "sp-consensus",
+ "sp-runtime",
+ "substrate-prometheus-endpoint",
+]
+
+[[package]]
+name = "sc-network-types"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c372dbda66644a1df0daa8c0d99c36b6f74db7dca213d2416cd84f507125224"
+dependencies = [
+ "bs58 0.5.1",
+ "ed25519-dalek",
+ "libp2p-identity",
+ "litep2p",
+ "log",
+ "multiaddr 0.18.2",
+ "multihash 0.19.3",
+ "rand",
+ "thiserror",
+ "zeroize",
+]
+
+[[package]]
+name = "sc-proposer-metrics"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f680a0bed67dab19898624246376ba85d5f70a89859ba030830aacd079c28d3c"
+dependencies = [
+ "log",
+ "substrate-prometheus-endpoint",
+]
+
+[[package]]
+name = "sc-rpc"
+version = "39.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ccc910a40803287c65194e232d99bf6e1f9200b04f8dd91433f298687b8bf3f"
+dependencies = [
+ "futures",
+ "jsonrpsee",
+ "log",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "sc-block-builder",
+ "sc-chain-spec",
+ "sc-client-api",
+ "sc-mixnet",
+ "sc-rpc-api",
+ "sc-tracing",
+ "sc-transaction-pool-api",
+ "sc-utils",
+ "serde_json",
+ "sp-api",
+ "sp-blockchain",
+ "sp-core",
+ "sp-keystore",
+ "sp-offchain",
+ "sp-rpc",
+ "sp-runtime",
+ "sp-session",
+ "sp-statement-store",
+ "sp-version",
+ "tokio",
+]
+
+[[package]]
+name = "sc-rpc-api"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "575a098a1c59d15bec2df388437474334b76c512e9dd92b0f275801906303354"
+dependencies = [
+ "jsonrpsee",
+ "parity-scale-codec",
+ "sc-chain-spec",
+ "sc-mixnet",
+ "sc-transaction-pool-api",
+ "scale-info",
+ "serde",
+ "serde_json",
+ "sp-core",
+ "sp-rpc",
+ "sp-runtime",
+ "sp-version",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-rpc-server"
+version = "16.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c14c236a01e03f55f16b92d89fd902cf2e4e9887357a3c36827a1e39b799c6b"
+dependencies = [
+ "forwarded-header-value",
+ "futures",
+ "governor",
+ "http 1.2.0",
+ "http-body-util",
+ "hyper 1.5.2",
+ "ip_network",
+ "jsonrpsee",
+ "log",
+ "serde",
+ "serde_json",
+ "substrate-prometheus-endpoint",
+ "tokio",
+ "tower",
+ "tower-http",
+]
+
+[[package]]
+name = "sc-rpc-spec-v2"
+version = "0.44.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "934087c0aae2642327e07070ae3739ae82bbadaf876fadcff0c9b19c37a87ada"
+dependencies = [
+ "array-bytes",
+ "futures",
+ "futures-util",
+ "hex",
+ "jsonrpsee",
+ "log",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "rand",
+ "sc-chain-spec",
+ "sc-client-api",
+ "sc-rpc",
+ "sc-transaction-pool-api",
+ "sc-utils",
+ "schnellru",
+ "serde",
+ "sp-api",
+ "sp-blockchain",
+ "sp-core",
+ "sp-rpc",
+ "sp-runtime",
+ "sp-version",
+ "thiserror",
+ "tokio",
+ "tokio-stream",
+]
+
+[[package]]
+name = "sc-service"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd9eb103478c93e3a9325fb9c07d2c6a507cd04934954c930fc33a1e0791010b"
+dependencies = [
+ "async-trait",
+ "directories",
+ "exit-future",
+ "futures",
+ "futures-timer",
+ "jsonrpsee",
+ "log",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "pin-project",
+ "rand",
+ "sc-chain-spec",
+ "sc-client-api",
+ "sc-client-db",
+ "sc-consensus",
+ "sc-executor",
+ "sc-informant",
+ "sc-keystore",
+ "sc-network",
+ "sc-network-common",
+ "sc-network-light",
+ "sc-network-sync",
+ "sc-network-transactions",
+ "sc-network-types",
+ "sc-rpc",
+ "sc-rpc-server",
+ "sc-rpc-spec-v2",
+ "sc-sysinfo",
+ "sc-telemetry",
+ "sc-tracing",
+ "sc-transaction-pool",
+ "sc-transaction-pool-api",
+ "sc-utils",
+ "schnellru",
+ "serde",
+ "serde_json",
+ "sp-api",
+ "sp-blockchain",
+ "sp-consensus",
+ "sp-core",
+ "sp-externalities",
+ "sp-keystore",
+ "sp-runtime",
+ "sp-session",
+ "sp-state-machine",
+ "sp-storage",
+ "sp-transaction-pool",
+ "sp-transaction-storage-proof",
+ "sp-trie",
+ "sp-version",
+ "static_init",
+ "substrate-prometheus-endpoint",
+ "tempfile",
+ "thiserror",
+ "tokio",
+ "tracing",
+ "tracing-futures",
+]
+
+[[package]]
+name = "sc-state-db"
+version = "0.36.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f689d0b97c1bbdb2ca31b5f202bda195947f85c7fef990651cad202b99de896b"
+dependencies = [
+ "log",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "sp-core",
+]
+
+[[package]]
+name = "sc-sysinfo"
+version = "37.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2ce11152bd7a2b01713e71de71a5610067bd1b3509aa207e3d87f5ee53dd328"
+dependencies = [
+ "derive_more 0.99.18",
+ "futures",
+ "libc",
+ "log",
+ "rand",
+ "rand_pcg",
+ "regex",
+ "sc-telemetry",
+ "serde",
+ "serde_json",
+ "sp-core",
+ "sp-crypto-hashing",
+ "sp-io",
+ "sp-std",
+]
+
+[[package]]
+name = "sc-telemetry"
+version = "24.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b59589eadf05088221cc60b6d9f68f89208262ae9b1e4fb8704eefe7de48845"
+dependencies = [
+ "chrono",
+ "futures",
+ "libp2p",
+ "log",
+ "parking_lot 0.12.3",
+ "pin-project",
+ "rand",
+ "sc-network",
+ "sc-utils",
+ "serde",
+ "serde_json",
+ "thiserror",
+ "wasm-timer",
+]
+
+[[package]]
+name = "sc-tracing"
+version = "37.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2604130246c4f6c2a2633f320bde95e7122383385c779b263eb03b714d92758a"
+dependencies = [
+ "chrono",
+ "console",
+ "is-terminal",
+ "lazy_static",
+ "libc",
+ "log",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "rustc-hash",
+ "sc-client-api",
+ "sc-tracing-proc-macro",
+ "serde",
+ "sp-api",
+ "sp-blockchain",
+ "sp-core",
+ "sp-rpc",
+ "sp-runtime",
+ "sp-tracing",
+ "thiserror",
+ "tracing",
+ "tracing-log",
+ "tracing-subscriber",
+]
+
+[[package]]
+name = "sc-tracing-proc-macro"
+version = "11.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "151cdf86d79abf22cf2a240a7ca95041c908dbd96c2ae9a818073042aa210964"
+dependencies = [
+ "proc-macro-crate 3.2.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "sc-transaction-pool"
+version = "37.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f716ef0dc78458f6ecb831cdb3b60ec804c1ed93313d7f98661beb5438dbbf71"
+dependencies = [
+ "async-trait",
+ "futures",
+ "futures-timer",
+ "linked-hash-map",
+ "log",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "sc-client-api",
+ "sc-transaction-pool-api",
+ "sc-utils",
+ "serde",
+ "sp-api",
+ "sp-blockchain",
+ "sp-core",
+ "sp-crypto-hashing",
+ "sp-runtime",
+ "sp-tracing",
+ "sp-transaction-pool",
+ "substrate-prometheus-endpoint",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-transaction-pool-api"
+version = "37.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f02936289a079360935685eee5400311994b25e9edb2420a3c4247d419a77f46"
+dependencies = [
+ "async-trait",
+ "futures",
+ "log",
+ "parity-scale-codec",
+ "serde",
+ "sp-blockchain",
+ "sp-core",
+ "sp-runtime",
+ "thiserror",
+]
+
+[[package]]
+name = "sc-utils"
+version = "17.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acf1bad736c230f16beb1cf48af9e69564df23b13aca9e5751a61266340b4bb5"
+dependencies = [
+ "async-channel",
+ "futures",
+ "futures-timer",
+ "lazy_static",
+ "log",
+ "parking_lot 0.12.3",
+ "prometheus",
+ "sp-arithmetic",
+]
+
+[[package]]
+name = "scale-info"
+version = "2.11.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b"
+dependencies = [
+ "bitvec",
+ "cfg-if",
+ "derive_more 1.0.0",
+ "parity-scale-codec",
+ "scale-info-derive",
+ "serde",
+]
+
+[[package]]
+name = "scale-info-derive"
+version = "2.11.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf"
+dependencies = [
+ "proc-macro-crate 3.2.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "schannel"
+version = "0.1.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "schnellru"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "356285bbf17bea63d9e52e96bd18f039672ac92b55b8cb997d6162a2a37d1649"
+dependencies = [
+ "ahash",
+ "cfg-if",
+ "hashbrown 0.13.2",
+]
+
+[[package]]
+name = "schnorrkel"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de18f6d8ba0aad7045f5feae07ec29899c1112584a38509a84ad7b04451eaa0"
+dependencies = [
+ "aead",
+ "arrayref",
+ "arrayvec",
+ "curve25519-dalek",
+ "getrandom_or_panic",
+ "merlin",
+ "rand_core",
+ "serde_bytes",
+ "sha2 0.10.8",
+ "subtle 2.6.1",
+ "zeroize",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "scratch"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152"
+
+[[package]]
+name = "sct"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
+dependencies = [
+ "ring 0.17.8",
+ "untrusted 0.9.0",
+]
+
+[[package]]
+name = "sctp-proto"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6220f78bb44c15f326b0596113305f6101097a18755d53727a575c97e09fb24"
+dependencies = [
+ "bytes",
+ "crc",
+ "fxhash",
+ "log",
+ "rand",
+ "slab",
+ "thiserror",
+]
+
+[[package]]
+name = "sec1"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
+dependencies = [
+ "base16ct",
+ "der",
+ "generic-array 0.14.7",
+ "pkcs8",
+ "serdect",
+ "subtle 2.6.1",
+ "zeroize",
+]
+
+[[package]]
+name = "secp256k1"
+version = "0.28.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10"
+dependencies = [
+ "secp256k1-sys",
+]
+
+[[package]]
+name = "secp256k1-sys"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "secrecy"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e"
+dependencies = [
+ "zeroize",
+]
+
+[[package]]
+name = "security-framework"
+version = "2.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
+dependencies = [
+ "bitflags 2.8.0",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "semver"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
+dependencies = [
+ "semver-parser",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+
+[[package]]
+name = "send_wrapper"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
+
+[[package]]
+name = "serde"
+version = "1.0.217"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_bytes"
+version = "0.11.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.217"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.135"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
+dependencies = [
+ "itoa",
+ "memchr",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_spanned"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serdect"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177"
+dependencies = [
+ "base16ct",
+ "serde",
+]
+
+[[package]]
+name = "sha-1"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest 0.10.7",
+ "sha1-asm",
+]
+
+[[package]]
+name = "sha1"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "sha1-asm"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "286acebaf8b67c1130aedffad26f594eff0c1292389158135327d2e23aed582b"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "sha2"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
+dependencies = [
+ "block-buffer 0.9.0",
+ "cfg-if",
+ "cpufeatures",
+ "digest 0.9.0",
+ "opaque-debug 0.3.1",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "sha3"
+version = "0.10.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
+dependencies = [
+ "digest 0.10.7",
+ "keccak",
+]
+
+[[package]]
+name = "sharded-slab"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "signature"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
+dependencies = [
+ "digest 0.10.7",
+ "rand_core",
+]
+
+[[package]]
+name = "simba"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa"
+dependencies = [
+ "approx",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "wide",
+]
+
+[[package]]
+name = "simple-dns"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cae9a3fcdadafb6d97f4c0e007e4247b114ee0f119f650c3cbf3a8b3a1479694"
+dependencies = [
+ "bitflags 2.8.0",
+]
+
+[[package]]
+name = "simple-mermaid"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "620a1d43d70e142b1d46a929af51d44f383db9c7a2ec122de2cd992ccfcf3c18"
+
+[[package]]
+name = "siphasher"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
+
+[[package]]
+name = "slab"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "slice-group-by"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7"
+
+[[package]]
+name = "smallvec"
+version = "1.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+
+[[package]]
+name = "snap"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b"
+
+[[package]]
+name = "snow"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "850948bee068e713b8ab860fe1adc4d109676ab4c3b621fd8147f06b261f2f85"
+dependencies = [
+ "aes-gcm",
+ "blake2 0.10.6",
+ "chacha20poly1305",
+ "curve25519-dalek",
+ "rand_core",
+ "ring 0.17.8",
+ "rustc_version",
+ "sha2 0.10.8",
+ "subtle 2.6.1",
+]
+
+[[package]]
+name = "socket2"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "socket2"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "soketto"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e859df029d160cb88608f5d7df7fb4753fd20fdfb4de5644f3d8b8440841721"
+dependencies = [
+ "base64 0.22.1",
+ "bytes",
+ "futures",
+ "http 1.2.0",
+ "httparse",
+ "log",
+ "rand",
+ "sha1",
+]
+
+[[package]]
+name = "sp-api"
+version = "34.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbce492e0482134128b7729ea36f5ef1a9f9b4de2d48ff8dde7b5e464e28ce75"
+dependencies = [
+ "docify",
+ "hash-db",
+ "log",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-api-proc-macro",
+ "sp-core",
+ "sp-externalities",
+ "sp-metadata-ir",
+ "sp-runtime",
+ "sp-runtime-interface",
+ "sp-state-machine",
+ "sp-trie",
+ "sp-version",
+ "thiserror",
+]
+
+[[package]]
+name = "sp-api-proc-macro"
+version = "20.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c9aadf9e97e694f0e343978aa632938c5de309cbcc8afed4136cb71596737278"
+dependencies = [
+ "Inflector",
+ "blake2 0.10.6",
+ "expander",
+ "proc-macro-crate 3.2.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "sp-application-crypto"
+version = "38.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d8133012faa5f75b2f0b1619d9f720c1424ac477152c143e5f7dbde2fe1a958"
+dependencies = [
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-core",
+ "sp-io",
+]
+
+[[package]]
+name = "sp-arithmetic"
+version = "26.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46d0d0a4c591c421d3231ddd5e27d828618c24456d51445d21a1f79fcee97c23"
+dependencies = [
+ "docify",
+ "integer-sqrt",
+ "num-traits",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-std",
+ "static_assertions",
+]
+
+[[package]]
+name = "sp-block-builder"
+version = "34.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74738809461e3d4bd707b5b94e0e0c064a623a74a6a8fe5c98514417a02858dd"
+dependencies = [
+ "sp-api",
+ "sp-inherents",
+ "sp-runtime",
+]
+
+[[package]]
+name = "sp-blockchain"
+version = "37.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a309eecd6b5689f57e67181deaa628d9c8951db1ba0d26f07c69e14dffdc4765"
+dependencies = [
+ "futures",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "schnellru",
+ "sp-api",
+ "sp-consensus",
+ "sp-core",
+ "sp-database",
+ "sp-runtime",
+ "sp-state-machine",
+ "thiserror",
+ "tracing",
+]
+
+[[package]]
+name = "sp-consensus"
+version = "0.40.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce75efd1e164be667a53c20182c45b4c2abe325abcbd21fc292b82be5b9240f7"
+dependencies = [
+ "async-trait",
+ "futures",
+ "log",
+ "sp-core",
+ "sp-inherents",
+ "sp-runtime",
+ "sp-state-machine",
+ "thiserror",
+]
+
+[[package]]
+name = "sp-consensus-aura"
+version = "0.40.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a8faaa05bbcb9c41f0cc535c4c1315abf6df472b53eae018678d1b4d811ac47"
+dependencies = [
+ "async-trait",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-api",
+ "sp-application-crypto",
+ "sp-consensus-slots",
+ "sp-inherents",
+ "sp-runtime",
+ "sp-timestamp",
+]
+
+[[package]]
+name = "sp-consensus-babe"
+version = "0.40.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36ee95e17ee8dcd14db7d584b899a426565ca9abe5a266ab82277977fc547f86"
+dependencies = [
+ "async-trait",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-api",
+ "sp-application-crypto",
+ "sp-consensus-slots",
+ "sp-core",
+ "sp-inherents",
+ "sp-runtime",
+ "sp-timestamp",
+]
+
+[[package]]
+name = "sp-consensus-grandpa"
+version = "21.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "587b791efe6c5f18e09dbbaf1ece0ee7b5fe51602c233e7151a3676b0de0260b"
+dependencies = [
+ "finality-grandpa",
+ "log",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-api",
+ "sp-application-crypto",
+ "sp-core",
+ "sp-keystore",
+ "sp-runtime",
+]
+
+[[package]]
+name = "sp-consensus-pow"
+version = "0.40.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fa6b7d199a1c16cea1b74ee7cee174bf08f2120ab66a87bee7b12353100b47c"
+dependencies = [
+ "parity-scale-codec",
+ "sp-api",
+ "sp-core",
+ "sp-runtime",
+]
+
+[[package]]
+name = "sp-consensus-slots"
+version = "0.40.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbafb7ed44f51c22fa277fb39b33dc601fa426133a8e2b53f3f46b10f07fba43"
+dependencies = [
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-timestamp",
+]
+
+[[package]]
+name = "sp-core"
+version = "34.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c961a5e33fb2962fa775c044ceba43df9c6f917e2c35d63bfe23738468fa76a7"
+dependencies = [
+ "array-bytes",
+ "bitflags 1.3.2",
+ "blake2 0.10.6",
+ "bounded-collections",
+ "bs58 0.5.1",
+ "dyn-clonable",
+ "ed25519-zebra",
+ "futures",
+ "hash-db",
+ "hash256-std-hasher",
+ "impl-serde",
+ "itertools 0.11.0",
+ "k256",
+ "libsecp256k1",
+ "log",
+ "merlin",
+ "parity-bip39",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "paste",
+ "primitive-types",
+ "rand",
+ "scale-info",
+ "schnorrkel",
+ "secp256k1",
+ "secrecy",
+ "serde",
+ "sp-crypto-hashing",
+ "sp-debug-derive",
+ "sp-externalities",
+ "sp-runtime-interface",
+ "sp-std",
+ "sp-storage",
+ "ss58-registry",
+ "substrate-bip39",
+ "thiserror",
+ "tracing",
+ "w3f-bls",
+ "zeroize",
+]
+
+[[package]]
+name = "sp-crypto-hashing"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc9927a7f81334ed5b8a98a4a978c81324d12bd9713ec76b5c68fd410174c5eb"
+dependencies = [
+ "blake2b_simd",
+ "byteorder",
+ "digest 0.10.7",
+ "sha2 0.10.8",
+ "sha3",
+ "twox-hash",
+]
+
+[[package]]
+name = "sp-crypto-hashing-proc-macro"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b85d0f1f1e44bd8617eb2a48203ee854981229e3e79e6f468c7175d5fd37489b"
+dependencies = [
+ "quote",
+ "sp-crypto-hashing",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "sp-database"
+version = "10.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "722cbecdbf5b94578137dbd07feb51e95f7de221be0c1ff4dcfe0bb4cd986929"
+dependencies = [
+ "kvdb",
+ "parking_lot 0.12.3",
+]
+
+[[package]]
+name = "sp-debug-derive"
+version = "14.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48d09fa0a5f7299fb81ee25ae3853d26200f7a348148aed6de76be905c007dbe"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "sp-externalities"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a904407d61cb94228c71b55a9d3708e9d6558991f9e83bd42bd91df37a159d30"
+dependencies = [
+ "environmental",
+ "parity-scale-codec",
+ "sp-storage",
+]
+
+[[package]]
+name = "sp-genesis-builder"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a646ed222fd86d5680faa4a8967980eb32f644cae6c8523e1c689a6deda3e8"
+dependencies = [
+ "parity-scale-codec",
+ "scale-info",
+ "serde_json",
+ "sp-api",
+ "sp-runtime",
+]
+
+[[package]]
+name = "sp-inherents"
+version = "34.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afffbddc380d99a90c459ba1554bbbc01d62e892de9f1485af6940b89c4c0d57"
+dependencies = [
+ "async-trait",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-runtime",
+ "thiserror",
+]
+
+[[package]]
+name = "sp-io"
+version = "38.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59ef7eb561bb4839cc8424ce58c5ea236cbcca83f26fcc0426d8decfe8aa97d4"
+dependencies = [
+ "bytes",
+ "docify",
+ "ed25519-dalek",
+ "libsecp256k1",
+ "log",
+ "parity-scale-codec",
+ "polkavm-derive",
+ "rustversion",
+ "secp256k1",
+ "sp-core",
+ "sp-crypto-hashing",
+ "sp-externalities",
+ "sp-keystore",
+ "sp-runtime-interface",
+ "sp-state-machine",
+ "sp-tracing",
+ "sp-trie",
+ "tracing",
+ "tracing-core",
+]
+
+[[package]]
+name = "sp-keyring"
+version = "39.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c0e20624277f578b27f44ecfbe2ebc2e908488511ee2c900c5281599f700ab3"
+dependencies = [
+ "sp-core",
+ "sp-runtime",
+ "strum 0.26.3",
+]
+
+[[package]]
+name = "sp-keystore"
+version = "0.40.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0248b4d784cb4a01472276928977121fa39d977a5bb24793b6b15e64b046df42"
+dependencies = [
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "sp-core",
+ "sp-externalities",
+]
+
+[[package]]
+name = "sp-maybe-compressed-blob"
+version = "11.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0c768c11afbe698a090386876911da4236af199cd38a5866748df4d8628aeff"
+dependencies = [
+ "thiserror",
+ "zstd 0.12.4",
+]
+
+[[package]]
+name = "sp-metadata-ir"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a616fa51350b35326682a472ee8e6ba742fdacb18babac38ecd46b3e05ead869"
+dependencies = [
+ "frame-metadata",
+ "parity-scale-codec",
+ "scale-info",
+]
+
+[[package]]
+name = "sp-mixnet"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b0b017dd54823b6e62f9f7171a1df350972e5c6d0bf17e0c2f78680b5c31942"
+dependencies = [
+ "parity-scale-codec",
+ "scale-info",
+ "sp-api",
+ "sp-application-crypto",
+]
+
+[[package]]
+name = "sp-offchain"
+version = "34.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d9de237d72ecffd07f90826eef18360208b16d8de939d54e61591fac0fcbf99"
+dependencies = [
+ "sp-api",
+ "sp-core",
+ "sp-runtime",
+]
+
+[[package]]
+name = "sp-panic-handler"
+version = "13.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81478b3740b357fa0ea10fcdc1ee02ebae7734e50f80342c4743476d9f78eeea"
+dependencies = [
+ "backtrace",
+ "regex",
+]
+
+[[package]]
+name = "sp-rpc"
+version = "32.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "45458f0955870a92b3969098d4f1f4e9b55b4282d9f1dc112a51bb5bb6584900"
+dependencies = [
+ "rustc-hash",
+ "serde",
+ "sp-core",
+]
+
+[[package]]
+name = "sp-runtime"
+version = "39.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1e00503b83cf48fffe48746b91b9b832d6785d4e2eeb0941558371eac6baac6"
+dependencies = [
+ "docify",
+ "either",
+ "hash256-std-hasher",
+ "impl-trait-for-tuples",
+ "log",
+ "num-traits",
+ "parity-scale-codec",
+ "paste",
+ "rand",
+ "scale-info",
+ "serde",
+ "simple-mermaid",
+ "sp-application-crypto",
+ "sp-arithmetic",
+ "sp-core",
+ "sp-io",
+ "sp-std",
+ "sp-weights",
+ "tracing",
+]
+
+[[package]]
+name = "sp-runtime-interface"
+version = "28.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "985eb981f40c689c6a0012c937b68ed58dabb4341d06f2dfe4dfd5ed72fa4017"
+dependencies = [
+ "bytes",
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
+ "polkavm-derive",
+ "primitive-types",
+ "sp-externalities",
+ "sp-runtime-interface-proc-macro",
+ "sp-std",
+ "sp-storage",
+ "sp-tracing",
+ "sp-wasm-interface",
+ "static_assertions",
+]
+
+[[package]]
+name = "sp-runtime-interface-proc-macro"
+version = "18.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0195f32c628fee3ce1dfbbf2e7e52a30ea85f3589da9fe62a8b816d70fc06294"
+dependencies = [
+ "Inflector",
+ "expander",
+ "proc-macro-crate 3.2.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "sp-session"
+version = "35.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d04fcd2d1270038be94d00103e8e95f7fbab9075dcc78096b91d8931ee970d73"
+dependencies = [
+ "parity-scale-codec",
+ "scale-info",
+ "sp-api",
+ "sp-core",
+ "sp-keystore",
+ "sp-runtime",
+ "sp-staking",
+]
+
+[[package]]
+name = "sp-staking"
+version = "34.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "143a764cacbab58347d8b2fd4c8909031fb0888d7b02a0ec9fa44f81f780d732"
+dependencies = [
+ "impl-trait-for-tuples",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-core",
+ "sp-runtime",
+]
+
+[[package]]
+name = "sp-state-machine"
+version = "0.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "930104d6ae882626e8880d9b1578da9300655d337a3ffb45e130c608b6c89660"
+dependencies = [
+ "hash-db",
+ "log",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "rand",
+ "smallvec",
+ "sp-core",
+ "sp-externalities",
+ "sp-panic-handler",
+ "sp-trie",
+ "thiserror",
+ "tracing",
+ "trie-db",
+]
+
+[[package]]
+name = "sp-statement-store"
+version = "18.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c219bc34ef4d1f9835f3ed881f965643c32034fcc030eb33b759dadbc802c1c2"
+dependencies = [
+ "aes-gcm",
+ "curve25519-dalek",
+ "ed25519-dalek",
+ "hkdf",
+ "parity-scale-codec",
+ "rand",
+ "scale-info",
+ "sha2 0.10.8",
+ "sp-api",
+ "sp-application-crypto",
+ "sp-core",
+ "sp-crypto-hashing",
+ "sp-externalities",
+ "sp-runtime",
+ "sp-runtime-interface",
+ "thiserror",
+ "x25519-dalek",
+]
+
+[[package]]
+name = "sp-std"
+version = "14.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12f8ee986414b0a9ad741776762f4083cd3a5128449b982a3919c4df36874834"
+
+[[package]]
+name = "sp-storage"
+version = "21.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99c82989b3a4979a7e1ad848aad9f5d0b4388f1f454cc131766526601ab9e8f8"
+dependencies = [
+ "impl-serde",
+ "parity-scale-codec",
+ "ref-cast",
+ "serde",
+ "sp-debug-derive",
+]
+
+[[package]]
+name = "sp-timestamp"
+version = "34.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72a1cb4df653d62ccc0dbce1db45d1c9443ec60247ee9576962d24da4c9c6f07"
+dependencies = [
+ "async-trait",
+ "parity-scale-codec",
+ "sp-inherents",
+ "sp-runtime",
+ "thiserror",
+]
+
+[[package]]
+name = "sp-tracing"
+version = "17.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf641a1d17268c8fcfdb8e0fa51a79c2d4222f4cfda5f3944dbdbc384dced8d5"
+dependencies = [
+ "parity-scale-codec",
+ "tracing",
+ "tracing-core",
+ "tracing-subscriber",
+]
+
+[[package]]
+name = "sp-transaction-pool"
+version = "34.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc4bf251059485a7dd38fe4afeda8792983511cc47f342ff4695e2dcae6b5247"
+dependencies = [
+ "sp-api",
+ "sp-runtime",
+]
+
+[[package]]
+name = "sp-transaction-storage-proof"
+version = "34.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c765c2e9817d95f13d42a9f2295c60723464669765c6e5acbacebd2f54932f67"
+dependencies = [
+ "async-trait",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-core",
+ "sp-inherents",
+ "sp-runtime",
+ "sp-trie",
+]
+
+[[package]]
+name = "sp-trie"
+version = "37.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6282aef9f4b6ecd95a67a45bcdb67a71f4a4155c09a53c10add4ffe823db18cd"
+dependencies = [
+ "ahash",
+ "hash-db",
+ "lazy_static",
+ "memory-db",
+ "nohash-hasher",
+ "parity-scale-codec",
+ "parking_lot 0.12.3",
+ "rand",
+ "scale-info",
+ "schnellru",
+ "sp-core",
+ "sp-externalities",
+ "thiserror",
+ "tracing",
+ "trie-db",
+ "trie-root",
+]
+
+[[package]]
+name = "sp-version"
+version = "37.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d521a405707b5be561367cd3d442ff67588993de24062ce3adefcf8437ee9fe1"
+dependencies = [
+ "impl-serde",
+ "parity-scale-codec",
+ "parity-wasm",
+ "scale-info",
+ "serde",
+ "sp-crypto-hashing-proc-macro",
+ "sp-runtime",
+ "sp-std",
+ "sp-version-proc-macro",
+ "thiserror",
+]
+
+[[package]]
+name = "sp-version-proc-macro"
+version = "14.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aee8f6730641a65fcf0c8f9b1e448af4b3bb083d08058b47528188bccc7b7a7"
+dependencies = [
+ "parity-scale-codec",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "sp-wasm-interface"
+version = "21.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b066baa6d57951600b14ffe1243f54c47f9c23dd89c262e17ca00ae8dca58be9"
+dependencies = [
+ "anyhow",
+ "impl-trait-for-tuples",
+ "log",
+ "parity-scale-codec",
+ "wasmtime",
+]
+
+[[package]]
+name = "sp-weights"
+version = "31.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93cdaf72a1dad537bbb130ba4d47307ebe5170405280ed1aa31fa712718a400e"
+dependencies = [
+ "bounded-collections",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "smallvec",
+ "sp-arithmetic",
+ "sp-debug-derive",
+]
+
+[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
+[[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+
+[[package]]
+name = "spinning_top"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
+name = "spki"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
+dependencies = [
+ "base64ct",
+ "der",
+]
+
+[[package]]
+name = "ss58-registry"
+version = "1.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19409f13998e55816d1c728395af0b52ec066206341d939e22e7766df9b494b8"
+dependencies = [
+ "Inflector",
+ "num-format",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_json",
+ "unicode-xid",
+]
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "static_init"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a2a1c578e98c1c16fc3b8ec1328f7659a500737d7a0c6d625e73e830ff9c1f6"
+dependencies = [
+ "bitflags 1.3.2",
+ "cfg_aliases",
+ "libc",
+ "parking_lot 0.11.2",
+ "parking_lot_core 0.8.6",
+ "static_init_macro",
+ "winapi",
+]
+
+[[package]]
+name = "static_init_macro"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1389c88ddd739ec6d3f8f83343764a0e944cd23cfbf126a9796a714b0b6edd6f"
+dependencies = [
+ "cfg_aliases",
+ "memchr",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "str0m"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6706347e49b13373f7ddfafad47df7583ed52083d6fc8a594eb2c80497ef959d"
+dependencies = [
+ "combine",
+ "crc",
+ "fastrand",
+ "hmac 0.12.1",
+ "once_cell",
+ "openssl",
+ "openssl-sys",
+ "sctp-proto",
+ "serde",
+ "sha-1",
+ "thiserror",
+ "tracing",
+]
+
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "strum"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
+
+[[package]]
+name = "strum"
+version = "0.26.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
+dependencies = [
+ "strum_macros 0.26.4",
+]
+
+[[package]]
+name = "strum_macros"
+version = "0.24.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
+dependencies = [
+ "heck 0.4.1",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "strum_macros"
+version = "0.26.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
+dependencies = [
+ "heck 0.5.0",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "substrate-bip39"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca58ffd742f693dc13d69bdbb2e642ae239e0053f6aab3b104252892f856700a"
+dependencies = [
+ "hmac 0.12.1",
+ "pbkdf2",
+ "schnorrkel",
+ "sha2 0.10.8",
+ "zeroize",
+]
+
+[[package]]
+name = "substrate-build-script-utils"
+version = "11.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b285e7d183a32732fdc119f3d81b7915790191fad602b7c709ef247073c77a2e"
+
+[[package]]
+name = "substrate-frame-rpc-system"
+version = "38.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdf4468637471dd481811d0d1ffaf8e8a98165d9ad6b586bfb2911ca1cb081f5"
+dependencies = [
+ "docify",
+ "frame-system-rpc-runtime-api",
+ "futures",
+ "jsonrpsee",
+ "log",
+ "parity-scale-codec",
+ "sc-rpc-api",
+ "sc-transaction-pool-api",
+ "sp-api",
+ "sp-block-builder",
+ "sp-blockchain",
+ "sp-core",
+ "sp-runtime",
+]
+
+[[package]]
+name = "substrate-prometheus-endpoint"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b6772e9c3621b8d067a706dfda6a20db6faa7cde39822c58ffc8588d16409c5"
+dependencies = [
+ "http-body-util",
+ "hyper 1.5.2",
+ "hyper-util",
+ "log",
+ "prometheus",
+ "thiserror",
+ "tokio",
+]
+
+[[package]]
+name = "substrate-wasm-builder"
+version = "24.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf035ffe7335fb24053edfe4d0a5780250eda772082a1b80ae25835dd4c09265"
+dependencies = [
+ "build-helper",
+ "cargo_metadata",
+ "console",
+ "filetime",
+ "jobserver",
+ "parity-wasm",
+ "polkavm-linker",
+ "sp-maybe-compressed-blob",
+ "strum 0.26.3",
+ "tempfile",
+ "toml 0.8.19",
+ "walkdir",
+ "wasm-opt",
+]
+
+[[package]]
+name = "subtle"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
+
+[[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.96"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "unicode-xid",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "system-configuration"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
+dependencies = [
+ "bitflags 2.8.0",
+ "core-foundation",
+ "system-configuration-sys",
+]
+
+[[package]]
+name = "system-configuration-sys"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "tap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
+
+[[package]]
+name = "target-lexicon"
+version = "0.12.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
+
+[[package]]
+name = "tempfile"
+version = "3.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "getrandom",
+ "once_cell",
+ "rustix 0.38.43",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "terminal_size"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9"
+dependencies = [
+ "rustix 0.38.43",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "termtree"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
+
+[[package]]
+name = "thiserror"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+]
+
+[[package]]
+name = "time"
+version = "0.3.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
+dependencies = [
+ "deranged",
+ "itoa",
+ "num-conv",
+ "powerfmt",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+
+[[package]]
+name = "time-macros"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de"
+dependencies = [
+ "num-conv",
+ "time-core",
+]
+
+[[package]]
+name = "tiny-keccak"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
+dependencies = [
+ "crunchy",
+]
+
+[[package]]
+name = "tinystr"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
+dependencies = [
+ "displaydoc",
+ "zerovec",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
+name = "tokio"
+version = "1.43.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e"
+dependencies = [
+ "backtrace",
+ "bytes",
+ "libc",
+ "mio",
+ "parking_lot 0.12.3",
+ "pin-project-lite",
+ "signal-hook-registry",
+ "socket2 0.5.8",
+ "tokio-macros",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
+dependencies = [
+ "rustls 0.21.12",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-stream"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+ "tokio-util",
+]
+
+[[package]]
+name = "tokio-tungstenite"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
+dependencies = [
+ "futures-util",
+ "log",
+ "rustls 0.21.12",
+ "rustls-native-certs",
+ "tokio",
+ "tokio-rustls",
+ "tungstenite",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-io",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "toml"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml"
+version = "0.8.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.22.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
+dependencies = [
+ "indexmap 2.7.0",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "tower"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "pin-project",
+ "pin-project-lite",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-http"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
+dependencies = [
+ "bitflags 2.8.0",
+ "bytes",
+ "http 1.2.0",
+ "http-body 1.0.1",
+ "http-body-util",
+ "pin-project-lite",
+ "tower-layer",
+ "tower-service",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
+
+[[package]]
+name = "tower-service"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
+
+[[package]]
+name = "tracing"
+version = "0.1.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
+dependencies = [
+ "log",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
+dependencies = [
+ "once_cell",
+ "valuable",
+]
+
+[[package]]
+name = "tracing-futures"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
+dependencies = [
+ "pin-project",
+ "tracing",
+]
+
+[[package]]
+name = "tracing-log"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
+dependencies = [
+ "log",
+ "once_cell",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.3.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
+dependencies = [
+ "matchers",
+ "nu-ansi-term",
+ "once_cell",
+ "parking_lot 0.12.3",
+ "regex",
+ "sharded-slab",
+ "smallvec",
+ "thread_local",
+ "time",
+ "tracing",
+ "tracing-core",
+ "tracing-log",
+]
+
+[[package]]
+name = "trie-db"
+version = "0.29.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c992b4f40c234a074d48a757efeabb1a6be88af84c0c23f7ca158950cb0ae7f"
+dependencies = [
+ "hash-db",
+ "log",
+ "rustc-hex",
+ "smallvec",
+]
+
+[[package]]
+name = "trie-root"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4ed310ef5ab98f5fa467900ed906cb9232dd5376597e00fd4cba2a449d06c0b"
+dependencies = [
+ "hash-db",
+]
+
+[[package]]
+name = "trust-dns-proto"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26"
+dependencies = [
+ "async-trait",
+ "cfg-if",
+ "data-encoding",
+ "enum-as-inner 0.5.1",
+ "futures-channel",
+ "futures-io",
+ "futures-util",
+ "idna 0.2.3",
+ "ipnet",
+ "lazy_static",
+ "rand",
+ "smallvec",
+ "socket2 0.4.10",
+ "thiserror",
+ "tinyvec",
+ "tokio",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "trust-dns-proto"
+version = "0.23.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374"
+dependencies = [
+ "async-trait",
+ "cfg-if",
+ "data-encoding",
+ "enum-as-inner 0.6.1",
+ "futures-channel",
+ "futures-io",
+ "futures-util",
+ "idna 0.4.0",
+ "ipnet",
+ "once_cell",
+ "rand",
+ "smallvec",
+ "thiserror",
+ "tinyvec",
+ "tokio",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "trust-dns-resolver"
+version = "0.23.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6"
+dependencies = [
+ "cfg-if",
+ "futures-util",
+ "ipconfig",
+ "lru-cache",
+ "once_cell",
+ "parking_lot 0.12.3",
+ "rand",
+ "resolv-conf",
+ "smallvec",
+ "thiserror",
+ "tokio",
+ "tracing",
+ "trust-dns-proto 0.23.2",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
+
+[[package]]
+name = "tt-call"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4f195fd851901624eee5a58c4bb2b4f06399148fcd0ed336e6f1cb60a9881df"
+
+[[package]]
+name = "tungstenite"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9"
+dependencies = [
+ "byteorder",
+ "bytes",
+ "data-encoding",
+ "http 0.2.12",
+ "httparse",
+ "log",
+ "rand",
+ "rustls 0.21.12",
+ "sha1",
+ "thiserror",
+ "url",
+ "utf-8",
+]
+
+[[package]]
+name = "twox-hash"
+version = "1.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
+dependencies = [
+ "cfg-if",
+ "digest 0.10.7",
+ "rand",
+ "static_assertions",
+]
+
+[[package]]
+name = "typenum"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+
+[[package]]
+name = "uint"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52"
+dependencies = [
+ "byteorder",
+ "crunchy",
+ "hex",
+ "static_assertions",
+]
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-width"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
+
+[[package]]
+name = "unicode-width"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
+
+[[package]]
+name = "universal-hash"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
+dependencies = [
+ "crypto-common",
+ "subtle 2.6.1",
+]
+
+[[package]]
+name = "unsigned-varint"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105"
+dependencies = [
+ "asynchronous-codec",
+ "bytes",
+ "futures-io",
+ "futures-util",
+]
+
+[[package]]
+name = "unsigned-varint"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06"
+dependencies = [
+ "bytes",
+ "tokio-util",
+]
+
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
+[[package]]
+name = "url"
+version = "2.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
+dependencies = [
+ "form_urlencoded",
+ "idna 1.0.3",
+ "percent-encoding",
+]
+
+[[package]]
+name = "utf-8"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
+[[package]]
+name = "utf16_iter"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
+
+[[package]]
+name = "utf8_iter"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
+name = "valuable"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+
+[[package]]
+name = "w3f-bls"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70a3028804c8bbae2a97a15b71ffc0e308c4b01a520994aafa77d56e94e19024"
+dependencies = [
+ "ark-bls12-377",
+ "ark-bls12-381",
+ "ark-ec",
+ "ark-ff",
+ "ark-serialize",
+ "ark-serialize-derive",
+ "arrayref",
+ "constcat",
+ "digest 0.10.7",
+ "rand",
+ "rand_chacha",
+ "rand_core",
+ "sha2 0.10.8",
+ "sha3",
+ "thiserror",
+ "zeroize",
+]
+
+[[package]]
+name = "walkdir"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
+dependencies = [
+ "same-file",
+ "winapi-util",
+]
+
+[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "rustversion",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
+dependencies = [
+ "bumpalo",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.50"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "once_cell",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "wasm-instrument"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a47ecb37b9734d1085eaa5ae1a81e60801fd8c28d4cabdd8aedb982021918bc"
+dependencies = [
+ "parity-wasm",
+]
+
+[[package]]
+name = "wasm-opt"
+version = "0.116.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fd87a4c135535ffed86123b6fb0f0a5a0bc89e50416c942c5f0662c645f679c"
+dependencies = [
+ "anyhow",
+ "libc",
+ "strum 0.24.1",
+ "strum_macros 0.24.3",
+ "tempfile",
+ "thiserror",
+ "wasm-opt-cxx-sys",
+ "wasm-opt-sys",
+]
+
+[[package]]
+name = "wasm-opt-cxx-sys"
+version = "0.116.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c57b28207aa724318fcec6575fe74803c23f6f266fce10cbc9f3f116762f12e"
+dependencies = [
+ "anyhow",
+ "cxx",
+ "cxx-build",
+ "wasm-opt-sys",
+]
+
+[[package]]
+name = "wasm-opt-sys"
+version = "0.116.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a1cce564dc768dacbdb718fc29df2dba80bd21cb47d8f77ae7e3d95ceb98cbe"
+dependencies = [
+ "anyhow",
+ "cc",
+ "cxx",
+ "cxx-build",
+]
+
+[[package]]
+name = "wasm-timer"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f"
+dependencies = [
+ "futures",
+ "js-sys",
+ "parking_lot 0.11.2",
+ "pin-utils",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
+name = "wasmparser"
+version = "0.102.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48134de3d7598219ab9eaf6b91b15d8e50d31da76b8519fe4ecfcec2cf35104b"
+dependencies = [
+ "indexmap 1.9.3",
+ "url",
+]
+
+[[package]]
+name = "wasmtime"
+version = "8.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f907fdead3153cb9bfb7a93bbd5b62629472dc06dee83605358c64c52ed3dda9"
+dependencies = [
+ "anyhow",
+ "bincode",
+ "cfg-if",
+ "indexmap 1.9.3",
+ "libc",
+ "log",
+ "object 0.30.4",
+ "once_cell",
+ "paste",
+ "psm",
+ "rayon",
+ "serde",
+ "target-lexicon",
+ "wasmparser",
+ "wasmtime-cache",
+ "wasmtime-cranelift",
+ "wasmtime-environ",
+ "wasmtime-jit",
+ "wasmtime-runtime",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "wasmtime-asm-macros"
+version = "8.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3b9daa7c14cd4fa3edbf69de994408d5f4b7b0959ac13fa69d465f6597f810d"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "wasmtime-cache"
+version = "8.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c86437fa68626fe896e5afc69234bb2b5894949083586535f200385adfd71213"
+dependencies = [
+ "anyhow",
+ "base64 0.21.7",
+ "bincode",
+ "directories-next",
+ "file-per-thread-logger",
+ "log",
+ "rustix 0.36.17",
+ "serde",
+ "sha2 0.10.8",
+ "toml 0.5.11",
+ "windows-sys 0.45.0",
+ "zstd 0.11.2+zstd.1.5.2",
+]
+
+[[package]]
+name = "wasmtime-cranelift"
+version = "8.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1cefde0cce8cb700b1b21b6298a3837dba46521affd7b8c38a9ee2c869eee04"
+dependencies = [
+ "anyhow",
+ "cranelift-codegen",
+ "cranelift-entity",
+ "cranelift-frontend",
+ "cranelift-native",
+ "cranelift-wasm",
+ "gimli 0.27.3",
+ "log",
+ "object 0.30.4",
+ "target-lexicon",
+ "thiserror",
+ "wasmparser",
+ "wasmtime-cranelift-shared",
+ "wasmtime-environ",
+]
+
+[[package]]
+name = "wasmtime-cranelift-shared"
+version = "8.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd041e382ef5aea1b9fc78442394f1a4f6d676ce457e7076ca4cb3f397882f8b"
+dependencies = [
+ "anyhow",
+ "cranelift-codegen",
+ "cranelift-native",
+ "gimli 0.27.3",
+ "object 0.30.4",
+ "target-lexicon",
+ "wasmtime-environ",
+]
+
+[[package]]
+name = "wasmtime-environ"
+version = "8.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a990198cee4197423045235bf89d3359e69bd2ea031005f4c2d901125955c949"
+dependencies = [
+ "anyhow",
+ "cranelift-entity",
+ "gimli 0.27.3",
+ "indexmap 1.9.3",
+ "log",
+ "object 0.30.4",
+ "serde",
+ "target-lexicon",
+ "thiserror",
+ "wasmparser",
+ "wasmtime-types",
+]
+
+[[package]]
+name = "wasmtime-jit"
+version = "8.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0de48df552cfca1c9b750002d3e07b45772dd033b0b206d5c0968496abf31244"
+dependencies = [
+ "addr2line 0.19.0",
+ "anyhow",
+ "bincode",
+ "cfg-if",
+ "cpp_demangle",
+ "gimli 0.27.3",
+ "log",
+ "object 0.30.4",
+ "rustc-demangle",
+ "serde",
+ "target-lexicon",
+ "wasmtime-environ",
+ "wasmtime-jit-debug",
+ "wasmtime-jit-icache-coherence",
+ "wasmtime-runtime",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "wasmtime-jit-debug"
+version = "8.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e0554b84c15a27d76281d06838aed94e13a77d7bf604bbbaf548aa20eb93846"
+dependencies = [
+ "object 0.30.4",
+ "once_cell",
+ "rustix 0.36.17",
+]
+
+[[package]]
+name = "wasmtime-jit-icache-coherence"
+version = "8.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aecae978b13f7f67efb23bd827373ace4578f2137ec110bbf6a4a7cde4121bbd"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "wasmtime-runtime"
+version = "8.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "658cf6f325232b6760e202e5255d823da5e348fdea827eff0a2a22319000b441"
+dependencies = [
+ "anyhow",
+ "cc",
+ "cfg-if",
+ "indexmap 1.9.3",
+ "libc",
+ "log",
+ "mach",
+ "memfd",
+ "memoffset",
+ "paste",
+ "rand",
+ "rustix 0.36.17",
+ "wasmtime-asm-macros",
+ "wasmtime-environ",
+ "wasmtime-jit-debug",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "wasmtime-types"
+version = "8.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4f6fffd2a1011887d57f07654dd112791e872e3ff4a2e626aee8059ee17f06f"
+dependencies = [
+ "cranelift-entity",
+ "serde",
+ "thiserror",
+ "wasmparser",
+]
+
+[[package]]
+name = "web-sys"
+version = "0.3.77"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "webpki"
+version = "0.22.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53"
+dependencies = [
+ "ring 0.17.8",
+ "untrusted 0.9.0",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.25.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
+
+[[package]]
+name = "which"
+version = "4.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
+dependencies = [
+ "either",
+ "home",
+ "once_cell",
+ "rustix 0.38.43",
+]
+
+[[package]]
+name = "wide"
+version = "0.7.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41b5576b9a81633f3e8df296ce0063042a73507636cbe956c61133dd7034ab22"
+dependencies = [
+ "bytemuck",
+ "safe_arch",
+]
+
+[[package]]
+name = "widestring"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "efc5cf48f83140dcaab716eeaea345f9e93d0018fb81162753a3f76c3397b538"
+dependencies = [
+ "windows-core 0.53.0",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9dcc5b895a6377f1ab9fa55acedab1fd5ac0db66ad1e6c7f47e28a22e446a5dd"
+dependencies = [
+ "windows-result",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-result"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.5",
+ "windows_aarch64_msvc 0.48.5",
+ "windows_i686_gnu 0.48.5",
+ "windows_i686_msvc 0.48.5",
+ "windows_x86_64_gnu 0.48.5",
+ "windows_x86_64_gnullvm 0.48.5",
+ "windows_x86_64_msvc 0.48.5",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "winnow"
+version = "0.6.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "winreg"
+version = "0.50.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
+dependencies = [
+ "cfg-if",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "write16"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
+
+[[package]]
+name = "writeable"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
+
+[[package]]
+name = "wyz"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
+dependencies = [
+ "tap",
+]
+
+[[package]]
+name = "x25519-dalek"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"
+dependencies = [
+ "curve25519-dalek",
+ "rand_core",
+ "serde",
+ "zeroize",
+]
+
+[[package]]
+name = "x509-parser"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da"
+dependencies = [
+ "asn1-rs 0.5.2",
+ "data-encoding",
+ "der-parser 8.2.0",
+ "lazy_static",
+ "nom",
+ "oid-registry 0.6.1",
+ "rusticata-macros",
+ "thiserror",
+ "time",
+]
+
+[[package]]
+name = "x509-parser"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69"
+dependencies = [
+ "asn1-rs 0.6.2",
+ "data-encoding",
+ "der-parser 9.0.0",
+ "lazy_static",
+ "nom",
+ "oid-registry 0.7.1",
+ "rusticata-macros",
+ "thiserror",
+ "time",
+]
+
+[[package]]
+name = "xml-rs"
+version = "0.8.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4"
+
+[[package]]
+name = "xmltree"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb"
+dependencies = [
+ "xml-rs",
+]
+
+[[package]]
+name = "yamux"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed0164ae619f2dc144909a9f082187ebb5893693d8c0196e8085283ccd4b776"
+dependencies = [
+ "futures",
+ "log",
+ "nohash-hasher",
+ "parking_lot 0.12.3",
+ "pin-project",
+ "rand",
+ "static_assertions",
+]
+
+[[package]]
+name = "yasna"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
+dependencies = [
+ "time",
+]
+
+[[package]]
+name = "yoke"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
+dependencies = [
+ "serde",
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+ "synstructure 0.13.1",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.7.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+dependencies = [
+ "byteorder",
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.7.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "zerofrom"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+ "synstructure 0.13.1",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
+dependencies = [
+ "zeroize_derive",
+]
+
+[[package]]
+name = "zeroize_derive"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "zstd"
+version = "0.11.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
+dependencies = [
+ "zstd-safe 5.0.2+zstd.1.5.2",
+]
+
+[[package]]
+name = "zstd"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c"
+dependencies = [
+ "zstd-safe 6.0.6",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "5.0.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
+dependencies = [
+ "libc",
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "6.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581"
+dependencies = [
+ "libc",
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-sys"
+version = "2.0.13+zstd.1.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa"
+dependencies = [
+ "cc",
+ "pkg-config",
+]
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..3574848
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,78 @@
+[profile.release]
+panic = "unwind"
+
+[workspace]
+members = [
+	"node",
+	"runtime",
+	"multi-pow",
+]
+resolver = "2"
+
+[workspace.dependencies]
+
+# Crates.io dependencies
+async-trait = { version = "0.1.53" }
+clap = { version = "4.5.3" }
+futures = { version = "0.3.30" }
+hex = "0.4"
+hex-literal = "0.4.1"
+jsonrpsee = { version = "0.23.2" }
+log = "0.4.25"
+md5 = "0.7.0"
+parity-scale-codec = { version = "3.1.2", features = [ "derive" ], default-features = false }
+rand = { version = "0.8.5", features = [ "small_rng" ] }
+scale-info = { version = "2.11.1", default-features = false }
+serde = "1.0.137"
+serde_json = { version = "1.0.114", default-features = false }
+sha3 = "0.10.1"
+
+# Local Dependencies
+academy-pow-runtime = { path = "../runtime" }
+multi-pow = { default-features = false, path = "../multi-pow" }
+
+# Polkadot SDK Dependencies
+frame-executive = { version = "37.0.0", default-features = false }
+frame-support = { version = "37.0.0", default-features = false }
+frame-system = { version = "37.0.0", default-features = false }
+frame-system-rpc-runtime-api = { version = "34.0.0", default-features = false }
+pallet-balances = { version = "38.0.0", default-features = false }
+pallet-timestamp = { version = "36.0.0", default-features = false }
+pallet-transaction-payment = { version = "37.0.0", default-features = false }
+pallet-transaction-payment-rpc = { version = "40.0.0" }
+pallet-transaction-payment-rpc-runtime-api = { version = "37.0.0", default-features = false }
+sc-basic-authorship = { version = "0.44.0" }
+sc-chain-spec = { version = "37.0.0" }
+sc-cli = { version = "0.46.0", default-features = false }
+sc-client-api = { version = "37.0.0" }
+sc-consensus = { version = "0.43.0" }
+sc-consensus-manual-seal = { version = "0.45.0" }
+sc-consensus-pow = { version = "0.43.0" }
+sc-executor = { version = "0.40.0" }
+sc-network = { version = "0.44.0" }
+sc-rpc-api = { version = "0.43.0" }
+sc-service = { version = "0.45.0", default-features = false }
+sc-telemetry = { version = "24.0.0" }
+sc-transaction-pool = { version = "37.0.0" }
+sc-transaction-pool-api = { version = "37.0.0" }
+sp-api = { version = "34.0.0", default-features = false }
+sp-block-builder = { version = "34.0.0", default-features = false }
+sp-blockchain = { version = "37.0.0" }
+sp-consensus = { version = "0.40.0" }
+sp-consensus-pow = { version = "0.40.0", default-features = false }
+sp-core = { version = "34.0.0", default-features = false }
+sp-genesis-builder = { version = "0.15.0", default-features = false }
+sp-inherents = { version = "34.0.0", default-features = false }
+sp-io = { version = "38.0.0", default-features = false }
+sp-keyring = { version = "39.0.0" }
+sp-keystore = { version = "0.40.0" }
+sp-offchain = { version = "34.0.0", default-features = false }
+sp-runtime = { version = "39.0.0", default-features = false }
+sp-session = { version = "35.0.0", default-features = false }
+sp-std = { version = "14.0.0", default-features = false }
+sp-timestamp = { version = "34.0.0" }
+sp-transaction-pool = { version = "34.0.0", default-features = false }
+sp-version = { version = "37.0.0", default-features = false }
+substrate-build-script-utils = { version = "11.0.0", default-features = false }
+substrate-frame-rpc-system = { version = "38.0.0" }
+substrate-wasm-builder = { version = "24.0.0", default-features = false }
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..cf1ab25
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org>
diff --git a/multi-pow/Cargo.toml b/multi-pow/Cargo.toml
new file mode 100644
index 0000000..0a3c115
--- /dev/null
+++ b/multi-pow/Cargo.toml
@@ -0,0 +1,29 @@
+[package]
+authors = [ "@danielbui12" ]
+description = "a concrete Substrate PoW algorithm that supports multiple hashing algorithms"
+edition = "2021"
+name = "multi-pow"
+version = "3.0.0"
+
+[dependencies]
+md5 = { workspace = true }
+parity-scale-codec = { workspace = true }
+scale-info = { workspace = true }
+sha3 = { workspace = true, optional = true }
+
+sc-client-api = { optional = true, workspace = true }
+sc-consensus-pow = { optional = true, workspace = true }
+sp-api = { workspace = true }
+sp-consensus-pow = { workspace = true }
+sp-core = { workspace = true }
+sp-runtime = { workspace = true }
+
+log = { workspace = true }
+
+[features]
+default = [ "std" ]
+std = [
+	"sha3",
+	"sc-consensus-pow",
+	"sc-client-api",
+]
diff --git a/multi-pow/src/lib.rs b/multi-pow/src/lib.rs
new file mode 100644
index 0000000..8c36e58
--- /dev/null
+++ b/multi-pow/src/lib.rs
@@ -0,0 +1,421 @@
+//! This crate represents a concrete Substrate PoW algorithm.
+//!
+//! It is multi-pow in the sense that there are multiple supported hashing algorithms.
+//! A seal with any of the supported hashing algorithms will be accepted.
+//!
+//! The purpose of this design is to demonstrate hard and soft forks by adding and removing valid hashing algorithms.
+//! While there is no precedent for changing hashing algorithms in the real world yet, it is conceivable that
+//! a chain may want to upgrade to a new algorithm when the old one is suspected weak.
+//! In any case, the point is that we want to demonstrate hard and soft forks in an understandable way,
+//! the multiple hashing algorithms achieves that well.
+//!
+//! In the future, the hope is that there will be a dedicated difficulty threshold for each hashing algorithm.
+//! But currently the Substrate PoW crates are not that flexible.
+//! We could solve it by adding a pre-digest that includes information about what hashing algo is being used
+//! for the runtime to use later in the difficulty adjustment.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use core::str::FromStr;
+#[cfg(feature = "std")]
+use std::sync::Arc;
+
+use parity_scale_codec::{Decode, Encode};
+#[cfg(feature = "std")]
+use sc_consensus_pow::{Error, PowAlgorithm};
+#[cfg(feature = "std")]
+use sha3::{Digest, Keccak256, Sha3_256};
+#[cfg(feature = "std")]
+use sp_api::ProvideRuntimeApi;
+#[cfg(feature = "std")]
+use sp_consensus_pow::DifficultyApi;
+#[cfg(feature = "std")]
+use sp_consensus_pow::Seal as RawSeal;
+use sp_consensus_pow::TotalDifficulty;
+use sp_core::{H256, U256};
+#[cfg(feature = "std")]
+use sp_runtime::generic::BlockId;
+#[cfg(feature = "std")]
+use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
+
+/// A struct that represents a difficulty threshold.
+/// Unlike a normal PoW algorithm this struct has a separate threshold for each hash
+#[derive(
+    Clone,
+    Copy,
+    PartialEq,
+    Eq,
+    PartialOrd,
+    Ord,
+    Encode,
+    Decode,
+    Debug,
+    Default,
+    scale_info::TypeInfo,
+)]
+pub struct Threshold {
+    pub md5: U256,
+    pub sha3: U256,
+    pub keccak: U256,
+}
+
+// This trait does not seem to be fully baked in the Substrate PoW code
+// But we do need some kind of sinsible impl here so the node can import blocks.
+// so I will not use it for now.
+impl TotalDifficulty for Threshold {
+    fn increment(&mut self, other: Threshold) {
+        self.md5 += other.md5;
+        self.sha3 += other.sha3;
+        self.keccak += other.keccak;
+    }
+}
+
+/// An enum that represents the supported hash types
+#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, Debug)]
+pub enum SupportedHashes {
+    Md5,
+    Sha3,
+    Keccak,
+}
+
+impl Default for SupportedHashes {
+    fn default() -> Self {
+        Self::Sha3
+    }
+}
+
+/// A struct that represents a concrete hash value tagged with what hashing
+///  algorithm was used to compute it.
+#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, Debug, Default)]
+pub struct MultiHash {
+    pub algo: SupportedHashes,
+    pub value: H256,
+}
+
+/// Determine whether the given hash satisfies the given difficulty.
+/// The test is done by multiplying the two together. If the product
+/// overflows the bounds of U256, then the product (and thus the hash)
+/// was too high.
+pub fn simple_hash_meets_difficulty(hash: &H256, difficulty: U256) -> bool {
+    let num_hash = U256::from_little_endian(&hash[..]);
+    let (_, overflowed) = num_hash.overflowing_mul(difficulty);
+
+    !overflowed
+}
+
+pub fn multi_hash_meets_difficulty(hash: &MultiHash, difficulty: Threshold) -> bool {
+    match hash.algo {
+        SupportedHashes::Md5 => simple_hash_meets_difficulty(&hash.value, difficulty.md5),
+        SupportedHashes::Sha3 => simple_hash_meets_difficulty(&hash.value, difficulty.sha3),
+        SupportedHashes::Keccak => simple_hash_meets_difficulty(&hash.value, difficulty.keccak),
+    }
+}
+
+/// A Seal struct that will be encoded to a Vec<u8> as used as the
+/// `RawSeal` type.
+#[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)]
+pub struct Seal {
+    pub work: MultiHash,
+    pub difficulty: Threshold,
+    pub nonce: U256,
+}
+
+/// A not-yet-computed attempt to solve the proof of work. Calling the
+/// compute method will compute the hash and return the seal.
+#[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)]
+pub struct Compute {
+    pub difficulty: Threshold,
+    pub pre_hash: H256,
+    pub nonce: U256,
+}
+
+#[cfg(feature = "std")]
+impl Compute {
+    pub fn compute(self, algo: SupportedHashes) -> Seal {
+        let value = match algo {
+            SupportedHashes::Md5 => {
+                // The md5 is only 16 byte output, so we just concatenate it twice to
+                // get an H256
+                let bytes = *md5::compute(&self.encode()[..]);
+                let mut doubled = [0u8; 32];
+                doubled[0..16].copy_from_slice(&bytes[0..16]);
+                doubled[16..32].copy_from_slice(&bytes[0..16]);
+
+                H256::from(doubled)
+            }
+            SupportedHashes::Sha3 => {
+                H256::from_slice(Sha3_256::digest(&self.encode()[..]).as_slice())
+            }
+            SupportedHashes::Keccak => {
+                H256::from_slice(Keccak256::digest(&self.encode()[..]).as_slice())
+            }
+        };
+
+        Seal {
+            nonce: self.nonce,
+            difficulty: self.difficulty,
+            work: MultiHash { algo, value },
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+/// A complete PoW Algorithm that uses multiple hashing algorithms.
+/// Needs a reference to the client so it can grab the difficulty from the runtime.
+pub struct MultiPow<C> {
+    client: Arc<C>,
+    fork_config: ForkingConfig,
+}
+
+#[cfg(feature = "std")]
+impl<C> MultiPow<C> {
+    pub fn new(client: Arc<C>, fork_config: ForkingConfig) -> Self {
+        Self {
+            client,
+            fork_config,
+        }
+    }
+}
+
+//TODO could maybe derive clone_no_bound
+#[cfg(feature = "std")]
+impl<C> Clone for MultiPow<C> {
+    fn clone(&self) -> Self {
+        Self::new(self.client.clone(), self.fork_config)
+    }
+}
+
+// Here we implement the general PowAlgorithm trait for our concrete algorithm.
+#[cfg(feature = "std")]
+impl<B: BlockT<Hash = H256>, C> PowAlgorithm<B> for MultiPow<C>
+where
+    C: ProvideRuntimeApi<B>,
+    C::Api: DifficultyApi<B, Threshold>,
+    C: sc_client_api::HeaderBackend<B>,
+{
+    type Difficulty = Threshold;
+
+    fn difficulty(&self, parent: B::Hash) -> Result<Self::Difficulty, Error<B>> {
+        let difficulty = self
+            .client
+            .runtime_api()
+            .difficulty(parent)
+            .map_err(|err| {
+                sc_consensus_pow::Error::Environment(format!(
+                    "Fetching difficulty from runtime failed: {:?}",
+                    err
+                ))
+            })?;
+
+        Ok(difficulty)
+    }
+
+    fn verify(
+        &self,
+        parent_id: &BlockId<B>,
+        pre_hash: &H256,
+        pre_digest: Option<&[u8]>,
+        seal: &RawSeal,
+        difficulty: Self::Difficulty,
+    ) -> Result<bool, Error<B>> {
+        // Try to construct a seal object by decoding the raw seal given
+        let seal = match Seal::decode(&mut &seal[..]) {
+            Ok(seal) => seal,
+            Err(_) => return Ok(false),
+        };
+
+        log::debug!("✅ Decode seal passed!");
+
+        let Some(_encoded_pre_digest) = pre_digest else {
+            return Ok(false);
+        };
+
+        log::debug!("✅ Checksum digest passed!");
+
+        // // TODO idk why this always return md5 only
+        // let algo_from_predigest = match SupportedHashes::decode(&mut &encoded_pre_digest[..]) {
+        //     Ok(algo) => algo,
+        //     Err(_) => return Ok(false),
+        // };
+
+        // log::debug!("✅ Get algorithm from digest passed!");
+
+        // // Check that the pre-digest algo matches the seal algo
+        // // TODO it shouldn't be necessary to have both.
+        // if seal.work.algo != algo_from_predigest {
+        //     return Ok(false);
+        // }
+
+        // log::debug!("✅ Checksum algorithm from seal passed!");
+
+        // This is where we handle forks on the verification side.
+        // We will still need to handle it in the mining algorithm somewhere.
+        // Currently we make the miner configure what algo they mine manually with their cli.
+        let parent_number: u32 = match parent_id {
+            BlockId::Hash(h) => *self
+                .client
+                .header(*h)
+                .expect("Database should perform lookup successfully")
+                .expect("parent header should be present in the db")
+                .number(),
+            BlockId::Number(n) => *n,
+        }
+        .try_into()
+        .map_err(|_| ())
+        .expect("Block numbers can be converted to u32 (because they are u32)");
+
+        log::debug!("✅ Checksum parent block number passed!");
+
+        // Here we handle the forking logic according the the node operator's request.
+        let valid_algorithm = match self.fork_config {
+            ForkingConfig::Manual => manual_fork_validation(parent_number, seal.work.algo),
+            ForkingConfig::Automatic(fork_heights, maxi_position) => {
+                auto_fork_validation(parent_number, seal.work.algo, fork_heights, maxi_position)
+            }
+        };
+
+        if !valid_algorithm {
+            return Ok(false);
+        }
+
+        log::debug!("✅ Valid algorithm!");
+
+        // See whether the hash meets the difficulty requirement. If not, fail fast.
+        if !multi_hash_meets_difficulty(&seal.work, difficulty) {
+            return Ok(false);
+        }
+
+        log::debug!("✅ Checksum difficulty passed!");
+
+        // Make sure the provided work actually comes from the correct pre_hash
+        let compute = Compute {
+            difficulty,
+            pre_hash: *pre_hash,
+            nonce: seal.nonce,
+        };
+
+        if compute.compute(seal.work.algo) != seal {
+            return Ok(false);
+        }
+
+        log::debug!("✅ Re-compute passed!");
+
+        log::debug!("🛠️ All passed, append the block to the chain ...");
+
+        Ok(true)
+    }
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+///
+pub struct ForkHeights {
+    /// The block height to perform the soft fork that adds sha3 and keccak support.
+    pub add_sha3_keccak: u32,
+    /// The block height to perform the hard fork that removes md5 support.
+    pub remove_md5: u32,
+    /// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
+    pub split_sha3_keccak: u32,
+}
+
+/// Various political positions a node could take when the network is forking into
+/// keccak maxis and sha3 maxis
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub enum MaxiPosition {
+    /// Allow all blocks, both sha3 and keccak
+    NoMaxi,
+    /// Only allow sha3 blocks
+    Sha3Maxi,
+    /// Only allow keccak blocks
+    KeccakMaxi,
+    /// Only allow a single type of blocks. Which type it is is determined by what algo the node is mining.
+    FollowMining,
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+/// The actual properly typed config after we're done working around all the BS.
+pub enum ForkingConfig {
+    ///
+    Manual,
+    ///
+    Automatic(ForkHeights, MaxiPosition),
+}
+
+impl FromStr for MaxiPosition {
+    type Err = ();
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        Ok(match &s.to_lowercase()[..] {
+            "allow-all" | "allowall" | "no-maxi" | "nomaxi" => Self::NoMaxi,
+            "sha3-maxi" | "sha3maxi" => Self::Sha3Maxi,
+            "keccak-maxi" | "keccakmaxi" => Self::KeccakMaxi,
+            _ => Self::FollowMining,
+        })
+    }
+}
+
+/// Manual mode, the node operator manually specifies which hashing algorithms are valid through the mining client.
+/// If you would like to do a fork, simply allow, un-allow some algorithms to check it.
+fn manual_fork_validation(_parent_number: u32, algo: SupportedHashes) -> bool {
+    use SupportedHashes::*;
+
+    // To begin with, allow all algorithms.
+    // After the fork height this check is skipped so all the hashes become valid.
+    match algo {
+        Md5 => true,
+        Sha3 => true,
+        Keccak => true,
+    }
+}
+
+/// In automatic mode, the `ForkHeights` and `MaxiPosition` structs define the forking schedule
+/// and the node's behavior during the contentious fork
+/// (where the network splits into two chains supporting different hashing algorithms).
+/// The validation logic considers the parent block height,
+/// forking configuration parameters, and the hashing algorithm used in the PoW solution to determine its validity.
+fn auto_fork_validation(
+    parent_number: u32,
+    algo: SupportedHashes,
+    fork_heights: ForkHeights,
+    maxi_position: MaxiPosition,
+) -> bool {
+    use MaxiPosition::*;
+    use SupportedHashes::*;
+
+    log::debug!("parent_number: {:?}", parent_number);
+    log::debug!("fork_heights: {:?}", fork_heights);
+
+    if parent_number < fork_heights.add_sha3_keccak {
+        // To begin with we only allow md5 hashes for our pow.
+        // After the fork height this check is skipped so all the hashes become valid.
+        match algo {
+            Md5 => true,
+            Sha3 => false,
+            Keccak => false,
+        }
+    } else if parent_number < fork_heights.remove_md5 {
+        // After the first fork, all three algos become valid.
+        match algo {
+            Md5 => true,
+            Sha3 => true,
+            Keccak => true,
+        }
+    } else if parent_number < fork_heights.split_sha3_keccak {
+        // After the second fork, md5 is no longer valid.
+        match algo {
+            Md5 => false,
+            Sha3 => true,
+            Keccak => true,
+        }
+    } else {
+        // Finally we have the contentious fork.
+        // Our behavior here depends which maxi position we have taken.
+        #[allow(clippy::match_like_matches_macro)]
+        match (algo, maxi_position) {
+            (Sha3, Sha3Maxi) => true,
+            (Sha3, NoMaxi) => true,
+            (Keccak, KeccakMaxi) => true,
+            (Keccak, NoMaxi) => true,
+            _ => false,
+        }
+    }
+}
diff --git a/node/Cargo.toml b/node/Cargo.toml
new file mode 100644
index 0000000..6ace2b0
--- /dev/null
+++ b/node/Cargo.toml
@@ -0,0 +1,55 @@
+[package]
+authors = [ "@danielbui12" ]
+build = "build.rs"
+edition = "2021"
+name = "academy-pow"
+version = "3.0.0"
+
+[dependencies]
+clap = { workspace = true }
+futures = { workspace = true }
+hex = { workspace = true }
+log = { workspace = true }
+parity-scale-codec = { workspace = true }
+rand = { workspace = true }
+serde_json = { workspace = true }
+serde = { workspace = true }
+sha3 = { workspace = true }
+jsonrpsee = { workspace = true }
+
+# Local Dependencies
+academy-pow-runtime = { path = "../runtime" }
+multi-pow = { path = "../multi-pow" }
+
+# Polkadot SDK
+pallet-transaction-payment-rpc = { workspace = true }
+sc-rpc-api = { workspace = true }
+sp-block-builder = { workspace = true }
+substrate-frame-rpc-system = { workspace = true }
+sc-basic-authorship = { workspace = true }
+sc-chain-spec = { workspace = true }
+sc-cli = { workspace = true }
+sc-client-api = { workspace = true }
+sc-consensus = { workspace = true }
+sc-consensus-manual-seal = { workspace = true }
+sc-consensus-pow = { workspace = true }
+sc-executor = { workspace = true }
+sc-network = { workspace = true }
+sc-service = { workspace = true }
+sc-telemetry = { workspace = true }
+sc-transaction-pool = { workspace = true }
+sc-transaction-pool-api = { workspace = true }
+sp-api = { workspace = true }
+sp-blockchain = { workspace = true }
+sp-consensus = { workspace = true }
+sp-consensus-pow = { workspace = true }
+sp-core = { workspace = true }
+sp-inherents = { workspace = true }
+sp-io = { workspace = true, default-features = true}
+sp-keyring = { workspace = true }
+sp-runtime = { workspace = true }
+sp-timestamp = { workspace = true }
+sp-transaction-pool = { workspace = true }
+
+[build-dependencies]
+substrate-build-script-utils = { workspace = true }
diff --git a/node/build.rs b/node/build.rs
new file mode 100644
index 0000000..f97fd98
--- /dev/null
+++ b/node/build.rs
@@ -0,0 +1,4 @@
+fn main() {
+    substrate_build_script_utils::generate_cargo_keys();
+    substrate_build_script_utils::rerun_if_git_head_changed();
+}
diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs
new file mode 100644
index 0000000..a8e1732
--- /dev/null
+++ b/node/src/chain_spec.rs
@@ -0,0 +1,188 @@
+use std::str::FromStr;
+
+use academy_pow_runtime::{
+    AccountId,
+    SS58Prefix,
+    Signature,
+    TOKEN_DECIMALS,
+    TOKEN_SYMBOL,
+    WASM_BINARY,
+};
+use multi_pow::{ForkHeights, ForkingConfig, MaxiPosition};
+use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
+use sc_service::ChainType;
+use serde::{Deserialize, Serialize};
+use sp_core::{sr25519, Pair, Public};
+use sp_core::{ByteArray, H256};
+use sp_runtime::traits::{IdentifyAccount, Verify};
+
+/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
+pub type ChainSpec = sc_service::GenericChainSpec<ForkingExtensions>;
+
+/// PoW and Forking related chain spec extensions to configure the client side forking behavior.
+///
+/// The forks here are all related to adding and removing hash algorithms from the PoW.
+/// The chain begins supporting only md5. Later is adds sha3 and keccak. Later it removes md5.
+/// And finally there is a contentious fork where people become maxis.
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]
+#[serde(deny_unknown_fields)]
+pub struct ForkingExtensions {
+    /// Manual mode is intended for when we you are running a live workshop.
+    /// No forking happens automatically. Rather, you have to hard-code the forks.
+    ///
+    /// If manual mode is enabled, the rest of the parameters are ignored.
+    /// This should really be an enum, but I have to work around the broken extension system.
+    ///
+    /// Aww damn it! I can't even use bool in this broken system? Okay then I guess 0 means automatic mode
+    /// and anything else means manual mode.
+    pub manual_mode: u32,
+    /// The block height to perform the soft fork that adds sha3 and keccak support.
+    pub add_sha3_keccak: u32,
+    /// The block height to perform the hard fork that removes md5 support.
+    pub remove_md5: u32,
+    /// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
+    pub split_sha3_keccak: u32,
+    // Damn extension thing is so fragile, I can't even use an enum here.
+    // Let alone that time I tried to use the forked value feature.
+    /// The political position that this node will take at the contentious fork.
+    pub maxi_position: String,
+}
+
+impl From<&ForkingExtensions> for ForkingConfig {
+    fn from(e: &ForkingExtensions) -> Self {
+        if e.manual_mode > 0 {
+            return Self::Manual;
+        }
+
+        let fork_heights = ForkHeights {
+            add_sha3_keccak: e.add_sha3_keccak,
+            remove_md5: e.remove_md5,
+            split_sha3_keccak: e.split_sha3_keccak,
+        };
+
+        let maxi_position =
+            MaxiPosition::from_str(&e.maxi_position).expect("Should have a valid maxi position...");
+
+        Self::Automatic(fork_heights, maxi_position)
+    }
+}
+
+impl ForkingExtensions {
+    /// Try to get the extension from the given `ChainSpec`.
+    pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {
+        sc_chain_spec::get_extension(chain_spec.extensions())
+    }
+}
+
+/// Generate a crypto pair from seed.
+pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
+    TPublic::Pair::from_string(&format!("//{}", seed), None)
+        .expect("static values are valid; qed")
+        .public()
+}
+
+type AccountPublic = <Signature as Verify>::Signer;
+
+/// Generate an account ID from seed.
+pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
+where
+    AccountPublic: From<<TPublic::Pair as Pair>::Public>,
+{
+    AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
+}
+
+pub fn development_config() -> Result<ChainSpec, String> {
+    Ok(ChainSpec::builder(
+        WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
+        ForkingExtensions {
+            manual_mode: 1, // change this to `0` if you want to try `auto_fork_validation`
+            add_sha3_keccak: 10,
+            remove_md5: 20,
+            split_sha3_keccak: 30,
+            maxi_position: String::from("follow-mining"),
+        },
+    )
+    .with_name("Development")
+    .with_id("dev")
+    .with_chain_type(ChainType::Development)
+    .with_genesis_config_patch(genesis(
+        // Pre-funded accounts
+        vec![
+            get_account_id_from_seed::<sr25519::Public>("Alice"),
+            get_account_id_from_seed::<sr25519::Public>("Bob"),
+            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
+            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
+        ],
+        // Initial Difficulty
+        4_000_000,
+    ))
+    .with_properties(system_properties())
+    .build())
+}
+
+pub fn testnet_config() -> Result<ChainSpec, String> {
+    Ok(ChainSpec::builder(
+        WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
+        ForkingExtensions {
+            manual_mode: 1,
+            add_sha3_keccak: 0,
+            remove_md5: 0,
+            split_sha3_keccak: 0,
+            maxi_position: String::new(),
+        },
+    )
+    .with_name("Testnet")
+    .with_id("testnet")
+    .with_chain_type(ChainType::Local)
+    .with_genesis_config_patch(genesis(
+        vec![
+            get_account_id_from_seed::<sr25519::Public>("Alice"),
+            get_account_id_from_seed::<sr25519::Public>("Bob"),
+            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
+            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
+        ],
+        4_000_000,
+    ))
+    .with_properties(system_properties())
+    .build())
+}
+
+fn genesis(
+    endowed_accounts: Vec<AccountId>,
+    initial_difficulty: u32,
+) -> serde_json::Value {
+    serde_json::json!({
+        "balances": {
+            // Configure endowed accounts with initial balance of 1 << 50.
+            "balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 50)).collect::<Vec<_>>(),
+        },
+        "keccakDifficultyAdjustment": {
+            "initialDifficulty": u32_to_u8_32(initial_difficulty),
+        },
+        "md5DifficultyAdjustment": {
+            "initialDifficulty": u32_to_u8_32(initial_difficulty),
+        },
+        "sha3DifficultyAdjustment": {
+            "initialDifficulty": u32_to_u8_32(initial_difficulty),
+        },
+    })
+}
+
+/// Convert u32 (default value) to [u8;32] (U256)
+/// in little-endian format
+pub fn u32_to_u8_32(num: u32) -> [u8; 32] {
+    let mut result = [0u8; 32];
+    let bytes = num.to_le_bytes(); 
+    result[..4].copy_from_slice(&bytes);
+    result
+}
+
+fn system_properties() -> sc_chain_spec::Properties {
+    let mut properties = sc_chain_spec::Properties::new();
+
+    properties.insert("ss58Format".into(), SS58Prefix::get().into());
+    properties.insert("tokenSymbol".into(), TOKEN_SYMBOL.into());
+    properties.insert("tokenDecimals".into(), TOKEN_DECIMALS.into());
+
+    properties
+}
diff --git a/node/src/cli.rs b/node/src/cli.rs
new file mode 100644
index 0000000..4e1ac61
--- /dev/null
+++ b/node/src/cli.rs
@@ -0,0 +1,148 @@
+use academy_pow_runtime::AccountId;
+use multi_pow::SupportedHashes;
+use sc_cli::{
+    clap::{ArgGroup, Parser},
+    RunCmd,
+};
+use sc_service::ChainType;
+use sp_core::{crypto::Ss58Codec, sr25519};
+
+#[derive(Debug, Parser)]
+#[clap(subcommand_negates_reqs(true), version(env!("SUBSTRATE_CLI_IMPL_VERSION")))]
+pub struct Cli {
+    #[clap(subcommand)]
+    pub subcommand: Option<Subcommand>,
+
+    #[command(flatten)]
+    pub pow: AcademyPowCli,
+
+    #[clap(flatten)]
+    pub run: RunCmd,
+}
+
+#[derive(Debug, Parser, Clone)]
+#[clap(group(ArgGroup::new("backup")))]
+pub struct AcademyPowCli {
+    /// Miner's AccountId (base58 encoding of an SR25519 public key) for the block rewards
+    #[clap(long,
+           conflicts_with = "mining_public_key",
+           value_parser = parse_account_id)]
+    pub mining_account_id: Option<AccountId>,
+
+    /// Miner's hex encoding of the SR25519 public key) for the block rewards
+    #[clap(
+        long,
+        conflicts_with = "mining_account_id",
+        value_parser = parse_sr25519_public_key
+    )]
+    pub mining_public_key: Option<sr25519::Public>,
+
+    /// The mining algorithm to use
+    #[clap(long, value_parser = parse_algo, default_value = "md5")]
+    pub mining_algo: multi_pow::SupportedHashes,
+
+    /// whether to use instant seal
+    #[clap(long, default_value = "false")]
+    pub instant_seal: bool,
+}
+
+impl AcademyPowCli {
+    pub fn public_key_bytes(&self, keyring: Option<sp_keyring::Sr25519Keyring>) -> [u8; 32] {
+        match &self.mining_account_id {
+            Some(account_id) => *account_id.as_ref(),
+            None => match self.mining_public_key {
+                Some(public_key) => public_key.0,
+                None => keyring.map(|k| k.to_raw_public()).unwrap_or([0u8; 32]),
+            },
+        }
+    }
+}
+
+#[derive(Debug, Parser)]
+pub struct BuildSpecCmd {
+    #[clap(flatten)]
+    pub base: sc_cli::BuildSpecCmd,
+
+    /// Chain name.
+    #[arg(long, default_value = "Academy PoW")]
+    pub chain_name: String,
+
+    /// Chain ID is a short identifier of the chain
+    #[arg(long, value_name = "ID", default_value = "academy_pow")]
+    pub chain_id: String,
+
+    /// AccountIds of the optional rich accounts
+    #[arg(long, value_delimiter = ',', value_parser = parse_account_id, num_args=1..)]
+    pub endowed_accounts: Option<Vec<AccountId>>,
+
+    /// The type of the chain. Possible values: "dev", "local", "live" (default)
+    #[arg(long, value_name = "TYPE", value_parser = parse_chaintype, default_value = "live")]
+    pub chain_type: ChainType,
+
+    #[arg(long, default_value = "4000000")]
+    pub initial_difficulty: u32,
+}
+
+fn parse_algo(s: &str) -> Result<SupportedHashes, String> {
+    Ok(match s {
+        "md" | "Md" | "md5" | "Md5" => SupportedHashes::Md5,
+        "sha" | "sha3" | "Sha" | "Sha3" => SupportedHashes::Sha3,
+        "keccak" | "Keccak" => SupportedHashes::Keccak,
+        s => panic!(
+            "Wrong mining algo: {}. Possible values: md5, sha3, keccak",
+            s
+        ),
+    })
+}
+
+fn parse_chaintype(s: &str) -> Result<ChainType, String> {
+    Ok(match s {
+        "dev" => ChainType::Development,
+        "local" => ChainType::Local,
+        "live" => ChainType::Live,
+        s => panic!("Wrong chain type {} Possible values: dev local live", s),
+    })
+}
+
+/// Parse AccountId from a string argument passed on the command line.
+fn parse_account_id(s: &str) -> Result<AccountId, String> {
+    Ok(AccountId::from_string(s)
+        .expect("Passed string is not a bas58 encoding of a sr25519 public key"))
+}
+
+/// Parse sr25519 pubkey from a string argument passed on the command line.
+fn parse_sr25519_public_key(s: &str) -> Result<sr25519::Public, String> {
+    Ok(sr25519::Public::from_string(s)
+        .expect("Passed string is not a hex encoding of a sr25519 public key"))
+}
+
+#[derive(Debug, clap::Subcommand)]
+pub enum Subcommand {
+    /// Key management cli utilities
+    #[command(subcommand)]
+    Key(sc_cli::KeySubcommand),
+
+    /// Build a chain specification.
+    BuildSpec(BuildSpecCmd),
+
+    /// Validate blocks.
+    CheckBlock(sc_cli::CheckBlockCmd),
+
+    /// Export blocks.
+    ExportBlocks(sc_cli::ExportBlocksCmd),
+
+    /// Export the state of a given block into a chain spec.
+    ExportState(sc_cli::ExportStateCmd),
+
+    /// Import blocks.
+    ImportBlocks(sc_cli::ImportBlocksCmd),
+
+    /// Remove the whole chain.
+    PurgeChain(sc_cli::PurgeChainCmd),
+
+    /// Revert the chain to a previous state.
+    Revert(sc_cli::RevertCmd),
+
+    /// Db meta columns information.
+    ChainInfo(sc_cli::ChainInfoCmd),
+}
diff --git a/node/src/command.rs b/node/src/command.rs
new file mode 100644
index 0000000..b62bd98
--- /dev/null
+++ b/node/src/command.rs
@@ -0,0 +1,183 @@
+// Copyright 2017-2020 Parity Technologies (UK) Ltd.
+// This file is part of Substrate.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.
+
+use academy_pow_runtime::Block;
+use multi_pow::{ForkingConfig, MaxiPosition};
+use sc_cli::SubstrateCli;
+use sc_service::PartialComponents;
+use sp_core::sr25519;
+
+use crate::{
+    chain_spec::{self, ForkingExtensions},
+    cli::{Cli, Subcommand},
+    service,
+};
+
+impl SubstrateCli for Cli {
+    fn impl_name() -> String {
+        "Academy PoW Chain".into()
+    }
+
+    fn impl_version() -> String {
+        env!("SUBSTRATE_CLI_IMPL_VERSION").into()
+    }
+
+    fn executable_name() -> String {
+        env!("CARGO_PKG_NAME").into()
+    }
+
+    fn author() -> String {
+        env!("CARGO_PKG_AUTHORS").into()
+    }
+
+    fn description() -> String {
+        env!("CARGO_PKG_DESCRIPTION").into()
+    }
+
+    fn support_url() -> String {
+        "https://github.com/danielbui12/substrate-bitcoin-like-blockchain/issues/new".into()
+    }
+
+    fn copyright_start_year() -> i32 {
+        2025
+    }
+
+    fn load_spec(&self, id: &str) -> Result<Box<dyn sc_service::ChainSpec>, String> {
+        Ok(match id {
+            "" => Box::new(chain_spec::ChainSpec::from_json_bytes(
+                &include_bytes!("../../spec.json")[..],
+            )?),
+            "dev" => Box::new(chain_spec::development_config()?),
+            "local" => Box::new(chain_spec::testnet_config()?),
+            path => Box::new(chain_spec::ChainSpec::from_json_file(
+                std::path::PathBuf::from(path),
+            )?),
+        })
+    }
+}
+
+/// Parse and run command line arguments
+pub fn run() -> sc_cli::Result<()> {
+    let cli = Cli::from_args();
+
+    match &cli.subcommand {
+        Some(Subcommand::Key(cmd)) => cmd.run(&cli),
+        Some(Subcommand::BuildSpec(cmd)) => {
+            let runner = cli.create_runner(&cmd.base)?;
+            runner.sync_run(|config| cmd.base.run(config.chain_spec, config.network))
+        }
+        Some(Subcommand::CheckBlock(cmd)) => {
+            let runner = cli.create_runner(cmd)?;
+            runner.async_run(|config| {
+                let PartialComponents {
+                    client,
+                    task_manager,
+                    import_queue,
+                    ..
+                } = service::new_partial(&config, ForkingConfig::Manual)?;
+                Ok((cmd.run(client, import_queue), task_manager))
+            })
+        }
+        Some(Subcommand::ExportBlocks(cmd)) => {
+            let runner = cli.create_runner(cmd)?;
+            runner.async_run(|config| {
+                let PartialComponents {
+                    client,
+                    task_manager,
+                    ..
+                } = service::new_partial(&config, ForkingConfig::Manual)?;
+                Ok((cmd.run(client, config.database), task_manager))
+            })
+        }
+        Some(Subcommand::ExportState(cmd)) => {
+            let runner = cli.create_runner(cmd)?;
+            runner.async_run(|config| {
+                let PartialComponents {
+                    client,
+                    task_manager,
+                    ..
+                } = service::new_partial(&config, ForkingConfig::Manual)?;
+                Ok((cmd.run(client, config.chain_spec), task_manager))
+            })
+        }
+        Some(Subcommand::ImportBlocks(cmd)) => {
+            let runner = cli.create_runner(cmd)?;
+            runner.async_run(|config| {
+                let PartialComponents {
+                    client,
+                    task_manager,
+                    import_queue,
+                    ..
+                } = service::new_partial(&config, ForkingConfig::Manual)?;
+                Ok((cmd.run(client, import_queue), task_manager))
+            })
+        }
+        Some(Subcommand::PurgeChain(cmd)) => {
+            let runner = cli.create_runner(cmd)?;
+            runner.sync_run(|config| cmd.run(config.database))
+        }
+        Some(Subcommand::Revert(cmd)) => {
+            let runner = cli.create_runner(cmd)?;
+            runner.async_run(|config| {
+                let PartialComponents {
+                    client,
+                    task_manager,
+                    backend,
+                    ..
+                } = service::new_partial(&config, ForkingConfig::Manual)?;
+                Ok((cmd.run(client, backend, None), task_manager))
+            })
+        }
+        Some(Subcommand::ChainInfo(cmd)) => {
+            let runner = cli.create_runner(cmd)?;
+            runner.sync_run(|config| cmd.run::<Block>(&config))
+        }
+        None => {
+            // Get the mining account from the cli
+            let bytes: [u8; 32] = cli.pow.public_key_bytes(cli.run.get_keyring());
+            let sr25519_public_key = sr25519::Public::from_raw(bytes);
+
+            let runner = cli.create_runner(&cli.run)?;
+            runner.run_node_until_exit(|config| async move {
+                // Get the forking information from the chain spec extension.
+                // Convert it to a strong type, and fill in the proper maxi position if they are following mining.
+                let forking_extension = ForkingExtensions::try_get(&*config.chain_spec)
+                    .expect("Should be able to get the fork config from the extension");
+                let forking_config = match ForkingConfig::from(forking_extension) {
+                    ForkingConfig::Automatic(fork_heights, MaxiPosition::FollowMining) => {
+                        let maxi_position = match cli.pow.mining_algo {
+                            multi_pow::SupportedHashes::Md5 => MaxiPosition::NoMaxi,
+                            multi_pow::SupportedHashes::Sha3 => MaxiPosition::Sha3Maxi,
+                            multi_pow::SupportedHashes::Keccak => MaxiPosition::KeccakMaxi,
+                        };
+                        ForkingConfig::Automatic(fork_heights, maxi_position)
+                    }
+                    old_config => old_config,
+                };
+
+                service::new_full::<sc_network::Litep2pNetworkBackend>(
+                    config,
+                    forking_config,
+                    //TODO Combine the following three fields into a MiningConfig analogous to the ForkingConfig
+                    sr25519_public_key,
+                    cli.pow.instant_seal,
+                    cli.pow.mining_algo,
+                )
+                .map_err(sc_cli::Error::Service)
+            })
+        }
+    }
+}
diff --git a/node/src/main.rs b/node/src/main.rs
new file mode 100644
index 0000000..a4182cd
--- /dev/null
+++ b/node/src/main.rs
@@ -0,0 +1,13 @@
+//! Substrate Node Template CLI library.
+#![warn(missing_docs)]
+
+mod chain_spec;
+#[macro_use]
+mod service;
+mod cli;
+mod command;
+mod rpc;
+
+fn main() -> sc_cli::Result<()> {
+    command::run()
+}
diff --git a/node/src/rpc.rs b/node/src/rpc.rs
new file mode 100644
index 0000000..875414c
--- /dev/null
+++ b/node/src/rpc.rs
@@ -0,0 +1,55 @@
+//! A collection of node-specific RPC methods.
+//! Substrate provides the `sc-rpc` crate, which defines the core RPC layer
+//! used by Substrate nodes. This file extends those RPC definitions with
+//! capabilities that are specific to this project's runtime configuration.
+
+#![warn(missing_docs)]
+
+use std::sync::Arc;
+
+use academy_pow_runtime::{opaque::Block, AccountId, Balance, Index};
+use jsonrpsee::RpcModule;
+pub use sc_rpc_api::DenyUnsafe;
+use sc_transaction_pool_api::TransactionPool;
+use sp_api::ProvideRuntimeApi;
+use sp_block_builder::BlockBuilder;
+use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
+
+/// Full client dependencies.
+pub struct FullDeps<C, P> {
+    /// The client instance to use.
+    pub client: Arc<C>,
+    /// Transaction pool instance.
+    pub pool: Arc<P>,
+    /// Whether to deny unsafe calls
+    pub deny_unsafe: DenyUnsafe,
+}
+
+/// Instantiate all full RPC extensions.
+pub fn create_full<C, P>(
+    deps: FullDeps<C, P>,
+) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
+where
+    C: ProvideRuntimeApi<Block>,
+    C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
+    C: Send + Sync + 'static,
+    C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
+    C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
+    C::Api: BlockBuilder<Block>,
+    P: TransactionPool + 'static,
+{
+    use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
+    use substrate_frame_rpc_system::{System, SystemApiServer};
+
+    let mut module = RpcModule::new(());
+    let FullDeps {
+        client,
+        pool,
+        deny_unsafe,
+    } = deps;
+
+    module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?;
+    module.merge(TransactionPayment::new(client).into_rpc())?;
+
+    Ok(module)
+}
diff --git a/node/src/service.rs b/node/src/service.rs
new file mode 100644
index 0000000..4bf3935
--- /dev/null
+++ b/node/src/service.rs
@@ -0,0 +1,288 @@
+//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.
+
+use core::clone::Clone;
+use std::sync::Arc;
+
+use academy_pow_runtime::{self, opaque::Block, PreDigest, RuntimeApi};
+use multi_pow::{ForkingConfig, MultiPow, SupportedHashes};
+use parity_scale_codec::Encode;
+use sc_consensus::LongestChain;
+use sc_service::{error::Error as ServiceError, Configuration, PartialComponents, TaskManager};
+use sc_telemetry::{Telemetry, TelemetryWorker};
+use sp_core::sr25519;
+
+pub(crate) type FullClient = sc_service::TFullClient<
+	Block,
+	RuntimeApi,
+	sc_executor::WasmExecutor<sp_io::SubstrateHostFunctions>,
+>;
+type FullBackend = sc_service::TFullBackend<Block>;
+type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;
+
+type BasicImportQueue = sc_consensus::DefaultImportQueue<Block>;
+type BoxBlockImport = sc_consensus::BoxBlockImport<Block>;
+
+pub type Service = PartialComponents<
+    FullClient,
+    FullBackend,
+    FullSelectChain,
+    BasicImportQueue,
+    sc_transaction_pool::FullPool<Block, FullClient>,
+    (BoxBlockImport, Option<Telemetry>),
+>;
+
+/// Returns most parts of a service. Not enough to run a full chain,
+/// But enough to perform chain operations like purge-chain
+#[allow(clippy::type_complexity)]
+pub fn new_partial(
+    config: &Configuration,
+    fork_config: ForkingConfig,
+) -> Result<Service, ServiceError> {
+    let telemetry = config
+        .telemetry_endpoints
+        .clone()
+        .filter(|x| !x.is_empty())
+        .map(|endpoints| -> Result<_, sc_telemetry::Error> {
+            let worker = TelemetryWorker::new(16)?;
+            let telemetry = worker.handle().new_telemetry(endpoints);
+            Ok((worker, telemetry))
+        })
+        .transpose()?;
+
+    let executor = sc_service::new_wasm_executor::<sp_io::SubstrateHostFunctions>(config);
+    let (client, backend, keystore_container, task_manager) =
+        sc_service::new_full_parts::<Block, RuntimeApi, _>(
+            config,
+            telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
+            executor,
+        )?;
+    let client = Arc::new(client);
+
+    let telemetry = telemetry.map(|(worker, telemetry)| {
+        task_manager
+            .spawn_handle()
+            .spawn("telemetry", None, worker.run());
+        telemetry
+    });
+
+    let select_chain = LongestChain::new(backend.clone());
+
+    let transaction_pool = sc_transaction_pool::BasicPool::new_full(
+        config.transaction_pool.clone(),
+        config.role.is_authority().into(),
+        config.prometheus_registry(),
+        task_manager.spawn_essential_handle(),
+        client.clone(),
+    );
+
+    let block_import = sc_consensus_pow::PowBlockImport::new(
+        client.clone(),
+        client.clone(),
+        MultiPow::new(client.clone(), fork_config),
+        0, // check inherents starting at block 0
+        select_chain.clone(),
+        move |_, ()| async move {
+            let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
+
+            // We don't need the current mining key to check inherents, so we just use a default.
+            // TODO, I don't think we need to do any checking here at all, right?
+            // So can I just remove the author entirely?
+            let author =
+                academy_pow_runtime::block_author::InherentDataProvider(Default::default());
+
+            Ok((timestamp, author))
+        },
+    );
+
+    let import_queue = sc_consensus_pow::import_queue(
+        Box::new(block_import.clone()),
+        None,
+        MultiPow::new(client.clone(), fork_config),
+        &task_manager.spawn_essential_handle(),
+        config.prometheus_registry(),
+    )?;
+
+    Ok(PartialComponents {
+        client,
+        backend,
+        task_manager,
+        import_queue,
+        keystore_container,
+        select_chain,
+        transaction_pool,
+        other: (Box::new(block_import), telemetry),
+    })
+}
+
+/// Builds a new service for a full client.
+pub fn new_full<
+    N: sc_network::NetworkBackend<Block, <Block as sp_runtime::traits::Block>::Hash>,
+>(
+    config: Configuration,
+    fork_config: ForkingConfig,
+    sr25519_public_key: sr25519::Public,
+    instant_seal: bool,
+    mining_algo: SupportedHashes,
+) -> Result<TaskManager, ServiceError> {
+    let sc_service::PartialComponents {
+        client,
+        backend,
+        mut task_manager,
+        import_queue,
+        keystore_container,
+        select_chain,
+        transaction_pool,
+        other: (pow_block_import, mut telemetry),
+    } = new_partial(&config, fork_config)?;
+
+    let net_config = sc_network::config::FullNetworkConfiguration::<
+        Block,
+        <Block as sp_runtime::traits::Block>::Hash,
+        N,
+    >::new(&config.network);
+	let metrics = sc_network::NotificationMetrics::new(None);
+
+    let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =
+        sc_service::build_network(sc_service::BuildNetworkParams {
+            config: &config,
+            net_config,
+            client: client.clone(),
+            transaction_pool: transaction_pool.clone(),
+            spawn_handle: task_manager.spawn_handle(),
+            import_queue,
+            block_announce_validator_builder: None,
+            warp_sync_params: None,
+            block_relay: None,
+            metrics: metrics,
+        })?;
+
+    let role = config.role.clone();
+    let prometheus_registry = config.prometheus_registry().cloned();
+
+    let rpc_extensions_builder = {
+        let client = client.clone();
+        let pool = transaction_pool.clone();
+
+        Box::new(move |deny_unsafe, _| {
+            let deps = crate::rpc::FullDeps {
+                client: client.clone(),
+                pool: pool.clone(),
+                deny_unsafe,
+            };
+            crate::rpc::create_full(deps).map_err(Into::into)
+        })
+    };
+
+    sc_service::spawn_tasks(sc_service::SpawnTasksParams {
+        network,
+        client: client.clone(),
+        keystore: keystore_container.keystore(),
+        task_manager: &mut task_manager,
+        transaction_pool: transaction_pool.clone(),
+        rpc_builder: rpc_extensions_builder,
+        backend,
+        system_rpc_tx,
+        tx_handler_controller,
+        sync_service: sync_service.clone(),
+        config,
+        telemetry: telemetry.as_mut(),
+    })?;
+
+    if role.is_authority() {
+        let proposer = sc_basic_authorship::ProposerFactory::new(
+            task_manager.spawn_handle(),
+            client.clone(),
+            transaction_pool.clone(),
+            prometheus_registry.as_ref(),
+            telemetry.as_ref().map(|x| x.handle()),
+        );
+
+        // If instant seal is requested, we just start it. Otherwise, we do the full PoW setup.
+        if instant_seal {
+            let params = sc_consensus_manual_seal::InstantSealParams {
+                block_import: client.clone(),
+                env: proposer,
+                client,
+                pool: transaction_pool,
+                select_chain,
+                consensus_data_provider: None,
+                create_inherent_data_providers: move |_, ()| async move {
+                    Ok(sp_timestamp::InherentDataProvider::from_system_time())
+                },
+            };
+
+            let authorship_future = sc_consensus_manual_seal::run_instant_seal(params);
+
+            task_manager.spawn_essential_handle().spawn_blocking(
+                "instant-seal",
+                None,
+                authorship_future,
+            );
+        } else {
+            let (mining_worker, mining_worker_task) = sc_consensus_pow::start_mining_worker(
+                Box::new(pow_block_import),
+                client.clone(),
+                select_chain,
+                MultiPow::new(client, fork_config),
+                proposer,
+                sync_service.clone(),
+                sync_service,
+                // Note the mining algorithm in the pre-runtime digest.
+                // This allows us to know which algo it was in the runtime.
+                // TODO This also makes it possible to remove the algo info from
+                // the seal.
+                Some(PreDigest::from((sr25519_public_key.into(), mining_algo)).encode()),
+                // This code is copied from above. Would be better to not repeat it.
+                move |_, ()| async move {
+                    let timestamp = sp_timestamp::InherentDataProvider::from_system_time();            
+                    // set default `author` following miner specified in CLI
+                    let author = academy_pow_runtime::block_author::InherentDataProvider(
+                        sr25519_public_key.encode(),
+                    );
+
+                    Ok((timestamp, author))
+                },
+                std::time::Duration::from_secs(10),
+                std::time::Duration::from_secs(5),
+            );
+
+            task_manager.spawn_essential_handle().spawn_blocking(
+                "pow-miner",
+                Some("pow-mining"),
+                mining_worker_task,
+            );
+
+            // Start Mining worker.
+            //TODO Some of this should move into the multi_pow crate.
+            use multi_pow::{multi_hash_meets_difficulty, Compute};
+            use sp_core::U256;
+            let mut nonce: U256 = U256::from(0);
+            std::thread::spawn(move || loop {
+                let worker = mining_worker.clone();
+                let metadata = worker.metadata();
+                if let Some(metadata) = metadata {
+                    let compute = Compute {
+                        difficulty: metadata.difficulty,
+                        pre_hash: metadata.pre_hash,
+                        nonce,
+                    };
+                    let seal = compute.compute(mining_algo);
+                    if multi_hash_meets_difficulty(&seal.work, seal.difficulty) {
+                        nonce = U256::from(0);
+                        let _ = futures::executor::block_on(worker.submit(seal.encode()));
+                    } else {
+                        nonce = nonce.saturating_add(U256::from(1));
+                        if nonce == U256::MAX {
+                            nonce = U256::from(0);
+                        }
+                    }
+                } else {
+                    std::thread::sleep(std::time::Duration::from_secs(1));
+                }
+            });
+        }
+    }
+
+    network_starter.start_network();
+    Ok(task_manager)
+}
diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml
new file mode 100644
index 0000000..05071e7
--- /dev/null
+++ b/runtime/Cargo.toml
@@ -0,0 +1,77 @@
+[package]
+authors = [ "Parity Technologies <admin@parity.io>", "Joshy Orndorff" ]
+edition = "2021"
+homepage = "https://substrate.dev"
+name = "academy-pow-runtime"
+version = "3.0.0"
+
+[dependencies]
+async-trait = { optional = true, workspace = true }
+parity-scale-codec = { workspace = true }
+scale-info = { workspace = true }
+serde = { optional = true, workspace = true }
+log.workspace = true
+
+frame-executive = { workspace = true }
+frame-support = { workspace = true }
+frame-system = { workspace = true }
+pallet-balances = { workspace = true }
+pallet-timestamp = { workspace = true }
+pallet-transaction-payment = { workspace = true }
+sp-api = { workspace = true }
+sp-block-builder = { workspace = true }
+sp-consensus-pow = { workspace = true }
+sp-core = { workspace = true }
+sp-genesis-builder = { workspace = true }
+sp-inherents = { workspace = true }
+sp-io = { workspace = true }
+sp-keystore = { optional = true, workspace = true }
+sp-offchain = { workspace = true }
+sp-runtime = { workspace = true }
+sp-session = { workspace = true }
+sp-std = { workspace = true }
+sp-transaction-pool = { workspace = true }
+sp-version = { workspace = true }
+
+multi-pow = { default-features = false, path = "../multi-pow" }
+
+# Used for the node's RPCs
+frame-system-rpc-runtime-api = { workspace = true }
+pallet-transaction-payment-rpc-runtime-api = { workspace = true }
+[build-dependencies]
+substrate-wasm-builder = { workspace = true }
+
+
+[dev-dependencies]
+hex-literal = { workspace = true }
+
+[features]
+default = [ "std" ]
+std = [
+	"pallet-balances/std",
+	"parity-scale-codec/std",
+	"frame-executive/std",
+	"frame-support/std",
+	"serde",
+	"sp-api/std",
+	"sp-block-builder/std",
+	"sp-consensus-pow/std",
+	"sp-core/std",
+	"sp-genesis-builder/std",
+	"sp-inherents/std",
+	"sp-io/std",
+	"sp-offchain/std",
+	"sp-runtime/std",
+	"sp-session/std",
+	"sp-std/std",
+	"sp-transaction-pool/std",
+	"sp-version/std",
+	"frame-system/std",
+	"pallet-timestamp/std",
+	"async-trait",
+	"sp-keystore",
+	"pallet-transaction-payment/std",
+	"pallet-transaction-payment-rpc-runtime-api/std",
+	"frame-system-rpc-runtime-api/std",
+	"multi-pow/std",
+]
diff --git a/runtime/build.rs b/runtime/build.rs
new file mode 100644
index 0000000..6db3d90
--- /dev/null
+++ b/runtime/build.rs
@@ -0,0 +1,8 @@
+fn main() {
+    #[cfg(feature = "std")]
+    substrate_wasm_builder::WasmBuilder::new()
+        .with_current_project()
+        .export_heap_base()
+        .import_memory()
+        .build()
+}
diff --git a/runtime/src/block_author.rs b/runtime/src/block_author.rs
new file mode 100644
index 0000000..b147eeb
--- /dev/null
+++ b/runtime/src/block_author.rs
@@ -0,0 +1,187 @@
+//! This pallet allows block authors to self-identify by providing an sr25519 public key
+//!
+//! The included trait allows other pallets to fetch the author's account as long as the
+//! runtime's AccountId type can be created from an sr25519 public key.
+
+pub use pallet::*;
+use parity_scale_codec::{Decode, Encode};
+use sp_core::sr25519;
+#[cfg(feature = "std")]
+use sp_inherents::InherentData;
+use sp_inherents::{InherentIdentifier, IsFatalError};
+use sp_runtime::RuntimeString;
+use sp_std::vec::Vec;
+
+#[frame_support::pallet(dev_mode)]
+pub mod pallet {
+    use frame_support::pallet_prelude::*;
+    use frame_system::pallet_prelude::*;
+
+    use super::*;
+
+    /// The BlockAuthor Inherent pallet.
+    #[pallet::pallet]
+    pub struct Pallet<T>(PhantomData<T>);
+    /// The pallet's configuration trait. Nothing to configure.
+    #[pallet::config]
+    pub trait Config: frame_system::Config {
+        fn on_author_set(_author_account: Self::AccountId) {}
+    }
+
+    #[pallet::error]
+    pub enum Error<T> {
+        /// Author already set in block.
+        AuthorAlreadySet,
+    }
+
+    /// Author of current block.
+    #[pallet::storage]
+    pub type Author<T: Config> = StorageValue<_, sr25519::Public, OptionQuery>;
+
+    #[pallet::call]
+    impl<T: Config> Pallet<T>
+    where
+        <T as frame_system::Config>::AccountId: From<sp_core::sr25519::Public>,
+    {
+        /// Inherent to set the author of a block
+        #[pallet::weight(1_000_000)]
+        pub fn set_author(origin: OriginFor<T>, author: sr25519::Public) -> DispatchResult {
+            ensure_none(origin)?;
+            ensure!(Author::<T>::get().is_none(), Error::<T>::AuthorAlreadySet);
+
+            // Store the author in case other pallets want to fetch it and to let
+            // offchain tools inspect it
+            Author::<T>::put(author);
+
+            // Call the hook
+            T::on_author_set(author.into());
+
+            Ok(())
+        }
+    }
+
+    #[pallet::hooks]
+    impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
+        fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
+            // Reset the author to None at the beginning of the block
+            Author::<T>::kill();
+
+            // Return zero weight because we are not using weight-based
+            // transaction fees.
+            Weight::zero()
+        }
+    }
+
+    #[pallet::inherent]
+    impl<T: Config> ProvideInherent for Pallet<T>
+    where
+        <T as frame_system::Config>::AccountId: From<sp_core::sr25519::Public>,
+    {
+        type Call = Call<T>;
+        type Error = InherentError;
+        const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
+
+        fn is_inherent_required(_: &InherentData) -> Result<Option<Self::Error>, Self::Error> {
+            // Return Ok(Some(_)) unconditionally because this inherent is required in every block
+            // If it is not found, throw an AuthorInherentRequired error.
+            Ok(Some(InherentError::Other(
+                sp_runtime::RuntimeString::Borrowed("BlockAuthorInherentRequired"),
+            )))
+        }
+
+        fn create_inherent(data: &InherentData) -> Option<Self::Call> {
+            // Grab the Vec<u8> labelled with "author_" from the map of all inherent data
+            let author_raw = data
+                .get_data::<InherentType>(&INHERENT_IDENTIFIER)
+                .expect("Gets and decodes authorship inherent data")?;
+
+            // Decode the Vec<u8> into an actual author
+            let author = sr25519::Public::decode(&mut &author_raw[..])
+                .expect("Decodes author raw inherent data");
+
+            Some(Call::set_author { author })
+        }
+
+        fn is_inherent(call: &Self::Call) -> bool {
+            matches!(call, Call::set_author { .. })
+        }
+    }
+}
+
+/// A trait to find the author (miner) of the block.
+pub trait BlockAuthor {
+    fn block_author() -> Option<sr25519::Public>;
+}
+
+impl BlockAuthor for () {
+    fn block_author() -> Option<sr25519::Public> {
+        None
+    }
+}
+
+impl<T: Config> BlockAuthor for Pallet<T> {
+    fn block_author() -> Option<sr25519::Public> {
+        Author::<T>::get()
+    }
+}
+
+pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"author__";
+
+#[derive(Encode, Decode, Debug)]
+pub enum InherentError {
+    Other(RuntimeString),
+}
+
+impl IsFatalError for InherentError {
+    fn is_fatal_error(&self) -> bool {
+        match *self {
+            InherentError::Other(_) => true,
+        }
+    }
+}
+
+impl InherentError {
+    /// Try to create an instance ouf of the given identifier and data.
+    #[cfg(feature = "std")]
+    pub fn try_from(id: &InherentIdentifier, data: &[u8]) -> Option<Self> {
+        if id == &INHERENT_IDENTIFIER {
+            <InherentError as parity_scale_codec::Decode>::decode(&mut &data[..]).ok()
+        } else {
+            None
+        }
+    }
+}
+
+/// The type of data that the inherent will contain.
+/// Just a byte array. It will be decoded to an actual pubkey later
+pub type InherentType = Vec<u8>;
+
+#[cfg(feature = "std")]
+pub struct InherentDataProvider(pub InherentType);
+
+#[cfg(feature = "std")]
+#[async_trait::async_trait]
+impl sp_inherents::InherentDataProvider for InherentDataProvider {
+    async fn provide_inherent_data(
+        &self,
+        inherent_data: &mut InherentData,
+    ) -> Result<(), sp_inherents::Error> {
+        inherent_data.put_data(INHERENT_IDENTIFIER, &self.0)
+    }
+
+    async fn try_handle_error(
+        &self,
+        identifier: &InherentIdentifier,
+        _error: &[u8],
+    ) -> Option<Result<(), sp_inherents::Error>> {
+        // Dont' process modules from other inherents
+        if *identifier != INHERENT_IDENTIFIER {
+            return None;
+        }
+
+        // All errors with the author inehrent are fatal
+        Some(Err(sp_inherents::Error::Application(Box::from(
+            String::from("Error processing author inherent"),
+        ))))
+    }
+}
diff --git a/runtime/src/difficulty.rs b/runtime/src/difficulty.rs
new file mode 100644
index 0000000..babfeab
--- /dev/null
+++ b/runtime/src/difficulty.rs
@@ -0,0 +1,203 @@
+//! A difficulty adjustment algorithm (DAA) to keep the block time close to a particular goal
+//! Cribbed from Kulupu https://github.com/kulupu/kulupu/blob/master/runtime/src/difficulty.rs
+//!
+//! It is possible to implement other DAAs such as that of BTC and BCH. This would be an interesting
+//! and worth-while experiment. The DAAs should be abstracted away with a trait.
+//! Some ideas: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3410460
+
+use core::cmp::{max, min};
+
+use frame_support::traits::Time;
+use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
+use scale_info::TypeInfo;
+use sp_core::U256;
+use sp_runtime::traits::UniqueSaturatedInto;
+
+#[derive(Encode, Decode, Clone, Copy, Eq, PartialEq, Debug, MaxEncodedLen, TypeInfo)]
+pub struct DifficultyAndTimestamp<M> {
+    pub difficulty: Difficulty,
+    pub timestamp: M,
+}
+
+/// Move value linearly toward a goal
+pub fn damp(actual: u128, goal: u128, damp_factor: u128) -> u128 {
+    (actual + (damp_factor - 1) * goal) / damp_factor
+}
+
+/// Limit value to be within some factor from a goal
+pub fn clamp(actual: u128, goal: u128, clamp_factor: u128) -> u128 {
+    max(goal / clamp_factor, min(actual, goal * clamp_factor))
+}
+
+const DIFFICULTY_ADJUST_WINDOW: u128 = 60;
+type Difficulty = U256;
+
+pub use pallet::*;
+
+#[frame_support::pallet(dev_mode)]
+pub mod pallet {
+    use frame_support::pallet_prelude::*;
+    use frame_system::pallet_prelude::*;
+
+    use super::*;
+
+    /// Pallet's configuration trait.
+    #[pallet::config]
+    pub trait Config<I: 'static = ()>: frame_system::Config {
+        /// A Source for timestamp data
+        type TimeProvider: Time;
+        /// The block time that the DAA will attempt to maintain
+        type TargetBlockTime: Get<u128>;
+        /// Dampening factor to use for difficulty adjustment
+        type DampFactor: Get<u128>;
+        /// Clamp factor to use for difficulty adjustment
+        /// Limit value to within this factor of goal. Recommended value: 2
+        type ClampFactor: Get<u128>;
+        /// The maximum difficulty allowed. Recommended to use u128::max_value()
+        type MaxDifficulty: Get<u128>;
+        /// Minimum difficulty, enforced in difficulty retargetting
+        /// avoids getting stuck when trying to increase difficulty subject to dampening
+        /// Recommended to use same value as DampFactor
+        type MinDifficulty: Get<u128>;
+
+        /// Now that the pallet is instantiable, we need a way to decide which blocks are
+        /// relevant to this instance. This function does just that.
+        ///
+        /// The default implementation assumes that all blocks are relevant which is what
+        /// you probably want when there is only a single instance.
+        fn relevant_to_this_instance() -> bool {
+            true
+        }
+    }
+
+    #[pallet::pallet]
+    pub struct Pallet<T, I = ()>(_);
+
+    type DifficultyList<T, I> =
+        [Option<DifficultyAndTimestamp<<<T as Config<I>>::TimeProvider as Time>::Moment>>; 60];
+
+    /// Past difficulties and timestamps, from earliest to latest.
+    #[pallet::storage]
+    pub type PastDifficultiesAndTimestamps<T: Config<I>, I: 'static = ()> =
+        StorageValue<_, DifficultyList<T, I>, ValueQuery, EmptyList<T, I>>;
+
+    pub struct EmptyList<T: Config<I>, I: 'static = ()>(PhantomData<(T, I)>);
+    impl<T: Config<I>, I> Get<DifficultyList<T, I>> for EmptyList<T, I> {
+        fn get() -> DifficultyList<T, I> {
+            [None; DIFFICULTY_ADJUST_WINDOW as usize]
+        }
+    }
+
+    /// Current difficulty.
+    #[pallet::storage]
+    #[pallet::getter(fn difficulty)]
+    pub type CurrentDifficulty<T: Config<I>, I: 'static = ()> =
+        StorageValue<_, Difficulty, ValueQuery>;
+
+    /// Initial difficulty.
+    #[pallet::storage]
+    pub type InitialDifficulty<T: Config<I>, I: 'static = ()> =
+        StorageValue<_, Difficulty, ValueQuery>;
+
+    #[pallet::genesis_config]
+    pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
+        pub _ph_data: Option<PhantomData<(T, I)>>,
+        pub initial_difficulty: [u8; 32], // Difficulty = U256
+    }
+
+    #[pallet::genesis_build]
+    impl<T: Config<I>, I: 'static> BuildGenesisConfig for GenesisConfig<T, I> {
+        fn build(&self) {
+            let initial_difficulty = U256::from_little_endian(&self.initial_difficulty);
+            // Initialize the Current difficulty
+            CurrentDifficulty::<T, I>::put(&initial_difficulty);
+
+            // Store the initial difficulty in storage because we will need it
+            // during the first DIFFICULTY_ADJUSTMENT_WINDOW blocks (see todo below).
+            InitialDifficulty::<T, I>::put(&initial_difficulty);
+        }
+    }
+
+    impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
+        fn default() -> Self {
+            GenesisConfig {
+                _ph_data: Default::default(),
+                initial_difficulty: [0u8; 32],
+            }
+        }
+    }
+
+    #[pallet::hooks]
+    impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
+        fn on_finalize(_n: BlockNumberFor<T>) {
+            // First check if this is block is relevant to this instance of the difficulty adjustment algorithm
+            if !T::relevant_to_this_instance() {
+                return;
+            }
+
+            let mut data = PastDifficultiesAndTimestamps::<T, I>::get();
+
+            for i in 1..data.len() {
+                data[i - 1] = data[i];
+            }
+
+            data[data.len() - 1] = Some(DifficultyAndTimestamp {
+                timestamp: T::TimeProvider::now(),
+                difficulty: Self::difficulty(),
+            });
+
+            let mut ts_delta = 0;
+            for i in 1..(DIFFICULTY_ADJUST_WINDOW as usize) {
+                let prev: Option<u128> = data[i - 1].map(|d| d.timestamp.unique_saturated_into());
+                let cur: Option<u128> = data[i].map(|d| d.timestamp.unique_saturated_into());
+
+                let delta = match (prev, cur) {
+                    (Some(prev), Some(cur)) => cur.saturating_sub(prev),
+                    _ => T::TargetBlockTime::get(),
+                };
+                ts_delta += delta;
+            }
+
+            if ts_delta == 0 {
+                ts_delta = 1;
+            }
+
+            let mut diff_sum = U256::zero();
+            //TODO Could we just initialize every array cell to the initial difficulty to not need the
+            // separate storage item?
+            for item in data.iter().take(DIFFICULTY_ADJUST_WINDOW as usize) {
+                let diff = match item.map(|d| d.difficulty) {
+                    Some(diff) => diff,
+                    None => InitialDifficulty::<T, I>::get(),
+                };
+                diff_sum += diff;
+            }
+
+            if diff_sum < U256::from(T::MinDifficulty::get()) {
+                diff_sum = U256::from(T::MinDifficulty::get());
+            }
+
+            // Calculate the average length of the adjustment window
+            let adjustment_window = DIFFICULTY_ADJUST_WINDOW * T::TargetBlockTime::get();
+
+            // adjust time delta toward goal subject to dampening and clamping
+            let adj_ts = clamp(
+                damp(ts_delta, adjustment_window, T::DampFactor::get()),
+                adjustment_window,
+                T::ClampFactor::get(),
+            );
+
+            // minimum difficulty avoids getting stuck due to dampening
+            let difficulty = min(
+                U256::from(T::MaxDifficulty::get()),
+                max(
+                    U256::from(T::MinDifficulty::get()),
+                    diff_sum * U256::from(T::TargetBlockTime::get()) / U256::from(adj_ts),
+                ),
+            );
+
+            <PastDifficultiesAndTimestamps<T, I>>::put(data);
+            <CurrentDifficulty<T, I>>::put(difficulty);
+        }
+    }
+}
diff --git a/runtime/src/issuance.rs b/runtime/src/issuance.rs
new file mode 100644
index 0000000..9a11f9d
--- /dev/null
+++ b/runtime/src/issuance.rs
@@ -0,0 +1,47 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+/// A trait for types that can provide the amount of issuance to award to the block
+/// author for the given block number.
+pub trait Issuance<BlockNumber, Balance> {
+    fn issuance(block: BlockNumber) -> Balance;
+}
+
+// Minimal implementations for when you don't actually want any issuance
+impl Issuance<u32, u128> for () {
+    fn issuance(_block: u32) -> u128 {
+        0
+    }
+}
+
+impl Issuance<u64, u128> for () {
+    fn issuance(_block: u64) -> u128 {
+        0
+    }
+}
+
+/// A type that provides block issuance according to bitcoin's rules
+/// Initial issuance is 50 / block
+/// Issuance is cut in half every 210,000 blocks
+/// cribbed from github.com/Bitcoin-ABC/bitcoin-abc/blob/9c7b12e6f128a59423f4de3d6d4b5231ebe9aac2/src/validation.cpp#L1007
+
+pub struct BitcoinHalving;
+
+/// The number of blocks between each halving.
+const HALVING_INTERVAL: u32 = 210_000;
+/// The per-block issuance before any halving. Decimal places should be accounted for here.
+const INITIAL_ISSUANCE: u32 = 50;
+
+impl Issuance<u32, u128> for BitcoinHalving {
+    fn issuance(block: u32) -> u128 {
+        let halving = block / HALVING_INTERVAL;
+        // Force block reward to zero when right shift is undefined.
+        if halving >= 64 {
+            return 0;
+        }
+
+        // Approximately, 600 seconds (or 10 minutes) for a block to be finalized.
+        // Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
+        // Divided by 2 using bitwise
+        (INITIAL_ISSUANCE >> halving).into()
+    }
+}
diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs
new file mode 100644
index 0000000..5b09407
--- /dev/null
+++ b/runtime/src/lib.rs
@@ -0,0 +1,529 @@
+//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.
+
+#![cfg_attr(not(feature = "std"), no_std)]
+// The construct runtime macro does a lot of recursion and requires us to increase the limit to 256.
+#![recursion_limit = "256"]
+
+// Make the WASM binary available.
+#[cfg(feature = "std")]
+include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
+
+pub use frame_support::{
+    construct_runtime, parameter_types, derive_impl,
+    traits::{
+        Currency, EstimateNextNewSession, Imbalance, IsSubType, KeyOwnerProofSystem,
+        LockIdentifier, Nothing, OnUnbalanced, ValidatorSet, VariantCountOf,
+    },
+    weights::{
+        constants::{
+            BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND,
+        },
+        IdentityFee, Weight,
+    },
+    Callable, StorageValue,
+};
+use frame_support::{
+    genesis_builder_helper::{build_state, get_preset},
+    instances::{Instance1, Instance2, Instance3},
+    sp_runtime::Perquintill,
+    traits::{ConstU128, ConstU32, ConstU8},
+};
+use multi_pow::SupportedHashes;
+pub use pallet_balances::Call as BalancesCall;
+pub use pallet_timestamp::Call as TimestampCall;
+use pallet_transaction_payment::{ConstFeeMultiplier, FungibleAdapter, Multiplier};
+use parity_scale_codec::Decode;
+use sp_api::impl_runtime_apis;
+use sp_consensus_pow::POW_ENGINE_ID;
+use sp_core::OpaqueMetadata;
+// A few exports that help ease life for downstream crates.
+#[cfg(any(feature = "std", test))]
+pub use sp_runtime::BuildStorage;
+use sp_runtime::{
+    create_runtime_str, generic,
+    traits::{
+        AccountIdLookup, BlakeTwo256, Block as BlockT, Bounded, IdentifyAccount, One, Verify,
+    },
+    transaction_validity::{
+        InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
+    },
+    ApplyExtrinsicResult, DigestItem, MultiSignature,
+    ExtrinsicInclusionMode,
+};
+pub use sp_runtime::{FixedPointNumber, Perbill, Permill};
+use sp_std::prelude::*;
+#[cfg(feature = "std")]
+use sp_version::NativeVersion;
+use sp_version::RuntimeVersion;
+/// An index to a block.
+pub type BlockNumber = u32;
+
+/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
+pub type Signature = MultiSignature;
+
+/// Some way of identifying an account on the chain. We intentionally make it equivalent
+/// to the public key of our transaction signing scheme.
+pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
+
+/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
+/// never know...
+pub type AccountIndex = u32;
+
+/// Balance of an account.
+pub type Balance = u128;
+
+/// Index of a transaction in the chain.
+pub type Nonce = u32;
+
+/// Index of a transaction in the chain.
+pub type Index = u32;
+
+/// A hash of some data used by the chain.
+pub type Hash = sp_core::H256;
+
+/// Consensus digest containing block author and supported hash algorithm.
+pub type PreDigest = (AccountId, SupportedHashes);
+
+/// The BlockAuthor trait in `./block_author.rs`
+pub mod block_author;
+
+// /// The Difficulty Adjustment Algorithm in `./difficulty.rs`
+pub mod difficulty;
+
+/// The total issuance and halving time
+pub mod issuance;
+
+/// UTXOs serve as the digital equivalent of change you receive after making a cash purchase
+pub mod utxo;
+
+/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
+/// the specifics of the runtime. They can then be made to be agnostic over specific formats
+/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
+/// to even the core data structures.
+pub mod opaque {
+    pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
+
+    use super::*;
+
+    /// Opaque block header type.
+    pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
+    /// Opaque block type.
+    pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+    /// Opaque block identifier type.
+    pub type BlockId = generic::BlockId<Block>;
+}
+
+/// This runtime version.
+#[sp_version::runtime_version]
+pub const VERSION: RuntimeVersion = RuntimeVersion {
+    spec_name: create_runtime_str!("academy-pow"),
+    impl_name: create_runtime_str!("academy-pow"),
+    authoring_version: 1,
+    spec_version: 1,
+    impl_version: 1,
+    apis: RUNTIME_API_VERSIONS,
+    transaction_version: 1,
+    state_version: 1,
+};
+
+/// The version information used to identify this runtime when compiled natively.
+#[cfg(feature = "std")]
+pub fn native_version() -> NativeVersion {
+    NativeVersion {
+        runtime_version: VERSION,
+        can_author_with: Default::default(),
+    }
+}
+
+const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
+// native chain currency
+pub const TOKEN_SYMBOL: &str = "Unit";
+pub const TOKEN_DECIMALS: u32 = 12;
+pub const TOKEN: u128 = 10u128.pow(TOKEN_DECIMALS);
+
+parameter_types! {
+    pub const BlockHashCount: BlockNumber = 2400;
+    pub const Version: RuntimeVersion = VERSION;
+    /// We allow for 2 seconds of compute with a 6 second average block time.
+    pub BlockWeights: frame_system::limits::BlockWeights =
+        frame_system::limits::BlockWeights::with_sensible_defaults(
+            Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX),
+            NORMAL_DISPATCH_RATIO,
+        );
+    pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
+        ::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
+    pub const SS58Prefix: u8 = 42;
+}
+
+#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
+impl frame_system::Config for Runtime {
+    /// The basic call filter to use in dispatchable.
+    type BaseCallFilter = frame_support::traits::Everything;
+    /// Block & extrinsics weights: base values and limits.
+    type BlockWeights = BlockWeights;
+    /// The maximum length of a block (in bytes).
+    type BlockLength = BlockLength;
+    /// The identifier used to distinguish between accounts.
+    type AccountId = AccountId;
+    /// The aggregated dispatch type that is available for extrinsics.
+    type RuntimeCall = RuntimeCall;
+    /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
+    type Lookup = AccountIdLookup<AccountId, ()>;
+    /// The type for hashing blocks and tries.
+    type Hash = Hash;
+    /// The hashing algorithm used.
+    type Hashing = BlakeTwo256;
+    /// The ubiquitous event type.
+    type RuntimeEvent = RuntimeEvent;
+    /// The ubiquitous origin type.
+    type RuntimeOrigin = RuntimeOrigin;
+    /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
+    type BlockHashCount = BlockHashCount;
+    /// The weight of database operations that the runtime can invoke.
+    type DbWeight = RocksDbWeight;
+    /// Version of the runtime.
+    type Version = Version;
+    /// This type is being generated by the construct runtime macro.
+    type PalletInfo = PalletInfo;
+    /// What to do if a new account is created.
+    type OnNewAccount = ();
+    /// What to do if an account is fully reaped from the system.
+    type OnKilledAccount = ();
+    /// The data to be stored in an account.
+    type AccountData = pallet_balances::AccountData<Balance>;
+    /// Weight information for the extrinsics of this pallet.
+    type SystemWeightInfo = ();
+    /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
+    type SS58Prefix = SS58Prefix;
+    /// The set code logic, just the default since we're not a parachain.
+    type OnSetCode = ();
+    type MaxConsumers = frame_support::traits::ConstU32<16>;
+    type Nonce = Nonce;
+    type Block = Block;
+}
+
+parameter_types! {
+    pub const MinimumPeriod: u64 = 1000;
+}
+
+impl pallet_timestamp::Config for Runtime {
+    /// A timestamp: milliseconds since the unix epoch.
+    type Moment = u64;
+    type OnTimestampSet = ();
+    type MinimumPeriod = MinimumPeriod;
+    type WeightInfo = ();
+}
+
+impl pallet_balances::Config for Runtime {
+    type MaxLocks = ConstU32<50>;
+    type MaxReserves = ();
+    type ReserveIdentifier = [u8; 8];
+    /// The type for recording an account's balance.
+    type Balance = Balance;
+    /// The ubiquitous event type.
+    type RuntimeEvent = RuntimeEvent;
+    type DustRemoval = ();
+    type ExistentialDeposit = ConstU128<500>;
+    type AccountStore = System;
+    type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
+    type FreezeIdentifier = RuntimeFreezeReason;
+    type MaxFreezes = VariantCountOf<RuntimeFreezeReason>;
+    type RuntimeHoldReason = RuntimeHoldReason;
+    type RuntimeFreezeReason = RuntimeFreezeReason;
+}
+
+parameter_types! {
+    pub const TargetBlockTime: u128 = 5_000;
+    // Setting min difficulty to damp factor per recommendation
+    pub const DampFactor: u128 = 3;
+    pub const ClampFactor: u128 = 2;
+    pub const MaxDifficulty: u128 = u128::max_value();
+}
+
+// Helper function to get the current blocks PoW algo from the predigest
+fn current_blocks_mining_algo() -> SupportedHashes {
+    System::digest()
+        .logs
+        .iter()
+        .find_map(|digest_item| match digest_item {
+            DigestItem::PreRuntime(POW_ENGINE_ID, pre_digest) => {
+                PreDigest::decode(&mut &pre_digest[..]).map(|d| d.1).ok()
+            }
+            _ => None,
+        })
+        .expect("There should be exactly one pow pre-digest item")
+}
+
+impl difficulty::Config<Instance1> for Runtime {
+    type TimeProvider = Timestamp;
+    type TargetBlockTime = TargetBlockTime;
+    type DampFactor = DampFactor;
+    type ClampFactor = ClampFactor;
+    type MaxDifficulty = MaxDifficulty;
+    type MinDifficulty = DampFactor;
+
+    fn relevant_to_this_instance() -> bool {
+        current_blocks_mining_algo() == SupportedHashes::Md5
+    }
+}
+
+impl difficulty::Config<Instance2> for Runtime {
+    type TimeProvider = Timestamp;
+    type TargetBlockTime = TargetBlockTime;
+    type DampFactor = DampFactor;
+    type ClampFactor = ClampFactor;
+    type MaxDifficulty = MaxDifficulty;
+    type MinDifficulty = DampFactor;
+
+    fn relevant_to_this_instance() -> bool {
+        current_blocks_mining_algo() == SupportedHashes::Sha3
+    }
+}
+
+impl difficulty::Config<Instance3> for Runtime {
+    type TimeProvider = Timestamp;
+    type TargetBlockTime = TargetBlockTime;
+    type DampFactor = DampFactor;
+    type ClampFactor = ClampFactor;
+    type MaxDifficulty = MaxDifficulty;
+    type MinDifficulty = DampFactor;
+
+    fn relevant_to_this_instance() -> bool {
+        current_blocks_mining_algo() == SupportedHashes::Keccak
+    }
+}
+
+impl block_author::Config for Runtime {
+    // Each block mined issues 50 new tokens to the miner
+    fn on_author_set(author_account: Self::AccountId) {
+        let issuance = 50 * TOKEN;
+        let _ = Balances::deposit_creating(&author_account, issuance);
+    }
+}
+
+parameter_types! {
+    // This value increases the priority of `Operational` transactions by adding
+    // a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
+    // follows polkadot : https://github.com/paritytech/polkadot/blob/9ce5f7ef5abb1a4291454e8c9911b304d80679f9/runtime/polkadot/src/lib.rs#L369
+    pub const OperationalFeeMultiplier: u8 = 5;
+    // We expect that on average 25% of the normal capacity will be occupied with normal txs.
+    pub const TargetSaturationLevel: Perquintill = Perquintill::from_percent(25);
+    // During 20 blocks the fee may not change more than by 100%. This, together with the
+    // `TargetSaturationLevel` value, results in variability ~0.067. For the corresponding
+    // formulas please refer to Substrate code at `frame/transaction-payment/src/lib.rs`.
+    pub FeeVariability: Multiplier = Multiplier::saturating_from_rational(67, 1000);
+    // Fee should never be lower than the computational cost.
+    pub MinimumMultiplier: Multiplier = Multiplier::one();
+    pub MaximumMultiplier: Multiplier = Bounded::max_value();
+}
+
+parameter_types! {
+    pub FeeMultiplier: Multiplier = Multiplier::one();
+}
+
+impl pallet_transaction_payment::Config for Runtime {
+    type RuntimeEvent = RuntimeEvent;
+    type OnChargeTransaction = FungibleAdapter<Balances, ()>;
+    type OperationalFeeMultiplier = ConstU8<5>;
+    type WeightToFee = IdentityFee<Balance>;
+    type LengthToFee = IdentityFee<Balance>;
+    type FeeMultiplierUpdate = ConstFeeMultiplier<FeeMultiplier>;
+}
+
+construct_runtime!(
+    pub struct Runtime {
+        System: frame_system,
+        Timestamp: pallet_timestamp,
+        Balances: pallet_balances,
+        TransactionPayment: pallet_transaction_payment,
+        Md5DifficultyAdjustment: difficulty::<Instance1>,
+        Sha3DifficultyAdjustment: difficulty::<Instance2>,
+        KeccakDifficultyAdjustment: difficulty::<Instance3>,
+        BlockAuthor: block_author,
+    }
+);
+
+/// The address format for describing accounts.
+pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
+/// Block header type as expected by this runtime.
+pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
+/// Block type as expected by this runtime.
+pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+/// A Block signed with a Justification
+pub type SignedBlock = generic::SignedBlock<Block>;
+/// The SignedExtension to the basic transaction logic.
+pub type SignedExtra = (
+    frame_system::CheckNonZeroSender<Runtime>,
+    frame_system::CheckSpecVersion<Runtime>,
+    frame_system::CheckTxVersion<Runtime>,
+    frame_system::CheckGenesis<Runtime>,
+    frame_system::CheckEra<Runtime>,
+    frame_system::CheckNonce<Runtime>,
+    frame_system::CheckWeight<Runtime>,
+    pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
+);
+/// Unchecked extrinsic type as expected by this runtime.
+pub type UncheckedExtrinsic =
+    generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+/// Executive: handles dispatch to the various modules.
+pub type Executive = frame_executive::Executive<
+    Runtime,
+    Block,
+    frame_system::ChainContext<Runtime>,
+    Runtime,
+    AllPalletsWithSystem,
+>;
+
+impl_runtime_apis! {
+    impl sp_api::Core<Block> for Runtime {
+        fn version() -> RuntimeVersion {
+            VERSION
+        }
+
+        fn execute_block(block: Block) {
+            Executive::execute_block(block)
+        }
+
+        fn initialize_block(header: &<Block as BlockT>::Header) -> ExtrinsicInclusionMode {
+            Executive::initialize_block(header)
+        }
+    }
+
+    impl sp_api::Metadata<Block> for Runtime {
+        fn metadata() -> OpaqueMetadata {
+            OpaqueMetadata::new(Runtime::metadata().into())
+        }
+
+        fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
+            Runtime::metadata_at_version(version)
+        }
+
+        fn metadata_versions() -> sp_std::vec::Vec<u32> {
+            Runtime::metadata_versions()
+        }
+    }
+
+    impl sp_block_builder::BlockBuilder<Block> for Runtime {
+        fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
+            Executive::apply_extrinsic(extrinsic)
+        }
+
+        fn finalize_block() -> <Block as BlockT>::Header {
+            Executive::finalize_block()
+        }
+
+        fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
+            data.create_extrinsics()
+        }
+
+        fn check_inherents(
+            block: Block,
+            data: sp_inherents::InherentData,
+        ) -> sp_inherents::CheckInherentsResult {
+            data.check_extrinsics(&block)
+        }
+    }
+
+    impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
+        fn validate_transaction(
+            source: TransactionSource,
+            tx: <Block as BlockT>::Extrinsic,
+            block_hash: <Block as BlockT>::Hash,
+        ) -> TransactionValidity {
+            Executive::validate_transaction(source, tx, block_hash)
+        }
+    }
+
+    impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
+        fn offchain_worker(header: &<Block as BlockT>::Header) {
+            Executive::offchain_worker(header)
+        }
+    }
+
+    impl sp_session::SessionKeys<Block> for Runtime {
+        fn generate_session_keys(_seed: Option<Vec<u8>>) -> Vec<u8> {
+            Vec::new()
+        }
+
+        fn decode_session_keys(
+            _encoded: Vec<u8>,
+        ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
+            None
+        }
+    }
+
+    impl sp_consensus_pow::DifficultyApi<Block, multi_pow::Threshold> for Runtime {
+        fn difficulty() -> multi_pow::Threshold {
+            multi_pow::Threshold {
+                md5: Md5DifficultyAdjustment::difficulty(),
+                sha3: Sha3DifficultyAdjustment::difficulty(),
+                keccak: KeccakDifficultyAdjustment::difficulty(),
+            }
+        }
+    }
+
+    impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
+        fn account_nonce(account: AccountId) -> Index {
+            System::account_nonce(account)
+        }
+    }
+
+    impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime
+    {
+        fn query_info(
+            uxt: <Block as BlockT>::Extrinsic,
+            len: u32,
+        ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
+            TransactionPayment::query_info(uxt, len)
+        }
+        fn query_fee_details(
+            uxt: <Block as BlockT>::Extrinsic,
+            len: u32,
+        ) -> pallet_transaction_payment::FeeDetails<Balance> {
+            TransactionPayment::query_fee_details(uxt, len)
+        }
+        fn query_weight_to_fee(weight: Weight) -> Balance {
+            TransactionPayment::weight_to_fee(weight)
+        }
+        fn query_length_to_fee(length: u32) -> Balance {
+            TransactionPayment::length_to_fee(length)
+        }
+    }
+
+    impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
+        for Runtime
+    {
+        fn query_call_info(
+            call: RuntimeCall,
+            len: u32,
+        ) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
+            TransactionPayment::query_call_info(call, len)
+        }
+        fn query_call_fee_details(
+            call: RuntimeCall,
+            len: u32,
+        ) -> pallet_transaction_payment::FeeDetails<Balance> {
+            TransactionPayment::query_call_fee_details(call, len)
+        }
+        fn query_weight_to_fee(weight: Weight) -> Balance {
+            TransactionPayment::weight_to_fee(weight)
+        }
+        fn query_length_to_fee(length: u32) -> Balance {
+            TransactionPayment::length_to_fee(length)
+        }
+    }
+
+    impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
+        fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
+            build_state::<RuntimeGenesisConfig>(config)
+        }
+
+        fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
+            get_preset::<RuntimeGenesisConfig>(id, |_| None)
+        }
+
+        fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
+            Default::default()
+        }
+    }
+}
diff --git a/runtime/src/utxo.rs b/runtime/src/utxo.rs
new file mode 100644
index 0000000..d51c203
--- /dev/null
+++ b/runtime/src/utxo.rs
@@ -0,0 +1,31 @@
+// We make sure this pallet uses `no_std` for compiling to Wasm.
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use parity_scale_codec::{Decode, Encode};
+use scale_info::TypeInfo;
+#[cfg(feature = "std")]
+use serde::{Deserialize, Serialize};
+use sp_core::{
+    sr25519::{Public, Signature},
+    ByteArray, H256, H512,
+};
+use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
+use sp_std::{collections::btree_map::BTreeMap, vec::Vec};
+
+use super::{block_author::BlockAuthor, issuance::Issuance};
+
+pub use pallet::*;
+
+#[frame_support::pallet(dev_mode)]
+pub mod pallet {
+    use frame_support::pallet_prelude::*;
+    use frame_system::pallet_prelude::*;
+
+    use super::*;
+
+    #[pallet::config]
+    pub trait Config: frame_system::Config { }
+
+    #[pallet::pallet]
+    pub struct Pallet<T>(_);
+}
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
new file mode 100644
index 0000000..4c59c32
--- /dev/null
+++ b/rust-toolchain.toml
@@ -0,0 +1,5 @@
+[toolchain]
+channel = "stable"
+profile = "minimal"
+targets = [ "wasm32-unknown-unknown" ]
+components = [ "rustfmt", "clippy", "rust-src" ]
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644
index 0000000..af85000
--- /dev/null
+++ b/rustfmt.toml
@@ -0,0 +1,7 @@
+edition = "2021"
+use_field_init_shorthand = true
+reorder_modules = true
+
+imports_granularity = "Crate"
+group_imports = "StdExternalCrate"
+reorder_imports = true
diff --git a/spec.json b/spec.json
new file mode 100644
index 0000000..f3925b8
--- /dev/null
+++ b/spec.json
@@ -0,0 +1,176 @@
+{
+  "name": "Development",
+  "id": "dev",
+  "chainType": "Development",
+  "bootNodes": [
+    "/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWDqY96nhSh1sahtNAZTiXu1KbeKiwsz9Rwowv6bBEUjvZ"
+  ],
+  "telemetryEndpoints": null,
+  "protocolId": null,
+  "properties": {
+    "ss58Format": 42,
+    "tokenDecimals": 12,
+    "tokenSymbol": "Unit"
+  },
+  "manual_mode": 1,
+  "add_sha3_keccak": 10,
+  "remove_md5": 20,
+  "split_sha3_keccak": 30,
+  "maxi_position": "follow-mining",
+  "codeSubstitutes": {},
+  "genesis": {
+    "runtimeGenesis": {
+      "code": "0x52bc537646db8e0528b52ffd0058244e043e8a45b61153204c434a070534c63d412249e4094823de82c3328b4264ecc48046290950666699ebcdae36560aa2dfe3f34603e6ef9dbf9ab708ca1987befc032db52b5b8cb9c6f74e54951f04ebfeb6b7dc5b6e29a54c3205701383118610737e4e6f9fe0943847ce915b2e03850cd52d39c130e927fdec04b939b9eaa12783b2d99a602885f5d46d1c5e3827d7922fcf66ad0eaa2def0a6f5aae12a00b21ba60b1186a08dbadd9adf6d960d8df1e9d7e5ec8c5b85bb43f7efa4d8f1f095992c4fef8eb47427ceaf3e3626d6df49b7d61d273d76098f4ed1e751924bd82a114eea97396825eb7a41bb5cbd7aa83a44b9ffed2bb4bb2ea96f449e5450f572fdd48dec87117817651972eddcbeae42e46bd5237ea4ae7377f4e5d060ae31c9b691d53fd752e7ee7d2c3ebd6af6523f3ce8d7a08b783c754fc8a533248bae7a1f5f1d0fbcd995f2c837c78c8facd47a84e443434d46ab9b358a1f721cf092d53fd749a14a6bb0d18ea7b3cfbe6d49cee030c593e60e87d18a7bc38f5d2d9a9f7389719791eaefbf8b92f9c4ffd7efcdb1732d4873ce7a5d7cc56adfaf43bbff8b1b33576b1cced179f3b0df82b2885a93eabde5ec1294c45c18f3fce7906409217291843598d7e6ffbfdc2a1bfceb54b933e3cb43f3cf4de43d6fb388f5bf9f29cc7571fcba01efff1b10ceadcc7c7328873962f4f0649a760d8e479c0f07ae637fb621c4f73a3f6a8b39e7a0f18b2bca7de81a1275fd43939f43c3e3bf0f9988378dcfb988342fb3cfe9d57ef79c0e9dcae0e0c4778ceb7daf31cc8dddaeee7bf7d213f771c509fd1ad053234f4dcad70fe0479e81900596852d7938a2bfd32fbc4bc6ce996746ed715252525a5e77671b742fbe17cf99a1d249dfd5eee94546fa75fc83d289ddba539f7ebbad62de937c2e185f3a573a744f3ea469d7dccadccb95de1fc0ccbc71cb479771bcc9f6e7f0343ead6a3cf764d30bcf2d3a35fc969dfec9674ee38c87eba511bc9faf1db8fbb581bf56c5775e9b65d994be9f4e39fcf5d463d72d9379fbb4a9d9fbb087017427421c457376afa49e1be82443668a7de4ec129dc4f70762b3a0349308a675bc210a538e7b2aa7d4182e74b145d6ca334cff09b2ba0a02385a9a71dd41cf142ea470232780184185ae418638507c513a5946eb4c929fb52c4cc9aaa13ac4415177587cb6aad4e70419d78e3f1ac3309092827cc8431040c6aa420c0549b3b43b001871c4314208d0b3ed284a993bd5a6baddb8a3b25405ccf9cabd58b6c692e59a2892f4aa0e0c68d1f086002931db38617a614ecc051c2a94ecf6b3d73dbb43acf5042cca993d99ad5a6a9a649c0c5094a27cc41061733415ec031f2013abed001468d1c16d034297501a28d3a34e860a60a225a5fa6be8cc1b559a283870e432c31075fb144741e9e58232a0f2d58ec310013b6700928428f24988e8823883a2c29690f503d48f530555956cbea2657748cd8d44f3f38363d434985794a635303cad8638b39646083c311302a803567d634a1f540068b2d98a6903a824c7cb2462989246ad8410b0d0108c01b23ca50a20717c030b3c716464c983161cc844113464d183661b8a04456dbb2ac08309b0bd366946eb469365565b602304b69d0d09921862d80ba28830d56f34314173928e110158494a22fd401bd88a20d1b2ce880e10d0030d99930285936de38c38c2d577461218cedd1b427dc585b3779466ada60c49c4d4875d3193710f1a529aa0e78c21b4b84682a83c39821d2e8d1656620f3061b188c98e2fb020b23ab3ae28cf1069d3b4978a147d20d72b44471c513687c38c2cb88a309292ace400307164094d8d2b0b075549d0d8aa1fab56edb139afaa4a63eb1a94f5cd4a737f5094ead434bb10b1a315bdc446921c64892292f5f842883c60b2a3a9bfa010e2a3030b4a19303055f68f981a28d1930c63871861c5e340b67b2f94292521a70944107531163bc14617a4399cce80250441a43a0b1041346d4e9364fd3afb821ab94eae073d615ecb0b085852e1e0b32b05cfe4053060da8a9a52d550c10a3062ca25eb062cd173f30c090c1d02483c0b054617041b6e1754726a09890aa9ed5329b656d32a629386a77268c0e65ceb461c41842c03143a4c91a2931a66ec882091ce4521d159454585281290e8e020c1d41a410c61e4f380dd1a2e95e4175911801c41b766821468ea51456504c6d4b48f50e523b4c6db556bacdd5d31eab8ac50fa82a67283b358d49c9322d592626cbd4e473789e50e2a43426abfdd534fb713b782cf50c9542172937335bf334068e21c4a0b3441b2d421e70861a69e87005174d5c71a782b183c3161cbae020030e60701083c3181ccc8820c51c534b384165431330ca7a2a8b38c2a74d0f347411049b215ec8828820da90654dd34265b554592d73ac4d0247191fa098a206346808c2044735a109ce0b2f382187993972c698a1696cc258cbc6e9299b323d6968d41c5bbfc439930798357a9062822f7470b2a60729dc6072214e1076bc5abbad3843ad80f2b83553926b2ba4b6356a8a789259b4ac96d14ab78d87a9ca839bca03150f552c1ee6788bce227ea03603a2462be28a1f6fb4b85952410f2f506d0861a28d3be69c80421e5ddce1a38939174a2a5a40072f94088385342e6c59f530460c3bcc01e7cb0c53dc913f74b07632245844a569430b9b326ff8e042ce1cd6c30b3ceea45185068d17490655551e75dcb0041e51f87c01070182b87091861c31d6c88007471380d0f420a234cbbed65ab7ad4c98324e659eca9c29035546aacc1425a2b469d21ae20b4e47ded810430e43a0c1860f1e131dca74874cca21ce147aa8f04297252ffc83131d3a56b4d9e386217ab408c20d3cb4b8828928e6b0930412f18e3d6186384b35142147d4173c6e9a5653defcb0b446197a38d9a1076b5ee62821c31b1bc6c0e9be38e2878baa3ab8d0410733e6b0c32db1003b4d26c4d0c3116dea7031f0c0250d0f5be29011790b2930a8e43c41461d632e53f1c3116b20f1c69a357238e9881f9a769062e1ce9914b6a42f669c720013a70e3676b49206516daa9a96d4e8f284d69243ede2af800a616ad0e3e9841cd460284d53d234fb9aa66daf59eb825307f1933de341b1a47caae566e8a90b54444f29437d26cb5c1b5f1366ad952f02d071051b2798f1c61b35306a9f6e2103c391c6134a7c5115449b2c9a688c7bd45a6badd46badb5bf463951eaad6aadb5d695576badb5d6ba02e27ae6466dd49e7c5d9065d0f40976bd71ca9b991b35cb9757a3f2f83abfd65a9ddb153f036b0557de4ff728e865894959d3349b56b7ed0b93a6cd8ab4030b4f61ecf0c296a6a423ece091840964d430b147a6c5844e8b0b33ab554b0c9a961bb22578a4d9a10e17348c60e3b24973420f46acf145ce13577b3114474da3450c41af1843b34ad3fcd05af4509b0c105eaa9af080a389062091841a1c9ed6a803c76441836a82c2276a090a4fabd9cb535252320166a5a6d530656dfd66b7a67f1122e3403b7ffae4dac55e8d1d05cb6a99ac52cc5307f1990eaacefd321203d541fca1f7b5b2ac66331e13ecccf082163fd0410374c21b20da08428d32e4cca7383673cd66b2882d2b4f61ce1c27d8a023a60d573104115ab050c10919ec10e372ddc1b33ffff63050e83f9dfbc51d149d3db41f9ddb45c130fee6a17d766e57e6d467bbac53b7ed0ae357a7ce79edd29cfaaa9dfa4fbba453772eb24fc1500ad06f3ebb15fdc62a2f3a774ab85bd137d0762bba5173bf8cd040c9207ecdb98b6920479f98972edde2b76fd443625edeb010ffcd3efb71dd9a1ea7bc1b39962fce238fa91eba78c24d0a6cc0a85bf9220198363108d1e60535ce80d1fec2467da2b381a114a2af6e41ae5bd3b94b9281b65bd32bc8ddaa6ed4466de56bd541d3a77bed8a4f9dd52e862ae2e9a9ffb44b3e756f17437dc9e1a903f58b83513fd2af09a3ceed8a5fc1d07e687f3acb177b81860833cc9c00668e138cba95af2a26c8e9c20b3266da9002464156b7a6c7292f5cfdf455bfa292929292126c3ab78b3fb41fae7e3a034d308a3f0320298b130a4e860a6a50b37135705e38262e060e866bc6bde3d6b9765c3a2e1dee855bc7b573d1b86b705a3816ae1e9c0a770fee046ec9b271cfb87968516869b4280d4ad341cb41c3417b426b42734243a32da101a121a199d1a4d0d46862b41e341eb41db4233423b422b4278d08ad8c46461ba30da109a105a1c5a07dd166d064d0bc685d3415b416ec1d4d8b6682c6a429694b560f0d052d056d8bddc3d6b16bd82aab869db269582dec16b68d8563c5b06b6c16b60b9bc64a592a6c9485aa715828ac9a8c857a8565c22261cdd814ac0a56c92e5916b23b3237b2363236322d323132303232b22c32aaec8aac8a8c8a4caa6651b1a870aa14554e65a356552dea16f54d1da342519fa84e5434b5891a445da29ea94ad4242a1295897a4435a23e55226a994aa68ea94354a79a43c5a182a934d41baa0df54b9d21b362cad16b681cd48d5987f432599032cc2e9408da0695a26ea816f406ba454b516568a9a6828241a9a06b281bfa45d64246872ac135d125e811d4886c8eb944c3d01d280f14073a359ba05f2614d4cb6482c22077985ea61c198384a18d9829442c2612b10d15621e61edd02b260f354d5635d150273a89a9344f9077ec10991bce866c8c39439646a6c6849a51778ed944b3c896241c3d05f5411641b19047d036d91d59c66e91444c2966145688ac8e6d633e4183904d370e8b82ecd279502ba452d79126c813fa0efb45e351a728183b85f58256416da03a7415d38bb6a2c3a03fd033990a2d437b9970d813e297d8144d9064aa9769029da2a166988e6a28ac141d45abe934d1857842d4427388334419a217ca0697021d33d3cc37620c3586cac47dc9e4cc39e61c4a86e342cb4c1466125a0d1a0d9269c631cf7032705d26173983b4236b3357a828646cfa883633e3482aa69acaa5a65061984b4825a613768c25422e4187984a4c33524d4607b765aa20cf48212c1959878c42d6d156b8773814b81568940dc272a1623412938e2d63f39027dcf81c2b0b5acb232b4e3ac06404274721306172a37c32e58809934d484852b19523119c4c61424496c14847568eaa8cc004e9e8034224197c84e404c90a932752a080a00356a058399a72a464881c6348be9122c5090852a43871801821207d60ca919430f8e8c8034ca82031410ae103508e441024c1602b52a038413a7ac2e4e8c80303906e988a07a64061524295231090c004ca088f34e54884129c74e0f20b3e02610a95294c9c308132c21f8130858a0490a680800a08207c11e9053f610265842f01490a084080e2010f40c98025bb78420584a3274624176ca584a3284cac3039427252e568cad107985829e188832954a058b17254814f6ec122604285099411beca51942a543030058a931040f08007967c520b3e4272f2048a1427216072048223104cc08327471ff880130f0a20b3602b5140380a018429b68234e5a8ca510853a0b8c4620a140f10916d18042856a640a98274e5884909524618c109932a474fa44001012c0a0854a4c07ee4156c658864c34e98fc482b5804264e909c3c71827414011f59c508a04871020509ca142840e41a8e020215291d6072840402108eae1cf990525c858a03388e47523ae004690a083cc0040984a32a509e4c81c28489100ab238d91c29bc543d275d865252fa98248554a9456a8923c46cfaac7ce69c3e73ae563e73e5e3c30753e6cacd9336b3642b294bca719129a5946b6c2a2b8bc5d26cd632a3b466565259a9dce82669db2a2533d35a2d33ad9ce51eb2b69967e55aa7262be59e75c6586bd566adb5e36ab96b9d9c94b2d2cef2d4dab45a96965bd64e4a2b2b308090e5ae922b655a2b9d927665a6dcccd4b2ac9563b6dc9123b7d56a95ccdc525ad949db9c8cb4a3924a4a9b796e32d62375d64a2311da52fefc74d176b5b6a354525a6d2d0001e6eca993b2adb3d68c29a541b6672532ebec69cd4a0750059045daddb4bbb9a6b1bb69ad1c8f94b625677572ad53cacab54a8ebb878b5256cacc1379380043781a4856e66d080098593273a4b5f654ae55ca596bad5c25a5d232b3a4d552090691525ad99b8f6ddbb6ca552929a5cc2c25d72337592b4fe58ca994cc1c2533cbacca8c32d3cb5232cbcacc928747565969ad5556fe6865965c5972adb1da3ab75867ad1cc771cc5c2995b2594a59abb5d6522ae59cdbb66d5c654b66e666e68c6564a6b4d64a25959225951c67bbebba4e4ac9939b93e3b89ec9492aa5a45272524a1963acd33afdf1e3c78f4a679d929394522aada4952995959bb2566b955c6b6539236dda9c0c1c0dd207770955a8887024428d22301fe0a88a079854a182e404042a52a438f941e22a72858a0890287025c002f72c384008569c84e09a94a3101c496172c58908467c7c808a14261f9802e5031fa0224548152748560610c48a102343a280e0a40352a450a94280098ea23041ba72348582a30f08f1ac20598172e5284302c18995294eaa20314182228208545a14b005503c705465842a4e8ea4804024c8932947238ce084c9d1079c54a1826465023ec091085090a680a00a48e4012410140172e52804264853a0541981090856a088f05304890a952a4c9e1c55397a52850a1357022c6062c1511427523ac0e4084a15240258500500972d787264c5ca51951144a00202932a4721a002c25115264eac3c01e188c901a2b81260c108201c59798560ca9114c2076032850a142b558e42c0a4040f40a9721402260a3840021260c193232654904628a10a084c90ae1c012004538e2411dba5394b96ac09d76ec249591a4b92c49234b52649314b9629936a6d9214b364c992b435e1a4a424db84b3648949b1499698254b379624db242966c992949435498a4949dd84b364e926596296d884b3c4269c94254bd26cc249596413ce92254b9624da242966894d9262962c494933296bc249b549969894d44d922227d126cc4d9262524c4a4a924d3829a99b70525252d26c92149362134e8a4d0ed0559199a308569c7079c0d823947cadc4785384963b33341901638f67d8e3937c2d11632708a82cf6702306c63fd288b114c4144d542401638f61d863137b6462f9ec5189fd0afb08ed42c0b387c0de843d56b54b7bf618a75dedacc9ef9ce2a1c36b08a85d9c536f69e171ea4888b478ea18f48ba1a867d0aeebd435d802a3de41bb7e38750f3e907aea1be802a3fea45d3e9c7a0823b46be5d491aed079ea5868d8d22e204b13c8d024f5d423987eb99292120c30ea514cbb7a9c7a74eaa7760531d3ae78468c31d0b0a0a65d2ca97e0d4db54b88538f5c4437673cf5f8a60518f508a75d439c7aac8a73da45c4a9473ab10e1c4f3ddae9174351ef2dedb24ebd97989aa69e7a83e91960d45b4c3b3df599169e7aa3e92f30eaada65d9b536fa97e79d47baa5d9e536f2eda8d134fbddfb48be7a9cbd152f49e37d5cfbf5cc5c4ceb36a5cd7099b2be658228c26d4a05344d585176f30f51046cd6fee40edfaf1cd5bf2159986dae5e39b232132e137c7a05ddb6f6eb4b906db05bf6dbe817615f1cd9bc857a4da369edfe0b0e337ee370bc061840d3ecc41451c5cc036d6e20a3bd480c9630d15bc806d1cc56f1e99e42b2a356d467cf328a65df3b7375878235cc08c1871ef8d32de88af8cc0a1c41bf11f23fe5dcc88ab91c57b3eed1a41bce71c0a30cf572c22def31f6f8d3dde7320af6aeabd2698e75555bd27f59e1bb1f1f49e67d02ee6e23dd7a08d2def39043a681743b5f1e63df7c0f30fdac5506e10f19e6fc0f3267196def327ed6237ef7908ed62a83854efb994767defb95117f3fa8b48b1020f2e4f67f450c514ac481e64e04c51c70a2db4b10656c45945d4c0e28b7803ba58111fb768b0791fe75480f9f80a8d2ede678ff781b3c5fb78f13e6904f13e64603e3e6978f13e5fbc8f1a64dec73368579033e6781f674017f3f9f9f9f93943cefff802bad88f63d0c5b63a9a78cd354d7396e6ae796ba85d3fae39923aec786d82d7344df30f36d02ecf356fa27908ed2ae29a4bd11ce98ad292e6e39a46816b1ec5689aa6699a11d73c4e69ee9ac737765cf1eeee1774313762c48811235ed4c58c5060470b4f812ba08b51607d7c7c7c7c9c48e88bd451c517f157172be2799ee7799ee779eeea629e16ff43071bffe309e8623f766699f3a50a38e438038a09b6cd110397281fdad8a07406b6396bdbb66ddbe848e33747d2c5360474318d0e2d5b1725d694f1c31033f4f0260319d684f182aa88263b30eb2ceb6ebd3544d4c25bc7a05d3e6ff740838c39527138a17103665d03f9ba600827346e9c00c5431798f50edad580b7fe81f526f2d530eb218c20e6ad235d515a626a0a139d9c78eb714c7cb21ecf588f50f1ad8fdb08b31eddc8d7845925dec77d7c7c7cdc822ee6e325a1a9418535d0c479a20a3a30cf0a1382f07286871cf07001e631e03d3a7278cf0fd0c5bc6ddbb66ddbb66df3a12eb649cd3d04d0a1247fe8e8f19a5760802e66fd89d069f3445ca88b11b1dd0f193264c89021438644fd10673a30bcf579a48b59abb9d5dcd3e8acf09a17c009d0c586105df142cc10e385ac792167887921be6a17035e880b2fc483ba9810d6f62cb7f245c1121c1de8344181c41430967bf255240e0a628250028eaa27602c67b56b01cf726fb158666c79161517aff96cd7d06bdeea629a1d401763110511238a0fe202e86241c250e27b7cb60bc8f7f4f4f4b8f7784bbe784e4ff63d623c7d4f4f121a2beea8630919d6c00006acc73590af2651e041039c2722da40c17a30f89e9ecd7b867a3c847679dee352da25c3d8e23dff01e679eeddf19eafdaf57acf03d0c53cd6e676732fc86fce6c7e73a02eb6b914afb945e1b5346048bd0003e38bd71c680c4cf32350616879cd91b40bc96b51af3900ba98363f38618e309e5ce84169ce08ce4c6186142678a9d2e382b76e9c78eb6017b3fe75b19e3913bc21e22770ef621358206e81b80784c80301e240edd21c0810206fc23c1038defa6c97056fdd4817b39aa6699a53d0c5342fd2c58010ad76f895ff74b1955dbd8f2f5cf8a208288660630c1d301f7b8011e70e36b668e1421d980f67b5abe87db8b74bbe0f076a97751fde925a603e7ca85d9afb7024edd2e668e17d388ff19adb20078c395359c4b1036ff19ab7dac55071d079cd8fe800d31c099197d71c83767116afc901e735cfa05d41af39912ea6d922e2e061460a5438c1a50d98754fbe245027cd19377bc471e20e9802deba67f1d681dad56fbd657dc83a51bb10f0d68db678eb19b46b7beb1a58efc0fa07edaa6fe558f1d68774314b25a48bf978f33fca88f33f9cd5c57e8c41c65f9fedeaf998b8030715e47021e209a43256dc61020b62dc9006d15f77a0766d7ebd25ef7524ed9a7f9d2885bf8e41bb78feba91061db4ebf5d73f68723d8476f5f8752923c4f9eb48edfaf1d7afc857ab071fca8861451e552cc16ed293165b446dc1218b292c60d7f5f77a7eaf8f98e834c65f8f63dad5f3d7e3937c1549c1460b165bdc602307d8f57846be929a90a34c1874409d89420bd84dc05f8f52edeabf7e3d4e9d00bb1eddb4cb875f8f6f6e194befa38bf7e141ba988f32b6bce640ed9aaf794bf321cd89da8564822ea661f13e38bc8f03e9623ed6732b5f146843052832eaa041872798e79e7c3d00052398dec82047135e609eb3da85e43d326678cf575dcc1bf23dce6f7c8fffe8623df60698b56ff478dbe6ed1856bcf59f76fd787bc65bf7d1c5acf69b5bf98a4c6b8ea8e20e26b22803b69901c51031aca1458e345a806dce6a1702de80f19bfbb8d7c52e15d4f3e811c3f3784f17e3c1638ae79e73cbb9c771cf71dce61c676786e77e3cb71931870e526730a9f902e3180ba92a35dc7883c61166609c05cf71be81765de7bc897c3114a739379fd3c384e77c9e633b35e8b086147544ad80058c73b1b1b4254c991bf09882710778ce231337c459e7e473ce4e6fdd5a3b59bcf555bb86de3a4f17b3ac20609ae69e1daf45bd96c799d7fca75d3cc66b78b479cdbb2ea6f9757bddfbf9ebd7b92e7601f01b1e3dfce6b78b6d5b17e358eabb3bbef8ceb52ed655f1d96761d040440e5a7c985ab3042c734fbe9270d80107266e48010713828065ce6ad7d067eef215955af2e5653ed42eeb9923216ae333c7a05ddd676e94b9069977d02e229ff9071b6897e6993709a15d9b672e65847631d41d547ce648edf23ef32bf29524441e5384c1e68e2a2f5680651e95e4ab6e31c10c34496cd1e169a95d157ce69129cad0aeeb99c72699790cd32ece338f62da153fb3e3399fede2a9e7dc7631ced6bf646851c6a9ca081e56700276dd932f8e2306a63228a8b1638c09b0ebac7619e0af18557f3deb62d785fc56278bdfbc76b1cdd2d7dcca57921065aca024c4162f4a5801d3dc93af21718a50d3020d69d84903a639ab5d42af9171e735a75d4cf3d92ea0b750757e78eb5376b1cce99bea3bcc122c7a3bf52b2a453a1ef5d0fb19e6a347ef31eda2cdd4ade861da353d7a8b69d704bb8b047ba9b2e0593df882e6d25cacb5d6dae122fbed764abe7aa9976c2f517dbb555a6ab74ced02fa76dbd46ec3b45ba776f17cbb7d6ab767da2d54bb26f8763bf5ed964dbbe6b7675d7491655996d9e1a2ecdb33376e323754df9e39654fedd999f60caa5d147c7bc6c5b7676cda75bf3d6b92af3867ce470fb330df9e29b5674bed195375c2895a6bad76b8a87e7b8582aa61a5faf65a6b2de3db2b9b760df976aa075f107de00aa2777f187db8f3ed94526a878ba8931375a2134ebfa2d28cd32f86b54f3afd9ab0f669878be6b7534aa9d21ddf4ed9b48bf5ed734abe2253649a91694a59c70e174926a709c3b74f36ed0af2ed124ebfa4c491724abeaed4917564779db6c345cdd4d42ec3b44ba776f97cbb944edf2ed9b4cbc7b7379c7e41804d9c6fef29f9fa40064577f361537d7b9c13ebb4cb0e17c56f6fa5f65e6a6fa67681dfde4ded1da6bd9ddaf57d7b3fb5f799f6866a57d0b73713dfde6cda658fc4f9f608a75f47886218dd7c7b9c922f223942fb152c5ca4d41e97da2353bbac1354bbf8dba3549a6f8f6cdaa57d7371befd49bfb80e8ade5421bbf9f60ee48b2583a277773babdddb5bedeabe7da89da8dda85d47be5d8376719409567c3b04da55bf5d3ee185bdf4d125125e18c9f0c208f5d1e91b2f8c4e1f9d8ee18591e9a3cb20bc90e37c74e9e4855ce7a3533dbc90d97c746ac70bd9cd47a7505e78e4a35328bc90e8a3cb39bc90fbe8520e2f647dd494be9f9e0190e4f1024c5cae6b780cb587d457f00ca547187f7b3267ae22658c515ce8449711641692f2ab6ed497bb24f2338f9ffc6ef611d9407ee6f233d0596883cf8261f45ac6b443ca61219ef352ca8f5d1269d4f2ab2011e9f62598e44a835cb7d89b06cf7f3ebbc7af264d338c21260e35b8f801c6cee29708d6a02186a9349660b20363777e592ada3883c69d35b0f802636ff14be8072a4ea8a14e0d78d081b133106b511a41c68b3edf10c28bce6ae219c67eb98af156cfab37ea9e29c68b3ee4396acb16cc12a0faf6eb437ac852431cd55240964930642c988ad7b6cb7197c5726fb58686e414d1e3a2e8ec377e3ecf0a6290033f5d4616aacedd06e04ffae3af74f3ce5d129e6f55252f7ac89a1ccb57e6ec1e17f53c7bf67932a89d3b20ec18afbf86597ebaa49cc745f2fbf13772f2e379223f002bc8fb9e853cbb0fbf581cd4ce6e845fd6dba3937c59700419d49e79d800ebe1ebc30a360f07b059ab799e65b1e42bf38f4e23b050cb3bbcd87e2be771d18f3a3b6a3ccc42354a973edb452518a99e0190a526d1b667dce837c6f8cd6eb17717e396f287355793d2f8611023ea94f423612125fd918bdf502ceb94f4b75888fd5ace78c2a427b281f621093e7a7f88e5a3cb2ef6133fa02ee6b37bba9c60d8fd7946cddf5f74fa9190e5dbdbe547427ca0f8b99c6178e1cfcfee876a5cddb8acfbb9f7c68d274c7a160bb1c7ef48b7d865176b79b77e64a7243eab5b3de36cefef087a2cc49e442365223ecfcbd387eb1691e7282e637e252486f6d9c6565ebb423a84f3b05dfaedcfe3a8c79ff9b1ba155d7ef1a39217ae3ec6e8fdf1335004a338119781ae94c2c60886524a7fe9310af317fa3c67525613bce8dc92eb272f7ac87d7b4be76e450986f1a547672e8a1f4a9752dec9493cbce81ff2e5cf762b3e7b04adfc2e4f29bd5f826195f718a83bd2136e75060ae3d34bbf318eed2f658cf3c1f36f0f23d3f7215731bdf410e4eb3948fa9a3959d46130948a9885c2effd6367c44263bac5d427e6458d9be1cd27e6454cb7d83a7b183fba51bbb59ed71eb23e64a88e2c799885622bbd0535e89674a32f836e49ef26e2d2b377114d44c8552f3d847649a761b027792143bdf4e94619b4cbba740d36bf9ba55403edc3cc43eb3423420186718e85a160255c2f81739ffedbb18b714744737e0f3a221ad80107b20c7aa3de3e221b4c2525faf3b9db202a29bde6f6eb670d64758be3675ffcfa85feec977e5142201f8812ae6f7f23473ffadc69602a2919f58d4436981f4a19fa26dd62af6095f95298ea3d38c06bd02d76a3ae2778d3afe4e827bf3b0d442525d875d979c05030faf5dfc9d1eff2df26b241382bf841b7d893fe4e291ce5ea5765be1456cd2c57bf70be07dd62bf6cb3acd2293b6a7c79c2a4d78085d8eb67ffb2a41d99f29010ef3c910de89310ef7cf5fe0a8655de8885d8bf9f5f38f4ec4fb639aadb13bdfdc62f668482223f44860861059900c8ea870f1faf87a7e3eea6d9acd2293bb2503b7724c43b0f8474a3ee96607ffc596252779721dd636899d943d64b0e62971e9f3b991463d2f589c5c045b7f8c3e8d52928bd9d3fae5bd3d9c3ea5efd567978d1ab87dc92e8512a68d44d8417723f3dfcf9e93fed9ace6a57f439e7bc94d6e6e817c3f9917efc32c63c46f8e9def34bf3ea965fd62b1846cf9cbfd07bfea6f7d19b6510bbfd580685f6994630ac4e3d8c9e81b35bed37cbc3ab1ebd9dbb25354a74ee56bb5153252f9cf1b3dd6a9f1fd2fce846dd49b4e31d4a27ad734e4aeb182bcb79ab95985abfd95afbfc38793db4a117b2f8e54d37bc8ebbfe356cf2d5b72ab399d52ccb6a0622d1af21a04337ca35385bc130e9abcfaf1b0cb95b2143b919f348cd81fc069985e6fc6abc93d6d6eaa77372bcd05a6fb5a2f4572c24bdc9f0e644c017366aac563fa51a9781423927068617ce8f7372d3a5876edbf0c23927c8c539ad340109933678b366b5cec9030c4b3f63d329e8758b7d82ab6eb127d9d83f5c069af7dbe3376decc6a0ba7de371549731357ad04ab00a5a1934db153f1b86c75164d87c68e4db3da900eaed967e56162062894952f618d5ef8c4778a194929a57fb69ddd23cb2d872d6630bec918bebf1ec20e0977bd02f231954ddbe69669fc2453f9c9d0a5f00c4d94960d7caadf0380abee0d959f245c4d923c0459eb34b205ee0c3d93b68978fb323805f4d6450f51fdf2670f6d6112eea9c5d882fe871f60ad8c5e3ecec6d3dc6568a61229492925212d6af563b6f7529a77df7564efbae7397b9515bee62f5fabdce1d77ebba51d72e76fd669cfda88ce4ab95c2c8a0ea2ccf95a0acf5a8be7aecae7397e48b4878d1edc7e2a2306adf8d31d3beebb73b213121ae5d4ed33a4e8b7f6fffad1cbd423efe2b5310c26d9fd472e9047e2bb76d6ed442bef8f77e52cbf5c1452af9924b4af2d555dc61e4aba538a83a15d512559552951287e930dc52d56f6bc95acb8fd6c29d92c894c417a12954ee7e528b579fa3989e3e4ececb9ad02e0f0c30643f7e0059c92536da103b7e689ce7f9f0a9aaaaaa52b3b1caf0eed5b8ee936b58a8a58238cb432f88cb170560105f73833c473149b5e58a7c1136e49353324806b17ceb48e038215fd64d20c28af8e5b88d9be0bb7ca9f0d8a86fc7dd4fa6d0e5cdbb51df8d13f2c5efbadb75178c663ceb423efeac2321be10bf2c83b89f1cd3ad1a5f3adde0c9290fa51327e4e39752b60ccf7ac8bdf5d5aa5bd6ad5bb0a1ba559db7acfbfa857cfcacafc8c7b0205f683f72ddd7ef7dfddbf7e36b29168a68bcb0a1a0d4dc8eb3137c9a740a235f72a9ab64507527252725272596e7c9a530d67aac0f3b420df9b6fc380a0e1be244be2d4b0e1be228388c48fd1b3d6e9e3003a5d427d9300164457f3839393db1f1e1333db92497e4926452c33d9fac2256509de7936c7a382bffc64e497f0776957cc9a90eaa5e9de3051c2b0865158b55f535943d2749fc353f9f9cea045427f2712720946fbefa904f72d141354ab151739f9cea56f59e0d94da27d974ab7aa4425e1f4efb240a1e47b5c0f41cc5e4f4fc990f17bb9806c6293cebb6a5ba553d8bc9352c543b29c542d5e3192f6ca9af1e4aa9afde52cd868be2575ff9e86224c43b7fdd7e2c2eba20104efba2111e47bd00e64329e7ab478f5d12cee337e72e098bf19bfb705ebbae5b4bdf76311b3f56b7aadfefa75bd5bae69a6b9ef9b59fe6578bf782a1087e03998542ebd9120df4b80a46917356ddf2d250df6dd45ebb368f1e27f8e89cec62d16edf181e910da25bb7ae79685f72b28badbad51eb6680ce340edca9c9b5aede24e498c91309594bc3cd2e6f1bbe320c86f60288267160aa3f679b72c0804b6aa3e6c7d189fb22f72d1ada96e753ce32c9fe493d7138c4fdd6a37d3adf628c66b0f574fdfeefde25eb5ff1ce1a2a8d45093cebd97d3348d73ed5e0e8c725dbb5aad60a77dd52ba8714701866de1729d07e49c8bcba0eb1de83288f38fbb95a593b6be732e038511ea65fd326a67d691747a4ec7e9d6ec2aab5910a9dfabfa49ab9dc043d65730e47e78f595fd6a1d0810b73ec1c71c64c1ea40bed5f7e3b39b6bd57ae54024faf3ba167dfe04a35c70d28ff43da71b18c5f3e99ac76e030f8c129dbe0646b0d5e8383f2d1826bd1ab1825a29df38bbaaab64d3e6a1f719f38b480621d15623f3ea0d275e40d56a745553b51a55757ae60da7a95a8dae924dad06a54d455b0d22f9ba2283a4777e893690e886442ffd7a5cc42f592ccf7bad490649d7a4e6d1ce6396b99739cd588b5d92cd33af3e7e9da577ce9de6990786ac1e30f4be6a3c600443fb9ae67cc57a078696032f18b2a4dfd9ae0a4a16cb56ebdd25d9bc7624c4cf34ab59cd43d65bad3f033d1692dba77da1cf4bb75f183f8c4d1f5b435dd56a40f5b40f2abe5cbff8733aad4b90c0f9f9b38bd1af560b90c82e5665178b6c81c72e4691b0f350bc805f3a92d8c524c3a91f7f7356bf3df429a8c17c0a66209f8246fd14c4203e058986e205fc1444d22da97988e4c3f6e9949d7aa8390543242f9d7649e2d75073493d3a1736c881511a0ce35fe718446a0d44ea495fba05f1820b46d19cf3a97173e82318c110a92d88154859ed9df30b634cc6abdd1beb17cedb6075a3e6beeb4692a1fe3ae7465d9dfd82dc2d8d0b2777bfccb52e769dfbaedfc8695f385f73aebb24996bd58dfa7ed372deeae36e452c5f5d7ee0a4d425120b6205d2a5d72f4cfa3aa773474112e44fe62dde342efbf856dee3e35b6561de9fa396a0fe4a8e87878787c7ab4f8fb15b323d9f39a75fbeccd12e966559f5cc48ce2ec6d3b35d3c204f9e737a77b1997dfccde6b85b729fe70be3f37cd0ad69d43c1f7f06723d6152e6757e00cf512b4c7d0a605ec873140a5bfe4a8ed69974e49c8e03c6aa6ecd0946383c753e523ff5ea210f58c124f12310af60d87e9df9b5f2d0f3e9d57bbe90e17ced71201f77508f275f3e5c76eee3ab8f39c8070c91e4f778f501d9070c7d3cb40d72eed3f9f5f9713b781e8824bf39ef3cf3ee9444a13ebfc128dca47e3dbc20f58cc7e96751787c7ae7b1db80078c429dfeece0fc74d92da14fb3aa9f6088d4df03d65a9dbb58e7dc6970454949e984ef36a3ce321a5b9f3916299f85f0d9e43b77eeecf1d5b32ff40d561f4af9cc8d7a9210bf8253569f8151a85be72e0975abe4d62fe480587218906e023e7ce5dc81b65b9967599679e65dd6f30101c46fa45f76571f7710f5fad96e5107f2711d443dfbc255cfc7e3abef87775ffd42af53629dfaeaf3e1f5eb3cfba809dfb904f26d21c35dfff1ad9ce7eb7123e9e3eb3eeee3bced5b75cb7e7eb17ce6f3038d24771bcca7f18c58c1f4e91975eadcd16eb16799493dede354e7b9a76ebef51ca5c2d35b6f6777db9cb3af3802d63330dcc07ae699c76e89f5cc3fc8fcba9134eaece376f090faaf672e379f9d12ea178c92f97449edd65e66af83f6ba74ea1c92ec4e89f528178cdd12eead7b9b26dd82a195a4cf40d0a97fd0ae2f9e112b9020f7d67309cecfffc2e32815aafe7e5481e9879ea396a85e06353c8e5a7afadb439ddbc5393bb3dff8f5dbb937d0a44a764aa46fceedea8c3febcebcbdbb58cbf075b10cbc43dda25e3f24dda22e3fa26e51f7f1b16410f506bd5bd47f7c401d44fd7295c3e3a815a03e01cf512b2cfd8d5c7ff72275e6ed46ad69dbb66ddb96f9b66d9b73c741b779abecf3fcc68fbefc9872dc656098f499cbef0be7c72ae3ec62d9e69ac74f82e1fce8da178ee0a3d7da2ea3cba5ded24ad1b568e72518566f8f5ffded0baf3c09f28e9d971f92407ef5b38f04d929a11fedb4ab7a4bef50ca23b59d6f0f5bc9a5797b04d39987b1498c0fef0c0c49b0418d1f8f748b7accc1ebafbefcc2125efae4b2afc7e3379f729acb2ff45e36962b3544fa391f46dfba0de46ffdc92f9c2f3df348152f68cf4096f20b635524417e187f33eaad5ba28161ffe61de17c88d479f4dbcfe321527f7b86d411ce47e7d9af1f9e398f67a0ece883078c227d6b8fdaeb47267df8e6b2fbc2f89b94d2fb0be367d1e517a96205fc3d5f78e4a97b5f88e4293f7711fca05b9de4cadd9c8b91eb62e4620746b1be79e4c0fac645e7787adcdbabfbf8f1710775ae7ddc2dcd2ff755bff7e3f7be2131cff3d1b7609a5adf9e8d40da8f7e0cf3edb1a9ebb7b7f8e5e32d8513f3cdede021c98f5efdc717c174506cea56bb8fafc541edda083ea2eff9e2d3f37cf5efc74e6286bedd7e61096ffd963033f7bed6f77cb1e979bef9dd1746a66fd7be3076f9f6edebba25dc473024c17bf59b71dcd77efbcd67703e03dbef10ee074f0af79bf5cc4329dc6b9e8121bff9f621dc0f1e92fc0d8c62bd7ae621927ccdf9e5e399731781ea5af68548f22dd87e7bcae60949f0d663b7017dfbd5e319f102feea5e17ab703ebbc1fd0ac6336205edf3311095495c4f50c49569ac1c237baa966e8f7ebbbb47d2f1a23733737fa17dd99167fc06c3f099853829c65e7339f6482e5ef61cb585ceb7f730173117d5678f9d929a871955743c734b7631ce072ffa6d2e72117d76d9713e7871769c0f5ef43bb9c845f2d969c7f9e0452eea67af1de78317fd562e661d05780e23dcbca1060b45a43903c61c14fdda69655b6b6db4962db535084f88e5dbdb85db23fde3bf930b2f3e43b941f3dc2dae5bfd24c83d945e82b65b71c943c10b198e988217f215cf5ec60b8f3c7b103141783e62b067784ef6396acb0a1f5a29bdbb985c59166a094e1fea73d4962d1f2f68a56fef3c3e9c3ebb25dd7e510e2f7efc683d59c38f387e442a186a8bcf739416aa14a25f373e5eb788785ac47c740834b3f4610f7f3e3a9137dfde41bba2f3e7758b880493f44be728d2a8797608b4ab3ffa4fbf08f004d46a57f423fdfa018b8e640f153e3a1114b0e846633e7a06edf2f97802988fee41bf222cbafc625ea8be580c4a5f2c862df2b5850c0a0e23c3557c8c7981c3ddc5bcc0e916ff8db3394e1e8e538ed4c3934c784ca5092a76dc89295809302101f6e2d92b93f1ec538d676f67af3ebd9da2f1a263f1fca3bb7c0971107b06860978f60a862d0a860b78f609861e183618b2acc78aee1ffa478f6ee5cb7a74e7d71037e4c4d08616304e50c0a2b7f8e56d3953859ba522b8100316c5853637cc41869d37506c408e1b4e6bf830060d3460d1b5cf8b5b78f1a91c4f9ee185f185e7aca91baf25472268c10211027873aa02cf8793053ccb441047c61254f621c7f5f06b88b3201ccbe3566bbc15573fa0d6cae3584e34c4ad7eb2363e0482aa2d570812f9e5f10f7e19b177d02f66a2765567c7a05fdafdd0f3d43c23d1a73e3d4ee9d195e8bccf3394d219cf9d924985b79202f499673fa20f836e45df80379fa394a6907cf421ef3e4729717101cf32017ada17c0abeff58ba158f56b752bbaf61de9a0e8f463ad3cf9fae9a0e811e8a33738a53c0d8c3c56bf1816ddfb3561d1ed198f7ffe8fe7a8139cf8fb1cc5858a0f5b3f73b80c147698977ee7a8a232b24ec572e3493194b7582a36531cd68783a2cb2fe8a395a397a292e7b94bbfd2ca8966e2525c5a8a4b6fadc7245f7c27275df07a8ec752c000e7c306f372ea432bbdc1b42b6ca6972ebd99bac9b64b1f7267b13cafa387431fda97d143a20f6d9444532fa7f7cfe81d464b43f5d26f84c16b7719bdc170fe6ca6ce607fb68bf8d97b09af7ee8d567d52ddbad66aa373caf59453c20cfce61f7ec74d258d927f30a72f49b3ec3fcf4d8c566bbe247e7ce7c748e517ef159be220745d7ac8f1066a17e066ad90414f2d433333333f31732941c4a7041e30c1fba58610d0c50c951040f5cde904385eeeeee6edee30539bca859dac2881538ca8d295c7822d3c41c14ae7d8e6ebd90c59ded1a3cff70e8a30ff1eb09172de8b480c6cb154eb0e844fc4ab2c1e90d2919cabc8006132cba11bf246066061e4c3073471c3060d135e017cb51c208385c8012630e3660d1796aca711928bc2d84273dfa16af9b74ab37d0ad2621def90f26d0b00825833a5ec0a3f4eccd45f1d93de9138b814eb7acf53c16cb7d7ad87a76962f769e4e78e14f3b774a7cbcc742ed33c6f6e122752b82e1853ce723b3774b29bd25c82cd4b35b11b48d86d73e8df0a2b7b327c5189fe61cb72c4bc49ace73a4a88818ca23d55bd64ff7b7d1e9ed6b4a6ffbe9a3c734f8825ee215d678f60fd83b902fa11a5260618b18799c210563d740beacfca0859d1eb678a2010c18bb113b917c2599598a430b145be4b1c21b18fb907cb19a1e96e8220a8e295e7803c6de72961deaec914ebbee3315cf6ee5cb8a19289c79420d1d3227c0f889244c689386196dd2bc81b147aa764d21fa28d3abb347385c349f3dbe69d77496ce3cc5b34729f91a12420633de8439014c5cc55574586bc245f1656b206dbf92c0989186862e77d81025074cb6f1a28e1fca2051450e60c0a4b3240c6b5e4a3094c2555f86b4ad81cc212bf43430b4606859dd6afe70f55dc1d05230f42608932e77486af7603688850c831eb44b108b742ced49485ca0047c8112b027bd3d761c23ca0006f40f99ceb7cf1c3c19be1d094bdc12bb442b83daade7b158ee76ba740962913e414bc403ead32788653a0593be9015b9254f74a3b6f265e41135518744df5df5ed61eb43fb2d5f0cf358fea11d226a309ebf6df7da59fce2286240620a366578e1851958d3d0c60c18e4b820c7863ab0f6293f2b83d8a34c8a4d9b8ce48b082cba06f24584412213984efd02ed122c015802321e486f90083bc3a897a07d82441824213e3bc3a6338c3ffb793228fafce21dcf3ff4242e2facb104154f5257a4a9a0cc983253684144174d30a9307adcb1470f5f307da1f4830f6c1861c60929e0c0a2cb8edd49dcf8a40990778b8584bc6521f6a983c71e02711a4744f190c69c3c8250c2009c3769968640410534435c7cdcdbef2e66bbc55dcccacec6d005e8bae10db56b56cb7d2192eef945e9f3e3905039c1fe420c3efa8cce455f45ff89128736ee57b817f9a24c17217620c20c19079c31c50a68f0900595155060b0d1250f33b884610406ca78634517519421440f6c628c1c46137558f0e2851f9a9e92764843c78d99378088e3041b442863049c2374b882cb0a10c0a20e2bead040c752135674bb7f7737cbafb81fe7ade14dff154b217ae9517a76e7ce9d3a3f41203237ea18104b0ecbc02c4430321424c2c1fc1946a4f8d28dfa935e821ce578a334c40b518401878933a8e258a3852cc66c91030e20def4b09d6b780e8bc848830eda3d6857fdf60fe47cfb06fa95c1da9f7c48e26720120cd87a5feaf8aef36a58fb1190a85b11c9c72024187004c31f9b0104da15329491060cf5ed530c145eee9891c50d67b8c09a0e2f61cc9922ea05396c602dc677140c69bebfbdd53ed4df6dd400788e820187b7cf5130ccb0830b60aeb8e2852e2e748953451571ba2e96049df7bafdaef6f1472d5a0b615ef2e0b5ba55edc742114d4b0655ef3e20a73d7477d635cd4651e1f4996b31ce076f7b8ea2e286d7dc6e9f6997fbb6b43a019c77df96258771e0910eaa8e82c3b81310224912dffb690f1eab5b1aa56f3e6c00436d5d6477ebd8b3b349d82abb49bb98f51b3b6bafe4b2db797731cd3320676d5feb7e9dc74e091094673d74ee7e9d679fe635a37176d7effd32c9c58bcf69b2987ace335816547010fffdf839b0c5402e35cdde56e56e0b4bcf9f65f6665091bb6c3eac20c67bc3dccca9674e37ba755b2edb7cb2bc95b5d6daed2392b90523121e7bc6a5d52d9aa43ffb80ba45dd96e1651e729fd1cc33b7208b7ae62c449df5c345f169b6f1f6c5243cf655bb58f10e8b8b36304c7a0ddcd07c58c153674dcbb26cfb66b768e6d6ab53b75edd6675a862b139f556dbe6600bd2a5c67426bdcdf2d6936c20110eaa6f5e7df3126479ead537d77cdbb68d3fcbd1af7e48c1ac044f9db74dc3f216a4d917a52ea974e885a9afcef746a7e874efbd9ff5cbf57ae8f37c3d14f27cb5ebecb1e3053ef77e21eb7aec629bdf6df3213812c142d559f2159f3aa84656646ddd29899fc66bf1b67dfc3cdce5eec7d3ddede3ff200d134dbfc5a614b4a6f0410858dfe31960570f09f215c2075ce43111133191cf73d40b643cc7bf96b33c5f7c9f2f06c11554f7be38040b55eff962089d57d6775ce583ab3aaef20176318d67fdbae5f1cb97ce39d32cb187cf731a26b670f1293ac531d1a909cfc7dde7149d98aac9136efbb806c142353ac5a5afd5e352171e1eee8ef93062a169f18b1fa7b8f6c8c8b28fdbc1f3bc396917679c136479d5e99c3e27c8e643235d12219f79ec3810229b8946699f524a29b5d33367975ca439fb74768d8b3867dfb8a82be271768e8b7a9cbde3e1221f67efe1221fceeef970d1cad97d701190a2099c7dc545419c1d0817b19c7d022e12e2ec41b86888137176215cf4e3ec43b8a888b313e1220a9cfd878b8c387b112ef2cfd98d7011e84ce9b55fcbd0adeed22dd95ba49d4987c6a970b237960b8dcda6e6a2e1cc746378b8fa45315cfd22986ec92843b7ea17bbc42dddc2d22da46e49e9d693205cfd36c0e2eae78110ae7e1018c2d52f03225cfd30f8e1ea87a40857bf231470f503ea96040047bf680457bf1fa0edeb18ea570589f59b5741f2be7a15ea48f6ad1118beae99c0af57a04005ef7a69e9a57f5f9f50e4b96b138c74ade45fc4e3e70e0aba58a7ce4b37f2453988c451a48b73e6bc740abed8c610367eba5855f5d28b7cf10c216610e92215d54bfff962182c308674d18d74225fd422481642ba3835e48b554cb086d54529a9972ee48b69804405e92214eb8b4cac9698a08b67cebcf4205f34e2471140baf834c11785f011c4aa8b4e4e2f1dc81779f0d9e14717c3485f7dd106ef8b8f2e36fdf8620c3d30f87491c9c71757e051c1ebe292cf174fe89ebb68424f1795bc6f04dc7357024f77a5e7ab729f3b1258488ec0f385db730785eb42e8be0e68cf9d1316924db84f0356487e20fd7e14c89ebb09685d07dbf7802a24359082d1e7ee59481a31549102584812d1cf02f9dc1d807643da47807eee8266d7ca3e1000f1b9fb58483a0b499fdf1016927e81b8da05cc87adc34be7b7425848ba125ee8bdf4565c1405603b5a4a6de69156192b659581c609d62a66599c737e99cf312fb32ccb6259e6b2a3ced4631247ba7524cbb22c034329434fbd15c70b811ee8480b687e441d051a669dbb09449805876410144612e8c88fcf39e79c73d2966e24b33361ea5ca963b7d8922fcdadb373644d102910c0b3f3c41b95b42f2ac9a0aef322a2eec50984bd40c32c7865e8eb570257d03e3f1270ab630d2ccf40a298c2b74790c8c617dc605112bfdf7843dd2ae1cad0f71012cae6c3a84386a5842b75c2d4b659c43a146b0b6fbe59f4fb61591aa5ac9f379f3cebd4c3a1a19e5d75fb1dc9ba24fd15046a45cf3c047a4b67c781101a723fc95c060a235364aa26f2d531a3b62c3956bca03afb90e8b23ef40a2b781ec0b39c022e9ad1b32fca4b9bc40adaedd781d86a9f9f0758a89d255f1fe0a0f6e63b2c0f3d39df2c3be8c7bfea624f78610cd9a3d252bbfc1b663d2227b16b72260419d4bef11c89023ffd3ad034b0890c6a5fc20b89be89da25bd1d83159a0fe30b198b8b5d8c997429c657f9a45b9dc56c661e7f66953a69c242ed5491296b4bc710109fd6c35a9f5a6d12f033b7ed406ea7acf76e9d122146ad751c08d143b68eb42a1dcaacb80c7467bbee75b7d67a8c69edbaeee3ecd7e7dbe2b98f77a779d4be9884cfc730fb01754b73ef6b7502aa5f19954479ac6e9df1f92637b9dbc5ae8c9a7b1fc3b48eb3b7d334cdb9e3ae8b697e2fe7f36d21d3e33e1e3bed6a3c3e1fc3ec27b978fd1c25069adfdc3a77313437fbe2cbce82d18aebfcb3b360fcc193cf697430f3d757ed82e339bf9916c9f57c2dfbf1f8fd3af7f95070989608239379bc1be7f331ecda8fc7bb53e2ddaacef3014579978dfa05395faf53aad1eb16d43a0b4633def5bb71f605371de7831841bcf5ab71917b8e128388b77e37deb66ddb62c6138ee037b0d5ad2e49bf7f40d73530e4fe7ae8d7efedfa813a67a3b69ccfc730fbc2d4f37b1fc3ee9749c981b25b92691ac88a7d2c549df5d5593f9d0b763eac80daf8f1ecc1e232736c82b9d81e6314628e950e245f9b47183b3f21e3c1e6da067a32a86eae75734b9ed002f1cb9c7ef16ff685d0ad18110d70aeb907d7b7eb13f480730dc442663a0712d1ae8a079a5f104b4b06b56b1460d8900c6aa71d079ae621d1f736e5f6314cfb1856bfcc9ff2702c5f0d0ba15bcdd16f3aed36009f7accfcf2d6350fa5495242ea213ce95687d4a3cbacd22fbefda244a73e3f9b394f9434ae3c86b66ad0d1a9f5ee36d032bf1cd75d04b8a10fe10d2f64383f1423109dfa1329ede21e9e0f36e086f33aa09f07d1a79c01e0a9601869f4b8a3272cd4ce70e6647d67581579edaa94b3911b838bf8a35b6bb36a3d1aa3b2d6ea941e89ce45fc4f2965f5a55ff54ba9b5195dd1326efb8d17b4c642b1d9a31c73516c90eb56c72c0bb5471fbcd0bb4b32dfbbd59188d0e3d0506b43b45332dfeb567b24c2e397beb25cfc348f6034a201df2ebd855ef3d83d9dfaa52e350d0c45f036faac323ff4bea5f49b711c2fe067e7eef3335ef4d0198a4e4d10c7f82aa9c7971d07419e82a108be8252764ba64b5a27903cc7b03d2d67a90c178864fdb07e82c93309ebf1d4ef9c5d4c7a9eac403ca1089e82928b5b9b67ec19a3f4e972fa7439794e660b784211fce480a21b97bdf959f9711105ea0c74697420ef212494d6cf28838c7ef188a854bd36791202ede8966e4925f9f58b4a5fdcd24152039c5f100b19eb1c686590a400c3220784c7b00dc6b09b7df1ef87858cf52c1bec7afdc2a8bd05c30e8ce4fd187663b7c4e7a77b1f2d977599cf2f4cdac0c74fafb55352806b37bb558f7c9b678271a95b720b9729b5cbabb4e3b6afced12e56593fb4b2ba0d32bf3df4a5c72d587e7449fa91be2b6578ec21f7ec2b8fab9f45c36befc0830fe4ebbaf45b3ff9f7bbd241d2e987e4837fc40b5a699501b92ffd4ec0d5cf86e1b5c7a8c4451bfdf88974d4ef956e21754b7efdf78b4b5d546221e999166f7b2cdd927ea55b51082f643a2f1d4bbba2d057e95778ba585db5eb470308b0541a1b1db26d736c43e20c31434811220c88d2f8a1e3470e2214705ebba8f374315abfd6916ec95b359f3eab6b9e7d71ac068692822ec957e9985da45b523dbb9ce42ec71372e033bf5cbbee62273bfaf184493e7c361d5c31f98c51629f517e367e1c6db9845b2263d269bc73e310d6edf49e2a29fdc2ea51c09597446334e3eafef83767bfdbd79241d2efac5b9c6062f32bb9edbb5e33c0b00b9660738619f5ad6462fcee62edb76397c400af79c7a380962c80f4f8e46d9ea43af5edc3323dcb06db6eec38a014e0ce836d826107afd5cb53b72fece0ad536f157adaf5a695d423487d386ed704f29e2e46c6e364e74378fc0c6b8f1e7a7ca61ebdd28f55bf9ffb83db3e22ed494a4a4a4a0cbbb2baec92b01406f8eab3db60ab9ecd4ec9500672dd8ae09065ba918c375d7a1ce34d8f5609f5ea961a75045749338ea008af7a07718c9769105a9f7e69c73373cdb71a3dcb324a35225634989ef903d80a088c7c0646b1d5efb55f785dcaf6d66fd671902961358ef8c20602acc6115fac78eb37f3cd8d64b6647b0b6ea05da2b9ede78e9227b4808def36ab5f7c06a260144f89cb40a1f7f15ba90022ed3664929b5ffccb53761d489af3250379b09e4d9e9f7356ea752b5eca655f0fd6338f0508598d154c8f24bf2e01c336f3d3b3af872433d8ccc1c50da9301964dedd03927e7ad639c9206b24be8251aa5ba920088c3021b17452b7cce1763c69bb3abf7ceff5ee62b7a3d7adf58cc806b68c17e5fa1ce345b11e4ecfb80befe6f2c3a225de8191e93ccb0693be0aafd78e034a812f30e9dc7d20848d1a477c61a3c6114db0c9453263bceb5c94ebf35e376a1e100c3b78eebae6f1b52fccb21510dde2a4e146ff91deaa5b1d7a51cacf72934aaf6ea75d450a560eec92971e81f0e292097ae04ac9d04b50080bb5b3bee08f5c647b4e5ba98773ce59c5e843509f8408f5118a8fcedd03928e84618c1f639c9fe5a6530fed0674ced85dcc8feb96e4b853123dab1e521a6305ad1b49fb714bb208ae3efe2b39cfa7377f2c3da9b190b42c2483f0dad9b6aba987f1c6ee94c4be334e963ca1059e52e73c376a5ba387b51bb461bfe50baa9010ef7ce648d6bbe34789558c9e04231f825a2549e94968c047ffb8720692934d74f2a25b4ee3abf85bbfddf19c4edd6b17bb74297d7631d9ecd4997a55329dc66c25e7ec96509f6edb7aa8addac5811676f0b6a95b2d33c087d91b5e74ee94b0120348f1591a9f4de725b22712773a03855efb8c946795fdb3ad53cffc7297845948f3cde3373febdbc72cf48549dfecb14b326713e1807a9e9ba8d468d7caa3819a4361c7149aa111840105e3154030301c148bc5238aa2c9e20714800f7dc04852389348e4c128865110c518450801c600020021c020c3d40cd50638129bf846b091b59164cdf55bd7816e409633528a668b19ca8cca173a1e6d70d235ad3edef93ded8f34bfed0b94f52d7d919f1f32800e7d010649d6e8aeba1a91673b73cbca5835577c2befa92d16cc1c9cb3f4ff92108b9fdf0555e29725d1c6ddd9dcc20b6e220deb64fb940b0c94dfa7c244d29179e76c77eef8db7926bea2635be423334dd30ff1a807adcf3fd47964d269e8412cd87769523c84f538df36026f58d4ad134bf50ccf3ff0bed97a37cb9d8e03085105db019b0652616eb21fcae09be7dd779e5e339facbc7ba62c3735f71d7aca29671cc192e3923fb2133d2a923aa00b660d7130812006385f9a7dbf43aabc032de29e3cf843a0298353b301c22c7f44b8e51ddb502d7afd73fcb7fa1f62cef7e88deaec6e7b1f1e17190078ed9583fc211044f5c258aa065d82982e88530c5c935325882e50f0d0b960a7c4dde6145494cbab47b108f3d9869e6c6c3cd7a0094063d5f1fa54b5d9d6c87648a93f7dc6db9a84fbf580b55f6b29fe7ebb7bd8df0b5a28d4eb95ad6e2c738be38d3a00751248d6ecad434621071560b250673308999bb1614b116cd1300c8682c962d93e42fbf415bfd774de8722d2d29e846c95c418ee1e188be7522f9ee6ab9c696111d47d8906a763b88faa8c1a145ceb7d861167fc38b20dac9cea12ab9c73c0e08f94a62636272081195c1e12eb0dfe96aab227c601ce3efc0f56be57a6f7dfb3778ea8bd9d33ff72902aeff5da2b8b55f4142d27d3407ac4582a602af4bb9d5180faa474ed46e8db823ea1ea978f737c9ad7cc75a423f28e66cda69345f6a9a74107ac710d9be57a25d1a141cc5078c9cc46282d4d4707884b0c75a16b03de4a8323c224ed358dbe229754e61b20a394f40cd84c8e6e8615e70244ff9bbbc57a1914cfaeaab7c08a1334538c95830b4f5e620d6bcfd9e86be3dfa04bda10de6a8a8958d4ec232779775fb7da656273e985946419c9fb2952ad57069ce9c4cadeb4a31d6e95827669647455d5abf7da1b258d467bcbb4f48444b17e1bfdc0afd71f9292d3ebda7baa3169741de7a741d25f08c1cc3faccfdf8acb484c06d26331a90dccacce505a3a73e2f673e6e536c53e1ee65d269a698919c3a0cd8b7a9a8e3476a827d6f7057dd37bd761b143b3e770661fd7ebed402705eb9e6cdf30bee445a9a44364d4fb58a1d3dea8cfcf4e101ee6e42d3103ffc97ca076c4c57336245f9123e63316c866397715acacc007242095b567187f13c3554002cd7ec838b87e4100e27e12b892225a5ac0d5570b685027b2e361c3056be42a65e398bc79e576e45375e4d837f2205f0ef512f8ea3751d87a1703fad8cf5befb237f2603e1cf50afefa53f8a44bc12904dabac51bd42548ef8d1ef7c2bef98f2a4121ce45d2d00a0665178f3159bd95775e710d8ba08c6191b78a0abd49716277d1a1acdbc4a6332eeab51f5bb581a74302a364e7e511867d1198510a0f4d62491e1e50d9bf42d761b4bceea0867e1ada594b977e20899d8043d1558ffb423631e82b969837982173debaf8bad5ff4bbcffaff9235f0f3571dd840bb0d050566757504263713fd5a504aee79eef417d15ca47c4d2b73b65a656845a99c3e3e713b1d4a8fd097105a0c486b84c00a189fb63e6bc6948b1f2615b34e250bd8a686d94ba2b89b4fd786c84b60da3998ecd5e5243766fa29665e14993eb2c8b7f78d44ea5b551838903110bdbc6ffac364bf4d7a802d97e05dc2885ff538124997c92c9af587e9838fa3005a8c869a47063cd165ce0b5577d6b34f470d9d7f54f9f7df5c3d2f2f862569a0085faea8df8111f324fee4e11f56b47044286fb443bdc7dc2b81ff07e5fe943f71b6dea6a9282e201990ef58102656714dcb0cc96e5f0a4967911d29de6213b5f99107abf5a421b7215bc2ec8ccf74262c06c892c6fd5c73c9fb28f69df15f23e2c6f9ccdcb64666780362013db02a23def7233ac1ee8b441ca258ae4b9401a14b937dcb3aed25360435bc3d5f3ba2f6e9e26dd84af8db064f90161394ceac04ad62f885deb412035169301d133eec46dfa44daa218b4740d2d50ee2839062dee18d20f592b4a42628271867997b49c5a246b812ddcb6da91f8220ff581348cdce9e47e9cfb97b7394cd8ffa3b46f4896b5e89a59074026452975dd170a0eb3b3522f7ec4b58d09e28944ed57f88eef2d2d38851afdf827e073c4da49347249683cd26beef12f50c0a5a416a1645813bf2eb618fb970084f1666cb91c1bfc9ce9c3f4b4cb6ad808f4ef27dd78694897d65a850368dd747a2a994fa961786379b50b31e11885ffbe029a7cb9b75980fc94df2eaf4e6f0c0e906842679e90eb67d16aa9ec8a39790dae8338b495526fc17f320736a265824bf5dc84818b8279015092217e3767c5a6ea00e6a80d965860821df01fd57227cc44e8e83be8b0a988cdc06aecfef8e3e41a58063309b959557c52613927ac43bb94b323542846eb352edaf11478b474ab9c114a4995066f428073d8824018211088bb8cfc6477a1c1c0d7cae3c07336ebebbc8975c2dd879a100265a506d4a45974c2b538052dd1263ab20c56eb2053658a59ebce168ef4ac3b947dd9520636606d6446fd5794885225251ab6c0d31dcbd1e0232fca38d93fd42896c37f75cd9af07df6f3ca46c4659cc4391a37cfba6e3f8fdc65f9f14ada8ee685f4806659d8f28f4589bcc2010e5f208dee9fc322c509c356a6c8d28e09f98fc014fd984a24edf46ad6767a838b3b454a7759c6c90467c5303080dbc24352c55c13bade270265fd603928843766331441f04f6a4d22a993366619c58bdb37035a18cb3f66a1d9146611653ae1f8f1d886718e113e72cc7e1cf38fc231d07963582c5f393856881db3bd9efa3da338571fd3d044de17f798f6b3a573e18fbdce386420946121f7c05367d526027ac53d8c506e1439a5d502c830f93f16d462e7a077416c32c156f422fa0c998cbb0599cad52b3726e7cdcebcf82b99039e155e229c6eeb98de5cb79318f07da7d331ae65458aba2803a09219879751c130ec2dfc8e29ba266e129d3aefff9a3db3f86f95cf03cb63905467a14e08c71a50319fe3a425d0c4f41e59bef20e8cb42d18c1083fc5443e2d994fb3effa284b8f6e6cc87746ff511a3146d94660792037d6e071cf17c4f4d9613c22df5620857f9a74a723132add563aed56c4143ea02f42b923ac7565591c80e518a8df85dbbb0ec7320ac64b2c1c600a86bc9a3f81e671d98e0b8dcc2de22c8eac33a9abf1677acdab4fcf54e22ecddbe95143a0a305405dd0456ef600fc895c94b48befab973018e32bb3948612636c588b899b882134dae693aa783034d2ef3ea8efac58ffba823db0682fdd19d9f2f2e6c0b99dac0a9916a2ef476b8efb70bbed1db0d9e91c8942ce393591b91e9e5e0251472ee0855b201e28fe2368ffd7fecfee3635bd627a710def947dacc9175017d023e19390d8af342b5fc2c3937181fcf8e42608d350396db23da07ee46465300a756fb42587c1cfb1bc2d703a6d52da9a33549db6c55d19f6bd8ee863f0bde5fe099c5a4f0c06aee2cd7900e074b240a135e34c9d2074bfc515be0f791d7ecac837a1e6760c5ce2f02298fb7e353bc1d9ccaace6e05e9be5a00a1a0dc59c3f1fd0f0b90ef15c3fbd29bf8e1928f48ff78f57ad6d17c272f4ef0d20d6edc068e1fe8027d5d6ffbd3064d8f934882f8667b2e806eed07cdf9fee34b8338dd826143fd50a0791ceaf8f15819d99fe91e39ad2a8d9e0bcb9f6e3dab3917c638350329ff99e319736bbce66316f7b840cbef2241b5d6d7748f8e2b6d136c8a6880b5c2f353ec26c3e01a3550d46a6cda1073bb37bfe072a83a99e112e8cd0d36ec9daaf7f60458eaae87f61aff455ce1d3ca5d69be5d6b409eb1fd034ae14194fe6802e938cc5556c6e17d507bdfd0dc582aadcf3691c961968593727cf5c5c8875761e5f395111a25bc9267bfb82a1c71241ec29fe99bac35bf7f4f85ba5c28c001d1b93b8d6d5942a8c1d18daa40ad904eb78dd426d50b5a54bf5e2a961a54ab55936ab90a5713eb85a41082a2be9906642c28c0239bcba1afa289565b217a7eca9533563bdaaff0ec66a84034e2041db0c81462dc71690bf8cee2ac04ecac58ee8371f8d953502b778bf6642e620a592a50e491c16a3f57a692061f67599c4b33109daeae529ee7f8fcd6cdddd3797814f0d980881cb38566ff2ffff37025a1fb6855ea031301ee3a5542f9a11846bbd814c74e22e8c9efedbe5f00c5964a09113181f5190b48ce3b2690d422e45111ae05d7bd81fcdcf86d0bf3c70adf940af4c633fe08a5685b148e14eca41ac58f3f194e8b840b3920efd9823ea1d37f7f2f1f85c34353f6593f04d1088c7372addaa68c5cccb17855d0af8bd027d1405355fe481a23ebbc57efce8404cf74c93464d95b6c21b3c955bb4e8ac864216d199074619005db42e7d14eaeebc3507050d2848bffcf098a6bc2dbcd81fb40f121e28602648898d6f5f1e5ac18dc7798566ac4f0cfeffd734df08b2095108ecf3ca8b77f11c94600b731604639d1616631dca4a52e3894a3f8a1dee6d51781f70b35141c1c82cbd2d0fc869cc10c60f5cd72b1502ca7ee3910b8a0c1617ba71e9d04e7776e61e668dc1814918942326d4587771e541ecc15c38db7e0290a6f89ac0e3b60ad46e22ab4bbe55b1c3653b7b9429ef9ae5015d274582318e0f0412ab125eb32d73de2dc2bf40752a6174cea369f62c87c9bd7c89564d060e8ed19e35cf4c96bd7e8a6705a2bb08330d229a11c8522eca270d89031d17484540a1723ec042afcd6380c1c691a067fc2d8c95bf7f5e09ce6aeffb114b4a3df3f824383fddce6b5244cf09d49bd321d212171b63d29d6948b98d924969789d54a0954b4151075f53edaacb86431494182c55562c713b71af935acc893688558f827af037c015a98f67b219763ac9b003653bc0e10e08157e48821cc1cce08a0c58993421e9211fb52ef8379603b7c4223926a6ca50b871e4eac4053ea0575f5828c31d647d7850b36b6ff2dc16689a6286b90fbc3022da39ef2205cec5a2f87f08527a0036c0de2783e44c80894274b2fe0e29bcf0c2e64c9b388d4c97f37062c2a81c8120288543f5358cbb27551750105e5faf07893d10db6a2e10399d21ae81dd65c85051173e3008508220d7b58491578e3ea214e076a8ec9039d3c098df670460e51a6693853a9f293e811af6178cfeab37cf90bbf5d3f34ed3805af4fd49f0dd82beeadfc56bb0cb1d711cc36aa89e06bea40367c2335f67d9c847f99f332eaa8a3242adcaafe823cdb7a0a87359beda1d1c3ad794cdeb3127d995998fa35cb91d896c172effb70bfb3ff028c29775e948b80cb89e7d5b89ed07e0c4973e769018314a6da209622fbb8411add8945175453e8005b5206a899051af0b644e7b90d4a40d8839b7d2578b29fbe28768eb89eeb83cf64633d714e9f00271f435b38c1095272457f28ca87a217230c3f4f94b8f53afd65ed3f949a5f108477826069a8e1b084f673ecc54e20d828a1e611a08cd594599e20caa5f2f631cb60fc95e122a1b94f2ade624c4a248e8e760ebc1a193d8f36328e24c904508436e7250426cb741f1bbcc2252cfc8ce7d70db8bc237803b48958b0e5c42214eecedf244754ea564e68808d003621b56237ae94d1dd5604d7c682905eb66bdfe006cdb2fe9bb8ebd97c232313c8ddd7c9c3cafea0280873e3b107d3c169fe5f8210d2613c872cac44d4abd595b1ab2ffcc9b23a39d7803758e3700b60be17e3513a33c2836063b6449b30ad3a4f8c971edec482ac63cd90c05dc1163af2f8ffeaac533812018621bf25a30652762c1f009b34b8b8126eb1bd5102b3c59e93a49c98255b11ca355ec13e90dcf9ff0a6b4a36f903daecab70920fc3a56be6d80fa6c6627b4d8263b1f2a31e929d1d64ca5f5afdd8125a0fa3fe77c249f10d9b9275161e748f9845924292e6d26ef7b5461e73a28fe8fd3ada7c163241968c56d1ef7dbdee025fb8fd4ca83c1747ca9c6334826d3f6f9bce906d8f38ea560ae1a7b50c85ff976c9d1450f30838209e82232c4aa24882beec6bb45ee593107a8623c4390e448f5d0542f2b466956daef179d34990c1afeded30eada3bacbba3298f597062b759073496495615ecba65edf06dba7586fb4454045ca59e26cef44030d58e92a0fec712b3d2dc78d8705c459b73e8d791959b91b83536fdc0af1b1b9ce8101d5efd96024fe9cabb58e12f0a01167fc8685d2cba09e92be39961f6083d0d9e5310a5e0947d0e644bee722d3038fa7c52556f2d28ff45796d4d26e86a147f89439cc669bef0dc1172e03dddad8c1e039695be94fe8cc2e71fb95d1dc161c5c7db89cb455043ad14b3b106237b79e11ce2161ca663980b5045e39e15e15e21a779e1054950c6b1a4e90c94b4782a51ec367bf8362586f2e60b125f15d222bf20792cb620e41974286151a3a6b4b94e85d57123ee34d398d57b10e04763ddbdbb4716f5189a2f31528587008fbfac6e3a6ee59d33198eec3975ba8abc71531a807b63d2435c04d0c7c6d1d247ccde10cb926241f4058da9388784c29b42321d2dadeb7a612839f9898c09650c612da3579feeb5fbdbdfcc904a9fbb7bb7a56c45793281bdbef5488fee335ab51a54ab22c7e8b2f4d136e6c0732321919aa87c39b08e7053d8183583e49aaf2aafd9c666fadaadfd12bd670c252034c3b082a04c0f2e0b4159dffc393e6eb56031257e310110e93bf43ba8a81792cd5784fee81ef244fbb72e17eea08300c5b41e87bd9a477b8e34f5a9696203fb9dc8704754b86d29825283884383708f7d70780c7a760f1438d9e5c24d1c7f941625b6b900f784db6eb3d72908d63c7b25bb0735a697318031395e9f29d61d8b37e24d6d20247fc0033731b79542e16c3ca24248182b56e2e4db50c7586b50a84e6efa66bf18ff8bbab20f9ec8ec5f99969b43d7dc8f9efbd83beca633172bba8a8c2a980b46b87a56aeaf354c56f36b413eac1311717fc6d4f26c47829829b6904c832750981df69a40404206e0b57a669c77753485b64a999e3559716cf242a7ff016a57cd3eaf74c56f245581708ab4c2c91a80d3c9344e09679de707e6a362a73b9964d24658dc63195382368f573740c745e072946368156c315ff57f02a07dc3c29ce753f5bce36996f0a7db4244a5ad33eca5cb8da76230cb5496be469f230262002b6ea1a0eefc7083f78a7487806c26cee25818e9759655cfec44d806e99999be41fe55ec26e440d7d1ed393a67c65fde2b3b07490cf5295373eefe64af1d1c84c9560060b05da7cb0511df0a4a5e33cd45f12e929f6abcad7635418b39cf292ebe80c4e616acd4c4c50a872375a5417c4de59a11593e1de1cb94e3aea79b3c08ddc1b0f98c4df4633c96905696d8d74a9ce0308f3520aacb0e717e7dcfd594952a7da4f76bbed58d36aa34f934aa2bdf3a9fff39dbf40dea400d2d6a89df8fe6e8696d03315f3ae4c687ba9e45b92f01b5c36f80dc48bad3f246dbfb574a2d19b76d9f309628aa40538783300789136b459e98e4d5668e661d35027b233cd738f882919b426a8a3879993f9db589603f0259ce5c95e525b57dda322580986daab56da2551130d628621d19724cfa3020015df57ba8da43feab2b08c2416d8b07bd06f38d76c716251470cd69a2238b624e7c5b78c8c3c1f3eaa2650aa92a28eec2369567146585c831af5524d54ca9320ac9531206405c7c6fbf1b74345f767f9e9aa926a77f543048696780ba1aaea45fa94416b8ef781d8ecd9d40e6d8209f3c6000edb524797d03349eaa7786d80172000e1ca00d28aa220c35d310e63400e3903a1d5d53713653ba74ddf49fd054210a0545ed95372e7e7bf22e22701901bda43c29394cc325f8f280185686fb372e6454bd2dfc9340d6b738b98d9c73686d0740154b73040d65da7dd5fbe0b829362d806a5a319931573741951c1c88237616248102d4a02b5c0ae4241aa19cfa7094d149f0f1f0c219088181f2a55eb51cacca18dd813d3307a14d4f2eb43a64141f9551dc311460e9581eb24755bceb307c6044284efed1776068be3a5ecfc4004f9233a4f9ad5ae9bdfcccfd1437e9a077ea3f4dd4de75e16f0bb6e7a10c61df022c8b92bd65a0ac9ac0eefe38c47eb2c0d6f8955bc0cd17d50bbccafd18568b1bea0758e82b4448c5fcac95e43a41b96a0132775f36124b429c2367409646ef634cfc4df1c27697dc853dad9a1b1facb11baaa93da50bc825a5997f6f3616550a7d89ca8c111f99897b90605bebb7ce906dd26a133b360fdc82f2e3d84559d61bd10a741ced851da7e3a7b889f6978cda1e69311e67748af7339ec945aeabc28e51c584d10149bb3e84e06d587ddd1220a178b57cbb26717dbf3a6856222deb9d6b9dbfb5a808ebf23445b4b11a29a83d828a405396b599d4db96053415962b7be1efcef63cf132c87dd2d0f24ca4cb01709117be352ab8c6f0ee1ab61ba0fb6f99567bfae001b7cf41f563010239c794047cf426510dd1ae87875a0a10912eab18c4fd23ababb9da6543085b36b14d1640341cbf269c7b4dfd93590e09a9c81f779dbdc161a8d6ad9cfc629de584f0d8ac371be9bf899bfb2548427c8a2fa8a3fa2b1b655b688ed4ad38e193603ff48fc2beb37e9d39916411709c2da206f2e85ce2743b546ffa9339656ac065fa0fd266759cde577cd564923b5fd9a8533c7819c234e31b4ae0bd6ab3cf0fd63f48beda23efb0ece41eebbfec1ec39509235b625619643402b1c58420090d3642274bec21a86429bb74e066530e395488242f42bc882e880dd400ab3fab395ab4942df3b0eee1b79ea5af5ee8435f9198865ad2828895744929c225854e1221edaae0c96a72648d51791f89af6080262c6c4e83830f813142c00080e087aa67910764a2f470a4a4007e7562acaf50ecc283e34ad751b13b3939f0ca41b30491a1140f91d46c631ec7a161e5ad27b0579d24e7f30157885aab8ca6a354331e43e13759956c6f08d296cc348217ad584e770aa4a55219d2b914675542eb966a1c67893795a7745ba33673f74d3aba39b27c94ffab774a98068cb08a096b54546785b8046d4d0941d4a7ca9aa6273132186cf5a7e0d157b0ff98a26f5c27ba051934bd48c4dcc56360704693b2ff9f2c0bfc536d90a25697ce4ad5e19bddfff6bf4cf8e0bb40bbf5df58d27c2ce5ff3536707270a234828bbe48440445246936c3b85f07d3559b9f19014f1bed3427352c5a1be073262bbc22534922e44509ba0c06bb63a792f0145eb7fceb68b09698c8276d074e2dcc50b9ca49700a6a7b6a78135c947db160a9946fb93a97830d23cc1a67fc8a75da26fe45d26b266ed98066cc454dcab90c07c74cf336022fcb0672475974ae54ba345c8a44800d1dbd3aacfc2a93e4aac3420e15527b0a3919789194641072555192d85011b91562967a617d928408cb83d03f2b5905ab26792b423a4241ee09487906ce527d5d2d72b1560801a81c4acc02f56d63145c8136e9dcd55798785e53590f809ac49e50f7ff0e17500398a5d6347f96c119ad816c6f377205c2a1a4ffe108bfd6f73a8a2524c943a9420c1bd10f1afbeb0247a7a61415ca80a6cc413acd89223065c080ac5b53f1389cdf895d9aa38b0cf62cb39f5d0b4b5ee2d5cdf09c4253b35cebb202e04c8d5f328c32cb67b38f5a81daa33a95ac2f0bcff768305c4761957a08355f308c53ba8136c2e09902ca79c968716b09b06b2054aadad4069015c4a4e2a81859a1124618a8b21f9f3ad3ecf1bc8f00d9cd422e57e46c1725076b7653ecba7fee5b0c40b80c310115de0d4f5479a943de9ce2fd89fcaafe21dee5f3fbe26e3b3053371484c78aeb1392a8a7a8a0f06977cc79c533121fedfb2e593fbcd46dffb626e7bd2ed2ab66501e825bd75dd1a666f8f60248e751db2f9648dbf66e06e8367ad37b4fe3cb9c09f5b6378f5a1e8a0e8f25d11aa43b2a2e7a0a980b2813eff8fbc922fc83270a1e32d45a09ea051cc54f4ce2cd780295cdbb27c4c86a54f229a821e3a904cd7ca9a287aec5994a04833a2738b3a7f126e131db70661c08197386da99213e749727445b71b737623ac01ca10f7a96e350956afafc9366f36f314247b438568e4b6aa3a2ae5ffe1ea0bff6c3aed53e8f70f49c6b89862b58dcf4c7f804ffe551e50b71b0a8778389ef034c83886a15e3b0ea9643b2e3cd80b778f07e6087ab740854b44ced8367c9ad3b8f0617f8272477b8cea61423a325878230643bb49b870f1d7675e8e64110f6de79b0c2a5386241f2ceef4b6f783c2e58e511a6a1454f4b2fd375d7d20d4f9cf9b012c5d0c4b8dd2721ad6d883db5a9eff0d91257963c757c8b8ae75c044ba5988bc7d1ea2b989bcf56feeeafed72ab06acc0cb1c6c39a17d9bb33ed06a8da6b5a401710bd7fc23c9ef5c142e7c1c26fcf71f4f2cba0c942fcda52243be7cc0009ce8dfcfce507925dff1e0c385653643def049d2e41486eef4a4e7927c82a648f0f832ff1c44f8bf198865600739f4a74907bd9ee7f746919eea8ce808547b55913cf420bacaeea4840ee31e4477ce70ec172c933fa796623cc224fc0333f0eca48c2e088a502ed404144880320ac8c5fc9406bb5b498f0e03fd89af9d457d6b60d66f388f8ef13043cc0be02fa851a647c803dc813e056def60279a672150d68e8e5b2e089d77570f6da56962dbe65007d891bd1314abca011ccf411058007c40b4369dc6d204c2a3d9f0e33bf6c649c995789fa67ff4eee9640740daed9ec86f64bb67cc8d9d3d320c53193f8e525d0cccba572dea90484260ae322006fdfbfdec9387b49f9206fe6f4bc599e70fb576e34241b1b0b3cbd66c561edf4bce1ced0315fc86095f979075e0400695a0051f581585507f316d690a9b2ce605ea9e1719ff999b8f10dcf5ce9419fe087f6940de04822fb1bce78c029ec6c362fb76e16ee8fd79843e0607928b2dd18f81f5554e4ca374f5838d74420775657aa9b1afc8a0a43eeb93d32f23709222fe95da5f0c7c6ce16c9bde5171baf567b7c162e0b4606c251f76b50f1859da0748be0f2915c38fa0269a0e9d497fc49bf509047749416c3b1eb83df939112048782fc10fba651b5c2faf4103cd135e82271ca5ad26e1556570a56e4a57c6dde0416d7c6e4ac498fde12939e147c4fb6c3266d3dfd64bcbda8f5fd25c864d26842ebcfa02397763e58bebd76d1ef4ac31648f2ac08ee626f35cd2d904368e161678e808ceb5e491c6c65b0087f2dc33e3362d0672c3d2477347df3beb96749853435a46116351611f936d0b323be547048aa45acddba48750aad3ef3e85f5904ef96839983103f82810fc6a53c74e606af37a31a185e18704cfc9e34c8039b5870b519e0b57b31778001790aaa8a5ba19aabac240ba9b1130ffe8e23b44b9e0d5036d6530a75b5b67e69812553755d121ef90044fe941966e8d6ed2a3940b70952b6054274f5094d04036684a1a5ba4fefa08d34c53826dc79f186a15ccf9dbe2b4da6a8d7d1c7643662da0ff480d47a128f1c56f44f69be84a73455167d2ecfeb4250be4a3a411c80142ff38105e72acf1b6c374f4a0b0737e8457f5cd6c6efd617f5593756b6588a43d8079b24021e79f4dad6af51157dad170a2d1cb431b1f18a18147d460317e3caae9800a69340cecc7a99c07eb5118d1484ca4b9be0dadf4cf938ef92708bc2cc2acec41c497211177be427b4fdf54e838db80cb9a890d5b24f191bc6f43406263038d9abdf32486cc81974de297b21b121768f14e41c60bc31d0f75fb50f4cb724b50044d4392684a7a244a3bf41805c9df3b5a63b1297d9caa240a0ed762e66055b6bc6dc0e651aceddf567abf4c9167b2b888d161a3035e401efbd6fb22155fa432989938bfbd1c68687de810d8b57b3a701fd36bcb133b21641b3a5ea372523c0b7314368cfb71040903e26f8017e1a3c20283abf579790b776d56b05e543c1894ad48286edc8dff795857d9254283c27e465075873aa27a6f454d3b130eb53987a090a5ab188e91a759f85a9b7c821451a2c6f043c9d27d6a3ec76f743a5efbe9dbf0d7022556a2726d6918edda93d2e8274cd9141256b6eb8e291f29fe569b52206544a4524111b43cc1ef7cefe8dfe9862bb24ff39b635a754681613d266c3b218edb9ba5f8d74ef3b29ddabdd85050f0cf97cd559a1468f1aa87a988b7d2e08dd66f357169d372087c0eb0a6b86199b0c55287970640ce127c43e380137d6d72738165d5998221447ec803792f3e3e32a4f6e80a068d0bbfbf87a735a379c36f9dfc4d8af4cd24d0d1fa364364c90acb3f64fe25662f7926dce9005b1fb33705835ad9cf5db5b271704989e20ef0ff85bc61cde16c3a67948b1fd651c6e38e3fe2c397630d96a1a972f4af4d54e8df867ec132165af6d1a3bccf19e5aa8d68c47a33b0d051016839502b2256882383785b84ffc498d66e9c006933104b08c3ad32a3f6b0ca05db172787f89cdac930cd923e14263368b4c2e29e91bcc96476b178e833a89aa60aa1c2d49a83c8c3a64d7545b48405808229271248fa95c645f47768fb8ed5cbcb33c141b5b7ed93e54f8fad867319006f8c36965b201fc1d0a7ac75fa1cab979ebff5e4c1c213f8c60d52ad1d39d55377182e24b34fb4a01a3d072497abadea73eaac7ec3a80c1e034bc8c292c57cd3749e3c790250603d144237337c33abd41df15068c64886fe9832dbd6fcb004baeb9ce70e4767f670375a2ea6411333a8661b8363caa74a0a742d29cdccf742102ae0b16e481877a6183ad2d429e911355c517a27ab9aa2f27ea1ff955e63454ab01a186b76804211392737307f144544522e829a28aaed0df80c0614d22f93b4258502d121bef27c1df7f5f26184703a738c7c44d2bca336cf230608961dc025267b5f4b4a3d121cc1dc9ee8e542b182cd1165c237b14f61f5b3cb39f66879fd482e5037c9a4191f30458b5f6235b8fe29eca7f9488f5b31f27dfdb2e9e1b6e8a62b97561c051056b703b7c2ccbe60402f99c74aa30838c5d0e6253a5744f97b45555f7c10bff86e52891c038403378ed98fd1fbb3c599fd7ad997373a2fd0fc86fe3001314c88b9233abfca23103d023a151c9465ba199a65ef1e18f601844205349076f12fd70180590092fb13d98bd0ca948fd8fe151e1ef52ac0990c8f17fcd8e000fe0dba7d81d533d87e8f3442b757ccd038302148cf483f030d0cf8aad4c6b8f3e0ecc8826b219ef7a56ed9401401cfb2f6b52edc0e615f9a3475db59b24ef1380b2aea6a21348515ebce65abdf807677f1f2cbc0ac239f99e5296a9284d0ab55ada680064800845924ecdad8a9f2171b7ae2d866ef1bc523dc9b6e8609abc8e16381f4968302a7365d19ab60cbb3009ccaeeaa0dd815f50c197133d3a06d35b45601a6e022a563b2206701969ddf6f2d605b9ea40e0c363b23c86c8d1529b7a4d7e807390ea78709b243a495965058763113ebc493bc27a3ffa4717de9c27173f4226119d3f17c31c8387f1922cb911a0d171336efd6d38bdbda3a77347f2bbc407c2ad9a679b64fd5f23c8088694069ea204b6d35c29e529df7b0a0f8e562241a2459014b50e4673dc72a096a8b9cbd4df8fcead0c84197dfc22df2cc6f1442646162d75c6e1ebc907be3edf12c9214d9f7f7bbfac1598b2829b4634a8456415a94f2becb1965e83fa83b885776809a0dca6cc7abded0cf018a943b5a1e4408fc6ca197025d673ddd28e25f8053561af713b4cc76d9c6ad58008bad70f3ce3aade67d6dff0f21ac95ae5b0d2b710f6194337e51a1c63c19a19263b6900512510c46f9d77fe5dbd8024ad65a4601c00a068f0ddd4d91030923a93748308d3302caa2677d4d0e7e26d3d518a0e989b9976628146f43e1f0b56ee1aee745a950aced30316e119c7f64af6336b1eb1b16cc17d34c3a310d65989ee009bfbef2a30c1d2f2f77847dae51cc13f129606bb6631476183143305e902c143f9ed89dd7eef7472e56e894c69d2952e2157a5ae18e909186dd91b2eea7aeaf24117df1187db6682f0a054ed409873cc35a494b675546fb1930e3b91164eddd560baee060147d048339f4301fa3abace0fea5e6839573c513f16f9364bde4c425f349bd486a4ac0f7c874b5664733527c0f82b7f69321932886ac046e5a99fab0c8bd5a2997a90e00050494a967eec2470b668a99027690aa2fe4e139a6c1f6b44fd51a6d0608fb831717857d125bc5ff918f906d0e3243f6c17d48f48f667778dfa08c3089bb87004c4657ff6def5b647594141cf66576a97c65967b86925079f2a1dad2112e8514be092ae6c452420b707ad65c05d7a1217d6d0009292d5712bca216023ca30ee9ed2fd358f148c1d9aab444c261a93d7d0d70f664f62bf4e09c4a14e5cde8951cd83c82214ff26bad693cdae51b45bc3f6694163e0817ea867e005937db5a2cac5887a83cfbd4f443da2d829f5e13df353d121dded38983d0088d75e9b7eb45645e6a50f6222f91f6a4f685911790698f581529f4d066948f5acb302162c6a01d41a9d11cbe0b37f0e1d746c6318e03df7c09cef29a48567e4102e9a0b3457126816d466214a16a5abfc355c9bca5066dd9b4f1bccdfaca2088cfdd56d6c01bee455170f13170e1c2d31209e6b6c6aa72c22a6de594b51ce3df1e1aaf2962ea2d75089ba5817f2a8eb874dee115c83317a7e13d57ea98b0e3a91ec0fb937d93ac4a3a36aa0a39b0a90ffb5095d81904b8f969e49253098eec130c9450b24d26c6b00d62bfbf7c6f8c4bf63d65e83ad066d32accc21e5bcddd6e5b9d0d9500ea3f510972e5856824702e7ddc150e310b63e93b617e517d240139bb68e1736f71f4fca4557ef88b32b23b84dc299b43b1f7823fc5d85687f3847d90ff5a0bb48db1fe461324e48c5b8d95693533757b25b7fec1720bcdd5fc89dd99c9e92de8fe4662adaa90eead5385abf99366808857565f10b05132aa3b094c0cce9c17a326d31be0305c3cb690de4c2a0a84b6f66568b0cbe8e04f95851456758b345ea45cdbf66440108154781063ef85b335231d71fbdb7bb25d64fabd985c577b6f8cfc586761f748c042c0ebde70b27e3aa423a8931c137207b21015ec00c9a3650008cdbd6445bc254448d95e12af63f6eb08894568bd11d01c8319104627d9944dcca06532437bc1d430a179e3797cc60774fbec55d63119956b6c69941a0a3e511877ca8264a209bd07af41e2e6fcfb734e0200130249932d7fbce54d8feb3b4a36a3a7155e64ced021b25c5d6385444d6bdd26d8fe6471c49f14e0a24b5a07bb2d63b4bfca68d0805fb60a8c63ea6746a1bc94691b51ba5a36410467d56e082c8891cb0f1d161c8da5ee3f398832648f7260dc14d486ea17216b90af5666c5117e98b36e32e40e4332ad5a06167e01359d1aabc4f926840ff6266d8b11d12a2809bfe643e004263f4faf73f52bb53a1b7094fe51ced18002e568fe0668bc960c0a9adb373564e6687b4fcbd6228863140e7a8672b6a6e57c0a284125f851d6cf2b0d86b5a9525433e85155940d0e6d3339d5ca8090cc4f385d1dd90f3902ab9e57c0f7a374681f61700b8b5e70e09c41d11a6367c71196de9988a0f8ab8d6542e6686c1e4211ea28d4dc2479b4fa39b0315f42f78647824ed9845ca9c3c2277770e97bf295499387584981ddd9dc29073a34a6b3d66f1093e52e7ec496b4e9e10eea14835df2723a71a2b4cade8a8ba5a3dc7e4c8e9d7f6d624b3a8ab2de7513b94ea882cd8a9d00a1d64f7ba6ee11e5b9a58f8a6c7b6b0af7bedaa2f700445dbd1fb5471943a6a98e638f18d8ce193ffec7d7e725a45e5d435b90f8da053fbd8ba640cd90556597d7d55af464aa15cd94dfc8b9baf8f634db942d80be9fedb48d9ec2ce05c573401e1221f4b5dcb3a2a4fe59f54fc8e74ca3c09dc29426d0a0fe8167719499f632a449d8e3283d71aecc5ff31ca8003813927bff6ac1dbe6811fdf4a467e231dd4ba385943f10a1d5855922f89212fd54f0e87af71e5651fe720cc2c2ac2993fb177de209f31defb63b77e31c3a9e7cf106579e04acebfa2dc595710d6d3cb958e37dc4ae5d62f7604aaab1c0a090aa4bda004115641c05dbb5b2b40db6745c7ea9e9809a1027e23e32bf67e10e520dadadb26629dfdac7a4331b395c44bb95cea3e7f40c076dd0de47104ff6c8c6440dd28b49eb730b7677f7f93045635daec75dc5791fffc410490e3571983325384c37e73d4d24359dbd1052d22b35d615bdd8a55db1c31f535de5d210566992df6518f322d0bf4fc340e5e570ad6f6240c14321c21d83760191e067699a412f7df4096458eef87fd6bc57eb12872c1dae93db28823fe46c0a88d80faf2cfd3a09d400ff785b9839aa21d8534cc9852e9c4e1f83800c4103d24e5bc0eb0140480c0bfe451731e23529fc5f8ba14e62f0ef72bf89a54c531c9839afb7cb3044a7ac30cbe2ce6c1b043ddf5336d3806da44dc946a91bf9774e4683676b8ffbc705612c657c4d0945ca8b8735b30ff5332f39c535ee8d4a17bf72564a2249ba81b73fbfc8d2be22e859604b79b9665312bad73ba6a03e9091907e406f7dd7798076b75995d488026dfad781c06e712820643605c09164edef84e10eef6b4bd51e8f24cdefccf09533313600e75dd177517d274c899d71eb89d78d941738adbb17d486b39434cada8c10d3e62f3338960fd3824476a7d442a29f6f551d5bfe24be815471eaba870b35f7c57cc5deb665e08c18e573ed8a629dc3779ff9acab573de96ca178a7fbc442381bd003f46e8a4602f699e59b02a4fce5ee87d56d4be771242ffdf7ef96aa517fdeb69eb3db2a0ba2403d5722c704fc2181fc85d52029fd343b2373c61aaa3873921c021cb7ed2f112ecae9610689558a9ab468b13c8004f9d1f2494017ffdca80abf1225f3532ce022777fa55864342ee16e9b12472fa29563724ef6a989ae99112b8d7b95aaa5dbfc8d28de487e0c1b6dfefbc476b6949d6bb0193557ed820b13a681fbe4afcd441da6f61d971c973eb6ced55b81145dea4fa63e7e22605f5ce9ca6c2d4b6b1bab005b031d7ab406096009f583987fb7fc6b5a7f6d6df8985fc3469a6db47f9ae0b26f9395af960b06619adb46b9f4001d601524e5b7210a0037de9a45cf08fcd958bdbab2557b54e0e1a0ab8322cdaa3a93856d0814b16597c244be100965941880977000f456499e431648e217b9ebda9c079844ec31a88d2d7dde64da05ecd58fb90f1cd49204e91870faa9939cb84ef09cb23e51ba3a15c61a80b24284b4220191d37a3d3ae4be9895aa6f5d3aaaab6e9a8e593b56c070b6174ec606e5779562d306b705b2435ec194c1a68960c1b34345459978b5443606881a66a186bc12cc8b69837922ae16aee4126811d3f587d86f4b8c787bca73a352a7539e151f2a3fd23d6d19af3786c8b643b567db574cecc0018597746c2b2c173901569402c43ef629363f7332b90ca63c0a6d5b326ee206a8ec9720e039ba9f1ffbb4a8674f56b3062191cc2d52d7ff189f8d329e428fd5178d324ea559545fe77272c414a6b61f880b38d90b1f6d421d066c3643f3e5d9617920f9a910a797ef912fc82ce44172261fa6c7732ac6af59871e431178c9919ad7d6030a12ea3118085a2a329a6bff803bf5b2a63fe33649d3b45c36c1bcf88c839f053480c7eb7c2ee4b095b1cd0d0fd0faea3075eab2d9d70684f11c65ca85a79058a76c5358de6fa62f788ba02926a0fb44b5901c0f71fb583579f39593c0a91e3214d3d2e30318f87fc84cac3a10537fd3ba17fac68f2457bf7bbdbd60a6ae89a2a8c53d76b49bebf2ee51ae103417b06ef0ca1f8134db3df3025c55fe0a0af4a7231743a41fdfcd51ba45be78566bc9f53b557f87c0a199e84e7d7fe0f733d8f2445ee51c95882f69c331d6444bd0afa4d0ee5201aff7d2a0e333f30b8647141c90e9181d54d2959bdf92002dea6113f9532abb7d20d2d4f53dd3904c4747cb9a908d878cace3af653cc70da68d6f0a7231fb1436c90166f66904445604c51bc6fdeab92b5131cd951ddba4d0cdb510411f0dd91bf23aabb516cbb582ff42cf07fe523e570acdfff3c045a77951469c4ffdfe0f5ededf0e0961315b5df8871b90c794e5b031b70aae8f3c6447a496e96cb41da83ad3602a3701214caf4ccbb0d938b4264fa014bd52314093d2636f425f31fc56f83b12fbe8e990422d8301a6b57f4e4d64400eeb4b62619348ffb08795567774efd866ee099838b87e80979c3379bb045f6b5f9d3b8a1ee3bcf6a73716971d374a2a142ed0b4c5a7b8b4adbce8cad52d7250f0e88e198cfbaf3fb7cd39560ee9447e7b54871107737c52a9ea0efdc6d93685a8d86fde9f30ec404560502d0afb483de994b0397fcfdf55a04231b3dbee5a71b8fcee6916e56d70c32b43a10eedd2d3cea8f300951c6dda4dd82f3a58aba5e3785a9011ea1af25bf8e137bf3099820651b5a53572bf1789fea9439b0482d96f53b9d2504cbd36257a7d6fe6ab8e16b7cba020c1dca6686b421689d0688d85e9f0f75df6a03789539a17d9c4855756fa1cba40cfc112f410e8e6d495b1ed88aa79284c2e567608940f1aa15ca8420065a114e576fe7c3b34a8733c2e9b8d7ab0cda5ca731fb5bd1de525e3029179b86ca8796b39b285e48e713965d3e24fc57c6c0380c42c3ac406d669ad0b8948a82ddcad726b11786069c23eb5c5a6f16d57c6e0f5e361481826c0e9b67338b555292cee06c3d0ee4746aa4a56835a0b643d06b9194d7eadc6161f233e8cffc06a8131ea7f02124e8dca2652061cce51a0c06e72889cce6880cd9c33569f3429d902f91295b0a9960aebdd0fcbf2a342e329f7832fe904184922e86eab118f725f44cc4d55b679d656b60d9fd814727fcc06feb56d031c331a6840ff75f769c1f0126962062f099aba6bd506ff58e5a5c31a0bde5811c049b1ecf70312ba56177193020fdf4ae4c0b038be0c7f4b22f8bdbbdcab1f963b7e719e0ebfe77e94775ff753abcf38471d6bdde210b56cf3a33c8b237f40a3aedb316aa699cf81f9ec23d3e91a8d79e4540212db720d2b89c492152e790dcbce0a6e49f46133a514706eaa325b0f223e035ded4baeb08fa20066ac6a9aa5c44a0c35743257421720b72becd8873b489ef8bc3509673b17543a30ab8ed8930d7ed80d7f577161ce4db8a6ae5ec5fc380f45a862ec9ba7ec114c5e560c66571e127502211c0a6893ae3313936bc1eb6be52f88170bc9b1d1f937982b16ba9e5e3f36b8a436b722786d156b9f6d8e0a4958c3e1c71126d65c04f0170a8a7f19a04810c1e75c7403fb9a05aae0e1bd08f0ed4009eb4a78ae80be67bff3f3498c3c1d312b7ab339f08c0f76169e3315656d041e661cd98209ca50b8bcd16421ec4d46e7f03c476cd2a757b751987bf07f71f154ee1a336eb1e853c6422e26095a3665226343f59996bafb2d01a4f96c95dd164a14116c14cd626a92c3e8e200dda7137263675585ea74e7126d95f25e90e07141d3b495395f4f29b503f12c4c1ea53a7bd53cad8a80a9cae831f8fa59b06f1f03c3856aa93343b51dd7207d5aeb00cb8254d5cf95b408195694188c1b4edd5aeac49b10d62dac787039d1626b6153642535287aee831c480a4b889e790557b9a113b28b3725c0aef6467bd34e3ebb3614f1de133db519a0c0872a32f48c3519f5d7129a52bd958848b84a4ead9073017ef94e2a1e175df39a741fabcd036339c0891c6c4f4b0fe521136efc8a92a2d2cf5f6d4ea91580158c5304cf76d8dc82587635426500580a78214c44d43c1591c5fc3032d3539ec6b05ac4396e9a3fe8bf0db1c23f35207c628cfd83e0c4c7afa4b984c16073abfcaaf2580d00272b295aa4b11ad15c8c5223de0a2576a58b0e19625fa0a0f3781bcc9dcb2820899df8413aebd8bc801c2bdfb31b0415cb35f36ea2595ceccecdd3d0191a56e1b305e49936372c9ff11900742dfbe503cfefa0daca92a6d05cb8ff36cf94231c22fb7883b8c6e1c666d70fc63dd3d219889bf8290a02720b82aa7352c4068d39a9f87d167bca2f4b6448eb809688dc994194afcdce2af4020a2eeb9d7a3317b9da5db2b784adec2433ab43fcf92a5129914b07d9e70b0e5a89d0805e055f44eaf837121e6a9aef28a7f76c34d83e4116cc9e22a688329287d89018a46f5e7a60d7d6d31de652a4ec3e565ff338af7ae51b54db9dc6ccb769549c593518727f2f8f4b73d6bf9db0c6ef49793656ff9b441440a94ae2fdd0084c0a72fa524c2608d887f02c610ac9430cb0c2a1c5c1f551b0ff3dc47394210e3e8bf24c2b69c4e733d2a01e66253a6e7d164eb717866cd86d1492c0a4efb18ca64a4c0613f7e3818a283108137d01fa8613da7ccd8917b57806793276387362f7c87156e8174f05062e6abc042aa9167b7bdb44706aefa0cb43e76ad47bffc2217108cecab2b4a96f4373236526dc1606143454133d537e48e489b904cbc4e2623519eef7a258547f847ae6b39ff0126a5cf447483dda9b441e245c5d4a773dd3ca782ad51ac3933fa7e27f1479af8583e2c1480aadc5a5aae7f752bbb115e0de2a4da3c8b7cff43d47e6a0fff125efe1ca40dd9d61b1775eabca43e0de244cf30665fa040d8af73ff061851b33d883cbfdc23f6d07700719fd3fcd4d37a8b3ed9dcd6b11ce420e3eebce96a99b7d97dc005ee62f3f0d17b233d6cfb557b809799c95e6c269e655e6bd6c7e6207195bdb5a2faa8f3f533bfed4206763f94760392708a483a3c556b8b498537f1dfb8e1695df90c52accce2aeffc7ee7ebc55f6594b79329770b342d38e627ae6ca5c34b9265d0d8dfeb9a97cf9e3993e242d1f3f2cfedc5e54567fa5a3757f7f5b4c4e8c42d966a7920f4f24cacd2946365c561aed74ab7d61eed451f66c22636ee0022c34061829b51364d5be70977cb83d9c676dc521982b108c3eb00459c277147fa924d0f31984c46052279a8e226be05e580b8482efb78dba4cbf44224d2d040f3a9af8778ba7a0bdba4690353003ed014d8715774c4b39ede306b3091b75bc69f4ad4be7945b09614452bb13f7273164a5c6ea5fa1e951af14ac338aa8d3e24a038a442a9ff24b04e7fd77c179ac70229619694e447567afbc51c6adb8b8701c31cf9b8fed58090642e82ecbb2cfa2d614e5755d921efcbb5c989cea924eb4235195541f83861a51369eca700e5a19fca6f4193f8b5d974d3b0a2193528101238dbf6b9c53c9be60379c4e2c6d6287928cb449da7f79e9ff1c7f30bd92901e310b36130a075c968b9a08f27014ddd2b19bcf94b3b2e9b79770a865ce822044b2d2e1670c05f8de2ab1d8b59bbc8cb04631d1e0f7d9680429a110ecb3e98c53cde65b5f4a4806122e2103a3c9e048bb9c86405c35fa7856907a16f9b2849c92a57fe0ea45a488ab2b358b128cc070c58f31a07d8c8c8d17c05982be10f7795a744622864e88dbe0a5ed0f9e07f30325701b49c2aba271bdbc592db2df4188073fa47e55302ea1a07dc6c687cfb990998dd21b9fd28f1382c979599daa914f0811ffa3fd2df7e0ba0cf491b19c5e684d6e6d9a8b37e5ddf872391d62330ac61a80c14a3c3a23866ce607875ed3651bcf89e78f9cd8582abac1fad93aea765c7e9c0cd217ea3e90f66770f4562382affc382d82afb5db26ba829161ef0405b110f5a075d5f794c5930a05492350c290ab1200d83c221fa87b5c1a9f44ea416219b3feac686fd84a61f0d0002bee609d7d238b157a0e1c07592066841baac41a59e956d6d525130d2b9ddfe74105451b0ffffb3fb2d9ee8f98013392021d5d565602c53267f5d9521b8c69ea376d17edac204a10b6cfab70d714ed00e98ffa51504ea1759f62e518ebd47dd60038926f360b0500fb248cae66da5c3e259ba1da7c02f4a40c343d44fd0fc5d0b78bbca72abedcd0615beb0d4972333221aa6f9becdc676b1cb167ff694e60163a6034bc145f57e0d5f53fd58924962567f21a8c19e009fec5cfa07f8804b10978f1c20f063acc86435dc8fc15b5d8e13838e8bea1cf0ef6f57c2f398a95324bc87fa66591b63818807bc24a04ff7655687947806bdcba53d7739c735425ff441495c15503078db471d59bd147666790024856c4c3aef67a3fb412b2760fbdb0680ddd30e84a98de68724eb40d2820b69fa3d08e4f314280d6b426adb5ccd0d6c8fa159290c282df19abab1dae88a929c40e9aa6259d2770a312b5c3ca6f1186a4fc0784aae13512fad1828591665ea6d362aa444485a15f2666512ee6b2c9e7aaca77ba235b4c43f80a04ab9f44f686ac18b3fed9e1bd0bc46e029427438240d30854beb760096571023301aeb0735a7660c59fb901470d1ac1d57d19a095016f9b1ef4d4621fa0df80670514684f1577130db22b416dfa364efd27f65531870482ba3bf5ef2e362e7ba9f6df4e06cc60768e7f085236b01899e53bf7a941ff263a300fb5c6068ec994422bd019969f47a3abe065a9cb3aa3402b7e2e090c3578acd7f500f13c82b8aa3e2087f46a777ff00b0bb0b78af9942aecb174d4c71f30c088a838307a9a75d004b8b7312ef6f39a7b5060d5079ba5b626e6161ca8fa73596d4bb52c04d2640604064654f82ca2b2e956098a4c563b9cb5387ac0d9f58c060bd580c8aab7a22492e12160427dbc26208bd9954b33a85d27d344352ff8a7c118e813e00c24b2400a81e3d9c7d12eece5fb42b25dfb30d0a0249f673affc4b7d0e01e657256cbb4ec09245c732fc181210e3290db619b371d529a7efdb52de4a36c4d3ec156c5495217e3a95a807d62874d70aece49835c56f7ec186e4f6e2dfb3a9aa7aea871e8e3848be0038df4aeda973dc7cfb66e86ead13930e5d144b1aff666cbf5d109cb8e67a1a392286872ac7d57f7bee8647ef0116698a50d5b8180451f4a8ec46ed2e811f4983320fc570410cc080198ce51c23eb6cb8ce6e7d1e84671d0eaa36b73efa25024498004b6fb6ae8d584106024547ba6d01154d2b9327c2936815ce4638972be41dce0d2a211a97f2843b18159e5328f751dc2ce86daa8a2d2952e6ae2edd299b8c044abbf9169f7e1f5dc36d6e514eb03fb1b0284ca082190b54d425f23944bbfa01574918151472471e35ec17285a2856cb83ac55494860f916b83d2382afa006e3e0157cc26027516e5378e11c1e4dfd5e8c3b4d3ded5b0556e9d5dbe82c2f802cc55183c0392fbe63f45db5dafa6ee6a7ddf1b1b7104648d26a7c61c78913bc87d6b08ece3b685371080dae71ee6538d4c191ae8fd3f9c1cf5a1f3e26d5d1d77d8a517c071a69a0ae1408b03373397aeccffe0809fa9c939d52aff26146b1120889a762542958eed022ff963f96d10b60ecdf3673f8813cbc98a06664e6a8dfb1328158b66c20d457af033442777aa2dbaee7776c575f40117532b134c10627d7a6fdc35950406f820ca8136b4bd77103fa1a7360b33174307154b19422f1572dc6d25e30024d6516576f5bedf603da07cc024fdc9a1ab84cc3f04a95600eaa8bb42a2b8a80803b5b07b1c072246ae31d73aa89758a37227279c66ec1d8c48a560e2821caa5b96deeef4a43a8073e3a6aa2b22a066cb7b9383962338e50ce83786b8c5db418b249dd36594a5d12157443b5c0a9d94e2cf7e8f6581f09b50842b77b291116ffb30ace383750e837290441f4e3c22e31561bf6d7df02b89566efb3390b03deadc619fd17baafb025ab46c0dbdaa489fdb299f5c18c189565358950822d8bc751c3fa6543ec9a1e46b05106a315f3fe060dfcf16898fdb27e8c8c6a9800bc4e25991adcf46d432787655c5fa1be16fef5f740671aea18537c860905558c390f30a32d06badc60791b325512c78e8a4d46478111c93792b1a4187f101b1b172abc0289362f22e98f36f88467a6cdfa08c5175d9cbffdb4fb5aedfa73ddf4e2efad946ee324b079ad1d73fe489040e4884390d56201a16a7039a25227cd323f79f4f79b6742fbe775df7407ccc6f15b52293c239ec4f92245f383fb8614fd718433985ae01402911f5c996a4679834bb375836fe34782227d73b08ebdeba0909697b77db72ef2d654a292a0d1c0df00c53a48c7405574074a67f5dadda63da67da69fa238669199c024406ed728762666666ef51033777b3928ef1d5a3478f1e3500c9a16608911e7c3072e375ab98170cc33429b518334c0bd632d8e32584dd850bd757ca74d8923006c7c23416870049a0766e314ccaf8d9f04b99816d3580c8eed8ba403b6e7c3760bdb0d20033be9d665b0e59ed728814735d49a040f6f696ddb4f6434ef3edb319e2b7ed451d34f97fc031721344af86608008b33a9472c8d65e0d7466666666686a0022a40603447af0e187ce9b01025733bb034a66b50331abba10148420794733a587a66911c36213669d7921a0d4783e72213a2709e1f9c855ec3524efbc66e49eb7a762ba03c93be7814417b23ae76144699cbd9935665dd5198f7654c55425a4f3fd1a8886cba31d3d7124576959d6cf4918676674442d326277172e5c08218e15a43507c3608cda0a52a954ca5f56313a7ad0d4004408ef4ad8ca1cf3f594bf704e601eb1554ccb4097c2c2f11b6f2cdc557b75d111d3ab76fe208e6f672d7b3bb42ba3291f9a557e772a051b7382dbd1dfe8613b84980ac35adb0b957281fe027d053d06ba0ee833b086c622c351532d09134e31bb87707b2d09f367053146182116218429fe7080508ed8e2caf74e485fef0253d21794cc878060540189970b4ae64cc455181826747615e6398fd1ca1cbf1becb3ecdbff61de655e8e698d79ef15bb4baf988da41e7afc6aeae3ec55a4d186af5cb972e56bce4bf6b2c0cf917ebaaeeb50299797558c8e991e35c8af5d4c98d247891efc6e6bb7eb3217044929e544a5fc05478c8e191ade95dbd72e397707d6f25d11f0a5dd1bfb2dab7bb76f5d9926a59649f9c46ab55ac5e898a1a92107213543884033665dad7640c0c6ec8eac6e12a0671e6330fd5f3adb9253b840ca13ae58c10514db8280163d28c18f166900c10baef6156b5b9c23e06965c03746ebfa7cbbc4bc69a490326d0c6bf67c649a96ad564eb2d69ed0a19203951c6a8660a0071f7eb809022749e73184dd370359edde87443e531dbd6229618cf4ce3daf4ba50239e8b01358196ca9ac1810b2dabb0ffac816cb201c698ec6dc9734d609bffd09e184134a29252792d2697ad36272a092838eb402b75869c29775499a1eb0d4aa0ca765eaea9bbd5265d486fe0c42175223d472177422420f7dc8057d6200f4d07fb86999f55102a8bbd52ee859af7a043df4185ec143311e7ab4a27f7d9498e26b8f87be34cdaeeddb6545975f90f9584cc1966c165cd77a51bcc0d8900b6e5fb821447af0e1871b1c01f012d6d14adb31313306b2a4f4770c6cd5d0acf65e29526ad81da36f5fa021bb8345e4ed3ec0d6e6ed3f04c179e759d69e0da3af610893fbf67ca876e8dc731e3af7280f9c6faf728e48c3c90d961821064a34a1401137b83206169890a206ae76cef3dd9c731e44ee51213a173947858052d3b9c885e07cf37571dc719f8a9df31c57f7a998aa76d8bcf39acd3b67ef280e14a63522e7284ee722c7e17cf31cd77add7ddcb72ae8ebf24f05a98dab87b41369f7a1fd87feba5fcf8790240b594cab64c12ccb38cba49665195ca0213c5a8bc2904aa552feb28ad1d183a606204238514bd18ccbbbdeee7641b50b83f97e7f0a2e64a615d3344d6a52d3b06f852395da6c0afcead1a3478f1a80e4503384480f3e18b95996e1d6f4f5ae5ba423375c7747467f239f476fc3574848e443fad2ab1a1f42bc1ffd39e090be85b9dfe3db7ff4a0e1013d16a8f6582c7a7cdb70b479f476b8329cb76b2b2382a7b8397fdb39fc5ac475de68e475dc8723260721353ff4e8c12faf37a0ae43a55c5e56313a667ad4c0bbde2fa58b0c19ca8dde3964cfc7ca928f163479a69246e8b926a516176685a3575df7936db12e2e2f2b1c3a66686a009243cdf288779978fe468f8561bab8406f27c0b676675819e9ed015819cdbd665a737cb3beba7cc7f8c011312c2ef3d8bebd1ffd9bf71ea105529e3f5e8e70b44511e79113c5d5c2b0cb0f474c0e715d5c36482b01efeee82831888787d96bf3ac374f94297aa650f1420042cb11c322532d0933055b2287bedcc72efefa45dfbae62f6cf514c862177df18707b2d835264cf61f8260173b2f81acb3d34f98294f4ff9018ad203f433858779a2f0f0f0c428a38cccc313833618709b9131b70a2224f9ad428aa087f9ad628a2fde7747032d4c7b3bf6fa760e895eed73cdde3fddda5e0dd46004754b00aef61612faf63ea35bfe7abdb8e06a6f345a66abf801145e002db3554411f4edf0d5aded814b9adb0bd20f215ca8458751fb2484ce3cb6e61e2dd59230b9986f775dec9a84addea29bf0ed32bbab6a83f37567e28b435108b2daa5b743bbfa07b2da35264cd70e2594f0a4e795e36ae727232bb850824e9429b08581c18a93d7ebf522c2d54bbeb293ea3ff4ec3240175e088307b6728c70c5d51e81608b81769a0072b5c7a01aad0c45a16fd7a2c04133f6f91b687774cbb7331366ff688efdfa68e18a5fefc7e899f6cfc25461f6cf635f3f438e9bf316635c18f66d19483bade4a30560f46a3f7eed9f6f3ffd56e1832b7cffb44c655ee321d59230699aa6b19768876be65e66516f50fe7a84be9e0dd0bbb12cc3b428e1d622166d52e346bc30ebbb63650cb8e8ab85590ebedc7cf711bae60c3d730dba06bd88166195bd523e742e02a98c5f70db321b83ce5852d7878928bee94d3f08527f93fa7624f26db42b6bbc9e3d87f9489c79cda1d79827396c4d879e4fcd4923ea5109599a6f50abce5a4e6ca6424d3d74087dc2967428010d4c314615b4b8c2043b80c2b5f97a12a040167e9210818a1354a82025fab64f4256e6f29bb0a3710898d3cd4e601b3b0c831f742c3a3b16b908f4a64e6c1b1d028aa67953150eedd2db25bde167ba2a1bf8a3ab8248223e3a7f7cf9506c8a40dfaf395fa3c37d1dda397633914add743f06aff01550a818bb34ba86dd1d81950f5d3ea42a1ca2438fb43b324f9132c64a4ca6698c611fdf6037d86710a0e1ca952b4c060ff150a669317e1c049d90920eb1412e28199f11e34b1a2f2dc34c8a8e41e798eb18ba25e0f755f98b7decc56eee238066c665cccc39e78f9bdbd6759de8e42cdea8eb4c26af2e2678a5e45dd775236e3bcd6d9bd408ea37cfc877bfb577f28de3b86dd419416d9e725971ce0e448ea8731b2d437e7b7139d16a0455512f12d5d95512d7719c11d473a817a1b86de344ded16ae43b23a8ce088a478e8d5cabb21a41bd473d80fa225be7d649d9d1ee0653feb7de5a18d91f266918018ae1a22c81341a394db3b0d492732693a9e4d239d28e4823d25764841ac5de584e24d289c4715fdd1e96adbb9141c4d148c5426fc879169613cb8992485fdd1e9293bacf446bc9db6f92f347722683f38a72138974a23507a7ab28af9d9bdcfb6a918e4e97a7e87da351e725aff3923772cf6960376d702aca4d24a7e9ce063ec999e4ec261429bee7755d7ccf491df53c2775b4fed0ddc813e944f21a0489147be53989e415e73b6fe74e273a62a1db2bcfebbe12add3fbd649dffee8839e73dee7d19f2b4b203109096e5faa7b9ef3e739578928af261f9d4e1c37f25aaad339140b8bc96462992e1de58d7c4f4ed3251bf8dec9fb8a9c4eeca5eff455fe53ec8d8ba81b375a6eb4b4a050dcd6ddc8202210fced39d7d27223e54a6e6ceeb9b799689d71ca0e02ec1e0bad39cfe2a5afc62fe194aac96bc947de7db54889def4979ce492a5446bfc9273de7da7affef0a7343a35bee41d10b0e4d34fde390d2c7dfba7af925c3af7d9e03ccabbaf9a7ce4ebe180f345d83da7e9920d7c9487fa8a78ce3e32d19b7ecff4b1775f8ddf75255a71be648adec9bb71c36b5a6eb4b4987cbd437947bd12ad3f7437f2e49d82f03c8fc6d35759dcf36d9993e72a16af385ff2768ee54332c39f9ce38ee553ed90f216afb9b1c3ba922849790b3db9921b6e833a649d6e7ca96f216be4ebe98052e160f2939f6815e24dbebfde99becd4bdfa495446fbafbd6479ff7ed633e543bdcf094d7d8f016e7b8bb415336680bdd8df61633734d0df9551c26b8a9079a73dd84996d3cc6ccbce4dceaf06dfe55520634d7c705529e7dfa7a3a745eea9cc5ebbad3e974eabcc4e21d8af759befad9f04f2f32bb2526893a47a4f2cff6e6574f3e55277a43ce6f9b57a2153571808ec65c1f1744f131dd8a2ecd054fbce6385ac6dbd36173f6e5724427b7e1ebf96839d1da7f72938b44ce7d95667a9d79d1f41a33bdae2610345cb9b2c69f9ce4a2b936fc54472eddf4d90c51f94fdfbe8dafa29cc55b3e1bfe92af67c356fa8a6ccecef2754b4c146ddfd2c7222f0531b988567f916f5fdd1cc90c7f9252e4bb2d6e731590fd13ed6e307dd24ae4a7b7a9e4eba2d2e7f9fc48b48ee80d26fad6371cbc1b72be7324d81759ef5c762ee59c1dd77d2a20fb406cce39e7220742e4eb1b5defbeeeeb2ce6e622e7826ccf73bdd17ef375d1578d70d06f14097cee3566e6fc517e95483761663a7ccf5a893b2c642d68826806dcbed4961f665ee6cd2209451cc1093e406862c7c53936a0c21786aae069028c242e0ee3b90acf323c634c669d93e60727fcf3e2e9209d1e38e424febc78b0209d9e6cc889f6f3e291413a3ddb9013d1cf8b870bd2e9e9869c783f2f9e51904e0f69c8c9fc79f19482747a4c434e4e3f2f1e54904e0fcb508b13d85a57cb8f134ef0b5f5d18fc47ca436a42b5f973d1f363e1fd22670120c93bde3a2f875301ea500ce869f9d79a8b8c28347d9c4775918de2390760bd3bed45b9834be2e71c657d924868c0a737da080f1b5fbdd010c7607f4766f772cf7ebb303268fea559f80b4b3debdf6aaf5816208bf3e50587100293d0042e9d7e78929587e7d6eb044fe4ad9011a3d40e2092c62cb54ccd78bc82accb9f08b8e7df0374375c30cd5584db9b412988d3c7711e61a41bd119416384a59e714d38ecad4d7f89a63b093a9be024bac6146abff7a16635c6cd29a7a0cc33c3e26139dc330cc610dbd6aafd1338cd618234dc611093f4078750e86e292873e3f78e261377d9c40e3d707073cbf57fcfae0a0e751317e9156f8b19747a49376f0b9e63c3b747ee99ec2677bbec83a8c1b638c2c5ba64a39672ae5beea195ab1edf9e85c246234d29cc8980eb7bbc3eb7639d1eeb6be1f6b1916bbbb7d2ecc76b77777efee2eafd771a3d14683753941afcfc9bebbeb4286cc4c996b04179198ebabc52c61ae8f13afafa9a1af32e5b22e21fdfa9648d7e6da97a48819d7e64ba44b2412c91f545073114857c0cbc408db1d3a15221dd2852c8a750c83c3bc98ebd344d0fb34a1235b667d9a00faf6ce25db79897449dfdde184ccbeb89e15b9e98f14097c2744a0f9e96562840daf5ce1018ff0ef952b2ecd6ffa9dd07c3d1e68706974212ba680db95894d2b8ddf42991861c32b5778b4d7f5b847f8f7ca95f69bc68186cf810c8b80827122acc33e8e963ef0d04b0f310c1b01f6d08fd4f0ebf5c29c137dbcac2c834e836c0f5d588771ce43479d87f5ce499115fa1c578eab5d8abe2422e7be249c774f4c9bb5f2ebda4580e6ce36e43ce634100e117150c04be736ee2ef4461b45d2af05e9d7333d72333f73de1c1127f382c4e77cb08b8e48ca0b93659ae7434a2dc322848ef9c034b8852d28d1b9e8f1b0048acdcc17597d8e6bf3e805d1dca632e6db9764f322a0d8ccfc0d4440e6f1c36cc8f9e85b1da2c6d36b5ec31be5656d21f87686a279fc8e6023883408f6dddd8b8d2045d29bc7afa65fae8d262962ba761150570111e73b48fc1622f2ed5bd2ae24d28b902e11e54500e68b39371424fd9a0d7c0d8a4631ca594722b87da9d9eba17331c6c83db0055d31744bccdef938b43bd8a3c8a37316b677fa041f9b888ffc85cd2bffc8c841d0a1c87b07b63020c882fe0324699d4129a1da3b0f7bbe760f4697c8634350e4333c4663af228d49441fb6588d491e7a8d3adf1c93c4259149cbb0672f8c082e3a87f1300f8cf24f0f980be6441ce79bd9300761e65b96f93a84bef97e36433c7408b5d911312bfffc4621b8a465a447874c5a66f3e85047e4d1e14ecb701e1d36f17cabb8628e2b6e956e4557743e6388d168192bbb236a5276f408ff641e19f4dabfce3fcc23a36d85b9d81d90361816267a6c2fd3bcb6b230d16114264eafa207d1abe8de079d4056f4f67e70ffc3c244d77e8c3ed8e4833a1fdce95574d10791804c8460abad54197d295cd2ab6844c664c2e85e3f99982ff330bd7e7df62c4ce4812dc813773b4c68623cd1394a74ee611efdb104b3eed047efd77c58985817e8238fc75857cf3c30ba6c5ae58c1ee521c88a1eaf7cfce0abc96caf6de5635be955c4b02ccbb24ea35711be201566f4b6f2d3322a1bfee5affcd14a5b890e5fd1e192e850077b8db6e8e9e42e8470f7eb660966ebe8415330d7ab8e974d23d0e4c202b9e22a1bfed4bb24c13ed3be8a99e920ecfa6ef7946f6f8a93354ef40ef28660ce5455c3bcbbbbbbbbbbbbbbbbbbbbbb53fa673dae63ebd9ae0bfbd615bf75c17571cad757eb9d44cf6af103650b3a5041114a20c1133e5c0801075c1c01a80bd7baafcfeee929fdb3de4071883b4b8117cfa9946f15fe1bb87da952e7db392ff4d0b7d7ad85b0279154496f85198120ab9dc463be7ea3d0c2781cc258b02dec09132d83797bb4b23b326f8f5f581e9a4e6541af31da8ef669447cda6b61dab14f7be2096c69496c0cc3b6b4122cab3de66b462b1604c88ad89354ea74fa1a87b8990767279855f3ca3d5a106c693b99f6e4dbb5cc8a9c3d5a500f6c69afcc4a0fccacf42ccdace8ccaa0559f9765ec1ac9811be1d46d9812ded07b274604b3af9766c8c6d694141bb83bd1d8bc2f2e8d996c6035946d81d98b7122cc8b3128441a3756e21d382aa90029a3f5fb129fd647251b68c3f74c6981ee16762761f9f3df68e7ba230211840bd823f0b337a386561ba5d1c779029c6c3aff1c056f604b2dad90ad482608bab5856fbac1a4fbf7eae905dcc27a4c6d0825ec94bca431ff77cecb339dab325337a8d4030ca936c0a6c2dcc9ec0d66a05a7c06cca14a9d12a672a7bf20d9740563b3ff99a7a4e6804b3873a7a61aaf66b2731e7afcf500e6637315ba887dae10b7a2cc1acfc82241e5e839847a4dcc339a4b03b983215cb3c7cc00624e9d9fdf6011d139a35027dbb0fb8577cd14410f785ab3d0a318f7ea6f5480ab6b020c86ae9d9ab27f55262418c053d7449ca41329855aee0bb85dec6870dabf1d5e6a307c18e7ca49e0418369952a7e5889898ddd1420bc3fefb52319d6767eed6b417ba6ad2c20550174ab6b0820eaec4e003202821451323a438829d10b33bbaf38ee2705455d371187430e4ea3cc7e5798e8b55355c1c822c76ef8b4131414e9ef044e99902141413146305bee012a1216c09f6b202a930ab3f735d0de79e7b14c7abe97ce4238a33f2ce735c51063d62608be60acd95a15eed8fbe85634cf6ee9b6bcc3abfbd760d7e3ff6bb1b4cee35df9e35807ebd1fdccff48a59c7c70f694ccf60fad70eeaa01eda560e0fb0d8620b26487022892fb8d8dbcab6828041126428b1021d08c1898b1d9e311db63aa859ecdc415c8d7cb750d55e736c79c46c0e76cd653779b5acab5c61d60efa2017899c77055d93746a22872e9d137df2b7af7bf9d59867b8cc8d8df6b76fbefcb4afe2c812f0fd19417d0bb5cc173f897546cce0c90c9c409e5f691a8661580ceff48a25edd63426acfc8d0ff9f395776470860caa38e66768bf473001d0afe703a335e6355a63b02fe6fac8e089af70870912cfbedf640ac844b7d63503a1af10c219043d3b849bd7dd60aec71fdebed031f8cde7a2f7c3fbb1aafc5914b97cf875cfde0f11e5b4309756ad6a8e49d7707cdcc425939669ca4e90681949631c66611a61b66362cc762c0ab31d0b9ab0e50d4159c210a4d081bc039398d811667b2f319bd6606172ddc4e4169654185369990a31acb55c386182c933a9491464b8d8798a96591f1a80e1d9f4ec2c45cab3f34fb7dac55aefd060688c67874e602b0994f57132c54be1397ae66a7cbb60faceb67a88b282226a00c517bc70818b9d79b69503031ed46005599861c4158ae0ea1bcc0a993c3b64d22d87cc8579e4663e8c41129b83bdfa125264d8e14e1498e8162f3105dc7162e5d9898f93a167e726fc44d3480f771686bd999831ecf4071dfb7e1842e731efaff28fccb585a36af3f32d81762d64b5f6ed67417c37bd5a6ea7572bd8e22496c5be440c0e9807cf2bd85a57ccccf6f04eeb4ce884c226bd62f6686556b8f3ec3862681bcc853c24a03ae7eee829434e983b7a7a4aab6ae442166f9faa66c39190c5a3928a07d1e6225f978a87ce39e7a810d23b5fd7f23ce6952b820511a9826cdfbe7d17d1bc3deb2f125d65c352c1e4e7a3475fafa960f2c4c36ffbef87edd7bb4fc5c3c8a54b2a44e7235f97e853f1408570ad37c4f38daa6a36ce3749e37a43bace2555d54817b988e2885c7a8e2bc735a21108b27a208b9da635264cd6d971f2244a4f0c0dd44142ec710a7bfc61a1a067a067d7a230b7af7f1a08b2d8b9af83208bbdfb5a08f61064754fafd6d57deb5ad7d64da677cad95771486b6d073674c69d659d712f905e41e1b5b3f2548cdcd6dc1997c4ceb8b3ac336e202c80e9d1609af40a66477a6d01dadc069396a92ea5b700750bb604b55469116a196a41a3250d1b2f1b496c2cb1a1b349df59c118016607722d51becaaf2d402d4090055b7a3ed21a23f2ecdb562987d9812c29698d5e5b801ebabaef5b56e6a2af5680f599c3ecc09607b35361762acc4ef76ded0561bd740e2ef76817265b97e8dba0469de03cfbb886e9919d25e98c3bcb3ae39e3395725fd59d22042631a1e0e2075beb6ead9f83dac7bbc29cbd2018c7851826e13ba17bb9479eb917f1f2ed47eec81cb923e4cfa81312934498295fc5d0c0d66e94e976157d2e2bfab26296159d66591148cbb4b3dcd5177715bdbfdd55ac3f3cd6c9f819b5c1792c4631666af60aba3c742e876651205566756f198ca2fca565e082c141ef6eefe65eeeeeeeeeeeeee5ee6ef66daac2bc553630efc274f737d6700a9725616e8989978c0d89f0b2c2a16386a6062039d430efe87983103e71d2de0570342197f48d2e64613618faea127d6c20f4dd5b7b125897a4db2d98fed545873280c2f079828411689023c51a307082451090e093c4d53e5af084cbb6360b55788110d288010c4c30e46a7fd9560d27f881c24917cc20a30aae761cdb0a410f9ae041132736b08114ae761ddb5a32787686a0808211c06002573347d622bb58a95b2dd51b0ea73005c81420426a8610e9c1c80f3741bce0ae562b292bd4aa1b25c6aca88f11c550c0be30d7c541b1e38346cfcb5557efc50432c503a7afbfe5abd3451e3d1bfa4d7e62a12547d18afad2e933bdc94db408e7ec755212c58173e6f7be7d1ad87dfbdcb7a2f5ed798d1641c2cf48f82b12cdd96f348a84bf48078ef0b30771225ef5bd62701c1a62a050d8335aa47f502d12d291f94851c5e3368d4c25dd6ee7206f8f9a5909ec878e856199981f5dcc3a4acc63867d1d14d5e55be2c034af98432ab32f62195df5aa338f2f1af42c73ac33485399c7ae575373cc39f8759aefd7f81a4da182d698d0b5d5ba0ccb6aa495e5316aa4fb4873beb52bdcbe64eda457cd4416a3635f3fe9557b3f91edccda3ccd444f692755f816bbd6470a30bebda370d232fc82d92de9add38491b0c1accda3d351b44c744cf64f34428a28bf3e43787d8e5f9f21e8fc8b6582d0e9553b23d1abd6612566e526dfdea4652aeb20f1af0e07043cb03b9657116098fdc0baca0883977084062cc00b57bea30cb87d592d4c1be09bb5393ad5ac4e311731db6b8a6738c81c312c321b31612b765f573160a0810691294c61b62fc62f307ad080a301387a2c0ca4014703702c8e15cc8ae33ba8833a688368608bab728b0e370a2325224484b3823bd99531db1713123df3e4cac59e40050c843e0ca02853869edb2c8cb93e42087a6e3331e6fa08e1e7395297a17ae55ecce97ac5d1f78b79f9ad2b855a18d8a88581361e7a5500cbe668d7e8230b269096a9297777f74fadbceb7ae5a8a159e78fb9f50a47af72a2af173df2ccb28da95eb9cb9cb8a5752d6e4448a3d3a0f2b0bd8c62f19d58e22ecd9dd0e8102817142c523f783d7bea072ffe420d356ab0341db9e53c11ad3899f4f57c7811c86815b9e69eaf6783e652f39d4ef20b8cdcf36d9278d44568056d282626867b8618fa762134b04e4cd6e48abcf2ec6540b6e582e1046038c1cb083ada7be564d62983b98b4f9980d6c1f946636dd770a44813798d2f696def166d9e51ad0ab3a234672f0829e863d043efcf4884aff942047dfb103d2219cd339b19ae5c49a39de4c8cf066af4db031bf4911679811815bdc66c0fb23ecf1e37cb2886c3b2df601f895005212da1f3ecd15f446041e7256645a55ca0af76477f5019dd42dd420cb5acb7146435118ca665cf4e35adec29b8d19acaea0d967d6dc6acabc54786104aa1d91e9bd0ce71c38869abc66a66349f1009e48a9920333cb3c6ac739f6899908561e736d82710610c064e7bed0e4864617a48a1e2c53318ddc6c4e3388dde195a71926e61a059ec699c81c6739d398391d82a4ce00cf487b4cebc461e80f94d6fa260567ec2685079cd339fa1812cf6ec23025b429ac50e241434d3bc435f67602bf3197ef203f9c94c7b7c1295cc3af324cec099cd86af4048671686ddc90d2a5cb72a88d91df3f4ed550108581ea5cdd1a35f22666d1d1f8458cb62478064c0b3fbc02fccca4e9e602a52a688c28993c856666520ef24a96634be817637354b100359d9e4166230c320846d029dded13030a44900f443600b870e20e911cb0148181847af38a659ec5b8f990c46c83d78c9cccc8c08c78abf24b3b64e94d6691d1d1c1e29c7753b73b60e6409b18e467d681dd8fa61c9b78ece0bed7c3b1761c4608c11760a445b84cd52cb961bd59ceef11f701ac70d31adcbba93679d6fddb60ce6bbcef9fa9a46bebe6a1992afe36899e9eb313ae2c2789ec8510ebd8462c8ad27819c18f010b185175801e50b315c9f476be9e36f5871fee4f033d2bde9642a7dfc581785f9c95d795dbd217d317abbf23aafa3ec9c8846e91d8d50c0c4a012658c5e64a3acd1638c51fac26d730c1371954db4ad6b523af6ad4b2c7a3e960ee915e63450f3fd30ccb5fd5804309e8378cc23642f887ccd63740c5b6aa3bda6c51ffb516e8c45c1c58861910993e7209765beabbdb636da67187bb363be1f631f070d818e7d2c05ceb1dece1e84fc76aed22ba68136da778c391a633a5c3b8a69302bcadb71c4e868195133fb7a4cd3cb6154d3b63a3f85f2a28b6835f22291cb33d32af2a86118e618f47885099da56b996e49855953dd7b45cdd91e63d6f8ddc566b5b714e03792fe235a7b30c2a843dc55868d200816b96186514845105e41e0913ef8e1f5f1c14b66b6d6832176f9a0376cc8914e6ea64164c8912153890c3932642a912147864c25466628405f48bbb1237863b85bc84f439681ce5e49df1895594cf61a31ee3baeb62dcc1ba3a866b5b757120a15c48b45b8bbbd8d60633b9c11b32e50b633eb2a660a902a2b287ebe1d470fcc03f3760e308f0df3f5c83ca4af67dcea38afa3d7d8ab0c1d5d719a8daf2b1b3608f135c789296c2011f2355a3d60c6f38fb562c8060688e1d9f4141f36ebf322e26f34ef419217b936c673e1055a30e3d935cf862d638a67afd20331681046189ebd0c29168c279a10c6662184c5428ba5a2c56611250c3040a0e5355a73861006038cc8918568dbb66d1369a31a64090684b154b280f962a5051ba8149e3d0625a52c6814b42e7a1040bd46eb07bc286d72935bcca8fe608467e744dde6fde0cef85105c18f080469907aa60e9e6fc881c50fb98467975e90fe8a448a4d6edea88ac00bf28b97de0f4c8967df3c1b60148ee33891881389384e2412711c2712715dc6a8feb3b77743b6e40651099e9df382f078d686601f6f8ecde50737c7e62bd8c296b57975a18165a335e65b4431d02b0d02fc224ae40b13a347fcd7fb7180b7d92b6b3c7ba5dcf6f17359175b061e4192d9d0f022ca0ba3f976434e90edd11c7a41fa25258281c640af86ac945709be872f263711203e3c53625638aa98bd35090654b480ca2f152dd031c02f152d7022bd98ebf9884966f47576e955af70446fb325737d78a67c9d7124fc15feeae8d13218dd1c9973fba5e6d7ebdeabf6679e281e0efc90be7c61aed34ea536d214ca3f9ba8dd71647b1e49bf0da7c1bbe30812f998df640ffb33e8fcd9c78f519bbd72e523f5d182259c63d500c2a3d8f4a4e70ee45210a17861de167650e5515de6f9d8203ceae3cfd633cf87f7494df37cacffd85f1a435685b93e3b986207541ed52bd9f1c683edd767074f1eb58d9673acc32df80d9672277283dd60371884ee446eb0e944be63419d44a2af122149392711918805751a491389e4cf99e60de6cf3927495ee788e6a1137108892cf4bca3245ae788d65425e2515a53a91b6ca66e886c708390831ce4e006219432c541e87e83119142565240f3a7ee14af333f6356bbaddddd4db94b1b7f24316cd06f4fd0af6fcf6f907b49091c7b3f2aea453f60dd749092a341a0b743230f5122971c05c10cefb9f4edebaf21bc21e73d2ab7a337e47c46bb25ada5ba79d36ae48da09e49ee7d15f5dec9b455d44b1f6d9ecbaf3b99e49c23a781de37a2b584faf9d512c93323a8afa29e736e0459d856873cf4edab467e73d46f4ed35044ab9187de9c4b88f9421f51cc3d5a8d3c9499537a67ce7d46503a684536dfbac7d6b9c8e5ccc7b85015e79e8f1c3a4ac55120fbd347ee397408a92a73ce37af246f9f1f5565aeeadca3aa4ebac85519b7f9e69273e822177d5525822208a17350f3f51e2b25f3cd4531f5e55da84a7a87a22a4981ec8fdcf3cedb1736a42acea5431f7d1e5571aecabca3aa4cc549e92e4232c30391f3d2d737dfbeaadabcc7af7ea340f66b8f5f5f7d8f5f97df7a453d127e6c94c6179ba39c437d9385d6f82cceb944b9e8ab382f72ae6187fa448ee24acef29150df54ed70c3537e011bde02646fa4e842d6892ab1d1b27dd145175f74d145175d941a9bb29df47e786ea295df44fa2ace934e55e4f0ab38a2205ee428a7e9e9ebfd90b4720e4b2e3f123cf97a503a8a9ee8c825ad904ed7bef8a3af428faaead6b9e6db27617ff715c96eba087741c91cf362d6177973319b8b29a2d5bd98edf2a16b9ffce662425a1ffa6e73312ba437cdc56c0868cf2424fcfd3ca31852e27cc55cbaf61591f4a65f46dfaf7222879a74516f241f798de71d69f3d14617ea80dbec099323adf7a3c6f57ad35007110da2b93396f322bfe9175110ccf022c7f97843ce8b36979ca813751413b9fc6efaa5a437e4bcc8a18b441bac380f2945c2cf0e69c5f91bcf11713f214adf1c9322b951d5ba2a6a32dbcca3a7a48bbb9ead47172ae9a843d6de3463988c1dbd914795745cd33844ccd93a6ec175196b4b81ec738e398b38912aba2af3566514c87ee6aa4881ecc74c6630464d85b9fceed76de22391e181c8f9a8c268f7126bdaf56a61d32862580220d833d50ea3ce6b3c178dbc73259e8b32a939ab761839e7359e6f23251aade99ce3a812d1461db2180bceba8fc02d4742d25f64d959e49273fed6396ee3441b5d0d4a8dd69bf8b01a7179c81b739094520b2db46062647f52d00e6977832cb2c88283346602c47a165724922e72259ccb0cc90c0f7d87aee33acc3757c251872c8c6a5954ed20f2cd6ba46b22aa4452871a75c882586081c510590eecce825be7f653ad2fd5808051c64dd2cd1cd332bab46ecf63746b64e7a632a1578c1a71a991dec4871409fc9c8cd90c6e5db8f57da90c04747e2ac6b0f2fcda7124c6612f15558cf89b2246b6ca47ea81ad52e521e5305e267c19126691f5fdcaafafeb5d65c9330efc7abd0ef3a3c30f49fc48f7ab39af0a22fae8013e8e006361f66337bb06547e7db6d079d6afcf164e7ec2166fdfbec5ebeb0cebf3f382e7badb7e5337a813584d6435a471e30be6fafca8e01d055a08452b4430a7e99d025b983774f8f303041414c4423a30569ca15eb510fc4ed2aba6f007b25a89593bc9b777929659d22d8f2f28842550591f2da2fc6a31e5d9633784d0f3b18e84164c5c01e5e612ca8dca19272633e74387402d087b29b71f9218042efc3423263bff664998f1978a29f8e0d93952968489fd5231851d3c0b00f5eb83041e663a6356f34ccba484718686df764f8183be63d5f8ca2e23ed62d4c15c07435b28a486b38debe2ca46c2648f2b57325abc3e0b2b90b5bf7d2e29396572af9cf4d7a78a35b2e0e26b2ab280db213c33760514165021410aac50868bb1d8c10c5840c5172c60c2135c2bd8ea9f181d2dc3f2ecfed232521e7a842ea728f1d03b14dce0a1bb4cf9824c031e2601080f1d07f498133c741d3f2ee83d5a66490f1d88d043cf418812ac3cf41a1bb8a06380480c1e7a0f2dc3f2d07de079e846a0cf156820e0a1077183878e0377090e1e3a3381eb43458d87ce48402cbc78e8dca46516e8a14f164f3c7466a265460f3d7e7bb09b67204725b874bb3efcd02d040c41091268e155c6145d70450fa25b394488829527869082204ce10a57dc2b1f9d9f1c31c647e72754e08ace51b40c74eee129bb839f8f584214603479011951aab822189898310331a4d8820a44b8e21a1f8fb8f2313a901c84c0d674451f4264598c095d6e6b5da85ea5b2b03f9f5f500a5ec20e908999ba81f90c0d27674ace949ca9de81aa1df31c8ce2883c739c6d35177d423e55cb8f46d5bea99aaa76909e798df40c074ad39accb74cca281dca6ee84507ed0e6c6761a44bade7a5d3c016e682c22e55e639ae922aa342924c37798e8be40b2b0f10c8ca9ccba457d68170947d75e6e593af988ef44c72de65a6aff4614e204bfafc48d893972eb730d745f20959d2a1d434949a919328cea8a9af4bba6caaaa1979fbc8dbd7a5f2a8f41564494c67473ae6443af644fae8d39e409674ccdba15d980e6449d79830e10f50106ce5b8a4432138241d5a5922bdfb385ad98974ec09c6231d8b225ddb91ae4911ad5a948d568de7e5939798ce4b97b488d693b5880b1883c9cc9cc27cb54f155d240428c7c56d9ff6d1a8a28b3cc785b33052d50e9a6f5ea3f9e691d66c2ea2383190057d731ce81a74412626464b0be3ca38961ff6c575710be184ec10ba843e21ec2805d7ce35afb7cc17406acc408c35be18021a6a8421cbc9c111c2a086174918a1e488be428b35d080a202269670795d20010fa080b10434c270a5810425befd654600bf3e5670c18a2990a0ca4dc52c93b4ca8f3146091b8bd139e6604374b7102627352945bdbdbdfa8ef99ee1cc351ab34f661946abfc69209a65ade76c1ca7e884c438c13e2331af654e200dba542a76ed28295d6a1475243e468dc8a6e2e7a17331c0752b0f1768ce2c508c84af2190051dbe608b8598c52ee59c4ca30c812d29e704a240b5a33cf4651ef2b5de10b3b25013cc637b096c710ea7740b1e4e227c854247640c819847466110e7800e1d3a61773085525818e8126817e75008b6f88a65314fe11cec9095f0cc424ac6483d6142a19882871ec9d816f664a3151e462e3c8c6a605e31250fb1143cf48ab9e0a1ef62327888094116f49488d6d49c9810ac5890462b06f49156ec079bc2500a3028e3cfa0802f98d9925ec1ca98106c653ccb821e65a8e7a167531ebad0d0432b0f31a10c8a8581994ec62483e2a1472b73bf664bb8670bdbea615942ccc3029b831d3a5761190b2b133d0bcf2e148687fb042a3ce45ff78865be543c373164613040047eede2c0f819532d53a1b3a37a95aa53ba30adec10621ffff5faed612a3b6736f320e8d9dbeb047a27cc66ef28b3bd6e1acf1eb930db39898443df431d51d0cec118cc211820e2f9d2f99302821c0437e65b054ff8750b2c0f66c22a1cb222ebfb34dd3b369cbe9f28912d398ec24c984723c139da2533f1287c41563ff9f68e56a735b50375bec1f8da4c446927dda47790601e9dc4e6e8182c4cbba4487c3b6682c958e67ded825e0ef16df64a867d303d44e6186f8e8883f1aea2631f4780c9e8b146c8c3b57482db75b93ed753ebeb006f97b5181afdfafcbccce0f6a5b2e4b28fe3c2100f2c7ad0d3eec23cda5d96055dde2588e5978a264d1ed23aa9f46adfe54d9c838544290318aa620d6a25a60aa167af01c89367cfa165e0b3d74448c40753189e1d6532318f8df3f9a5573e45ed16c5cc0973a570610a4ec70dd95e27ebdb4bcb6a395decebcd85e91e33bd5a1ea2d7f3733385b2322175425543c23e9ccc852001e61955f1a00991b9465536fcb2eb05b4af2ba3ec09c1d63553debe6ad8900932c608bbbbdb65cb7c1331c5771361c5f7c8d5ddddfaf614cfb7bb100184ef6ef912615371c5b777b7a8d8e2db5fba63f8f5a182078f3d9149f1a400852b4f744109340882abc1400226bea1ab7b60e2043c6278c1042fc882cc3056cf0cbebef4442b4899d651c3daf908667c7b4c75017e7d8e40851ffdfa50a1f3c3832c06cd031d604f60a532188359d5ba960d7c60c50bccd8620d25b8b21728e9220b662c71c20f5cd917b0a0c186c593a85123339fb98e9f5963626260abcbb038e2b32c662e61c6dd63df0b6c94cb8d5f9f2e88f0f3d7a78b257c7de9c168c02fa8c92ee5a8ae57dc3e7b9ace1f7e69dfcbaa513a7ab44ce557cc4ccb5891c5b747d93ea1155f7cfbcbaa3d86a609df5e03907621ed43da0a297c7b0f2d837dbb0fed3fb415dda15c823057bf3e5634f1a65f1f2b90f8fab2820e128a4258c4ce28a3ab74506ca11612ea253162d8621847c13cb0751a8966d24b5a05add33a3e88be5f8ccb3a2216b199fe623847f4f67c2cc7dd7ed1d7d321019c23461dbde24f47ecdd88849e1e29f4f0f440a1e7a77654e036052511a2f8f591228d6ffdfa4cc1e4d7f39159316bea3b665ee1db6750dfdd55f8ec7cbb0b6ab64c453d3fa0c7caaef6eb1c5ad67e950fe8115ad6fed2cab45b35eaf7574ad7537030c208238454f20da66cc2645f661250f1faf5e9117a03fcfaf4587917cd01d231c7d10ef066618e6111c3d87331c1d468aa579863de987760cc085b1bd3517a9cb477aa7b087d665ae1a1bfa4d278087d5f2a1733f3f18c8f3ed3a365a0f74f8c31462344f131fa7ad0e3f66cd18459a3ecdadbe1c26db84ed3fd2d906c67aed7c8bfdf7eb73b8163df971a0393cc941ca3c52e9f22a4f1cd1be0202c022973106e7f77a9acdd778c47187ecf23c9d80b7a245dc7f7bad1ee38c2afb7a1e191647f84871e89e908fcda7dbf5ecf3ebbf6820852c840b1689a974a2c2cbe9e0d161b9a7736e80d392d5a8b8d1b2c366c9041060a95baa152918142a16ea0503e6a7116161bde6203e59ea76cd838a57ce479fb373e1b7ecfb99467327128efe34f7d35fe447d353eca8673366ca01c153d1b4c269409d5e5600c92779fa74d4e1b79d53cef6b718df35ce35cfb6ca06cf05cf337994ca692a6b9c9860dcfb5af12790de59c7b25f7a49cf354a2de57895422cfdd2879f5dc06ed96989eca739373d4d3386e0c13e71c8fa1611de75a89d3469ee6eb37beaad11bec3b6fa41a2206c75151289d43a91dc939d2181a89a47da619660000006490c1c545a58a21861b3752291b365a5a585850a8d3c9642a95e624914623cfeb3a8e1389b68d85a554a255a2bc6a3b524ef2dd1d25afd8b3b80d12add99b7ce4a96f1766446bf69aa3bed76c5094b37cbb30285ae39b7c57a6e426936b5e22f2f5062b7283bd562a9568f592e6af75ce25ba14878e7ff4ed3b911214aa984c26138b771f8b9b66c93b2f695efa506ec3357af2f8a693c9b9538b9f4eaa1619349473dd953e94afd7e2348df2ce3bef34ef5c6b71d50e2a950caa1b2e275a715e73194a5fcad7d3a1f4d5ce51b45b627654d5b9c935da42551d0d52f29397fcd4cd2aa62a2593a9c8ec26ada752c7c262e3ab265f4f7dd5446f3a06c7b951a5e4fe259f25975e6a69c9d95e95e8ec3739476b7f8ba764107f6271d407046c711b3e2a95fcb43a4d6fa93726df3cf5d96857ae5c59e36db80da7e9966f7f648322e137b9c9d939d357720ef5f173d053ed70c365f00ba8dcc503c2eca7afc56f7c32b8ea7371962f7aaa1d6eb80c5ea37217e7b00e158193b7788b2b51790bdd5eb178bd69d3d7ffa6af5f06bfe1352eaeba21c7e427194c7ec3853a6499e8f66aba2af66a3a4d9bbe52a934bf7ad3122786ef75e3c6a9bd2f32eee32f394dd7b8c3f35af2da2ae870e06ff1ee6bf1d211fe18ba256611cd4d5cf7955cfb6e78ca4b282f995c9bae79f755d4775d37519a97bce49a77376edc70936b5f35f29ab76703ca4b6e9a27158ade90f3b3e426d74a5f35f2251bbe9e0e279fa6af9afc06ed969826aa3279e725da1a55996890934f3ff92c6937fc2cce7137ddab11d49fbc730e0807fc0d7f078ef09f9ca63b16e78e685e62a175d21345c25f6af11a3ddf85a99dd756c1674e03539f8daf96b6cebdcf09112871284590f0102ac7898142e11c4ae51c09ffc83993731926aa0ae26f727f9397fc865f15c4e4d24d2e47fca7165a73bec54b9fe9ab4650ce42ebfc924f477ddbab49eb7c93c94b1e432b0647a16895317cdbac49abfc5235d252a48522e13ff97e3582e2ba3b7dfc27166f2f88f49373a7cfe41cd7de0d39ddf2f1899abce59b0ebd169fb4a2bec56960a712a8740b978a433d0a9942332302000000b314003030141088c482c1584015f73d14000d90ac4a644a9689a32488619432c618628c0100000020003333a40df635ccc233fcc116b719703863a4f80251cbc14e35e72992d4035737703ead0b2e916745c401ad68218c57cca910c0764da566f61a8f401cc5f356334e159ff80f6eabe5b15f30890dc1cda21c5f51cadabe5a45c0a77643d48263140444cda0d8202007e7a89d99dee0e31dbc559238142851403bd2b585ed9dfef6e785c8740c86008c9ee508eb00f8bc36747f9f58cdb1d88aaa3d5d313a73da8b1aa6b1babb0b5833d690ebb694b4f81d847cb2e39ae224ac9cfd2fe886d845c0bed2a1b2366b7514ec9e467df87c0a42bd59af28a280cfee293e79b23a6a9ad43527212b46e1dc1a3392b25c6cc1ab534a487baea1bbff245630b91be2e4a4f940de6b73da1dcac182e0a377c5800056fd98a39f0a98405f1e420bc1b104cb97513f7bf54dbbef1a6c8d97305cfd91a2d62488e4a6ec3d7718bdd7e463d512120004febd1260ffe509c69515d059b20dd428b298e1dea1cf8e8423f361661be94596fb4501eac3f5a577cd205d3fa8ca6f99ebaa4f2ba1cc3ad2f2ddad942f367d5a6b123d4976aa17794a92d29f00f2987e3c01d0f58efa24fb26f01b262aaf4979b91bbbac3599cbb15bee1e7b984824d0c4e03061051afe8fe10fd8b85eb78628d28c678290dee5f04b3a6444eec7b8d1ebf4cb0174b1b8efbaf01fa2c74dc38969e9c42e249c7c5895c99e928ace0b65f9a54e610d20ae42fd8c6a035e6001b3914cd8a5f0175a68a226c318296c91ef37a6cb277928116dcbd02c40fe219aca834d1b2e94851408a6ebffde053fae2a285804456e47ac1599b9360123687214652efe84705e7758785a854b2dafee08736e0135f2ee20473dc8a40eec54feac0d7bf68a59b231104a2998a0904d9e17c3ff679d4f3beafde8b910cf7852c96b9ae2fbc2f9e1604eef8ff0e36f7b06b42cf40fc911b487bba686dd11103f7a506beebce25b9525596c00a160be77db9635647a3d810af447473ebf1617d1cc84b7a48274513c5ce05c2ff9ed435fb2b205b716ba5ed14bd3ba8942823501323bfba2a317c511be1ff4e40a14e01a43e651f0ca6029882bb98d66f0a6ebc9d660134c11bcf8e82dda9ee9e81e6f7498806cfa497d3248d5551388e0f48d098a0dc8f9c04366e680f6f55b62b0fc14a70bc627ba96966f30e5a39f63d3e3c0a1f1b55fa9733d9cfb5bed618ff90bd1d7be223c1ff492604f90e3b86303ec413ee608902bf529ed7895a82e584cb5e06ea66b3b746314537b3198e2e8ad39617ea8e7dca0d7165d3f16db733430aa8a61e2fff718e32197ea9e975a2988d18c16d0aaaf1891099e431e8e5658895b7a62dffac46cba0017200c6a23f0f070bb67db4bc30bb0848369075532a10a66535430e9c98a4e572bdfad0983300803ee8b82daaa99ddf0a7e8e405b64d0403e5d77feae23a6885922b1f23e644444bdba00ec03cf5965d50ac71b38a2d2c042443242d9ba60150d8c8794bcb82cb0402b4b10284ca3cf5e639d627487b102b26ea2f20b6b0803cccc33844a69c676e337b09c6facd1ed31826568c00c8ec1d5c806bd89ef10d386488f254b0386488bdb8463b012881083d3b81ad40fb79d052c5f38d911c9999318cabf8728425a9c44a483eefe9ba4413d4a783a39cbb46ed52a5871210e4035d191ca4e761308db389002b01343a9d6962d81e1a989e6ad551de1f4a3dfe1b432bc510e7bf72a066f1e9ba17ac0ff29959790abb760c063c4a3860419c3df0ad666ca590bcfa87b8e39d123f8ba925f0a92d399cb97b072026bf615a1228a40c3a96e0da86317d3e873abe3f5e4e2bd46acb3e6aa1834869796fe846163dde9bc1b49fb01e847eced7cb545d35188d75c5158169ab061133c89a5be68ab0605d6fd41e3c498c1d899b599aad159044f230a08d7a0bbcacae991c0bc6b8732c3974c0cb6b623aa0da4c397b47730fb280102779ea34c72efb29b86dde28a58f4ae725934bb73e304884842140887ec8421228181676dbbf35d634c786e635c8f5753674963c5db3b8f75305f4e8be5c6a84c662b3dc103bd47a9b2845f5ee30ddb4b9741715fd6383374f5d7a4e12255f85f19ac411959715957b9174bed35900d10a1e22ac66b73d91ce3d4c71671cef116a5a61f0986033a900b7cd3e6af0212753e1855653214d4312910fbaaeee2f5bd21d5907691651068427a83c61a20c3dd15b5ca8833a4af855f3ce98f17e3b8cce96400aa8f7767cd9bcff8374ec7818feaaec0ada9f2c02d601814fec4dd91e3ed098e29f8ea040d7a99f003b50615f8cfe22a14169b036deb5949cb3a83a123014039196c12c00cf2015af1fd7910268f5c3350b0e56806e7700101933f87a291af29a8bdf7f4833263ecce2d2382c3b4c9bbc352ed18b5e1eb7c2061f12af85aa2b83eeb35490c3e0e91ab83d15aad87fd605eed41442264c426ab80d7136ff660f86bb1873efa01ab5846c4e3af78e25754c1bd9a66d682e0cc55a125af968dbc932380bcf7aa69b721a98338da3ea1ecdf45abf6aee73c437cabb3c680b5ae5d7b4dcd95aa763a686836c61b52781fa0261a53580328a1fab6bf61bc37b733a30c798e66f0473bb8c0d830734b5434c2fabe28994a0170bbc97e12fbce47735d0922884ea687dc4c2610018558f2b9daff94847db795afe46f5694082e39af7b3c6a2adead2a7688deb48c0e482f63befc81859a151f1019f2f25a33ef4d7ceb79f22862a28fdf6680dc03c7c101f2858097c3e9320358c33a841662020f2f77ac0ba252322bb93906b9481911783ca6a42cb5c4a567526371021a8a6c9fa1af8ce5e11aa64303c88d87738c81ed456b373d610092e888b0d83ea5a87ffd1e5be52edcd302b61315a90f326c843a187f3b1b6b08fc3a2f250c24cc12cca099e0a84c5e22dc382f9366c2ca5fe07b07e3274ac0b94a555e06bf66ba1b9a497a6bec59cd0aa214ae9d41e2114cae98a806adbca8bf9c08de2f1a42cf3cb4eb55e9e8f75f5e8ffb7fec278ddea403393bc79120c71b1232b4ce06db3cdfd0e00797e9481c9140c83672ad83bb7d89af58d4baecebf06ad0607d26775a9dc29b28754d80590b43894991469ec4421088d03b50392d5010ee1d11c203a0469ed3254a3cc31998465657a1d6bafc638e4a52c8e9143c829c6e93c1cf38eef47da188c28ec9d405b3befdd71bbfb2d2bec2269d54fb5efca708b3f6f556abe711bb4baeec2fcc747e951789ae3fcf51f68efb47fb0bf854124346434a0acc40e0bdad7b20480ba18cd23f84cb241e38f8881330dfed72916eb96fbc79258bdb663350c9a13346557fb4d0ef063b80a56736aa6e47769221665ab17b1581674c1e0cb3863f80ea2715ce2d65534a4d643242bfabb4f2f4f83e27edab1c45e1ba5df51418bfa937a5932db51dac05a96d8b3f8c4cc570980db6ad89b86e51da7240d2828107c1e111656f5f0ba946b62bbb4d3408bd005875890ac041161dc3f50e88f8d32d3f276b61a5d60fed048147b4f5c85f174811eeb50dd3df8b35d9ec32f70f9f61204e21a7f8d826a198968c3cd790daa01457fa33ad001583026428e09c919a13f067430ff70ff6e1c34c0c762040b65df49987ff9af1d3aa9f9fd864b57eeeb1f75ab0a547154181cad43c1d09d14794e8045045793ccb10f3adaebd990e33739c467b7b493c54b7a97a9e278c2b65514aa1f90bb8bebd1112eec40b5d6daa258dbbab2a66f270eb4f8b3c9939c38114fb5ee927af2b4f74e1452ac0bb328902f30f838df84baacdf868a83f5cedb646b95e1b945c86887042085fdd2554d3fdbf6fd69800412f1972bfaef91a1f418858bca71ee52a00b332ccbbafbc44bf12aefa2df1bb722114b63c4814b8a1f30174c4542e8f59f0f8e7c484aa36d07590b4959432d3a17bb682382c38a7c69a26f67af76006f4cb356a636ea313166966726c01004563d21e3136bed7d97b49fda8d21144d63e36594bc87168bb8257343d34d19336e1c90da1f7abbbe8dc6fdabbb009f1759be14fb2bb6ecded1f89bd564c8285788af16205b294ca7fec476b33dc51f1811fea02157393b9635e284a4c6d436d2ea39689441fbaaad07b6047c92aa192b131888f00e21594ccca9456c7d51983f9ece02b25b5f229bbf3ed4e103e2117088cf85771f516eef21e5950866b05f640a28c5265f48bd063f8edbe11488140f977d9fca10f9f09aee586048083251582bcfbed165f61531cae0363fa04632640c619816754d6a84030c0c1adbb320ae6f9941dd11ae1b3554e5b26f492c6d6da2860c32db12c4f68cc304c52ceb1deed04b2ef196dfe7e2ab656ec7bc2f995002916921c8b3b51aff4378600856f4f8e022da9ef1912a1c211645d7a4f08ba6219f8468ca1fbd8617ecc341b7d490dcdb49309576f00a9742a049c6a9bef1b88b1404e0875b3b8f935708011b44085057fdf050fe708bfc36386bc389f8fefe869edc2abf018f927663037d76c043decfd861961defb4ec28d57dd67f51cd0717a667a2ccd80f96a006f07aae4f337f34c8badf5d95a44cc8cf76532a45fc2111f0ed33e02ab1a98bb0d7a17575f5f13940fc2ce0fe76be0633e2ccd279f1c0d933de72452dfc19a489969089936351cfac97bd502c69b329a35a71a91ef30bcb12d625535ae90d5a7dcd49e083d9a4f436ab485bf4166d1cbea53ba22eff15871771979a8611b34bd76bbe0a03862133b9ac536e447bda20dafafa70ee2e82117c5a301e5be8031a4bbf9793827a1dabd0d2ad856714769aaec7094a4dcafa769f5287d16d18a450fbcd9d4971d23d80aefc5b3ea8c0a58303060710fabc0773b754f1683a8abbbcb2e5c0d0abb4e2df5fa425806b38d7ff9f96a627b78ad0a2f79747d42e92a33db61a90cd80d0801a7b702df6044614eac37f77b612ece9f47a4ac8325a7cac54a722d464ea3ffaaabbede914947e13a59a6e5488c9a1c5eb2ee6b89012a0e30aedbe039897c22ea03769cc880f1d0200ba95a6e337e332d82cd272f5ef8c2e852f076b4c3a5fcaa95b9707a5cb689a8028f479925edcd40024d7e6d3b937763afed4e38d2556f1426b81222159f1b3793dd685bf73e6343bcd980dc79d9042417f3e119c1765548c9ebd2ecdc2745c316b5b7a7755228f032bc8e11442d6bf46a669a4a9c866a2884c2cf1db19bbb4481a3a294f0959dc281d73a7f811196174d296a1ed1a1afa315235f99830f658687f35d6e1211e3b25ed58413eb299202e52b26bd55c324ccddf1a9648dc589fc54146245c5a652574295971dfa6f962d6df53757c901045ffe2f7f650a1308daa69911d1d8a0c2ed5e20d7d068676b7d0c4e942d08134c06bbe05ffff23100a840434facbd8526e61c7f294e8bce2e9d472d996adba322ae5d7387e6444f31ae8d5c7e3604f0a61b3d0e635f2108bc49f3f0c5e24dce582b0dbfb40cfc8bfffaf0c0c3cd83291cae8ac7c7df31f61b8c2d94f89dcdca0379c11f59637346742f2b877b88be6f2e552ae3573a50dbe2079af0c25b5b399af4074f408e9ea57e6560f57ed698d40b0f4d99469a4b766ff087ab981c43d04cff8eac13709c84b87fdf0e7a63c4fab9b9c8a683e66790caf1bcf9b39cbae758483af48b7525414229daf836523ffe04a5c1bf4c527384826d910dd18647375c9983456d7bfa120da463ad875cfdc501a2dfdde910c3ce0e8b6a2e7db00c612f3f434d7baf1212ae41c4bf73c9e242d538dba45c4c1126d1f41b17ec398d592f4cbf7c88c49e55360d769c882564d21206fd0f6d66d5163053504d6a17fc95a7e3e4176cf8e102829d8b1b9061ccff25b4c744003c52ae2cfe85d8295d841577a0807fb3515beec912d4116ae20fff2ce3f98bcfd1165af76d28a343236d807e192a59050395ba7140fe2b1a90b3ea4976db411dbbf0ba13b6c12d2c446bf254d66c650544cd06ec361f9c05b6119b299ef61b0976f3179c83e5069fd5116367ea073216e3ab447b586bc3d68f18127dbade2a54a75130450e0da013a90e5cd0e19ce61f88d7d20c35ac78ca2a5d6d2550b096b3142d82094e92f5a5aabd826cf1df81cad80b2acfa800a370d4e0d9931e40901c9e7c13aef046aa4ba2728da74659868da9998e2a44c3e20d532a228367cb4b46af7d80217e6a2b4a97e7315f9680eea4bd08370a621aa7aed83f24b1642a76136aa54425036af3208c1621c05843e049dea603c1e7a87ae4a3f6063c2252802b8d0f774ec25d24ab50999001fdad2a5fb0aa359478f06b9abd9e7644262f48ff5a38734249c79afb866f3043d7a1e2c465447ef20053c85ed5f86cdddba55bfd8c3a4984443afcedc211d86a1e9b57e0d7c6be6a58c2a99a7ad33e98b22e27ca677a621420a6d90ce4d69420d000ddc6cb4d80b3aa0fc9259ba2616dc7468ee8f8e0a1a18044def09e153efb037a9c98a9546100ca77e8c93be081cd97a9451e289311b33c945763210ff990e6cb4532c3992cfbd34ebe1f0d4be3891a60375e15e090070f8bb0f0a2718fd243c1d07ea6b485c2286c5e85d73abb3ccbeb8b90f3ad7378ee97b143de9f81b99afa93b596f58b32e99755d6aad4abc8e19f432263200fadd5fc5825c001cf618db5e883bd8912cff807dc9b133659a44cc9410a17ec68e090dbc0905d640ca13f0b1338fd903b6fad61159e93a0b46a5fe1484aa0033d7b5f44b00ae5bb08f62c1bc0b0ef750b61b814874ab100fd212d1418725cea098b0e4fd5d507c81d4fca9e250466cc811f6e5104c96b13f1facb1f1c4819691e45e52128aec9e942db6253eb0748eb7dccc2ea91f729f1ec4c1a9dc4368075893edc31047b317a92086c9bc293d0930e3ca4ea9b9e06653bfaa9c82517fa8aef8523473bb3cd61167bcc92dc6ff86242be8667ea14c723a2d7ae62d45c1843cf35c745d26b51c02ceb6c64f601451071bc3cce36d3f99c721ff42349e68110282b76904a021253591f9d2246f110c505024568e396694489a0c67dea32611c07da520a71d38e884836e1c75c169271c3ae0a84b0e1d70d005a7ce38e9c8812e8e74e26c0727ba70a68b435d38d881932e1cebcaa1034e3a192a7c773f5a31df2213239d4856ced3deee222acaf2700d8f83c6330f0a7e4792b02dd2cbd8d9d44dae2f85f70ee2fb425c5d478a8ef11d811f6d0c860117fc70593416efee8ded101107bd1810579406893a801bc1affc0c7b772082f73827d01b1181e294b95212407be8d4535bf4627db8b9bc4f0393602d365bc68185f1b01315ce6ed93c096bac21a4cced5bc8eb23b054f4edb80edecab9df07fd9811134a541fbece8862e06f1eac50b2ea090e28aa750363a03197c971116bf58bc8015a676df1a4cabe13cb158364754231aeab5858b626b78cd0501de9d5f2728993a114230664a7a2c6dceb4ea8810274b26bdbc75bf02ad30424762187fef1d5649f1143d735f2845db0681522e3c7f34bf03249bbbed9b0394e6a7f397381bd9844a4456751d3187e02131f452e5b7ee02df48bc56dac29c98d58c480f66cf948558b1945ef334ece3e55b32d2c10053a265035acc222978398afe0e84ca04098889d020b0d33ce5260e992fe2c26a4140e2fe652f92d13b554e5b510042762819b1c2e41edb3c12fc330daa00451121a18c92e0cf773e1bc329f1c69adcf55ffbd257a4fd19616b38574f354ab9db08948dc8771b8047427018d33177d7881ded4f12ab9e35543ea1baae29a9ff9001d3e79f87b0bb4f21d1b8ac7cf02244fedb5c8c0be9d4a0cc9184504c0121f41421fb20f240a1d6d68c8f844ba6d8c601e183c0ba4b8c6a616968c1587c64b34b0c4c7930bcb2c18fc8a07e5efa6d8f8b710273237cb3feb254ce1d00d94118c1b6609d62eb603a85faa46e8420fc2ffe135eb186b72f2d293f466febda5a2ae62abd3d6d77088fc5c9b7ce4d64b4b41de4813172d730a7510cb40e5872832e01d24c283a0defe8c111eb67285451347172a5851e93763c9768cd53377e9e2d0964090d0e42a9e8d3b633ec7aa35b75935925b017f12a2d1d85a092d1c8dc101beb3c89fe3ad4da448b1f375d7e8b13820342ad0617b28a2354ddb40877ab025063599360e0fd60f2ec6de65826dee30a8da5d171e493e66e44f6df6c299cd460408128e85ad007050bcae54bebdf8e17aa0b615fd54d2ad649ac99dd177479c50aa104a802e3027d9108feee31d69b442caa400b42dada68aa1e1fd482771bf1e1dda31cf535aef00cdf9bfa9386b3ce88b68e40e2cf33e9e1dfc95f1843d4957c1f4f1c965479a15434371f5fae75b9cc54566c1dad540035988700cf4516f297b8b5bd052b7d8db348b22386826bcd84457e21313057f208450b93804a1cef661037bb79096b4c3c4420ac586a8e758643268c68b10f66e3ff654e33c848a22097fac60b42ef99143d5064edc303f8afc8a02b80f6a451e1989053e6424ec8660888e752da425af366c732c260388cdc943065a961b2f4d1243906206646d0df7bbca4c84d5cd7286ee0632e1ef76a9e65267bc51178ad92f71e28ba613733fcaefb3005bff4c1382766ef78b56baaceebf2b5c0097510c88074d25212e7de4ea106dc9fb4478fa755f7dd7155e3ba1c11206472a015beffa8b18bddebee45306b7801af04231ff1d5de25a53b61181883f8673db89c23048a6776c63805efc467e31cd4c4f3c8d2184d30eda2ae1a064eace0006d8b13c66963ebd1f7ed64c93981d38a36c1855014629eb0b88995febe15856aaa2096b11813983523513c261d170192e576a3ec78e8a3296c1803e9f01e24742d99e53734693f2116c2ccbc58f572caa48584f06a335e2c627128cfff2e33121493236b3b9c331d2f82560d0800d498428a3199cfcaf1ad151a336afd730585ea0b60a208db198d0e580040b6039619309c88590da1e22f16b4cec1b378e37643f6f18d64e023616a58adc95c33035ff1709a982d8d28c7ac6b9162c9111a40d7eb0dc7d8c39a087c97a6d607f3caa7edc8b82b769997e21a0e20cc85ba589428f821aba4422846197e20f269d0a0912bc098b3018831197a70e3e510e8906450e9369f5509a9529c3228c73d2b06f8bdc38f899725681307f82bff0fa0f1361f93b43dedb32892ed335c342bb57c520d6c6d060dd399197bb5542097f873f245944e7bcace86cd86cf3ccc798583f18cc7119a099302c9a32c9f15bd7f32070a9da193d92a15a7ffd8865727d2cb37b52849bf84702c7102708757689f4a92935b0619c68216986925df826d7a397de6b86b37e117f4aa6a25ed862ab57f34fcd7a49b266ca724eb736bc050b54606b8711a22ab70a01134cd723534c7324a86f82e818f45a7507780366d2c40ba030c04482cfc1dd7c5e54cafa2a6d2ee04d2c20cf6d24d9c59163bebc21ba58e0ab479363e32a5b3be3e5ec59b4dadf0e02d9d8547a65c7862e33149d6a20d96289acf048e848a732d32dc038fb1f5679f54d95952fafc84b775088e2e2bc7c123696290a7a604bb02956c09a697a0c1623b15f874be73763622ea210c5b462ea4c8b80e913878992bd5b7fd9ac386c6e3f35bcbd13fb1a80d773244e7ea50004762fe67e7d899a98da708a473b367c79be95817e520b2652ffea329fa8a61d66c2a45b9dde648ebd9cf638fcd85132071fcb47a167c3740049c85b49532421573f6a79280a719ee9e187448babe9ac30c9eab9889609dacb58add92d702a363750d9a3ac3294de1963d56434eb026eb5bbb60a4e4d01e3443bec6dd02ae66dc209512264c811caaba55d47f55dc6710088094a6bd9dd450fb4b3a452992c1c570ecc693a8817d904d6b9a15cf7e2ee62d98475a8fa8ae17ac9f2dbfdbeaf494c7eedc7e9b7124aaf2604b83ce124a03d88500adcaacd69f533135270164837b579693edccf881822128041969212f9a4f4708adec033865c2421e343d3960fa471246d253e633eab10460a7285f30c0d3bb4d6fbc7765fb379a9ccf1ef0bbb460770d206627ac59369589b4117eaaad67070aa607409776c05073040e482f44cbb125ddb6185a4b5a5a25268a6d20ee754ae8234a180ab6b1e0d2dfafc17f15059af347baa464c568cc44f3578cb251f92a3a50c68437aceee434a1ed5accc22b86a8655cbccf2b32d77c92f251f607ccd520ec9f0da5b8286d0c1b967b587c05be80c17bb161f2f60653f5ef27bd667f5098080ec553850eef6c77be8368c489432c0e0c954c2367fe1021bf9d170339461d7307c61d37b79384413f398e247a956401b3534b821eeb574ae886a4e66a94156b0872bc2e0820c0ec43ab43ea0c786f5e5023323fcd46fc049e914834d1c0aaadf702ca544a07834dc8198c5e283bf99637b6ccaa77dde5adc8d96d178957c8536ef3e9fa4d3ca3bc69161000f2833334a4c2c905d0116d665b9355580aab51958d7de6c55acd4bc30cf28cd60737ff7b7a053d70227208c109bdc609a6c8b08afaa5184b5bdb40a4fba0ef962848162b5a2e0068a9e15a427f4ea2064c83991bf29766f5782ca7b4d19d55ddf981e4b729d5df50dd664eb660e146f2be0be476038120e2ea45ce0267a53f666e897ff54af84d921e1ede6a8581f19757344f0e0c085afab7aa1122470c69192614eeef42e3b8a35ddd0dca40c19143170d5fc008d76323af7930a91d51b0a961e355a55bf8122bec63ea0c051561d0f4d585759a1ce3e618f80878169ffd05411bdeb318ee5cb1811afec9da8ad57a349f982639eeab87774c6d3fbf170270bcdf20e44a1a2d7fc784061f9d7f252f7d3df8f64c91717d7be8f2e9911c1ce10d53de5e9b9e23801a68b674793505008b0cc0bc3453145c65fea0de59897ea5f93b7dff98043f80e7842c9e0ab6132d89fd862733040526e7dbc1658857bf248b97f9a03a3a788b9d43aeb76ac49508b331d4115a1e91dd230b8eca25fb5412d432dd292d1f35d81325dac07a3820621376bac23660307ad6e7101600e1ab14319c55071dd18647f608bc3697119fa619207d6d6a52e75a03a73f69d31acde0591b4068a0b8f092b9bb5637c136ac406342e2025439e09a69d0a94d8b4d8b0d9445805657b160f3f03b8b9a40663c6109a6f222ae546436b4410f624fe80176bb360f3ab808051aabbfb38ce675ac0ec91623951d393fea00455633d4a3dffb806a7e9805fa90fab6d61eb704bf7e6689ef3ba08a1dc9944a18750530238e7546814172a651d2c7a8ce4ddbbc11b3e306db0dd5a8bf8bbf319fa7ae7989703af41086912dafd411762fb9f6e8deaacb777810d64437f28284ae6622b5b518035da643aa481e5c7e6866a976cc16831ee6ad65c87d3d3c595531ff8b3c2545c4228b0091a07b158f675b8622f9647d073b90ba01db36668a452816e63d5077b342c5c5dcf4d4875074bdd96f8e513d6d7b85bca5e0b21212f1ecfe906fbbe83b52e032d6baaae60322c0988a7f2366529416edcc5abd2a3d8c2ceb1bf13ac6bdc49717d6ec28d93921a2359437564699142d87f3a88457b015fc491bf1647b38227a5d4e1427150e9311ed993444838d7d354c3d38ea8e525c18b09db2d4860a2a4064d94b8e46812a5e8e8b75a07b25ee363e56e82855edd322191c5d81caf72c4b103bac8e5fe139c55d84326608d2b5c2b6e3327250976efedaa8b4af3f479f1c7ef7bbb0b63f00ffb7178f29c0c4164b854cca55fff60bed7fb4dedf55315533667cd847a2577d1fd9fffbc60e76f1d125ed64f22358363068dd9fab4d3ea33b8f04da26a1206e505d48af645dc3b217abcd6f8f54961c6d7909fa3182cb14ef493a0840c90c9e05800d2f559c41b15435e44d85e41008b439d9165f14cfdc8036409a3723c9524421ae23969ae0bc619a188723808311ddc783ce8381f8a6b6a957b396cddeac23ad157797ba4c995e7570c93bf5ff160ab16ac25686072f2cee14d1a40a0cd870788dbd743e44d076730b10308104639459938622ac73e243fc6442eee0973d6bde04014963ec4180e9800248d7b9bc3d378040bcd90dc9e2f581fa0299281431037bd06e45fe0f094e744b314122bd8b63c74ed3def6b531884a6475c09cba3f84c27edaa883d47b1a8b3f0f8900fb4039ad8050c12a2f79d6a600df11ce34e4b8597c49c19b8d245d5570a3d89d1d98700819e7980d2771c4ed7c9d74d7c8512db42b557d82a9fd703297c85817edc3470a69e95ebf9e6be950e2669d9f01610807ca590496fd0370c761d5c3e9fa21a378dbe099e22f382e779a0e51fc089d75dc2f92ebe3735ad1b05d9843f160ae42a3548ae15f5eca457b0e659f90177f503cb81cc1e01466d6764ccf636cd181980a68faf99b2337dbf2a0c6d53d535b6dbbcbf8be549410bc41cbdad89381b64ee3e8f9ad8257a17391a9a476857e94b3029bd2d80062d4df106dfc6e2537f131176ac6ac305c686af0d97575fffdf0525eb5af4bd46f7a06289666ff6d02048ecd4c353167f1d2f767f0e739d1254c116e5f739520e6c133c53543658a3ca292ce8d521b0c37552f75e5c711a4d4bd000318244a69f1b8c8bc5ca5b67deaa9a6c0e14b1db2cd017c3e90665f54b6d9a8c03e7737126329ffb166ca31109f4e1e319ea16b657362c9950755d31d7084d2010b1ed007c9d3e3679b8088b2e11a868cdcee8e4fc721a559f1f6032a07a8165fd874604a3227821e0853d21f0104edd08a5eb180e4a20fe2985ced1ce5185c6d3c4ea0918af677868645d7915a4b0453e9c10bdf65cddae20be1bd9e1f94d95b666d901594025211f2a0acb063032dea0a04ecd50df10a945ce846a19e5c954b82952f70b78c9e0ba3a2d096a7dc9124a8dc1b738976b09c710ba65f505429e521d2bc813c865215782506ba51072321b1aeb02f083ceec455005e94439809c4c440540efea96261d8ee18028df768e51da208904ceb547fbda1f91b5cdb85295d5fe15877302fe6077fa477c29193ec397ebd9880dff58ec82c5a086c484c6eb72f7a9ba25e3b7b16324c1fb202a3ee4de1308417d79cb20ca1b4140a601dd246900e4c8c07c57808d2a8567b2ada679827c24099ce9085e0637de75503d7476e2964b2e2841e26c9fd35bdf1a5124b4d139e298fff7bc26d74e882c2fb3d203346f2bbc69a86c2a481cc0b1dc4da4d99ceb3adaf68af0b57c70fc2e4af2bb2e54c7c52633711c7d57a9f2ac4121ccf6e95827c963bc0ac54ca73c0fb1289412283ddd2b78916eedcd89771084f11c229064144cfbee5088f3195fd3c4e1610b2aa99812893228c3ce4a1e8d25d1726e5664481f8dfba85ad3985b67b03cb41f46306a46971553c1328cee96a4b395802be10346320214951e3f373c81e5147584803c0aae8b465f56a3a2a0580204fb9dc2fc02db5f1decd77b28e0c4fa269b8a7a01fc1e2c3a50d55ddb862502a4378a36271d4ed626a6506ae4582c8725b090e4cee8dbec1f19db2fe7852fbce2a917aaca6ebb30a2a22a10ba4f903c8135214f1d82734f5909500f7f52429f6d9f5052934aa08363ac2c7b5c5a2cb94b2cf43153e93f41ec61cefd3f38c832f5ed0a70d7d17f541d84f7de8fee5da71b1872e1209498f13812a3d086b970bb406f8e313f4fcba513875c43138ac24298ebb55e0d466277ebca71ed0bc8f0ab857021b8aef3233f0d3abdedba33e65ff2d822d9966cf3132f11056d4ad94f66281edacd79aa255448f7189db57bbc9eea28e235dc3197fd3635fe30f91347425dceb29f38a405a1d52342ee647e3ad9133d2caa5d71e70764569085933486b3c3efb20587a508f449c2fe9b012da6b2d02109fb4f063ac49b88c609534eef20803c3b7ecf4e484f28bf3b994b86effd1e8de8031e21f36012d3bab71af740f9d3b2639a910b10815ce767613c1e5bfb7484f53bf4fb1e3c00539bd8991a61848ab45b3bc104509598e4d1c13075d8fc8bf4091e195dc18d8102c2688ee833eeb2352ee98fa2a683f011ab7b3f4790f1c70a6f51cad06c4a7ede8007c9f90413c8189d2cc95c449bd45f78832f992851580f8303b53e53558d849001c64522dfbdabf06285feb955e96e1bbbe410a22d842b6780ee436f10b012876688d4d6d5edede6bd3dbaf608ff8a3e4f64df9126237d26bf41935ce30fd7354a904d9c215993d6600d3abcd618c48e04a16e6cc73f14a986c1760df2fc244f6e5d6c225464e36b0f40057c8d86fbf4ec7e5bdfbcae456eafc426785eba8269e58b80eb2952f989c3305065d93906542347783666b83130758040df5ebd6d4c4cdeb316521ff514cdb4cf8a983cfc44d76f402f58d66c9aff8e7e47b77eb986951402303b70e80972d0ae2abe3f29a8a3c5f9809bd133c1f397039dd5b731bec64d5c26605dbbd3f3f781b2fc9702baf2bbd6470ac796533b99bd5a7e9e69b2187a3d6abd8b015b6f620c1ffe7fa5ef9a609cbc3deac1b33d4a6c0e5622c37c75899b1693a997db7245e3f1b5c109728c1e3dc309fce937fef442b9c7184290fced4944dd382ace819f561bd30366358426c1a45b122703be504ae6edb046b68027beb6e57d42d086df6cce1948a862e5cf60107e0f390f1ad57eff9ccb468c0a91cb6572c57a5687e12dee6ef9db98b32f0f73b5fd9c2188eeb1395a6f150c2f31dd25caadf8b083d87d607eab873f2a58f0f4624e365db6d32a474a924774c70aa4b20fbbe6f1339f18c49a8b3f09cde00a838991cc2eb2600c4c1961f80da110a5cfcf4dd9895412d05b21b23604c59ff51386c32224be557ed556b2aea2bfbb538ef76427bd6279f0284dbab9af7386f16ff47be6002fa98cdb84a7561e8c9b770f4bbc01637f9226ca1aa2a1d697397ba5bd66f0a678f1be8d2a8f401778033806b6035cd292b4caec3e3fc43fb3846993d1e77cd3989e825b4f23651667c7504ba0c60644f2652a8db08019d162b178d028bea10c137b8b8ec4a6245a07a26518107e5ceb1a73c94ca3ba5a96c3d34f30c2656cc47e550f1012c2c86b363d74e0e82cd04d44628c4ccac717a4e6a2c05d462a0a3b79944425c92e7e2992ab58d7955e3930dc976a74992812553c1654ea2045a573a4124992236b18087c5832902ba094234efbebc50e9475d3f6c14722f06bf7aa3c8b363d31768ac73953705e6b4ff44713f147291b8a85acebbd84102a1ff619c2da2d2d526aa52fa1a41490dbe134a97fc113c078fd378491730727840e44022d22e715f5f3018580f5e54c9d0a6ec9e0f94fd42c03b1fb5a199a8124305e7656fa2f969c810c65068f3c76c8b369b746f1825b08f277fa779ad055bd5712ca870b906412bb8032dbebf76a9854e54880c7b95003acd43999c60f9cdc7ddb2e60dedb38f07230ec27590c730df33618ac0d28a4012188091cc43f87bdd9e8dfa21610d51012455e235a4760bf94c4d096599096b93f2e0d428c117a3d73306b6034825d084a4c3d1dd625f881d191c2ca327d7c4b4405924659cadb7dc18700d8647c0d3ac241c9b22c094c8d9be099cd56f8cffd42455b87ba6a3de492b4f0f320c90ba88270b08854aa8a9e16f67cc86ac475648a22bdbc6ee90031f512093bbae46c53e8de88d974912add9ee73aa619c100cb96aae6dda1947074b1bdf3eb392e67fbaa6d674729d24868f423b3c337df0468a92255310fbfcdc225f3fe826fe6c39f0c3570dc4800caccf2c42378031d2707545fce0df147bf1f577746bca5fa0704d3e814b2c49831ad5c744ffe904f07cb82ab7f2e0a722b4afb6a1a2bfbb3537e5c2a363520723e1011b73a16fd7782e1d1bcad90e3f874e2a08457d0bcec40a0777593c078293b90411b368670d637f530a3758eb0635b4703bd0eca6f3f08e6f709928610a6669775f188f85cf9749d824990951d5d7ebb86548eaaaeb3d8dfb6472a0a7063e876c9c9689798ecbe36622f0a5f7fca09a2295a5a1e4e6fd128d478a890dd536fee0fc448863bf9f54868b6935f3ddf0ac5d7f18e88756c623d6dffd12aa95205f2b5143f7975efa32a3a3b99bd78600fe9e28296b79c25afc2b49e439c270303a446239f34f1b39adb6c0500afeb5d86aae24d45a319f969fb8e4da2f032e76a1af6091c88e41a8eff3f3c0e1223128bff1c9f0b5ba54df4d66685096f201b3cff91a5295e6fba04f2783e60315d44a06021ef15d4b593a5b1eebe7245e6d34c4c87a35774f2212f00285273455f1cba8737ea894898b75a5d8831a7ccb987ea3e30306ff9632450bd5f95bfc3eaf30f2293043feebf169b9edd103332a85c6fc782d3f0f53a9cc0d0b7d48055458ddf36833bdc968b3fa071252d4087a38f06ab25ad305cf193581aba348a9e120c001f25ac6a463a943a0812923e8fa1852240d4104c27b87ceae373a1c39dc3bff25621297caddc06397148084e080262e04035b81102c40cddf0c00458a444a4f134e86da6b10c4afc372b57061d7dd93019e2a78871be61067941a49ac8f5b7be5a061c793188ce5958d2f3478a2d99f0f70308681fdd98f982835ef4ea54c880650e0f7b4659ce458f884678ee2cedd273565f499ea4675b37babc6a30b1b75018e7ba7b2947604ae878cb059ed6bf04cbe9a73b977587bf0094cf9a46db6a56429a917a361886d45a24e3f27d318d0fabe436623c122eb9e1f62d670e61162d24444e7b1ea2184dadfcae40fea67fc824359d726fae7e4e84484dc6b9848fb0b285111601499aa698da2699250127b176226a791e5980ade1d4007ef4aa5738763fb78d86a38f918943d867dbbe4de99017032900b75c2a64f5fe5523bb7fa5c52f56378b69c67b431e3db21298ce428737fcb31911c5011d154ae862f24eb32d4e23ba00c6c714b1270e8c293727a1ba9063483fcddf09a7dc8aa2cefd4dbd1ee22aac7e7e4822b54c7f0f522e9280aef3c0280f7235e646a2fb644a43070855ed70ccc2f356e89e26f2b332a4d9cebc2fdb57840354e33904a0ac25a47bfb0ed5e2fb7e571bbc2a3cf539acd4dc0a956ed3561c2994c1a53943e387c18eada9520c302caf967a30447250e1384ba1da52b11b70c45c58fa85f37101321c03ae325f43e5948dc815d37946b67d0e86e1f249a20870af0b8ebfde632bfc39f391c04dcafb10baddbf2221170990322b628ca84d1c293ff4b9c9b10b386a2d522e81f51d7d9cd0fb0b34ac35b4b87b7291562e77e7521f689e16d6b46e0df8918a8ffe21745f9a1d6423755c8398a591e9594e55a82839718d8a39f169dc19ae8149fdd852b6ea0c3d4b666f55296e11328661e76a1041c2989c0e6252fe5eeb0e03574f867f078d5e30760f2acce3df26c40b75e7525d0e86f82a25a637b1316245d02bdc7d01e6e4a18c81ce678c6bd1a4afcffe9f7aa001886b218e4b9e0fbc6c5e41a983a6ac4649bf3e15ec0dd539399875de9106af0984566ab780a9b674e56ce41c747893aa127e01e4da7301c56dd6fe284a1b7652c49230a6b2d2c5e4d12d06df661e9090bdb07b9d492c338b0f0b45c9a02c32cbe7c44d9a464ccc8625032e2de989163d1e292c6d0c3c49f71aa1def0aaac15219d43001eb3faab9eff34c21cc0fd6367584631fb6073c8d4e3ac6eba91a601f9273cabc7b8f6a922197b8b2596cf5d41daa736c2bf5f0830ce7027ae050f0d48252230887f0a5d9cd3837a2bf8cb042b101e8837cb098ea289a8b8c0a96bdbaf3e4621c1e44d43498bde1cfde77002cea36ae67035ea139e1fb7cf324c323d0a0c5ac7c9cac54cdc34c89644cef2c34d1a685f6949bcf3b11847dbd8403ff935f0f41a2f7119305cbe37342f3a1c32e92b18fe1f41c8b095615f6c12c5ab535001514fd6357fef81bb236f1430a07445b9dc19f0d0b4da4a90acae6644daeec81e189d3bd407edf5fe5b037e46bfb8e5a36d110a2bff2100901f5bbc7b2f7041cfd809803b006bba7fc5527ced5d640419135f285b2b460be986c702b99cd2a7838f41465cc08181044222b5e44d1e22ff94c0790407bb7ea3fa7204cf522a7214706629f38a6da3ce99135a5b56ee32146098662f480de750974c94e7d5ad9c290bf876a286757f8492a5da9122a1c11430a58eac8169c4d39040f45cb32b2a9d806605ac564d8c9bc7afc7e51681a3107d774789939d66ce254413cdc700338505595b8034ee72d59c29020032d601f38eda2b0bf1547498b9595cca8e8dad09ccf9cc576268dd3d88a11f2d4553750912637754d6bf7891fc126aac068262ae20863defe9f59a430a2d79d39d9cd6c9696be8524898e6bda0c49a8ad60ddb709a3926209186693dc0ef0e2f94ec8d144a323ec704cb4e1a69ac5f781c9aafdf318a17d2f4ed1acf7499e6e62b6ff28f70c3ec1d0ea63f914be60365065a813f30fe2b5ac8c9432be30f722c9c47ec6a0afd755aef4f85f7d3a6275a6c49db304fb730676e51fe458f677a6e6718706c225b34018afd1ac878e0f4128a3280de22961af4e53308b6fcb1435db2df3e57a56bf1452fceed46e1e58f9951770814bcb79eadf3623bcc8050759ef922a9e491b2aa0faf9dcf1b8ec02cf8d78fd2e3870776551bd89d8bb1493cfc74eed3ffb70f3345e82372427a54901119e4942e436c78170f02482aba7d16c85ca7c29ee76d4d82b622656330d6451a45f8daa12f1f19042140074ae480f15c7b4ec2247df0ebc3414c2d749b0df40751c5c59674d5449ac435165a39bfc144aab64f9723dcf1b73c6425d93d31c5fe8def18f6b4d93e5292ab12938f5b5ae80fb054e62675ca45f69378621b6b889383fc9855e234cf81d3990b85c07e09e7f5567c81ceece66fb39a68ab86e30900d7fc4c8de87d133a3e2f09c9bf342e302dcc26d90642f11474ae380cc4f4420f1216726de3b1a2fa5b814e41621e79f61594d5b970769b8169e825ffd33f338ee1c0755c8f1aa88723aeaa14f07c9bc484cfae924e0976a4fbd0e0fa31ac248cd24f6e4bf0d903dc72e6d435971f3f348a9d79ade158c17eaaf626f946be9bcee8fd30c263ecd4be5cbd5767f87abd32b9dc8e3f1a2d2766a0c54566e60108c3cf4f3294671640f1679986b4be3680e101b4c01a9803f4796233986f3fbcb459720b166cc6a08a71615176481499b231f65864a55a4d3d7a6c332134b8a13bde01d31cec9828da817823b8e6e0791c7d5abf7ab1f08bd596ddc3d9151e094b7797e1cbbe1fe4b195ae957fa83586ef3e93a5a8442075a25aa8e1d04bebd80615c5fdfca99ac9efd0b08db9ac92c0c00a8c811d6f5446546309fc7f6f01099ce24a341cc8e2ab3312ecfdfe9bb3c95d924288cb130d3f7ee0473c4c47a2b43b6aec625e78615ea6e817d41a91d65b54b4c0070ab312ec326a838c2f99fe93562c641d09475e7039f4a807995bbe8b129b5f4acb340ee74d4c6a38b944ac8234bfb67fef3985db1ac967c02530b0740d654bb47a6c316193aa8c0117420da4e6c9a82366d982c729cfe450cedb6831490ced7066b27ff53595feccdacac6bff1c45a59c463eed08938797083a62ff58eb80c4a5b9437003a3ca039151e7ac7294cb2c8b0a9bbb42a82fab7dd892cf65f91dbb9c32ce3a4c0f810f6c768fd55829b7069fbdc95abb75036ad8f33faf29b50133a688caeada9d5d3b3a2fe012ad898ec222dfb73a6a504c3d54880fc934eb668c1c5c4f1171ddcb1eb039833c3788077a116a1550a3c7df7b0624509df4f62b008f42716134b58e432007717cd7ce7369a4db881aa348ad5a1322213226935a3e89e5ae7d20f38e2ccf108b1485a84f4822646990b206eea1dbbe711c8e5edd3fd3b0761a4c8762cbb5f6c20e03a5af6e006698845bb7153a23e8394d17b695e6c91be652721db59ba1ab0b9aa79872016f0250815823f6db195161756e62d8f050284a71a04f7f15413c8062407b2813bece3214819e2bd1d72f500ad3e35801a402e31affa1afaa3ec78b18ea6ceb6db6b8c6aad8116c79d0d271bf9ba215e43a13ddce12123d7da434f236783c11ca95d9474d59947ad6a1dcdb2d911a442e5ca35f9c7e9a49528a5fb86524940f79194f3f769bda78019de284f7570f1a89a0e98866820834b00925ee55006109ac7fa2cb9149211b922b5e21fbbd723a2e0de1f641ed401b01bf1f3bf272c147448605d05205ae4e1ce0c998283a4e7892968a54e17580da67e2490631b75a6c7c944a5f1816bcdfdee1fd5491826edd020675a2ecd867f29f5af04330b5abac3cb36d7ac2b3742650570829fae19f642b11705142400be19e3ed85d13ce3d84f84b4ae6dafbbb959eb0e8fc6027b095849159555dcb7c3fe622ee66a977785c8026811ca378a3439864682400847231bcd2ba361c3d056d89833a4151c0b5e06a4559b9f345710b6e80eb4c2dcca5e5acfad111a0020b549a32698d7a98229cea96516ff0460a35f5bd7318c39489ddf04437c3da4502ac3c267a1ce8443de6ed2773e28d512c77b4aaccf0d81c3395c0faa70f4d2393b33b5ec4ce755defa353996850442536e969c50ed4a1fb624a3263c4712142ce426526e6f961f202dff88d608cb1db9aadd757430aa7b8fa6ee1b38f50615b61142340f229f942642b0c290a766e15787cc52601436ab2b1c46db7b5613c7687417a2d02f95490f34c400b9232a2be9cdc82d7175013838c316924b0477fdabdf8b8317cdfe879ec5744fc2bfe01d1794ca04880cd884ebc7d8bd4da5efdca46086f5938d1672f8a965d696490214f625f08f7602997c6b31c1100c11db0f06520525d33b39a0795beea0a5a997648c08ecffc3458657c6c152871f6494bc2e8e207737b02c15a6e600ed31e344fcc142a38c284e616e7b4573903766c2db281e101980b5ccf693a6488102db6fed34c768902659754945069cdd3f817ad25c90216f602a23a788d7b2c8a60369f4fe6c8b0e4192b75768b910099dbdb21a64b441d559a4912c0456e2071fc6eed0862a71826b15f9de5cd38275e3f88a2afebbf18be605bc0b804a3d88187a56099c7c7a932d2106e63b664fdcb603b20b6603c2f5c4c0caaa4f31ff87c346eb149bcbaff06bb9a66939a5dea02f18aa9e35d8308d9bcea8b24054fc621618230b2a066b0673614e60024f813124cc10220712deedd76c102552e98924513d1acdffd11a27230342581c86b16b874ddecca9451e09da6fc10c82d1daddcc1937cb86d1a200a5856ebf796e209ef0c4ede08dac8f8fc52a1ced7afa853843753aac5d45ab2a94fb265f2ad5f0d0dc1ff452b51b7f9d41e8405c20900e299b5115ca84236552119c860a047706c3daf6d88a185db8565ddbf2a8f4b9c5dae30970d413dfcb8eb56da800c9325a1a4dac0d9c6204a55d1f8c1cd285d30bca7f62e4d796b281d2703d98a080efd2950ef483490778b6361c3189d101cba264509ee456e5f2008255977fe506181f57cdd565a277236b3161c30d3b3ce5239fbd2bb201d1a4b51e8a285dab55e11284c192e66640a0dbdbb6d0e386401485eb7f5402acfa352d1e189650c44d4163e0de741b9ce0fe3e50929208fb8cb1c8ad6ac9c84eaadbe4fc85f336b680d8b4672510db360d897ec12dd289339f098bf2c185f4a4a27d16a711e16f27c577dc05539fd6ed85e1e774d8a3c4dbfea4547c83479056520b2dc24dedf643b3195183e00c122029cf09268bf9453d5cdf527e71893d32884adccbce957bcd9640bdf86d715cdd5e74cea529e83787730ea6a6dabccc75e6309a57049ccae63f725ec57161d262ad01b1fbb408db6b4a9189b0ed64c374c2953e5dadab14dc256df146fee23aa1c8c818833f018950f5103d2493a731e642b2e7cf9157c4e62da460448df35f0f26afd61947b182a42882c8aa4c400203426302b943a74e776c3a8c5fcc0357a94608a97a835b762775b5f67ded67cb1234562d20dce64b7904026739b91a64655848c3e8ac34876fa10278b79189fd668a58cba7b804a911b011be831ac3eccefb144987a1e609f75c27c2f83b4c3ed7835921150abc885a5079c7b16bc0641111832dbaa09e1484106a93b1e1b81d58daea37928016de792fe20f7a4c7b3c9a8474cdcb2c63592e20e1b3df3cefb7a5543b85c294de1520d920d795d6bd444ff6509c2f2bcb7103567136688992eb39861956ca1e033d18ed0a0d978c760fccf722098a8bfa9e8d3186123f8e41dffb4cf700c33ac53f954369571abda491f2985dab1c704b5a6ada56723832e0348b71006aa136af004e22e5140d1035517a05d1c4e89696d18980cc061cd2cd52b400dd1c1acf23f197ec354e26c3b8e1c664fed7481b35e827e93f8014047414b2c39a58a7abe2586b5c0efaf77b292066078278057175a448ec9c04ba7baa9ec3593879eda05f8802ef6ffaceba6d086d219c039fd39147483639d39481ec6178adb81a17140e21ace6cdc675fa1148af936fae852a32abb4548e47f2c5a65b3e680a86f527ddf43cd6534620f6a01ae9c86622ce469e98430a036b6eae9b5e9b21ec81c870789b7f5f038e7a5b795c5a17a705443f1404125a5e9b5f787aacc7ac5983f9ef3cb6f7306e51b6125b28eb034a4dcda79025d18c5363d9ac7f6421a8c086a1e3842038689e8456b056fca74131836455a1f1062927d1cd7d4eb8314ecaaec559f6a938f5a49573d6e8f8df130fbbd2bc76537e9cc0b5893ee01f3a4fa0651ae6780439c23911ecf7988d9dfe9e11ed57067a80a95a67de7beb1d863ca2c545392aec0f280fde9994bc19da953911fd351c1ec62b6469bc27897e371a493d45ad343c0b26db47d91f11ada2e83f43b6a066ebd09afc973a53af8e97b65658d5a903a48b6eb66190630b5ccbfba0653ebb8e442e253a70b37373c56d0cdf60e1e34005a27a16511711cde786062552ac4c8c9e0746211275f652f01ad0d49aea33708db1579d31f2208c34c4aa62b4d4c87ec53080ed41b0bbef2a2aa0013184a6c76bdc48a4d771cad0f6eee948acbcc66c900fbd45c239125c241128068cc49e47534c5e2fc13c9c8f5014b5ec05c8287cc8c96820921648c8389f49fafcfb3feb7eea30cb336ac8cde74746a32370b322daaa9648f3bcd5b71193647471580928ee9f4aef623d767d415a9e04e72832dbd5e1dc554c3c3edf2e357a5b870427df5937cc8c40d5870779d57af6010573773119af6ce3fbaf9f584deb56e0ccd1b032f81197f3e2b2074ff004152a9cbf5d48f55f8af4431f1771c61221e60f01efaa06284b8f48c19eda3b66d872fc61c20b8c50ad5e869bd19a724c46db0b9ff87b59f326b91689498b0439a9583eace2c65d15533a8b857e4b281c8ddaa999cc8309cb573bf830fe86def6328378b0853cb60400b94f66ccaac5db9c18b9dfa0af7da3c711e3dd27f91981b4aad7ec6df71d472a5adddd80b8ad816703d95e7a6bc56800772110a18ada37d320db75163ebc80bdcda7c541ad55c4140b33061ab72861654ddba1614adae42216869a6a8adc73c6b4d162a823b1c8ed818520d30a010da0bcf1e518a56ab1c7ad96a497d5d556aa064614fd5c2fe3bc568978753d33ff9184a39533d099c0a5bb76846692e2d3a7453a7d203df2a1e648dd63f64ec37e78a8b072cf80e742c5bfe6577ed941c6e1782ad5f52e1a2952bd98f0277d4b9161e8029eafba4563630332adaf2bec51bd43948df7c0e17796901130f6435d618a6c92c73dd17b032c0ef475c6eee063f5756b7346befe166124a524d4c7a9269dd5a8cdca8f26b1f595059d7f0dbdf728181b6c493f8a14ec97e487cea1ee6cd4323780767160893840f189051a60b51dec87e1690e44523acc2dcd4b7008f386d04929061d7591448327177d5807686af77a83f0131272d69a619efe823f18eec0d864fde2a08f13ec0900a82e20ce869ef06f1a60835aaf9cb225c9c40bc26cb375b88016d4c367b289adf648f64f6e4c909cebd16cbf66bb5c2ec87f76026c87539abd6dbac47a6c4054a39b4289ebdf1f8b818502d13b3eeefe075be0ccd01d2a96b186db80d79358c754b14ed1665f729607e6a429ea3e90d32289d2037a820e3fd10bf42838f551253d99f06e267dfa3210b379e74381128116fc8684b6fb9a0f5944c502a684147dfbe74f83407cd247e337ba131141095e54685a442f3a27ac67bcc32a79d87024b9bd6c739b464ca4e1b985fd088208798eb04bd852eaea0e3ae0c562191c1b86a2c386987b448105b498e64ada3903716836f17918509f24fa25d1f11674e0d4f53a391111058fe3041b958cc4a373c82b95e18a41ea9a7db0447c8bc12b917f575cf1aefedc5dc5207755cb76f56ced2a80da0e38bbc2c301c50855d8153fc4f145420eed62c7ca3366b142ba25e83e7f83083ac49bed7bb31db995b8171dc43a65f09020dede520bd5a7cd46738a8ae9ea4a39dbef6e7fa18d1a9f8a06d6eb1f613d290ae095f48fdb0cbb3127d8b9786dadcc0afcdf1f7912d7b40c36f4737c224b8dfd5f3633915975c0215b93be86a8493996109af3fa0ad71a1489c3c11aba2e86e240887c2019a259526c243f57e18d0d54ffe9c7e84fded5510b1e46b68df2e4f6680f16da790f9bc3f0bc13635e2e9c0c41cd71645e05d19bf0dba49079d7523563440be52fbe432354360f1a1d9085852dce8c67bff2d565f24f0a91d57b5d0fcbe40aa9398e78697217cb45f6963ded43d6086f621967ce6ee8c4659ca07801be648da271749027c332700c0e2560266f4ad94778041028247a8a11a0cb84e1e7f29a3153322b33efcffdf5573f8d7732d6c803c352318b3cf4d5dc8f1b716c4cfd23561a52fa15e26f0afe85407d105bf94926a3113ac997cbd266bf19c15d72a6b3418a0ade70e024d161871e04970fd7715d550607e35ecb6360eef5f597aeace6ef2508cdb9d7488d9a9e5e696aac1bc120773a8c6358a2e1d3459c6433042f7e5028acdcb89129eadc1581d3a2e2d3f84b154d5a3ee469f5dff2a6d158bd2143e55a61d0db50b1c870de5c3c34b19c3a380e28258fb48a08ccb458250e56b8d4897a014289ee36aeeea11eaaae6e9c2644d5050e86fac327412e6183cb45b904c4133b35c1273b35f52393ce28f83f3f522db290ba1b0f6f79d9ca8f5a4091dbc2e8c7e25be09a0be13b3e5d28dc3053fa2a8230b0f04fd155c106816b35ae2185014bcc10e0a990427f96bf1fe0477c6c47c481cb20e5e147ec7fab3c58e321aa8932b50df59fd2d0baae5400c9b527abe088fc55bf76eb4575ac4596c52f400359e65ded269f961b0442b1ab0c2ecce8d9ad079891cc0466c79ccc3c3a323592380cfcabe6de77868414d846e59aa99ea72500a8bee4d7e2249c06488beb8529983ccfa4b0f8d14a793cfc4dae4160397ec33fee08432d77f3d0e3f79717c17844f97047f5ab7cc2759d39753c818de64bc021464ae47a251ddf25430edd1cd9d2c33f3b56f814a8c34b13203743762b47cab28913096042cc25aac55ccd2d72ad3112163a026551e35c9130b5668d8be0f4b7b9aeff97706244746374c3bfa2e1add88ebfc1b8796a16b3b307e394d5d4e759bf1a80d30358c6095979bbb784ff6fafede4a02b03e373456bb16df0dc10406d86362c2525ef6c34fb0901a37c70a3b861b899ab495119d0269ecb04022824cf4f810a750b632032f9de5b02b35fd8c7a4372e1acf0e874f12a7d06c998415c1f15c39dd774e338df5185caff419977af6633188e26a92a01beb729ac90e8f010bed0a1fb65f45eb3d4ba264eca084501d9f41e401a63e51ccbaff324851b8d0a92c9285d7aff3e9775edee00325210e5214b8d4c02f4af13e50021210d6ace834200b4715405b2cf28bc95f495cfcdbb9566077134ea896fbba6a8c3000a59d7b830615b4a2ff9ef8f19bf59dd230c52184b52f466207111af8b2f87913fed05d11c5e19b28de3dd1aab06e13bd529122d0f14d68d5ce86dbada314b107b9bad8c2493c99ce3cd57e053094613f0e02b9ae4772612417e5e3fe08ebd32d089c019ddde7db78ae339014604e302fe742706eea5d83c92ce24b713893e7d91151a49d84f82e0066eb446ca003f5deec166eff1de11fc5cb8c25b2aa03e39b119444aaccfcd6be4191cf5bcafeb7075e863ac28f07c1e61aa4a7e3a0ba9787e9b7c1320507dae6581082e0357838953a9d9cba224b9eff5872a409ade803322e1943ce745f684afd858f5157833afdce8ce7038111ed46dd2a5c1d53f8c26e4010cd709d1ad18eba2c34bcdc6d065a77c1f2469f5977fbd3d3ae36aadfc51723be6cfa9a8f20e1231e43e6c81b843f61af73d6852d2f4d02bc4e9f0879db65470daba140cea661e432ef73fc21f5f4b071b6d2b1d36a03299a45e734a04c440c711be7c7dd6f7df4390a34026e9e2941641505ddb8544259b626dc90938759e969400e43298236ece48a955fb9cbfcbf3bade3473d154706cb331449576909252859c1071d965602823093d0ef83cbabb579c231d33a34bce7e92d94ef263889cd6cb69f9521c216b236d5184902533bfb39fcfdc2c64ec420ae07314be27bd6caa088aba191ba76dc96d8772e59b9cd8159b0b003dd152240182ce29b1c4cfaca71b3fc0391adf8a5185a92afb54c90699c413e5cc92a10b4ce11d3e6ea956fa1785dd7d5bd4d7728d0367787cecd6d0a9ecf1c79397652ba19e2baae4b131e98a037707e2faac581050231920964c6db98ca2279a5b14bd962ccce2d90614ee5d75b99076abb1b3a417716f9a9ceab28d31adddc2508d825823cee80c943040b8c1ecae6e95a6758a702f0182803a8614feec4ec2546792af032aabb222de65dfd83726097c392762aade4e6b64db9922f81a402eae0c4f8b59e987e4d1d045e3dac6f4d3241d7f02d8be3b4824f5552db334c1bc9ae54d8ea11293fdbb3eee5b6f63f9e33fe204a9a3ddd31772b8363e1397376bcd485620cbf09b0350d677fdb90c979c06c580c2ba2f4ea1f129b6953e1c4c5f3a282c12b4384a44ff071d99f9d7fdecc43e0961e7fe99a42fe31b330242ab502697bcad832e0e0775b2e50e956a8bcffacc599072f65b0e1f5d289908058c27040dc5af3bed701828f4aecb1091d0d0a662278fc0901182251d53c308476f2928c691d46d96d96c04fdb25e58387f51a2f5328e3690d80f6bb8215f5c7e74d875aaeca112e98bfb315cd5411c4cbf5d268b87dffdd719d93395602952de4067e2bf1ad63b17da8b77fbc41d6db21b80a39f91454fbaad73a073cbf1a596bf9d006cb312951115733909b208b6ef5dae64d45cac2d14374e86d56025a595140c8b229366811f66394882cc15cc220536caf306e19a23c2aa16726581f1023cd4b42c498a140e07717bda289e6c0c0aa98fc930ec983cb11f795248054107a1c4fa5b9f2e00c4d8fb3e3483a970bb39480792c0159baef24862be36efcfaf0c8ab49a98c1457f216a906e309dd2d069af524345c46241b7910a57b5832ca1b0f12185bc8515a800426ada554c9725723a8ed5d4db2311cc6d91c96516d208aa373ddd342aa09287fbdacf6db91cee6a256d602e8efde60718889dd4bc1fa391c7d10b61a9b669ec11ae3ce04edaa340d1362f7408b11d80e96a2aa1e3997e46ca0f6b80c2303e5277f9127065791f41e1608181c196152e8654a5925f20dc29db2888d44542f3d9224d2928d08558bcb64e5709111bdc8a90eb21b40bac841a6ecf4bab81deb800308348dcb0f7759014a8cbfdc2496d48008fc424cd53bd5c8bb12f00426d465efcc27017ff01117df933c307902c9b1f78ac7133cbfc7c90ce9d1091d866a23ef1c293f920e49527c054337e2e208528e01e728ca7e961c687fd0125585d2e73d4d2e5d7df3e2cff1ac45cd181e9d3c610bd5827df2933d396e8bc2699fe62a47df4b7b8d12250b1ce7fe9e18f73d271049457ade970ed5cc104cc57265f9ba434adb9a643c83b64fb8f972302312dd8745e27ddf13882c440e4f371a5a58d40521b3185e6f485017f08c9fbfe604300b98f65b91228614abaecba29946dc6457feb041529d534f673b204cc23b928d35d029deca04ced28f2a559ca7b17e35d4692baefc34c6a2e7450b25235f2ffac9aa0d9a22fc2b182431432129ff1b3a7e23050b3348e918802ac38cca7eb31db7707fc7123178fdf80a4e4a2470d26552120ebc1ba9d52639d0c0e199fc09153a85aa96dcc3da16d548c2485653793e6f0125448c48dc35bc76900583dcc12296a0f58fa2dc4c0905223011dd11bf62d1929604438a50a53b50ea7b6878cfbb4904d34584fd378e23156008079cececcba84ed657cd5eea3cff2898a0e69e69b8702f51c34faa1d97b9b4aa0bd7c636c4ce588dd62c9058ae58e63123a8e15674851e544530feef100d728dd92482a50128e893e8de94aa0741cf2f6c72f160ee97fddf9eee90103881ef6d452c9fdd371ac0de3c94a80762f6a48366be712a18167b548cd9c36ef02e8da62b5199b57618831c777b6e146ad30b88f05511a35c5eafc6991bbe70dd8f823acf858c6495c359908e0ef0297c9eabda5240028a5580dac2e10c0b866dcfa99d9c2a01d1083a6233c89b3972f3e6716b3d1dc8e05108129d15f96acc17d80a3f2db88f02393e45fa1469ea992cc18af2ab43acb03a9ef935e02cc8619586b5a61f3fceb0d65301a088ab351b5086b69a39b38c9a5f6cdf5b197df13bdbda154a38289bf7511ac7aa7938b659c04064e4f62b3cf0a18b4962f355f2c30ae04ecab0e883103f929eb7ad12c5c6accf38ad87e379e8c6bb267182ce99cb325c981906915edaa431a30d3f04239837da4d478f147e168efcd7567a10c19b65d99b3c0791bedb13c06bf503427f6cad44c6acbf1dbcf0f3f7ad2f0bf73c29e3f554c2c6c0d08339458b24ef50a50a75bbec178c7b122099c66c76da55f7bd385e0a9dbfdd5db8888c00f5e495c85bb7224477a30b529be5ea22315c87bb08dc4ba9e5aa6022775fad43c614ca8c9f221b132c48f0c0cb09b88aaf2a37e823c83b0763fb195dd33f8a3e882abf2ce06ffb7e0127dfef582cce50f8360c385ca924bfbdae1d37286c66616bc52a68d04d9255c5c581ec04d3a79d33d63ca75f834c065a08eab5c8b1306bab19ee1880947350fde58a8c6b1679b97f52d2010996abcfcf5c603e627936f15663113962829c71de5e981e2ed24c27d638e841c20bf50b505ae1ce6a143c264c6ad1c1ac0472e3a0628d90434210fe4e411013d02863c5d7b6ee606b56de43c817073d47cb7bad6fe623b027b380b449762a63bbc0572120720a7088f3e6d49e6f1fdfd3a7f3f8acebb07acd3dd8a7638720d9cc9e9cb6a5d6cec078f21452c31db6dcc89b9cc50a0e0c2f04f7e06438f96d92cd814a3e26c51e2cb3360cd1de21f366052350b26179e7c9c3760e56d4c36bd0d08e0a8bf68ddd3b0d810540ad4e01d06a0fbf08f9094edfd555806d24eeeb2445a45712b74da867b7cac839d5734b41e535dce74dd65b340fa12051af36a80d6649e6760577b8460eeb42d9ab0d6c1664da18c2f6950f4eeeee272a459e42e03815c8997ba9c44891a2adc01ce0d4c5d8781582d0abb4068f53b22a3d7db28ecd97db37cb3f65590b1772af6cc9bbc72893b7d1ee3a94eb2930ecb113cf02ec0ee2b92d85f244d9b31a8831a6c2316c60bd9aefbf168b121c3caa94aa3d94f4417137a16afa7faa85c522d34903eca1ecdc503f7acca8283b0a6b8c8a44d06dca87ef840ebbc4123294aa6247e8ff64051f27849d02856c5c5493e5a01213159d4040092e12bc5dee94c0f123b84838b8d4cce605a071abfd5918395bf426f100683b53b59cfb2d4cb86e722864a27130084e72f21a621877ca148c8dbb07d3bc3cc7e2fdd1c76a9585aac21350d127a13b344a771bf19e4cfb08d7d0adc1d9829375bb6e6373eb26d1af92be8832c49a1c83a2977fd1b85114b0892a826342122834645f258b13454e737286c688dc18a710f18c12210ccf05e012888ec00f76a6d5ac3424e328105cfbdf5ab2afceaab1f4824efd148dcb58026f7bfad7b818234f960fcfba985abfb0e2db7deab62b6576c718aa41cb03cab2968dc91b2449022b16c16e1f36465bbce9b248613134dd1e67de1dc2d88360a5a3790c247e63e801d4a2a7f7a241bb332005e90eeef3d027d85864ee15eecfdcf0f7b107befd584711c4825f2dc4ada607f46b0551669dd850855ec224127138a12e131ab93703829833ca3d93d60b3e188aede330ab6dcd7a024378002b3f537eda5184b4bb25076b66d5aaf594c520e2e183cdc8ee377781ed410d73a783ba98ee462dd9a652d44913594f781d0bc68d49825067e1142ec09c814178829267a07befe77950753410433ac311035675c49018d4aa64b45bf777f6f62d7202ce792ec3e81acd63dc14759e67cb9adc59979e6c1dd1c818a5bbb1aa5c598288e069849b140b27d27182585d9ee6dd350c4500bb4cf890b58f9bfef37aaf3778f217fc5b644983398d3f7ffd43bbceebd3915dc9cfb8720a304207471c7b0030d117ea0302a2df6170460661cdccc72794bd72e8472db9cbd597dc5826703921dbe5dd4f689c207e2137538adc719841ce21f9e0321304bf6dea11619b416c3870a0985d2e5ac356ca333a57efa1d8582e5abfff2807caf5dd562e2107d15d1dfd263dd538ac5431a9340de46870ca01f3dcb2e9c043091724f93171856ee2f75c17b721b5761da1c3ee1aa672d9a7289fa7596a72b70724c320060e5b71beefa6cdc76a9ac10d31dcda1621c9f226511cff4df3d63f61353d74b858ee675e7b98fcb72611bb35fa1f1f1703dd536daff38643b2bc1428d9345db9466e5806cc4a6b4f4182aa29109926fcc9b2d1297927c02b342852415c487c6c9880d4180d2aed04c879275e4d4c713544ba40b3fa87b55573d929a12ab77b05cc17404d939fe540a8130bde1c6fb41f585bbd9cff51df46ee66250591140287240e8d38d90ff4fc3ef1fd95a68ba72a7060e89f8373b97793cfe9d53df9c7e3090fb45e5a5ea6115e40dee700646287ae20146a87fb41a3ee8b0e62bc3d6b331dbcc967ad345f1a07cefe5878379c221c11e21f67a6d650f8ba1a99299dd0e12f73a514e9d9918f9feb905cbb204faed689fe9d9f1c6dac1e91af931810e4641209b35daa460b03e5c4b63b9af3cff40263cb5b6050cfd9d4d82e9e5cd103d19fbac85de75eed398223a73a2cdba173ca1997a397c43b0a0ac4e605fc60565d2fc78a8954208d9a22582bec279c3af916828e2ddd6441fd1707c387d6026a1d3d188ef2643c3a29e68ca04c0dcecb1189348e2679c7d9b9098868b076b2290e6ff451c575480b8c16ad2b9cf2727fa8969f7c497fd249aeaa81a4851ff87b0f4fe82633823ed69aa0f4aea506d869d0897ced1a38a222999508bcd8f15505e06340619c72f0d898070b2d948a284768642951a5fa1d733982b8f7cc102ffc39c20398b7cd2880dc53e90c3b1096aba5bacce28b763408f2b18304794cda8d4a703449ffb3fafd48a42faf9f69ea7ebec9403f083332fec20184374e95d766b810e6edc229f5da965123838d0b93b9a82ed4e2659ba7b4be71fa919ffee6f61b298f7da2058bedca854410cc869289896d6e018c6d5ae41a4e850a9ea016ebf589213e3daf07876b89cf5dd370d23b90ca5d3ec717760d39641297f339781f25213d375aa432bf9acf7177d499730d93b993adc97c8f4fc462780dc0c65199c7a18b47536398ce14b47d1103ea28f8a897ff1b736009050222a2d5d4bcf7192e35ae7947000085bd33637ec2503061e09b3634437de1d822c63db7af7323bde46df43b808ff79874a5cadb80e82ffcd23ff1c76ab2aea15149f097d7912f84f485d10618a4afae7a1ba13d33761f40358434a97d04a301805d9092c51f7c2c703c2b4050f564058018e5b489803c8e0bd6d75b46b3bbe287aca3b3606cd9dae24511c90af8031d30eb3a70a20bf70573d37c5519a28a419524c7846a6d0a7ed2b4029a843ff357c776f7a5a8157041ad7015a21d68a1a1e11bc42aa37523a7301143f8cb2f507b8116cb11e3a85298cdcee4a8bd803db3a3c3d6d9dc9f070cfb3346cbefc7546445c3656a8877971dcb72e534dd94292d85af69d4312b9a318909f6a930cf57935d780b9a5037db0299edd1247d7cbc1580872a424897e482d04636b0893122f45422994e4015a2f994303e82b0980b50f6c923892f665483b9af4f905e95014dc9319dada397cf473b166a030e128de7766de7c1f40d93ac347f9456514c030c02d002de987ccb042b2d509e03a3faa5a2f129251a9f355bd00aece6b456053887ec0376d732e97b40cb361b4d94838a0738090fd20b85990aff1f5d4df4900114c0e1e43e40055f0ff40d4049f1dd15be3b0be0cc026c6d2e2e70c5b08b56437a606f91dd1dadc5fb9cd822bc754415e8bef8a9011da65020cdaa2f0b8244795a50c0c5550f31a9b1225cf78b2759746de6e4effb5719d843af419fdda4dfd10d43449b3a80336ce552b812021de4cfba6b8690e693b889f82a7cd3388c83082acd51d44a3cf70f69152bcd8b0aeb8817cc10c698d2ca74a2b599e144058a4d5475a709c67744addd1d29ea412222678d577fd4b859ed6201bcfb9d10570e346fc175ee094f038b85fc0ac29fd4ef4cf1d8b5ecef8abdf29cecf08b371cf91d581bc40c0d32c7c7d76b231693763942620f12a91222e08fe6870c1e2c79bc3067c74e7b35a0fdf96604f0fb5152c608cae26371a6f2ff066a733dd626ae1b420026222c3a22cfc49754d413d96d1a51b1469aa2e23081a5e9bd116d94803e5b03eaaa0ec843840f5fda33592723eadfb1fc89cba827f63ec834d6f940ab7c458e0f3ddf71e529427b2aa4060e3806302c60aa638cab9b078a0e5f000e3c5ff9cd7f1894b56528b8f3d9c59935ba22a9bfa2011346da1c313dd56c846d62ba11ed35dd376dd9f4dea44428627c650e4bc7acd49ce4960d719954592c215c5f91947c85ce9a0f0dca196c9adc8d9111ccc1de1845a7340a0d4a9d341374a5c170d2e6c221c349a9d66ac54cd923812566431f9e8152c2edd0d63bb6c7336222010c7e40737fc34b49b945f7cd9d1493c273ae96b07e2d164f94fa4e458423afe2ff3f82bc1a21d6310d4dc51f7ea91d412bd941ca42d493c8036735da9841286937910f9cc3889115d1205cb868a03e030e2fa6ae78e2a1a11cbe0a4706b0f6c381c08889698e383effd424881110c58044aaf2e9061e9ca87f626f480fec4f04ea98d3b7572092b29a0e14f1df2691be54a7273f9211fff7b90beabd3a8013d7358a73bd18bda74ee743039f8124b5d668ca5a478d0a29a2450e2b0100ed6e3254b59e5757da31c28adc5ef9c198cdf3877423bbdb967b4b99924c01640bb50b620b344843322ca129aad048a1e50c2d4f5a9ca4a032b31eb090b024f54009e98824248efa91130f335b7ca05486d38c8da718698c92a90a21a54be9b2c10f4e4e5801033ab22c608e18a45839024b185dc8a257014687279cd8418a0f186278e1c11523a878830859740984cbdb2e6aa592d690f59206447031d425891d6aa0814cca99afc272e8d6a68b710ff8f630e6178bef1809bb4bcb64845f6d6485b4f71a953d4a8ea272610c49f0d51281d58d1d605fed3e7cc8c87ca8427d88fa50f5cd51d49520093f547f23ed48da59684fd2eee4840f8c9ebdbed857f610ddb489a0571afa0dcf9d04304a31d55fe5963480117af69a58e34835f4188e1a7a9e17866ed10bbb8a6c4a91292eb122d3e67016a73947b7b997da462c35fdd07c56d6aca63ed1533d8986c54f308cf998673082f27bfdf7c98fa58f606c92a13e8122d7983dbb07238ade43b8960833ad1076f6a589c397a5249eb58ef87ed2292eb9968084868a8c8e94965c4b2ea727a6265eb261555ea286bcb4c437a17b719bf9339978357ec2fa3ddb23c854d8c55fce360e35649f9f2fe6f9a7890fdfb4af83ad3e825906f18c6761aef82c49a7c22f76ad4aed226a7c6217659f98d44e54c95ca48bd230690c3d7b903d9a2509e3a23482e9a48f805fec928bca1e6fa8ec60bc6d72e3d9a5530c83057b800dab89cab3d77839a8a1a45ec8e9f1cb57f6e770bb93804617e728996ae81bd96da4dc4117656b1332126800c9a5a10f25d003c92a9e18faf2ecbcc4e66b13caa3670fa2c518679c1f0c1c32638c73e3fafc6c9c97605711975a430924813ac651f6c54e83500e43ef43e4a19f29518fb41b74dacff3955e825fecfca5863d54c437cc00168a240cf5127c133df6874bbc6f90836ca87ce52395389b016a9f09e29bb087866658886351b65b7a30d43eecea9eee79f60e88af7cecf9b087f88a10c726161ef2893db18735f34c46c7195904248bd8159b427388e513b20805a1a267a10e127af60e6a21af6a3f1b0fba1ea2d8be2b71c2f621ecc27150493bcc0baa8bd3d2bfe8f411749951e50bdc3d9ee1861935f4677679334c460d61b0212b8fb4d4e1ed195a9e5d6a3ce79c923e81c20a6097375476ce52d967667413df84f1e9698ed16e3481994c0d865fecd38a1ac627c6526751c7ea50189bb69bc26e32ea571ff58bbd09c6e48a4ffeacf8149f96bab0d20a31ea174ed3b3e394307ff03e7a6110d6962f41cf5ea7b88c28a4f2ab5b672238c32e76b1b3f71c9d1a26840f952d66143d7bec89f18b3d3eac00f659430dbd38633d370a333c8b53aaed619cb1e26c3f865cc7b34379fa1ea2a63bec9ab102d839196af5d8b519d57086e322d650c37dea5913ab9e4ad4decdbbbbf2e322ea13283b7c135deec42fb332ae3c3b9418e7dce283a3393b8c33283bec62f049fcf2ecf14b749a55ba286322ea0cd094678f416478e966ece24e8ad14f1f325018c17c283fec9f1e8e5516952bece21f312a0ffae7abac5243a642857ff66bb9cca2931e473dfa31b8f06bb7a85d585efc8b0b0cecc770835f4b86d08774b77876a6a5e85ff8a6490cf3cbc5e8e810d4f14ce9f775acf4f0cdd26006a3df3e217e0a85f8ada30313dfb4dae337f85b80f080e843984e9dbf5b7800c3b2ed79edadd3f700a1055efab7af65ba7d3fbd5d82e0eb140ab20735965167181d47bdeb8ad6d65a6b4ddbb63935dfb44939ca1eea8a76cca890d2198f5615f5666043c018a276dcc54faa0714cac9d3b2e2943a15e5420855476ae362c62d5135260ac46a2a156d563aa934d37c50dd346167d0b047695592610e9e393e0f813d0c67a861fd85169e4771f0c303201e08d978f528a595e53c8250995121e73b10c393cf36cf5e43cf9bb94113a51da8da1713a8315c5aa83f7eb7ec208917c10e80de9bd9810fbff6b71dfcf06b3fa4286fa6e6fbddd265c9660641c66677c15851722ec1b0bbdbb5d69aaed6524ac975ccc6eea667042604932e5b4aef4f881aa5f4d8f5491416b2bb89ba5e440dbd5fa75348a5ed3b52925258cc3e1d8b43f109e53164a18fd1a79498f49b149362524ca2cc85b70039895d4d5c9e62130519dc641ceabceb2f826962576c50f66cad29189d36308269aa124abf62ab49ec9c9d5860509fc70aa028d0773a5f59e4c01d0e4ac7903c3d7d442eb4e035293d3b027e5312d09ec812e6eb4c8b7d6528efbe16834d649cb30fb573300bab5fd1b75face8483a86b39b466d5a223e9e888c79eca3c7a6e8149f66ace445e9765e610ec3090284e1c5062fddf5b25372f65043fa4b3738e0a52f69f1d23de9f586973e239da5832e5e7a8d0ecc78e936d2c56dbc741338c6b3d96c66c34f7f137976fac333e039075f3c0e184ccfac2f83ad7cf7b58655036e60c8ded2cd511c846fba2d600cf1548636cfbb4e5d351cb3e15795f95e6079f54e7ea16515e32be700ab6e3da0a807060d2a5f59b7a994f3f858de7d216c27ca643c08dff086f2986f27c67dd8a0c020ec628ffe78cc477484c6592e533ab4a5428cf3f02331cec307b8e3c3639c824778380bdca1711ede29ea9d16a36365097008bb586908bba2525492718619e9f1016ebf68c0ed57b7b2986f653cbe956df593f1d5b7437424c6659c87779bd77dbbe58b3a9e7ea9df140af15b2aacbc3a51e73cc09d1ebef20e3c525d06dc89f19ad2e9f8863bcf6b7e5043160b7476b1cb944e471b6471aa49fc13ac1076af9b849fa5f6669c3d9e608974e013eb2a0fa312938ec5226eae2d674ae3218be5a1fbf0d0f5c343d8f7e3db7df9f83a677d9dd37c3c3e99af03c39c8ee95ce5dcd319a0c80b13c73e197b6c628f60d8a31bb10ebed92d601c3d3bcff8c667aa3a261d0bc139e643d22ff61edff60bd56058db2b82b18bfd8e4a57b0faad0c15c2d743147a3df899af874886a75f68c3ea206a1895664f7d0e15191d2529fd5c7aea32496989a9c9e909e8e58ff491b327a7a6a7de4c1b5b9951d19010d0cfb7cf53ef190b6d6c6543454647494abcf4e4d4c4b4a49404f4e313674f4edb148f58d8d8ca38a147790e77b4b2dc050b71729a7e9c775d93edc3f82d2cd3a336ce6317bee194bca89ca5330cf6a855e87aef5707862857398f4fe6db8ef9ea97924e3f2d453fa6549f4a7d5956200c301991f428650a3b1c1c18cce57267b1288ad2133adfbcaf9d7ed3bb907f366edb569ec39f65d54b5409a6864b602feb0d358c4a5f00f1bb1e97d4a8e192e993677c50bf5ebb28c593e2cf8e19a7f8c304ca12e98ef948e9530af54d7323abb446d825918047d825a5c72df846ba942e619c067bf9dd07e563f2845db2939d6b9ec34c6e3a50765bd781210ae4c027ec92145c0d0adfd4972ffd09dd18bb4b77d7ca951b953431bab509e31153e55f57fd1af9cde717c276a28cbdd3901a8aa338df79299594ae9272ba8ccbda32206b5fd22595a0c4a1288ea2507484d917331447635c4aa95491b0d03176e91d448d1ee230192f3de6ebf9ed5b027bcd67c74c6f512a7c13e24c4a632228b13082241cfb64d29974017ae94f8e64d27796fe7bb9a5cbcf4b8f3ef187e93671582f6378096a9ae673e2e494304745d2dbbd64997e4ac7e9584db554606f27d27ca79dc1d6f4951d59790577d857606bca68bfa474b9496204714312685c59030b994cc18b0d4932b011870e3ac8a4cf125266d8610839e80843269dc9c6645bf824095db1f286914cfada48c9d371375b704aa94c3a0663c5278a6ad4128dd815a3cb396a187f62f46864957e76957e7695a69cf28b3fec42c94e7a528221074620305ea9d1eb7418a87ee494ab54be728e8221abfa06865593015df105eebe24b8faeabed655a9665f90e391c7930e4dd3341484215a63c80a258270854c9b0118375011638a1c51649a94d7b680e3b5edb52dec78ad874cd3342d46796d0b315ed3b620e3b510649ac6d3c41569f8f0823482aa38e2c1610727a87823e98b2129bc70c288057831e48590fcdd72c5173cbc55d43829dba68ba467aff125d2a485531747a1cd1c918b375e4a3248ea68975faf72a55796f36595976e0292152418c7602ebc7c57cc6ca004d734d3810cca48420d2678d0618618e669037fcce2db5bab810e38500185174818a1e00754aae822480d249ad80108556adc162825cbb7d76c3a6801e41c7d2049d9e165a250f1ed3f6a103b441a2fd6f876164f12453c3147962b6198a1034f146fc0b1c4831733e8f872c50a1656a22c9110e21748331ebebdc7d450a86fdf7656bbbb3af601293f3ff0c086208062206b87754cce30458e3994a0a38a1cb2d6e1bbe7d4664be93c523a3292f1ec92eb48e2d90819731d3878b6a388e7c20e379e3d481432f6213877103d7b09ec396162787613380c183fa364e54a0d3df1a64a3a60f0ed31ab74b3f5f6ddcd822eee48c2624418a72bb24622c20c2c946270c1153090b5956f187c77912ed2311637b102dfc49643b2958389672c9e9d25c71bcf5ef30412cf5a3ccfe1c63fe0598e29cfbe4ae930ceaa51451337f8820839a2680303327822630b9529ea4022071f8dd53555d6530d4af8f6544aa763194f4cd43cbb97d2611d8c98d2136f5012290e30dfdee1100710cf2ed9b9940ef300471c0278769ad2611d66f0a3ad121c59be7d83801356b4c8524515550821631b10e520280636ccc0051719ff58d172d37d917e4597520651599105870c0f7efbdc7450e227f6cbcbb74bbef2f3ec26b04f00c90a2ccc31a69406f87e8389a737d4d063d5b8e1c6b3c71913006e68a325329ddcf8f2bbc58da10fa9101f3dc8ef16378c9e0a7deb257802aba96e033d9de1a68d4636d6401bc4db18e31cc1763ab12bc6e858d9e2c3d9349bd8359d2618769940886f0f67934c19dffe256c2a328ddada7c3beaf940fba8b5b4110fd55bedfb9cc6bea203c169caf1314699719353cf5608ffd41976c506c337e16c8a4c3f47cd257a2771ccebc2b13d8ade5ea23713dfac3e7a7fe19bddd2c6d147efa676e298278b2e9b67535ce263f4e954349fe21351f848f1d1b99f190069118a6d0cb9f1512b52e2a3731e5d335ae2a3531c3eba7684c647e7c02a1f9dd160b958aead68336aed878b8cb8888b8ab8888b8c8e929658099ce84570929698589bb9c13721fb3cf1ece9e9e9e9a9632b9bf9c427166a63bf7c5938df14077826e34024fd8a1e515d19e74daffd225b19f57033c0f91ae1c0963693693e7136c92159248de451c7e2648ada4cf3d17e36a7e8db53a43f1fa9cf473afb389ba6d377d4b1e93459d559b3c935a024a525a6d8349bd815dba88f3aa995660065478a25c2de021ff5d16c36eb9945b144da5b706a451f2adf7e799f277eaefcf8c812c694246cb0831843cb0697227c90411d54dad841165b112808287a5c220ab10bcb6cf239a736a34202b801d36e4c03f9099ee0f22b642dcf2017f6ca5a22512af52b898b8a8c8eda3b72d10a6132aa04a9e45d77b5d877a324d18319cc90218e2853c80c85a181c9075594a490ad771136874d388b9ea373cff826822dca2eeed912e9d1346cccc8bed889c44e621dc551e4483c370d517dc8e15903683c976063beaff5389ecd78ee563fc137214e77b483a9a954f1ecfdc3312fb64aec8da5e879f5bb25084653f604f88671b6b8e1d973865079f69e35d00fe19b5532b244da87592b64637c854c2f6689c48f9aaf9008ee14e957470edc31d2afe85d7f21cf9ec33814aed2af52cf8e929496989a9e78957ad6402d34347de60ff7149a403d5bdaaf489d0329b87dad2320056bbfda7bbb487297838db1f28415b6aff58555a4a0177c04c3aa7d08fbf5220b5bc759cf592fd2566ce4286a8ba313cd51d8ef3eb213e99bb7f7d5786b5f0afc382774cf72f2847e084b42fb13d64fb09e5137a9c804f8c6eb3a640eed45da8bf4c228ad95d9877c38ecea2e6a749ea2b61709f2ed0b2e0c27a7088fdf2d40707ad6e20161e9a3c3be617c0383e1e414398a59398b5d7485b00f16e6ac36a774a2c7a50a65876f62bc63fbe2e1ed5f7b10be5179cadb87f08de7ed387cd3396ae57d42ff37f5f675ea06613cc002f4cb442a2c0dfcdea532e4f0428b38e028aa41d64a414a3cc111c30b988042d61ef37943685167d66f5708fbea53a5befacdb0b8ed01ec82d80e6b16cb5dedb01f7aa55b1b56f9de8038fd6a5f810d762d6e31c82c82ab4095ef8ce02b70e53c32d5573f1ac6683ed5301a292df908467a001121c94753c75a4f1d0be1f356293175ec87b747a7687414b544232a4d49d848c7803880c69dc81d887fabcf5df501f12fa502cb69be9575dd9444a6b71389b145faae35f8de5a9bd6db766374c42549a98b17a62f4e9bc6434d3a3a7c8957aec42b57b6f839e10fe34c827136a3a1dee3239abea926146c519c25c279fb023616a3582e1a711e46a368148d8eb8242975f1c2f4a5c9c9434523ee41718ed3b168148db868b4711e53db46b3f9062e7b387cb3a4048e31e957b31455be13f9e136e9386951d0880371e9345f4f4fcb7d78cf0f677907e4fb7c84af878bf0d1b87f3b444768fc73d03b8d9ad4b11e47db12d9b65e3900fcc8ca0100ee106d0e823b3d7ce51b7844e51fb843e3dfca817c2a1fe15b9908dfca6abe95b562aa65a407cd7eca6bbe196f7d3cfcc727e33ebe986d03650f0f8ff11e19af2e3735651276753cea577bfda252bf9aa95fedd4af8e49df4fdfd1885dcd6409bb9a988607c53cb0746bc3a954295a5d3011e88f1f1e55de3ebc3d0e758ce53d53e39df25e79d37887e05076d8d532895ded5064c75cd4d5a9be96a7be1f5ef345daf21fbe291fbeea44f8883a9b1ee0f708df5a0ff10dc76c988ab0a3b5864c7b2c6a99a49d49c77a88da48c74ae812bebb8415d29bd2096185ccac90de5c848fa8f34d35d9c0d6f6c3a51be9b18215d2aa8f05f1d59e8a529e03515038b67714cdee88d1c8da6350c7f41ec52246711d14767161573b8a66f9e1fcfdf0d4e7536529577d3d5360329f2afb0142e957435921edb28e4ac16d8d7a4c694ee7055656a3f9061a69b57e380a786abe9e1e96fbf01e1a5f79e75a22aad6a7f21f5fca598ada22788d231101dc7ed5802dcd6b7c65485a1ad85241e5359e0195d7802f101df9e1297fa1056620e52d6f812ffc00b75f9a8f6f6553c6637ce5e3abcefa649ce68bf199cff3103e1e5e7d155f7e2d232a55ca470fb0a74706cf79784f4f8cf7ac3c15c2b7b2994fb6af84fa55d4af76557b6d97f18ca02039c2ae6e2525191e8e2b12281a9a558f1eab964743a3e2115323c3aa3e787c3d5ce6a3f19a2fca562ef3a9dcebe1345ef3ad6c5b34ab896a71342b54e7751daa43799ea33a94d7a1be2c3d7af86ae534ab1eed9b6a71a0911e349ec35d4cfceadd8c1fc297721fdf8cfff87878fd649cf5d5f9c3c77f2bab3c1cab8ce8d6a6a7f39e2954167d4a95c5f4f8c064313ea5caaaafb346f0114470208ef2adf15d4ad2b1954b87d2b11e3f5c86e0d29174cc5534eec325cba564015c815d7269894e71731c6297f4ee56df08aefa6adcbf28eba2d7e38b719aaf3a6a04af719fde01f988f863a17ac8bcf46e4ea9ec71cc86a9083b5a45ccd628620d19229c58267d361721e2cb1b81d9f0d26b68cdcb1a6e85d015624765e714e7403e220e6c7135fe42cbabf7f85e203ad2f2ea2f88e0311b582132e6e340ec99e2b28d0908555101e196f11dd879280f3c81dfeb1c09c7f60e1beea0b1c1e70c1b7c1063c3eca5479f9549f73a541314d6fbbe88855dd23dceb272fe92b04b7afcb2f850d9caebe75365d563be9e293059f5a9b21588a45f12491d95a754f698a29f13ead3bb1f5386cace2d0e3432c208358e029effe13e7c7eade919e8e1319e011aafded57c2dea409c4736c2d7a2604b8595d7f89195d738f51a7087888247540e04dc69b9ca47701e19ac5594450b49688b35a090411ae20b47618b2454f4237c3b4423f8a64e00e247560e04dc21e27c04704704b045bd87c7f8ca39f088ca6bc09d16d8a2606b822af4f0183f42e3d569bcfbf1f1701f9f8c87f0a59cf5cd5c60653d3c5cc63fc6abb78cacfc022b5b7906ba0d99eac7b7321ffbac6f65467a7a6448f98cf7f4f0f09e185f798f8cf75457d17cdbaf0e614a67a15fd2ebc7a45fd265be38eb97f4992ffef44bfaea93cee3939e8a403f23f3ad6cf5ad4cf5ad2cf5f1cc90e08043d8255d8e191e8e635c307b6a4719d75e613641611f09bbda67075497246157cb51b7746b732493ba7463fc98c9c1924a51e46000464c5c9143ecf173146c61bf78dcddd9f36c4670eeeea66973c266154260f9450202ccc77e9180a8e3e57a32a55d511709882e1fca8e44701983ca4b9f913d9b67b41261a6c720d44dc9fa00b6ed93a01cf6e1a6e13c52caae8361275214c8813d5384c838f7e121a33fbc242aecc399df6fe679fc74cee93c82229ad32798257ab860080392354316c3a5e3fb8a74ce000939d81226dcf96dd261625efa5a01f34fe26b4d3a4c989f60961760d81bfcc82238730986db33cfbe290eec0d7e640cee4467f5ab67fe8d20288480a288c96752892a454821620a59cf142132761f1eb2e83d535846ddc7013276eef371808cee101d61df41d23b444738a7e04e117087e808756ea7bd70cc9045161f849104195dc856d63c3b6c314510416c5972a20dd9caa28738473c87b539a59ccca5f1a5dbc1ceb973fa82ad699ae7b0a6edcaedeeee10b664075eaa49fc056996ea5403598c3a3dce5ebaa7c3627cd85a774f4dd3346d6e2ed9a5699ba6cd293730eca07474524aaec14423727185cb4a33e3056afce043b92b89eceecedd1fb2a7b27b0cf2a136a7e6da0a59dea1bbf204dfa03ad4e7a0c4f4441ee59decba0e0cc39862183e15a20086ef3c3abb949e7b6098f2762d7aeae34f49045d88d343a1109fa25c5a80c8a7ba30ce7eba06475da41c9c5e7ae75dc75e4c31f5a6de9d40b7a553e790accc5e3ae5542af5a54004e5213d81ba4ee7390a0c39e529308c8feabc03c3ce9fd05f21284751efcd7789285942e43bb00522ef04e54fe8ef0a694779b777285f219c6f4a02d2a987d1699c7774d1d746bba2b2c7219ed90a242dcf1b90d24a0de5d3962d93f03ccfb75270d574cb31f24eada7f61b35acdcd3e34f300c9fae90e85bbe3fa41d84d8c55dd6e5cccc5186d3c3deb6cd45299d73b2344dabfdea6eda2fc9391739dfd491389bc98eec918c8b577c7a3e53f966c150bad7ed576bd855594c33dfdc449d99deb395829c2f2520651ddde6beb974f9e9483a42a9f52e91dd5669ee393c37b64a9bcf2e888d722a5140390a44a150a8e5627c448fb27bc694148bd6d96948e8d71986a5465f66a35b1b19ac632da96f655775b9e3c0d855244b0e5145d246a28c896aec8147e1e20f3574d1013ecca1fd308bd48409b00368c4f8aa45109d87326685ac2ce2222a836e6da203ba06783101ede147590132df1eaa5e155d94c5375fec0e05b68aeca39ce7b94ffb42efb5f885503c23aa6f1ccfc7ef496b5fb85d5e7a4e4fd6010f6fa579aceacd44f666b6283154796666e68ddacc546fbd991ad62fd20f0c3e647de8cd1f9cd083131453700102194ef01c2187156d5861031454542124e50d3a983749ca19538a1a7187359c9c60af494b2e58964d0c2a8414247945174647b9a0ac9c4d4a164e4a11ad319a52a69894f5d3c373d720fd04750700931403212464e0c2081e29416022061b8cc088e306190bc172d78f0d3f33302cbcb61bddd07fd2a97d4fe66f921104559e2e670ce54fe9da94524aa56e6bca2f8eaccd295beb3967c775cdd85a6bdaacfc65ab8dcdd79aeda853df9b90e7a3731cc7291dce867af23985e89c8dcd6fee7b139d52ea9dd2a1361b5b80f3185dfb8cb04b73fae93859815d9a236197a6790ec767a0ba044cc22e6dbde89cc49604d637e7efe79f516a8803856f42261df37cfa0edf509f9c4f944f4a6b65b11c85f5cd09ca398faf4d8f3376f5449f48e563d2afe9def4e973ce39e79c737aa86fffbd8f67367d7bce3971d835635004c2f9397d6d26a8240ae1a09bf14d07396a3acae917bbd723af591b2fc908cca8d1738ec21cf776eabf79077e2b04fcc0c635e74f3400bce6df9260b38294dfba340f40075ea6302d209ff3ae37ca96aa26fd1ce85fd5a4f73a6d372cf9662a96ccfc9c93a9c908775a65d78c8c1b6c5fd1bdd0bf73ee5c7ad77d33deb386e26cbc96b27dc9cc4f90763718845d51898328120e3078d42f52953bb098e1f53ef49606f08b84830edefb45aa12042f66bc6e9c512bb0a77459beb4bab809c847d6be622c875fd197db2300b06c6a587e64c362d5e4408726258a465939ccb462c3cb61499901c586579305e5d451608e0a82a630e38d1bd690e20d197f3182888a163498e1c419b220ba6861684b709eba0928e4c4589a941ca2b0e15170d92983351b3804e6352c1b160e4868dd4838342159ee6afd22e150e5b55f241c7c3e842969d1c929757db7a0750ea94a9777fd225559e2bbd59eea2255a1f2ed5c975aa9a429d47e46d9a286975f97738974bea0f673bee7827ccfbb2fc98d6fb27acf3b76faae7ff09d04f3dd54e33bcdfbf2a8140ae077deed945d775dc75d17bbaed3b61faa9007cb778e54a5078ffa785ee521e7ac52323ddc3cb51e72aea95228701e5311a080055460b8ce39a7d3815cb2e8790fdc15d2cd39a7ef8fcec3e972fa824a386f57327d3b999a004f15bf1b44a628c0797360b8ecdcf6a180e7c10f77ee6e17b537baed98f49531166cf810c5102c343cc9fa5b59c7414eb0218301c5c64ebc830b26190c25001dc1854c7a7f3b718a0c86bd422641a256749e8f31980124838184398850da89329c3193c100eb59a30b7ec11c72547992f5276d1043d66d9efc769606464a32183a0699c70a88deeda6452efafa4088307c64fd753690f1179f8790a8ec5091a828215161e299b6435d731e19ca7954ce23abce2393711ed98cf3c842709e09b68ecccda7f3c838e791752b1e190f0fe1dba31a7de6ab3c3e960caacce7319f2b7afd60ab0fa78c1ac2728a7ca9e11e19f990f480fa5848e254c36562024506355ca78f31882906ed2b7a0c8a4131067db41249881e83a252943288637e842536138dca8849471f3d6e11bb708c23d39568c5051f3d5ed1a2952825626197500c9212f4d1a3941a66bf008021864732ada2934a5d971f63ec96991c3439accc50a452f872bf5ba220f986be2104b9532bddd2baceca29d2316d739c292573cfa08bbc52caededed955c6f37ebb2676597a7ed4a29a5dcf59cdeb9799b5a304cf2ebfd8538a871bf25299df56db9350dbbbdbb51deee6ecbeeee0e79bebeb12e512f3d968f9890e33e6a1f085e7a7f51a39ad7ce37bbae9e5be99472a31a1a949b63702889ea3c8f5381f4bcdd9cb7eece43711dddbc0ecbb6ddf9b20bd55e83924a7f916ad8e2819afa45aae1899a8afa45aa21091458630d42743d0cd113d4d52f520d3f23a8f517a986190d4ffddaeeab6151b94b2b0d5d3e64a1589bc2aa95c6c8a3a3491e651e8ca088e1c127a8b543d38f6745088986282b2b4f3fe09103130cd65c88c01ea57576c5e7ca4f6539143faed4b1434f65249fa195f7d0437ba0c2affd9056998f10eab3f1ea51249f590572001b5900a0faef163690c8014aa1c6fc6e61630609d4c181ea3951a076679c50696e50811f5c11a4aa7eb7fcc0e889fcc009d90c4f333431f3bbc58907a41994982fe8c2e8b55f1bc3f53072cfbfdeaf6defb4df1407bcf8f977edf1279f59fd72fa27fc7285acfcd95fffa638b047b266661a77eb1cfc5b21eb524ab969130ca3b6bb0bb2fbb7ecb0b9bb25333333c75f8622f217b2640fdadc505474fccb11e57108d4eb4cb1c2c59253971d8e90b1f350c71608b3a4198060c71251e440167f7876e6c2497ce3f97cc621e3d94b0043e90ba61adc60c411b211a4401ac28e3053b29821faf0ec485660a1d9932c61b2e5d99f40e938eb9a971168c33294c3337d5e9ad2c3143278ba32832519f36411e2810c3070d0069734641c812a752e4ac11e9d60bf4a3cbbb483861a30352185b14610647c864f105454a186147364e981bf73763edaf29e2721f33caf6bbce7214d89e2bd2dde439a4186f7dc866f6adea31f69951e2b3d7d978b0104f8ceb9944ec77cd4b12a830f8ffa1ee5a8940e2a8e7ae4c4affd9c304f4ab3251fa61f7eed8c9d7a70f09c734e533a5c8c841c20cd64dd1b4e4732ea5a4a87d60dcc6fbea574367a23c3f49acb948e26670c50fcf499d2997bc347b3996b369b45719acd64527a7c7414c7906fda458d7ca4f4d28baa1fea2abd7c9c4899a268a17992835451944595ac8e19e957f4caaace72d73e17238d45da1b1e0afb9aefae03368f0ef071d936e93697fbbc24158c2c917ef64d838cd7c1b393f5197f2210bb8238badfb2987993ab3171b4524b347a62f3a845283e118d6271280a4519555a39779aaf40242a90a626bbdc51a1ebe31c4964625567b91c49c756c6d4f484ea58ec43ac5ed4b7ac80e8dc87f36d531e8db529ed3b29ceeeeeeeaedcdd5db93335eceeaedc6eed8b13721764cd14e919967be17d437f3afdf8392be5ae942be5cacac58564dddd85f16ccae508428e93ced9d4894947aba435c992b04aba4e4277b010d5ab880c50fd6e71dbf8a828e8cac6517a5b967b2c11a983efc8c5b7c72c7ec1a8c5888a5abfdddb1b8d0576b5ef4df4dd9bcd4790846709df68ce557e9dbf709d581d8b4ea26b9b11c7e2143f2ec8c1fb41a80c29dfab2f2ee8d2e4c46d1b97a760e82348b2845d1d3f16509d72c3414e39379f9a4fea734a9f934e4e931bad95c5f2a7200dc55160f5139495559d156f50524576151887d8c5fe452c54d4306249aa3731372b8f72876e544a37139459f18dca39c6d98dc459c77878aae3b6982fd66ff5451eeca3028df48b3d058695e52e663dafeb43d6fc4d1591528eca728c98a3965ff4ee8e31ce6ec386b96839fce270cee99e53846f66d75967ad6058c4843d929e6342911967e714993e25e85d5143184ccb9194db2f529096af69706a4c1c29715c89749c1b09525aebcc8ce63925b08b719e59f8d8b587c3b13a9b49ef8a1ae2e08443c219a3a3c39021a95fa4a0a40f6d9e679464381ab22be7908f328b1a5656957383fc22f9f0840f583e74f9a0dbb93bf3eb51c9ca9db1e79c73e39cbbbb524607c2da0b5a33fb8a31139ac6098459739c124ae0823f40e5ac18a98d4308eafc45f2a18637800f3e1fce7cf4992054ca99369e5d3203d5f1ec362e76183b0edfb4dc052406100e66c85001081047d8ab073100f68218c034408080bd0620a87310040dc224fd9c91451d234c21c4121858c4e1344313258c20ced6c7983a414a290550e52f129016432abf2a0b8b97d27dc1904a70a6ce9794605873057735340aa0a30f5d4a41ac840d69a7950b2e8c08864b707ecec99ae2db6bb6c0e21b25eb8ef2b3e90622e2faac07f28b0454e57bfc22f5f024c508a377dc4725c7b9d69582db06d2c9929b95e8561b62d5791e874fbec39d5f7983e1e6332f650f112ae5dd397514b8deb18742a13a507e777777777777b7bff72991de9b3f73ceb11ea24ee59c0eb72857129df30e0576945316f092a8d1f73bf7cebbae03bb18398ea334721c9d1690dfc515c27114e5027fd7711c8feadb94ce72509e7a7cba791490ed318aca72cedf465b9b6fddd7dac01a7609d52ae3a8e1f47d56c2916eee65f140183c199106b624c04ade798b6ef9466a1dcf39e793f99bc7a39fb3a1272127a0a6f8c3c474d49414ee12cc715c216c32f3d47c7bc0f74fe90cb6007b2591478bd2080528404193264d54a00215b8e0820b50a04071e2c40993c92b26d3234b6632a7641e24c77a3666269a3d651c9b8c274f9e84304866e6c8ccab14541758324b3a7b7a136efc6a32186acea02787a8d2956852e3be70032947374ddbbe0d0cd935d7a22c1250d1722441d7ed26e9967be537674a0b4bf8f56dd3529493359dd2f196736a1bd5a8b4f1d6d9b536ec5a4ddb369ad2d98f4be9a050a830c84ffe09eeee76e4a171bb32bf507e0c2b03643c8c2ed497f1b03f469007959e2fdfa4bce3bc53c555ea4b51c9397b7599cfc993ea0d51a3f785ded398989818afd65a57abd54ae59d77aa2f6a2995a78aa98f73efdb25e1e36a4739f084e9d2739a7eedf39372c67338cb4c8332bc75d1c929d967fbfe9c735345e4c6bc499e3fb97b7a0e73d7a0932ea5d87c1794a92651f60f0d4c5d242b5e3ef4e2e6ecdc12d995311a18c54f70865dd16d38e2a05b6da92e120f3e4f977299c50086ed14f4d83551a05a962a5d493b75cdb7467987fa42ea5c0a8cfa42ea1c4863a460c854fba4cde4243a1492bcdc4dd334ba94eefafa6c8eb23f54f62804f4235b4a70f352a3a321638c31c6cee1e698d25aa5ecb8cfa392f31b4e7293d3386e636dca8ed56983382358bbe9f7cc9ced73f6f67cf29af7945dd2c55897ebd34329d7e5ba123933c339e7da7064ea64b7a25b7f2c594a2addaa72ac8793bebeb954e23f88a694beaf494d6ab24d49a94949a5d424953ea5dc99a914e46bd2670b344df3648cde4ad8c1d6e20ae1d8ac31735c5733cbcd88ce3725ecda0f2f89cabe2f993d85b94234163c7b5cf1ec1974f2a4bef4b92450289db2809ceb92cea9e0a55ca96ad24f41b942640b5eee3c7bec303a273cfbce51de754e9da7038f48e7bcebc017a8a79c035bddce0b4447a8a7fc05ce555dc783d37d4690f40be5f2535aa52e7afead4551d73c0352bac6b9d4fc05e95446f77376a15cfb5cfd4239fd50f3a9c694911e09b6d6a5f3c838b0b54738b0b5d28fb4166ca9a0b9f423d337dfbe17524e5d7ed45f50b554e05ce51ca09e92817395cb403d25eb525f6b7d65aaafb5601276a17c65338e1abfe5b9f495b53ce919e05c527f413ae719a09ef214f8421be9e9a931ae521951c52376a192f40be5321f937ea13ce68bb37ea1bca27c857206aa31895d28f7c0c8855d28944b39ea7a188f1e259d73249d65e35f1b9496d4714bc68ea463ad8ebee00beb713d82ad7e21ba045bdd2b7baad1d7e3520b384b70705ac071613e99fe94c6990b93fef08e902dd8bc1229c3cd29e71dfdbc20549b97bff9729f7c492de042fc08d2166c5e0395cc13262875e8e6d2b96dee04f61bd864f5d4672b85289483a7ee04f6147441f6f46e869a5376cdcde536956c9376ae7d28d738d7a84fea93faa47452d9649d66b37f22f39e773ff1de63a27d4e9a3ce07985447fa2bde64e347fa24900044fbd0990a7ae7d4d1ef07185449f00cf537037c8e624a23e27cc49aa6daac83e892fdd666a3178c10920900002b262063db002873776d022ca8c8920263cb05e778538a288819213445504d9e0073d60e1c40c9cf8a28322a20facd7f5404c8c1cbeb0030b2f8ed8010438183dd1c41636ec884b7440003fa8e1a78a272a4360c1b3c40f10501871a921065e94f000cf0c49e0b004972dd020238d2368186369498629d0a84112bb2ba43046186100614b1419e4b0714c010717622069616207487860bd6e07e078238b1a3788b27485cf3e91010510aa1035cde06768c3e0810e292ec8420648080131061153eae8a2258b24b27c80053a9c90bcc85145195dc87878e8c1082c37e8808a133738c203351dd8b8bb82d350d1ed12e1f5402cd2319a03031ea4b1850d68c8604516bb20438d296cc4008c1c46b218a3111f61b18aeea1d65a5dee364f3db6b187eadffa12e96ff72203781681a86190d095d848e3c8dec284180c494a87599800dff4f450fb26c05f118f9d640477d4d62fd20e3d3f01138ab4c3d82995bdd18d7a4ecb140577c768c28b0de0b0820b35c8e8d409311b0c3f4e7589ecb7c76cd7c58f4be96cde812d14f6a3f3bcf685f435289a7f9cc6f3ccb1d0319811101358b820065db8216b67336a18e4db839cc04fc12631cccf2c357ad7f86de093e94506ac93d7048bf58a44623e7acc4c0d810059214fd4e81d8b6f2291d5b36c7a83518d1ad6ef1767d97e0dd523ba6d1b6a28bdf376f6acd832f49af3b78ff27073cdb7f84e9ec84779cabbeda417414f6bf9759cc7290a44ce233318aae051cf838410610ace5fe4a9e21bdc0e157693f81bd215375e024f242025bb5078125f9be017c2f0cdcf370cfda652e06f7f1e549c34ec40d334d7babb5b6bb91a18d6d7b8b99bbba7a6b1767777bb43d8f7b6d2253734ea3ed222fd7e38c24b0f41464dd3b4a8691bc20af9581cd69915f2922c31588b31f627e532a1a6f4604b0a05ffa97d4ee4ec9bec4409b3200afaa32b991fc72e3d7ef1bb04a64ba8740c17c5418d2a54340200000002c314000028100c088422d16834d4d5ed0314000d88a8426e4c994ac42889510619638c218410000000400066666834200b7712133ca5ea8871b595c2851c1ab70474c9f8c8ed29a59f10971cb6a1a30690d6dc14f3de4658c446feed902f5d33884445b4ae86a5f936d5d07d5f42651f15e2ab360b385a7c9c213077ffaa5b86e9a5516ddd56fe2e1f131aedfa323c0764adc2e2366f41500ba33fa34e6b4cd94d3d9173b782280358f3a0ed6f2c2081e3a6c168016dbec404e74017b9c74b40cf2e1b80648716273e20b6a53763f10cd3d2cd475f635a68d42923028bacdbe73cc4333e135d0bea44485a67ad865eb6aed838c823e30be7343eb297d830658ebd0637218f0bfc1ffc78c723a142bcb41bb42a2f3e5835cf116436f14bbc8a80e033f5b2af3a326b1fb52808bf886d97b9ac41e5831586326b1c4356a9f2f99573bad8835edb06cb478685b9ea29f32712610a590a60f6a7367712abf2d3cfa56ea7f54355be73858e73397e967396ce15d6e0e2975aeb998e1cc99e04fcb17ac827c636ac4c774f527fe8571886f3a754e65638e024cf4a4572b7be9cf10fe6f3d92716f306f903042d9009a39b2a5143752a96aca414750a458a1306c495c302fd02c9ba5f65216511c89d5bb46c523cda6cde7b5de32ed002ab8be15de25b587f9ac78506bd1405bceca70003d499874c9fac9144bd2c0c06fb5cd27a7019efbbe5b04c5a99b8182e97cf13148a1865321397d7d7ceb6d572adb1a48f293731c6974ec7c9a49d26a3fe8a5888f7f81a9b8b81516076dff7d92fb2f55cfc2f65e567f5ba65151efc7d35c4efe55ca8827f77e49777609858b46c90520b881a0e8b08d88859544d64c6432f5e36646400b0a978d8c63c8829b8c983c17b381cf42b182d0370218ce52dc5d0eda317dfa0cba4d7bc96bf0c66f36f6af9b231df49b73edc1b267eb90265d2dce58ba48a3702141f3fde113d2995de1a331e39701ed8a595a499dfbfd207fcee048222903c162b13c350ce8c6bab8bf84a0ec15fdf20c3af7f8d187d2936fcfbab8d9f1ac2d53e2fee9ea0188117c16dba93db7956030c8adf36d8ad75739ad09fda1a232c49c9d8318a6967078ce12bd6289e3ce126e3a70fe97190c59cec69fa82c82abb6991f09a22dcd90b2094f98ad43761840183d4b663d66a11108ad2532c8f8fe2fa2a99cfd7d64394de54336ee322f5e539db6dcadb1d17c1e0f9f722ae84a4529b3d8ff2128763e9195bed02356d809adf08e2b581cb4efe32caab832d6de1d07235e062a2dcf3d6ec131abb291d02a2e803e3f5c4312031f455cfd0b677d63a83e7b3b8e6761485b22394e79c60e9d5818649919af855a4451e291a3adfa01dda2969f6cf679eddb8cc5784df65c48617e28cd0391405ebd4260d8f1f295820807f0dff6cb21c354857acbc3976e5adfd5e4d84c2584e14caa3ec11f51c00c22033f52bf86b7685d655c9ad97f31d2f4c56e088e3b40f7fef5f918f6b834558f5000d28fd20fb0b2b0fde7323a37636871174ee774c8c3dff384fc254cde301eb89c1eddeaa0d8a505fb3ca02125567b21cea706b5ed5320c124aa9d7c484f3286636f9e30da6d6772e094d6f6c6746e91fd256c9e24e3c675609b1a626049bfec83ce91703de99125642a6a5363915a1962492fe6e522a3fac914f25cca49cfd96733c619244bf6c68827ecc92a545af67ba2719fda2f365e2d0925c91f4019d1296e9caba15f75f61ed0960377ae8793963905e8e477b74e00d57a9edad19f3b5bafd861eb7226b6f8e3e4d969e2b82fdc08da56b88bdd48339b41ea7281953f5bf9298b8b9414676248cce3f0ea9497b541ab3ce37a56bb66524f2db3152183d3bf6debdcec0620d5ac0cb63ffe28c8e956d25bf4901f42e7d22a055836ec79e9eb026fb3108e4c751bf2dfb20ef8b9e619866bb2a51a276bfaf753c804a3c010a9970f7bd04c370eba47c6b642bbb923612f84e3803a792b551178fad0e8190d621c9c5e3058a5a807f5013f3357863ea8c8b6a9880ab80732e16256c9b2e3c416dc5fd1f558881cde19c73e16f3109a54e50a43890eac2e8ada0fd6a035ea08b3ab9cbdc5755c0d2e58b803d0bbdb5523b5cf03e9611c45282fcabfb532a3d3050f48371b5375c09182c6709791a2c97e0830b43a22aac71f8a14c4759c239e98a07f6d22f4be80dc8ed7ccf6202e73c01cab8cdc285231c13f6151c98e7ed6c0621e666e0b63f7c96f5186c6c236161fbf9704aa484130282783e23a6d4aa190c8e7e5ab9bcda19b8d5b0bfcce5a957246d654098c98d729c7ea83e5c300699df0b19d2484b9d411ee35c0ff1e2ceed342c6c348ce65fc8586a8cb50472a184a2615951269b5e021adc9bbc7a2062f1c6e1ef2f920250ba749b1f784fde8416985dbfc02a8fe4c3e4789d42f60cf36e0644a42edd985fb6af40dc4d82528db4d4cd5c148418282fd9b8e37ec60a7fa2e0555299d1a1f03fe41ab5bff920d7597a0c3e098e184385daf5cf2915ffb9d898e6800a41911890b0b0e86085d6d91fd2548e8ea1e42b2e5d901236cd1b0fa0a08d346ef7c0609c1081713203a080b560a0ecf24e0a05ea84d1c3f9332be07b9e557d8a49f19f5a0cc0529008f5df574eaea3ed23046c2bb1b8800dce60ddddc8e42a72e78ee2f6c594292710e8e62a02e96c506ed9ccf274c902240e04c73f5cc3973f0f9e7d6ca668b60224b7c8208f92646cb0a759bb22373e2fe21c167b7be467c7cd1b288e8000113499ddcfee8426123c6cab47f1a322d873df5258b61ed78d024b15f8c9cb257af7d4189c8cd87b00aeebc1870af30630f27534a5541eed4e32df4ae7d19f6f0c555c2ee7e6b1847cb34ff2ace1d98c94fff3d6d71e758c4d33b2e94478732c79937e62dd10d1c14ddbec6d789b41386094196f4bc63e51feb1f7737ca322888fb6bf5a9f8184e8a064837f2344a3dd2c300f225ded8498fdf92bb5f2effcb2214a8995705711a3e12f21bb122385f870266f612d4485db6a2813cf4d106356033d5198b3c0f59bf999d0d6b53021b57a8f86b532474fb52ea8bacf7f368a98aa55f1b4c2565b2c24966e7338da645acaf5ebc0058d7497824763c88172e0c2e171486efdbb4bc1737b2862eb10cb624c4b50592510be1230ea391c215fe4ec8a46a8ba7a83ff4a82939e6008ae61b8598fa98cbf041c7a06457cf36ab480dc820f616930d13334e4dfa731eaaeee45d9b6c6235a08e8c886588c2aec5836f4c3208998aa466c3cc2ac9af60ec596ed800525f23f7f3e25f5cce6b3420de296122c2080fd922fe239982f9af7e96de789ce534c118403ce65cdce6fd5dc1cc01cc6f4bf3c5a1f132fb9f0bc5ec5e829998411e5cab88fc6d077d121e7bdbf958fb2e90d1aa457bc0a76e1cf25f2f73a00bc233320c15b7c2ab143f36a773fae28ff6fae9833da3804333c1124c0d9aee801198ce251d942b5a4591601e5efb6ccfbd4bbb3aacde567298a00def2b4c591e9f29162e2daa0f425dd1ab782e99a204772aabd4e54761b744016ba377ef66f32ae8c3b1e913ed208da78f20540fc1dffd7e6cbf21c520d1846e49798668033c2878ad539fc014bdf47db8c31a899e91b4f062f8e9d1349879d7f65f150ecbe63666c09e5a5185dd71d18a42cc71154cc713171b9235edcc82144ebd06d5c74c2940c9c1868263af923328bdb15f231774046f5a601eed293c00ad5c3a939b235a5c1f03892c5aa7922e8b538ba1c32228bead6fb22455725d86982f95a28b2c620409529245653171fdbb122b31c27d00e2e2d999d9b8f4bafed0abf50a0d9f7f1bd2ed9e3126ae8262844b2fd9b0861a169883a5424719796520b866104832917a4a2358e082d4ba922c6de7ebe8a69efebaa8a6a730c7dc303bbbc891d6f830d4a790687683c35f6ebe645d119e8689e3a0ed31a03c46d778724f7e89ba0fcc5e1330a392c69b17289e2e61143a85b70f37973ac5474260df640a099e9bc4b42f30a1bd09c1eb4f0f6a44751dc7d787b012d5cf896f46c7bd73717209fa1735fc6110577689eb08cdcbaa3ce684cf874705b0578f2bd9a5c6a4ba512a01181bb3628403a4a2cbe41d5a7b2bcd62d86aa2367e7f9a7d3a4756be5ff1b265b703c623a403802b567a3432727da22a13fba098ec21a2b1eff9f876908800c05b7a5127fedde9720928b23d4b4a0afb36154572504e235b4323db4c7c069d96ff59619413298827f02755f0eb4ba64c99855dd2401d0ff79f7379944a3582d722184be84c5a6a3885b721d221fdc4a8b4db6b2d3c3d22d6bde4e21229e5e22505975529c601d9a00d7b095721f79a49017c2302a5be9ad0b51844e86238a3efdb4d991449968042197a6a7d0894272a4b5aa8152e9aa84caa6ab3fb51827867d1059a2e52aa2d09d5e218dee8b8e5d3aa91b3c13951fda3cb9a7632690e83dbd50430271673b744316337b4663701e186621ae99ec9b70520b74c60e5411692017e9126a8459d840f5447dba25395a974e59f7e808b1d4845d37217d62d52dddaf9ae8046442b76e08275696a6ac7574c26e7937702dd07c833fb12e9c4b1b8424d3dcf72e1a0247b5f70b8d5c689543940d73f8e91a95e745040ff006dfb86fbc3a83ff62ee4099f84e5c0b272363429c54efeda5e343fb2d4624945ee62ec57d72aa7ea55493377501cf82261c7e383b75e1624a58774f6f81c032a498e48610ae7121f4d215fc41a1f97286c40213d65ecf447bc9536e9d56b628e1eb66fdad409bcf1fdb2f49db31eb4d45bd0be9921f42e9bdfec75466b361a0bacbe5618fa74f1af321aefee593bfb020e45e7db62f0426ae042ea4cdab3bfc00f8f81c737779ff4f5944afb0e913e5fce5b79b6d0891cecb8aaa96c8c22ce23af38f2ac55025e2cf40ae22bf4d7e48f478d085e4a8ab4dc30d5268d5964e1df87c3a2d9efdde9da5d0bfbf0a150206dd95c527bd597c99a8159863e437d0785b8a206f15ab68e85cda8b6e25c52a382c90380143e168c6739b899e1b4ac99eb31fa97d5add59fa829e73885c5119aaa153a0a6a09ea3051d6bbbaeb28451fcd82ce519f69cba94da94c6b0821c20e05cc1d45c1f0494c332506ac72eb9708990dbbad63ec45eceaf8c83b5d58d61c3805a726522e36ce830fffd8293dd9e9274f1e8543f8b38884c7f7ae412333712eb97ee48e652eb17e7d4c7a4382700c1c8393b6a70799d8ca5e41ccd163f44ce1be3d4037097e65f05dd639a078bb69aafc0280c513c8dc9c170ced8e83fb91de5ced41f0a07e998a61b749db9efd39483156169d4d4cfa50887b42d84363903d1b27eebb320700120eb8295010b8f1f6b77932fc0416fc87953a91046341818c2b3903070a4517ee586aa31ab9768f5c7a347c006a1f9e3fe0b201d921fe88eeece22945f61bce6adf6e2431db8abf7b58eb5c2a09c9a1a5b6a1ff910fa32fa74daa0f548384377f4b8b9b9efbbc8ecb57dc0cbd7b536ee100f5b4feb1d11283c9e635791b4be028cac2ef821f901c7a08dc40c23042f27dc5f3a4a5f7c4751e9e90c0d0a6be36c2bde385c0bd4e18b9484f3a03de830457962958f4c749b8ece14c6181621094fe21a0302b1dd5ad5653b8d043016b257108f8e9ee485241e8419e49733eb78018aff00a42890f25b5e1ec0a4d248d4f373b86753e6d2e34cd6aa3afa62645232c9e9cdd1dee6eba6f088a3cf7b048962bc510d72b52cf419a626283dc78dc2885f963fd7b5dfd0a1a317dc41800fda0826c3394a990d21746a6648acc7ac734180562e390f12e7d27594ee59f9308a3989824e0cea47a13652efa2dbc9d85c924be27e5a092816c027ff6183fd793c60cbe78897e1cfe360842bfa6c9f10fbeb8539cb524d357691ccb450a4c87366704c1d1a8016d2c2ab480ab5f77053ea023471456bbcd530d296c5d1711c9129c438989d192219a55de85ec19e1ad1b6765a32d81ed44b38742df9f3421fe37ae5bd8088703893f5536ea88ba1b5ad2d6292afc61d7bc5e9ed4d63166cdfda88ea95fad32ec1689f196f0b6802e09c7ad64eafc5758e16c24c1c4c6ee2980cb874705a061093c6ecfc97b08ce77ab11dacd1d76f7be023758b3b43a651137cf0ae903ad147218ffaa9122401f1e00253ccbbcddb04c4b7905f224a51db593ffcd50d6284612cf88ba65712a5e9be7e2cb8e5cab54f4e3b0ccf784e58462c88441b2853ef57ebbd31e962738bb59b3c4a930deb215485e7f3cdf247e412fd0f1a0d575aa71008c2cac039a380c7dd5260b5917da820dabe5ec669fd6774f4dd0881eac0944615c3d68cc8591ebbd33778d04ae3ce6f3287d3773151c1a99131c8504383e9b1f645ca4aeae5c352b589a3bae1b04185732f5bcc0e25e1d8e062c59ab85bd809116236735e751a32f1b13bb96f06c4e80cb946be5b2c43ae7711614fd5a91fd62874fa19c77e38ecdbccede308303789e1f9731547cfaebb676be004f1408de2fd436d630403d716fe7cb66ba4d52ee607d9854ae9f5a5612255e08d5a6cd5aec2b9746770ca92614c16ae1a689374f8596f87f309912d413c5f677fda6ab375672dc71901b6c77f17224d66d641d5e78342d71961753d5470d358b6ff54077f206ef1bcaef132187bd806774904e84bbdc5c8477eb4e63fb5a94673b0083bbe93145480d855af627aaec9c18dddc2eefb5d929290767785c1d37e2029dce11242f00fc8dc91d96e192c5003f622cdda2bd4e92b5c7f98d38294516b8c76ee42c190e2c5b11be12227a96fe21eac0c50e95c94cca6d4c0e42faee43cb3169b5999f9103cc2c0c2a4b25b1cbce67379f19e9c8eb05836cc3710ab54c40a784ceb3b733f3462cdc6e171e37c00ac669383bb41e0c0accf6271d85e924f5890588c09b74411da0b6bfd760b1511a67afc64c68a235a8c868d6dc6d72cee33b15e60bb655f7d364294b6080722c14d203d187a7bfb4a4eba805776ee71e787889982e43d324b8699b0781b81254f85d59570224b31a37f357b20c2ac95ab5710a37e7d47367409202d9ca6605006cb83b10edafda570e0530f266191ed26e878cfad4526bb938e4981f5145413de6d072a5c855f47171eb8c6d7be1443c9ead134ac67983c29bc29bd409a85a5d1840809ad510a7a6727d2f4c16488c78dc795314d5aa4a883503c9d0362785600fb15feb87c36e7bd6176650878b1b5b68f72db28cf6c997be4049223ecc9ee94308a086b881a11aeec49440ddfe2459622fa1cb40c3c78e8a4508dba2d5b8c1b26e32c02c33f7313d089b836e8a1f8bd7c303fd2b3520a16f3e430dbc9f0992647472b025e5c64a4571ce5b58174e6128deee01c00a9bf29980450fb8f4d898d367c805f03ba9b9367ca50239263a9e86e36df944fa884c8243cf1584a188fef0b13da3afe12b20d41c8dcffdd650c0c105381dc9e3b5072426b4bd8732b7b6c017900b3885528df6978f55b1b8fa5f93338602f36b1d392675407a3afada894c65a8c2bc858aa1f8e356752adb41f313a03a42c44cb95245c47526a0cfa983956b2df4219860a1f78c56758d5e5a2f38407588c0c0ea10d42f1355fd64c99b3872bf2008af84b2204b0ef583544643bc80a903a42a4b5e1c87569b744c694025f897c56ad177b2e31dca2cedee5d633264c21cd44501fe95aa68fd0c8674844b2da7fc72e4c2ebb6123ba7639bb0290a07718da0873bf53d59196a34b70ae350f166790dfda677783697d0b9286b6773d885696a444e1ef27fcb0467f64dae8f298888de0cfd9384f1f811f803b20b9b7e242f638706f26f988e8d0a0a64fbec4dc3b5ecf115a6fea253fe360f7b67728b5f79e207705f53f09104e6207110440880634f254252bc8be0a21946bb5d2c630ba89e0b7ae000aaed68593dc1a476f785ff8fc0241ebedc03b81a00b4df49144544e7721642efc2ec93345e2e28c8e39d62d5dc117503aa77f3f78a587ac6f6da4ba1dd04e0e1cde55a50555ddaf8043f828abb2c717607f9af679ea555ce3a9bde6faba300327c5158d56e0ea80d5e7825efb7c7f31df3fb14c4ddce125bf000826faee700ac7d85962106c4229e20b19212fa5e161ea3a04e85b3fc0b39c7ba3371fc560777597c4e94e6dc8ff5083c10dffe763daee77a5537a4872e95fa84680db5059dbdbf40939c69356fd0ec8a651b43202bdbfc9510dba844e7ea0febf1076a01051fde5601afe9719140df30ff20d63bede2059774b903c1f4764dca04b84e93ecc43ee74788a53e0296bc018544de61afb80d7b26073ff0ad608d9aff885c022d2d5973b32f152ef40625992ff98a0271905e0dee14465ede0b1b001bcdf04300d42a65b20efeb0fdd4c13d53dcd0a43aa6d08cc4c7ed270cad29c6820e6759aaa78fb17f9837b60f79b2801792908c9f7dd56acb49532a28b9bc562104b751a8c2e5baaca9d765be319459ecf8cbc4f4fe7183daa93458256a21411b10d1a2e2e2efb55b450f5613fee2d4647d22ea1761684ca9285447b3e4ae55ca1a2528415b781522e4184611562458e294f0e67945fa4697ea32916e937e28c338d9323a481138f7d96a6b71ea681750810d18350d3ff6408e264ecd5c7559f586a30fd33d14452d8696066f7d6559ff4347f4826336289a519d6f822410b260ccec584551e1f4c79628cc05ee4c52f0246255a83caad4f32ac0e147c83b9f4a85cd39abf1a2fc6ab48c81de9518808d896d0a24730f3f34754d1faa7a90fcd4e84660338681e214865a84ac391fc84dc8d6c60098f731a71422d38bfd05cb3b2c1c3504bd93f16c1b25c6a8c771ab841761016098aea7a040b9d5dba8c132cbc3f683441724ce23f68864b24dad7c8ff8de486b39921c7a052ee224206b06310e770b7caf078a8064a0782f4c7dfd40a1f2e114ecfaefcd7838f10b4b32473b5092940a823efc605a503d2a236d3586d78ff12ba5ee9c504de81143c6778e9a1bbbbc105684fa85a411d5312e9442416548df55bf78b17dbf52034c55e0557dbba554dec4c70240e0ccc02871a8a4ebdda422e2302f5b02c862960dac897a751117e4a3e8db78ff0b37253c99ec2b7ba5ea5648cc718a780d38e54370bed84381049570a8810843701677319b84895dbc1b90043b6deee48bd715707df168b451444919f26b2817640f0882a9347782232d50a286a0eeb115f80722c1cb4320e75b1759268c559a0c26b5397225e886a61b8f30bf07e468e449076eaaf4ee6e13d9cc14c98de77f52e20d2a7740df0c8b281ecd4cf8db67fe29234e371b01aaca9752129061ca2f1843fa758425aecce226bb902ff995ee1a2415877dc4cb27e0278d46e8770e803a7c9e2401301524c09428415cab317305a0f106bb184024eeeaea5f41ced6677f8a583e37c8de709035f7d17e017a3854153f4695752a81cc67f85ef7ed9ba24806a0df88fff15672494334a03e5f82bf50427aa850de4e6707bb2f9df6774f69bdba11b5a31b532c2c9b808db9e38d4ff3a8afd62af8552e25989686d34115c2cc198b2b5f620808c47946fecc59ba81337b7d304144015de3a76fc099c6a10f0122263d907f03c82582448257dfc72e7a9be526ade6841ed357997ae67eab1636feafd8d2478a3c1628e7261ede2786b53adb748eb55619039731a1d3ed6a9590d6e328acc35080b62afa582e3e8fcb02e86ba220a707db97c1e0b2d924fadcb25a3a479dd9ab616bb99c6c4fe4549537829ac5cf5feb1768634dfb97d4c3a1691b6d76f719d1ee28dcab94583e6f8984e263a87d214865acc79b8b1356195f43a2acdbc10c6523eff0ff81102ee75697097a6b91563bf741af02309d42a39bc2dac32944fd1a2114818f733e7a6bc275b21f71cc88835a7145aa5e316647f850936b8cdd2145d13fceecbf1345f07bfa8b1c0a9fed446aa8fb3926caa96b07e5c3f1b0d5ffda1bf46a7bfd959ef5dba76e54a75d9b2f8b3b407efdb91ef207eb8aed28959c5bc28a4e8fab3c33797682746c6c6dd1ae8f58c2c33f4fe63625a3470b8692d87fdb5e66c2d742975c78006737bd87cfd45ceacf88679bd69e3d6f9f767d1b473d897a9797f9044edb1e7d726b6ecb68d12292e177894c2245634688b375fd6f84deba14af24911da031341c8ed3e8db8dc76e3193af64e9703d531315e3d95bdd96b39eba1653c2d189c4903b3c6936076a39c609e939a80a804940c96a45fb72dbf37b223427a2c1b9b7ce7efbddebcc0f9c9fae71955fe0a223fb1eb34fb7dac549898bcae9a97ee066adb584f5470886068db6e03f8c1d0b04dc4072335d6e3d50c61f53510634074eb2811e9f551551f6b2e249e3152d83b2828f697dbe25c3e9d045fd2c348bd11b2be14d637d425c39b4425e1624635b5e948d4e0396a878632233835b19365cde5531fa25e6ed2b03f6400bb286c95aec26565c0f81511a516555503700f184e04bfb6ed7aeba9eef7befbea992c0e72154bc88123c0978601ddebe1cc4b54d4dfca8a35e5dbadc1307efee23b26894370b40c9223792340b25519e0ebc597c1da643a8f0b05650f1a82a0bbd9eced4f6e13ca6a52952677474b34f0dc473156d8c8b994b213edff0eb507274485089433dd001c7c2204eb45928eaf4c50fa7929da66940e4071e8bb81d7990a502f7680e67a6ddd565f4bcea0693cece3b4db18c07c43849fed65e34f3f1b8eb69f7c6fc3b872934101a3834ca7fae68f14e960454ec13b135836b00c5fee3cfc9052167ab95186993796178dbef5b30d702d42e757153bbfe0436f7abfc8e54caec1dfea02fbeddd961c5cd74c6ad0ac2e485c40832187de72fc3a102f4a26828f72aae8c282e54b09099360a2790ab098260d868d35648ef092b2d56f06f3e0b1b5d0fb9181276df1c5a5914d4e7158621e5edb16f1ecf85b5043081a04859218bb9126e2411367d529ec71d511017282474f27db8e78b220c07a4cd06264b30d3af1c8dc27bb8866cc22606120ba8fc32e0400af57695d41e1ec44b80f8a142a2e1cdaab6b894a62910361a2a0de0251bb502e4d89252efa87eefe8246312f31412dcd78ae2fe4e6115f32f49df893815d9201035fc4bad0630fad9c357984c4cc165d26d36bfcb388d1002734322d02e7e80ad21a413a19d73d1d46b1f65fe91756764b0607387085dc60f0030685a8ad85812c360344c290983e330d9308d0f1847f09204d97dc12afdbf00256003f30befd575485940b167f5811f2a43c630599fefeb6e3bc483a1872de13426d3d595c775cbd7b625b38611780856a385876db4b85a0e91368ef52ac02e65c7dab56da0a7a91616afaebe4838eb8428aead43b26589bd0d9f0bd64bea688cb2d7794cee916ca1f7ef807be93a6b29eba1e34f402efce22279513a248e263ecbe15bec014cddf4e7decbe30a9369613611167c541f9111d079e12cdbb8920f712a9f4b45c2aac67f21d713f662c59c4ac960b8c6fc2ae84125f57e832b1cce8a3de7c2c319c063bf0030c955341deb318012d3382e1aebfd01d1e2769dda8de97c318fdf8136fcf3e48479fbc7b17eb66bfe845eeab49817e050e496e014ff44949503a65513778469214a01175204d98a491241798152cc12b19a486b83bff2c26520e078b811a8435b09e391eed45858c316a29b11aa9c822d74320f5c895e99582f81a09cca446b50521c6ce5197ef57c5fa5b0592d9834c572b5bc6b3588756822ea214ec6f4a8dce59ad026651cd9dd51f91d4d6ea4fff9bd00579a1f6853a56bd2637d363e916501afc0a8de85e1cf6367264f1fe9252303c889708341764a874ba5c202d1e261b6c8a2826aa458ed7d18896ed5632760adbc9f7e8b5e570befdaea164bda37011d2676fbe0294f29a73408c4551320995ca8644ade70f0cbe72148e8a28f397ad92502f6ecacbad72462391a794fca26e4ec3e6acb3f9c27dfcf6e884eab86ed013ceb7c1d66ea64b5c4448ec0b86a9bc992c812a2f1149b78b3bca562deb029654691a9e9497a298c9a2bd65250c1780d751f177cdace995ad29621dd8b74e040d066071abbe5ae5c24a06ba282fe0904cc8cb2d966f6e5a238956f16a40ab553bab645efee57ec61929f4a31e595183edf1c5fc92c205d4675437741ef133e69e23314ddfdb5cf08b5d5afa143173c3789c8018350011649129e1d80b69ab15337e8173bd4409a978904904dda60d9488fd1c89ef55445eab4762d0b96ea028fd6626787c1c3db73bf02c11fb2eef7cfb70f27d41822f27b7c36f750e2c5049d834638ae2e90596e0b88919e318c73b61cfbe2544c58907bdf8a680593aa1ff15f60030751c43f83e601aa890e091d5469be9e12c5f3f54abab36ec57627ddc2fc97a9f3edbaa431deab958f5b01639424425d4890cf48e5f84c2110e01d2611a730183630f4b88b4d273d7dc5208854d649280982c3bdec693923990fe216ffd47e40b2531a9072a590083c6c69ba80d15698d68f5c260dfe2e3eeba5691d2644c93a7f6b183d10aca9a283d997bf4ec1e3bcca73100770323a42fd098d80b29fdb3c0e2c1f72369ace612eb144f27d122011a6f5c614f83bd3f775caf8846d4f737285ccc396265e3d03a604f183ead662b27e03509bca0b5054e8bec45c369b4b55a1600bd632b4d3ad32123df515f5dc7316e0f51ef8524595df45c8242af19809616c7ce1cf97bb83a7fc43b3cd68324cf0fdd2fbb80b5273a61e9895ba1a17d019db85f572a61c30bab3c2fd795763c8f3b803db8c46e3c39d90c4db1b45be21ff92dc947a1c3434978744bb89772c84ec6e91af8c48732f6a2ab1522c57d6351d4515a088a9d9fddf6c1731d7a7537b7e42226f8ee78f8d0c69c9411846fedea28af44188c2a4ff57f6aed7d4e53820fc3f349acc2007da636a4415c0db71202bbce46e23b89a237659c758a856ba2d2f676a47869390dbe244dc3feff92e8fb9932e5867ed8492d9d7d3f64984492b6a93e167f8108dcfa872ef7b7689cfb6a41a1d393d8ffad8c2ddc7b87c9db074d21c66bfb3eac740a3da145c639d83218372cc8e486e83471182102200349cdbb90b41f49ae500c1401a6e08ab20ce35cf0e240c97e65441f4fd9dd7c9f290ca6f06c6c0b66cfd6f8d979337a42c729e08a4fa8de5fff76fce82d31855f0c531394c524955b5678b7e21caaaaea6944014d4d92e5ca72a331a9163e40041c346b415ee7827678be229d4e8c95762a90c2a3a7001451eb03021d741c4e94af0d5d897e14d7a41f719b7e96465865764d2088ef9c8fd0bf88676365c9a895854d1b7a2b188fe7cc255d83bd72f0c8e038a11147af36984a1315ea397a60f8543a01006a368eec8fe15556e1676161f51e0203e8c4380c45a90bd8c44b7aab34181b32a959b0deffe4df3265e8d7aa687f810ffb5b43e6766f787b5cdccf7b7a4fdf303e106e1f1da99194b7173e266c93d4a8dd2330bb89bbb5a0587c864ffe9f79d27307470e9bc0171cc8e702171bd982a13c245efd1ae88a2e2052f25b960d039d8a449d7c7e5874a099a7cdf8f3f9ac603da1e68933a7eb224722c6ad978ad5a5d4cfd69094aab476bc67bf3f458b5f17dc40b413d17a4217d352840aafce694838b86281a2e74db87c9bc89814d7d4449b16ff2100a34f805158ab3f12d0965f50ebd10d711779b3485746d29311ca91f8ff6e085a70d5cb98e0cc31bf0a4f7f506bb8fcbe3fa8e0337a43538c086608fadc19f9ee14bffcd9152e6c4c7b2b017bd849103a127bbde3072362adc2cc996f072c2d838fba8856f4e948862ab3933ab2cf401ec078895ac00b3fb20bdf3b13276fe9ae0460b3a97f8bffc9298d7cba45f08eac078830259469a8002922b0f20641c59232f6a11d4be527c1e695609e9948af18904107925e39a5245e3c2cc9ecdcf342ecb1be0aa83472dfab615d4e0ba21816d9d55cb7ec1ebee5e37e7ee0fb303ce21e910a219fdd45f7621f5605581cbffe8cf84959b2da4a30741f8f085ced654277a409be4cfd1daf26d53379f4c09680a6d122e47926c403fa2c4ffeab23dc422cc562e253231c5248d7f5253a4dcd888ba24cc6a4187248e903a32218613aa2d6fad81722d4c12ed91da9ae7a3a90f9e58f30e0206cc191338f873d9387dc670461c536bb183f9af927cd91754d7a3abe6c1ee987001aca1425e786331993ba339419d724feaa507b258e19600bcf82fa309cb5bd6e1026b137976f11c89615308d247c0815c2511ec49aca7183cd0b1faac508c0c78e43604f57c5bdede68924015484e1188aa5aeb795d76dab9f544d04ab6a7b61eea4e1721d29a8b5d5fab590352eecc479392b9f3027089c620ac70d397f5b144b130f1f80c084e8a15c07e2ebbaa2b067defdafa44840f734eda233bac36c181dc5219648c29f81829f7ecea48a25b6d09969ec84907ef32e2f05e7ee763fc138c37ee586592cef238cffc69c0f807d0bf1a6c9049cf75ee077d567261ee5ba22348043035c095960b23ecc8142ec102b379cbca5f2588dd6dda28fa23befe0582999a72b9f73147d7e4b4260b30f5d06132b233a424520d81628000f195f2dcc793db3b12b05304e574500b09f4fa5f072761f50b9b2a8ec3d375d4889a0c647221d0975dd0a5e9fdfa64b181951839745a2c3e4c064d80eeb81b6d359f8b24250496e3b169f1e69486b953f7725448918ed3e3daf71972d80e543d2cbaaf834c24b6f604671732a1d86140c732b2159565a0b36c63d3aff19f5c11e666e5169175e6041833f9a6bb2349be120683b693488197ac61962a07495db27b775061487b60558e59ff6b5e8ce12e005eaec4319e656a19f4ee2884ca03ac6a20f6626332c192c71fd08264808b170431b1a21ac42e87217da941b620609e7bc81068c2a0ff6376a4429e00ea11a66f06594a240c4c3a307b2f2326c97adbdfec5b3eb5f530d7072ad94cb2b3432876e190d3c3b67b91c97c0be2533e78d2144e779531aa95fd4075f7a1d4ab37c4a713f4a80e84c912517b4a911525b000c8e6ee012cf931a6d003b78c01cbf8292d1520cbb4148c8edd9b6884f36611a59655faaf24fea1c171af7382297e05b3ab50472ee22c472f9135f1793c324bc3b963405e4249b23e2105cd39eb85c78b6f8e0ec96ed7182951feb08607a7143ccba4d11ffda940ad84a12acad68ceed207999373877780874948441e58b28eef5cde1e4a10db97718d1623819dd17d802b621c84908e95f1da4c7e1486dbd7c537b34f0dcc7c4b1fe0e2199fb74ece00e9798e87b35469a14d3e487d7eb34f642634384a9095b8bb4bef47cfdb363ea2717e52d76f4c8cf929c24cb76b1d9f22346628bfb324805e0977bdf3e401da7ba36f839988d3bb3245905f04923186eda5e998ee1faaf64484ca62576df4e568e3024cd15ef022fe9b9d2c0fe8c834f72795efb80c4957af771ad58e5d98f85b16966518b95ed5f88da2e0931f86a5c194efedd2751aff7923c7638e75b30aae9a14cc7a95e8c1a613c9f4c49c5e49abdb1f283c2127478b9c43ac74b1d0fe270c4b525d9648251895779f7f35b22a38c3346c8f74213ea520af686c979b1ef287239701b2c9089b7a29a53363d460e8a670f6995c44b0baee7652582f5c34b3757c2c8a4985b8f8cd84d641a0a8059c4c99ec5527ffb801432613c4ec8048a41264e1d297732278f28d31912804ce48e9af36fd090687719ca0333ddd16bef675b661cfa1922b918249c0c8026f859b3c9de0cef7f7d783a7fe5a59e03f37aeaf8780558b24c68b83c2aca295d9f7425d748441b91532dda9c11e0bd2fcf01eabc24ed6dbb34c06039b75377010d08309c456bd19840d132cfe782e568b428e79e04a98be8e7268fe782d295a110ceca78a0f0b7e294c2c3c1a7781a0e6324c4971eb8f74e4a2e15e8ebd0f6e2b7836a35c820497968b36954268cd8ec45c9c97cbedbf6a8ebc51d247ecf133d1db496e9135e8332302741e2adfebde882c7a12c86b3953336458b438ba8c85d8ef6d2c626b882f955ea20b712d3c7feb0353e9c65116789f17d3d75a3d17185e9e0f2dde846f217998dd96ada2079dc9a98c705ffc201136fee3cde5d1233d0d573a1d9064031f242a9fb97fc0ea8e96afc43297318b7a1871f04e50f22e0657d24ddd2020bc4450807c0faada72edc2afa3f0ffe376d6b828d68bba5e310a8edda37fd02aa5277483c95ba041a2e1866b6984bc0e6e90fa5189cc5c710f3f55bb83dac52cb6ac5661a98b8affa4257598e7eda68687cb13434b3341cee0411cd51ba33875f6dbccc3e5c5d4ce955cbe1e49897dac6accdefaa5e5e998e8a358bd11796780bed736a0075c689c28a0f1468727489e176df8faab503bff6d1e79ce719649a028e0955447c3d3d06703a1d4050594d98478546a73fde642c81d3345c9f1ba91f8829d469362785a79ea4264f7551908314420ea22e61b3b501af02e561e1bf5cfed11eb49efec51ee07fb43fec4a060493014cdc3fcd15296bf881a11e5537646d0e2a74c4d4800e08716d6a0d674e5aa1355da8094ef2fdcaebc4af35ed0c1bf566b1c018571f18a5b82d5311f51b7883ff0d27df2e0ec21a89ec61518a442e329139fb082e2e1498e45795183bbc762cebcf1d11aba08438c4fff6ec8d6912f4b30feeda9549cb3e348a5919ed38e23b2182866b001f720b3114b2de81e631e9862bd3af6d40c99aa8ce74e38b4d949aae0fedddf1192e3d69ea3348355d257f8ffdf8c493121017589db77ad2c3b168e2c2c493901117acfeddc101598d788ff16a1062654d3cf95d7e87cb801a0a5617cc358ef029712449ba6c4b8dcf84df8c171eddf1cdc4d8f5b27b1b7550e006e1a56dd8679c9846aee63082970e782378d9cba825b8e9817844037011472678d00339dc802c4990ebec84b624a42131e11d34800bd60a78aab9790d165d469ba78ab4e7d795456ea7864418fd195783464dbc73c0801fef5674bcfe17e616af9674851c8ca1b88a67ecb545a60145553920eec380f62ca0c40c39d6999fb6ac240dae3ba4cdf776795e0ec4d503a147f8aa2f781d1805ada39566a10cfa89e7c47cb01bdfa13fd1176e4a898a8ee49df44557fce3209a24f3248cdae83f3e7a6531c3047d8717ba1f0946f1edc8d3f123eef8fd1635cf75f800c6e0229bce2a280577c840bba1e71668082895ae7edab4c73077a2b28012ea01772dea1cea850a2afa3d4685bf50e3faa93c089a1e2b007759358234faeada36427d3ded98747bb75e7983b61e70c7cc6a8e6a4c58f738fb5f068a24ea2de04a87fdc4ae2bf487163d4c39c9e96bfba92703634185327e19225bf38fb0fd7d1da3e9a083bc39dbe7fccd3dd9c017b7c03bed46f7377799307069dbf76b7c62ec6ae920f915a862b8ce07f483637000dd2aecdf9abe681fa49d49f26e4d93d675c27a3c787a5ef88d6196dd7f15d7a876681f5c7b004d8176e59b4c0078f507b05e40e3c8012939f8063a3d0607948a3b41d0f09709a0d090e92b08272d9471af25b8ee26ac8be814b9da1da32e9120b41888895569118b60ce49a3fbb2a5f1e3af8b9231ebe40ba397bd5e8355fa1261be6ef9daa8fc3bcf00cf58cdc32eeaab007338083c6e4f216002538dcefe065450bb5086b25d40e8986240b88bce6d9ca2f0b82d4d90a38d355eb3cc2100374b48a905f78bd4029d1f6ea0384478ca294524da9cc5902e22dcb75f907e84a1284976fd6a9f07ff1500f234fc169dc1c3314ca012e05b0e201eaf8a2e4e5088a47ec24651eafbc2b48a4763c8b7947c0d604456ca70a308a5796673c4279bf8ec8c86619529289e87938d568d14034b23c0464cd15d4f8959cf2d63255d74a008d444b70ad136fe1eecb8c9c8c43e4fc2e5fe56593972b1efa39469a3cdbaff908de605ae7458ad3e94aa8ce85c7f767f848b2290681122398abb84471a9044374d384bd540faf626ac4b547ae0f8e39eb1667b80b100b6f76213f68c7eae908773c0c3dafdf2d8d708cf2f34ea93ce512aef77e6e702993f6ebdcbbb291ef8b499e0278e9772c6c0a193f917f926fec1d7d62dddf7a22a81e54257a6fd9566f479d3ad264b744589687eb295cc89c38685ceb1fef8db5eb61686cdcf107dc13c32ca234af58d97753a7d201c91e9fcfaacf8e0ca60c620de68577c95426f46eef0372a125c9c8829172f1165b6117a0ee8e1d3e7aff791c7e1dce0a553c7e0fe4a0e71dde8218686d277937eebb1f394d25a7bc660ccaf1a8112de3f71255655bd7f1811e2484e6cced8a717c10ba2a1976c9526233efc3d080b091293b083efb6b0b7d04c54dbfeaa9eff9ade1bff49b1daa8fd9b09803de69fbe5abe21531f2c909bcdfe09474d39342a76c3acfa507a113b4345b6bd54e6d48a0f375f4f1ba8840dd6ce4224a28dcf6bbc50e88b85888feace22a20654c0ece3028aae8d3d6920284c2aa335e1e5e0969260ff86bd710967eff71e45ed1851a514e8fa595446ea654032504a106345d97ad12efe7764819e654ca5f4ddad868a3d098734527e06148d48acf5cadab2b6aa4444574542ae1449b00ab8b6e4220de8347680b3d8363368051178ece1e6e35f40e550ce3dfe78d9b19c8df3151f74b388044ca1aa0c951f4b1ec713d08ad0154e8672fcdb0f5ca0b81b23b7a1064f90e88ff9765a7289b48050f6458c09d1373aad91510b38b09ae2ac58c423af53ff698dd0cbf75acce0e3d14d8ab6d19fec1c92d2635666748f91fd9a1fd0c1454d5a0821c1b2eee040f91c22a610d98182bb80207bc2cb6e5ea108b8b44f020131e269942e2dbaf24a159f6d2f0b49ca8eb82ee227d8d15c9a1a3ab20d2dcb4feb5b2233c2af8b9ab555c733976666fc059b1fb39515a75a26c1d272ee5d173411a723b2e0a4b16fb5aabb656b4752f7705971d52296b9400c07908c01406bda1b4e5e21630a4631e71cca55ad9d35bb5a4cd41ac4774bce8ca76b08ebe2a455b1161719e292f945ac8caf54e0ec0aabe57bf9c74cceda24b0753034dc560ad11d9691b1cf9c86a9f3f3153f99092d77e9f1a880dad8799daa172199685322cc8ffc2bba2115ef7ee7adaa094e4f2fbc9b70a6de4e3d8f48fc3f8bdae12ef88664f710a436de7bcfd0bffc58863873205f25c225f5c5120334d08236c85aad2cdac2f01342b0ad4e250fa78fb0d6c3fd7f3e08d1c1e785b38952e6919bacdec4c490dd8052246b6da0387e8db2c600d2ee8c5a6740bd60ba3c89306ff46d4c497aebb64fd0018e7d94e153e013d5181727db668db8b87e90db063a251b61039bb4ed96612766742eef645af236b693b1a3af31168784e0d1e7fc2ad9de8e9c73c9cf907e6a6f38c3324cffbe036dea81704acd8339ed6664a4146fc309dd2c26c208ca2451910e8b759ff4d1b2caa4f3d04a53ee2608537953b626419e55c82443e1340b43f943dc2b0a35e94aa3b0193341cfbaaf310ff55735cee8f43aa7bf348820b264a123e9fed8d01b3317068c8a110bf7281f6081fadb4f5d1d676a983d455ea9c1cd1ff22bc60bf94826c89c45c0a7bfc47b7300d62d5d2b259d1fbd33728cbe75a0f404ee00e8a89b7e13c380abef06ecb618c97d589155aca75e1e590389fdc751d68ca534a4b5fbcb46ec60f7d2ef9575557452614c3e85cde9840c6686e938c842be404f5d413141c382c5c1506d16fe4e8e0bdec126c906d9373291db57e3678bc0021340084fb001c11370e6cd631b9f8e465b380e1efeed31db0cb82e77ee63f812b8e3063d88821ff21fef937b83388a939524bd5ff0d718c8ba5eac2e6352bab44b6550522e4892369ed32b0f82fcb2885085f322c921827ae294ce282b9a1f7422f670f6e5c20173109fe7ff9d55f596412d74452b794f365454722b0941d90f182bbc025140e00c4715692560644c480ebb69e1ff38b8b8abcdaeac5d1ed6340aea581e0ade3f2f3721ce015741b3696fc90caaa8f16025021252e72c544b4f244a50aac5956bd25cb197b6a64423ad3fdbbea6ea4558a91e6e9ad0c53580ac05bf8c27f441455789bbcc6bec039bc8c262ce6f462fee7813b181f4175ef0ec247424591536a2497d48df94198e1c6bd4b771a6f1ae7fc9aad425df187b32c00d45cf04928199fe94aa25b6a0b01c81301737f1041b0d6a3905604b81521fd79041c6cb174a321cde00153732f461adb08d17875e10ba2003042a13ec1f6b1073932210e28843a396baa979652bcf2ac10551759f30be1cd6b5ccd4187af289280bd39773566e04d901db92ea45292afbb9ac0d118831fb098848433cc2872a066fdeee7e492271f6522d9156b7a6d867a04690c83d531724ef8157b866c0b6c32b0a87466d2e7bd1a5db798db3bd242f19b7e2c3fa97c1a84e93a1f2896902c1ae9a1ff45609e269edb0c5fb7d9d454449435c6a2724c70a1ad17e49d787015ef30dc8afb8f8386cb324714c2fa62afead58d41515a0e1081533ed3d9c201f345a0342c473cda430dda7a1bf6d074c4e18945cab26f4f5064ee861eb387af3b4f0bf00e46c01681f418fe4ef9a674b1af2e33f9d3631e486b419d771b4518a8ef554b8daadcf1d6dc89387a956aae35fb70b7264aea5d3f4a7976fd4ea4c0135fa1384145d725bc54328cec3fb3012b92c2dbc924ef49dca8fb0cd8f5aec2c3fc2458d90623cfa64e5d80a3e672af682738b496d621d88d6fe90ab98b2a67380fbf94d89b183adce7759f0b9fc8f9b4b033775f614d39c9842268283c5d9a8c72f727cad9e75debd083ee078e2299bd06db9d7cbeb9fd956f6fa788f3117fd03efd2ab1ea9318a1cc763c15f1e451cebd19bda27e2b13cccd9c03617c3507d92c755fb69648051aa54124ce600fbb17eeca71fd3e0a9b7b1a8a8d07ebc361070a000269378d709285f475407d5f650c2a55b52cc88ec033952c7f9738c52e48cd99567e76fbd763458e1bf4e3f49f171216b10741ceb0f8ec102980a33667c54696a4bccd15dfb44f5bc7b17f9f721a4e1c73e8f7b2a3d42b39c34138106579eaeda974294b2089f5c35ca74968307112073abc16cebe501111bd44c50278e29d0fe16517befdccc0144630377e369be89501e0183bfb51f4bf2482bcd077f0b7b699816ce3f2a55cd1df4bb828f237b9e53d59ad58ab6601ab5f09e7f7c4cb460d6efe0eda6776d5f2adbe8529f617e3ac31a43e6dfd7f69b90f9f10d9dec62307f5d92de16ce1034c446dc2c31408687cf46629a29ae9e2f3b9a7e6950a625cfac5cc062914bcc911cd8bdf202bd2097b64f575a71129980029d42e81f3706f06293619713b631e270bc2919f3e46ebcdb3eecf519e6bafd8b685c6d861d9320aff5359fcee1cc3dc5f922f08bacc274a0c092bcea26c5986b32fb7e39f66f9c58e59070784c15f08387780b183ef648eed74abbfd732e463e7e4f073870aaab0d6cd5b6c45a5d8cfea57a3160720cee1b481ad4b8330f7a15ede0cf3f4feb4383fd044d5c0fea1a6c865741d0c82a78950e786d7251f0930923090c1a70b79c29a01136f3d2f78b67e6ded29c42af5f90b210a75a5d4ed30ade0841384d27400082c72585bba35d4387e0fb1eb512cb483c8a58fa970227127cf274b2a924a01d38b6dd24eb528f2a88785712662e493e398ae18009bb267cd6d50b5eed0120445e1857632df158af32447ea1dab1b3a9de1f39cb1bbcd8d0a912514fef48fabc584a9e70b62c4959434ae98333045f194093e9b4978e5c283cae849071905d9f2552cd9374c460b42117ed74b991686d306213c7aba098818df6e92e281cfea8d0809475fb5186f52358e10fbf20f711f6f6f4fcabd3c55aa703276c09fa05238203821dd466053264f93182a1e29763c603706b03a8960e8e88a6c1ec5edbab34417d8f3a0d0738a187df0243eb089b63f1ef4dee9db01008fd67568a91bede59496709dc7f7aff4f223ed78d1fc5c54da89c18b2a18e4fe36ac90bc868b900975fd8ea40717dd78a48f48e5c4ca6db3b7f0c0d122ed9d38b992279bdd569eee7feb9403c5582bcb011baeb1bb8e464172e730215c1dfd8b72c51e2f786e325bb470e3246b818a51d16786480e4c85ec938703b742a97921681464771f0070d49dc6f6d27f9de6909e6901c5ce0624641006e57196c3a83690c40dbe29c74354b2be41355ea2830f8a37fe25736c8d69ae34a116150e5f4f3a398037d045236d5e1a4811becbe941b39e8e3bb659991c7e81cae057b8792566a751a7b546ebe194d4843c789d9c268f8768b7a01505c178c332e110295839e2fb0229fc9458c6b219bcfc07a24171f04f9f3f989f249447ea19fbcb1318fd74ff1c49274e92793ba6774975ef9c59385760210ade13080d9d009662c7a41d170f3fd298d712b32e544599b77b098ecf4f40efa029866713b8fcca06c629b813d5186b074b951a1afbc4f914f2e64c75d7fa6fc7bd3f185c908c68a260cc78d0fd507a6872b24d0deca6543d733c63a6b31121b02ccc4ddbc9ccb0aefb84a7c15ebd99b00150b7d3390745c3a7d399705c1803618728dec8c83ebac3142ffe1e994481928de878b93f781a9080c999a50440ca080b8f8758039e62c45a0b02403463763268529defab3bd5ab5f77ccc17a6c7530e6514bf0c697fe79f5b496a3b7b3da49dd5e35453417f615f5fb0fffca50e9ca1676f9ca60b06702581e0e2ff797e4e60e25175213c13df17a7151fcb7e7156e5a9ecba9d0a4b29d01ff3cbbd8e61e14d62193d5813cba6e3c09102891e151fdbaf857010d355cf5d4ec70853af188a6a9c39bdc7c4b3100fba53fe6da8f40f0942633a657e74ed3f633b67e4e9cb91cf44b9bd0966803f283913f33b3eb9b4d6509ff0ef65653bf5744ea2ff16a6deb53503a7bdb8e1f62f42c2bfddb86eade0e663b96ff44493d34d57dbbe9d44fcd8f98e766164647ccb444a44f14da7066a53d8c9bdab1352385dd91bcf7df835108f7c9ec18b0bd1b0b75e88b8f710f71def527ef31c2ac36ca0825704bc63fe5632008f6ac078a45a75cc6c180b33ed027cef0030f7279d978df3ad913f06f4c3ac54dc7caa02d6c00cbf5b11ac67b6911f5adf2b61f9428345a7bee5c390a3c362a84f6dade6dde877e69043f0f43dea60e25a80b628d9ae25850f0977fee1bdf660f0548e18c3371d4964003923515628aa355ef916b3ce5b6535ce0ebfe3103b8edd7bb0e4de746ea479e0cb9cf6ddd37ecdb4a870077370cc5dbb90f14527c811a51c9beff5283b30b81aa7f19ab0a578151c3638f72ba950e4c0d87351f37e98e2358d917cfdc32925970439ab61df1830c130076a5ad3586458130884c937cd93a421d8bf1092fa89635f11123cc118bfbb2f7abdbff8187967ed3daa70f0ef99bf02a06355e49724c53cf98d91f044da27e1c32901cfca402a4b7a30e26009e912a38f2d28b5384cb373535395b99e1b602eb8cb36c1a913d2207b9c7a957dbf279ff28c5dcc353b93c75ae57e9ad4f05d7f41ce5cb653e9d2b2aead78561dd6278e029c646c767ce6f3f4dd5a169c89a2a1ae3e01748d22119a4bac914c818bb6bf08329aadb919e544e18027667d01a080f802c914bab87846fa47181435de01ffc729d4ddce0e9772ade3b50adfa0c4cbd3bcd06bf9f4084a5cf453eb786e8397eac67b255a99cf89fc29acff897ba4602eb43009c7d4d31b9f938d5a9002881fdd8f7eda344392163b32a2f3805a075f4641b9730ba99718eb036d0e26694deb7a77a01cf721599739b7a509abf1b31bb09307245cc552e0e706e20177e84382742b82faed6896ed95cf46e797d02f37b0cdf2c3f65c2594001c1404e5f00c9b8f7ada00129570d53dbf93e3bed946100310f507af0d4e8e68bf543e58be6b1b00722ef39e51dab53f7851b803a1839bf81ae3e8e3630140bd8ee08dff49e6c3af2d89a86117b668ce10f543dc9e19c4b6a93139045619e36bf6d6b091152844a58c427cb0c17feeb0e723e6831ceec3309c9a1f3525945d89e2e87e5287ee9602221ae55143d9689db7c6d3e01f4bffc4210260a1127b18a15afa57301229fb78e50b0210ea0094900533045c11fbfa29a0fda065f54ce88270a00c27f970c1d4a638944a0f3aa269d792005222509e10a059069726db11be132d76df393efe38d0c17a7f3d7cd32b03c7ba5f0144b991dbe0c10d5dbb6cb22a293e29c3eb967a616c3ba827909034442f4134c125a92f38928a9691513e425036be38a545e6ee19c6ae091a24da32ed88e578131e4b6fa787f98d628fc46536dd84bd13b25d624aaea0f64575d4c90b3f881d09d3e8d16f67383b0dc374310598e2b4e68add8eb1738d6620651c7fc9c9b9ab2b8eeae4f5913e495780d7771763ddd3e574ee2456c23d9ee4a97871d095a1ab84e39c5e87e90e8592524950d7c64223104ea4ff458c8780c712245ced0c9a225bf9886486c920040f172bebe25193b96bca78deb6fbb2e91ae5cfe1f0358caf1df8c531c4fe70c008002c663ea71908f6b01c3e8c1343c533c2637ccb2e31b6a639a9c7a13433225672d15ce48d953e8426213e18a5b8ca1b21c5f96f7c7c403e55fa754893a9d44b2ac3a4a881aa9fec129f2cc16ae302ce7caeec72004b3be6fb35d7e5af552e49002149bdabebd7355e05c5e9f66bed8255a0560fc4fc6bf5dfb32cb7d2e822429a0a43c6dbca222363d986c5004d4eedc9ecb9e8a72c65f318a22c62e3746a2357ea2d02f52bdca1137988b80b3e507599277a8abba4279ae1c54533ef95fff2fe78cada979b1015b1fb936844091125f5ef0486a81a80b4cdaa6f9aed9fee0d88f037da901c4b44bd6a1973248bf83024ea59e9c2f367bb51c86e9129ac3d93b5699a9b30465941525bef5ac5057888d988cd93734d8199305ff3390a508804340fcdf69191041f02cf3dd43060685f54c4112dd995d6bc8ad6b988cd44f449705a755ea6e87210c88df4dd03a592fbcc516c27318e32b8c108e1c26f0075eb2e31fa3af36923abf13951c20e15601f167dacb748b4bcecfdb0f7be1fe4af430eadad7e10c293ab621ba633bb216e5a74375686ad689a9c6a300f7863605ecda713dd1f633425ea0f1e5e33ecea7308969fa012c00c617ffd007faae06c50b0a1fdec08fdc05e2d45ced12691aaef971e12732f643a6e8a9e290d7167363ee3b30f2fb29ad03f2cace19b6981ec8682d326c875c71b4a14c225f1a98be3a609a7d37d52b0f5b9207f3794a8336c194ae465fb97d903cb07d2fffd2cae528f881aea04065c83d28d6f37c3cd2e79c9c38cb20cc283d2b1c264e7c9301bbad440bfcb801582320497c020d88dbf480fa08998abb78842711c169a2290813652e52183b411c7af822529225aa5a864229b7acc7dcf823a1f1c3f090807396cd74da7527c2b66d5c074d2f81fa95a9ae231d05d6b4bdaec2c72cc57a9cd8cae90863db11457db4f07903280f9f76a8fcc01299d830881f7ccd4cb5939f5b977e108fe89c8ac07d054f59722ff5d5b02f79c9a3aed4240e36bfd008937830e8798c89449c718451a6d452ab953a009cb7839f8e42214c91e8f7fc043a3da5e10f42607fcc26d1b92e60d1992b940112a9181dea2b46a6434cd7624318d313e6af0632030f6e67dbfaeaaf5fc48778e8c189fa879e257e17f3d444346f55dc2c8e53a6b269fb8c3723b542e59a7e218bc010790c9c2d240972a804383f24986695e95276045370c106bcf50cdea0c3f142bf63c0d7de2f345c2e88770e936c7c492c1e06232a4ee06842d393efbfbfb53e83edcc9cd09cbf45715f3183678b9cdfa0fde0767f3282225a7ebc079c34979970754fe31cb5d4bb276574692db260cb03c0033898eb285c9f80de7ee41b62dac2764a0890aac4b03344d524eee1e454ab10dddaa184a37be408c96675ab60e6132a0bd875e4a2cee04a8cd8150264da3cad1eade18fc844ac3d646938af3998aa1d931647c8a085c4d7eace76421f61c758770893d871b26443556b7cf27fb528ebd938883bfcbbd7b038d05bfc28f18905230f27630252714df369ae55b98d488fc792812ccbf8b4cec4b9f7d2311a27150e104bbc62139b08114e500117d56d72684e3e7ffca5a1adc903ff621a61295b30f4b99fba9c706aee725735c704b2fdef564ece9939f6ad3701abe3bc9c55642c58107c19bf7625071298c161d749af99bec60fabfdd60e90216c22e51e008ce0b0c2f158cf38660d7a9b470ce3d18851ed3fa2161b70b49ab047f1af704a9eb22fb10189116f4165d9df3ebf7ec3519c6224afe30fa423c95d1552432316a688f338c3da500891ce64179c24dc1f4dc8d9e8c8527985ba37be8121ebe161fcb9be4c4d33eead0871201d7054bd4fcbbeecc2a686da184c509fc4a3dee2fbb229b5f4d0bf4fbecad7812ca6786e6fc9cb069b794d0af441c31349e5e4e4808cf844e68dd7e9201e6ebc6351abae7bacbf147964cf0206d2e6f7684978bf1599a4ccc2a95667289810206f8ea7a798f1d63c4bc05acaed996d1dd13a7dc01db1fe1113f7fd6933f0be28bbc64d1623ecc75c251200b7d4b3f099f20079459e3c811199846c2e04334f1baf2b851d5b85397a417d3f912c5cbd79239e2a940fbe9187b121af2a271a0fd619fe11ca70da8875578c4cd5b4c43a1080785020d990116269a286a40b32e3c8ff23069f2458a7c98c840bd870bee9cfff318c058103d45af857b7013d86376c40285ce6ba9013630d1548c3df76de4041240db7f230a5476f49d20ac4874903aaec6615dc0eb9018409874521175c561583b3f09bdeac4225980e8a16cdf0a30b2b8a59efdc2acc81e388dd46ddc3a3f9ed18e7140e9b59209c364b131489fb2dd7d5876d4734d1e6c7606e012cb880a6b52fb8e74d388f4d19686e03a9c6a000683bb0e9d93d0cbd9dfd5ed4069740accac76145e4683bc4d0da24cff5d8e999645a7dea2460d7b334dae47a67980fae6127286cb6c62160c00d5c45655c002bc977c17e60e24d269091400a9a0286c8561dfc879fb890157f80e3828f8966481162b4b9522af29f45b4666c421bf60bcd10a1bf334cb1a6bcbd4cd3fe96ca9740302a1813a60568855ce0d49af63b038689d7d73dfa7b43449e0d23df684c10cd8d8f5195b8439f376519cbe039f1dc723506d1d95085a002f213d051d669ed403d4ddf215f44733fbb942c689f555796290c1eb1597b0e83d3c29c3b697e8c001e9c9f9dd280e6b0b266db9ff0fd02a2c1045fc97e60ac45bb2a048bda935b3ead285d3281c58db68540b8c7c09c406d090613bc65fddf1ef858e6850a457d65b3e62cf86119a5c88371b3ae529d55f09dae156735757b282083411e644c91cc8f7884521e8e0e53c7c751bb271a1427da22df2fe082d1a566f4387c199ae442a6f47ff489caed108dbd9c1946cf0d209e5e24865732666521d6c7ce41da45708ac98493260d93e6811c17d1d6240a9c363259f2c6875f03b23c22601b652ef61020065a2616eb05fc43e41bc44f3b62b4e1452902684cea9e7ee6a2c96449772af2888476dae4167f3790449db107f5a304afbbfc51847c0e93155344da5b07bccdacd91dc64f8d3c15e1644124bf709b24db72508bd107668f708a49c784047b20bb7ac09dca89d228b38562303bf91892de1374d08c1afe6fb6e450ac789767cc706b81f7ccecbc92f13a7a2d928eb4f27d36ae9b82a60958fe6e3d6c88c82a4ec9b8f48b848d7591b2a3c8e70a711d982488c66ed4314d64a94be3130a957b7ee3dac8b64f6f31374e2fe80cb46475f970ef7fa1f94247e285f8e278c2a9e786b5c8a8560087935d8fda225e2f49a6fe3e4dc3081050e5b8ffad814efd2a4df54617f9010d254ab37eab8e8960ba4ea49b9c3031a32899ac86e1e5d6da55fad3a2f0f4fdcd8bbc2f349609ec82f4ea875d0476a7288e83239d9cc961695a7008dcad5a92d09b03e3e358d31bfd355b58dcbb99376050ee169b87494063280412e5a458619804b9a04aee3eca07fe1c93a70555f594f34f4ecd01d6a2f0015e7ad80752d17709105e7a4972ce1c1f269c57beb271e3f1ce22467e9ec31e93981b993b6b649338f62b993551a8ba833be7598e77d137aeebca1c54d7b50cedf260312d56111194405d5aad7e4cdf08c5603c054e5235491364aa6b8d8eb02013339649784fba687faf7ddc84f5e47acc1b34930ca38a964d9b23fb8787268b1b48e8eba33dd9b236641091c695e9ba0597856c33a2f652eb9db010e00f6872d1d05ae86b2aabd7c520f7beffae843ff58f50daef662b047dd629fb3a3d1a48703c6f1555fb2d8c49dcc0eb452a65e5e131d4da778895af986cd27ed46ed2e90f448378dcc0827c533b7b14e3393301253dc1be176323820fde6e54d96e72c8779fdd15c2765aa8d2cd635bf21e87083e9ee76b82131f5f3e03cd500b397c240d5e363c3a5afbc7cbb27a8c0bfc23b63124f825839cc48bb54368023dc316689ef78359e6c086dbb4330acce28f30192aa66e30e16650f8aab08a319f3080afb0e4bb580439270e434438a804305255ae6f3b8981b3b8c2ab57aeac693dc63b42bc83ae6dc639f16112a4c7d9deaac6adc913ac5d4a591fb43f32112df83cf0fe849c8ff65f7afdf6fe697d65088071ddcc922d6633cc28d0c363a7ea6c8305ed6991885c8509207190234448baa270705a5a2b0e3581648f7346a5c6988b42dd59568116b13d3ad3244da4275a72444d4c8e96e29c4ea0ce926b510513470cbfc662530d58dba42402af5e033690885dedb270e4a5f501ec447c40a8a6f1dd025a2900d076947dd3a6c78e2a3f704411277e2787e1e038f3a7f4a267f64ca55bcd040274f5ffeed125e011413feec35a196a1eb0af94261aa50ba4db8381e1bca8be9f439c6c189ece18973f77070bf2a9368de35f45f971efefabd2d961dd4b601be969cf881e9484cf806e741f3da7cf3840ac56b1f2911b6954bb92aaa7c52eb1116145f62e09d8f78b7bf4b04eb2bf1e1364b3059feb0120fbc55cf49fe2921edce2a102afa12d90ac5198c36fba21afb10f6809f38ba0942b244c196620b4ce9ad685b2349f012b093edfda4e60fb07f899cd94ed0c939877c142299faa7bb2e0124e4b47f0aae31edccac30b99babf1dac961299e1e3bd71454d3f104c6d45ec03e682984e0cef92bb25d633d15e57282cf6124ad4b656a4ddcf4ca3f2a51880d38454678f213c4c8c4a6c45d51bc205a965a8923a8081a5aa97a2217c0ddae4b83b40b28b930a7abbfb70ded81f125d61009e3e76555fb0fe448de680d19ce8fb0a017a78d25908a76c7cef45412041be44113c1a746a7c28f680f91bbca13584b830c6f1873ea19e468980d7243f0f582be93404d13c9f0eccc89be85d29a870a24078442badafcbba90909530391b4107f271556148de34bdd516dc559b97a9e725160eb2ac993d8f76d53c5fd4788c3ccf6ccebef253f7f1fe2a4bc6ffeab5d26a6d38c0f48109240caf483325093f56cd9b060edf43eb437261b1648a62a036f275c88e80bd56bdd4ebb18f14e96e4eff9501e15364d9a0cb7635d92ad4939ad41ccc3a34ae226a39259df5f742139ebc52f8bbfe903023c6bd7a6c29fff280376ded9dfaf44d47e65a17384a7bca9022a5452abbf10778a5f762b032b280f6aebf4e733d5df9ed223d45f70c79df0d11bb1c6e4a4f9bf33858b600122faecac8590de847a1da2ec60d057800592d0a85de528a30173ba3cde45945216599ee498139dc38e7777a75c981d6bf665205eb5595d0ff8dcd999658c1c38bef7f5be028ad085382878f9b7ae086616111c16c99476848a68c0b088f72af407ae773bf9f8f16ed78eb631eaee87e60617aebaf88ff75ce82db1429b2f4f6836e34d01a1df5ab7b8b652692da1a59113710674e82f3b8b1f1af734bf6a84b82f48520ddceac576bfebb346476fbd69f9831bc8f6fe8cbd820fce048888f5efb4f4ab399ca442022c722bccec2e0b34595f8c554347581414481397e0e565f7daf4ee68741f433d6ce30bc898a601c63c8ae63c319e457278f6e6c15ecaf3695798da5da65ea95f38e2a5d6be9d8276d83681ffbb7a288828aa4c7b313ffb5f12b385cb8fbae2ddbfab2de7c2ce3de015860268cbc1fe3e4da6e7d37ab17cf7f94044c56b70b89ff789ff8049ca883f2aedb9621f24ce74990aaf32b0bc4b46264c06042805f7f86f86d06346626522422db47d268fa840c22e412810dfb8831e3180342711d5671138c800b76848ca8db1cb4b00f3a6932c058b63690a1a9bd2f4a753536a1b19de2827e47e589a827bf2033fb886755f1a0422a5977ed686cb7589c83f39448603fff6dee9f8a5d077161732f2660a5da9dd3a4d71ed551cdecc8838251e455abf493c68b89270c66028860080c0436c6f345e7bdf33dca094c244ee885ac2d6d5c31de5aa4e1f947600be7b35d4a2f137afd088fa84411aef2df49d4f9bdd94f7f37757eb6612209afe62c802678f0dc52b122a30bc744d8df46918e535559af75bf63f47e2c8a7668c8ec66b00fcae92114e3357304ab18a13151579da7fb6b55dddde8faf9fb4799516a99e10c7578a5c30b6e88f8af80271c619b4bd994ae2918bac92fe8e373201d620b8159801aedf83a81eb858db35506ec9cd8f2b586ec7bec255ac752bf5f2a7e1cb959f7163bb7f95dde2a944f0ad3bdcf881c18b5c790e1086f05d678f0e18582e1dd3d0d6d7f886e13b77c01a30fa234453dd6ed6f388899d9dda905fc78122343b6d3c35c63a0af111fd97c2d43ddf0a5d161b719a9b4a6115f5f526e99e16e8c3e8de68212a45c01a5bfc236cc808b2dce2b03cff99e55874cfb7fe308ee18c5354d74add21ebea2e0d16726560ce8cdaf1558aef5aaf7ced629d4733cec21459e18a91ee6fdf24d6913d08d888f2c559661d59cc365922bacb20c424d34d64d9e6a3e45eb5718788bb40cab4ee91a2c691436db5b1b97228f12333b42b1b117861d663b5a3fbd33b970502938b8d05a462332aff6cd16e5a00607d66e0085b639bb42efec6a80f199f69bf70862a50a886c744292d44f0a10c3a680b8cd8b7c4eeec11b1adfada0ea61d0ae1455dbd991278ed6158f649b0e08ddc7c5953b2df620d6c8bff58673448986ca4b0447df4f4b8fd523d000414ec5f3a74d9438773dcc5508695859c5ba8a118defe46142d8529ee471cdf65b64c31e73b232ebcd48f024ff73c5581266ccd47c490ac8fb59ea36089186d6b8889309e7ca31dbf8c9828bcb9bb93dd768737378fb55af07ada1b7892cc2d03ce6e4a9ee35ab91bb5aa5499863cf59ea031e41a0eee168b471f25d2fa5e5c0dba0fbaac0173864c3794630ccefc5731671e6c022e66a40c206ed5b55b31aca0b5963fd3348b586798e5bd5ca944b4b76fb6c54be8dd405777c6d94a6d2e35d195c02315420e7b0354c1256a6cfed21a2e7261838f7b4646217b5cd8c861a5dcce76e4493eb144647ded2ddf821f0e0fd040ee13e3ee7d2678b5d43ef7b7c452988883ae8f7fed70bcf00999d0b12140cda6ef61077ffefdb7bb012c6952cb491f10c7ae6fbfdb473f11d3db2c8cf970f52335f8dcd84472deb50e4defe2fde6e7ff96ce6b4f71c8ec783063a52627ee36489e69f6593361b01e0390f942bb0e7add0b26552e3355074b5b7160518ab66f21c19e22c54577da7b92f6609ba16a16bfd24cd1a4b5da436d9ea13d59681fe39c8d44c8b7a3656db70c87c3c2be877a605e7df5ec61bed3640f7ddcb976c5001ef0f224d1f58321bd264544cb140ea40b04587cbaaa7c2259fc4766bb0a66c8a9745300980c6e4914b9c9c9592b8b11451cf532c166c0176c766c99a8c53caab98f77a7842317c9106d2d111a00c7580bcc04c996e3030c00955a25fc1323edfab91d84bb1210553c9c232e9216c8579188d6923b67322c2a4351008380d295a2fdc685795346725d8d765b49f1a2b8abd53e015e7009e3d76a15e1486d7000df65dc9272b037df73280c5db27e276ca9b289c83359d9f9f91662bd84143c0abb620f2afb719131196e526abdb156716cd6e4094226e2719b477a53fe1169f4cb5521c52720d577aa8e7dcd2d7cf99d7f07d5c16cb9e157caf6357e09b719beaea0e7ad525a9ed0e040e0471bdbddc06f603417e9a7c9b3ba89d29152e439b16801e7f52d7e4700c08866ab9b109014955cff16e8d68ecc8cef0a53281cabec7d283129ef20e4c747ebacc7cb7a77a329e292ca3b848585848fef40fdfcfc68972f39021d4dc01d5475a374f0335be19ef7214e1059695f4e1b0f2f3926074dac489e5c4e7c7427ce845dde587a2dcecf6602bb4ba72df2aa5b50f1e3fa01b685e946327e8b98b04184d8deab0681208c7d85bf708ced936505a5fd4de5b944333e1ebba600a6649f44265e43187f8808921bcd3202c334389cf1603fac1f87bde986c0bb7e37c00bca201eb91cba46e5fda23fe0a209b7ae61ae104f8b3ab1604cc4fade60bbd3a0e83f5037b45eeb6155dcf560b0b96f7187740c06f89c1ada0cc70970e8917653f8bee595bfe06382ab227c4f58e71ca4618459c9a373b65595424d3a816d34f73b5bba7d7c2d336d276e111763e3fa526b1abfbb2faec4984f1d3b0cb78e41af1b818da8454170c3340ec336abf52fa19559c9f3ba9a43c2d825b1036f39316a4802eeef27d54a6baeeebe4726a57052e8e943558656a9cbb1e7d16409cdbec4102d31ec9e2a6b6387efac601e34ecac989913809c2a634d1837af2f092e04c8d158b3606b54752edd9e3b41626ea541d17bfa1eeaa59454f24b3e95594ddf65691081028539207764a40143df5c3abe573ee2865b7a41795113003ec31d531ded76fd67e826f9e35d3fa3b29af1e276a68f2f0dbe5c02ee48b7b8efb603e0a7f626060af541d7f501679c5d018c9d1b4b23da885d8e47816e98f83b3fd306f709f3db5d7b96077f5ac21ecbc4d41ee55a87a19e7db1d0d15fd4ee4adce9963c3e70ff910e4a7ae0e8d6c88bc2d391ea836cfc00aa70beb36525deef65f3bedba7b996b74f1da1c156f119322eebb4043006efec1b1a918aaf27089e61179cee574574c311bfa4f5c54c26ce187ada0988cb18aa6f1bf91c94f02b8e65ff455742b950885c7e2f53ba110f051926f85e04a978b205506528a1d21ab444045aef03c8592092b292742ca671ba88b7d66d18cfcefbd39eb16ae95d9595be995e4b7fff77c7fdfddfc1131a3643eea235442994dc54410520c4164d18fc7be17210f1eef3f74f3fad8b7493d6e85891ad6d23ad114208d964efbde5de01160d6a0c230cd8df8a4a29fa654abf2c32fd2ae2e458fa48abf0b673b7c77e1f667f8743eddaa78aef92a8e2bbff8061d4be9369da3b1ce2308d4c167d2843af28a8c9f7c8ac041581c88cfb7234d54e9c2cd54e349a737eb7e93cd45d7db061f7249637897df697335966d84c9c8955b231f7f923dd35ec837dacecf43b9d897d15835cec71227de1b55659955d7b04b10cab6ad87efa11d335eca3ddf413f6b1b2a3dd845519761fd337acca708fcc118c2076f9c53bf615761bec39d8753013d6705cf56a0d6f621f2bf63ef3dc1bfbf4bbcbb7565865f14ebfc32a3b3f95c5aa1ab8cfef74ef739faa1ae6b9eff4bbee4b4d1676ee8b9355bb6040bdfa6c260b7bf6ad7a855dfb30217a15b4ca1850c61e6b30cc2385ec6d264e8331469c2befc9ae1ec18bb973ccb7752f56d190629d6b93a3a2f73bd9bd86c3636fb2ec43eb4520f4a80884be5974f6a0851c5f466064981c5f51fcc028c70fb24c31821717ae289430d262f49b7748e5f9716a78d3ebd348a36c431188a0051a4d0c4901827544185ce21002106578f922e7200a920ac628c2082a201125c890a28b163368020ab085c0230ca3276a8006192678033422c41157bc0c6189288040e9451ec11a694041831ff8e08b27a0068010841b6b9880042d5842fe3c6184114926e0620955dc00bc000d6c30841a50cad8e28d1bd945eca20233c608dad2841857c0b6c096232cc1842c5e00d404d85c64229660043184b0441366800d84082ee092a4c6101426e416b90d2db8604328ca9313c001760d295842162788a0850a1b60cb2db98de8115bec47d52a0291cf968440024d649cc008440114475b93600c2530c4bae0200964125f3298c11721360490494c0dc089effc2216335c5005dc2a37bfa8450b78a00402a18c2790c00de3e6274df0839011d89fcd1570bb588b2d8a2802fba381029a9184173f67341e62f480470f9890d27ee0427e55c4162b166cb1a61500a32cbc1af419a3496bf801679226ab2593349354c30f38a33459712649ce57234040a767ef543b13d47e353cd35ddcba5e13af158089a33af22c054b60865546543bafc1c208cc700c40958913c1d4fdc16bcd24190d4d1c1f411327366ea5e467b44c1ceff233471307e6f233481367bbfc8c6be24c507e26684668e24470c695e56592647ec0d695499a600d1646a096ddfbba9b2688f226d801653fa98c7057d910414e754482db25b861b1a228cf28cd24f54dc462c550969fe132b33404f54d763ba69f64d7fdd3673a793fed989ee150bbc974edb39265dfb42fb4d2b762a4c3a10473e4b8f659e9a3700873ed3bdd73e010f5ee1bcc37a334b33459f2a66fc6cb64c97b5fca3559d204f3a1be79fa22987d11ec660c3242b931f78556b6670fb99fbe659f6a9e3ed5c4d93becd33dfb09fb8456763a7a53ec62a0a2618a7d0481928aa6c910c9204d1caf6794264bbe9b49ea95bc4c912a004301180a4095001005a0289b499a499a519a59929ff122cf833bc29311caad785497e0b56692fa05de73eb4959fe0ef8a284862be80738a2442fa44411832b4e30c69012281f25144fa703b0fddc3e0de11283479313cc302135042c3789060737c89de5182959d4e505e96a2f5e4f1091a91255bccc2a22a71c7fca5442d05f423315d7bc676462d51114be807d090671609f9874cb2327ce78bd9898f262e28aebc584d052521b1efdaca90640b269dd1c3f310f84bce4beec0f60999a717f765cb87c356f939b5c82e8d7887974885708e5897738917885508e38ca16e49c5f640b546cb588993471640751907e7e3b1e483fe7a4424c9618b1892d4d78c9ad9b9bc8d2c411b8d0249ef822c627a808c2174b1c392183dcbad909a01c7f737c3931841351724c129ad2d3cb9fcc75d4699c383b95fd071474c1fb8c498eaf5ff63dc90131a0273080d88328783f3b95c546b0c7bce381b78b5cafc42657dc73ca54ee5b3f797ebaf2c53e8b65b25c148b570eaafcb584117d2d51d4b2718ffc22230d36c9061d224fb94a69a414cb2c53ac22d2a2997299621db89cd281cb353fd99b2b906d784f70b56fea9053a633ab5443b03c2f73671591ce1377042267ce376f3d6977b794b2bb63777b268ac4bded5d9a948b7e32de1b090717573f705822a86609d711652871854aeea6bc37654c72b95c4168e479ea9520cfc7dc608c3c4f335f444ce489145f4a8c8086e6eea68d1278fb0aef95518aa1200e28344bdfd07c299dd2098f07b91fd32f1b0c91db8a097237e7e140fe10242f9d739584112847b5ccb6f6bb3639945a7bf2ea6fc4e91aeb65c5b77f2893ee36436701bd92538a00851b43502103252011840435a4b862892625c832840bea10439a4e4a051643e2624b504cca3d628b31015b34001088000417003d31a58aba82388c9090c0650b14f60a4f9e46d4eb89245e4f440124b164f29a74f9a08473e5f936ea2e94f652df348e4d6a2d2ddff22ddff22ddff29dc61b4da37cc5af2c1fb344527f8f587c272bceaf1595b28cde125b9459c61738578e3f70e89b56aab3a59c7918e617302f43e344a37923f33b48fa26be908822cf6380762a668a3cbfa2f53d12ab88d0ffe439ffc30518e617307f7b1ab96aa6508c31c6186394b88b40ba64238a86783dc125c7a228454007da3aaff050952e2dfb467533f7556d818704871cea93a8acfc8c70c0407d0e8d0300b03e49fd92c68947f5613de57a099444aeb5b65ce52a45aedf56130787c9aa48d54b45a4d75a8f903411b57e556f539f53af53c1f024f6ec18f6b9c79e611fed59760d5fd50ef6fe307c27ab1babc1a6e44b6ec696b2cd423148d53285a69419a5936e548f706dc28befa489736f27a53a69f5d529befa922df437aa63a80644134b83e6287d73ca3700c8fd39949471a851dfc4570d9072bf66e91b493b243a93851dc9992cacb7d92169249b7bb13bd24793d55fa976b4d491d56461473e59d8ef2b568d1a2787966a45dff4eb51e30000ec57a42bb95fc16836c07ee5d237f1550589dcaf4a358da5eaa5a79d8f37bbf603ca0cdf552b65d32b2cd52bec56edb322ed0fb829152125cddfc9aa92d392415d8da82b4868e2fc809256a9456d54916a5255c2b460476d84256148554b35f266359ad5c8a82e19f5aa8572cfa19aa557461148bf5ef1e467ab1ae53eb68442020039beaae080ca080eb023a68d01a8a0f56d6200b0b2d9bc4489a93c1aacbb6f0d95a0dc8a4631507982a5ba3d2a401e15277d9bec8838726b75c406d6d8105ae44681ddd8a5930b94d44173313455e4568d91edc151aa870655a420430b31ac2803eca035a65c31c55015284e80bd832c5815d8b5980ed868274c482401832684a004294643007bca192888f28415407091040eb04e620649180d6db1a665b35dfb867f84d0509665d97ff2bdd9bd73894d75249467102d91f90615a604869812b83dbbccb1a66573535fb15e4610e5558eaf2943f975842bc7971146b9e5bd8c38caa878034e912267e20b316949be004e2142b610734b47116cd20dab6288f9fe27c7af7573c4b0d71429761e9b723a41a3ec4939131376abd24411af26544029ad59e6e5d54490b516d3b42b60bcaea471efcdb62d4bdd22b9d79525bad7152a39c6c4c9ef75650527aeeb3ad3e974c565737c5d11f25e4cac81e2727c3161060c8742a160b80803c3c41626b8508d8dcd9b928b31c63805ed9b08c56321c72c6244c9b15e0cc8bb9c6c42ca7e41125cb688d94a678b52540c924571bda28f315956f07ac1952a625240848a2280c46041166994e08948842648b8d6d0d2c69333ba0a0c8cb4c0872b8c10842014a0e007104a526e00051a558e9c78a38260285a1ba80165896bf5d2dbd033b24c575aa5f7d2148da1a92e99faaadea63ea7d62fa071aecbe5720151299d73ce399bd65a677d6ad65c6badb5d61b11a325954da4851b34f801ca0b869630d4c40f146f601145880a26aa28a2911882618b121738b072041c4c818512cc38021329b8e275c69530b010782deee68e41b5ddd5f37254a1821ea4808dd7118c702399c8f4296a413a440a315420e50625d0a208a438e6c876f7ff821ae47e4dce737cbd60042f685284cd8d6e94d18411ac208c3674b0455c830b127ca00110406148b1c416b78606c16bd5502a6d88a04fd164fad58c96ae4611411368e00408405cf800c4029c0c95218490124b582881a5768a52155c2a43bc9c479fa2ff0f0b9456a0440f809074032c407a9b898373c611161d10c9a0cb0e404a140596298d1307031db9442e17033950239ef7644ec95ddab469379d3d1b06793bc9ccf5ca4a69b15bb3df2a8f555ba5905a8f559da514fbc9c5d8b7ace52c8d89f1628e99b1668aaf4bc62857ca5d34bc16955cfdb8cae9b48c119531ca4f6cb1669352dee730711a44c00a5625b87c928ac363c384841caf01896392acbe8faf8941b02954c8f19ec49143de9b0b99fa90944352e6ec5812c429b2fd6b07b93ebe643787a4919090a6c8548a5ce314b97ea398a5f4bb7165af7d5c5cd96f3a7de3c5554c161d3c3ae627a754c1724867e2783bd89f2df656e756dc622df065facdce963556d3959adca04859a3bc94974970dae34d7d4480f618e5a5c8fbeb79292d292da91f4c86c691571c19d9914782833c061ac7d3413ec9122959ba302bbb8865142965b284a44b3ef58a578f612ffea06fd1a25e9aae5e9a38d9ed2750e3d8379a656f336c95ee8f1f35354d9369ac9d47d9de7a11b24a6da4d2a2d1512375522b655fb8ddc787ec1bdec2ec5b0d11cc700f6117c09e16b5500bb5941eea2a4dd44549494a4b5edad541444445465a8e90b8265ecb2a65fb162dcaf6d22583a49094228764951844c6b8b2925d9a383fa07df6fd80d68b3de6c282260e05ed31a1184466dacf6c148a9032eb2ccbb22ccbb26ddbb62894d8826d7d7ab7b07d7abdd457aadcaf4598baa0255802d2143279d19cdc6cb26ff3fbe64d9f5e2ff5154d0eb6c9db2a6f9f77d3302797202fc6b0c5b1628a5babdcdd3994db648e9994a3e8157d16a35ed1268ab1d6cfeea25ed1bed22b3a3f9b4420f4f39b3ec8166813af35898866d1349a5ae6d144eaa33e6aa424a5252fb509af3fa72b02a19f6f4dd7d292977675500bb514232d4748494a52488a1c9255888a7a08871c9280412d9b4c6d7274643082846be251fad6bcde2a0619aad244b38bda68b6961844cea4ab844d09768f611fecf71af68b55f1d68b738c60ef86c4203312ec27b30c13a7414b29ae4a783463d866b262d26cc166bff170f39cdce35bf2058973640bf6f65a0cd2384804621f9f5d9c63c4ddbb799e964a65b7d8e224992c9b86572b9137313581574f53bdaa41e6cc37bc56ce0b5a833e5edfd5827ec0165ee496cd023c1b840c0417bccb831e52e8e0654e48c0b34409f06e1519bc3bb4da820504388102b618c1095b00f1f0ee1b3978d81a1cf0608890e34504b240e2693ef8a4608077737c6d7902cbf1b585684b952d3ed82f52322173c24b19399a702199aeb8ace09c08d2c1e94ad1121b13432e9869c2e8158412744b04c13871a445139658ba9ed4a20c1dd2051b9b9c25b4342b5ea90592c963e2a859f16a71f4d2a24a1c589c5957200a2b05f05439bea240812a8a2630789e122ee09dc8d080c7e5f882820b1bbc1c39bea0c0027aa61c5f503401c48bc9f105450c6cb418ea2cc0d04109b2404a6243da929774ceb1e9983326070caadb9bf334e79c73ce394db935e79c1db775b796cabafb6273ce39bb71c4b66b77d3796f2a556bcda194b6f46ed411930306e59d4c1db769998c294620f13f84b035b5a89bc94a0f827a985ca3fc66965ab7d159cf71f25342f3929a6fafe4a722825b9e0b2b55fc4f8e8fd1b2ade34c374e968a887c7f4e9de9420442d3f3fbf2e69d3a21aa483f19b1918a63de894620c5291db966177aca38abe9cbdd4cfa677696c6764d89af2290ac6fada9d4bdf10d406146bbcd39a5774a4d56bcfd72229048692bc6ce14162bed960bd96b25e81a9e7cd4887a528bdd8cfbc43975d2fb641015e9da382ecf2473db30aeab3451bfb62a35db6e842131128fb2adab18699d8466b4655bed2a465a173591d64618c3b239aee3bc1844cb9da5b364a145f0de5d13e7c52059d6d2422dd447f49418e3acd9a6b5d014aca360536a0b4dc186a460536addb4ac85a6604352b02926ced409d96ee24e5ccb855c02eef1395e74c4175a888879b9f20d19198c99bcb410b783da755b8893c75ded743a79494a6c60495d7472727292ba70e9c225755952ead269a62ca9cb92529793a79db8532784fe6442710b681ca965b2fa56e4782d5b60d0391d0c9bf802c41724182ec420264934591b2abe20b378ab9fd6ef621f074617634507860e9e9ce9c8d937d9651533512d128c4e22c9a34e82618153f6cd33e1d861ad13927ddb348e28cb15198ddb88b2181565c99d61140a05c3b5910d72bfc5423e7915474af90f1b1758f10599c4e3bdcf6b1bdcaf669d94d237a8b8d241844c2b774474701d912fd7d6d256749d45cac441455612df0e392493c84de493190ce7c520a6ec62da668a7de46304477859f86056ecbdaa69d664b57ee4f945ab1aab6eb8f41af6b9a7f7de53ac6a55cff9791ce673984f32af95d795259948e8e79cf394da7401e6ef97335973568a53b30caf25916c3a044ab18002233d9963822c0f838e0c46fa86e686ce1c74381242965b96524a296d64163ac85293974592465e224930683c2a42ce4eb33fbb58400cc38e58908af400b9628194eb1360ad150b177c00f4c88a23b8b0e20d24206ce1e20a24f29cc11540c83054c1459eb30bd8dd3229df202e0aae644a4f6f77a54859450b54991ebb4273520144032aace43432bd4d9580522d320840a62f2d4799fe00fc410b324523d3d74e087d55c1ab08999ebe407ace8ba179cdea47dffcc814cb19993ec9f43930e82c60062359dac8f43b3c00e92980854aa6f43a2891e997f44d97e90bcb0e327dd8373f5c3c8802a86f7a042d659a458d4c2fa334bd24e2c5032f32ddf2ea81954ce3174441395291e9cb075a647ad44313410873a0f79a41ee4faf5320a54920c4ddeb01600a3872f7f5b61adcfbf4b1cfcfc7ca4e1fc3a9c9a2f7b98f93d543929ab71be6b11fc9b06f98116dda0cabac668304b3ebb436b30ddbb06cb6765745f05a291b220804a43dbb3dd5322f2dc5b3f9119528d8d376b141e007a48f35cff20b62ca9225802c5b06f05aff4a3e4747062313673bf7ad264905cae7c8c320bf007919669047323b0a49295e46c0352b72114813bc7823da55aa23b30b98c5898aaab9e3254e2366ac7ed8e4c0d0385f401aa82c3f0318b3630f378c2c7b2699f6f51e03fa713d2082f43addc3b79a2c79eccbf964d03e2b5dbd922b29b39fd997898d52492556dd80bd56ec15c32a23f6530d50b533d500b157ac928fe0c52a499fc41ebbec6c90e0bdcb4a8cdeebf4e6ca2106893528ababaad305a0c73e19e6876455f16ab2e8a792d78a4a3ae49024764f4d9cbe6c9a842dc6df782f3e151ff3166b368de6abc9aa666c41b0acbd3eceed9bbf3fd2fd9bdd54aed8f6ee4736ee1d877d38ac56f92555fffa55bd8d86579355536b78f7f34eb2f755462656619f8d5518a64064d909511999efaf83eee777ee67387f8fe19dec19bd0abb9f0a5bf2c9aac7be96e2853da46217571542dca80e497a5092ae1c62902dcf63ef0153c26ee2aefdc876d3760dabe88655b6fbf347b6b9dd673e7a39704926cee947ba73dd4f1d7e771356d9d42ad5610ef79024077a9ff9de2e77b8e31d0d639bc9c2ae7da3365992a82acec10a2dbdc29e85a3f2850eca71be7fc3c4aafbf9ed8d55d90d1a565dacbadf99dfbed3d7ded7ae23c3646118f61c92f440e50b588eb1535d5cc3fcf61be637ec37f4358c64b2b0ebf4d13dda624dab85224eabcbd10899d688333b8b75268bdef60082202c9a68492199383ab375aaab7a6c95e9500442631059f4f494e9cd928e66cca7b2885efb7a982c1a945d6c04fa6b54c4a3bae1c9a7ee27ce9cdd7d9fecf311a436c9763f95922232775003750165919daf49229545f4b78725b2e87ab32f0eb658336fbf1dfb114d3b867dacecd86bf7c1be3d82d108865d75647601ad9c487a452f64a75742a6ec19223312690448d228ed2ff6a9e65515ab6ac09efd88fdc53ed8de273b483f6fb2e8ed67f35dfb45b0a5783ae01c7a45b9c425ea02bb7913877ad49e7ef3cb99ac55b638586bbf8a417a3ee565c95abb5ac3435de6dd1d7527309741615595c1aa5a1f4e9dc6be982b4c6d4a851727eb399365adf5b152ef03f3ee3e32476119e6dd7760b00a3bcce9bb57bc2383551856d50083613e0f83e344fda23e1586194163904c0b6164bee19dee216ae6da273396b5af8dc0a03421303038b4a23da4efaee1701ee63a8dc97c36aa8b57587b40683015f51f70877b77d477baa37068257be8c11c75140e4f87f90fd840645b966d2a0d1be96e43043bec6325bb0f7d07837de651aa1ae861be430f8355da611ec19d7995865535cc1ce647660e837dacecc05ce63e393ef323328f790cf681b9cc23783f0d88bca98ce4c871d591d9058439cc35254564eea157f64296f44a9bb9cc751ae653ddc73c82393ed5c5aa1a725cc78fc03c06fbc41ce63ab08f959d98c3dc47c7733c82323130333a7280325f04757c11cccff0ce3cea3a6d6d26cbfef4e94c9611d367bfeaacb5aa1ae8bbefd07758751fc13877e65517db473035592b7b1bfb1c7b1dfbd81901a296fbb17d8a62e3c1dd06072123b934d4472ea2992464449786ea918bc8260919614b43f7c84594250919694b43db918b884b1232ea96864c472ea253929091b734843a7211c1240919e5581a8a397211e9489211f2f242baf242ca2273f7cd8134b22207298cb20483522acfd1251d58a1832c5210e5bca4a892e55de85446b6db10c16d6b19c9f3f4dbbe4f96dd81961ccfc8f1a50330a6098c649b184cb309de71c8617296f2a84ebcf8786eb3b8e57531f495bcfa984a5dde26474706ce7ed7c166dbb0db1b865676380e87dce3643159caeced75664f489463042bd83d33eb60931bdfb86475b02969179188f34519629054ceb4d31b3ff0a2cc9d29bee33bbe7f8a8fb16d6051df78e24f119ba87c77938a7d648aa50a368aadd4925bca6e866e4eca198af4ef8d50944d9798677b77ed6bf54fb8a5fdf4ed743a994ea779e64d72261a3c573ed1205df9f4f3703f71b862bf91a24c98ebf3dc6b6fddc7ae95ddd4cdf09666327531d4fb38bb22da4d11c8fc290299ae4c6d168fba9ae4d337d34fdebd7353c9129b39259c777a67d3bdaf07857c3af7f524e074c231fe3051aebf9676ee527643221843703e5d7644640c9ae413eeee6b71dfb8ef3cf2315f0c7bbdb218e78a6364f64c120b227677636facb1969f1289b908047b0c31371a160ddac52042b818047bacc1c6d8fa14b7b81de21522c094c21d2297dc3e49b4d6e5d141cb1ade41cbfd9fbcd5eed7dafdfbfe5ab640bf51d9fd222d9ddcdfb2fa2ac395639c2237a6b49ec63e62abaf9708dda86d9d292d0f32db8a2de6b19f4b32fdc6256f9fb9f37619af10ca1ba69437dcb2857a9bab51b65075e0a4e5b138126c9bacd94b5b85279fea55c49e7df7b2ebb917477a31d72b29c646a412a9aff562d7e97b7beb9d3d31cf3cbddffc3eb1cb6ff6c52decf2f393b36dc7f0daeb0f3b86f12082439e3fee75fabe859d67ce244d030ef9de39afd3f513dfebcc63f6d423e98f95f58ccd00db7622626fbbd85de39e5d8bf952bdda789099bbfd626c6a92f81148e4308fbdf4ae7142a24579bdd26e93b9cb4e88fc5a32f3d854cc1681c41c9f7d5eaf6ec624a6bd8a3f71afa7397642ac166fbe53567e97da330db768d666b738dcd2de3d5c9e72be67e6793b8637dfb37b680bc32c642019fb687a15e56d109b14421f69a0dfb6dbbdd23e9fd2b60db7e4273fb9cb2ef62ae3be25b3a39ca6d58fd9ab16f629257613b0a40ae97ba345ad6afe5ed978c975af59d1fcb03df0624465691464646478a8687aec9091c19e78f23dd4e58a57b42b26d5220b06c625ca17a492942f50d70b51b610e190ac298f5b4c72af915b3f9952dc6acc437b1e8a83b93978a0272c4374c93cc464f979aec559383c79ac13d2238958578e606429a5bc534ada52da9549feb68cad3ed6d47a1fb95533104f631997b7d8c664aa43116a9017620aaf25852842a60fe3bdc9a23f28e5837280f1404f1ac41e8480200480a1951df9503eb4b283dde25007875676ec250e8fa94dbe107de3a39b16b14599222c659a1c5f45d0226fa758637c6b56dc33b1acb5c52463b6628be7a572bfed10af106a6bf10e914bdde100404699622a3e4c708c3de4796f68a18b17954bc5d5830446441972b50f93c805cc1edf32a93074032d2e9a2472c9545c2d74f172d90300195d57bc4248f321720133ec8a5cc0782a2e992128f183192e1718b10f93b792eca0c618c2117100b95c606c408edab606647821434a8e305d62a4f8f6b00d919bbde2cd951783ad67ec18f09329fd9152c83644e6fc23650a50c8aa2a52e9abacb4ca8a7948506dadd65a6babadf2f5e391983b820717985c669ce127f344dcc3244fa3795f6f3f9e7bfbf9a98a4c9efbf998e7e5b7b5bd4edb2ab12fa9d8a57dd74b21d2a875df98878acd5fcc5a4ae71a5bec1b2ae7a72a2279eafb53d2d323db2fa9b91f63af785cdff460f962a76f5559310f6d148cd125c7d7185572eb94e959c8f13546517decd5fcedf9c9cce35155f1e5e18ef07a98e496344b9494ebcf4f9e794bc516ad91b79dc800ca3d4f56891e26991e035bec2de64837ae6f5445e6972f799e6749e70df0a0e579d924f7c853fab0c5a6dfa8941ad89afbb6a4a5d5ca66bec240939494e7635a97a78f63a362af62af38daa7b84ad937548c2d1df7c52686962a99364ecce2dade37d6c4ddc4d9739cc9647ad7d16b2653f78c93f49ca53c14f320bb22f4316fb31b626ffaf6a988b46c0cdc6304224d9f4ad3de9d7634d05fa7c528da708be66d360f379b6ec2d474eee3e1666e7b8c4138dce2ae43903c3713ee99d95e88fdb4318bcb87bc9d620cf24b6b7bfd9169f2d61581d4635fab2f3359e3d83e719c9ceebddf09762732b74efa4e76dce464de0914f994931d3884f9e47127287c73e2e1d09b7732f31d77228343999f4edf81fae9bbcc43191ca26abee3a1ccb99fee64e2f0de6313871743910fef4f38ea9d93ee6f3b70888fa5701f6fec3b1ef677e0b0d67b38d4ee3ddcf1ed4ee879e03026e630389cffb687df371ccef970bbea393cef1c0e6bbd86c389c31ed7eecd7b0fb97b38ac391ed6b3aec243ef2ae03026e63a70a8e318f613701873c275603aaec243ec2ae0f0846c9ef030abc15056397098e33a745c9543870efc1434ed27f4d0b44dcb3e1d3b6450d3c33ad364e6dd74d4d357b9be3b50a7be1fe64d4fc3746c9593d92173bf13aa6a5936370fd381e23c998cdb81c2fab676faaa8e5975ec98d7c70aded6a76f3b0b2815341f3e72ecd866c6623decb358998c0cfecabb5f712bacf050fb0a2b7c18763a3e8bd3ceaaabd5c3ef2b1fab7bd2e11d7f851da8af70161eca9c0516ebe176960aacb3f030ab3e7c6cdff15755c757edc3878f151e625f01873e7ca0e6595041851e0fb9f7c88ecf3ae13d529061e1ac873bce5aad00701570b87a0a2a9cf5507b0a0f3d5cf31c397ac7f17df4e8f1144e38e1aaf748e13d1ea2dee3dec77f3c3cfd87b4a1390b0f4f6741d63c0516fee3a1cc537878cf5ad1d0e0d3b04ef3f03b8d7cb89de62aa8544f21ecf114ae3ae1aa87dc55f261bd0a5f3df4be9200f0f110bb0f1c02c0c7310e01f0134ef8eae13c7e98fd070e5758e1353854e150f51c394e83431e3caec221cd73e4b8eaa18eab70c843751e0f39ac1359f2356721050ee63d70c803873cdee31c77fc503bc6214c0ac70f379c24b2e461cec2430df71059f22ce070050c45b2b6ab80434d7b0c0e63bea9f0ed6186916c38d4b6d3e0503b979d7bf8612391254ff350079621b2e45738f4a1e300c021c621be0adf6b7098c28f7118cf006282155f5ea0060a82c02f0b20a260e1461286709205e8e4bbce0e7c3f1c1e5f06a3804fe8b1e3343854a5ce03873f503081c611d211485c0105b8e3c7053e08e1042f2f9880040370c743144eedc0610aaf4e7806cb3c9c3887c89297c1a10e0c45824e508fc1e1e93930141bd0c9fc31820a1c548cf0d2e5084a0067fc628989199cc0055e5e4c009dcc9f1e7a3827b2e44f3834e11c0cdbc454631c224b4259814eec351cc2f0441448b84197202cd500cc3094834e5098828d26a410c21337d0009df4b18717af62687158f1b177262c0904095bb42cf0b42d5a233ccdca604ab430f062a7c3ca600851e4d6cd318611e41586143b64671046508eaf2fae642e727c7d91453ebebcb0f52d7b3f3b034f66d918b69bfc36656c1377b395b6b3ef6e899ce127dbcbae4708112fdb6b97cc8cbdd56ab56c0e495633fb7ac2164d9e9686faf5cc4c55f0c59435bcf8fa224a8ef32f2144c9fd9814841181444eca60f3e2a828c76721c01669c81b534a6c4be8c249115e284109423060e1045558c1020711e02012830a18542aa674544441c5cba690486083801c6e08810a2739b06e2aa4603f80e3cea02343174878c10f8ee6107e1084ee07493da0205d0992224492165bacf4200c25d208e3cb129ad0e9020c36395d18e1d5450fba882288edf64d8c2b98b6767bdddd8f40e4cd280f0f335301413d8fac234785a944ab18332d25391a31ac2d0f9d95d02f99d8656c818695c8c4b01ae5a4f406ed1733d1b40751190500ca6e87821a7ef2c309bc6ff0624abb4822e39a782d1a1434715446327b2a44958837b4495c49a143b40a25a24057b2bd2adceedd8608a6420fdbff80de51b72182281c7ab8e5796fd9543082a8dbcb1b992cabc48608ca1066f888a3e2ed6ccfbe612b3bf4a58a622340dbad18d1702841d34fff01b7ec5b967d7bd65d82ddb3d3a218c42ed599c6ec329766d2549a5c7a6531204c082c0873d9377a652fc54104623f3f9a03d9423d4644dfb46851a6c7a4f44d370e0a7d13b3bded626fbd348eca1e03b2c784e89bf88ac113d9da6351a2c8f6d890ad9416d953a34c4ab6f65826a56fe2ab8b20b27d4644dfa090ed378ceb84b8543bda8f488ed33a21744bafecc140ea95a55a62a455d277a547bdb2d4eb23f94263ab245bd0220691d89ed119c9ae7d3fa0c4996bb2ec65f622895c9f7d59102daa55888aaa51d5625f8f6c9295f677c9fe7ac98482b2cd5cd91e1bc3b34ada617e64db0e837d72982c7b9fed1a0ebdb211b456c97ac9b05deaac12eadefb28ac921e5649895519ba967d422af90d932235cc3559f61ab64b9365b1a06cad976cad1276c2f898c371686a9943b3ca249a4546f4d2d9d1a208c43ed7699dbe6f68349f39cd6768686868349af7e84143739d3e0d0dcda5c1aa22287c3b0adbb6994c720a8f63277cfb09b8b3d0bca57a7feb86ccab64a6f99d69f4a81d0dac99f7f8cc7bb4ba87cdb199aa90a9478fad478f1e9f29ebf1d9d1c0ca3db0aa48eaa6a76efa46f329a199e6261ab3d92b9bc96432758f5d0364b6d784554576bcfb8e77dfba6f3bcd77b31cda5a470f0c8976db967b7c3d52667b9a2f664df5f1b8cee4816de9157deab3445588569855a122abbc615511997797c1d74bafe83b2c8774ccdcc29032fdf58221c57c960caf73cb6ee91b69afe4f82c199ecc96a86fba561552ea1b142afbb2674a7d93dda0d3fd61fc35f7b5962c4bdf4879c26f9d6ec09ffc4edbc45fd0c10f4f0e7f714a3e7d76424e5fcc27dc597a45effd2e2f961f8eb68b20bc642039620942cb0896324e8e584650244451bec9118b10ae208a822022072104943432162860649a1cb140d941de60380fb7c2ec5d7edf177410634e7edc391c7e67a281b10be079df36eea3979edc38ee5e19eaeda7928ff927ab8a78b78fc19b6958895ba19c4b9a0656965855447b77ed1dae4210b1654dda4bee12b7de6a2db275dfd83a6cbafc5a97fb9410e1ee9d08cc394f0911efa81339dd3b875b3098c328dcf270ebd4c9af0701da7b6447032b6b5855642a6944f4cd3d3d8f37e4100feb86d723dd70c30d4f62ec315332bcd64c838725634aa6f460d8578680100317c8842a4d31c40bf40141f803d61c081bf0890d6845be0a21331139e6d65ccaad25d3b715294ca5145a4b23208529b8b3e0779608c0a7e7c12191a9041dfcaeb2df3b4b047c291900f9faf1883f24fef72f05fc69433ddaa6053c2c199e7c7c8ea5d6b44857bd128d668e5880a892e3a3b444f03a472c400ce5e8e539e7c4de5f631c866133688c0136ed197baee4e69c73aea8dc0f59e59af597e974179393b46317a08639e860967137e86045c0c5e13d13ecb10bd03dfdc5df2f82d40a0f8de58997bca4e5d064e589e59090c63d58beb9b606843c7da294edfb1ae190e040818c72bd0b4866d2cc2a7b19ea8dd43cc9f54856ed24d7e3a0bd3e073062713294eb5df8216f5a4a296bb2d84ffb38bfc4e69abea94ae297d82216e841a12701b31b22bb18e4bb634018faf8649b31c12d3bc323cf2d91c62d9f3c5b32cbbf6f540c28322f71116923162029d97ed5e2968423dbc7117fd4c77496f24bfc119f63bbe28f6e92e567658247efbd813276198c502f346398c5a16f5a3918761dec1763c740e34c103b922c19c384904164acf30f4119c3302c2ecd1260f141a9e6079018443e66608b9914dee50b928588c58729b9b1f8e025b72e0c34b7483882c7f5ea2cc4f7d723334dafe443f9231b86a54cafb19194e9b32ebc30caf65b174499be731d65faeddb29deb8b5669f659f19c785793b6dd76955110cdb30cd847dcbbe16f7ecf653697808f7fbc99c653cf599a6651d0df41ae6a96fd17be08706fa8c3b865bf61cce9e7f72fdba6bdf4fdebe96ccded9eff4d98fe3e94ee9e9030202023afd498c0290e0138b25a83367eededa3ebb221d91ed16b7ba6f58b51d7b87551b2e726f7f6f3fedd8c5786e03e6c56e865bb6c57dbbfd54191e52bf3a64e3d1bed9ed34d0db73df26b395198b4166fa937ca19be478938d0b3930f44dcc5b13228d27abe445d9356cfd8e47f68b4751b9754a02af51a69f9fa5c26b5d22cce5d1dcba2ea26b9427a59276b2a8ca7a4a050d52a79cf7d37e3ee7daf93955b6afd06851dca5bd8a52266cfcc1164f63102beb6d906d7a65678bb34a5e8ba3691862904720f7f53ffaa63e47fb6a5a2a1782723dd73831cdbaaf576dd947336ba0d3f693d1de4b831c73afc23e736715f6f8fa3225c7d7172a39e69319a6e9d5ad1148349a446cd1a2bc215a963d23be1f6d49c3867dc3eeb7d96f88963fe34d1fcf7da45f86728d40bed686f4effb59f6edcb1e658eb8959dfbd6adf81881c406743d00f9d0c4957b94701ce69498cee3817854254a10d9842f900faeac33b7d8e1560f797ba43cda63d48e378ecbbe7ede304f96653d32fe70924631e51717378138b6e478a23635a7b62bd7571c59a2f499946241c838769063289db412f1729df42da4e73507dbcc3e3117034f0e65fac8c6d4be55ce54fb5c5fd3eeea1a66bf695fc5b21bd25dfbfceeef76facdf461df92ce2d7f7126bfab0db1f2eb9e6554bcaff2c4adbae3a1aed3f3d3a6171b01281c32393d7601b487b10b30ef7d9e7634ac32f7f53d2bdce5d7e116cd7488d5be7df76234b072ad7828c7ccb55dc14f5e423f89dc28e1e17e09a561955b4c72ed21b7e2e57c1c4ff27cc301465e613e721532310f17f3ccae888f3cf1295e0e2de948bf1e14b20cb37d77457ce4d6b4adfe8c5fd27916590df52ad6ecca656cf7b7d58f19cddf6c895bfdf87b9dd91366f92ba594efa1694c4abca4738f7c23db4e08761ebcac037535c9ad7e0ff646932f99878fe7e36eb7fa3d17c88726d979c0b2077e728663ab075bcaf53d3ba3dfba65fcd1b75994f2b295613467ddddb8953d665f0cf3c53cfd88e121f18d7978e21bf784b965cdb0a1980a262345595ad3ab7e6c967cc7cef1f586520fbcbec7de5873314baef80d306c1a4b1c450d800347be1125cb0698d46882521390dcb0c276f1bc64792e85c3042bbc78e9550c13a4e4d9da62df44491fa7e46e4094dc9f5eaee4fe7cf6d9cdd0d1d09fa71fb5c92d6993b7934d965d0c5200590a00e3b4db601d0d3cdaa73c67803cff75433479bb23f73e17fb14e9cfeec8bd7d22c17b9f2712b4f63ef65887e4dee722b9c7a89c31d8bc00e5f9d0766d74c9f3d3a28ebafd7eb8b7af1f130dac8f3108766b6750f66aa52701b9f5933dcb85a7fd09762bdb5d1a584f7f7acc6d70c9dbf6eda0e5eddc4744339dda64ee2d1e1db673ef3ebb21df0edbbbc37cad9f8ce2913f7dfe031efde9ded733bf7c994162fa13fe80975bd4e592377daaad6b2389fce5f862234b1b44e49a1c5f6c7861434965eabaaec3b8ed536da64fb575dd75ba765857a47b1b457949e779ac2ba2e5798b7fb838fc0135fc04bb042b95208cc3db7572c5a1adc79e59cca4e21fec4326f716071db4bfb5be1eb373ab576d94897743af07acda5eeba5c4aaadfe0ce5ee84cccb8ae36562fb9241fb74264840ef487726310d73ee3edd611ebb1d987338dc11917487f93824a10fa8c23dd0f39939771f6f67e61c0e4df7bccf5ca7a7ac1125cfcf9d1d479df3d971d36b77038f77b7dfce8ea370687a4cf6ad72af7968e2f10e873bce1d4c7d3edc79bce6f3e1f11d8ff97c42ee3b9e7dad9fbc0650deeab7834644cbb5728ff9b6c9ee06d3637efa7c4c3f1df585a6a3ee7da1e9861de7719d8ef9c2d36bce7d11f3bed8dd109e9e7aec76769c070ebd773e3cee83eff33d64e283c2611ef3d00bff90077e88ff3df5f98421f7eea18ea370987a2853f3f98461772fa4f9096fb0763ba6a35e3b24de77e0f0073c7de60b2578c2f5db31d5a3b08fc7cdee08771e18eb2cded901f385dd4d9889cfcc6b8e84c33ff038f71366a281a8771f130df48e5b36994a90e91c66a281dc6d47c3bc3cea3be9ccee93e0110f87dc3bfcc4742b16f3e8509fdd1ef50db76ce4fbf3d9b7433d7d3ff0380a87125401fb84aa873d1ed2fc84d7fcca63e7be1f78bce6335f98facc374b82a11caf10b22418ca760969e49845966a78ad54a6587c88927be488a589ab4b962e5732901c5f5d80d64823e35c61e34abec9f1b5c61b5d320d9296dc23c7971a55b21a5296f046de38ae7e2a0c17c9b2bdcc5ac69472e48229651bb9644bc9b0e2ca070032a26458c9366f260efb541513b1cff2cdb123d242172f57ee881c00c88808a612647a0d0e2518a680bbd3438c997438fc70d0c1136682c2b91f3341e149500240273fe0e9a7c79091e54ff8820ea2dee3a3f998748fb90a33f11ee379984987830e7ae7cee30b7fc01d3d09c83cad285b68c5971192b204535fd0c1f0860f830e32319d3bea335f288399984c8f79a8033381790c0e3ad83d070e3a88c24c6070d041d339fcc3e9cb972f5fc02ebe8c8094255e42b3bcd6d110b3c81277c0bb22b72a15a2ac433ccaff19ca596703f7eedec4e9705077137ed2e11f12009acefdf4b7b3a13beadec441e120d33dfcc484add877a7c7f007bcbcc4cb3c15f340e0073c35683a65e2dd50ba5c5e0fd108abea4d7f72d074fb56926cb1aae21d4fbe854396e74e53b285ee869b5ebb06783bddb9cf6e87bb09873544d02439cae3e7b60746a392a8144c35c6911a668c219a0104002000d314003028141008452291582c0e95791f14800c96aa4a664293c8c3248b51c818630c3184180008001010982919ad02a9650ead843e9fddea2d6141b22cba200ca710a34df86b75054f8b4b534b29509c87fc1d1e7cda2af627d19c15efe32733f74871a2be0b55c1a552728e0eec605fb8519282722a414f6ae02c5e3198d7f0f58883942e4e243003f92e6911a4ce19d0c72301a8fcc6676acbaddf26070057e478e843cf79b81cb6427e2556d385cf23deab577cf622d7e128dd5de3a73fa7bb8e8e3885767fa392a6e051518a3c3ed3e0e011d4878babcf19c2f72ffaca81bbef50d5e09e3236162ee5fa5e454ccae07c8be0b47575d4015decef09627a8b842b445d3d380dbc91514db9e8811bd53dd4562a555ee32c67347b4073c341ff21a984c1602ddacd720b04d8f3367d4ecbce4cdace383f315c5a3b5abcbdddb38cee2e91884143220300eaadc9311da26f9437e4aaabb3f6fae12a951b88367f68d718b2177d7b8f2acbdea1b5bbccdbfba0297cab8fe68e8aef3536c9214e1200878f97d192d1e8d8c64f93aa3ded5b2cd87bf0268c6e22707fdd53a5dcde5a73093e61077960b23b2a37ee4e68f4f2fc4950793492c8bf9f657cb67e6e8b48a3093da1b62f0c281058a65d211e132f70b94501298a0ab12066b81ce8574700a690c0afd558b934750e5544632ebca68b2aeb3c8870e6cb73340d25dbc6e723a25ada293ed67517f3a75d270f4ce4af3c85178af9fc6819bd06845a2a2dba50dadf79064d078a0dbf1d48eb81a27f92221aaf891a1f1cdde264ed049e0e06aa37b75a371634980c4d78a1d2ea45f41ff503069bf0f24b34f8d1a1b9b9d43e999ae09aa02f9f7632f8f81c8c8c7f73e752de2432316861676ef70d977c3c5347a4ef9dd3429dafb224c01faa154ede2c495aded9f2c05c870375911c28c5459cc824d8946e081aa60042fa8b54f2d9243684a6c556e368a5cd74d99464814d6ee9231b51a14c104f52d4ff43052029653945d77db0e62b988d80bc9b1ddbd16dc43e651fd71728e7c46c30d25ccb49a055752db7bf99e9ebe73bbf1706078cda2c5e118df22cd5fe0b98961af7a8c3345af98fb1409033feb53262e0745cd258bf48af716a9774962c718777f9a81054571665226e04600709d6a10e6223899fdc47d7693f8353f6f68a109d322fcd7b021521b51e50b417ce0392c59c7740eddfbfcbc075e7e2fb494cc77af2dfbebdf3fffbe0ff84b5ea3fe81c866801ffcda7788a67c53814220ef9e82b0d14ee9a481844f4f441e2386f51f33dddb29f0a37386ad2d76841fa99e2a5d5db2499bd562ad2ef4988b7e3001df2dbf885a7f3f2f71dc62be77f0e20bbe9dadb601e3768a68eb5b6dc189cde9e6aede1349eb0416000f74c81c07737a24ec2b746f252829b835e12000d024bb34878b0b6f412359934953da0f22cb86ba78df20945d1ff5d8d6dff95003ff3ba1db4bf767dc4c7194aa8a4573a2b283f399aa2835ff31464f3041df6c34129b2315340a1446b6ee2e3d9145c6e877b804c379eebd91e7a0e884faba849910408ac2d184e03aa925d34830ff0ee9352df13589ec846db5b315d7a51bf472f91ec929c620d66850c9cc596210dbc3137396c82be44ad589d8d41cb10de3a2773b476c232be7e53eda288958c65d327fea695e0a4e6973cbe0183b631ba3346e5671d808b4551282e74d53aa6aeffd0de1d33729a531dab19092b2f513d53665e435b3ba8ad4978af9d900622218d4950697d08fc23f7148797ad8e50b42576e4b92e66beffb7883350d615eb10f4294d89777a4b84eae1eb7cede210b6bc6addeb1d696a4b3d1b13e4f9a55c6d5b77a922bb2520db55cda2a2e70058767fdd04b93c74cfcd8e09de4fd38669e53f901f751c4937ca50c1b434c1b2ee1b90ce89416b1865e4cb18b1b71d1b2e7a85dab4a288c77e49233487da2b0458488755c7bd332d194e17e3daa0298d9244859c0ecf28acde02b712b216e0e51b7ba1e6449dd83b701e05c2d809007d52e91f5554c94b082acd02b6dba80e7211d9215ae24b34c49fe26d34349514c5ebfa3208724959413f327ee36b30b3b4201b12ccb196beced77a1502de48f8b0637776e90676d449a561c746d96541203a96d7284548ee158d022f147fc0d6dd0f72dc4ae040735341a7a9b602ca9cd7ba8bf89bbcbae5dbaa47ecd297307679b2b8b3f3d825e6999256c65f86b1f06fe74910eff31a369ea870c4cc3b917ced6dddd23866af1d209cbe56b4d12e6db824d7170a80c1fc25defe5221bce55393f415f1403218c61e28e10ae8dc1bfb6031e630d3385a67bf1bb2beab7765fea18b1b425312d615b4490712a3a8f9490b6d07a604d5a89162d0227f70bd7114e0d67bbec69c34f7247697930640f96d102bd39e0ac98ad2fd40544728a0c38b6f6cf4d4dea0646d2088f200c91c8a702e7b39665a7feba126b8f927200d4e7cf48c5ed094a8e67328396443359a98914c9b6de204ebba70cacddf31f907f6ca259617f5ea0da5e21485ddc893e92d99656cd178c6fd67cc516ea678ea667dc276781de782becf5db12ebd8d1eef6aca34b0af5d5dace0afcfcd0e8e6adc40be485e379565427f2ca3699c13822ce583bae067b5013263eae4b977b7819b3e75849df74f1808e6829dbe06c32656a7aaa56bc41e500e17de6b64c5ca514d33bee0039ae370916b2f7e19f04078058376f624745815cb825c67f66120e0a2e68dfb7d79d509f509479d2a2458194653e07ae3ce60b7e956514fa317a9b251cd46d461265d60ac23c5b5ed22a9ed916a9037394f90b38d032d2fc400753db1749b547cc503e6f7373a8354ac1351669dc8554d0b6bfd7ce6194590f0404e5cc242df0d1fa2c9f71a695a08a232267c3b7a2d02d9a8ad65371d326ffc5b14f9cdb0424d8702e1252b3cdad37c6805e1aa732b0c37bece5554d533781fc7059160b1c8864f0f0a610b43fb6107ffa52ac437a702c7a31075e6082c66d7d92cc959bcd9a146efe8fa979d1d8c5090157b17356bbb21f3dd893dfa019446addc4242e2d1274714547eac53fc758631e152a46b44eec9491d1bde94b53d0342a9b41ec5f4e9f410b51b3d213ceb3966dc89e7be2cdbb9e90a033765decaed8ed094c969055859ef48b0e4f2085a90929960a7a08894e353bbff7c8dd5d2c464ee54c0020e18909d9afbb40f6ac87b17eb8f1ba6c39fb8e58065e2da4ac8b43701f5e3741e60df175e44a8f848007b444e84264f8e52b380a512f936f1dbc102332cd8ae304e28d8db6ce69a6db44e0f5daa3e79c2921f9a979f6c3bcfaf7475a7fc8b51a1a3589a1171187fa9aa7872df1cc57e6d8b0446471ba20e472bf8e00b3fec6e697186c5b8288481ddeff12e0f9f95fc1708ffbb02ec26dc3dbbe68b09706426c17f1e1b1222d9c19e7747d89a71d31a31b56e3fc1a89e4421874093fd7af043c3dac21654e4908c0dc1e40105d6a3ff31794107ba1be7958d57dfb8a2a3f8625a81b6730bf2e4f2c50a59a403ed1a7b076f7a2983cac3a614ddf9b251190af6688f8afe09b52af52fefec3930b84c3d9e4b228234afd0855aed8cadd329c809abe21a990ce6bdbd270beb80b70da440ffd8508ff3f6b5dc0d1557f27cf8ed413a97f037c69ad45e360bd083c2ccf6724bac0c0780f8ed36292e5d45a045924b86e200384e2487db37451817e02ac2d4b9b9dab58fd6ba19573bb32ead29ed528c00f514f25f57abc0d4545796d57b765fbec8ad56e2c511b0950711762654b13efccad070037a6a3ccb6923cabc560b93bc341785ec2896a978db6d9ec962bfbd443a18a8025aac010be503bc5e3afe8cb0eead5a0403236c063524c9b019a1f4cbcd2eb82459d8abc070ae9feb92ba5fcd769d61e67184934b737d3e06fb503e7fa5bf76d03618db30e432b12295bc9053b3249108ac24fa243bb27b3e0e92bc926235a342a5c2827adbbe464dd8c6cbd49257a5b7efc94448686ce92e68a64ff98ce75b1ca7c823dedc8b0b0036e38b6de1c48dd335887a079eecb3245d450239fe30ef651f92d8fdf3af8f298aa1a2a0106dffdc553057dd3bb9d6b5efad94e6eb65782772ae4c31742e965bc42c541638279255a2f29b3be6c1565dd2fd924bc1be32d685066f4277328d75969262493157d87a141768552b502a669e88a2be689f3664e32dae2c5c71029667ce86195cfbe0384ce30284944dde1351d7193e494122adf411d1014c1cc6bd79706978f5a7c17e48d4ab50eb5ae7e3da8eb8a932f332fceaa77e9e80fd0a06f7dc5c8c7376e1d9495b0e98dccaefc466d5aa4c15259f2992f186ccd5d331e088aecd50bdc26121e92fa86d03433a57bbb62a09d24fa4962660ef60ae3436ada1f0fd7b5e193dcb1443a072589240f48cb9fea9bd151334a1f03a1a0c505ba58901b8671877cddeae11d8b3e81d9c76f3518da9c5db365c74c4ee9ad371eaeae2806070d5301d5a13d8569e6b76bca28a5eaa9f23c61ea79c7d209cec31851bf59b3e7f472abdc0288feea0d4b6d33691d64bc5e962d65f67f298c799ac8b344316887a1d0d9e907d6aacbee8f5b5d06f8c66e2a3402f83bc520d03badf88d4e4e42707d95501679b4cb234c2e0885feef82df354c393c81b5aacd5354adfeae0ff09aac0e128557422f676950a579cc8449ef7244cfaf8c58dd48326e22661e06c4414ce362ae03faed44caea93833477671c294143e11ab8b28f225689820df7fc7fed289278471da030c33b4dc0821d06f3371a0f38e0b2927b704ebce0b49e67c0216cfa39f3ad27e6f0e88063e180297a8376a18698466583711fa375b1c7a834e703d0bdb5b30ae9d074e805c3ca26da7bb455ac9db18aed3f4c5aeb877a72ae3db38a8253cd631d674e6156b6fbd443503d2bb4d031053a2360c2af4b0c22415b9d881c6aeaa71796c5b2cd5b5a0001e6e96ef0f012876f679eabd39abbd6ceddba1124bb061c2450fad13c91947d3680850ff548b2aff0039428743a5e82c6a22f6c0b53272bd54505963503bb55bbf9cb4a1bc96f91862c3d8b2c3b823109c90d2cad2156bd1c302b7e01a6bf81f37d1cd5c41f52c80dc54cb23fe38536845598a311cb5fdf527f70c64d505ce7dfe30a8d93ba0d59bfe464ec51d81896c121729908d5305d4dd92f71308e488ed227d43597408831a39d6af0d0eabd91c3833565d5008c41a15b997ac07205ce6480349d3733550b5b8a66ca39436d701d1dcd020fcdff2bce08e8bfcc193631e0eabb9f39870a0f1ddbc84e01dc495a239dd7950b4b4d209b91d3549ea12f031187221dfc5355dba78b304ca46f1489b2fe7ca8867cc0da6ddddba4fba35f465435adf3be210365f1002dfb600947a6a6068ef906667e813f6b9a659cc7e7838fa00de959d6f1a0243db6069c3e459cfdeb41167d44a758f8c7bd671da8dc60ef468b5d9949c7497b9e8cbc9b0c92734d741d7a2599f90b9b9681da7116a82444b8217a854006d2b6dc5d06dfb3a2617fce000054fff8cc720315276bc5a998cef52727881ceb4ea5fc28cecbf5e5f9e0c9bb88be369bb60c323c51fdab623966e7489d5b76488ccb70e891697e3e5403b11e1478078c32ee0722d3eea21be7afd386cc2d941d540616c3600c40802c0d100c834d245d8a7466ef983efe4a30c2646b6266658bb0d3559f00e5e1755483d6e3b86d58683013a9ba38ab37433be458a211eb675a26973e20845ba7c7207537cf10ad6b10d18c86ad18916a8d254a4a7319a49f1f73d602ef6c6212d6ad96f37ad509c66562a14c8df03719d6169165d87409c49a7c65ec11999acb0477d9f5fb305fd24b69f09e4fca7aa4f20a1e0b61d450593e9a58482c7fb7b14665c0e417d161e852c131c752424f7dff90159e313dcb34a945da3922853af103bec2a760ff5972afa57d2177001685534d6faf1e26bca54bb6a11c714573436d2d91ce09e68f4717670d64affbd3aeeef53ec3cce7186b1f77f89c1d8596c5530491e8ecddd45d3457b2176c1f1de528c1282169d4c8631eaa4f2ea036fdf19ae194ee23b76b1fbcebf105e264e25e2a4e2b6da45c929e57fb8178c5f7d2fbb4bee8511133d8ee8a5a7cbd55877bf5ef9d37b1c2b669fce67a71ea136299887b03ff4ddceea69d1bdf1f5063db5df20c1008550c9c6e7d3a68871ee077bb7f1cf9591a6bd42adbef3af46cc3da0fff90c2ea82a19b925d6c2f936383384d6d94f3e0f97e2ec0a70ba0447c01d717ae4ad04a53aa8dd9388c96c7e9363b70f98f954fb73a0d950d39f6b2ed802de1b71dd57554ff5e702150064b432f45668551f61f93e0658f58a23f5b991392ca15620c57dfff45519ff5aa528105b822cee6e6a9d99494f9e1546c9aad0b7e31d31ff4281635d0e642661126d8238cea0cdaa619fb8d1202f09bc74e241ab8804ee594798203b1ed8ab9723d417ba86d9cf517a1bc337ca7942f7c43c7e7ca16e3d9a7fc7b494ee1b80390ad8b83bc36c92ab05c07cbc51520905628d97a0a76a899a6736093973897ba1009282f7fbb0e49e8f867b8e5d184db8c714ec80348945c61f38d0c83d606cc1d7a986e1ef29d8506c376e15531f1ac305024b495a57913a2dc4c380e9408e0b119c6be76d20f66c9b7b186b5f03d8b89090082e37acf0294de800950ad2096e18bc13b45ab29bd09274364b0d1024977e60598818e817f284735171d38c63618506fd9f5d4ba6541c09f1e35950644ea1df0c0addf5d01b7c1d29c4b5cd64cc59348302cfa0e53b9f2a32105c4e12aa411d9219239b34801f3411b255c11f27faa20e6517c72203fa7f9cc4afb7740e953d3a4f874f9e87420206a305956ecbda73763382ae215ae8af2e6471290b0a5c3b3d4ad5b7d8d465f3f8be427a803f98125aa70551014938fc3e829220a7a78a71896624a4cf5b04ce02a453a0bd72adfe89347324252af3a1b2b1cf8d87b0f275f664c1da854547ff5918fe1cd1b0e77f463278d0d3cc6f6ef0033b962fdc4bd539f2910afabb0ca371231d8619d7c7a02cd11d37908286bd8bbf8b8c5176a81ce40bd8db6a51ce20699d9dcedf5bbf6f31035a9ff606fdcb68e74311881d800d8e8027e99b158fee6791c71e90968772fd3ae6c4923cd58f2a088824fe3125583a7674c0cc2f47ba4e99396e0f17017ff91c5f254a6aab7ec05f66c41c48ed869ebfc8ab3c000d6847c6c8334f37c9e32e2f315be0513d9a4ba9e46a7ef38e982ab01b1106d0ca0b12364988ee8b0233b55b934030d22444a83372218561603a939c2c13a52788bc5064ad20a09b5e96ee52586fd2ff95230a96c1855c4bb978db7c2bc4caee635472a50b2c67b2c9c20e4562ec22168ddca7ad5908135c4d0560e594b36272b6627578d75337361b5d364bc00ca589680241a6e900651ddcb96e2e2e53f8dc096d3c3e39b58e5f0b55a5840e686c1eebd2cda4f448215138c91056c3f1e2914ba0732ac0360172a77bc8231531ab818c1de69082d26fa9a33710fdcdd097cc4b29df193925159fa02a022fc82810022da824df499eea2b7ca42d33f4c4d7a52f33d810c142419417548651f0df5dcb0cce5fbefbd8210c6b892430e3a551d64062e2bc1b715d339972a0c2ee0aabe736888551928e5a77762bca4beeb4806669393ad37d298b094f9dcd4318dce90a3f47b2bff288304a8e561443329b43d0e73b5b582d63f1613010f15cc43b645303867ccbef54ed3e80ea0a06df34bddd8b1fcea54b6eef68d798353c4ee6f2a276359f41c981bde4d81abb66693aca3b8d5c2bd37be5443eda8750762c473641ddc43acb9590cb6c3c4567f305c2152fd62b66a42324c86bef68def5f6c0e541e8cf1361bdc604075b251a775faec49a197071f7775092b7c2eaa41055d4e673f54b149807fd357b1b841762f6ef6caf8ea15f32d1a75d703030ac97017a27bffed3e66abf39de42b7e9fd0ca804697a3cb0b842d6c7d1df0036d03a2c83ddb340ea003a617a9173fb382dc7f08d54378df41f33b2b32f234ac5b3e5dae762ebe73950ce68317794fb702572072021e230936ca21a55a4507665a191ff0705c1c656358940b5f79d1b94d5f73c03f644356c230a725c05139dbe1ad3d85eff67749285937beb09ae59998144680e178bf410d4405dde1d159870847fa8c5134ccd15d5373c2c3b6f764202d25b66209aa35eaae7e53bce77dba025de81d557a3b31443f46b99a659ba7389b5df37dfac0141ce6fe4f5b91b95e3baf6cb12d4a7667ba45c6727ec9b2c7f1f02523130f85fdbd76c307e6c3d4fcf803a114ba9a9e19587086a198b4b2fa76349028e01bfceba1a15982deb4652ec1018e2be442122da903a21a00c4eb0b3bb951464a71ee41d7b6db90e4bd1c9a4837302b7ab2911d3e884613c011ff80ba1f5325821e592f075a3d3c19a02f18a177df6447908ab2c9e10f61f596b899b2f6897889cb53adbb65cdf568fcca526eed10f56d3bf8d880fcc86eeb9ad88affd11409d14268ad566852447a9249da46824a6748040fb05cae45ad7738d6bbb245c5fe8e450605128a11065b61d47c8d4e4a794638f2d319b733625c0e68d0392732e0a5d07c5db058a98908e4826157b55dc8213ba7ebdce066ee10829e95740564a56589b8dcd85323175877db384ee63541658d838de83158586f6253522fa986f9032d796e00277fe4936200c811d1aa1ab59e84d0f2b4b00e9244b00dbd1a7fdb15eea02d2f7594f7ccc13841e281ed0b65847ff6c42d6509b831bf16ddf08e85eb04552c229a7661dbed9b4f117f9c1b1e48d5cbdcfd2069ee162fd40283ae7f9041954e2db6c7212be717bd3e5d25d0e7662e11bd97ec58c6e145996abdaf04a86b29650628fc5b8133d4c22a26c26eb2763a61147ce839ecc17b6bf414fc8bc91fa1b4c848a211e33ff4c207c632e8841a2b4067a8950284349968dd2ae3e13e8cf835181b40af328e33806cee366158cf5f97420322a83860f98182bac7051756d8852472f610fb0a563d43098ecd5f534657d3b8fecdd1dc2b6c7a316c5859fd093448db5f3d059c1c71971fc5f921440280e7c77a61aafc05d01a17c931c190834ed4034665770a4a1e1607134f67668cb2bf6e46e8cb84e99ec2e71993ad2f1a772398385305bc91c6a1d886048434a96ad65722131482200c0948ce4477b55a793940f46083af91b357dc2564b1cf949ffa9cc3b9fd842896dea060dc1b63c458f0a836639dc9a2e47fdc5196e6db1a81a8cef57c6567210aa42db6e3b4598b09c39dd4104d0e07838a0771a084edd247d4237576eab3417567e9d61e8854e3d80f2009e0522b5467e54e2ae1ada12ce80fc0a1ae385f425cd980278d21fba848c3fcb8122dd10bc36767dcd29469aae990de96ac25d38788b2aa67953234b1729c12788b94b4a9a075e8c8e85d79e54cfb716b9979917c97a2d447bd89ecb97d78aecc004af488c888ca5383299d912e451af6b237def03eb3c3887b21aa8fe291e494b4dbaa57cc40fdd96fea7a91a6b89d993edb56b6143af25fa739bea3610e42ae1bc1eaf25ca5127cd050590a0b7c63b9c29cbe53b8e4cdca218244cfceab03c707261b07e8667d7a2506cca458bf91d68e90e1a792642755ff74b3af806b084c7610c8732546a14203f0cba1cd6bd44da71937b5f14ef82236636d41da0bcbac16be411df7ee8bcee9d4b042beab81a8146c26f04bfc10c00b984b4c551d4e0b98ec5c3858d1668e0065ba9ca35c562743bebef93d76097db2a60694c80fa3cc3eb3d1384409cae906ebe235203f2499af51b9a2e892debcfdcdd25c86c882cdf1a119a8b5b44acbdcf4a6a2cbfc69ec2b6eac60a29ece33f6ed8c564986d239e71db78124424628649862835ce65c3ae942efce7f129b8046df7ab320101858f5043df98b543d9b96ce1462070345e34ed544786b505685f19593fec78520b32c1c104f7b2c11c9d2dfb3c8a779211da1b1562b83d6f2b84e998c99d87055aac36c215408b91a480e8b48217f2c1c64083939ecbd9387226a4a9006b406e0947766cf9c33b2fa2bd9bf337e17bbe7d7cc1f9ffa4b22716c020d9550e9fa4afde81240066b84bea489292208629480ef7e1524f8aa6216e08a919c970d161f1369ff056d1d7a0bd15c0e7b2edef4b792e41ab158412e2d59821769e10d0d5d79d18c9ce03c9e1c58bacc5eb3e4227c17742deb99175c99dcca5d97304c9621256c9bcddc3e4f5c9d548d52a2c28655566ddac8fb3eff89545602a7336564f66f7613b95aeaf1c6256de6a7644e976eb0f0ba379139ea14870e04c092bcb0b13c079764c2621319bb31e2467ed7a741c7096ac13eca390c8b144c6711158a31a8ee00256b4e0bb2d89011844571a1f2c79e2d2678c748780823c79e9aa1d6c5f76ffc650f20e65889834ec332f1ffa83250ee03c2c5e9c058bfba618043465e7c3229ed643c7e32b30ab57f4515a57a6c3870587796038556085a5756d437c298bdab074e23dff135ac5f2315032e2cfed5f21a6c07e60856a9cb2e441c3b3345d38d3b3c844f7ff6cf05581cec31da28410b3ae1caef945ec8debc63ca2de8e20f526362122cde744db385c061f443be0a298692a7de0a0d62ba8c2eee05926a9888fac08376285c1b901fe39c6fc11aa398314a3b88cfce1582e7a584e25207f2710bda0377960f121fa97c592e13c733128480a1900c3bcd21edd3db5fe288e7ea2791598561038ee1cecef5108eee7d78587c583b4f5bcc85257a79d99e1dee2583db4b007d43a9cf6dc2f627735cdca1b1871d10fa81fa5f6e80fcc21ef302c1b15708a179b83ab8fdcac880dbda337b9113d3dd4c12d12ec98c605e406da9a6c04485ce82453c8ced84fd01b6e62f804f3e789603c23161e0b3273ea8715af8753a6d2a599d2922708f72cd97fec10c2a8c16ab6f03c9374da94b7cc13613d27761e13f45054b4ca7238cf264d9b685a63e2f1ce51ab470e798a16adb0128e324b674d4bab3c618c736ae37181719b9e68d57e18cf22bd36695a633634649021e79a89bc39d76a1a35ab0fca4199a50e9cf11adaf65c7d8122cdf4e0a91f0177099aebfbe7f8b4813d81b3c2ee877daa24cb16bff38d530bee997305137a940018b16a9b6831e186390730a12743888c3be6914ca8f421ee5384a08ab2b0e3bb5a80b72e1b7f51be80316eda7fcc3b4d656b1c3f502333a311c6b584973a2a5d7770349d8dad782d630c9db0b162ef33ec1c528fdffe9d59c57fdae5d01d80daf0925b9b9ad5c36d80a95a1e77a1c61e621b53d066d7eea8e37aa2cde54a33a4c657b52e2ee85bf4dfeee676ab03d4f89e233a8c8b388c572af19a8c3da4f221f09c7a19c5cd5dfeb453a0f3bb681978992437e8030a60f5dd7301fdbcd754fb173b87e94549969d7c773c2ae3a014e9558677f56b122e6b52bae19cd011625abb79de5461696cb5952cca69ccf415e2fbfaa9c26e78ad3cddea162e819833c18e884a64643a4a444cfb58defbe444227765768285c7a4a219018414f42314b3e5a8109b7f024b931a984135b59d5404053848175a9f7411709b2a069108aeacc19190b8eae462af6ae04dda269693ceedb8590396f28e6ae692f2c8851b4ee9d06d1ceb870def04a70ea3082a66802bf0ef9cb252fc9f2314c4adb15f9f261e9bee73bb13b2dc9f2f12936b964d6fea29116159f5537b14afcb768f50bc2d686b24516b81f87692c548d34161b60f87762b88c96767528298263d4c9b33e914d4b4a1e4f3055a006b76b65caa8879e7b3a42dc6bb9ceb012431c7b4410a9c2fdf8d582858634fa242e1487807adbb30917d5f6b461ad3fa4288079f4160651026bb218093c6203b9c0c16e16c8711f144571308242ba7a0dc4cd4b9a8fe8150db576bdd657f3a5e7006b1bbe2cd9b729f1caf79ef30b06341e3e283b0019dc10a83a63f578cfcbd033f2ea6d6c4c48ee15681c1e82abc561376b9572b18c581340f0b6758bb5f1a5defcd590a081d37b4fd803b454bb9dc178e5a271227832c87a8b7f11f6f0ac559da2891d68fe756a6b104e9592a9a4072fd191b137a7ce3aaa514cc174e3480ca520fa5e963497a208a20c9de7e7d4c7dbf5c5b31c0312c02b67f227b8eee6abacafd5f363dcc8d820889a14face9c38a4dedc10f1af2d0b0f950843d9600e87bfbe31862314153952228ee1cbcb57f6aea616235dedec23d155450b4e5efec214635dd6d3828d24a60c71b55697e3ce02d24a139dc231084cafc69b9fe1f4e4ab00210c25c7ba3d53532e989006c4d06a756e3169697897a7a992ebadd657c0009b48eebd8fcd55a2f40b82e7a29cf1c006c89d1c18000f0cc541a7b513281033ca02dcbcee0cb06ac77aa77067855cb8575373d0dc611143c6b3005712e72cd0623c4f63933929aa34704ba5c4aaa7f61afbe8def893a327f2c0581b23190966dc238a72cf7215305874950531b2a7759b5923d2cabb1f2dfecbef8acd100433c62fd138a24a8c2505956126dbfc21ff031eb55c494faab1af8b2c8d0c0c18011090ab45102c3cd27e1c7ec3500a06e9290d3d1c20021f92934a3ecc34d2f5a838c718ceca126d6b53a535e33bb4d2303a05c0fb1bbc141b3d44b4d5520757a2a71d2a4facaaa89de265bc1e3827e74189460231086e699ab6125480906a436920546f2ea492a4921f12054d13ef4b02b3584079eca37e663c889188196c236d10764080efcb29a5f14adf02f5216cd9804ec3c12364f02b71b7fa82857078c226986339c1680b08bfbf906e4f503e83960c119957c4bac485011522d31fb34bf15a28039de7e9a8e3a9d8f5df6df0adce4a2c88d02a0ed864b6828495bf79736801439653bdb3efebb670949f41d66a180b4b9ca5608ec3276ce6753db2ac491b064512a01fbaec5297ca247bd33014fddb68e0ec7eb5f023e6890f65205d69a3f1bb3fc533f86c4ce65d9e406c89426b9f40d981ad4bf98fe9069e95f345daf78828af2b934eaaf62a7cc466bc5b7eb5f3caf158fbecf338d1c3e53e31e432db0bad07df744ca5b5cd880855a457e3aa617723ee40213316d641d624dd816901ff89f2b61c08182700874640e993003e42c2872d4f387737073c83cb7bf1d73e9910a3caf5e267956e7a74e7bfa4f343c4457490955bc9051cd88445c678bfec3a57a4a011fa3ffe24076c12a9a13169065777b00bb4658bc4d71f4bf71d86f9f014f47ffac5b8c45ff3da004082948a3dba41de4e1d77e7bf6cd24af520d3bffd6c245516ec147a4b9438b1f233e877f4b0239ec94b1eb4d39d02bb47a3e0e4b75bafc3c37d2871fa03ad6f42057e8835b80d545944572bed8424bbb85fb1ad37e12d0131198205aa6e17ec00d9ad78be66dcf9538beb44f66ad9a162d00634866118e75c54eed81bb6a8d1345beab0e901c2df1232d7c7647b6b2d4908e8296bc42d8e4a42d788d14ee9c1160ec7a7c24a64d2b948e795e8b7e639b8b41e2cb8bf30f39e89e9395f4d6b5c9b14732dc418ae229fc056502ec8493f5423e9e964b4fb6389534b61ae35f522c2ad15ea752df6143a1b5406ee0b062355243bf1b3d1c9ed2030d1107a9e6dd897896d3fd085d27b34ce7f1f5d8940e5658ad1b33464f7102641e4761c14b551bbae2d82a1f069e4380bb3c69bfecc7af2f715b0c6b049b501f062419429e111bdfd1846ba988217ce5658c1857578a13265f1523dd610334386509ad8234ae8020ff3e5be953c084c2644905de5530f891a62beac380ade40c329e69256ff6023145158db0b6af0b91c4c36deb2dec0b7f588b50c7f05245c7e1c5e41a905f465472593659bf6aa0f2598c259a7d3296f9aac10bc9db2ccc896e851d3529227253eed14d41e34d11b0073675e18653ea8366990d2d330c9d3859af0e75c1444a2c214affa38c0a45bd91c84282225086737c09ceed77bcacbb707580155d0b3487b07a6e11dbb2e94dbc401b199ecc68a36cb8cd460289bc75fb424629f7059131ead30ddacb3965fb620bdc4d4aaa1ea6c6cc72814d2c9c1328f47465960f31b5f89f014652be5b86108ddbf20448537f546f5fbc4f70b3219301e3e28dafb884645ad24604b6519b94249a327aed5b78e350dd816db75b5a223dc27d9e463d47e3df81c5eb1c95f355d2708e90152c6f74cae47b6b526d01fab2a432f7532e0286b9e2fa04bab700bf32bd6597eba91382ecbf75ef2b77fcdc2bcc8ec5d7969095182320796a485b9c7d52c8f91a7b7bbef8c24b0c0fac0587042172532d5ce3801a8828fa0ecd32c45cffd605aaf670b1bbadb4f3a1492457da9e6166dae26394b4e816f991fcd373fb4acfdf0e828a369a4575f8daeda6d596f8b41775e3381258a69d4d1cef9ad0e1002c05ad5ce31059b9490f6cef63d17972b1e92ad454797658034b1ca9f01c4410b7f2460ae00ad380d3ce45d124d9100bc8f4b9872880bf61886562d432c7fadd00170ca21ae56735f27c4ce9341e5f6eeac9be405ab7b14828a12e9696d8e1c6c0ed96c1aceec6917b309ca4013d3a307225a62f9801010356daf0fcef2bcc6fa5f255a80823ff638ef1e33c90ff41fb7d94f3e0dc8ffedbdbf9160a624cdb0d3e687ef7d3f624b010b13f7ec5eb8a7f0d466c3f9671212e83585283e53a72fedde9c18e975d06812b16840319458f17b03aaddcbf2b3a2b862b78b4fb63b164b76e775ddaad2cad2f0d6b145ecb0295946fa1ab9a3e59cf0af0948b7a38bc6ddafe54da2b21ba3d1b83b7dbaf295eeef78024585cd349f4c30cd3ae71c700d3ee1adda893f627b8fd30145e438db1de5be1d56c31a29494343e6cd5062a552052cec5ab6f475cf38b5da1f8395e5fb0019d09f1f7cdc879f0f26f0fb259ccf109725d2098e232ac74e371350c842d169c2929bbc01ef25e6d604177d58179d1828212fd487e17a0f34f197e1c5b7ec514f0517ca09ecafc3d327995cf8a6e6c6b0d0cc8f61d0fde33a392a7825857663e9af2060704d23c96e06a40007580c4074d42bf4c7cd3fe6b47ead1b43e00c96d80db244f0568d2d084496a01606e63dc26fd5700270d4c98441300e236c46d92af023c696cc2a4f501406efdc1fdc6dc326360a73614b63256f2fb4560662ed11d98e209f05a12109733fb67d615c188981222d2f13ed16361da8a1cfa6b228b251648d6ca101f63f1534f8ce8b82bb90b17944452c69b26d228e351e84f12ab036e50858fb835b02585a07074921242448ca5afafd61094692321c47620b028fb4c4bc6c3c14dc4f8f34d2d6c72921191f0e4d50f06a7c5b54f490395b9de51d8dd580cf47e5d99aad0aaa1eef6fe3bd8c820de61dcddb2ffd7af13eb16476dfa7ffafeebfdab9ee4a8ec37cee412d9b24b3805e43b49397d888bc6b720a6a6f0ffd88abd732ba6955fb16addfebff9ffb7d204dc4bf088d029906f3aa930527b5d7ef8ff23fa9e63c2038b16df23f407f14d5dfee48abbf6a2aac5f609c042fa2a55459fd866f7fed27ba847e5ff2692901c000f6ca795d1a1fef718023f62b5ab9a5260089e0eebebf31640db2c74db60fdd3f6a003eaa4ece39773e7fd73ac8148434843d557839167d400064659ab8475724ba80df6c1ea5526c0f8c7f00b90fb7633c47c83c0f78b72d337711b128b830c005f02ad7b43979fdc0f09271f51c7cdb0379646a8d40b6d3430e49341f21c4c6693926f9b62853b4223ac8e7c41fef76ff6b3503a918a8e1d4abb2a958653bff6b2c2d672092ea18536469ef6d3e57edf131295fca0f91436c7281a45270f80486e57f04845d127e551c1b8ac593512e839ecf46cdb1130ac8444249a1a8b5f82662ab188b7374f56c1a244b306277945ceecc6904d53fade92e1b0d5cfe1e4ac78679df7615b108615831f81927c5d562655e059c82acaee7bab30c415a18aafd92fbbe50c50f0e9f3c2204ce23932a140303fe9b98df820a1cd0d72d19172f98b75e5b4c0816c46438ff47bbfe66d4474c8b39b1d48c3ed90ecb9376a31346ae2db642825c6c22358877b0c6fbd342d13f5afba358cea5f948d0a1b3ba191faa4a38221760e39db81d0fe69865a331dadcf0e5fc17dc9f422b358dd6521884aeb7d9ed04882ec38064d7755bd1c38bb8138c371d91848ef4793288aade2c20a5ca9e40dc9a66c6256fffc822cae9d457ec9e3b0f14b067e79f21a73f47281a705516670eed7a02c67c0639189b05ce4a41f30f81cc8b9a5331c74863d243437ae67dc544dd49af217faa3e72afbc70abf6fbc1cf0039797511eaa5880fb43d11a9744e99489081ce0d9c093b86f25e6af81936b10e06d0e787f1ace3ce39de9f994e8da9a64a857a642d53ee64d845d711b7b91c1425039018c6d34a645eb7128582d4b00795e4aa0328232dc4b890b62baa06eb6c7520525b564c4b1b26883d99c96fd9e7181bdca9595f795897e674116d06dd0f192c58605bc78c2d6eb48190ca5b0a2ff618b5d4dc53d0eb1e0fa253501b18ba96a71c1dd7e5ca9dfe4b26fbab91a1c8e0d590d993e415541ca88d4a5aacd40a5e5779fdf089341c29c293f1753085ae32c25864ea626bd2d9898946300938238b2364686837fb1d86afd031142ff02ee1171790fe0aadeb1a1de1c4e858a99090221346a464d262e5fc879656571b3c8160c2e7b75866856de1a8aed470b42d73bb5a523ad819d9c42e1b650af04cfd1540f043748a8551c4404a97179741ea69ca0687085b75784d8fefc7730ecbc8aacbedb170298e609c073133f6a99965187761da024c15136ff5ce9333d1c1980b9de86c0aff848bbbd0cf0be4f23e143898bf132364bbc8bc2b2e06fa4c5ebc150a8be4e21825f55a39aa75a0899aa0b18d29a65c459a5f2c9f5daabd4d8f55962dd748cc63a755c1bdaf1cfe9b73f78c383f12b95c0ea55b80b07b519a91ac8eae5509a161bc1e58e01de33d0aa07fc93a5f9e888491acae7a7535847d9338c9f9d73b94641767c0544751cc4b5309bef123231c7980a1fed97aa1577dd1036c5bf155aae5abb4114d7501c1282d6e02dabf0591571d2ee9381f368d8d507d7d0cdddf39560a076ec9a29b9eca7b6c1e7561a6d2e1720d0c5ea1cf8a1247a0deaf8290c491314a1877346b79fc7d406614381bcdfb9d213ce4bebd8fdb67f0a8c395fa94d1b846b43718f8d72704f329fd3fc3c29aa1ab6575ea74604e1962a833274f114255f1f330767763a24d2bd4f474f8fc28a4ae0f930f11c18cfb3dbc1baa0b98edea8172bb0492b818491670c027c724db122f0794c1aed0447a1242569514d62c97e2aa254581969793ccd15cf355331295502a084962a325eb873a7aeb183aeff52728d6f5c5f1460cb063f330c8ee400be583b273838cf689a2a35c4ba1e5b801d12d5bf0b1b8096eafac28046044913cfd8b3a555d7503489a2c9a4befc423b8c8891750d0d9ad97a6128ad0634ba584f8b9ab7469168ddfac1440d4a7429c12ed527986e19d8505f8a1229a1d9c38b93ae5eba2f5d4c8ca0d9ebf9d45dc711ac00b72732d963f035118a4b763fa6b5d71ebd613179a4b38b3ea912e1d034c10e318498719eaa7a856b788b3e3f0cd54dabb1e336aaa1d33877594511b01bbde2e0e3cddbe77adc8d0ea37534c48c978aa3b0aca7ad7bac0802969fdef492d2993e52c6b2781c17f7e416df242225783cc138dc2405723b7a0c311eef271c09178754f65d204e6dc0d8acbd84a8e79a80217704fb4d20804d375847fffaf5d6631800c7aa89c44f37a00a99ea7717bc168013c14b2176aa4136a4e66a1149d572f62fa0139ad9e669076c2740ae21d79c4418b0f001f8ea86f8b5c9081053e8eaea2109c87003391085632aac26ab0262d22eec16fb7e842e6b99bf1aa20a3ffa812eac83c4c3b647094403c889a40170a3f2d969580533a46f6d3be65d51557276fed2bb9816b389ea23941c2d7f7dd3b5136ff9bb870edb0b4cf5ef9f1ab239558bfff367c5fb13b6be4cd3423e678a8c749624042050fc1acc81adc81bc87baaaddc0655c6048475550a1666c9dc367cef64490803a9f14a32789f4f7b9c760fe6c264316b1ea9c7abe76f41912c1b78ae30f222fdb4a70a16371c55c478f457793958fa764343f989c56950140cedd5ba52a9f922b13dd00f65c35e748ca9f2d45d6b2ee586f7a0004660e2637047800b8802609f3298e64b93340fb824166d3bcbedc32d9e39d5f9540acddc63f8e913a8efa12cbaf73d799fc0ecc58ea0086c129bf1d0fcdc40b253e583c8d331ad91a3e76e22c986148af00f781da6e43978f69730e7c231d6bedf62e89ba02a9e4fffe3cb10e49b20ae90b7e1e522fa86e37ae11884b74f63d4837441bce87395e3a24e33d716463d0a7b427e31bc034d8c9c1dd745d6a83476293d75e0e0c852da4072011375a5145bb086fc611641ddd09c6171bad507b4b4b03a4325cf33c422d4634b7b54f68954d7977bfa7063b3ca986f2d0f3cd25ceb475667337a040ef0f28e368af152a4bb8e90f81ffd6263c38a4598cb0b507aaab4303af315d9370518471f2a580d6b8b825354eac3e987dd8a839a0665b2f9e0af2cce99b48c6eeb7e5c8c12e8d63216ee1a71927d6bc0894a376540ad6af332edd2d42873fee43474fcf25463f0e58035a9d5906ebc8716fbf0f654cb612d6b14c1a57a9205e2f36a69388346d436a210a085a539dd86c7cf7df01ac60fc671d2f42c1939b8478e061cf4e10389cbd6b69b0bf1923a99258588350768fa3750dfa275bea744d4a0ab838ad20c9ccaee28703532a4ddd1a1da1dc5b5dd21283e04c3b92a29ad1e13c6e11cae4a74dfd092031122105515f221d0ff9b09683adbead322fb952b998b1a31859b952b01588704482c00cf0aec196823384502207b4cad0e16b78202b06fc2a3e07c5ac003a7ba4833ad93e4476e1543330aac44a3c2b915698820744b13ecdc72285adb5e50ae0dcdb9ed5d7fa6ff5e9f56a103276249c5d1df3da05e3ca4990340424d9f02c8863dc0b6c51bd6fdf1288bb5f3ab5f010456f53921d917339dbf9a75436878b024780ee1d7f6029d608c8237064e0421906f6f0dae2cbcee954d87b90ebd2bcbcceb5a158274e9f198310351b346325f5754d938366e10d7c529fdc31bac94463a67837f4848bea691dcbae1741d24512a63694e5966197549c560ca4c8047e450a3d0c18c997ef8f1b24e6fc413a818f7ee503ab22f29bf2c538d3e119b06f387a01e1b1a8dd7f49677eaa6021109f8a819a82c18f18035c71bd11e448768710352f8e71a40694e511f595017248ea9798b710e2440b50a545701f1538114d440a776d82087bd8be7bb4b0059e6d80a26aea0f87a021304a660810565575e42d418bf4a33c96c05b0c26b597755b5e4615048a3c7aaf55cc0ea06a03b0dfdda89eeea019101e1e18ed5221b82409961afb3caacb0afd3fd8abe4fdb79118340e2a49ec6d7c6299a5cd2a90042223962f946c17502a3186034211753ac5a6b3c591f0375e4c6289ca0475f03ea2137064102beba97e013068470d044b9624a7dfc99268f963dc16084cc1dba29fedff270c983e3ea61d56b08d4bb80818e5110fe63aa9e9e4508828895ef82e88fbbc2be06abf8a6bd644664a8c730002ce357215cb67cb6a52aca5b65b2e8bd85dfab2c2e726f33863de87e7f59b7105baabd8a1c24f5154cad55fd4d743a653c3c2cd23d5a606f71e255bc95f6b7877d86e80435b5b0160c84fa05921b63e6f429e51dde17f08438496e4b6e3b558df03cb3abc880c09b26ffd0f5fb25f8b6ea63e74d43a64cf47ce5f6ff88c86561a413281dfa49b6f5786efdc4137adff645009f0e8ce1115a62484cee75e1381ae9bd4ccaadc4af5ee3283ae08a2d77d0d41c20cbf54c39ed56126dbafe25ac12f1f58842c2e15fc8f95269ccb8d0781a39fd0904624884f2535ccfa40e9c1b68ad82db0ce89d803280a0d14e6ab53216651da97ead19ca638b5b8ea89eefeaff2410fcb5766cc6a15aeea610f0695874e4078437012908cc293435f1a083ae00a94ed8a9b52a4219e45cbdfde0c33a4aa473ab85bb2b62bb84c1ccebf1acce3cce52f7ed67278a20bc75a0b0bb592d0c34dcb1f9d3c993dc5fcd8764df8423c7ba2059aae7283af23096e9cc04fbca78554eee731a095719aa74dfcf2be1a370a1d13c43ca8b47e721a3be5804f9fb6d7d114dc7824fa716c8bbf0976409590f0895b46d1e8e7af0884cfbf796b96faf3fb346bf02e10de3d53b5115d996b4d5ed2f54319ae4fa5e74ae174df351bed79396faa8f4f4cbad9f58aed7cb778298de1cda7aeb50d6477e935f00b13e20b2336dffe841f6021b531d3524e41c14d783f48c2df0b14922e6d4fffd354604493a821394d00e86f9d80587508f688c562d7f58bc3f0e7a94605c49568a4f4219ffdaebe979f326fde43236eb2a83629e0be94850288f61ea450f5127a2bef8800b993f265c47d7de9ae0cad1c6afa0415987235b4be9b5d76a461d41ea9100e2ee7227e0363db7fce78d4a3a0071700e9063178e0d5c1eefde7c360da54c8d4d6f000d090c4839d09378b390f6000cf74e75750ddf0ea731c643ebdbba43335cf3098738be733f60aa318916d3bce45bc2d376f774e038dde24910887e20b6fb1b74b3cde9d6ab136560922712d80c0f98fef2cfc5839aa8a3d1e84f88a7dc2ebda35c578147d387a92d086eeb9142905b5040460591260c6b857e8adf496811a3e7e536f88151b35ef6821c0023cc19abca67d9d8d1544533aaaa3a5c5033002773ca2c3193bb3d6e973b2aff7843d0339f07fa54adbd778bc20f36d34578398397a3e2363cf8271b16dd2ca7eb3171ee86b25f2dd6fcc5abcec0ec9717d701f65fe745c0bb4f64b1030469ac6f64c81302705667912b2d9c437e4e069fe75f98015818f8b9c9c6f4812cdd46576a57b5b57ac0fb2698f0a7a77c311f1a71ac298fa2ad0454da1f0a249431e78e72944a105304b4fe9e335a55ff3400b7e23805fb0e44d1b1fe91cebc046ebe5643d57b925ebd85b0c7c0eca15f22e670417e1ff3dcc7241b118a090d4c241f1f50120e34edaca5e3b617f683725ffe13fe478ef4d9ad73ae6db21cf118c18fe8414f0c1f379828e8b78a645117c6899c84d7bd982a358c21211c62f7282d5caed3f4872428d82ffa3529526fc89748335a2e1bb7a76d3c3180259acd7b1863d6a7e2770860b240e546b3a7480c283ba78976ffeab77d05e14650cb220f6c4e956d7c6d162bdf5526c4a28b87bd5fe7e1b10d85142f6575e62ba22d34b1486466e9f3829393e558f627a8fa6c60955e2e503273cc813fae0ea396aedbf951d44664267ec36598cb01e508c265df7654acf37f863485937a2d7962a7af4e3513c969136172af3fa59e9810e9ee1ac1eee943d401b56c2b8aba14bbafa46365cc7fa0b35b89c35b98f0b397a9317c8630297323393c5f93e4286e3a3f4b5b3a3c9e63a47de356dc1d10460ea73e206019101b318a8ae303a8f77fb5a9a5c165be836a950521c268a00e17f619afdf686a2823dfb8db09556bf1ac6ff6094ae316ce38524dd163a2ec9aeb6e7ca63c8539f8845efbfda0bda8985db14e3f478b52b4db7151fe97f73a556cddb8ee20fab8a8a8a3292a69e2ad42d74eae146b6a152de8bc14c6e0e90766a0a74e896439fd1ee98d9f6e64609df8fe10b0c544c2b6ae5e995af0e787a96ab4cbc83fe0012dff622fb3647a804a196242e7d50b208241c9b6853896d84815164e53b5cc327054ec89c5805503575f6d47e715775e6db378c985c74ed200d56afe5f56441f3726e48ec32e83a2849170c067606534c26698b6262d61ce11bbc86444c8f1a823373d41bf1dcf7c8391e5bbe85d73437f94a30174438848c571b6c220cb64173dbd402111f7957b88ca0a9488ecb503ae5b3e7226e11cd2529e4fb7d8b5010649e7c40e316f6428024090749cf628aa9251a9cb5a54f70475caa2fc4c1bb19eca3c0df2f2c99069d0c5874a1457d84c1ed6d38a0a821fb624313492fed34b4abac349b2b76385f4ae90da920474dacd5c84af314be5ad22b798acd9a89517fffd1b1209b4523235cd2488142ad55d5a91aee0eae5633d8420dc04a96907377de3039416441d8d007d23986455a3b1609974d9e19ab15b6c37583416831b8f7cbb5c45ec289c4a7835d0c166b22a8af823bd1706e8245196a2a7d347be0407844c58d5332886dee8bb081e2a3d13af95f677630fdd85f1befbf0ecc628fec511e36839695ecf91e46f9615a60f51aa89f968c1a4fdf5eb7483cc6dd737f0d01d4535d377ee864264351eae7eaba9a9734d1d089f108a700d3053aab0c69f3072aeb0ccf3c5ebfe6630c9214c2d6d0f866b0267ea5e178a166657701ec9658871c64d50684fd9af0f48d3f49416e3a5023b9b1ad8028ea2ef6f029f243b0540ec96285c976f90886e9c1d84926d4a3c3085921ebda8fae1704a94705bef3d67ee00bf8754b6a20c87000737d7e9b8505e9da5d34b0a9f41798c408e656fa01fb4d4c2709a3dea9b5c6cb71d648ee64e4fbbdf21728d78bd5f6e2698ade5fb1a889588394372792a238b789a39f50fc04a5bd6f3f8f0d974d94a4c7b2e988839032b9c4e97c99471415c3bcc02aad3b5baf0e7a34135f5be04fe4f739fcb0e2f9f261e28e745088526f554b9342d15f793deae04f41476b19e28e3faae5a81b6418a79a4400bfe3f5b1452e9b491575209586b71ec9430d588bfad0cf46666cecfb69d8b5c749ea5e61bdc3abe2e54f8008610428cb5f086f49b0bfabd9700df6afc5b951afbe2ea654378be33555acff6233d99023f0addf7117589a356649c91181fcf868ab58f94da7f5b5e5ae4fa32164e4c5faaf4b4d0539ec9c1a5190f08357587e040ac7081b018b066866e07cdb7a3ffa84aacc28031ba3026f645f0c162bed82f28a5e95e46106c5c308300d337dc30214684bfc1168d89e4488b89daffff624dc0d6d33d7f68f63f9dd110bd91fb102b3b40c14d7fc6527f358d82af428b119cfad20600fa61aaf6ec75b5f9969b79a6747b84805f949fb3171135c93ed5f10e3018dee74c0176c74464ca1c0c42a19290940b3dce0d02e4e7f8fcf29b61903bf0ea867d7890f7cd214503501605d451a89a45221ddaa5c239f762438d7973f50a9921a685bc485f0a94afa7cfaec8419b78ac695032ec99d36c414cc9cdaa1063763b79165faa0a160bfce8b0c0671111837140f4782f0710baeba1c7be2a7a860a8265a0a349e22b6fde11e7c0010180f263d7580119e7994e9dbb710853ed40b8478303fd37e7a8ebed6049b04ce7029ade2019e7428b80d9c5780f1d3de72510ffbc8c991f940b9f1c489a7c1f3b9642c431d25611d08d91a9ad086573aba1df7af3dcfa1dfb82831992c43b9bc111988a85ce0ac7b3d9f2ea9df6cb7bdebc6dcbcee3c19dee3abe1a13ba2be7af690b898d20aacab840f003ee5f2b491d3853d983925e54cd9fe1c06f15be1c56c9f954a6fc058a53bd27b6fd185afd06e91d91bc8271290daf34d69ccca57cca15e3117b8c94f9b74b31e80b7149c8350b5a77413d0cd26e580712af40a276788c1f37ce3e7e2796621b7d450ec48836dad0d2f7c857332598a22431c868048c8b75e621b8a418c0fa2aadaa42223cc7c66052f9cbea1964e297af59b550a79b7d7f4a22744aa351147b780a6596f2f8cb5d3137f3585227ad8a144ed9c9c71a4889356e1b5dfbe46a9f0eaabeb94c6ac46ae6e8ff421c838a51510117cd68fc0cec691fca7216cc06cdc259d3e2c07a2000308204c4d590ab208136fb46e0da98c8a12f94ab2111771247e390dc74c91c05960afd03bd9fb41dc5876abf3e75cf3e5ddb70c82604f3b068f0818aed2cd7220415e3f7b15ad6d67e95c0073d1ee4040da472e1eac4a61a00394deead1ba8f47aab10cccea2b5d67a70ded1d76ddb6d0be1703f1da34356835ca9fef78e7ee65f92a052f95c5337d62163a47e53bb303c14d96d558143695fb791b226a6c72732d3095fe2ea3f48eae55681bc94f524cf07cc1cabe472ec016d9b3f35102d45298e1156885fecc9804c477cef03b59faf5f386e93b4c93ffe454874521ff50820e8669f286842212f7a494c615bccbe872863bc7c73ada7ce363efb0d6cdbcfc493fb3764fadbfd6c7e2c8978bb62982d53ee5618b045cbf934d50d4f4268e77033aa0872c5aba48da82362b975763a5c3bebbacffcf095f5cd127531bd9badfea31b195bffa9e6edf83846c58a03af2b2dac296203f4d5dce01679f05d3d768709d308735bb2806ea297f6817b304c42fa08e633c4dae9be9daf7b9764fa7e72f2f7a2e5fc2417d756df8853673064f5a911947bbd52e2ef35ed3821532516e97f9191b41546a24b09206e7fb404694b0b50d6458a7f0e55a907b3b36533241612a436832560f258da72e8bd09682da2da4d8e177fdebb4c6707ecd31fb947300310a00cf9e7bd582e430c675500611f0db90c21d4599c845275853502fe710b2b11fa585de6162acb22c1c5432915776f9b13535cd1c0d674b403ad82685256607cf0f15999d0c35f0acca9bbfe4f3133f92063a73fe1691f044b778f69d5b1babed7f154e30fa17d84c4984acb0d723e2e959efee81174f970895edc9902a68d3a721770c14582a0cb6e03a45ddd62511e8da389bca74f630b1eba9645b6cfa0a018b41718059e4970a208f6dfb6c9d26061fdfabb3572d553583131d150e78b7e9864cda3247a5eaa677ab3e8496f3859830391ed7fe6eba169d7d7651c6606ab96dd7c43c4ae02fdebb116309bb8380e6f625bac0867bdb27b2e9553cdabb1cff932c3e3beb0bf50e2029e9e13779b0bc9279e19e4549a78981b1c53d83b01d9cc2f69fb485dfe81c9e803d5bf9ba2af1a16a76496e7ece280322f23e9d24c85d523a09abe2585c3af71ce4cdfe1fc8d7586edb2fa09dd65d791a861b57c243db71fdc7765c047472abdba467b0cedb43bc12db716deb8ebada2e5241dc604ef385b314e75bf6e6b00fe249fa3025aeb27f613b697005baa733eaf3bae1d0e883ab5345201a4a7fb39d61e29bb05a25a542ab1b496cea004e13b01a2583295680e47a12cdbafee4dd14d7b2d2700cea0877201f7f1af56195744e591db3a9a92a46282b60dd6c63d28b8c0335c24b5357f2958248c08dd8208ca90decbb5110ddddababd7e6bb6706e4788448166ff526986856c010d1fa5ded3066db77621c65ed524adc0ed220b196d10cc154537ecd4fc29bb2f1aaaabb3388c7590711b11002f2b1a7656c5505d0e630c5a1282434774c1536395dd85769fdcdba95c7013f03de5ff492807a509d1b55e319ef491537c0dcf663f9087f185c48b210d4e9d71eef6f1ce1721d60895d1129569dc98b8cae696e0472e622babdc0ae56609975be1c193c963724ba6d30dd9e95b849d5b75beb60bc392b1d0d2d9a8d8abf044c631b19d1610af157a57a69ea213d55b75122e48cc01aa3dd306b86bc5f2e94d7554b4a85c75de1bcfe5dc2088d5c7c3b3063501eafbebd08a6374e72546d6310da8a9ce7bb9f117125b4e19844cbe5b59d94145c278a20c624fd8c075dd1c2d61ff155776a8c4472094993a113eb9ccdd9a8406ac8764671b4090de4cf2304682497666b6f5bc737f868ede6cef0b8ac7ce92367e9e786a4f17e539b7b04f0a7bc9c4dcc5f36d80754851a4263ad141ee1fdd7255cba9242bf3e115f0944a7d44b49b3a911e9c4221cf637dc26267353d5cfdb0a63fe7be6bb0903eccaa0aa3ff71839cb511c7dc3ebd914635670a1aa98091da45edf3041224d4a12c58e7e8d6ab6d2a352cf5751883a3f473515f52d836499d10da69df65cb1e84d42daa21b9c869827d58a0f5569c5d91f57beb05901dd420f068cd5467e137d7093141e643d3b169e657b96e7147e83033acc628bbaff808a7dd27cb72e7e02c6cda439cfaa30a213483f41b311f14ee9ba43d762de3460fdd13b1a21eae8e899411bde23274d122cb26feb3217a634ed5d209c61b7a904381e3f28e438932c2dd1922b7519bb44c6d682d13de96a98ca699f3b500df5f5a0d5e8c85a754a448febf163b7ed2cb7ee2c1a6bd846d9b36438aff334d456c5ada4b4c36422cd4d356aae3e7d87a0b509ec3b141bbcb4ebc36e427c7452fac0fbf9b76ea725a4872123aa305bf04b69580ad59c3f252228bcc78d6961481625ed2187bec51a4e18682faf7a97019829f9a2064b392b5c34cb0e142b42949fa2b4e9b108b8adff50e995e202aab3fc16d0eca28ee515529f47599ee5189efb86958a679e198423e577ba58050e4308f98bb4fdbb95c81b536f235755adb495d75d11b17e2e838f2b94516ec1060f1acb507bed965c8549657d127b16974bebe94d67a57a662daf3e1849b51813032f532afbc05289d78fd91cab41deb2f19826651cd64a5c103febfcb2562354f5be37e945e6e55f00ec30f2b525b260c3596653b3d700069bca55bec99367c2eca8de07bc48e240e198748f27e490e13f4041b118bbba3fd5d211afe3975d0672dad75b94458ad1d4c27c541da83fa4af14e07862820e513bcc9e3b5a7776953408a4f7b7ebd639dac2a8ffc5027ef4765a94e34a600625063ddad708c173fbc115f038d24667f919bd39cd64c81383776e23e6c4e8ecd77db29f7dbe6b0cd0988e623c4c551a3379d455fd24fc2e5405d4221d9b3ecbb722158ae8b97ed358cbee622e6d7dd9072a116d437bd974ba00332c22c8442d4bd8b5c6d8548a4742e0d545578eb642cf4292e0533c999cdf2f3f2ea7906039506ff7e214951f2a13122f936dc4b4999979a311e85c60e3c1ae3e6c808455e02672171b5506c535aa23aa198fe75a9227cd31e1e9d28c4336522333fdb6066d67ec448b05966c8fa3bde435a5f0076b09b2771eaec73c02505f9ed1e8ae0b2708d4b8dcdd8d46b04f2d61c5820644c3adca7008e19f2d241ac9320b33a39fd3668052f969c38f3cc480ab2a76e7f915ebbb3918b3bf29650067d550c802e7e288ef3d6e5155a05eb158bad319daa95573408075617023214127edef01f3888469bad81cd2a63fbdf59376e0874c504ca79223ab1e2c7342989d6080feb5494662b8441781acdf366ce1034807f7a256910536047552428a6d647b106311b0bc25d4463ee202101bfa2c60ee8cfe219714c115413020581f9ea8cf39e0a66891222a178a1214b88748c01bb6bd115fbfaddbe58acc60346c94df6f8e42c9cd775468524c4a79ceeab80323f4305282426a19e60865b3b7c864b3e23d19a022fd444150095d3d6ccb102a15539977d9e14a10bed2ef393c734c4724c51ad9cc688c082fb9f6bc4faaf00a5359bd8e390ce68cd4969e58dbbcbf0898da896ed85627cbed4698bf1e9fd084f5d5e164b2a33972e9bf2282f908ce291809de7b81bef360d33fbab6e60610402f20b90fcc2e248e7a169d94b6f54648318bc5a83193cc0b212dd5b740423a723dde5cc98d640058dc0303771e45e302230fe1228d84404d391e9ac01bf7ca924f525516c24195f8b50dca33d25d93fbbc152a539c4597383dd4afddea862341b9c12202e3429c45fa8b1f71baf0daac735d443e6c5c465432c90ac52a507d92a102605cde6d114d5d48d1b6750432f64df3729457a9d11c6fdb685d2b0d0660a6de2c5ee79e223aa2f3fbe08d9e4c7481ff50943e740ef00bdbba3d33dbb133544082e4843bc3ccd2735a751b027ed09d68df3dabdeb3e53e07d6cc6f357fcf6343aa0ab42458752d615c8be990c1fdf5d905c65268541cb402ffac0a0109152ee4914052a24319d3a5e411bd83ca5b63ce7df63693fde13e1e9ded4d4fb5d1d1cd7be47de9b00ec66c47b12bdfaae74bcb371037ccebe5fed50ff4cbd8abb8d3b12816252712794b8c936ee3899bf634529d3c85e6fd4dee2b61ddddf4732007bf66d8e99388ccaeba535489edfced10df4c664afa45f68af14f07d7531d1b035454e26c44d8358aea5a8a94142bfc8deec2f2f0dd38a520be6313dde5dc8f2746da2055ee25794684deb1c709bfe23c85b2b6795233115bce88409d08d2720026c1f74df0b8d4f2b67e5559d0b2dbfe4add101255ae70a3880357687723e8ec968d1316fe8adb3bd53073844cb5dbca01d7f2e7057ea560a8882be7a903b9bce952400e38c95b43bd05d3edc38dd4240adf07cf662f936e0111953d228ef7abe884dce19d6dbdca93acb686bd38f3c14a7515ae51eace8dd5f87b70930bbe3f9885e8b0b22fb58366549929db0ef224a42592e73ff4a6c0b8fc2462bbb8b26d9e79515f5a7912365fed14460af02143576c3f20436d111f94cd4490c38a1597e71ea904312cc5cdd8b00bf9355607d176645005d2276bd31325dc759e75e7557139a38efc16fa343f8c1971fc8ed11a406e57f5ea445b70ae30aaf7409bfaead8fe841f8cf32bebbe857f4134f1a4d708bf7dae09ffb277db96cc4ac0b91cf73576ac277da44ded7ec03ae3e961fd4042cb5e8e5e0c269c6452671999979fea64af07f0df94b2c25e759e2e041999a35b451fa96ea9d419e96d51a99e56bddef5feac3714ba875d294cd59f13437613ff082a5fa01f9e41a60dc4a30bf74023967729b62d28a779174930ad0329db9a38cace7d49a7b6111604d9e6690f4f0286239742fef1ea1142de963ea430d4a1756d40120f2340bf2b9653bcbc0d9aa4cbd23f129b02c83a4024c3745ccb2090d3a25ab09640b931612b585df0cd7ee700031b65e3aa64143e70cd52a9d13a0aed541e4bb6b57bd72f0806204870b8d03a6572e48e1f5696e7cfbb3df7dd63e20b925e0b2fc33c477bc8ca798c18ae4cd2051bee08171067429cfba8d530fcb33bfc8c0ef754fac436197d1ebc6026b15e3240f3b4b8887826c0ca66d13b0f4d81b4c6359ddf5a3ab2c6019acf26b4326c942dbadb68cae526668b89aa2fe585fd888454aa5fe2f0a12e6a061c39ddd1d7862c3ced495add09b23c107866cd8769939ff946b2e5a9ddb94cbee7142195e0c0a6aeade495ba06de65c5a03d445e0f744151e2e8eb2f7380fdf955984e37ee7ef24a6d918bc7ff970adf6aa091a1a673300f00b4233221f4691dd33d8039d591096453846cd008ddde6138e27585f588adbc44d7456f6613da83a8425a42c1d6a22d9e09946264b839b62a4a33bff55b19701f462aa831a443e0551e674fa401790bdce07f33d92e2610d3b21c7a27f02765f4d25d706356034c138cb5ae2a4bcf43bca0cdd0594689512fcbfd0313be47275bea20f2442c5823728db6ed37cba2284765bc00175e3dcc09ace8ab8ba957a299b48651dee52e07f4e3b779a26c952cefc329f638e48c5221f0e256e0412aca0e3e8ffa26242b8125ae1a7f1e99e79f4a5e71edf8c4a39a860bedb2076ce2ca0c355504a66066903a1fe3229a3f1406f993768bf3dc170d2c50b2c357bf9b69c6a089a1179ae054b3d4169224df9a1f90410e05ad6b18a68f966445e52f361de431782a909e8453d79c41c5506d41afbce53eaacc57af55f4d71db2ea2a0b9260af5802925e52b364dfa60c055c4a2b4f457f33d03a923d5dba1037cc3d2fce765471183971dc764b7999f43ff47b1bba9881b520c91c9c455b379c2f88e9896ab8ee6ba07aa8668263d73d20ad08fe61e6d25946162c3e8a4de9c096b618e91463f4586fed87f0183222b07434f86819bb6efd90cb3ee19e5b85062638f796139b2a8572b598b026e0132104947a253125fe8d56c5c342717cce4fdadf2c28034fb2715aa3ead5f043abf5f7a5538c50a08dc0310844fe61488cb3768ae84f2dcb25e1ab2102ad9b97cf80a6ce4ec4ee6fcf5c2b9f1117024d2a51e44364842c3aba309fc317e6cd899453eaf6036fcb8d52a7006209a81fdd103ccb530e8f601990a57d34719ea49e6bb0623456d004b8cb65ebd9018a002ae8f6c2a5f1242cfa3bf5fb2f40976cbc23dfe5d72e38650b2235256c8b41bec418a650e268ba85d2506b8d8b02b20d7a6b96c4e64d6890f6f54413b6cedc90ace3392bc9a0c239068b72fe8bd43d8966198465c0cd44a50c11a1abe1bcc022b3050a3f1261c2b5e9d8dff1b32ebe550e188a54971ce80a31e2a059775f046878b12c127e897320652662224f15cfaa0eeaa21b1f41a51c8b551d381a5a5db9a84b462c6ad52129649d24182a7a49b8e4258acd6b5a8eb4b35664a6ce3ddc8c4e0a1ed0116a657e6595c1952560342ae93823e9472e894325c6ce9bf9b2fd843293f3b1168f8ab84fb9dcdbe3355706016c690a8a4eee2611a4d8c693ba3a637f6a468c938f0a973ef40ec63766cb594801bd0d50be0001bd06657536ed768d5b75c5f8bdd72928ee5cf7bbdef1e6a29cb1a127bf988263a9b59f9e437ec2673c7719e2601d8f5bfd495f711e07e8b9394b6dcc4d4f54284bde98b88057ea1523674eb153786b9ed87873c22c0f29e7cbd9ac73b5b09e7799b63fb161dd9fa84452cf51b6fb66bfb06615162915ef2578d7e065218d62eb5232960bbe76dfae324e1ecc6f47b2945471aa7ed994286d7a471e454f1d32c91f85740135a58a836570ff3af015ba6902d4b4a36e2a3112394cc3e61e55b4b61063a2b41175c3d290654300330faea4153a8e80e15ea4c19c90e65f253647d533c11a44f4c5a9cfa793a67673b4819ade1625ea71de20e689d2e7124da1ea93e5395970ec7bcd9b988f5321850fe6aca923570913b28ded5a855ed0e7e3d990a3b8902167db53fec974e101b410da434d2f41d22da370138545055a2e26357727bc5579c000a87c081d2190181883707209d95c683e633bff77287a8b9014ffca754698a3346c93581a5ddcf1202096a199c0a85d0055536fa1385238a7e844c2bdc19c130fbd45001c5d42fdd1a0b874541e3bceba6de69be3363d870f35aa368e484710f02cd8da644130f2bde7b16678384fc3ef5adcbd0477f18a2e738013b30f1465f2e4e4d6000bab2bb08b0ae8ce2959376a9ca057634823b359501a70e7d526906b4f110e6ef829c12c4f80aabb685f42aa375e740fc2dda7f20a6d8729392e5402cc447e04ad2970becd5889cf7c50893277b9eab4798b00e7aa4489883e39dbc2e8c77dcb993f796304ff402eea52bdcc6a2d0f87c3b89d9d39b1533cfa96932336e2bb2b4cc04aaf80bc65a30d659493afd98d7fc410f1e657a4793aef8277e342675074e40715bfd247a47d59371dc43573f2115df0cacf3a371fe95c0d35bc8076b15e9575c4115e12fce2c39f537baa2b0d7842e5b11531b1b698d1042c8de7befbdf70e080c9b0c380c34f213f31004d7c1a121f978df030f3f7c66bf6dbbb61d74e0b9de52c40e4ee083d337fbd874ececb0818b350c3ae30647d2cc9bd5ea1a71d864c25d1670ddbbe2eb9575641e54311b657f5d67a4997372b37b4b1c9c135cb56238f33d1c08c7958166c79947231ec3a9b882c2c577b3076b02ae7b6148e9661034b2c3861d9f87a56b0f40cf6276f685675ffc4080a484ae35df6ba916422631a57816496bad9512be2bddf9acdade7b09f5bd1d91ae32da4b4c5fab9552decad367999452c6ffd88e3fb0e7e7b3407a24f07dcaf7241676d82270fa3d0929a51a7cd35a58a9acb5d669f18c997d66f17d71f568c0997ebfb6a6eea4f4bdc22bdf9c300842bb67fefe611d4e5fd705d4570f353de30acb37aeb0dcd920b47bec2bf689e5f82cbe589365b750b87b6f76d15fbff3165314642f336120d53d4f755595aff2f7f41366d5f51ea9b2b7393b7c36ff8adf2f2c0f2fe1b57649e7f3aa40265c64efd953bdf7ccebd6877b557d0fbd7ccd9a0ce4697c59e6b7c42eb14b9854f122e7d178284a29a743d3791b030ece34a5746a97d239e79c45707006ac01676ce05c21b20e6620f311de47a885de7befe59a199c0232af56827bb661ecb1f2c199b4da1b57ef10e6f8856697a0a6ee28adb1259839fd673c1af05688f8285eeb05af95da6157c0755a471f1c3a4b7193dacc28562faba1a24d07218419a5c5d66677425ab563ded444b3dfb3d941deba80db8e4842c9d822ae9359657f912822c98937ae68ee525d2afe9d4ad330dcfde82cfb2afbbc37d250abcade033519702a1d78ec30d35fa99475c2752854b4e91e10e22a36c175ffdf748aec457466c2b2bad23d2a1d73e7b302924f7352d4d6dabe525a2b897455d21d109494164521a00c314fed469865efdd3b93c415a552662de21b73fc8bf9515cc6c23a0340a79c31577125ad10d1ea303384cf4ccf57b8c39bcc9a194fcad24cd6834d0234515c26eda1b5d64a29df636683f7bc7ce3e744cd39e7ccb21d6c130e7e02d1a632a928d9fcad99529a0226848031de7b2fd0b4425cb1281e218a48909268c5a2586485a0c24ce99d86bad1dea5b6d7d2865fa4b19acf0c16e50f19cc2586e92eea9dd6956b7987eadac9d46ea6575d6770ef6abad6c06ae4cd4ad2c8d7d4e00b85bbdf116db6c7dbd0ddd40b4cee9e95178cc23c2ed8470bd6618747439ec337e24ade8473e24abe8437ac61edc2ae7d527c705e2035925de2ec1797eef2ed46a8cb9f2e2f2ff3866dd48834f142e17018b5fc74a2d873e48d8b7d47db29367510dadd0e5de2a691cb0c0d5539ce25673912ab5c9c557858bec95e6d2e14cefe7aa75d289cbcc9e22fc7a55256d64c9c96d78c41c8de4c07df93adbe9f370c7b04677fefe7c3d258fabc564308a51c413ac28b222445488a901421b98a905cd715898e146d9bed7154148f6ebc41dd7e461bedf63677409089ae3577401209d111222445910849d14574840849513c42725d441712ecf4461b0e2eddd5228dfd09c36cd4728a8d5a8ec25ca4a1d7b0c472c5f32d24249420211106121256201d8105d20caaa045cc2552494c722488b8b28f44d1c61e298a2b9bbd8b45da69968132ea3577a56f7ff5a77b7a3deabe723fe117694c77c12fd2702dd9943ba0d9d7a99d6db56f36e667738f368166679f401248367c427b3e2281345cb927b334db19445b2450868ac9e9936afb6ae38f9e3cf43cec423793eaee0706523d734fcd51b968638fb56033d1a6e6b85e8f61788bb98a4ff84ac8152129425284a408491192523c29913d2b0417a58c55082e6a93764048d92b4d944685ba392fbea7380716b5f5520d85ea22dca5a5909c447afe6d393c2e58d6c8ca4aa4e5e9b479a866ecd2b5dea5333864838010ab3e5ec91ed6dd137a8fc7e3a26bc53c6428c20db2f4fb7cd75289f50f8ab07e3332297ba5ec95baad610989176f8c6037e2441ebbf03bda6cc05e95a11ef2b12203844ad0b747cdbbd2809cbe971b8f686afb0cd25247a428eec8e9fbb8e9c040ff10d1d1ba181820f482be5b0ea125fdb3038caf54ea882ce97a7b35ece64bc3f063e96091481b55d1f5f8327717c88babda63fec8ee91a7cf40aa81525df3213cfcc42a1edd063abe464a85ccfec0c519f4439281928e30e88704032df4aa1f120c8eb03f709209fd905cd06a98d40f4909183da31f9212253f3a3c553ce94e4717863ad09d0f467802e482ee8086867cb2e80ea868e8a73b20264540ba03da22a9df7f7438d05d064c70d4ef3f3ab02b2ee842bfebc07c50a57f5e962c55fa5d07a7c8957e2f4bbf37e422fba1b7d807d8f6b0271e1e8905617404021f0dfab2743c86c5fcde0c0aed8fcc70578b30bf2939d2dbb16714c3a60ef6edf7da21d68ee1ed71e3711dfe6578ec1aee6207b90d5bc8c2f884cc562de288b9130a72c263edb3a892c0f57a3f33cf35270e203cf53707d5e3f0582949239f13a7b453ae7ae08e13ebe48e1f4026abac31c652bc8c528a2c9394527ae1202754d2a0075021d84352aa83598aa34e064df415870f3880a086ecb21b0efaabd2e9845ed0f175061d339077bd50f6b24b1be2249e08f60b737251fb01ee21ada08b96391e80fd82c0635dd949dc7000410d2c2c675b8f9d7b10d4c0ba7eb1e2c60373229fc54de75431d7f142f03e59ea20d0efd1d0e273e20d3a7437819687923deb010e831fc28b8e3cdb104b3a0058ac5cd8af5c0309709f13c3e0b05fd8eb151c96553a7168a8e5890c0df5c583fecadd4b0799ed733d3b6da0cea6a49d85125e4edc4a275396994ea793a9e519d7722a95b892a92405945d9d90bd992c76d1b5934c49a2a4931c919ac65d155f787681b3af97af8132dccf88abfb558d48737fffe2fdddc2aa46b582a3bfef6ab41260fdcca22594b2b14b55675815afd20e555a3622aa81b5fd212549423fa42458f485e58e485fcf6f86ebf7f79cbc81acd2ef0f69e8b0abb26b604a6ba0075dc2aaec9015591c5665d901973b1090c5fd19d44a3ec0363a1dc39d067cd0d8ecb7e1d8313d27968a4016975558fe31656923a21aaced454c5d60010159db8d5c532e62b364c982c3cb8265a8c8cb826593fde0a58087db0ddc0db2ed6fee7947345223a8004be77e482ab04205ad8ea11f920a8a5041108dfb21093185ce4c6ff64c4ffc94e1116d728f7c3c47d41377553ee69ef8f9b9dd106573d146e69efad714294908ba53328f1db7792edacc6d076c7948436c79434d10603495423f245d74fe813d61ee8a8e347c7cc72a1e540a0d2f714f7ce78350c3cf7e7135347190979e71853b4aa1210ef2d2b863eee23b1d78f91cf032773002991d1fb38a07cc4059bf03655d02230d14816495ce7c42837e3ff56b234890a4e5af7ad4f4d72311d4aeec70eb217764806b08c4b5bd6abae6aa178c5b8febd7150fafeb089696df7e1e76285f2cfdc02c70fbfdf69844e1a545b8915e7aaa699aec4113b518c7106f9b8a045154df48c0a4e5e5a6bd4dd3ae65cf30de345cd2b2ec0518ae637a0106d3f69ca82add4df57b95ea7279215af1824aa552a9f00b5c7de1307fe185d367a81854128b2a866c73d166b4b97a64fc7a4d77322ee3d7e5af960b757ce1f685ed31aa2676c3916932cf892f00d1c9607866bace76ed190cf99972a76d4a54aae744ec07b6ea59ec7aade949f5b9f5a0695556f1486d5b0e780dc6c01d6c197f5b0f9ade8e63c448c5609a24aee861b00423ae4eb80bea162c4125dc0535a449a20d94589a1e4a30a215bd5df57047b54db26dfbc6f343553f1c742106249042022a47ac1ca172444aa6696fd3b463edbf7e3d075dd3b626dbf69ca869d77de9f7a5d728a24de9f459a954ba4adaf59cc85d1888ce75edd234ecdaafeb7a107754c96bae2f13fe815aa9b41d7ecbb0495cd1ff58c89f8f0f877e8c3baa04620d5ec74eea35086b06824dd330d728b61baebe72a781be9ebdb880a167b71e0f2182ff0fb19e8d0071d673e4f163bdbea34ab42c77324b962c551ea34a9adeb0eafb9c88b594af517454494c8a2b4ae193a67f4221134db9bfc917f0d3b9f1e0ff72e3f983f29ff1eb912ad214c95e2d02136c494f193649cbcbf8a6ea9a7e9bea393116a0df26e308aebea6bbd8dce1d643c6bbd85ae40eb1963ba198a362a18658f50d77321ebf5d5a893631c410430cefa2941cab8ee16fe389e199d46288e139d1648201c300c36180e171c301c3b6655936022299c3ec85928c7e38e082179dc9d06270d751f3136a88bba00e7ebbf64d7ad105f5bc56e91119d364cabe75a6d2e0062fb335803680c2bc83be14471d1383613e711ceab7edc0e494a48126219798d22283cf1d949fd126defce62c1bde0c72ca944721ba1fd294a1fec4a83090788005c6c7df292590d84f4e09043650c4112876e45143c753498411a6119e4d0c3f2f4fdf93e59b4148c248b4032f6e0a3a7e07431d8f9a53ab4770f4dc9c6fd5d157baf1903c3a407b760fbd94a73cb0d2f442ad33e9a437ac36cb052e76b75ac5f89720b1ed658e99b91bc49c68b5c07528d8a9791bfec64320d8134a81518a122922905284889291f2830b0bef08490a137dfb2149691293ae3067c2989973c61ca8e04e2acc9c83125c9730b440a7d441113de714b07e485550014a19a90e82d0810776ecf8d8a10a29b43c0f3f2615e6cc8c1a36aa8042cbe7dca0421556320e15b8ae06cdea1d21552184b6fd90aae841772be9832b57eec5c18203274f15495a45f42024095574ed7933593af08093b363e706b3e57de8c0034c42154f48a42aa498a92f383804a5af7e485530e9eed2276c142e0e169c2bd98b3638e26fc7f70c7e6218f1edb75dfaa88ad1e6fa0d763aa326de6837db4de9f43be20d57c21bd6f0bb34f1662eaeaa6c05d1280d8949d37332f2497104d98baf5bcd558d8c5db4567360c346b4b971f58e8e9c102549c78e4dd4af1f15585a867e4854eca0a91c49e9f85a371ef13576ed6057999f23674b492fed1fcdb0c6ff98babeb35358d1416657d9f116cbcee0466f71ec9adfa3015e79d2705e12e1ddfaae74ad38f539f53ba24dd6f53b51743d4fb4b9bade47155daf43bc89c1aae7a1d66a82ae50b4a06b9d41d75ae99411a61fd2145374b74ae24206292663ada852a678d2f7de9a712e7ce51af7fe462ea68ae87bff3783cd5cd448e24afd90a6106246a49932e64c2182a6fd90a6f86166d962ce9930662096380499f4005f952b54dedb49d5c89b0380200649ac776845260979531022932313e3155bd82b20931e8440a22b74844a62db8c93b3030a19ac51c346b4b95c960a5335ec10388834851128e44408ac2419c11545a454014384309ae081134c7280a4488a2834d70f498a2474b74a424aa6015508c1091482802509100000ca15b230050e3ef045122457ae2c6099542a47ce265c48d424605a106614543ad11e81eb1e157b04eec12ce51249f3661249036191a47991c6486924824296c45d19736e5c716fbca39cd494aba405bda1093092e8c114b0608210106882132068c205110a9a44123c01657b628a92164fb4a0f404125ad45c1c6421ebe83bf96ebe8b87efbd1c4a29c5c9a45c49199f9a1172d9ac530230274ae042b823695eac31d65af30e49138940211ae91119921441c427df8f2c84e0c512296841022958f148cf277ee889f404d18b003cd004234f3c49810aa0b0e6cc4ae6ee3692144974d60f498a18743793034b8428526c1cb2542251150ba3ecf0a307c8040ec127906887b88af49035f1ce10fb995714fb9034390cc93e33a8d52022f6f35826623f331ce42407f8450d7830c4ca3e1f442413b1c7e6675c1299c89bf926110154aa5c1926499ac824aee0e11024923442244d54e5406f57aa1c66ac4b240d1349739f54255966fa0192437dcb7178acb7f908d28ed95b78646f6114f824ae604b864958e2d02943295b8654ae54b172da7eece063cb5ecaaa7921d6290b59226998cc2df7008760124814574592061ec80f901ceeed73a83f1d888f20cd4790e9d9eb331c28777a20f23f407250e57061a503d929654ed2c04b409543e92d6fc943b22021d695342f26894b8a9838ac8a1762d56712e3f05846b61cb05ff791bdf4b7f9d07c9872249234f0a5ac921762c158b4e3c22a99b3500d8ea48127521292d1ce00070707a78b8ae4c4142427a2c02b0f9d68c2b455ca57a3051caa71828bc905d769574a2427b65800921358d0219ee54206098a15489aaf165c18b60a5b85a5e2c805d65a6b8df283aed5a278506b8d34d04e815303807e48518ca2ac6042217bf1d5232ac5083df802a98b1b80a00ad64492c4942ab8200a2d8c90248ae088abc4a4d907a7653fad9c538b24b4053d37d69c375a5cf78e7216d0508ed4134c3a7f5b55eb871405c951762305c04c2aca0f57f499e97999faf99a73e46c39a7167acebfbbf18e72e20a82d173ce39b34caa46cddd9ad05d4dd213b218694cc3df78fd909e84d1a77e484f9ed06fd3616f20e7a5945e649f99869d592488b484135ace6091de118d47484d24f5ec87d4c494ee66ae90c1bff7e6a3737a80f5bec3d3e4acf71d9af47b484d28e9f7906ca0a4df7b74be18827e8fa8df2d10b8d80fc9061fe8ce46bff8de1f13b04832415aa28b3b97905937ef25cc3df2b7a3139e6a52c6083f7f82ba3ec31dbded819fff910d51dcf577c54d87feca97c21ef96b1f8f8a4a58f17833594850acdd74e87b203ddce429ee991adc2a161607f7e260c1b1388054989999e939dfd18cc581a5a2266e39ba546f97f749c91e2e5947fbdbf0760de70cc4d0d9b54b5474716180506759753a719bf6ed2e7f4fd5a242714771cf38d96d8f77c1dd96bb1ffde4b9671cd64e19e2ee47976ad3b317b91bed33da6c1dea2e3c1d572dcf7097eacc45477614c7a1eee2824d4fb9dcbee4eebe8d7b8ff6ed9cf6ed9ad6928d52cf8937a9bc9d5ecbdd967d527d3af61c79c2a59b300671aa29eeb4a7da5c605edaee826f8ed462c3dca3b04faa4bf2da6c1b0527afdd4671af659fd47d7c898784b75270f5f6f3f4171d7c916880a5610f171717ee27eed8e33817972ccbb89f5c5c5c3017dcd15f47dd8deb5a6efa767813d688e05af28fe61e31976ff7deeddebb645aa671f8943b2a371ef2900656fa34a8d2f632ab1e37db84b41c0383ba8637dcedf4a671efcef900b36cdba66dd7512df7d4025f4ed927d5f7946aed8796bb546b31b4cbb76f5785da8edaeeb269da0f9f9486f9a46eabb6f7dc6bdfeeb55f2dcbb06c89e0ea9d88b7a7e892856cc77d3dce535945f38ef7f9075f56d9732a7bd57d54dd7bb3ca66f9a20f422db32ad657dca9ea9f94ae6955b5efa9f594e629abf79a7e5272cc290c4e25f6092b05770d73323422b81eed2fd909db6b38e636c3dcbe5c3b9d5a605aeeb2d24ecf919aa6bd5cc3dd8f1ca75b98bb3c480cfdf216ab6936ab60320384fa25ab60de633519bcdce69797bfb872f98b2bed2d2eb8fbd136f5b7f57079cbbb9797ec936aedaa979f6eb396552f2d77798b8692a2e5b7529cfeb61f784269a8dcb5681c172395b252bcb4e44ea85b7e7a41f529e6e5056605933bae5fcee11718989717dcfd68f9cbb3979e9654bbfcb4b560d82fb84bf5098563fe8261ce61b9a1def37298a35e0ef397c3a01e93396ec76b15cc7b5cfe721897bfdc259ffe924f7f71958aab548d1f2a1d64286e35b39a31d342a5bad930ca49371cd31a713670a6b5d6ceb8b2d7464e5c4108e1ccab193a23f39ab8a217ea70fabd27d32f8543f3e45036e0e0ed7bd9b68083c792c8de4c66997096055c87a3f934056afaa0a891d75dc5ffb8d7465ccd68883b8ee338881d3b762dde64c7b08b5edcf1599689a4584e6e56f1984d3f9b66261cbc95554ec439c6f1115796051c7c8753a390c1989a31573673dad3368dfe409ab3cf88ab591357731557d3e62ecefcba33669c133e5a9a89136e90c680524a93b8586cb032d871c39ac0aa808349535e0d726cb49070b066467c351e8d279689a41d382bf0c1992a1df8d71dd0ec977588abd769efec6b763ba0d9427db34ae725f5fd9581ccf6c1e9eb9aa6699a9677704e5cbd63f8c217556db0f7debecf7923ae2aadb926aee08cb87af3869725cb0a3656e9ccdab465cc33421a9c5534f8f7eb5e5a1470dd8f3da25232182643e77322cdb706062fbaa961835d451afba7dd18d453dca9c5e5ef355e9fb5e2ca5a38a5ed2f0b1e8558c495cd4631fee091bdb5968b51af232535da9e87acba6ef395e76ff0603496f085c2d1c360da106d3a207a6347b4d95e72e28ec669f8e24d8c6fddbdf085c2c5c80f8316daf8f20ddf988a7909fbe074cce3860305343b2615937fc0e01de22afe05f31057f1283cdba5a5e6c4d99bb0cfa3716d79a87b495dba4582eb26b4d84b58fbb5dd090df596816c679996cd67adfdccc5af63114684d6cf47e3c193f5bd6769c0c15f99540fac13d689235248a09aa4a0e1514d5200afa8b5d62aad11463c3ac3a16c7833043d1af0a6072924aea0892b9d5a60fef27923e3ef36726eecd0f085c2f58d9a9c1c979cb8a3af5f6b5fd062682a2da5c95c6b2d77f6308f81a192b80a22d2c8cbe01769b6a7f085c2c53c66197353a9ed4ae9f218fc823bd8416477421a4876cb5b7e6160f0ec971694cb6df199e996ec33232557b051d10625a5a92403efd8f0ac507956b4ec0188071f3aec60c30e0fcf0e31f1467933f4f068c0b75cf9b878e3a2bd66f74969c1b075883637e20ad6481af8fb1c7989e5146cf6846db9bbdd825f6f76b33cfcd864a24c818b0dfbccf4cd3e5ccd8d68332367959952a57b33e7827fc476757b36acd6661d116e38ecab7dc5218aab187362a5185523a58f0e2ae9f8e2aaa6a3b5b1e6ae87e6361c7165ed4c012773772da45164997c58e4c322b108e15a4758d139b4d32d8790aea63b9f1a3d5bd3364a350d8221e9758977845c57e20a5ebf7cc4158e1e767874e81e181d7762b4afbf97e352a93f55938a3455cad24b33ab784cd972096ece348c4570f0d7159f6968a219a52999dedebd29bd4d73675f5f5ce1eca56726ac7dd20d9fa39a9651717587e020662d3c9da2294a21dcf7ef9ca89e33775523c2f48cc3d7ef33139ebf2639b5b8e250291920c9e3aa97f1155309299e4054c854319c1614f6167cc2a6d2bd8ff96eb9fbbc96bb95ad57c7902c59b248690a44bb660ce034cd3db314651062207f69f8bacc50d35f4b5a5ec5e3ba7de9f2ad195cefd96e5bfe1e8dd32f7cc22db8bbce3d5eb738ea2f9c1d156d2cec5a1e3f5b72677f9d6e3de8ad4cd5b97eda7ec26d7a4ebc3afb7853e9f43cb46fafa8ef14812ca2f70ad05d2ef849991e2c7336a3b428af983ee20aeedcb89287f335713573726eec7834a0ce9b0136a491c9c8f00ac1c90bf5cc85b761b479ad193ce979a9bd197e60fb2044b71cf373b6ec8b5d62bf2e7ba0dad7815c07aa8d6117fea9a1e1a341731e0df8b7951e0d5823ae646501f6fb1aab199f91b9b971f36406efb1dce96014bbc52a18147bc5e85fcd6a1553d15e5e32ea3bdcf73d58bec7c11e6b562b0ce7caf38b2ffee8c4f30b28837c576a0bb2578be0e6959e4d97f4a42d7dbdd65aeb271835ba7ed6449b4d877cacd0befe625e8936962e89112765e26e31b4820ac422c30f83b9ecfc02d2107318e35dea19ccb31933325996652fcfb2ec142303c57ec93db24b65a0d835cbb22ccb321e3127dcc1bc40976710d31f34661583b2e3fa8230885874a4e133f98c12356c29656d4b5b12cd2f88babea3476295482526c528f591896a9fb2b9eb409539c3a420b87a7aee10cfbe9d8c4142ae2b8ceee0b1faa61790867adb4d30e4157322767a9d57ba038a5ce936cf9891417dbbad96cb3db233e52a5850b122698ab5d1f68fd6b49587275c71296ff5043fbd8032d4db73d884250a7730a9e95d7007a9a4705abb6f39dc745c79f343d2d0df52ee2e7d5664ce5a20841042d8527a57d3b0e52f6e875bcbecebda6bce54da2eed7ac99a86ab8637c5a54ea315991413599458a5ebb948a5eb4da5eda8eb2f07a256a592cb58d9bc9041c823d2481860d46bd8fe87bc8149240dfdaa7baa44e9ecea538389ae578dab7ad3d6438b46224d7d93ae3fe56e5544d773b9bb92ae41747d29775c3cd2f55ba69f5ffc7a66350dcf2f24cef517a55cbfe495ab4f8dc6def9d4f0a951d3f5d1fecaf2cdddecfae6179086d7d75b361cd795f9059401aea0b0a4b59e43bdead7920195b63769987dcd9d8e7d7d523ff385b9a7f6b0f4a2592382bb57d2d01abb32a1c3bee7665bf3fd8c44a2d015250e64d092811049fa76ab08a2ae2da70c6bec3201bd909b8ef90c3e2b119e70a0e048cffc6ead77c12b9cb86a1961a511d0af65c493cea606b77bedb5d75e7baf3d96ef7df639f1da6b2f8ffb09338c9fe1da17771b68fbd9d0ce0d07f69bbbd971a0e1bcf7482432d2d73e8b4373ab8d0ddd5b6bb7db4fbb236f5c501da0f610a74ec0755a578dc3b4b7e9b8f916775ccb182464ce0c4677f0405147f6f6392dee9e449b2a90867b2c432fbafb91ddc1de728f7d8f4c33822bbd333dbb95863234234a192876a69cd9cf6787f6f0d9b35bd8c11963a9eb00b59f33c32da00cb00a94c1fe3e273ef8a465445167d04adfceaadd8ebdc32c866db9e7fa3da6c12d200d2d5dcb99e89697724fcb3308af672d2df61d6462da63d95118672d187b767a55a67409d3bea450e100467bc787bc9152db6a4470d8378cc22e7847d2d8df77a54d18267509d73ee137c5ca85bb0df4b5817b0ebf2429adb6d770f7a4b47d862f86bd6e37dc6719c3f6eaebf00986fdda706056ae7bdf110c0a327a1819f0b8889d84f0f214660cbc2e2284d7e19b81004d1f0d7a0afbcaddcd1348bcef600789a1ebdb1870b564c0e3a2658ffc2d01d7751323d22a1eb2eb65df9e47c3c3e249dfdc4df99aaf46f1ab924477f31d6d807c09b88ebeab97db8e773390d8f3103b5d42d3dc75cd9dd08e53cb77f5f4170b6b1fb6093ede0f4a50fb6d3e2a095ee0430146a8b8738b2657bfcd870c45b801d66ff321b180020ab27e9b8f002ca1810e343090900084addfe6e30512c820881794620c8c5481075498fa6d3e60b28052c40ad76ff301b9a0c1138c18224b161676eab7f928428f9d62203c66d7d3ab72a8768a4016f6e380ecd881f820d4f7465a8e9ecbf49229c35b092b5dd8687b8e2cf518655b86dd84b36fdb2bfec1512ffec9d16364fa6b9f206d94658e6618cb742c0f61acd20542ef000ef39841da087bf6b61c726908636dd947290f612cee591ec258d96353cca300dd196df71152d246d8f6ed192e9dc3a61c38d3b33cf4bad06427db88a806d68d187ce0d178dd3d1a6ec460e8c9f01ac37010f61f84584e4a788893120f13ac2cdbd19e137bd8cb030c31858565223630618921a6306189217cc0c22ed46fd3d16384fdb54f07da6888b230981d5e8da4d9fe24cd96834a197b2f89fb636def38d3b9d05d1097f6793c3002086dcffd492e0765a41fbc2b19920fb074cd403c64cb0769699f69e5062debcf8e36447be919d5e68663a7c80f422c209cccad470d5d0faf489aeca5f8520e82495995232ca9ca12b8a4e81d5c12d4c407a1a6c7b4259ccc3ebca3fe79597a82b8b44f0c35300294b6db4d37e5a0b8e53f56a94a6fd94864617fac1e997b7408b57c1054fb3c00063fb4fc43c2424525af8129dd69a0071a2e0259d9310c44646559259fddc83dc5407462cbe3f058d98f294bcb673422308d886ab0b06718cb52bc2537be1811796f06204257c3dc1191f233a8c727521f212857e06350c38c0807a60c6ad822224aeee1fda0a867c68051d03b1153129329865836e6470c65d23d728fdc8b8305e7bdf7600c2e92a1bff7a605b27774010060a10b47965085298260650557ae932118718229529085122a4358b10208193cb4893d934008951015112d69f97824dac0cc34849e27fbfc630539e129d98d437da7e6207a5969f97b1eedf4f4fa4c4af6528658b21c344dc77ecf53fa3ca5cfcee3727a2d0accb55f99e7e5f5a70c935c3fbd25432992e694836ad0cd414ee6bc769efbf9129396976eca904a90139ed34d7721aa77394c862f39881e65ca41252aa567c7f28fa0df8ce5def4960c99481af9535ecd7339c894e5a0a0ecda4bd987132d0761399585c8152492383089a4c12225490ac74a1448c4ad2e150b99d43f16cd377573ca8acd1c953f56cdf749995912711182f146b928cd074953b01042c112466001116a20042414a1829e3ea87271c03092740516229020e292c0d40f690a932952928684e2e592a4ee8aab226924c4468000925578c88e3c6443d914cfce9110c38ec1456a600d91d991c1127305c64a15794314c355aa9cba1786e352a92b3ddbf40cc7f512c6177742fa76a76353a5628a5a11c872c261979881f0cc3ce62f7519333162d0cc30e9f7307bcb3397ec2ecfee12f10f6cf8fc727a07afe01efad7998dc14e6606c2137319e789f118274078548f790c19790e89c9413157a522a616f7fca8745a8ebde5d8df53e960773976975cfa81dbe38643a5833d88ec9e535eb5e9918abca992b4c315293d481af9981c2453392826c3214923ff77af0a7ef7aee4777008e68f058067590c4e1d629e98a772d00b8f390c0e1262c11c6e2a07a41ef31c52f912804b5430fcb1609e2363f010f844333a8247f0c90b8f79c3dc118157a02dd430779b045e380761b010eb6d3d68c30c6fca3df574c35a0e22bb5b3500304cca1852c156248dfc0b180621dd753009c34164775c0fcc3103c9a63189bc79ac2449e0152c712812c5227923e3f2990a07a90e44911a583b324fe1a0d48188390c87c141300722260f89f963bd50430ca298c360a298c390e7559828e62fc8c0aa1cb36f268ac94ee251c3fcb16092bc8951248dfcbd416acf67456a60c5b88cbfbca37aea2f1cfb9337414431f21019188e00440c8ff1577324917a80a5e56314d106b67c94126d9e76793344f527e32fc67156dc5357bde364e49ae7481a79194fbdab317a920626c77c089198c7c843318739cc65644ed2a4f0dd74c8bea7f8a7868e8f0117a98125938190b98c5f190899a71ea36420641e734cf6cd416ac76c249337a0ba5cce416a774249f2261573af0c8e9333f718a53e9fbda386afc768033191c6a177d429bc810dc43c9b180e35dc766202d65a2bf4441347f84194244c60640b4e38010c2b6444822d9618010b1f98c008266c21b3c4576b34272459c1e22a81c5364a5bdb7282176dadb5c285a44643c9b4983084cefab59820a5bb99a3212624e9db8f8b56bf1617443d807e2d2e92747db1898ed10691094f3ade4dc7bd6f46fd7bc7d5563fc0bd56175674f7a4d8faeeb56ed8b0e3864be1e04833ce8c5617ad9e33d7d4cb772b9b5a6bad3932dbb857c0b1916382ece2604d439c7e477289a491ef082e91371287e6ae66f589e58ebb96b4bcac226f706eee706a72b7ba22699e4a71505669d9c9243df070e83962920e7202b34cf268c8c7a2a424db3146180487583940b6ab2a1e0e7540b66beec11173100b828e87b9ab4670190eb164161afe69e1061390bcd56b696d6e30c1046ff5ba7b3d68f989b523b8970520a4000b2790c2fae58d3c8ebc61cd2a4a68716185142aad2dacb4b6c002c605e33df5217888131e7bd387441ce48467c33ecf835d0f8ac77e651eed3207c16b9a1157394ed2d8df84c36319893f718ff9839cf0c01cc267e771027f659ed44d39c8f454de8139a846d2d89f1e934ff630c83ee6a089b14bacbd84b71ce444e58079ec3cf3d8fc95836091a4b1300739e13986c51c048772517ccc4130076d8f790749631f54fa9334f72d352e7fac5725be83432f7f2c8bfa63b1e4861fab5f7090931d540e822ceea7bbe021d910273c59864b866846a7cc65f844d2587bcd491e12e40487f758581e426f3f6fc2f2252d1eb6948045978c543bf53940d6631dc9686770c5c297c988359a8ce8df6644c409bc5024022304e35e1c2c3857e69c096306870a970aaf6a5346814bd96bb7d6da56152b6dadbd5298b2a505157df56b696184ee66ae005b55a8b4aab42e14bcd8b1e363072e742d75b5336ad8b042d7e7dc2fb8ae460d1bb5d656165e74adf78beb45ced6af9585166dead7ca22a9bb552b8b28f1384e2d5b3d30d232c69b2370f1ca04ccc84109afc8b69beccd741c6c1d75d111d200ff2004f22001e4a3010fe44102dc06d202a38160eb088c06821a37a794474143f94ea83bfa17bb6220391503d9a183682d0fe5df1086f7dd1ee8ccbe62ea6ac62aa6a664662aab1c8ad3b697664d5cbd1a0e7523a7bd49ff60cd40e681b0a4a196a747433de7b3425f7b7bd03cf3a623b10c754fca500e1965a87f2496a19679062843fcdb70a00cf14ae0de3b9c777429c9b2ecb5c5afc544ebc80a2d2563b21caa6625086d5763d65aebacd76697b66d5849335d4e869376b168d16eb4a93183d15e361c36df2a5c3c7cf6a2bd68a3b5bde93330da8b36ab1959c4e00521bc16425827a43ca58e02d9acbfb64eb9b79bcf386ede8a357aabbd68f36e70228db420e07ae6b377355a5e9bceac0f8bae592ea2e9ed6db4a99f6db3f9a9836ea03bfb20b28d38a0ed68b988d0d0d1922222231ff0c010ab88918745122a1841155b4c210a162ced46822a20052c6c810b5dc842451596f6202259a8d0420a58d80217b2b07ec826206ac1c004442d18b0b4ff20c4d2f27b34d9b5bff366c15dc75e710f967f8474cf756deb2888a69f0f8bb6cff3f45e89bf6fce09ef03b2196d7ae8253c32d2f1940a303a5ec6dc057594b1cbf113d415cba61dcd3d30e6b8d7e24e888edc55b8edb85db37d8ebc5af6fc3c87b5415de3760394504e1c147129a8342aae52b10994424ac727af9a97ad925835f30e15ad92190242acfad752028a7e2d25a2f42de256107859b050e465c952d07c8704412129a3944b857b0d121d8f684961e4cd26a2e8f937ff66b48b9b13357ff498d4f2b74acbecb7892636c842bf2cbb7cdd74b25f7b4aadb5f6945a4a71cd53c700fa6110a362a8b76b8f508b259ab74cdb6cd0344dfba663b351e9178f9d7e9908c67272bddece07ebebd6e66e67eb71dd29ae5cbff8decf393559ea2050df164b37f760bfbf9e414d628f1bf6bae960bfcf4e9b8e3cfd8629dd28a53477178737c1822488c085143958c2c2369dab6d3aee766fb8781ec6b7e9d034b831607e62b9bb3acbf70281831708dc83f6c2b32f9541a4e9699e9b0d4254cc8cf6f5a01ed244fa6d3db8a1be84ae0bc84f0dad1da8f68fedf76898b4217d2ffe89a1b1bf0ccb7d2fa16ab57c232715572fc0f068c07357b8ab5f2b8aa1ceb344053c420d9ef46b2d81a56ffab598208a3390d2d146b47105d73d291d758836b15b4b54e9d8eff81f366ebc2bd189ec3dc5a4e3ff56af154510f70a4eab6141068515997e2d28a640e1041448ccf46b4101821948a8d1aff58451eb09142ce00a1950b83029adc089234e0c51a1d445105ca6d09488d1af15650819595a4d985a4d4c6919d70777662f150313a314057c09b83db853a21577b66c0086e98f36a6431bb44c973765c944d36356343d67832e5ade546fead96e4df31cee4c2f7d9a7e2fb71ca663f7d1861e5e87e92d267cbd055f3765d3b3aad9adde84e92deee1de73b9fc741376c12db8333d9a1e371cdc73a4e9f698fefa843bd3332e77426dd2d17e5dfbf5ebf7267c5fcadd9334c7aed35f37f7a4b6388b9648520207fd5a787079f07210a069a6109499e27a1f840e29a573ce5af3a387b2523aa794314ab9c99c83003ce2e984973df3315ee2207b50aa74a95febc9143a8b45a48ae8a80451c78c6a376a7a14ae39e06acc469c74a88e31e8185b50ae749c36db7e2d259634cd28d8b234f3ab913fc86436edd1783050a249c7a32c40459197c5031984252ee2460469d2c1d4a0a0b3892a99b0b7c92db9e0d24e803d216a9406712b89301aa545229e0c75dcac9412b05a326500ef9929be806b72d2e07541c3160d8a6680cf5e4b101482d12a91a1de0c40b21c706658218494d2f91e1fe214a26091444f28a4950416fd7210a06ba5744e29639c5b8e997310a079d4bae52040f7c4c7c31c9f5529f3cc90c2f981ba030e66c6978ad1c875892fad6a554bada28df628b59c8a2b793ce5cde566ccc193f8a66469c34fd260bf6e865d0b44e3155a4d92d87ead24ac682581d44a8289c6d24aa2889ac88296ad2482903177f7be80a355be43b53cc4892be9022e25732d42d145aa6dca5a6baf55c275a94e5dc65a6bad1d5a42cb8915fd5a4d9ab401fab59a44d19f49c515a5d7e20bb80a243bae055c771ee20f48036cfa1e804e5faf3461d2f31ad4342d7740f3c2807b58366302ae9be96acc6b79a51d9ebbf2e690896843af6938342d2e207e1e2517203f9f7dbebed54ad7b86d5955ba2a0779d371903765a12e65550ef1a6e3106fba506bb8e35acb7a68ec1b3661f519d0ecabfe566e62793335b2526afecdab6e5326c67c0b6700e6fcd5ea86e355b71932e69ab89237abcf58e10aee109cfcada59bf08d34d16a5b49ceed0f68b6965118a6b1d6473caf272b05924deb172fbb50380a3194134a4129a41b8e6cf18dab253e33fd88136f6e441a592f14dc6decf0f8d0e1c68e6823e96c1843962c59ba86c027fe88ab78e7bbb0eb0fbfbe2aacf4d27734f3375f0f3c3c1a7127aea20d71156fc455cc39467049ae124745449a6873145c079fd83925dabc274cc028308a0a8be838e11168448b3742244d8cb7017765924542f6b0b4bd8ac7bc3dccad95b6974850e9ebb309917d9d53ce9c9ef9d97a6d76e9f4d057e7d67bbaf5b04f7de2ebb097587b34649ea547837ee2ece513bb5ce2895197387b346eb65b8feb9b36717cdd74d8bbfc62979f70cfd55d377dc3aa97bfde52dc5358f5f2edefe52d8f46ea13a770375fbae9d8d6c3be9bbf8f81790c56f1b80ef3eb3059f572158feddcb773f2f53126bef7f72f3887506f47e10efbbd0beeae9ed35f67579bd8de9f70cf3d97b9b8baaf2f619c99b8a2572adbd872d8df2c1357af51af70331415ad115927a4e33bae53dc14dcedeeb7879a2869d8ad3fcc3c4803bd2ae0eee3013e99734e3a218455e013f828a574b68cc2b832e0ba9a7ef30aa594d65aa717afce2f26969a51ecde7b5fceddfbbe55df9a9abf5a6badf53575ce8b8299d65093d39e69da75c46b427d7157a3af761dbb5057a0d8d7c5d21e6532a9ecbd2ae5bd62c4f79348c729a3b440347731e2ee1dcd1cbe37b388117733d28cd24b1fad124729637e94ce78652a21e21271efc432df110666342dcbb2ac5bd1ed4a534a7734bdd174fb21d2d829ee5e17bd6537ae320d0333d8fee26ea6ef3d2ada60a5ec94eb6674dc36ed36a8869fa984539166a6e9e1fca5c5b9851f1cf2f5a702d80ecd103f47eac89021f4827eaf4f8b7ef93d1a517bc2c57ead191c0d2132a7c4387ebaa0cef13edff33e67e7c4f8deeac1c725a2b5164ed933f76815c2254532326fe6d1d61c145738ea917abb1212575a53acdd6e75abcc441b683f6dc5281eba038f742b8e0b8733574b01773fc306a95ba8e48cf5c4991e758a6804000080001314002028140e874422a1603822d696f10314800aa0ae466e4615a85912c41042c6184300214400004000606066d80024132398c883c31950bdf94ce8a706ca672932d2aa80d63f9df2629f587f04e79a563c0a6cd8b1f35f1b6f525fb94155421c6c2989f6ba392c8b41c550801451617286d0b3f73a29c7c4795f52d7803474a1959b744f10548fa9b08c4d153fe02f9fbb423823648398a69d2e7d68d8381561586f3c3166e14f964644c22e3d9704fe5e124693c4afa97de22f81004cef947f0ce01a31abbcbb27a1e971ef76c1a6bac6434f5e1b964a7a79a1bcd61723deaa4bb4666b51300bac1da751cc696c8e66801309c5cdffdac6de0ef181b802822afff89ab8cb0ada58c93c7dd6272718d09668dd4f02041670517327c070c72257199139134e4bb4be71255a99e60f245402a4b11c679d9b02a9f970ffa344697c6825b34b5002d6a75ffeb5871f7594c1e454363ff9d70a6859f0223a20f6448762a25c4479b935edc7cb94443fbf1e7aeb6db43082b980ede54350ce310da94cd54fcba12c890a6c4e5262698e93bc9bbfe91c37e88f175a5a2e927f0f18772008dddd7239fa160c7b9b3e2127de106198e3f8151b83e3a435cb1bc2597b6a03e26d3a2ac6b5673c3b2833f897f44e8f505c7475b570679a071d70b933185ad2a2ecc408b9c8f31061e20622a165e3d0df57df8a7a3b7f21a1b50a48aa36925ef06c7b59c7587c21b095b727a23a7405eb98911788a60a3d4ef782801065e57e1806cc135740b428f022f4ad3325b04026dccd26ca219390c2ce3b64b87620651844bee43c6c947c28517d43738111644b871c8cd9a6062042cee6a1f1665146e8f2db408425b080e1a2a887f8413ad26b003d20339a4c5f057a71b7ea050f3d647ab6e9a3ecd7239296afc961a68c46d76aed9b747fb6041fc241284ade634d9b46dd6849c22a732f040eec10396f19240c0c22ba8251aaa220de4428a0f984649c1242543592f53a807196fd2900c7869be0cf7f6d47b856e2ee514012c58c93a7dd085513f3bd6a3fe308ad671a3ec1cb386e949b9f4929f07d4ef709d71216d2ecad7fa28e207a2c191f1994241ff99338a11e2917e051dedc6e7d515d719998483a8d311e484986f70571460b2b5aa636c83e19892cb59cac0d416aa3f9f6659e1151300e8cd95865ae9124b94f28001d2aefb5059ee78d1d3dde6c3ceb94f689f6e22095ce6e316faa55ff1227d2a26723bd614bbe93e71776ab960e93ee49f121ed254619ba29cbb3d4a6ef822b435507e01a074a781bab9169a2236ea0680f2b148cc6abccb2604aefc1e50f2243315dbc68f510b59ffc6a6faac89d2b544c72268ec14ae337e0c30761cf2bbe231dbf81037902d7dd044c215e25566d778f80840e508755aceb7717157650ae078164a744f89cbe198b4572067ad80adf71a36f395b9493a02b2b19e9a6dbc1bde0e37707f90bfaac856230af17607a62ad193d41bbc1636d838f188e3b96eb0df0f979cf3d2c4a2321a4b1490690c42222eae21aa034367bc27f0d092083c5630f1ec095280532e0aaf5ff310f4588fc0579d87320173b132cca50ebee56953d48b1a9022c5a44c7d150d2224ac34bbcd9149016413f375773b7c79ac77d40371edbd0de553088d9c6366d257cce33061ccb1f571ebfd9dbb9cedaabc440f137abd34d50d03aa2271236a721c0966e269d32d806416624c4740aa194b0a49af5eae4fc14b4096ada91041711214657076d400be01b6d5d3a5791eabc336340ff3d739c9c829f4c30e9c84d7e1293d4b151711dc9e0c89cdb735e7b130c5ce3dd912410cdbb7aa0bd5ace880af8fe6503e0b336eab976733029900539e2da0ee633974db284965f480f2f0f642501fff4bb55e464b80ad9e71f54535cd013b68cc0e8af5fca84256cb670dec00c0d4c21ea23113ed12ea602f062a8b330f5ec20dec0d73929fe9ddf836eeae000ee829429b6a85bb191d2d3ea8733117d6f3fe4ccdd92afd896d36f97163335829ed319a606273997d22c708241d339049c48eb4973e7f7d33d12f3f23ca34d2a721eb89b97fef943490e1419ba54f90b0303bbbdf0c08145f3b0408b33fd31ea101d3c1cff2137f2bb91af1d2beb12f0cbd8e2647af20c74b73c33b5f1c8dbc0f7a5c984ea29e6cd3e656a06f301c6f6f36176ad4f7ab055b5f14c904baa61e5e72430724bf5320d80dc01f1a15e7b7520b0d1c06d28b165f0b9492d462f57d41ad83f04e739291c0471010c787bc57d9503f017824625e837f5aa44d16250ce6a19c1bb4eee8092fa4c9b14f4af9128b6e6dc3ebb167b2f7b23622346a73f4fc8a111f3b390888133dd6b1967d41006b154176f6f6fb75568823e8d3d6340e84d2416d65f53ad2e32a5ba86434f101a263b4dba5d43f7d61fbd1ff56bf3478b4e27043a2294142750914b2982b09247a5fcf18d90d4e8fdb328cb27c7cc7c0d6298d16401dddd57626a2080a0415d64c90c6c9040d24c9f8246ac25f760516aa8e0c01e9547d4b5108a14fb17554cabde961741c01dd84742bc7526c69bae8361d639342485160dd23d41832ab9b4e7b713ba1372b022e3d342da14213341484c123233f9b090017f9afcf830483ef9f00dcf67a9aaf11a74751320d44e0d1fc3e90a522c37aff1a134a141a3ca961073d06cf063580c2e6abe6c8e54650141633002cdb9c7627534b7ce5e490d5949007662a8bd9e28710cf74b29d4be3611cedb4e593a8508120121f32585189c1cfab8daec1e472d80f7b81efefff8bf00e88e36cfb570b386e46b7eb0bfd3e820083a7de5056affb4fcaa082be026b61786140f71e99625713447a6034e750fd0b5d8dcee8b71847696acbac20a44268d34612a177b077b547f02003188a2c7658ef56f8ccd0b2146a13de0a287e4ab2a3328087a0d8b4f47aaf81baf08b3f8b36aa254b4252aae05ce01294b2fd3f602c5349b73cd48051cce53e15ae796a816e8f17c8560812a4054080520e34066dc84596a353ca0770de3ae070245b191ae3097ec212adee19ac3648d2fe00f95d7d6db454d11c404c6a089360151a379f839ed3a5b5434ad78a6812c9aa5903bc07755e11d868d514fc42e15750b148a9ae55127ef3d9374df5c00d902cdfb6bef4acac82308a51923cd19500149c16ea5a2d10f74c79618e313331639cd84ddd4a22d0014bc061360793e9d1a894f37b9e3da6724cfe23fdea8244c429fe5fad8ab11edfb1f410271330d0af46818c9a0257c68e532d72ac09ec19341adfd2602ba39568007b55554f6f119b2aacc405fb36da46591a2395752dc2a26c5f50c3c09c1f6c647335e3fe1405ee2f45f155b41b83809c76c3957b7c62dbde18e72260a54e6128a4d132146c19974262d608980542b97ce099995517ddad9bd7f2812fdc378c4eea942b093f454140a735973413175697206635333480d18116b1124c4b2662bbb9fd5b4b968c6fc2ac7a4509cba3e236b924d624ebb4f1932314feb72e5350dd02bb0b6df1f0b7fb3a2102618fa74371033630fb01e50988dc809bb763dc8eef8925cc1eb2e39aa084765e3bc3a4ee3c5c86c87bb70abc3b61af77b6cc63e79d0674859f48935fb0a3e931cc15cb27940a6aaf5cdf75e06454c07860d6ad4784102b2a5635c566487191ffd55f50c1d4fd3cab89e8d74d1b9fc49f21a55a1598a1876c6e1e3a189215ffa8b477549113ddcabf19e7094b0461fbc6e944e09340c24a82038d8972856c4509bd025b9cab12cba0839db06ba63c3699df3a5388a3a4b61cef22ba16f125f1ceb2775c73d48f379eb855450e2d86b462e430391160b8dd00ca100741e5a48eab8e23e43cfa30c32fb53de0d46b0e7a36f52cc2692d3d5503c9f49c020828273c8740361480c2893af6ee602a1321ef99aadd04687975cad3c2144ab13135847096fcd258f291921850004108dd3952cb3194d306ead6ce7a9be0107be2ab7c04ac0b665551d0ed188e6eae8f8971518bd27a97603fc61daac09b931af9ef86ba854954aa84b63b582dea6c4c0068fb3c37490fed1b4c61feda700335f2a5e4b99af6f10abd92a2f9790521f24c5ab87677188695996eefd47cd88c45a1e75ac7e12b45f51398385160bed9217ab8e1bfd34d7162cfbaa7554b968107e00fc83c73930a90619001f287ab6092775ff7c8516a783c096704ac7dcb0dbd6e36f0c62ea03d7784d956e2a4aa67c5b5138afe04317bb6e41df78c7d6a6c4d0feb4ae895539c43245b260d270b1d79f11dcd2ac2672f8524b2768ced5ee35850c686826c170a837b9cdc69ca013ba42a438a76c835c23223041ae8e3420af9e4573d819b1e2c0e3c24ba80c312090f20fa8544f6481a1976b15d89245a9833ed9820535baae355fb459851348b6287b36df1223e189fcbf84078f06a8318f6695f8b35a05b1d1684b01c59be1e9a1418e9c624de331a23bd77c8a09ab5ca0846f10d884bfcaf184f255dddf0685cb0a5f9214cd36df0310ff92437e9a9861f4521155d7426b536df74442ec304ba6b659df83013ad04a61808195c60e8324b685f7b03060a3d7fd7d94eb537a5d3656cae9615ac99bb6f708e1f6715f393d6c6181bec19ca649d4b0fb4c1dc86bbd6901bbf1781ecf050380662ddce0fd8284f49ea097b0a5947998e95174ddc829d34386a402aeb912486813f8a16e5225c2d702b5570f0b57a5291ccc956c202a2c6c56c24e9d9e6df90fc008333ffface4ddb3a0b1acfe70aaf53abb3fa52c6e297b81573c42a35a6c4767cf5c69e9ed79e45a0200eb1b99841e90f644df93c1492cb4f8c8e9bb7582d245da82f839dfd97be48289d4f7424970ed618b27d48507938ecae9ad0823b1d1e2365b161abe7b416145491a076ef848dadc3f48a52d90fc9a64071ce124a1518e8a76776db41f6e4547ac87d743254663032ff59200c5a44fe9ff843ffc1f2e7b2dc2a6b6efc09a90bc6b88fa924026bbe662d72225b111d082503cd08a1260a5e5bb389df4824943cb032a190658708450743d0e6178f95ba85a9cff7187f6064ab9059b96b9824d4bca2d815bc5b8a400d82b3141438819b84018a99238d3284a1ae40e55c9f9cdff76657433b911c48aeeadd0e5f39fe1bbb5f8f935c4ba3351fcc3139bfbab50b04c6f3613457e57028b6e003729f1d41174df0ec932b13cbb3f617facbd08d18e63901e7371b1ce13d834492c6cf9e1567e83a4ec326aef803eb464bbdd57a024970d1ca697b01769319a6551860e7dacbae5d1995f27fbc435a940d74b003c2292edfc95ee628867f12d942fc7ad3584f17f814ebe7ca781e5d904ae46ba54292b8cf27cf5ec0561234ee603d400302547a6b663de396be45e1d654c76d287ee9d3c12a7c47bb491d18a62acc2489945bc65fcd9bc34653d515fa08ba34ebcae3dfe76680b0f8c69541e3a69ac440961a08426f10f8e0b1b82843f781cac5012e68ffd90b7771b95fcf6fa5d4175fd2473def8523fe3f9602385f5f7aa2b67a501e63e2102f60b550d8bfd560677569d088080f4026b306e2f7ffd2998a0d55195493633632f7e49412bf5fe47041c8039298d9779dcd828999a8863189416897d5f407d73d966543ccd76a09a31f6277e20a5cbfcc50b18ae543f68f846636807aea9226f1b36031ff022beec755d6ca75a7bbf270cdaa9d6553471e30e4f25d55a820b8a61357818fef94c812e9f7b2a2122381c18304098115e45d0aaf1d4eb0cd50f9bf9d3e9706deb2567cac9839dc55abd1a0bdb85b320a274c2dbe99394e5c06bd450e6d72b840c10deebae2ab48b570759dd18a8b587e72bd03ffbe0192d85bb6b69d296033bfa32f3a937d1e4a7374a42b48152749911804763cf221ff390aeea30013a634c39729cdd713ecb82d6c9ef2e5273e530813fd8b285193854e84d55adc3f6ab673340a361ddc474fca4f833fd81769a21db4e92ffa79f6a106b2d02dba0705528c6ccd1d470b68cad5021a3255ea284d8e52bcffa7ad1bdcad6dceec9439988b1ccb8334b71d40a15f561d48ce8d0e38df71d9a9eb954c70e7da1c912c6dd66717f4ecedfae1fb8d70493af7f64c2bd57b32826973d663ab39703e30b7829c796ec12a236b665472632403604045e5d295b59bdd930ce0c55651657cafd0094fed41955e6b3f30c6b6871f165f4bebda8d6835935d3817db9cfdaa5c9247f07242c319f7bc7eb52029b7791f97f14ff2728e74434fef49f428b8861529f0a7eafb2337899b8593f10df0751611a1a7aacc8c6e6065c0abac1849ce7f30763f70e30605aebeb0f9f84f845c141857e445465a1f78b10f868d0554f95b03f25ca823d60152f1b0b3de3ade326ffd2aa6c4c6a7d24723ea6f651e79c82c7a3382feb0ee13e04d1417600a59ac878675ec8f0d833c18e4b0d63b2184504cababd2f080003d49a8a818f625023c7b08c80deb93854715db4b7a26cdd2def77af4c06a2d9e8392ab7a8501e38603fcc2fd9c17520bb190135537ea4bc49767ec731f304250f47a6c8f775a71624d36f1228918e77f497af80972cc65862e01a8e3d71c449cedda82374fcbb675e2a52e38d66e9e0a0afd66572208e99dbe2d159fa3f4de19b45a7ea2c37ff2bcaba265878dab586f7bc377f68f59039b2a64c0dd60991f37ce33b88f73e94b4d7d988e6cdffb5624f05f29bfcba82040cfcb92fcd2f1f89e05f57ef80ab1cb3bdde78110c19426b3c004c52453bc5f3d0147463c19850642560ea3a2a315d70936e006ba5561dc1ea308b1f313918558093928f48532a3267e9c2e74b3375d26f60c7fd75659bd7f3c414406710b9448a90a39b8225f0d74e44ac4d42512a694741fec9a93f87e7ac6c0e5d81a8bef378453cd47955fecd31da7ad3ac288bea380c9f2e7009fa3af0bc7fdf348db9b9184abe3d89f3b86855a43cfa90e7b9c887796f37ca203e418e791294874e56af19712aa22edb76dfc95d100d9cb8beaa2fa25804d62f2c271ecf2ba0e15bfbd4514aa0c368f234008d87750d8e4a9f3882cb53e639e86561b7ba9100cc384713427e675ae8d211fbf29ddef8782e3909091f1523bdb4f6081598b7ab2d0f66ffccd9c8d998275d4b8a6a3198335ce3724dd88c808e876bfb141512a1784916b26128918ffe74834c928e844dd6c3b35d21e15f0dc1e951fbd9c79392b0267052878497e529a336ff5dcf39a80c9a282c1e1524b6136f7c7200c06f612b5a20ee12730bf3e47c9a1e28d15af56931ad2114233d6587a5ec70c1377dc89a0ad334c232b1b0b918acccdd01405ac684beb45aa655b685a8dc237d06448f89ad067136cd77b67ab4e2f6e7e8b0c8a5c12600c259fd2ea231bdab6f62348ff07abc367f95af7ba6fcdd3ed3be00d6ddc4ffdd0ed68d6fe35955890cff8909650248bf6d2f7f10d4087306690c130b60064e3a8fa01727eb65db1fe265009c1f9f0e3fa99923dd6c9f2fb880ad082d27c41e677c54a71373ae15ab0a1494e5b8eb0f419075f0592ade4307985cc3cca3a047aa606b1e41842af55264b13ede73b4dba2afbea12702b80f41c9dc145ca4454037300a52f3ea365ed92e5be894b36bef9941950783a9b367b4919b7bb4f07a6db6a37a49a9f1411261d80f5b1dad5a29b3f07df6fc1f9c19604447b463f96fe0c01634f71e350911e6a4530ca6ce009ec0663cbde31d4b427ffd1cfece17577a93d409499c51c7f1b67aa17ddabc01370380f638724d7b768b118cd5d879ed82608420395fc71465844c4a646fc9ca6c66a72d0fc9ef2e49e3bff2f8b87ce319435cada367394b1c09747a1134c22b391a211a619fc28327580be676131e89cf4fcffa9e44d7bd482e1280e99a52a8c69cf220e469b49da93fe43446170fca09a334c6629303ca81f1356c2bbeb9134de0d8c65007d7890272c6bde244a01638e2341da1bd661473bff8b0b5c704104b90215162646a7c28ce6989c38d8bdf504dc4d7b6b243c155d431c4bb6e5c575dd32271715d5e01db740eb2f37b55a49b26424fab49c0f8fb929686094a79f61789c3e0295211890c86e93a55eb086ef133425f80b513aec6dc1f6c9c191893ba538f16fcbae02b7d46f1a90124b09f96da91d7a4ac2a78e315a5afdff68dac77f50b3f9ded261bb06ed647cdeb4bdf5851b5537169fa66bb24d031713c35b39864a4526074e6c7d6ec9f87fe11f478e5096f745e1055fa3fd4d02f40116dd35da9628c14e3389691685fc01513ed37d0f4af51178f6e62d545b6a194e229b0fdb17a934754d94f8d92e76c21a663b76959e87aa6992024fd81499351569f6c852e5ee045352bb3197d04c24344cdfbe27e23a5c085be4f9b77d1f532b9a974008f0da5677a46e6bcec55898ce7b80e74c1efbfd2050a4c12716bb689bd1bc777f5f3ba440b07dc026374b570a0f8128aaf3fb227e6ce234e68013fb47cb0d5c22d3073863ec2331d96f92fd929bc497c43981b17a97af3d1bb90a971f1718f5ec39c7ee899ae7fcea58b63cad433fe0ae9babec34f125de5cfc5429eca217fb0c96d2c20834f9d6cae1446e2fe0f68b4d812d74aee7a6d705d4f40b2b517e8ff5672e8bf423ae895f1a322b9dd784c084ab9a315238b223b7249de2a9049f6374d203cccd0c1183a5808b51b2bc92d7266e827e9f2b35971fb7327d7e82b88f36e1454a322cb325f85cdbebe25bf72ca9d7b92c559a1b2d01c8bb415b0b815d84ad76b5a16bb98d2efad2eeaaffa667f99e1665dcc111a962a5bc3c61ec20e3a99113f159e97e0650b25bacdccabcc8b702ec732b9f48e2f79a20895f94754831ece7a86d7851a2abb2dced64320c02e10b0f14d569b87af2d3a17440dc296f87612be60a84a76cac02d2e3944240595efe8a792049faf9d5a8ffa5d000ba1b54c21de932ae0b3b358885cdfbd2dcaae02c0334df33e79fe9e6abff8533a72cc76481addcf05a90717327e854bf498e91483c870a1104930c7c4a7b0a2c38bdf74e10fac0e3471abc44ba90e4706a64a31432d7a64508601008b5a2d91b4b74c09ab8aa8e3ed7b46f340c6f324c79b6209cbccc40aecb7c16e53a2e9400436b03afad8f3eb617fb7f2104116a4b5bf9637ddeee9c1a8d50a709f9b00e3a58d4c38a581090d6080c71260a819fa1045542051ab6faa62ee222d89fd68b05bc0b08f15a2ec26ae76719d9741dc167eabb8eaf472e667ee818ec3d802be5992c5a6c428a71460b84dffbe4eed726cd8b85d39a5274ebc053998dad98fc269faaf072390eaf3913b3aebf5552eb26795d6c84eb1efa7c296fed60cdcdfa843c7ec948a6da7486727208353292f37157b96d08b8d9bf48ea35c404491816108acce63d4e3a68472337374744a44ed653e41d7d6593ef0a03be5520d8ddcebc29dd0f86487c7e9d3258a8cabf23401dac4a61fc2c9cc1e1c34994d768a4facdd38e45f6bc387ce7e6cbc4523f42c68780bf23b0ef180d5dba121ee533604091cb77def840e47f5491d50a6b7c2adeaa9b2140f5a53adb2856f270eb1470e7ddebbc884f0c0735458a0e26e58c555917d3b35a36123a16ae41b3386a83a4e49ba80c27baa5a78a6e3e1ae31988fec1eb7934374b763b1e53c6c18e2086a95f9708d91d15d4a5a1b83d1b863a80ace10dde2b53e7b8c94c23bbd8c42b4c3c2c3560129fd56d991731c6225019ca7a00688f549d9ad08a57adfcc2942d029f6a198af4d9656c9ebedb340ab2d3ccb3a55476d787eac4809990e80ad4772cb178cf8be360d23ae025c109eab5b30abd17a0508779c55fd6a40ab7e8486c1c2f6a754792f537ad708ec708d1ebb908caf9b9218277e225a787ac476980e50a99251b59a0b4dce5e16b44176984c73e4c245080601603bb0d056091d649e29200b245cfb166c20766243a4fbe777911bba9a9a4737479014dc5fb003fc96b32961ca405f68e205ba97fe0818868a40090c903dfa429e647f118742d6d12fd089784b3e6e84abb8d5e75bf9de74586ac5ed92c4b6d53141915aa46df7eba1809f8baeb64baa916b8f48014c6ca7955e9c908c808927d32f91f13342ba5a469bdb1c799cf14a5345864b5a52707b7f06ce1d912cbab734b5ac1a3ce8f0fe54fdaf1c26fdf12b6e0dd85480de4fac4e55a58a696a3398d18aa31c87ac2eebc5133a7bc2514a130ed1c466ee718b0996e27d041838544a1a229c7299a422a5cc23a8a29e4256d4683fe01a47306e5d0ccf9e103d389584908958867117a956af4aeec589ebc8406fd0821bcb8d722e1ca0d734a438eff0b05599940d4e94a299dd39c521bf1e1d99a6ee41dcb293e3bf40cafbe08dfd07e145231d1b03461b76d3f157e28ab2f08f5fb38f21ce173c978776c436585ef4f6f071ea2900743ec91f2f482d2a0ffa258da1c3540e59fdab53681ae18321cdc0dcab87d2d8b80611d251c3b662a43879fcda4e13f25856386326367de6bf313ab5b4111fa6191166692138a579108dc7cf2bc37054dc8ff41d40b694d45fd2ba886eb017c107c2a20f1ac2cc609eb8e774432ee09ba209f6d909ca3da4598a9909f43f133c248d801cb4147470a7c74421f4a40c678aab771fbbf3b6d4475f16706f98e1b2545f41007e482f0930a14b6eeb6724de35532ca1114876c81b4c5e3dc4eac47dafe2a257c5f83651eed3ca038ab363d8191826a7e07c6a74cc54e00e2d99c99a865949f79acf7d03fff309e07aafe12c0e9d7714349c8f625a6d29e15dac4181b71811cf5d8aa9ad7669967e99fac8f3d2efc7d9a2d727864b6b2f5e5a139405e09d18e7b6982620d6db0de0b710f14e987305e4478c32fb6653ee1959ccc4ac585a054dd5608ac261e50cb051542667ab4b5576a6a5a66d957cba07e7137dfdba290ed86a9f826ecb8dbae5a0361a7bfb7dde4cf22454f6d3c1e3d5bf1703eeb2122ff180c5330915b252a8cd129c8825003fdd00aa5448ed5b1a126427f82d645940aedce6c84544bb21c6891cf9c8ab5ebf8d32c207801c872ac25b51f4fd81ab6fba9a04cc9120370cf67a8eb708ee7d82860c977025ff300b503002f9d2a32a25f154464585741b8dd594b350ea4123b9936a1b089911e02aeba38e00346d2468ee495909e03e8ccc10e4faefd70793561aa51d6ca3a7910b441f77811df148555c71b2422c451e12a207794f623112af4092d74dca27412ed9454fa357af5a0a1c9eda58235dd295af9296973ffe13fae2d087b91ff4bfa1bb6414898e56113456ed0fca7754a3529eeceec7e76949afcbc440d8b1f1582cbb6fa24601b871adcfdf678b7a46d0199f6f5f3328f5a337d4ed78496504b5046a9b503a284b6bd9bd5737ec3e5ffb3e29524d2664e8cc919e336561c0aa358b3be7ccfe98562f28674b6ca02740525730357aacd3562a7c61390b6785e15b4301cef1ada47cdaa6474da633b30a79e59b92e4c95885fc89c455df61b9fbcb4e0e79be6242e3c18c6ab0bfe28efa8ab269a6000e4725591561953b73c952d895388ef2cd3d6aedf52d47e714375a814b1c8709fef3541ddbee33230a36fa5d341be70520e66e0e22c2e018ed0dc01addae70a4bbf2b186c0b4d4720063de304aa7a1c615e30b9c21def94bafae1abb477e3f91e45cfef9ff22f9906591cc210578d61df5be2aa31b1aebc7b92e3640b3a3a272c2c407390254320bc9e81cbb9e24d566abf73f1853c377ed310951325199ca95dc8ad5b95b495ca301af36f98d6998195250c0b668d45a46813817d818b02fd5263ca83f081d14a4fe4df656405d1b181572706ec726ed34b2f5ef499427d4de91c388ea66a41fa53155a0e39881cced14679828601825c04722064913630cf2e27fab4f3d827123f542aaa04f514aeabdb9f68c04474c3a781e18b0b898dd2b57c643f55494f7eac279f657c2d44caa89cb55c5e61f987ab0b64b8667542c4d11a84a34fbd81aaa6ac85db7b9fc73c9f8cd88768d68392783646071d5a04c471b2a48064fa5ee0a8f14aa0728ab423df88328eb070cac034e7a529e683082b89a6cbc36515cadb97b8480ff0f4c4e67e25fcfea841176f5911e2bc282f6b17fb6dbe7101b2b34dcc7bfa3fd6bdd8eb368531d7cd74fbb3d539e234fc7786f40a32537efe5c8c54b1fee58177897dfe3813767764d2ae40114d03c5da8bad743fc4c6153b1d95b883dc3a5d2b212db15e64cf2e41e779e61277bb62b4a1132708d3d9eb3823bad9149c03721ad9b42e405403f456a14e6b3d75f89facdfa68571ae057497a1243d98938fc2068f1b993f2aaea882504f673564e63af88f9211bda915bbb459d67bb797be080e86eb3ea97aa4d3f38bbf74d7779d2181e456f93f7743107631d09de8ecb154804d777703c9d2f2af82b2834856f8357530d02c2bb927324bcb82bfbd8d34d819e3a13453ed0e363c45ebf7a5bf6d105b1153e781e0f9119505b30466b41bfbede4fa4c1c0df014ee7c5af7e7b07c5174dcd6983d9cbdbd848f431883e28d186f96c5d9673cac4e9cfb492bce0b1b04a0e3b5739d8cd4e8cd4a07c45eade122a62e48896b165734891258735ae2b355932938a940252c3efb8b3c72e58ab40d9d065556487404ea593ad1fdf609026d6838a7d0b3275ead246597cd02d3cb981f4dc759ebf154a5ff235c591044973f7c47767ecca733b8a3da1828b7bd0a950d548ff0bfcd49628cc422eb54baa7cd438d1ed9b416ee6f2fccb6108b29668c1ae1e743599a82609180e4aaba0394bad553d6407a26931b208e9ac7058342e363019bbbdb7a2e498adf88fcafb05c7ef2d8ed09b1ce17883cdedd5462f0d4f192db74f506337463f3a5819b0512e5671414e731a7fec56900160e9222441760a7eef373e00d90e546b34c94f4d5e837173437d3b163a727d17d344c304ee7ba88024904e5f3ae7e2b184928b50c5daddf13ce8ebe6155adcaac74f844763bf15ada6bc5378e36f117f9e92e29990513ed215937b19ddda3e7f2b67d8c7e741193caffc8a072f23c21d4feddea5a5a02492321fbf84de8fd2702c938dae4c3014ef7a514ab6e00cb879fe5cafb76639e512fe80bfc1120c3cfa762e0730a150fdda057a61d39102b2ae580d5f2a40898dc7fd01da8b416bfb054162ab248496a2ea2c77d2ad63f81c38939f7d09d7a1465467e0f15ab956ed0e2ea11cd0fffbe0261b618f7166b76d8c213e35e06e26b53b05dcda687b72ea1090420ec7e1a3437568c3bd41d8bcce9aeb851810b9985d161bf49c99c8321d66dcee3b9e29df735012de2f204858a634b3627139b9499d4199315897ac396659145a632dcbabb7a96adcbcb3c6a6173e8db21b17d4627a6c989afcb74e8564cf9cb0b5a3f1a66c5fe7dfbc508800120090b281d9e2411165080c4fcb32470e68bd63e5cc2f0ffd0d0179343c8d603af1503340590ac930516878cb2420be37c00e2e119338e72081ad239f64d878150cea5437e91591f1fe0b24f7628cac66757ae10ff6b20ef4c1a8eadf3ca06fe767c9e701c996828d9b4715249d98fcc7531f0a1d3885ad7c09e7de5a318b5f7e1edc417e14bfe27827f0b054ce09c1ba9d0d39ee22f6a273a0abee078a6b9ad5192099946af129b1dd484d59722a9c83341401198ab839a390b3e851e6ea01384dcb0f75e029a5816dceccabeb2d2ca8ba4e1cf272d02bee3b0cf7ab5f4fa5fe6b554016bee01aa68083e883e21ed8c45e2af6fd268ea3f5ebe15d1ce816a4905807d94c8cdd7f747f89b6c1ee46fabab32f38d5e03200249e76a75e763b8023a5caacc72b919e1bec147e8d567d6991714863a2470c323b811dc246487a46fc085dc01526ce8949c6d6ffbbd3c6864b21e4cfde2012e28bde8dc55fed540a54887d625f7ce247e21fc279fd34587573a0e278c1443b0e5352110fa2d1f118a45cda88be3183b27fc93565a0e0f2b683f4384aa61a034458b424f23a65a04f11e7c651c864458ef5885411eb59a0e4059010bbc52da451abb458e1c44f0d5813ce5500bd91602a8fcde355246b432acd73c927cb596c7dce73d8a6b9f3fb9eb4fccd806eb8f877310419c9cdff6358101c5d782afba906e77c9a0f3fc8c4bba01f8da385e07e2cd6f31b083632c12ca51a1c8918c71796b3060d99c0ab8f520d94fa9b98a2581d3a44504f6622179d113d3be2807e2570e9502c8326ebb848023f4df7adabab2f68374b5f10692cc48b5f2e2eae04051df751a0aa3645345220f6b19344d97e60b2de4c4a825488324446ec0e22abedcf19b91cc05eeecb24205856fe9d6e041b3e7e4df0aa61805a87d8e4874bbde77558f0a5b0ab869c16a31dfabaf36a2c8a664011ec89ad04053a177d822f991c9c119beab294d7ba984ac0829d03d8d6c9f38c7459d1d51292ddbc3ceec758e02b87783daa8105d65ca8f2b331ec5ae0df043bd6c0677ea08da510b6d5a1cb70a8234bb83a315c7ae41e280b213830b5d383293ab93cb86be165342e9d58f07714e8214faa951ba2702e5dd735e241216ab706cade05cb68519f99c6ebcfbca274af9e3b14153a2c427a7a449d39129513ae65110a9b90c00223beaac12fe548b059085b8b8454ab4e8216f24a405858f55814023c0514709e848cccd559e5c94c91b44afc2be7d05a4b22a2bc2878b8377f46f75fbc0af9f66e1cb018acf85aa80c6d0edde480665639643a1799ef4481c23ad4b8ff38e13280018ece9983e4e23e4783467032e21df156124a130557d3ea4877bf973c8663af40df06d179b48902353726034bf9a4966e51f55078ab775dcf901765bba7429cbba4ac9f4782329d446ba2e02cd038f462ec353d7914f373b9e0cd2039037729fcc59cdf5edd0a304074b09b7b2fc57130e091ec89ad4bee8c18ddba2ec16aa10564e1bc082be380d8d4c817c2e667093eeb4e4bf4701aa0b9a4a5ffb26124c273720c30c91c05e9fbc4053020bba54a5d221d345834538cd7cdd91597ef24b5898167d599983213be2ec53ea6536eef0301069d1682e7108037fdff469182752cb9ce8200cc4fa25a461d50f83300092c265dd4e9864a77fd58ba49633c902f3906a4c6bb354955d4ca363b8f97d79bd416466ec683a0e9589c5f27d1b2e1d9a0d7db67073dbc821374514b0b60d3c114740c650a07cb2d5a9ef8b67cd0059d1a2741f52645414dd0552d7bf05ff027878e334794bc1ba4d15d86bed4a0c6ac0fc4cccbf9308e6560daaeac914b8fe34f5004112737db5b67025f11fcd4a8b16b6e0bc6345d91427f1f36c7606f94d0ca26e4e0f0cdc775817e80190d327a0a902fd3b68d07ec59884001d467e48d4836c089a8f3094a28ff09a6a6e044f2b76fba5f8bf1d21147fea5b1d41b20ff046a2b689512ff04fa218c6c41bb0e2fbbf3e025de297fa524207e141d0a8eb2c11990460428f63a7328e86e090ca87fcbe2346507065aa805251da97636c08e28e5d5ff0dfda24f549e186bfbc24e4c1938d4c94b02833a81edbd214e72a8e995bfff195f8c5b9f1722df60875bfc1032ed5955a42b448c97c4bb1b338c7e8f42e3585f1cb107543063718d672e0760e1217bf26c002e84d8d8093ecd1a8274c35de1e1fbb8a990db00c70b55949fa8ed5372114804d826606deb2016810debb782457b49639d69156744ea7cf92ab67f39af0d0b67d400a55473a5bcf80e7dc9897ab302f857770496154fe572f20df407dabecdc25903bba241b1de18ca7485e653658f2586062b5a72ec92e0e760a19632cb31037fce782b2c132eb5fac2b91eccf55a9934b01bb5ea93c68213e5dbb41a2b53a6e667457e21efa58e9cb5d379bc29b1ff5e9105bd13a2f1585124e0595fb83986496ec34729a04af94e430ca4890514068234d522d97ae252a0bb43469575314f3838f54623fb6d2b772241e1fc741597f2758cea50add295a39be4aa34d4efa0a38b6a9b9a998285a327121896fad7b6e238a0aada0347dd7f6a098312656091c2fb1f59072b2a7ddcc4a14a80d82376a4c47e4799f67cd0b0802444818d55cc3346015a1188c0d6ed0be54630ccc5478e2e06429884f624e0a4f734203b5b49a1c2212a6498fb1e1f25abfa0cb430b7863631a3f3f1134de7044ae44bd1b9c9a7edbb903885bc2ec468dc00b7a2cf832c785d910dc340b71d1edafc46012a6c88e8c84af2f273d7a5f16669fd082b89ff65b37e1671bbe355a013f0bb7458a84bc62ac97a68e8cc792fa501f198229b86d3cbaea8b6fb365024a4c7c411baba8456311c030dfcff28934e57ecad2820d759787fea87a05503ea818000c97bd7e9eff563ded23adfc35bd7a0beb27e83887d57d31f41a4cc63c67a6ce1e43e6a6a0e82d1f7ac26917475bc91c1c333562b1fecea27a608a3ea761ff2362a0fb5e29ebf090fa0c453d3a76e71b14cf1d5faa58c7724665a3e9268bf025b309cab1a985df0f7b210e37beb02d0214dbc860577a2858f5d000ad75f4eb995d12b636105e85b40d3ec60c72ff8a162de42991c6dcf37f8572f5b8227e8564f0b3514f3d2240706042472ab295a4101ac3c79bfe643da89c9e39403e4a2a2352d36d5bcc9105d7f2ce5676bddae9820eb49bd864e412dc7f26e313bd27655465f2156e2ea11c3bf8ad82284aeb4cae26adca408002178b79879e37bb7a42bdbc2c8d4eac9ba642afeae1b57b1702bfab98ec9c959731b95d14316fcc897d20b1a18c4c2822bc4264e00290038601bfb1bf71491077215768a4d9d6860baf6c30c02ca3e8f2e677fc3f13bad61fd1d48727140dc7bcdf5fdf6816d5874cd1ba5a008728c619ba12fa5aa5f2d1ea1ee619c1e46e33854f42d6b2b15fded4a49ed004440016de8b7fd617fd12559b391a5f2d4af27715bbd6c87de5e55c9631be259d0f4695b9827128abf8d31d069691b887500e8255fc055c66054ff86b836dd3059869dbf45434e07d240e6ab034eec37c85ca926614a7ecb577e60af586ee22c0ddf32e5d6a8c1e752e9ee6620653a42bda4870c434405a3ddfe504f076528bcf9cd1b7447ff847b89a40d717686aa24943ee547a0c64fa90116c3af38840f7567a64986e323295016dd44b09dda9784b7dcd541d7c370064d81056efb41cd85453672c4c22afbd818a03a4be7a3222f381c49bffc0b793488a1edc81b43ab43d385bf65a9363d3a2c5b936042cc31398b711f8799e7db8db44b8677fd3c7d8bdf0321a0a19ee132f377736a0107380da032d9407413d982869c4701cd9b05e1707e4f8120b67bfd2dd5e285e864d436ce5334a0b6afeeee2609018f19fe36a0bf600667a437f0bcc9f6df8f124ac394cb6248f8c398b0e72358df6946bd503140474ccbbe23027bb4c9d666b59760e4d4cd02f6e93dcfe36b2d7baff106eb26dce9ef13477d54c8b42db36cc73551f395868904cb6e551232aa1188840fc905813b1c7aefee7333f963ffa2df3d1d658fbad58d91b840c8f2b5005b90177c20515a0d6db93e2ca6c6deeba96b3f1ad4fb1e708890f89f4bc45613788b124b0031ee4c1931880f92af14be08ae86432b72b10ddaad32f30754cd95d97b7de5b254be18a276f8cde9ecc6e98576742a4e89cb0e47a3a50368b541419d8924e41142e953b5e2aeed6afd499addabfb1460eda4aab89d2d1a33388e629a280c97f4a2213128b32862bfaf3b04b2b48a5b57a0997f5b1beb778bf0a116f7322ff256ff10f0db8038edd29ae84b790ce4e0ec28382d322c19414b3e6364c3f369280b9434a4cf23e34a8a3b428e792706d29cb13d58940cc65912c6f5cc423473a999907c721d2575f9a4164d1b241eb10d4ce0d7266fd18a186b86d30991e159468f8905a0bbed9ead78a796786f101641c24ede93b44057d456d94080bc6fcd0d1179dea03c4b604ae4e9bd3f60e7badf6f3f6637dfe1ec51b6d5bfc10f90e9bf04f220a80a45ef2d56f16eb31d79df495373c6bf99bc5d4777c3b5a9d6df5876b60ed366f70db525c01711f69c2a84736c2a8a790533b4b0bae2c95ca172f28937184e16ed545a5e121183c91515cb984a31c80cf8b21076e545203c934c755c77cc8813ad688ea368d9e385b5d4f0effa3f03ce0d15615a5445166dc61406bf679bbd73bfbde03fc6b8dcc032e1a61880fc59ffe039839b603c748812c50b533264fd6401e92dd0a86d370ddea0b44ec1ef736ca869617fbc4d3939b7daccabbe0e4372a9f3cceb70d7bb000de74851c3a93e7f3da06f1e75008deded2b010b067e2751deab5ae31f1cf160f4315d6073cb000850f8daf481cc726115baf3871c739846e8c27480cde323292f2bafd4412937d58aca8a4a4a25eea7434de4a2cfca1c24f8908fb07b9156b610d9c700dc6df4e572a86811eab4c14edcfccbc125aa42aa468eaf6b32313ab0e5d721fbf528396be2ac8daa6cd59fc24c895ae9e70ac251c6f6c779c433dd112d1ea326affb137995c0898ab255c77c6630bd50c0c01e563d76e7923ba873be2964e2f385694f5a657bd3b6542a1e675589e2f3d9764aae533a712e58e1fdfd8fefa97406ebc748471614345f5be225384debed4d72dae3cc94805f5277fa2e87f7608b917c94a4c6e4092c4d1897656d928476ddd44aafd5345da3cff8846355cd17cf587b43186bff12d44aaede9c4e720fb754e8440532e53ccd919458331d35127323c3020de22b2bdfae13ae44c9caf5e0de979b7f682d63269a30f6860ee529b946d941e20af8075e4c627ba42dc76be452d98a95123efb66eb2a32bbd1142e98d206d73c2dc7d407f0b6f11d84bc8fe74da4130dff8a2423dac195f14daa248b8796d4fde123c24c6f23b4bf4ad20586494014dadfe44e4249a65658f80e3e6d6e0e2e069a353644bfcfc5043618583d7a7b554d16c133ed41b4b484283dd1f241fde6d735f815cc56f297407762d9873729a1971478367965e155db1026e771576a61f86e6d2cded878591b47ba1cf85cb48a85ac904aaac73f017adbed62df98161a0d7c2f569d08e9cbb2d3d51ff6450acd877e717488502f15ec5f3d1c1cad6144ea29265706218ceb980e501c845edbd5ea19497b89d8060b555cc647339be949d240d4d26445e209634c5b6ee4b78c790f72e60f35e50675c3fc4fbe1b9b80481bde448536657a6b40f151a85b2a12676afb2306bf1ced3f6d90827e9a1cad382fc2b0c7c55afb25361a9bb3cd7d918460b5f13475db3e7c60689b1620ead25c4300634a1d5fbcedfe6660c4a5f1c114035a973b420a84b620af886c6bb85415071b03e7337711b9a031daad8266fd8479145f1d6e273d0bba4739b60909ec99fea9ad42e922a8ea4c501dda060b23eaa23afe44c26e46ca6d0ab8fd459245c9d0dc612e87c71f8c13222fd0cb968ecc863e44720a745879a94ff063563ff69d693ebadb1afd52de97c89540fa53b0a2e8f8585231f2847dc6d161ee03bad1a2ad9f86b03774ae256fa94bf2c7f095a0c37ce40c2706ebdbe8d849fc2b01d1ffae18099a9f1f4b0ec8c66a97877c20ef2895305bba4ca4eaf3754f21d72113fccb7b2469e9ab70b6c475a4c15db32f4975b92a3c753b624405359f9ada4050a72bd2222643e830032c2f522e9652a87b86f4a5b637049d2b616b915e05f102628a1cba6da5d81d1c7336fb23c20a7ed205fd3a1edfd4d579d1097be03fbeac8489208b06626b65b9ba63ab12b84a3d91a962c859168c994e3d59c8929673862ac662b9c1b02fc6b0c4bb7693c96f9c64c166f9a4151c67615a3801c22c3e7658e9723e15fc4caf1eb82d32756cd7396eee8e9dc6b0b5c67e1ffc03d074e93ce08ac5f8fcb71d2987bba4c19f92958a17a5d0bd805b735004d9892f6ad3467c8e45ce62e88d157f691733670ac927f9b35a9c8cb4f28c75bc416de9812b642bcfcbc5e4fbc99b10c04cbf524431554bcc9794cf789842007421a7fd38510a4b966dfa453e0a51b91d256ffa35e1975bc44363c189a6cd7836e39e405e37f8e593c987311c20ac0817b8cfbe88b101df9de4f9ab2b56e3ca4b3cb484c2b219db3badd2a99363418719f7ad8709f7eeff91912ddb1b0030ee11ca20f9657e8c8a62f3c9901cb2f33b01546451f2a137c7ed1a115ec708ad0194071adb8c94a9110e49e1b230ebd5eb9568cebd14326998bfa25bd2b0cec31f269dbf64bb885b838684f7d22c31da6369370d1891337de1050a99f2fd57be39c31b54ad95ae56b2d1ac8341dd8229abf3374691e73b61d3f0055e469d2fe4436657f05408260589c9ea02db2e5cd69b32fd82521ece16140aba32333ef48f091b2b0386d892b571c1991fba20e8053014b8bdd44d9cc48af800b50c9454d02d09b3b304d50d7383314250f41e06c1d91246d65d9e3e57d00db1bd5849a4f2eb576146902ba14b07b279535dd8ef4d14eb1900ed3de95975e1447566cd9b58ef3d079743c8fb356bf6f6571c630219f6b8558bd3e11c925f1819a1f33df1dede05b30511421373c39b66cab1a09d2d864a5fc53a4aae346a315f1c5acd6ed289dbfab029c96ace62704c2ad9b879fc171e4d9b5c8f3fe0e61047e26a19c48b92f918e41a53a50256ec551d0c4ba746ffc4f9c57e2e59a9f52dcb3de5af6498f85200cb9ebfd4b94d647b7e6bb25729e5d82915f9bb9f0753140e7e9b2bc4b11cbded1896c819e8322b6c65ddd444aaa14ea06bcb247319663a3e189c391e74ff6f52189d228128eff9b5890bbcde0d2bf1c542658d34237c2a483e45903e66c0fe08ca70319455ff671d353028a18945049a7f9b0263bddff2dc097ae236303594f3540945f5ce0b469c7c48fb4d29e28614d82833928af4c562904ef13a58c1cd8d95b00818f4c15eaa1329dbd7f240451b311b82b5c0a351019efe8f7c49024401ce272360f38a4979fdc0fa7fa07fc5c31b7f3d0b4cadf82d536df0810541b7850f3148d3670b109a78b14ae0b305698947c6294fe7418ad2f920e63ca6ba63010e8a10570b89fbf097c00debe9dec1d06f37bcc35a4987045b2295053e7337cae3fca0949e2e814031c7b61b8bd510599d03a1942bac721c137378172d2ae87d360605e3119bef294c8173f089d0fa6009a5a44daf09efa3d2240c652534662b6bd4f6e32b5156f670ee7e0bbd08f87f91af4606f22d2918a732009e7c53483737ab713df924fc20403776488635cffed51536ca535f06fe7e385964a6888f98aada938d3c2f0cbd60f071259e6da58a14e51244bb3eee01867af3f2d37a88a48400f621ac2e57b807cce4253d211f11590a53d83633e320d40ec01c360d313a3a2ca3873b98093fe05b3f50218c6da19eaa1926bb8bb424c0c406291f0bd5a93fb0e70073e6a6efdfab1106f969d565e518d779512fcc05c345b5b2e9ade38a5c7df2ed9c50c222015dddc0b68ece703c7e7b374c4e0d5767fe12b597613be4c76512a1408f9a2da38e289f69526e7cfff6b7634df175d380c498603059358061a72077fd1cbcb8778c54715283cb2ded1231b8f973dea8c1649e1a05e211a55aa03195342862ab1375c547a95813490a0288f6c60c4e97b254965219e1efd1b8b2cbb60e6c24c621085b5447147f52602d4074eb25be4062a6a6254c3ba0f26f9af436cf6128f6ab56cb704bff1b26354513d60ab31844088c969798c139c9612545fc1b58a10669c10bc38f0fa6702de3e332ac2f8b296d15966589e91dc2a4bcaaa24d61adccf04da16d82050c8669c9311387ebb43da2558f8eeda590f60f82c757d88a26c095fb97b6729a453caa5c7d1a6e583d6cfaaa83699c518bd638423b0ce8039bbc4000984cd35324724f67c98a73087b07513d3c0f7b45199a0458289161517ddfaadb2f0460e9e475787b2356e20b250cc9693c3cfd736220dcb7a45b12cd5768369c8f08dfdb8b359f93b484c377f0720e1ef1370712a3ab8b02a1864b1a99b23fd991fae1527643b21671a6e0e022489ae2069084b90309af9f500806f29af0e983c6236864186edc005702bd45c589ada9c47c97151a6619b77cb231766db850f1eb32d992720d2864b26f933b3ed0b66119a9c759bbbf149e771c387ba039f1b0050f99b2e825d3fdc49d6d316be8f22527bc5baf517eca52c0a106d533892e1287e7cc2f9fbc036f032e05fe0331871c67a5975982e41f21eadea1050093d476a19c0f740a344903eaf561452fc0c9809b2d311b62c500b1d94bf1affaa118c37a5b60c0df1e7b188a85e17a60c635f6c63561dbea57eaf2ffdcd39ca2f5a9b452a1f36bc88db25b0dbf04b345bf3ba7f44107e2bd9eb75791856d6736ac4e9478ceee8e4711a588227e527c14d1e3db4d7a5afd804454b1ba27ac9cd9f9b7cf6e9f2a5564bc1342fe399a9e7865d31060b76edaa54bb76874c31f5295ffc658d3d00d332931af28957daafabec565ace8062cb9d064e8cb8755724f6588189134788349e7f88f502a5179eb2b2adcbb6c86c17eedeca67f15df801b43ae475e0f9cd80c9e8d3e3bd2c7ad3c4f29e196a8a4dc5c313820662bcc29d45bf2893fedca288cbcc3209e24780a47f2aa38cbc05c7dc7e0a52e07f96e8fa6498eb4123a94ce506aaeaff98d3516052c0da704ddc3a18b81dcaa07871e0631094229adb3509eaeb3374c0e1ee659cb6dcaf53a1677c61b31587c491f1515eb5f95a0ddaa22d5d50a956d7afca2614d2d4a9f164f677ea266f0673398393fe71d8e7f276a840de47a87c87b800d1c7ad0abb6dd1464cf61e2cb98400459d0b2cdf15a0d75621eed2d5d31b4226ce0132b7e63853829f09023653ff70d5000d8d20e0a1646b4389fdd1a97f84357c1767f516e44aeda64ddf1b20859711e6d22638e6f4b80b96328bd3a4798d1d773e924cf7ab1517dec0301b0a1f31b69b27020790f650434f26233f5d4e8f1e588bcac09761bc0e7e67063796c9c8de9cca8a605404f1d9e6f0aae00fc72cac1e1337fc6b11ac4fba0d34e00ae1ff5e57bbebfeccec88eacd3041321487bd28d366e3c757c24d747591eacbf570d6d9fc8a522d820e4b7fec63593d1cf4f4fd2eae8799880d160c553802b6eff3e11811f13280d839077dc20139e1ba2c87908f3e5218fc441c6d3d4afe17229f7bf5c4cc96d521e2f7d7659726a1d4aaaaace06697e930f15bba285e1462ef1d1e5ac72f9c3d06dbf6673a9c252a699825992e4a98d6c223e22b0c4281556c44d5c4d94b847e5b68a5d235007891bd9dc16afda97d03999c4e69bad1f602f8a893323f661060659b2b92acde797ec579f932500fcb90f6ec9d03af50ab9e330e718201a60ca174be795e4e11793d9ffc66023a3f464046041629ca7f204ab60f881496bc0e07a6ef17f44199bb06d7a5901d2a8a5d97139794694bf4159bb9712630a1ae32bf64a995f3901aba0caa9ba822abb9eefd04654c1ac05a98d89911dbee44a7df2c903bf720eb7c237d251926d2462931488cdf255ae74819fea9c4c9a5db9057e7ef7cb552483e251c1ca7566d052e990e7501560af69b2e64c0a67f93fda0c33bf41c8377c669d580f8df11873dbd96b73e4941feb115fc8ffa399fd2974a80b16dc7c7efc9c1f9404c5df19f6cbad024ea7b5c27999a18250aa620336a8d6287673ec639c6593da56df02585f01953e4c250684b7f7eb22f4bc0197059d662ea0a2f446ccd4bd4cb7115024d019adf25db7215690c84b91de3b2de55e8b81e5f640f524bd46ac2d7620ce369e08f40f03b103a1a78f048252968835dd9688211d9df85d69bdb8480ffcadfc584fc9929a75cad66e1a45b45a9e4f103e54a53136b52ce8143e293d315b30e0ec88a482c1aa0f5d91ca1f8ca1adaf88ce7c1ade7e78bec50594d85018ef9b29fa5b43cda06c518b241bef7662f0bf0d688213f1a0002acc15b90f6bf244252787000d100f5bcfe9cfbfb0ca04fe0e2b28282ecc35a5263ea47826988a9bd0c7840c77cc0094eb9cdb42f54adceaa52cae5e71068437c1d823d08b7c334115a8662b19210df4d6236b8a76edce508528581e3e459226a8345b810f5a6767feb94ba3425b7fef2f9849f10a29d38112ed0a7f7319cf344295e2d15ad6d0bc5df6f5cbbd9a15efd6a2d2cdf1c0914268c0696276950a845a68dbbaa0ad073ecf18bc82a513bbb41f75f85da2333a31234c6fdc238e0e2333026bfde4f878d0e2a959c8ad1a41adfba34505f9f8180006312c9c76c2f3145cb6a2edb105f576b4d00a8e680e60974204913398b16ff623072a8d74680e506c4c2ce0823a1cf0983073a6a1d79b5aa828b5d46941c6da3becd12b526e05ea03b257694b29370f9c4242c3eba58c2bea350bd096d36ed1bd18814fe8f9d708730f5a95a1b4534c848942b0d5afe6b0e4c3b4e240ab3820535426d9cc91fa768c2072cef6c2e3974876049e5652404a01b1a30d1b6ea10c1b3565676423a35e556e6ff67c48973a8dce64ea2f2b0a85c1a5764d5a133cbef4829499a31eca986c23f747976ae4885d68321a1a3efeb3cf837ca75b80362d44c2c24b35e3027233dfcedc7886454f878c263bbadb9a6b2d14a509726de03d9d5e2697ea29baa90eba97e1338057277c1a47fc9967783e50b9919457701d983f5d975d7e9e96625af4b363b0a105f98a46c7c4d1462e96c512b6eba705b534a2be0072c5d4b79838bc1d00462321f73393a69e9229ad579b0ebd94e684dd1cd17285a22589bac464279606939f7163ff84f23d89872501de8e384c756a870ea921257283441a9d66d73aea27d40b36c175999aa7b89109799e34d37b00343075191c07e2bd0666a4f048aa147176cef496bc217b49e6418e7873d625db27b5024019e62d2814a9b938b38fbec75ac90f9eeb594e114886ef54db031ac8dfbd139a44be78c833edf67f49945641a7c5688b3f7fbb3ccb2d85defd264ff4ff17ea174d4542daf1ba18c8a2662bc24584b6c2318d652c6add87d6838581abad6849d76e161c491484746c1b2af16555e84f043329329ba0ccaca0b9e6318c0e6ecb7f2f1021570a0af49797be983b3e3939d15d612d1f37643be01e2e37a680b69d2f5cef2fa318d206a073ea5490152db827edfb0c728a9ebdb347ba44c5840f4ad2e373b38013fc53030fc7a1070af8ac893f75c50f4030c42842ae213c27d105355b728aca1541e7a1c4e71de0d773b0e5e577fceb291a9c5fdd13a648b323a7720ba895615b43039aa26a6513ad95060f4d115a55ed11a16669c9fc3321008f022cb2214eb7aabcf0bfdd4f8ab67767fa2cae7c8ad368437280187fd37a148d912fe7a4cfcf835a155e430bd5c1d05514617f1ee864dcda9a7ffc47458b04114c125219db72998c0675a001a0e7801b082a90439a38b28252500aa5009add04c98ec9723a858323922bd4f7f02e640fb59086a4b585f90095a46a5fbfd690ac1e09926d14df4d8a35e07c945a7e559ee97de1012d9013d9e94c743ca5cc1fc0036cac060e6f0955a573d8303803d6b952187c899183d23bd44afc00b92b3364c589d81d13d3a28441ce211d4ebeecc5a43b7c1666df2ee0cde45eee28e190eae9c42103d995eecf7238a4e20ca760099fc690ced8838d7c1ff59c3ef8e2cb5eb6c2c90950d5051b5f74bdf1ac58ae0fe9ec34310099221c9ebc793e31e47bd9bc6386ae60bb05351478c1a8ec157fcbdd3f3c81dfcc2270f977b18173a41933e95c34d82883aad2988b34a714aba1d7b68ffc06bc4ef7e0b6f4945d60d912df7627481a75fa874210accdad02613d9bb66e42a12901484a650a638442f3b21de652237c435afe5ac25ecb0d0cf8c155ffed204618e280bbb83602da1abb7c709c7a7bf2a0efe72c5934f1af54cae1f127fd9584ae7eb1c004462469912a9d2ded4aeebf4f8752721e2dafb70f27b6ec0d93f2c9535651f4ceb9a2784199ba86b7237fc076169d9a1bc8ca371087dca46c41f54aa14f2981617350ea4c70a43332683b77a5a3da63b73b5c04fd0c3ae8edd19bd50e42fdefc61ff6eea3f1917774924785af02e88bf11ef566e1c7121722752dbe482e9c5e7e6a872d3acf65dffd6817fe6bc80f858c981425fb2c9b42429cff48cf9521d2e6241a4ca479dd8fdcc32b2c09158b842b1a26a701c0012a00d876fdd1bfa137be9927a907283e912ff7376406568d22bd929d1627393c0c825a40210e0589a560e9eab6c10e980a95d441eccd6c8201a4d90a0a1ceccb5705f16e295e2a20ec0d04eca2edbd549ddb5f711ee1de786796459f7de8eedf01a8c999c4979dd0f97a94e6693b0f9f1130d0716282a384a6beca988f32221479802e0550c75e91fe730290f909f2c6056df2d95976ccfe592e5e3ec5ed34c73013f835b36b4c07bc39390fb2e52f3fc47c9ba14b717130710b7ad9d5bfd91d0120225b9fb5db37129e16f09097c4ff77a95a8f52accce80f5b57bb09502c8cf1c1663abde4eb168c923d076295d75236741e86f4cabc6eb2bcb0a91718f800365ffca290b41834cbff960d8fd81a2855880bdc201297cec2a75faa18257a6db3b82987b58f1296203d78e19c89cbf8d5d487247ff2154274b131dbb060511837553a245c7ca7e94418c5edfaf6c45ace0f9597218a4ec516ff9a04b5859e09babd84f837b635f4784a796f89318c40adf3833b7328ec4bccc354d9d55506c4e8081c87a98f10ea492bff299961d04a6d42761849601f48407c07c1ca4ea6c4fe8804564e2cc2da04745288728e4ba1a839c169ff2ebe787280e0e967c909bc8c03ec9f0903459ad21169210e60afdcafb436a9bb5f7c7eb1746afd9ca4187111754135d51d398e438109a97191bda76a880818c68b801adba4ee9d45b7c0d16cc2bbbef10348c902edcd5159438a3790d68dbc2a4214108b6d0b04672eaa4e045e4165e60b12887a8bea0ba2f21a4d08f3beea31ee02e01714163fba8386cef3be99feca2dc3655240dcb09796e5da7eed7e4cd1055977c115e9d21dfd95040b89f753e0b85be2dbdd5e1de3c0339fc58474c6baca5f265c5ca92cf9ceac076e32610223280778817f0bc681a2ec903fd17e4146b329c50134412f8f49f54ddaeaee7a598cd08f9450dfac81deb463715a8abbe2297a446bc77dce0b0fb1039f79efc0ddc8acbe2807aa8bd524650f7f9d5cd0c6707ea5edb3ab6e5c3fc103c87172c1e5e16bef0643e73af523ecf12cc70ebcb76c63749c8cace408b74620f5c9c6d1d6807369a89e1cda6ebd8186fc6e0029c28a59d086373e00678dfc456b0c410bb9bff42ae1c6dfab45f691f19395001c47bfee1f3c4a96211ca1b11617ef9d0d3dbe0e773ba412cc42aa21248037406ebc6492d824f99390c36b43bf561d23f0b6bf808ac48c0e0fe93f281c382c180d38f091c98352e26378ec5cd1a82b1762d17a50ee2b15f201ea2abeee659c3cb3fc58d51c177a3adc9d4b438edc2e9e5e9c998b192295a6ca5c1065fb4767ba8d66bb95b5be762eec4673ac0e0ec265e09a57032e4034b15b43a26be53acc429b64e8f42b55fafb88b6424c9ae7aced63e4a7d058903e07f406537a22cc0a951ca90f658756b5e5fc6a972409c6c108808b090487718c19da37c6ff60fe854bebfc0945ba1825c06e8a2c0cf9ad7cd8a3620d26c22e88233d35e0725d2adc228506e29e71f4f3582e1c6e1ec03ab1011c8b77b1575cbe4960d0dc08b7c590c73d3538b25dc0587ab723c7e216208541357d387c058f3e354cf6305ee97a8e6d215caa90ba49fbcb8c836d41d28b404663fabef506708bafb6e3090147a205ce2170814bbeaf0340c2528e2b90c0a91fa505aedf22831b1bd279ef04ba48fa2eb4a8868ebf6c74ed374ea5f31a17b61765d193c2cecc79ddb13971600e5298446d1d633641114db0366fa1842f9af55d26fa8bc1c0c77f23d02ab7095312326b660eae8a433a622da2199948d9e1073e61c558ba5f01eee817e1dae4486f4bf917a1b83ba65db77566e8733a2d32afefed93c71f7715b5484a2ff315f93babce640cfb10b343cb19e1cad5f97b37401d11fb204df467eb76dc04246080e241609d72a08e05f1bb21e89676155bcb432735fc14414522893ce28f9b9197cb938c71d1fe52e0eb8ea45bcea1bd3c27845d3a9eac1709684483859227969c1c839ee918e0bb3f915586a3ac14354b408ab4688491f79b59be2fb96268e719e27bb60700cb76b8bdbd46b28a4ce75b2ac7f5c3b8c1f9f489a791873bd0207c3fa7abdb55dedca43831ae7e99e1dc12d2aafe51e51cd3e98f504bc960bbb075d7831777ee20120f89965cc630a0d80f0b59dcf410dc4ad8f2d0b26d0f83b080d04d049ef18001ef7892742915151b11774a22d809652ba051c119b63a996dce93d0402f02a30c0670b40fe760404cd96c4a7b4cbd710f05cb429280269ce6910c3a6d05802b7819291584e8dba94e4237255991d29e37dfb26d811a54aba3dc2fe22adf1d0b7d8c017600684a29b612209283f48b904eee4df4b4576df521b267b0d6dba3c918d20212a83da454569bbafca8819f8320a60f1a63e6dee47982380a2da0600d85e0436e37dc4187c76d3d1e4cf6231f5284fec560333da6cfc02895954e085d43798cd51850d479d09414ae4f4d43c43c7a221b82e71faebcb9c9759c5945285e6e14f7ba43f06a136edaa15efaef059e0c91c36c6542ece8af3837e7197fec4b8403fa61175cf48fcb8a82f9edc0fb15eed71177afda0cad4383708b38f42bf7f390f93161f6814e52d98abf2a3c2ca5552c8915a8b05b46ff1d04ecd5c9bf264c9b4a37ff2f6c84fedd443da6c7c7eb92c2264ae7d8391fe4fa5bf2013fbd961d196ab495c7ee144901b01635c6360de04db600f7d28dcba2ca01ec3e5384e31c24d3681d4fb284b1c1aa97f10b6f68792f134d7c4850960000e031610462fbfb709a70aae77024a5c608318d4c753078d2d81465be9d01dd2cdacff8ac48200f3fe1de830550045f1310d362a3bca4da51b6b13affc2cd425e9c064ed6e6dd6d314383d0198b76cf8c4e8a412d1ec180c3b719a246ba9a383a31027f2bba2663c02b93731b446208e14351339b225243a3770e0adf8082739699bc43210ec5662c7043421bc8c484518a2005f020b50885a9e1fe33ed783ed74fcc486957535ef099e6531089118419f83041244ad877f8617bb7134ac76f6c1e6cc1feb68183b816853fed027902de71c430264a9e22659fb0d764321d08e27b0c964fe047415890752c1b3534f49955d899ee39ebccb67aaa3a8af5512c727a20e73e943bbf086740ff298072e8464ae57693cd8a216a2b2621bd835b6cfa4f2839c80873e5e951a3c2a4f4fe4fa6bcae62b5b4dc734efd0cff06f481bcb8e595061092d08f255987658173898fede807681f84a2ac8d607dde53e1ea4bfd5e337d7efe1c45a030e51e17a3d73e5b2104284887b56db065e51fe6715ceb424cc861c24ee50ae16091216a1002bf10923f64779e771650ec0c5d77022cedc2f062fd516220716dd296b9ba76e67d5b85449ef42a5cf5ba20ee8b135bd99af69854385341676b1d89d55dc2e5c74cba1187ebe25e52017b1eaa45dacb596ae8c72277b164804b7dc86a85b10fd323cde97c9a8912e69d4602770ee69290724f7b645a5a5c29451a458aa653a8f609bed9995ae4fe69232bc21e9c2a543a7ecefe3815cdb2793edd39343fda8505bc39fbff5742aceb492bfcbf52dfb4ff2bbf927ca50b38efa5af882b7bba76c83c9997d3b19353c373fefafcf7ab5cf4721a6869605fca576dcdb29ab4c76a05c2521960f58b3c44313e109969a44596e757a8c2995874dbaf3f22f72e3c0cd871fea973dfd4f990e8012f44c5c3b0234fc8a84d32496124673426e2b5ed98795b43b577b9b6510e8b5b9b8d93dd641226241c6d82600e01d7d8fe01fc64e9a3334b608488bbf8c2a4a7239e35127f3dda5a9792574a669ffa73a706b5292b2f0c27a17336b0044677328549a74b33aadee672cee3fcb45ae84f2ada1610f3d7329c985afb03c170e0b17a68f1d07c582f05dae2393e9030eb349f0061b29753a039c9077a1c54c20f0f0fbb6560c7bcc82012d789206ba62645cd4855ef6294ad7fe5e18469f2228df149a00a5e60cb7836d32256143884af05f7168ea61121d9fa858c8fa1aac9037ce8e365bcc0029b20f9b42f6ad90bf666e8d11ba99aa83c7ecc2a5c4f0ddd3369eacf2c0550236c1ba170d7e422245514f19a8b1ebf8682fc1e62209bdb27efe6994f6a18ff27990ed420408b0f483d5b1270ab7b641ed662de19eef79befc3ed86f9f872733ebcdc9c0f2ebe316ff1ecf20271080593264476141d53b526e22a2a594c291be3d937d4513247d92ba646623fb28c7932d7f2a52b82abb16cb3002657d617bb035cac8905b454a98cef9390e6639d8645fa6b595463b642b9642e1bdee69746736fb740eeb16378d9db464d462ba1345aff928954c1ef04b7578e5cbef2da90570fd4dfab9ce076b007311bf37fc367fc86ce17494254c1c1c6279c38b86d5ce3ca516923d3dd99d8c2f638b16ca324862fe08dcc44ae3e5de22e11e8aa69e57754c022e28f012f0b5e2d8f1137dac298ad551d0f1dd0b2ba2aa84e611a3240726450fb8232a15a6c91637bca17274d471a1da645b7e5334b38f00e99d83d710988bc4948b6d4638109f1525469791c5524a124b3fa4cf0ba648926ebe4b177f8e6aa5c8a852f5e69f6dbc4f2499f53957d2cb6a23d4f30a36a752111c7545c41a9cf3f6e6f94a0e5337c00f0c0269aa1993d6a6831e26a905678f4229de74a43e3bc6015ba63f845308f6422b9f8f26838140b342183e40e87d17f875cab1f5b1731802edcd2e7a3b26b27ceb11a1239a767880f0b486e455b83a59bc5928cdf42d87589c90f63b160bb7460f330cce2af6e00aa2362b03f26de868318adb405a942df57086973e6620b48ca294e7ce712f98c3f4402f9b7305dda0c1928fba91261574d7cb6f7bb502e3f62bf6b55bb8a7f13e4a8576ab88fa36b87c59fa8e29730bff89f4f563f5d5a444f13f48a28fe1b36983804b02ed14acc9f2b9931ded1299bb47320e8c1d64cd9f15909fd98a5ea7ebbfa38dfe845ad0117cbbc8c2c932ed07f5c416facb2f4cb38f893e58a3f0de4dc0be4ab446be4033d1697a89beb5be983b8d6fb7a7b51c3139d0c2763d5c29a340479b1a9236a3f4b6c526ccc6521d78a6fa07d4b42c8c42ed1b4d58b9c5c84a6badedaeb65282e9506afa24e7d01652dd7d73cfc35b5189c7eafe98b55bfc97cb1224fe830513201a6e562804f609fca4deee154426e50405a86aaa2f00d7c2dcb76993434a4b54265400adc0da9669a85c98206e869248e87cc25931c6deeeda994c9effbfb9c45903bcbc5f75e3a86a45a4c7f425e9d4af374a85e36f3b61231c0d420bf2d04c6a428497bd2912f21e8164ba1ae8dcf58464c4d049392ac7f989ca134b4c8ca3b7555aa9c242220e18422c4db78cf60302ee88cd4a0dd57beee5c0638330808f28926f262af387fc2b088eaa70996b5d941bf80bb44b45ce4b567cd3f81680d7a8f6414e8db07e6133a4bbfdd464b19c3ed84015a63564dd90295d683def6bdc61f49123842e4823d2556644e4e09bfc5b97e9465748324098246482932b27a523dcf3957799df5d71a058bd708d8aae435ea1e45a82b8f80b694a95a41a3f47e62da48acf5208a10b92d7cf9ead0a34265fc4b013c7fee5f6ec70c7ba4bb94ae7dfd8cd07e06c411f81c0ab49728b7bee34d233fcba7a33e7602884997f1167843d45c79ee8ee780e9747b37a2a775f8ccb3e47e1661fc0ac75a404a3aca4eff6bc872986b63f817950dc9a96ce4fe8e34097a2427b4bcbaf7e80f13b11b4f3ae4e88b6e275f6c078f9e90274235bde105f2e91ce16e609e803aae0e8e42482ee1eab244c1c4a1c179773e935b3d712e1c88abd7cdfa5e1bfc7a44856754632fa8085ce91d9e3571ed7a9068fd1b7a0f218d5c602a15605ef918f6d0404fcab28161a51ca5d505899b3669f4ad2a4a2079da3148ebab6c5ad0ba5289dac1b3a0dd1d70ab9db8bf2d69daef3d0cead8b4058eb4d1d1c803f7ee71456de60b07113a27783c36440ab21e0b5b94cbae909ba12259e3638cfdc0644fca1ca0de0bd3f7ab8845a2ece89782e9901b407429fe79fe0615c79373c5fd7ade7c631f110b031fc5c9332fc6af0fee2b7bb56890f4159959463987ce52878b3970a32453430f7bc894affee31dacaad9d7a78cc07dfa5c07709e951812cc75ac6869ce5c4704b6b6aa5964c53c247b315993ed35ed66406dec7eb31db250cbe776e52fb38558925d5b195b9b3cb33930b7f3018a40917203763db6f7ad63aaa2109a21d3b791b4b899684fa1404860d531a886dfa72391e76c40724367319e59f05cbf4a6d78d4b195cc9e1d4274d3c6bd123b98cac064c5817db589368de54c4d7fc07bbbe63b64821a1700f3380b647d2615e771e16fe0014a27864ae02dbc2314380684f12b8731fb5b54ff481946c2d9a924614200910f90b8483cb34b00fe06df70f3fe9f2b92cfc0589248c02ad8f51f8011337b4abfaab246fc91cc358e82c32a1fba965438a45d91e5f7a5f047d5978805d873e171d1c841b34218ec8b06020b929ebbbec1f61bdd2da779484df01fb26b553536dd05ebcab1100d0857885cd3363f4755f910dd2dc192cb489ebc902a85431b55c9b8f18870c706586c077f41d67a5fc30cf19e432ae9cc1ab07211c2f9889e883a860311d2fe701511368772816a8f0d350c610e1400c4f1c4c5786aec72304c810786e81ce0e1de0cadd97e8b3f54538c57827d11b2af32834cb69b894f6cd9429cfb5002a264f7c11a6c48e80df02373b294b1219b1a9827314a9159f0bc8ab85862e89097d1891b214f58267ef01b6c8f35c0d10738c159230be0a78b7c90d8e6b05c645b631cd29781fe7068dfbd00134b3254b18797d4c2c4e9051857d9fb918abbc8398b6710f477b7816cf59be770c233a47c072107e27310358a82eb0c1b0fd1b428e510fbe37a9906b5cec154ebc07a40c07a12f8ab62a5e96241cb4c1f88ff2ea8d37ae1da956f25e7505f8d03778aee2e097e4d7de40247265966414fa6501f0f50c69a027e4c82507aa3450a9df1b2d250def1d0ee9b91e1304cde10633078f414f3e64ac41bd16a48aa61e920daabc2c839126e5a03e5c169cde08ab582a76321bd2f5ca6b74c7ec7ccbfbe2cc9f630bd8ccaeb31648804fd3898a49d1ed07c4870b31127aedab9c375026f2914f9471ccbf0f88f7e4f7c45c0651a8cb0480bd9cabc82d8b9590d1719c36070ae4747c3cbc57f1865677f61c2bc900580ecfdf6ce15002c59af8fd319035d8b44a007ef40720ec25d458c0ef75d1f8dead9515e0759f15716b5781b1b3ca9eecae5fe4442d9abf6d038f564044c84ea9b47968c01fa05836ae525630648c0986ed1d50f2120d46d8fabd683aefaeba65a68b791b6aea7bbc397a4cce34c95f1cc7bbdedcd498ebbcda17a30867c87683b36e712ce0ec7826bce66e28e4a3fcb30d0710e9470e614fae2be19f6ec17c0316e5fa8a28cf995edff4fb64baec9d9f4e9ac3cd570ba187718ef4102dac37ff11414b8bac19a84fb50ca43e52e040c71ec67a82b089f097417451b7de57efd746622e4cb63284cdf39510ad2d888cbc8d5599ae6e8a1d7a1d25c6b1a29c64d7bd9e9f465546279845b4a72aa9641b121d1a271a0855241e50d4badb7ddedd11a7e114b765592c3c740b9b549d852a4eb512ccded1dd65b1a62f6d8f00e0443bed2ef7355c26e91f55dca89d0b09227511c9c43c67663d905bf086c356c930584724318673256d0444295879c84d89f28ec24bee85342746c1e6ed21c60e24656497f531334558516a3cbc0eec8cb7b147c112fc240da2a60808444c7e3d96cde202f2842e48f2a7c5507950db503d92a44e449c4a21fa0196ffbbb99df1990f0821125396f58bc957fa7e2100efe8ed5a088fdfd973d60dd186093d7d4ebe3e64049faf238a8d331134dc5c34ae5757556305c39fab5f979282b04c1499f3bf2325ea2da6c74d8ab18337b32ca464ac7a46f732e723a73f17765e81ad318ff4b3b4934f5c0318200843e4e2290d62dadd8fba5cb7c7cc139e6b806ce3fb0d15048db9781f8431ac2006b0c43942321d2bf9195e021b76587551683bded0baab9966e1e3a23293a8cbaf00c77f666fbbbb414ef234e711259f1db83f0f5970750bbb66b33ae505c1f95bfe1e69f3a38712e61a0e0f879649a0b52c88bb8ee3f537ebf31b058bd161437e57c94eb5c089fd96d5a89a0e69922f891eaceea6edab8e7c1009f945446f6284849019e411b94a8f2f6c325a448407c58d69c69c02b39d156ce67cad5f478bb0f747eea6179989d552ae972c32fd7b7fe133d0d788fc044931f5b2029f2409e9407631244388b885b4fe81f97098b37c14f5e4e1db0299314efd2cc58ade28a8e280aaa8094611360df81914217c8357f03a8cafb9e90d427b138210e73d6bd0f248d3f23e4d6185e13096082159bba9a935c17b4585f9ef5b125dff8a57e353ba83204dedaeff55d2dfa7702d68349032bfb9f1f7cc8e36b3cb486c4efde6e6286ea686bd1fba0fa0dc747b1bf0e1c992d7048effb557e0157b28af8ba920f462e25767d984474d5a2b62f5376363d40fec8329c442dba87fe21868999677ad6af85c002d8a9ff78c6a064d425514e5f62032e8f223c9897a6a7f0aa9bd115d8c5002012359f25f831baab4eca06748e5cc1241ce99c6d6b233d9a2b278dacb5a041bb5e379e47392da44fb1e2b45e4b930d968abeac38783b39bf2bb27a422888ebb778d1dcec9912c71f9701692722baf4a611ca24e069c2ab30e7ad1026b515ba3c7df8905044da273c07a661e949e6db95f21ba355050009d2adc6d5761f18d806566f49f4de5558c85204f6d2622f7340b79bc155f1eb407b05cb95efaeb3ea028e3aae015a9e067e941fa80cf135cdc28ce3a544be6782c21dc134f15b1623231eb7876a70f52e71c03120c67555410e2b2867ed09e7a5d4e4476ab76255fa79618eab6f112b9be95c5c9b39ee38f6413eede1b7e5ae3cd8ecd1598697510526551c76345e637a08dea75a7f5c001cd802adf3ac57f4ec012218184581319a7e85cdafd602555c339a6dc639f1454c9cba8f3425e70d6264cd31282010599c0a20aa2e37f4d16ba02c209dcc58727f6a74bf7d493ddd5a0349c1808b52daa39c9f5e65a04d8543bbb3c85dcea17982e741aee1bd9a7bae7c111e490ac37a8ff2b9221aebf7a4acc87120897d69faaac2e9333bb13fe7a436475cd0a41170d52dbbfb83fcd5c9857039b8d4605b372c59ffb01f8b95f3a1fa85bffe1a8b460bce6cf4a2b1e74feafc5d21e1baf61f0f1880f4edcb08b198f43f756950469cdff627db6c9147158a4d89a270d9788bc79debcb70a963bbc22cb4c32146a2126d34f48952e26a7c4646edeb11737a3d2cc1493ae6e83089c79b41ee35a8cf9e5cf485827d18473fbc566cf73c050690f05bf25439726a86b73c9bcb481bb8d9fef0ff78cefb1ff6a0b55dedba125c0ffaac43d9301ce07810015058fe46946a203e0506983f299fe7561769ce5eec80afe624fde66ec2928427a3b508936de1addae73b3e2232aa6d3eccc5b65d75eb3e2b391b4b720c2699c59e7200dcff3642a92d2bb737204ac7941defd91cf56702494a4e0bb41d4445b554a96764836b79016462011eea2253139702ee70714482616a6ee14c8bb5f58e21d225095d968a39256606cd66b860060ef471b496bc56ef997b85288ffaed7c61900b9d8d220fc3377434fa9920d2a855526e2afa92eb85fdf78892eb976d145decbc59b011987264a51273041cda9d9023b22745ccd34a600179b222e22d5e9fcd3f7e4940b20f56e7bc4a15658db069ecc6cc09ff4316b56e01280384ffc260f661849cd15bc2e43240e26f63dc8a61ae186a950cd0b5191b2ab1c10b36f93145c022c5fc3c8b0aa51dd6e2911837bcd4554159e3c83c9b8fdd60a9da70987a9bf3388e6a531d51821bcd66f5df8e5a331c80772002d64a2eff042f82481e25c91a48bf1d6c0f6207a25410f844a9e12f36d625e9ac3e015d609e74e5e9036ef41a66b2d4b5da49602c58ca359600c8b75b49c92915500df61b5bea557afc4019c11a6308133533c7e77d0e7db7ede19ff38dd50223ee977b69d001a641116c8050902fa558809169acb1608a4fada9949db8fb6c5ec09aa183157c2658e30a49d6ff670a50d378ca01acf5c2d9470f8ebdd6d3e8ba0c7309b98776ff9561ae28c9948e77ec6e90bb92b9216acd22e38f1755663d88bdbf3e653258656b7cc4b79c1355d3f5ade82ca2938bac8627d81329c91b7e05e72e8dfea43b57aaee4882bec1e62b8a5b56cbc65a283ddd5b09e67aeadf1e584ec6fe6f420d845a4fba72d7e2215551ac84b3849f03967cc1bd14b7aab55f2b82958457f3491b17cb0e68b4ecedc2fb7a1765d540551d13ad91c57adb267777cefdd1af3e8f29cfe94459372384fb3380d3b9910fbdfea4b771ee8e6060f500a20997b904cd68827868a29e33ff4bd84dc6318bb8fa0ab844070e577bc9af81694f0ccb7b44b3e40d0ff6df5bcb53e038debbb79bb920e1e2f7d4cf6cfad1793c9ea2ccfaded8ce80da13f99b8e2883028a840df08595442dfb3e3c0ec9f1021638b00c0cb2487e6ef3c18b51fe1ab28a0aa400b0add28c8744f5a34cda947bb1ae26309aab08947b9185894155aba9a9388858d38114df15fd66f48114f04134316e60a27c3c908ea3fa60cd386212f41ce1b1809808b00627dfe9490e9f168a62ad44dd9ad1518dd866ecfc89d3be0a0222f6a669dcf36d63c0439d752032ca13672d773cd7f41106125580a8ede918eb21a1dd15ee878a33f79980ceab4006e00d0b42e141a0104c118016a7de90ac10df954ff40a60cc65e211314bd11bd1d788f09184007a2f979e24d674762bbe2affa53a4c1d8c6a4c1578c4b2402bf0a422e2d45c9219b93c67b752c5a6f4821fbc5efcc13e2c1c7171406704f62ae547ab3940988fc69839d8dbbb59a939d89b146b1878705005bb685902412bc7630f6d88db7579aa2bed7629bd6c39c9efd74e1bfdc5c0f8016f3abf982d67afb72104bc280ef5cbdd16407908042ca3e5aecf531a012cf032242081c543f493c2e888477079dd3fa3e105c4b9d765183f410d471b92afc70e64cc850b6432793051b40a513827e6a010a1f4ef56000e6b43f43aa660616c904053a04efcc062e1f6f55fd1c38509c238dd1514206478227d077f01ecb46a004aadfd79d8bef133ee8b5c713f262fa546316bd981cd69de2b75dfd3b754ce3130d58b7566950600e0185d339ff0243d5c82bd393ca096b30bd451f544a3ce98087ab61feb0fe99fb4dd9274ec59ebc92de760c9250533c97ca0764bc0e1fd47fd13d8e8ae6541945a3059bfc3216f73b553bf4632df5d38426d2ee21a6fed78f7c518281f6804d7d9d78a44e06ddebec1a27b9875ce5e5c694eafd4d92553a00522d01f3d014cdff52599d049c53e021434020a091e7256208a526e0e99fc332019a40ffecc08eed5212f9f5caf0e864802f6b367adc680d45530afa95ff00f7213244dd4fedea29735fcf1bc80be431c6ee06359fdef1f6de5abd0c9bd625bd98e2ae7e98aa3979696966c29530407cc07bd06378932390fc308cfa343ae830c706da0c815004766882949727572624491c34990859a1c0374e068c88db8207c8d106e1526f7e44d07ee927b04cb1c1c554e4d6e0144b8c91100f7c25d2898c8391b28aa1c02705bdc277f628b9e1c6e157e759988e363e4ee1730bccd85e267dcf0592207430e090dfae426c06d20a744aee84c89a3e0f670c4009c4f550438772786b8c34709104e94e440e78e91075698a2e42a8b1773e05c59dd3e37cbfdc10b2a36e863e68ed4132839578cbe39fafb961d2cf4571a7ded13304f3ec8f1e2c20f570c1cd709f10152725ca8d143a60731e4e499e175d0d4d064ea861ae6b401dd0a1e46d6f78d3e862cff5efce20c11c291b2a385866b267e9fab05a43d0fa8bb3326d7441f3d390fc78599a9dc1a19b84b850348727b9c0a3a570acee9ecb96cd0c029ebe04a3add8bba9c81e4ef7ef3845de7799ee7795fd7b966ed77aff0eb5ae90002ce91ee007f0cbdf2bf153ed275c116100e454d732b1d7a2d1d82ae7189fcfdece5fdadba735cf7cdf7a674104b065fd4dd97b6b04b9e7979b44cb9ca73e55145751e656647d46b87a765249367de1426ba7b0f0bce83abf0ab7b3c07bf70dd5567e53d7991f7f7032f08766ca2cc8c99755330951046835f6b1c47f7a2103633a6d381ad74e974e0249d8d295da2b4ec98f27af2dd774f38c715ce31e2ba247a1493c3ef92e82ec46fbe63827360176e835fdd77df3dc139461766835f18d74de9a61cd1dd7756380708d58126e8e8ee4b1df2ccada67455d21d9a29fcf1bbbf91bbd7c08bcaef3a2ce3c30f47a1f0658862f8a0d0c8846705e748dd4a33616f4a159c63fcee4bec43f40074d17c14c23f8ec93284bcd4adf48f6b5c228f3ff384f882738c2e2d3c785d700ed075e7dcaa4b75d75c366d1c479e6b75af2e95be9865855f7930c61813691e9dd5bd5a4335e7cd5826cfee1b2c63b6ea0fc7ba33de10f1d24a5f7fb75d3c25c66bf40dbb230fbd68f6ca1dc6186949b9a365f32290c729a38142441cc79d3d51670393203800488b478ff1c367099df8953fb86c581f0a8163904e93e3b34a21da0e4dd246978ce8856dccf8b1891c868fc2117e5d0a601b178810080e88f2bee83c2f0c3f9a0cbfbc2ff4c047e108bfbcffbceeb1d841750f8a1d49de1b86611886cf0313899e8ef2c3ff11f23ef46c7836bc0ecc23eeae943e34bb6c527ff38561188661e86fc671fcef297822873f732bd2351bc7ff5efcee78b19df2de7bef05efbdf7de7befbde0fd527636fcfa64f8f5b9bbcb684740fca9d0f89823fcfa5000d286da7b2c24d44cf8af788558dfed80c0b995169dc8b38bd314e056f88e6543be382832f922cb863cceb2169fb4504ed0cafe0e02604882562b82a35214813428dd451a3ea248a9aaa2af1e89c8adbb46df5b25c5835439c1f8de7befbd33c0291964a24a86051a7f34f2775ecec0fed1a8f1fdbda3af9eebafaec35440717f78bafb1990aef1d5f85cebd55d96fb6e1890bf3a5a8cbe1b5779d6c2d75fad1ae07a83700ecf95e57690e48deee37fe10b3466b158f88583f00b8f5af27f42ebd59e97e53e0fdc81ddbd3f45bb149d367a36433b9d3c3ac8eda3af0b82ec3cca07f213972ec8eda3854a1ad9bd32e7272eb8557a8dfb598eb260d78c9c817b759432b27be50844fe1983c82c0fae2e3399dd0b4721f2989fb8742fbe9920fad3f97229c5fcc445c41be0cf71abe070e785d05d3a25c806e708435628f4e38543c0c0a7bbff8b2fb8ae11bc1e897f44087f58e0f5ce0d8b855f9d963c63b132502b08cc2c949f979fb8b80ceff3fefbbe4f1473c6ae2ed7005da2ce7a268e54b2a7c50aba74308de7fd0afab62610c76f46a7af2b040f1e3f16018760019766f21e7718cb70c731fbf1d1b9b20b0a1649dd913e7b3d2349b7d1bdd7b9d22e55c7083dbba1bb876997aa5346fbcf0758938ea3cbf8355ac9b31bddf7254e7b42ebd518bbb280cf035f2157220b29fa03b54bd5d1a241d735a2f4e06acfdd3f71b911740f82f9f3be10ba07bdef5d871ffec0230ef96228a50f7d1e166a3508e4799e9783d04c1c73c076becefb843c31d86cd1a3841b2f3818c5f0c506234a7628c2c6a81be349b9f85bf8ff058d7fe845b403b75ed42e4587c916a30c5ed7e1cfd6fd904e8328a8581e8f7089729cd2bdd875497861765c1c90762939793c1da4e65c49cd4962e7053051543d79228b37461e114e30f9a14e982aa2e618794b68ef5b30d091417b0330f2c6296f344bbb949c35188c58817bc5e83ba5ef05d3aae187382c447921cb9d2780c05161c41548204982a5a4e49411c110f5e4a4ba98a3072715876a8e549c373080e143c4020a0ab54bc581220e989c1421a4e23c49c5e1221507cb7ba393677d19bf8066accf053442e559102b03799e1525f85fe720119cee843e386cf4071e4ebb0b4e9bef809eb8cc5851da7f7e8846b4e7f2bc305d5cf5a067a276c344bb1b1ddc5461c5917a5346bb949b2f526ea4462858881b2c393a0c87ea60282d46d248fed13e0525c5482793daa7a0c8e8598b035062a080c8601d5184da527e5032d0f0c62a28293e060a6a5cd287b564cff7e3026b083ce1d412372cd61229bcf01d2058059e3002d0000cc133180459af21a0cc6a3d110b28a8d43eb5a4093d1b8aba57ace44ffbd492293dcb650790d0e49a2541b48072d0108fdc7a52fbd4122e5a86f6a92535e8d92b0ce76247f86288a7081ea830a413865c8c5e00f5f0281e2d2b825ae1876228d1442896744431ebf05b59eef8a0c3300ce964ed534b8a886544708f88c1f1c33154f2c5a7c48b506cb5fe4543fb94122bf48ce86363263b38d6c84140b9d5461445b11c620a3df3a8f18b1c6a9f520245cead6f699f52128436d3bd295dac918380722b03056940ee518205828ca40b1650ce4a5ca8e11b5b435d287e1806e1571886534a94e83074d1867418927a201831188725b6ca2432a87d2a491bcda3d301bace804ad0f88810bda0568b0707beae8747f168f900625204c3508b0e431d86651d563895048b1789411e05fe0d10784c2579d20f689f4272a70c63fc6a1c915f96415e8e03bf7bcbbb2022a4ffd0d0f84343438f5f415a74cd444c6369f08140a156556669cf73b54057febcbba1ecfede7bef05fabeaf736f8917c5c144294131d9f1cb1dc82bbb7851008a99b13407f78b292466583e848328af766f0a8995dbc170ffb29ce47befbdf7de7befbdf7deaba5e462831dde40e1828f9a303c1885be040d71e680a1414b14401885797468274a87a11d291dce300a4b3aa0f629244e3ceff415122fc642d763dddb798ee7b84b2c4521f03bfc75da854416f8422ca1fc5ddcf927a3fb30bc1e665d7625785b3a48639f3ab247e31f0f3eb8feba7ffde55ffacfa73f2196761708031b3703c404d7d1e386f6a4d4b819148070b0c3cd1c51a0038202ce01d40ad2a0a57dea8816bad33e75040b6d640aa0324e202155421591e487510a1db6b0523aa1013d479cc0708405ab2bb20378c839714a1eb2288f50810105998498f1ce11639a2f3a6cd1e186286228a160e1490f2c2021958c21c617e3167348315bc85045f944074822c68c689228a100415671c98365644385ccc105294f4a4a2a9e70641630463b5e48e1829462cd9333e3184d2801868b1025113e90567220ad9861f4424ad98411a830468ab809c385aaf18d1b12c9153929ca1aca94478421bb1041e236505269298ba8817c0206168a3419f7147922c3a7ace20e16384ab0217fa082fcf24479c3d4688511a4132fe5921d463c3690b92925935c0b53e48ef011a3f492678c2347035a9067d2904c9829c52c31e641e2050e20c103b9c395196448034588295c92f24a9f72093d40d021c768436aa166bc228ab20a13e41751608230d30379040719aa8c5451ca267d9650d127076545fa50876cd3c5182b4a3268ca2bc8903328c1c310250c5da2b28c6b68d8f2829a319890318c61a464614f19c60ed9c21b23b018bb98e2891325165264942246ab1f46353a94b1426e40036413319c8c5c88c142d9e58a6c020f4915a7481667a8d04051da20468a23c629be9453b6906e6e20a1c4304671f5a474e10ac99531c0f882cc228f73482679dcc20835650b674a2a64481ac2906114516ec0cb28678b972be41054de4429b5f081aac2c7c858051f120b3c75e48c67b658a2863ce28c1d32a31661a68a98e285ac620be9c49512072a5fa29035ec812aa3ec315282e12307cf98851cf26a8b3b6ab69c3143a6a4218c10459063bc90386c297db8e284cad8274a19061489270c2341f029a5f0c491f3b4054945cd1267b2908113a6fca108d20b2f639d2de5d315920e152ea2941ab082b2c1ca0829c587bc01cf18869c12882dc83e6a483e67622053e2c224298254e305cb9612c99592092ae35594226040953b80618444c3872c02cfa8474e99c31656a821d99c79814cc9254c0f458c587829956c29a3b8328a91452a649a2c462139a0874939a5878572cd18e41560905aaac63670462ab47828d468b28b1c6a97fa028dd6525f9471b1d8e07052ce191af23ca02ba0728e17893eae78415616b328e67b2ff87d9d57c6c93351eb081f7f50e5f7df9e2e04b37f5348a468ffbaae1bb5e7c275343879c6d2dd1e201d4408701d432c7df1a7007dbfec22cf88761005611bf7ed4cb1c382f69f0f5a6d86bcbf4fb423cf101a7fd07b91e7d280a84e9e116922ecda414e91bf2f70b2d7a58cca9345cf86c63999d42e95670622bc03e7f01adaa5f214d1a476293c567ad6f2a2ac1a42c5f0e0430b575de8d172e749111bb8483326870787e3947bc4c831c94180bb2cdc22ee0d60d2f8e05e7895db61e1ae0d1a80a385d5184d72657235704e723568c9893970456e14be84175e1ca47c8ba89c99fbd17901cc1850a4a802e7ce9d171e5843851eab2c90e0f0248b0db9040ce1c215b07891d30354146ea4a2b063270eb965882aee2001650489219ac871c95d80bb22f7458e8319b87c27a7444b4e2e0d063820275301ee5a01a24e0ea709234914397cec50855185c74b7e0147e7ca161cbcc8b3e54e79d4952b8367715f10f2393694d0c0dd29c6f81b2c2e1a2d720ac045e992bbf292fbb1200867e71ab9811b9bd2941983c3153e441c51074f170fd48ee0dac4e043981de4f81d31b917006e86db8554ce85a3c28ec5fdc2bb002386dcb56207cec3742077851439d80170787262721b10e1aac8c9c95d03e05a08a34a8e8b07703e05ee092ff0b4f040009cc891383c39173cce10a1143900e0768873f338188c0bad3ac2c3d8df3533b5d5cc217b5595fe46bb954cf69d523366d26cbf99ccb635652c8bca8ebee883117e8c50828e006cddad493b374ab3d96e6cec8f1e66beaadd7d02cf5f15778791e0f93380bb8fe0d95be34d7177d86f93768bd1ccd83bd1766baeb758cc7cb5fda51415a2d6f6ba9b7e08aab4ee33bd3debb499926eec2ba9cfdefed5f65b552dc189b6d7df11780318a0c8c711092318c000b076355bd66933b1b5dda2bf97cc556dd9a7d1cca7d1d010dc5df4eca5ee7ee4d9a3c003cf1d1a77a1a514c5d1aae99b7f6e25f4d3dbfaad9ab2ad3a022cdd42d025f559a7d4fca51455cf6f6faaac459b7e9f6aecdb6d82bbb73c776c0fcfdd05ee7e82679ca6c833aec1dd4bf08c458080e76be5b07337a9349af97b359f7d1a4dc368b773cb62ecabedb7b6da6e5bf357f599622a2de977cd64d1a69dfe96b54e349bcd7c275a1bdb2b7abe9359fbf5b6842aa56aac01ed36212501e9d902a4ea2fa5e8996edbee013b376bee3596a2cf9ab23335ffdc4ba9298ba5b76753d4aced75d7ccf463dbc6ae3736dd4fa3a14d4fa399b1675159fb37fecd3ff78ade82ecf553156d4da51fb0735f005d55597b333fdd3be95953f6ad296b7f9fe6ba64bb7d6afeaa2a3dd23ed518d2db705acd144dfad7ef25b386eed5f65bd63e10777779be46f875770a3cdf1bdc614829ba84ae2ad23bad5bc87ea7a43f7f277d6a3600c6b49ab5bd7e8a9ab2188e54fd5d53d9df4ca60832d60481a6aa494cb12d8b75706453dbcd9a32209b3565361f6dba856cb64d371a4395946e2cbbee1315a2ae36b3357b98ad79ee58aaa66d7a531ba0b44b60d75dbbb1a91a33571f3b96aa2314151dc9585366da766bb66c8f96dd4be8d9de6ced8d84a222196b8230c2ba936ab7b4031f1cc4f6096c0c6553746d876c10d67d9a5b765620030474b0e3c6416c9f5001a20c5e013b6e1318b2cff487bb07c0dd7f70f724cfee7eee74096559f35b357d596b026157d849436f493960186000cb0087aa94a23836cd8cb11728614044b4010666525206199c3a3050ca81434561ec6ecd35061bb2cf14bd20b6b21738ad2d8b2eedf50275693563b00b96d25beb74935dc0ae9b85c0051f142d4a8fc2e1b4779f9422650d576e17fdb5f2e846acee9f587fe48dba1f859ef02779a3ce7bfc2c219c87f37e743d2579a322de630fab30fe7d961091158c58e3df57a17c225c8ebabf2e22f7bb27523e7e098c7fbf7411c99d8d2cd98d58ef46ddcff2f8ff3fba888858425c42efafe7aa11be0a35429704bcbfef461e10968bc835eabcc746f8cb22dde3babf3eba0722c275a9c0fafb4ed8a5029723960b49856fc47536be27323eeeab425710efa399c40fdf8d58ae925cc1884879bdc7deab40bee722e2fd2844c44584f5a50a3f2a70095f05f231f9f88f4857e83afa71f1e86c7cac2cd9637dc912c291cff2018474016159c9a1f3c0acd0c514fefd9e475712b946d70adee07b96952cb2d1de771f53e85830408410df77c20fbabcee9dbc1ffa3c2c56951ea4739af85424871f7b451c28fd5e26f25d83413a3d7a1e0e452f24bd6e0c433274cd3a527431759ee7795d5762cff3baffdaf0bfbfe07f427e9f88fec4efaef898145d33f13b261753f8e0c7a3fbf05f26ef89648fe9be2751fabdb7fbee1b7f786b2b04bf2714a4a599c0774dba821009d2d2a0abedf49d797f5f740521a24317d3ec82a0678d95c837b07460fade7bec752b7437049c0427f91eff539223f888106b86fc94844b1006e8fb47bec77fe47371f1e151bac34029763a887039127f7c22449e92bc117814e2ef3e03f7bd273fd0452403e3831fba321092422c1a72064697e8ca40e8323203741999d1e58b2f0c254b4bc65f8a8e2577451f6b0b079d8efb9e5954c41d563b4451b4e2b3e24be39150e8195147945ff8644c0b684a220d04d9117545a06c11a178d1dd0f755ef75d953002ed53506080f224aa744fc1cc8241ec9274df3de9be9b82735c9c9529dd7d8705e7f8d1dd775aa2d0dd773c745f42edb9427d1f9bc154980d7ef383ee1ecfc13920a8ca730582fa0a95e1a3a44d12305ff018758fad743a7484b961082ca620c94109a32ea7bbc75db2e84e882d46601da1d4f7b179536545e50ae3f01366e269e9fe761122aa8516a4700ed69832683a5b101f1a532d30e9ca3be30feb8572cd38e5848b9f26503401a367af3137e564aa499a0ef43ed07bd17322d60b9fe745c5313305a7e7cb0f675690c244ea0a2d7468e2e68a11c67da77daac9115ace569fa02456c852858a0c513838c112c5a7a08839020f0b3120a91ac3025de783d5244a932e3f4daefc48a07daa491339665a4d8e84631886f123c2c9e1152548057e4ccab03c2651acae63f285c5440b93299989133a3c7a30c1c9f809c32fca2a2de9d76dfb1d4bd5fde7665285a4e8efa45d435bb53581bdb566cba6d0b4d314f65e956aeaaa74d2d4b7a1b637083cff9373db60acd9f44060ff0eb3800a6663555121a66c27b168cd022160e76e329b4cb000c93d699f2178b64044cfbdc6fe0612d23b257dd35100dab8bb07804a0040b039b5676bc6d033456f4babf93433453d80a56a6cb36adbb22baaf481e70aac2a3093de7678aee009ccc6a9b6afcfe1b90220ee301b2c6c09b65f7fee0a2c0832e3ee30965569dfca96d0b5bda99f2ea5e88d1e3eda5b5213abca82acb4295a538380b4e8eb6bea6a636f6cd04b5537ab6b54a5e89f7b5559b3a9a69a5043087798ae817ba41f34b3558f907ecb8e6aa0a0aefb02664bdb35f2eda4608c3b0ca98393a682505474c48112096d6aa2ab79c249536508f04c41126785f0f04c010f21681b33f7f94ea7b9575a8bfe8ea5287baa35354dcdd8961d5120bac3904a3877cd4c09e079022a77189207434c1190fedcecbec0deabd2081368912da1b257d596dd27b8bb003c4f3004c75e6d4eab89c650a59d6ea33c011077d8abafaaedbb7b069e27c8ee34b3c95c4f165d5b76afefd4a22d36eeee4ddfa6bbe664da2ee8d1a6bb96aa68071cc4f609aaac69df68a69096dd6707471c289160bb31a9aa038a8a8ef65e955268da69cb0120a6e519003d000005d8a9cada5d1300add6ca60eda6d14c20b036765b5bf68bdad46cfa9beaf4bb86b60948009379a30213307fd74c1f9e25a842821e24984950c1069e2378e3b05565d1750b41776caf7fa6487baf1e20b1486a6abeda16c073041e54b9bb099e816600fac0dd5f9e812c20f20c419dec19022cdcfd019e217002818e07b0784089f6fc0008ee0eb3b16f6bfb7adbde4cbfdbd45ccddbd2528aca5a1b2ff666c6fe066bca4eda4d95b15bd6a6686ddded3ecd4d53d5a4d75f8403d6a61bb5a1b1bdb6ec3e911e070c068bb5fb6fb037d8753ba5a6539269dbad6c09adfd4d75ba41a3a14c6faa47bfeea41b3690f66d6d915ecfaeeadff81be7668aa9b4774a4d3635770dc6a6b06949660a0f5b372dc9fcbda26dba8f1ee80ee0990695c3905a555d919e4565474aea6ad26e4b7bade19906961b9e690c71d811092494b063abaaf44e49bf6ef6f6660a01771f3dd3f041038479ce54ee3e5e003024b3a5ed13e9b710f4cd679dcc269ae994444b5527b3e997d2d664dffc143db5bbd3f09cbf640ab83bccc9acc5d69bca7eabaa6bed5bdb8e0dd97f0349d69afb4ca169dd4a48cf9a437cb83b089e675431e3c88c1eeefec3b30c3e328c7087a5706ea7a41bcba24f335bb5fd1dbb9d7b7da474bd2521ddd8b424d44cd1cd64d676ed653154d6f4375876afe7697e0ae97a4b4ae1d933bd29b1bf99505a0a819d7463b33453e959f491b6109466a660db9b09295d6f492dedc6eef5cd67cddfe7d34cb44d77cba24376934adb496fbb3d7ba6fbd90224fddeabd29fe82d084afb73a34a68bade8c646c1911fc44fd54f959e127e6301be97a93c55e497da716a5a14928cbaab6269546fb14fd96bdcd7e0b3165dfaa69bb69bf23f0fa73eff4d9011061f0ed2da965cd4dfbd67c25f4f7567a21a8d95484a4ca9a901e070cc904a4df49dfb23711be0807ecdc1028814d55d6dcebba5125b44df7f98329a63a60ef55e9dc42d6cdee955d32691e986b3bc407bb64d294d27d017555a299dba63aad6a6b9ea9593b3a7f9ce88ea526cd346ad39b5a3355a5f487aa94a2abbaae3e7aaceabaee1464ac292b2a3a5af7996e9665339b340b88cddc6bca22f220cf2c31dd369b29fb9404771ff25c5239d168372596ddb1d88dfd73b79bf6a92ebbec35f6acd9d4b4d3520aecdcad79da6ecf9a4db122a492872cd69ab5ad9e4aea003c97d9cfddb6682de9268167b2ca1d76aa23904ccebdb2e752aa3e8bfe125ac381b6b45bedb5bb03792665ee0ec433d94af7bade62bba9dd49bfcf57db67d118aa841a791e8b5080e711e7ee30a5473aa1042435b6cf5fd54742faa5145db7ac457dc0da98b9b643f6abed9f9b869a1eb8bb089ec7d7d27ab3fd528aeea4dfb174af5b69afafaefb02385216fdbd6ae0597c736e59ac356d2c7afe4e7ab55d6dbfee96862a6dd991bb33c0b348c56ccdf3778bb2aaada6c6bea5dd4ca57de248d5d4dcb27da231f466420608b839ed103a70da4c1ae4b875b06f34f304a71d0207b17dc23ed598bbdbf02cbe7f8bd6b657e039a4aaa9ab52d8c5614a6a079e43993bcc666ed9b30568d35d4bd5151592ee77a225d536cbeaa41d01762f99360b3c8721079e4132e0cddd23e0190c00e8196cb93b0a9ebf2877187b043bcdddb229fa482920fd6621f0b0cdde9e66d656353df799ee5a4d8ded359216a8c42a98b06a18448a2912810c0000003316000020140c8905c3d12047c258f21d1400086dc03c5838118a678220c7300cc4300c022008800000000010820008c418431adf00f1132f97821cddb1b6c9d055e3138c4f244b021a92b74fdc7d247fc7045c98c1928062ba87e31a60e135ac952acc9e6947451f5a3769ddeaa685a7c1a437336c708281ce24037c91651f6133d237bc470c85b7a8c2743ac50682394eb77fef803bfbebe8c95425fcb690d83a4e70d6b28cb7a1f54b41987768f827ae1b1427825fc9ed0d557ba1eaabbb1cc4f915ce5f86769df48e81db81de511f6f4d5788adf53cddadaba6cadfca5c4d7589417c640f96e725db33506ff4851a66d82a15a82f1a9803cf0f64a7961f7c43c9b1664bb932f32aef3c448ba3274fc92a49186a35b07b3b10e3af27ed3a3420afaef47a88edee11da2c79bcefa13ae8506d7f4ccfad36e8d897b675ec5bb38996b6546965b579b613c2868c67b2dce4816a599bf8787ff760c82498080af2c359906a7ade5b2937230e08a477b8e7d87cd633db85419b9b1760d35808502e00391d8c938ecb7eaca83e95fe74381eef2029dec3c51c2661831c431d4808a742da6cf01642b2f3917bda41ec5d05d3bb2a6fccd878766de3791f02c7749b8f6d9d52dea13a5dc7b38439a25ba52c6eee2165e5fdff1a35d7607f9ff804caed527000f62291c03a92f925ad46d3600ed87256b45a763887a36b52627edd6c49e7943eec70c11b1c89cda9739229f12de4e87bac0242ead50e21d1b1e4429741f06cb77fee7429ac72c98a3fe6ec9de819b466725b94d1751f208a25007fcea655379e83a9d62609ac0aede6036afb723a8de72e02773e4b5ffe1347dfd945808a0394e0cd0f95671b7e3846471756459d1d452df0d247d9343e35a2ea936022966d92f1d605c22de913e881e0ce0e56ed765ad9ad873ae7524331dcfc1d5dac7df7e4dab413ee608aab3fd170a4d9363e0f672f90bb1d825366a38b5612054d3e024e975bbf17c72eef901523f92af72fbc121fcd5431a6a14b787158770972ca510cd379c76b231bca9420275ce4331a2d3e1c0cee4f829124fc144d198250a4c9cbf82a93113fae307889851b35f34d2a348800c7cd32a2d48b03db7ad82a7cbf50d35038311144f1467fc4b1f76a0e350a47ad8ffac4e6a1a2048f45989e9ef633c3bbcbb1f417ee5baa1705defd4c3329992323247dda967e4c692921fcfe59bc418d847f391114a1e15bbdbba817fb22b029a86f67100e48677229661d800c719f388c1d121b28d02f519f543e139997fa1a965227d5768d5ed72ee3b5d0bbe85fcab65def5575141ebfc6c0f218f3451703e59d8593008b7cd02dac310f123a8258cbff90ca1a73a07013caf295615be5e953e4ec3f8a245387f755cbb90480d59103da90460e71443bd7a603b3ee4b67d42089f58ca504371a60a366e32ab08d56d92547884eb88dc0224d7f4d9f932f3db07a6af9781abd99e2453e276985a3cbe1b758ca628237b8b296277ef926c09d99a4e225d757a690a045d2f2f72407cb5a9a73e4fbdaf0065c98f0195bdf1434726c3433ff9b8abe894d6b6309c0df156dea0115aefc5dc71742cc9eac9921a8df6358935f627b29579f8c79eacaf25e87d88998bbc3eaa3ce44f157427980a4473f72089d3f203f977d56a1a9aaef691a9bec85a697575b3abaa762cdace3bfbaed834a49f2ba143d418a0497394040545c95683de5bf3f2749af88b0f79d80edc6406bb3fc69704a1df6f6cf42aca1b2ade49cc7108e699c620b200e6cc45f2512b96f8151babde2c4d42356c5dad184f657c701c2b0adb64a45f73272f7a4ff3fd1c702850bd6b0f9d11d5b90ab19012f6a69e7c3c897e810cc59f0b14f488200af0cf75f33df642023946ceb189708d59d6a7837b7c279e6dd5d9ae68089f9cacddb4092d6a9bdac628973cde29ffd8f09f7e3726d4a7efe75318d0573e2497edb1fe605939f02b94755fc3dbc75870c3f683eb1a757c9f6dc563f14af7e2b38c0cab918805bdfa6780d9b96154e889eb7913378408dfa35d14b993f5fad0cf47a51a5661180b83bb2fdd246d4f4ed9abcdae999e64230b7e11672f6820325ff2ee763b6b91b0e0f19cea1e69c8f5a3c1524c99c080ae1b76d7c419417917330c1958252f172c20fbb384501a12c3f658ed0d0ecbde56143ef5a9ac507d7540bf7469a2f91d63a867e6a9673b58c404a6ea6586ddeb0c21ec11b17b8bd34283259402a1a82289f23850a0f2d20e9978c81f732bd651ad3c3d7f9655ad66dbed573e91ad4d3f3a237d9929910fc3eb601b6a511c3f59c1c005b06be4b2c2aaad55023605f638fbcfc9553aea87e2db532d93dd5c3cf028bb9a72cc2883f3aa240f72eedcbd3bc686b34caa9eea78f058b2d23bd35839e57a927ed6f21e405607ff20247c9d1e9dbd573bd256b7b650fdeecbfb94ffab0ceb67849d89030d7af32e33ebbe9f45c55aa814ec4be5fe13df74d957ef810c69afa4b463d3a09be97557a9178df4ecf958fe1b2e0a2bc4d0d989c4b8f5e2c4f5e36be426ecfcd1e9c74f1df8148f816ffcec8014a52f4575bf4baf093ba8b952ea9b1a602ad9dbb1d0c7db8d0911e2144b06f67e453837739f4e03dd93a46cb78b1075c882a0a664f5666cc6fc31a6dab8d454fbe6190d2a14c83fc3feb34551b3b22ac416edd88ce19511c5cd0c397ebcf0def5ad643cf25fb760cf9ed64c1d4ceed0a41412d9efe71459a5ae8dbd33f77d4a5d7dbae59865773ec9a607f4fdf57a5b1b282b0041e4b59b27dbf101d3e5830fe414b968bfcdaf95da9f51aefcbdb5ef7e829f1845c89f20ea53522338da95d9c2416243facc505ba7ac050eee4a82e872a4a1afd4acb733c08f05defa2e32ff1b8a50a7d96721ada3c42cdf3702f65339a633dbba3ea894803c35c9714a2233b227d763176154056905a348d80a5e78690ac443585566c0b85c7f49d5b4bad1671821a084701385e95eb88269718fd786a125542a3fbc09562d48650441538bcc412b069c0dd1109f97686aee57deb6c4f8c88c1043407f4415364f6169a7c18edf7b0f333baf1cd669b63b94c8c0bfdeeb3b09c4bc61a384f1f97ca9cddbe73712066f5640e905574c6446eabeb771d158796910514011e341025d1b0d1185a9423b4b72fdd2994afe0c8cab57a20ebeaa034c92a43bd05da170ced98c947510dd37e772a15688df239c446bca73408dba41c979112751ba320663d127230e0dc110bcf92048545169da95a01abe638f4bcaedc6335861c192502e84cf7d352ef152c16dd095200a1d2bf88eba53267eae60e5e9616f0a1305384b81b39a5392dec27521e3dc57a4fbf944634aa793010dccc3919e957b9c36f4fe65f5d802e369982d0d89a4e0438b24aa72d9c5cd102388fd91bc2e0851c672b6837de127812bc5b95a2009117ad9941f3110208c5b9e4bf441ad075a30152551a37411b7a538dddb5569d803e573cff46ecc7783d2eed83abbf4ffae89afd46267875af6c266eb3eea83dd7fe4c45cf65293f7361d86356edca982995e206c37bbb20e215ab4480d7ff7840525ccf684410a4ac8cc888576648e1f786bb5ef97d58bf2a96535c554f6d8b290cc748b998252aa0c29554eabfa88712a5a705f40f8af03ec542873f2c16d9bedb1abfff11e943f5613a2c2a04b1a710f73907c2ec9f66ce1c3b8b4df0a6f77cf33ffe40e8cb05be7126c4be441bccf7a37ec74e2552129066010a5899eb635d07487ead1d04241468533a1fc375a3b24c3c8329648bb69d459f573c4ed26abb90f7923331a26bfd785658a4093b13b6968a19f30d1e78d2b62687ed275d8bafb2cecae9115d3e190bdf1dc2c4c7462fe890a153c2678d0a998a8f4f039137ca1ba178d2370733b94fa5658cf541c83b86fadabe39867c2557090ebd671944e6f61456de21aa28cda09c9472a8f2612199186a11f88ae281696260e178aa7a270f5638de2b72d65b2a8418a1a17751204e2a0cd94a5837fbae000cc35ffd96dcc07c9ac581524adbd35e79d3f6875d05a15a74b3b11c0002f82e7a3c0ab84d3b6000406cf747eb06ead1f4db23c5e2b7982074fcb726f5ac417e680d420548779d94cf83a78e5bf154d3663b94231c3c55435306904c661394441b1842de53649026e12cbda1953df1ba5b42ec9c730d3235988150061f247461e63ffaed0f0224ea9b2b2af04aa07556010b693560bf642224e592c9f6abfaeecde8e5b678e66c20609445ed795664f3aa6b16ce6c9345ba83903ae1004e78dfe87ab9b54704765cfcdbc8f1d2d0257310f4dcf8e939b580300ad676145e0fb1e1d5201643d3815469eb55076b993b918c98a5e78007fabc61cbc9c1da7968247e99e5789cfa4f226163a3417083f57fae72099c01b234214ee2adfe8a2703f968961258b29eec356fec3ce7b65b5127c9a19d1b777fe55c2cab13588f0c10f749119c34e64afd3f86ad8592c9cb24260d24d8d6d5af6af0c3251cb1db02131db782fdeabc0c9758911e140538c6697eacf66d3ca0cb9862fc053deab492b7aa6149499d565cc94780bda05d85a5cefc5b480464cdd92800f2a3c9582658d58183644453b0ca3ceff4ec33af7439bd5c8e6e019f49dc92608b4322e46281342ed6c6352cfc668401cedc94cd186b6b1cec1701fa7adcd954c6449dfe5ab730630ed6a2fcf76cfc6b478114c078af7a485739c1adf3c236f964e936d02b9a8c8161b6cbdc38c5a71e9f3e527a0a5d92e095d7994e8985590929096f310fe85049d577884e7023196d8c394ea159a329a7caa81459ee4697ffcb28a7211c5812f1582d3ffc254627d050563b891a701ae721a50a48a49e6fa318078fdec2bda2b68e8e291cfa3374e7908145d44b32121bb48791164b46d8307b4ab425470dda8c73051ccc999c1cb3ac269d71437df9ce338ef529ab5916624c83aa965ef0806b0b45a164a6717118ff14838c28cfe0f0cb710612f8f091c1035bfedb34de174038c2674a16a80b94719e9287c2b7be0b7ac73e8a183372e564bc6f3ec11e85b8abb525342f29ccee26b86c633427ebad6cd5abbb8f875bef419f70ca4fb148933f368eaf3b8ddf25dbbd04ec6362c709d74841fec93ec01696dfce8e9e33bb5faadce93dbad249d0cc2cb12328bac946bb08947d57938af68e987d64905034f78b85a42b256ed46f07c5dd3596b5c8bbb8299cf6872d524b2658908f24e1610957c6c4c67911153de9655ee4ae8c1a6a2b0bcbe230518fc838ae400fcd538579dd12a2148980a590cc98da56a62d1751220f71cbd318e02d7cad667add9a2684a05f2b993cdbeb4a2d5d8dc12dda6e48dd0a8780b129822128518b5035394730ba49a8a2be53bb735ac86a528b9b1775fda0a37d90a6900a691344ecb4773f09623986808b8fbcb6ecce6531bb64771f5bf8d4bc661dfb128a89e226b8e01994e9c7c16caa11d64efaf7874c949bd5fddbd4a6a7d6d8c1b6beebff83207dbf85b9c8793381fd94809c1d149a230e4b25ad054c0970b76aa3f54df806090eb21ff77762ccfd02637d800cec97a2d33a057a1b0af5fb70377ab0c6bfae55f75d20b979d35663238666ac174c81f87641e33e9b3edd75818af069c3418ba4a17d18f5d1bdac961f109f892f6ce62f21255a424c01e804258823e43d87cb7247daa1d0c2159ca9e2c3288811a90c2951530f44dadc33add189e2706d199b9253ca101e50f367cd74eec279c7a8d05bf1714f3390afbbc56f13a8568d3337f914cee5a6a6d6af4929c68cec4a30ab756ad639c942b43d6738a20ca67ed20cd931e6160cb45b0649880b5c259b3ab2a6581dabb2472c02b0b36c329aba3434789df273d74820f3dd7cbf4f589c240e6c135c6ec41ec2dd3becc2dbe21150b7f121987d3e13872209b192dda06943cf4b450ea0900e377b49c2d9109b130e12311149b273b4dae8a084274da0051fdc2cf04339e54becbf314f23cadf509867d3896990571777f405aa787e498b5c9c2484e844f71c31250fa138cf988c3c878db2b3bb5a4c1e475027f70d8581ab374f342064f32409c1e9c23d76f9e22606ed1de7a0cbddc8d75068b519568f58b2f63a515ed80ae14146bda2fbcacf54ee97077d1468b972bf5fae2525ad8fe00e00645ee1f65daba346804d2e8bdd835c56aa8b8e6f0b1bd5df86d13ce2c2807deb082aab166b4888a301152668426fc20cac8831d258906d5dceb45738c117c1c46782b88eb616d6a9de67828b32a3e5ea8e2f468de51aac6469967e3dad6d092d18e1590588c09ed1990079f1f4d38b0109bf373f152be0da8722af3a1ea4f5632864a02be300c4da5fb8e30a39005e0671be5256e76b6bc9e5779605f7c1e7732f084106a3a0ce51c92bbf2a702d8a6cbe77e926a56f566acad276b174d5db1332e29e1f010149ef571ea00503dffe0071bc5c2f9740a0f1d8a9cf03a46588a5eb569aa898eacb61a77c5dd29a5800e0554ce4a51980ce0758d33380bbf5adb1db1fc012c9cce3b8680b9852ba3efed17650ad913121bc915995f07226e4bcf6175280a18620de7f2280d7eae417a7cec0477da4a25e4b48de8a14e6329d7eb708174d408186d9c0e46651e77473924040fdf5d34a717f713e8a1bd7ed942a365e6f27cb28515be95ab556351c79144170cb0061a7b45de846f238ea68ce17f8c2169f9f8039c32037b65fcffabd358692c8bc789728d0b2a0d88fb749dcec9416d1eb11eca8d10ced0e50368b86d369f240f2ec9675a3958706511ca93c40345a776f01bfb1bddadbb4386884edd9aeace7ee0aeeffd9c360740da19a782bd8486173b6a5c22937b4024053b35598daa0a4c507e497fa4992f74ec270298b3eba1649de9342330f84760bcc6560b194d022e78d96ba7824b1b519e4dc0a5119d89648bdfbc3754767aaea88d214e158ac652da2ddc40466d4c1c35db877123d116bb63017bab0eb2cbd71f65cde79affd5295af2bd433b66d668a1c8eee26c82bb29a080bce12189bc145753c9833f76c505ff5cf8a3830a63edda9a01cfa2584f510dec380b5183053dacfcdbeacc3912bfa5c9558d63c219d794f0a3ba7ee8f9943bbcf545c21dd172a1047c1be9eb1cd67b043842a3938d4b75daf2d8fda2c1d4a7747ea6b9c3d9a339b2c5813206b5d12a9a0662c1b5934f3626a8e79246969622d99d3707caa9f35d0782b5273fb7d0e15aa807535b71eba2657e41c8416237ca9235b11912b4a3b5a8b5a1b281c617b48801edbcf9ff5f1682f5af2db4552a743abae48f392e0c3aae492533b1bddadae590d665750fb98726ba0235dbce4e7b532ea39b005e770b1120ae48c1ccf5f6aee4f5bd78af8d90ce352ad0c59be4d0a3b072f178d5c849b03aee92cfd51966c6dd75b61d745941765565edd17b3457b73bd0bb40ed2d1688d6acd68b27c70925de7685a918c54c256d4f1c8f70bb0b79273e9e8e5227e364177b3562163773ebd75fcadc97e8aa034bc68c4e1ec3a064013cd94eccf60cb9e71c42cd9162f212fdf6e2c4032e576b41a1af33c9f310965707947c8ce48444036111e638be700137776b1a5f22ece8b8db7d1c477c9c02d582095132f310925bd5040ca734206a78597543f58d2a4ccd2109d1e50e3d639d2f1274a24c407b4818bc8d163956ebe0fa2142ef9cfae6b344092ce31ccdf7626ea6684b83bdbe666ff7742d239f0dc3924988d7251d191c4fffe923736ea8d0f234b72a4ce2b8ccfc1dd87ba9b2f570671a4faeb167838351e5938739f75cba169ea99f8f0ac9f7e8f0cea5729f2e42cb9fe8ccef9b721b387db9dc51a9fd2135a80c82d78f185b5eaa0c2046cae8b80077748a0ef299c082d5ae9891724cc86bece795e3f8721cbbe2a16741ce1117efcb787c8cdf872586d44b7552defd1f92ccf25f5594ebbb7f4fef58498590f35f25b64205259c3c6175b750d1bdd7e2ac911b6700f14e3b371f86ad5adf45ff9f0466d2af820c93d0ddd5f0a790242b5b37a54d6e91d97af01321781ce70eedd1ba24f850f095a192f769c247d59521dbfd550ae9ed6eb6d047a4da8c53268773534d6cd10efe92de7c5b40b717940b5a6cc5f2122f5193a4ae9593fb91b2b601e02e3c06500c4f37be224a744bbcd7e909a9f723ac24d2e7e425089a9ad0de36c7c713eaee2114d7358c852d016494770efd934ae0cc0f627a0f65a87342965512008b1fbb886a4c9fa106c3694927611c676fc59d77bb1c15403588d28e805848ca906ef06868a3eff1aed68b84eba54f7fff9160c95617418d5f8f50e0332fe2129a3a7c0b9b25210515a74e16e92071a31fcdcb9f48d0218b0644d641f8a971e6e0a6325f002cc5440e336e4b1525c85f447faeb61aaf067ac7fffdfd9dfeabfe08fda7481c55701a364582dd467ed71a3fe924ca6d1fffc7ff3b7fca3fc1bc04ab63304ee925055c05a32da12b896d0e6fbdfc054c9524ef21790255326e097f811dc34f003c4bb4ed4b8dad5a1acbc16ba7b84127e2ef0bfa0bf9f7f027ec9cd3a3f269ba9159418912f9cc622413fc8e6d0a9f458bb980a0a55062ca5a9ba8cdbaaf24904080bc429976ca143c947a3f85eda54155ca5453183abb4e8e631bb84aeb5f90fa4259605e2bf50b92435d19fd2bf84a1d2cbd4e557f894301697bf193f824e8945a96e4ad06fd4ff15b2a57dd501e3420543e4198b2ab3485453ffe9cfd44fe5174de015c41fe9eff5fbff3efd0834253565fdeff3efff79fe634c066eb790da254da902bb846e6aff1324255606f2ff50a1645a821fe6fe0250c9dbe43635e45cf3ee3ff89618a5c36ceb95ccd83a3654a460a9d1fe1be84aac0a9dbf802b61335d7f732603b51b427bc9bd2ac82d79d3de5673b85057498ec8ba45f85eb8510e4bedf975fced3f2b7f8355096fa9e14770969c29d1ff098c926ab3fc6f602e092ac3fe02d0923d36a1bff45e53f89778163c7f01af927966d02af96b18c02afdca5afe02bfe46eba7f992603ea1b4879254c63e747805de257cbad27ad3209340b4ad5660e99ea71edd548e081b0b82884498ac61f81a9e4a62a5897666e09a89253a3fc4cbc602a5f72c53ff0aea7976ff34365b639602f19bf0a7a2586e9ffd9fd9d29cbc2e647c02f695fd6fe06f8255665fb77fbd9fe3742595a9425fc056809656aff6b0029f1751594a56523fd8b7fcaff066169a1b6115fc96bebfd3bf029fd4ddbfffffffc4bb829a9952bfe02ae244da3505632a52a484a4873ee37fecffd49ff1f18946016fa47ff9ffcbefcef3fe31fca1a7842255481a644e166e0940431097d4bdef2f9dffb6fc02fcd7b157025692a045d894929ff37d82cf529fe8fccbf035dc9db55b029f14dbf9fd9dffd67feca7fd91fd76febbffd93fbc17f647fffefee6ff657f62bffd93fadbfc1a5b4045b382e991be8d7e88fc0b7246f156095cc6f06ed927f7b88b5f42bb63f7c7e854f89b56cf9bbff863f8a69a1a292fe8df03390945c97094007516ca90eb7680230e27305f60fff9fbff6fe4df6dd345603ba151a80adcf0b924290aaa2638c6c5d6f1268cfaadeaf5f9a3aa6495b0eac3a7aae35269a6115e3c97d7ea2bb4eecafbf3c3119249bcf933ec791c7394a741bb5027f2a54ce3c7c2887975f445f0d1c0afa1a344f6a49e0504fee385d2a7dfb36c18f13b146f047ee0af794539c9c4cdbc2be48053ea76312219f9ddf2e4a7b75820035d849e0c6929bd8a8e49d964eac4e36b9d8ef79bdb7f20cb97d88bc3431e19fd2bf03e1523eaac05d72cdfbbfceffe25649cfccfb1168977814f74fc6ff81aed4323bfece7fa33faa29225eaaa8b988925b5527a054b548ff597ff87f509341fca6cfc7ce1895cf3701cfbc3df33c0ac848787a6830691c30abe7f3bca30cd3dae19658f0d0fc86d254308b8eed018c482f0252aa4612cf8a85f5f4983eaddb879ed35bb4c4b6be1d6605551d7a04658ce16446b04e6cd326da5ad06b7a9705e90f48740fec727c93318d9bf326936c36d228236c946ab4bc2c474d77fed3a500a474a2d64e9a547f3b9341af74fe6fdaaf28e706737ecc6c9a81a98047be46dddf566e8c71b0dbc50362a578aa55f34faa79040fc609033fc73c607ac7149a4acd24b228e7a71adb10cc5b92235248e80b57231d37be270cc5eb44ca2d0aa5ea8c021bf02d2089808eefcf8287bdb3230e43f7f072992c1ba4cd4fa6efe668dbcd0d97723907343028bf65bd8373875f156fc6a780586b3a85d2dccd303c44bcc6bccc11c1a5243c5bdeb34cc353cf7af36461f226ff21309b2109071b327112e44974772e937bd3d0ed61e3888cbfde93619bef661d1dc75bd32b51bed73e7d67c307661c58ab827199806a1525e3c96e270841237be7d506dec990079c2d020f97169483cb636d284d7517761b769aa38f408b0cb7a64053416f45a22eea1e0c177a81380d3b5e14367339bc9fec281e9a8492df61d6729d95201df768c1d6729db593d6274186a67492295a03ce100999fcd200f1c50def717ca56176b9b9c7f8a57a465e39e6f99d36c03c18184c323f4592f4e9e0be535b3ec2b48552c63a7ee9356a5fd918e18c6bdd334ff9a85ca9cddf3d94c0ad8a7793032fe0c5dc8d1a45ab351eca3ad906b8d134dbf177bbccb20d3567ae93245cc49bea8007173574f2d9260de9be91245044fa4d66c6e9c391f086c5432d84df6387f7ee9389b78187ad545da8fa0231491f4592294cbb1c561a624ca266fe16dec98b8bbd685f5568eabbcd74e858118ac7910da203bdf7406f18f37723f8fd748ef6b3634a77800653182e7ef9a0ff6dddde3a10d1753544852cbd528839cbf38ab8779e34d6d305d4ff9a66ae7ee3c419126ba9837a8075f2fed3dc84d6af27692dc25acb26652413bc0608c0e046fd6a56dc24690bc5f98318cf8c1b2bf0b1f978732649146ec87d3142c82af7618a6c5211734f58b36f54da81732060bef3201d9e58ca941e13553a76874c2f801ed2df2b68ecd0548b97fdcf556ef17cafd1fed4d901a8dec91aed130c164adacbc37994bfa74491012292f4abc43cf9acf48d12e1260d1918821026b20f3a705b529f2f166e328887a1ec306d7a273a40dcd7cc4921f7de71a8cf9eddfd0986f42dabdcc81a2fc16613b5da8f955d67d3294f876beea4da85c8b88e78087c379da38f66bfa1059748452a2b8c21354fd09b7e10c133e41d14157a4441b39aec48f255189afa25e860f246d80b52a8f9df5474088918c3945e32b3daac187b7cf5e68603b1daa6e921ad6e7587c523aa59c62e51fe3c4ed1e557a5ae658e0f8e5bf764a71e2c1094704e490c7fed309fe3426acfa1f399464def788b5f6ad70276b7fa5a6df97ed4d64fbc29d02fdb3394fa9b10f4df1596c3763077b17ce617308f4914f9406d722e25fdbe5b32d26150dfe31105dda3f607bb2135997ace2028182e07d668abe402134050b87ef5dd5e824c3252eb87bb8292c62983987ecace121a314ae07fa6572c5841cf35ebed6327ed8c9e0e31110e376a2f69f6a9e76a0358cf2643245dfdf0f212a270ef27722275f49019e6cc1658fd11382934cfb2b94852e999e0ccfdbe63eb396d8cf570bd87e8aaa5bef798678a475aeb0e09addbd0c7386c9f097919a4cfb1e714a28726655c8196257b02c693a92d6f975754c2db7318c67527321008a165bb00d1aa46c71685ce963b0b4d013b1c897c11b80f3ca428b69afe4916226c76135213e26f1e3a4f5c147ceffc12aa450c50dd42c325d4ad0b0d55c69bf90d72e4745e6323a10247e7fbaf58d2d3fc2c53cbe4057108f45941f092d379ddf2e31b88146a10f905ddbc39b0f051af8894f3d603e4d69b6457d641e66f53ab781039bff5d7fcb41127b9b8f62824860fc073a678493e0cb8adc73d3835c4909d92f28c7ccf5c1c8672b3c1e339804d2e50d21011868637903f1430d293886c80c50d4befa906315bf0335f79214f7e7d46fd0d3579d1341975c4118b328f573fd140040d3fd5c6286c6303d44090ecd069a10acb7c6c33327a1f9ab18e22e02531d9276e6980c758d74bcd2c4bcb4fa5c86b1219ecde21bd3de2250f857dd54316e132bbb5da4903a3ddd196d7770901122e03f89f777352a70034a5a3aa8ae3254e545cca423d31d63c79a064e974a480008fcdd1cc8ff934ef1c7af066a5cf35b1feb908364696aaf373538d93c0ac3be3b9387e7c5d7c04ee838d42b5f546aedeea14e983c89fb9bf66eab48d2e7ef1d59e9a131791ecd9eba7ecadb5549e59282651493e947d0f511831d4d0da29f1acc1d120c15580ae301c48f8b619493028961d2276a4d471c08d4ea44a9f140369bc5b3a5f15a233aecd7b69ad3d11eb48350d00dbc5f2ae77244d389b19936faa5b81226b044808b5d2a26f7cdf16aa0bcda3aca6602b130578f47ca7217b430d147fa90142b96820108803f2355eee20e3ec6e1ad3b98093ca700e1d25593985950ec1e9988cab174c5c4d1d8fc16482228741c7d18b7b23976a2dfa3f1044399c811433ee0e615e914a6bfa457469db937f46eb441b75daf5fb2023f9000741d472ee520b1867c6124c0d396f09e714bf6ac0b2e5f5e0869e084fddcb8e9287b1a10456243b1ad8cd0ba1672e6d6528f06c55cfb70cd4d33755782f098f7079042e8192e806aebb93c9b85813971252cf71bea92360e7305d2af144664ffec334f214caa91b6022cbe1b568e0f3402eb911a8ce19d9b947aa5c6c2aceb6387d94f8bd6fd126abe196d582ea764b2c17132097ba4da3981f4df7e5ca967fb8888201e8e535fd5b4719fd575326c6c187f7ae164169ce8164a2cfc9569138328d45e531790df645253e4371a6c95b683717c1e910d55b2b008a5b3c6a53734328d0225d5d77757fc6b8eab27f5470f659c692f975e34f1da73f2e9ee70a057ac4c582306eee73320d6db9841c7528da4fccb2bb081507f5ffcb774eb6bb52b87a65f673bf12427e289b3e1d29ad7e0d0215f655b358cee02facd3f351d8a70192d9eaf5a129a1ee9d42875792d168fd8b84755bade6e855654086d892e350cdebe0a9009ae57b23a705613bcbaeaf413604b2c114580c9be83633c4679f01ca2e26185082063c1146934ec5edce40fb86e1be2c92e64c38049ee0a1f47d2ace0be01e095d21f6021a9415112d0e24ee102998d6191d0531de26bdfd6dd802484ec0ae527148a3aea7382c45fca03d620403c268d822185c9b222048287863dfcdf86ccc14a28a098bc263222560a0f847cbf4d2fe8da56d80c629d964f1a476661aa57dfb58bf181edb639d364fa8bb587ce07c98a68128a867e621a36ef0861ede223b5973143d020e0f8b220e63727f38bc03c2903ef264b1528f0561f561ba61da91dc0b38ec0c4bc29f6b010a21e0c437cb42962eaa5a1a03b9327872f431e9ee1837fa108633a1d8efdf0c4862f09ce9466b398b83949228211e3a14d998624998988b71e2bb8a483f285686f87bfd1d850a348016ec7ad884ae9799105d4c1b941b71beff34f681276148a51940b398ab15ee24e751b457f9acf57b8daac520d8b063cbe75613519923be516a85591bd2384f6d7aa220ccc0f64a7dcc43f490d83d2d73f34f47c6dce57427e0dc9054045e368ae0b1e17f6b783095488a7956782bf53c93853f51f2282968f30045c1fa378888e2c661b24ae76887dea357a7993a7b7e633b0484ec516aeb2a57735ed63223e195c0126e88a492163ab1ec93f33a64e87d557bb8abe8a134a4d72cf9d1b2f743d4c665e104aa9f96de8347fde21b22d568da941c1137915781b5e857c13a2928c2513ef00687b7dc07648f56f4710ca22f85337c3125345aaa816b96825d12c3aec76e3b5086cd8b7425ebcedbbefa0e992d33d72402e6cb7e521f22ea544db40113f037fd74d21d9b8d0b33abd25447f2566e209e514804bbf34612fa768b1c73a0dcb38ef49b614dd47b74666014a4d53f143661a445edf4e15b944d00c869627ec8445a5772ac4520c0bb3f1c4546aaccc0e712673bd04a37e717299e0de08110a30e7e6a0c46e402c3ed3d9d195e53679466245a047560f82ce7838ecc3604ed7a3c0ffe1c41579aad3c72faf9f6b6232e91f07199f1693338696b3f9c10c8d766712290567db5a8fd5ee29a2abd9eb2a5dcb331ba15c56086215583ed953797f31690cdd1783c4ab8bb54e1c4649c01b1fb141f6a12830732477e367bb4548d52bd20398c16c8e1cd95954b12b4c48ad93a50d478104cf50dff7832179c2c3cc3eda16d2a0453460d4e91b24ee4c1e4a51e783451d19bc4355f3348708e3132f8afa15f98bf7f12029f62b1b2ee666d7c4c380c1572102dc81405864f01873af3be6241a28ff34e7a3bafdd30060ce633e59b488150375027b12b38521d859436e96942fe2e86f8a2aa0a25cb4f1c698eec7aeca2679cf20758a19d3e5d289b0014de67e96883b240850c7091d34d1cb4cd0b25cec76754371303cc841a5342b612ed4a4a74b435badae9b0c35c4a7111cee4d43b72129b286728e8ef18fe8bb6e0376fd2d6384568143ffa5b6abd9c4e490ef501a5d31700662aa461c01832b5d446a74aceedca731551bc625fccfe2a07d3915dfa5411d939cfc71dbc10ce187b7f0e982d7bac0185c96b9c3d3f5a57ec04d9a04cf3031c4df23ac9cb7ce625d66024ced0bde4f58ba5a24152b3b62485736f3f3502738ada30903022ca7439d777e126b317f984ec7a7c173f06bd68fbf83a762ae475be9802d24312e6877e1944b1cfce55158851b7a790b12edd9c8b7f53832a5c0f7f591adbd0a5d89e618e7e3bdbd9b94eb9f91abd3b9e64b953bc29a8b2e53b0aff1f7fc6893b6a48db35d1adcef55ec5162d21266a0f514c388ab92e8d67dfebb63825b082b90689868877a3c68bbb22bce0d3ea5099a3767489bfe06e0f785c59c3806855a0d546ade91a73345125a844741b68cfe5124d8e0db227d419db1735e2e0bd7db94d998106e6e91c69d4539640ebabcc851870de8465563d780cfcb6aba69c061cfdce350802be0ea2f65953ac3462c9dd5d062a0d00174e45fcd464c5882102bf5b11c75e07a977070e6c9ee0cd0cfcde057e7908211f3d1018d4e601685f76cbe68fb7d02ee0939897ce42fbb2799eff8f30ea6eea1e6bc7865ba9fd1f30b5f20612b8428a10b923802818806128fee788b14652b21d1523eb203fd3ca6cf046f8b9612948f033e7ac05583f738599659ac09f59659a30c97ef16f0c689abf9f821f569509b4029ae66b02cd333381b9c0344d0e66d94f0b88656655993fd35c33cdabaf5f9759f533adaaccf8a7c004feca4c20f0f7abfa5599f1ef678a6555fd4cd35c33c97e5a5840b32aabca34cdf734216848c001b8c1ca049a09cc2a086682046b0a604428332b5499bfdfd50feb9b412f548109d3fc993fd334d33a564f76193bcc4e3136f53386bf140806a4499a5e4c8864a68596479dc50445dd4e8ba06fe701f53a2fe70a1da45b059da7d1690e922f93d3c286808354f6e904a431348604412df60dc6bc901898bd13b44c179279cabd4b25807ba2ea698f4a95a13d0af343bbfb726fc8826ad870a2719270772e90708271f52c0f64f43bab26fdacfad13bb0f7fea2c305f15ceab872f8eb9b2e22970d1c74f3cdb481987ba692c10253419f8d5f293b37f8f6bade9d0ebd2b85c81bcf2b6bab395143469cfe80423ac08807a33ca2eae49c3df0497102eb53871f40a7a26bd06104a117645eae59193c369a0b04d4402e10059103402790c93c06e2f07079a90d4194088bd2004243604c11e2307bffc13520e102f0cbba234c8e1f348aee5431ca22042894a60af92435075ef029a0232a0984513e981d820a60032048815204468a0348d8819a0e0d0966ef559bd28e22600421c3a947efbd829007ee3abd7bb233aa77658edbd163878a9d2676f2ecdcf50ce7d979164f9c439fd22b3d913e7dde37db016147cdce063b64777745239ee1f4d0e13cf3d0e14416f1fe2c432814c2d0c4a8f773ad0e9c3a5cea3ce9e79ad6b996dbdf789e5a676e7fe31dfe8974ee8f1e2678f0d0bb8915ac435787edfdc48b27dfaf911fee2d78c0157f1bed615fb1563b2e911e3efc3ebeab1367562c8274e220953fcf7d524d99e3326068a165d03a3bcb71e6d042d3ba719e6b27da79c3fcf56e9a74420885e8f9e144d9b3c389e745bc627d23c5040da081579cd58e4ba4d6da991b10c280b16e9c7dbe3c1a60f673adfe730ae5ad54ca7bb752798f00fa3974bd1b8dfe88abd55fe98973bad1e7c81b2f2a7d9af2e34b398c7aef7df3f9e51820274c3f737fe6fec4e51039f97efde5d8c9693b95b77d7e3ca457f639d1fb8fd34fd2cff8737f2b870014e856a120f53e05001eddc18810dd1492a5770cc1de81977aefb5c980d9c8647436c48b427b394f207356d7be4c86b37fbc717c892c1e85f5d9bcc48539d28760606a9dc990ba67870e677a7676d860668ecead845bdbb084dbdcb0858814a7870fa7bd9cc7189362d0f3c3892f91c501d0f3c39923fd5158e7e8bdf7e8c13797fa122f2af1d4faf0d4e85fabb9d1563b2e916f550e3201400709c7d15ea236602801c21639592329c2001d808a0aad6057ac20792382051ea004cf8ada8cb6544bd0805ee84c98140248a6519a19f0088f3614336c800114c41c0326c99c9d89660ea032985dc03a4bc12aa5b4585970c55c00e45025d88552034dd20c6615f00c248153f00b0b2068a6805747c628e1d42684153150bf4c71f4dedec074690b6afa052a550547a22e60da3a4cfab5099348d05c0c496a0060f4ab12290b1b465224a06b857e3da67cbdf87463c29ca33e3fbbcff9a70aa1187c5eeefcde8898fa04f600051191e4fc52378ce8ccd13560c09f35bf2f08f004a0e432054b0c32a6292f55ecb08b622416ba9890182081650e952c434956cc3c5134ac891181942c6aa09864f4b47309e80140860724a61321308438815125013b40ccbd357493b4f43582b087c38cf14002be1b6b72e40531476c3972a11200a7bd134613832273532d964c82c964e0244511ed4b044b2d7a7fe08e0c3252236a9005d03ba21f79b294888df98b7a9f8386810f23d153264cef5b1ca0b7a485ee94c2d03b112c2a305c000b8082dcfb7181417097310df020f63eb74487fae706a618c9dee103a4fcb9b107cb4b4def653d40c47ca3a02400d23bb00c5fa604c8cc7d41aa4b970a7909f6aa547fac8430954a8d2037602d22857d3450a9a82091d327c11d47a48fa6543ae450caaa9d6c89659a948a3e3584cd033fba020d18a57213636646a5883b2154289570528ce01d0d1b385cf549d5450544243c816eec20730715293f682cd4fd346d2307952323599d46d171e095b706d59d02da924f9684a902880caa01460d30044424cf01a50baa255f1ccdc1f286d29b255650e58e48ed992533e8980305d50b00e082206902e7421d125420f6c84975c7d641e780a0b230641e5a19719c38820395161b3665c28849c5e34d7e8ad3a748a39e308080a70bc6530b701963b760305404417d0ace223246b31cb31720314e65799287e54f1c0b7b00a03b152481466d18c408f981f3762a0f889e428e06e101c1a1ed541c01305e290d2d014a3a9c6a39b15a53c03490a1c49e8a904508203f52e848018576aa1fca83f0b1e0632d8f99a94a4c00c074c326a6a81833c5c74e108a9ba294dddb652a8d8f0e5c7d32dafc61b1c0140066fab83509c137774c5565ea06262b14f62a6c3ac2c794297fa506992565beec6103ca1409422b629ca57501fcd0640a2d4920096598ec30d56192a92d03ec9a701291676801a35210a4da4b63ca00398c54142ac5684c1215589e00f028d07befa8fa94aa53490c10d08398ec280199045cd484e87fa9cc71a5b0be8f2888383d3f9c4ae592d6c087da69881c9748b5fc68df69c894f7ec7befa67aefa57aef11f4de49f5de47752bb96ed5260a8250bd7750bdf74fbdf7077aef9e7aef9d7aef9c7aef9b8497d0b405d19838d7f01ab9bcf3615e3426f1d3438713570a63619ae640ef5d53ef3d53ef1d53efbd817c79f7f93732e60167de3a84a0993e5f6fb8e79566d0f44efba4a72df5de2b51d211342376b46fe45917ebf3e8bf32ef334eeabd9b6bcc36c13266c13256643af5de7b97d47b8fd47b87f4a807c998f52099b11e24f3a067c57598b095a669bf95ff45df08e45dc48b7ac5b6badb46bab5fd4fe2872a3846ac587f5a7993a0ab7bab7f8d2cd2f89773fb72732352d49f887be31c8bfae7bea8cc7df2cbd575fee772fc7ecbf1655bfdf7ee1a298bc11a20ad8769e466347ab630797a1fd2e8977551af58238b7c3e85b098e35f79dbb53ce123ef628df4feb48d1fbfdbceb58f2c1acfe39de7f788b3782a97f9c7ebf3477c79f7cddd6da7f2a6e18fa73f93cb13f993f75a1e5e549ec8bdbe33f7e78d9f77adfc7a7fef36710aebff954bfae3c8e2ddf9edf37be43f919e46bb95dfc6a9a1cf68f45fa9c1763b27a890935f9c70224cd09d72329d0859aec4298f38e9e6ea529c42e44fde27dc79a796b6b19aaa198dcbe4ddf9ffdc295cde7adef6f45716eb901e0df9e790f789e7d1b7b10f29e214d6c5bbbbe55d9fd22b73e44dd7451c0f791bfddddd89a3e1b67dffda2bff71c429bcbbbb71a35fde2e729ca7cf7ddb89569f681d8e45e25cd2a7f878dec3799ee78df33cbfb1983cdef48dbcbbbb3b4fa17dfb1ccf97f769df423c2f229767964359306038d7eae2100db7bff2a4c387b7f2db18226f24964158ecf47eaeddb98915c4f267e45886b3bc7b88178519729c19ce72e3d20b8527da8df3d442bb897b67b9f2e3c8e2dadacfeb4a0701bc740160cce1293d910da95cce43a3cfef7c880f8d463fbc52650555efbdef14e2bf6854fa8f8617711f77e24aa1d1f7de090deabd67f57eac927ae557a38b425418af696949fcdb28e243fbbe95c97f2ce643fb2b7bef828c43e5ad54fe3b1f2697c3de7b2040f97dcb21ef62fd65a3ff4317f37f24e645a588debb9fbc3ef80d87872ccab1f14116f18a4a15b51fd17b7fa3c01e3d792a5151d0fb9d7f7cca1ba3d1b309f18f9fc81b2fcecbbb2e7ae552041af2e3a7c78b79ca7befec331a4f7c89233ff2e337913e95cbdbc529c4f165ee953e99f4e7b2be95c9538386f31373db2ed6275ec49379f74d3c695f23ff89bc93cbf3cef3e83b4a2761edcffa1b45f42ee7c99a286fa220e9bd0b3f8df469ca1fc52eca5beffde4f347bc789e51e22863e787f35c93a398509040c1d13b9461ef7b6a4f00a83f5ea754ca792a64ba2768bf80a143cf6f64ef1d8fe9c18989ded1a4cff163316f6264a289c68b471a2f1ed598c04bdc74a371b9649513a7f70ea780de7b9737375f5e67abb8f9f23a9ffbb63cfa7ea31b0ee154b8cdc9c97643b9840839157473c3e15a124675922b1dc9a3def190457a59efdd469b2ee2dd6fa8aaae7b5eae76f3c77bee236f38ba147df41120228e40c8334206570a4db9de3b5dff659911f45f0ea3d11fe7ee9b6e441cc3f11bbb711bb3f11aab711aa3710cc3f00bbb700bb3f00aab700aa370fcc2effbba6ffbb2effaaa6ffaa26fecc2eeebba6eebb2eeeaaa6eeaa26edcc2eddbba6ddbb2eddaaa6ddaa26dccc2eccbba6ccbb2eccaaa6ccaa26cbcc2ebbbba6bbbb2ebbaaa6bbaa26bacc2eaabba6aabb2eaaaaa6aaaa26a9cc2e99bba699bb2e99aaa699aa2698cc2e88bba688bb2e88aaa688aa268efbd8b072ebd77b39b05f4310599818828fb8f936be54d7fb94f236f2411f726f2e84fcc6328632063d831e6183162508871c5e0d737edeb7fae218b3dab42cf428588c1db3515a2c2340d79e33486bf567e9c0ffd5d5de9bd0779d17b17da5f791adbe450ec7db8fad7371b9044bd7721102be5ad54ca3fd0d0198d9e0d6ee7e6844ae4de8dccf33f899f4a6fa47f7df6e5ca9fbc95c99302dce23885136ee7e6cefaff5a882c7a620916739b109f7dee6b22ee4dd41fb9fcb5f13e3b9ea7700dbf709e77ff78cfdd9d4262f244dec4bbd3be4ffc2b89f96d23ede299e1ecfcb8d193388577eaba3c7fb22fbf3b73bf54d29db83f7ae41dfd93f8ddf995773e770a73fc3612f333bf73e44d23efeca21bda07ba0eca9b441e7d1b479cdd9dc41cffca9f7f1b593ce245a427d2ff78e2218b5fef1b8b463a2d27e2158d277e1b4fba98e345ba9814f181ae43879cfe7aa7cf70769efeee035d07fc68341673fcfcc8fb1f6fdcbed3f2e57dde78677e23f9ee11a7b04f791fff310d593c3f9ed21b4f7f7e3d4fb4bbe36c64f1567ebd7fdbc853782a7d12ed149a3885777773a730438e6348fae3d9899f42fcdbf799f429d0f06ea3cf802c9ee146e327b23885b8b0cd8d3e977609bd40f5af717220e29e585be9bd9b73fac00430a52f481f5fb0af461fb16fae6f455f5c4fde67060b67e79ada99c1c28966e15c4bde279a85f3ec3cd7d0f0f39401e3d737dd47d6073cd7329cf9b3fe725ff256e6c83f54e6c8e21a1f1dbe137c6bc3b53d48bd1e1a8dc5bce170987f7c98f49f38cc3f3eec41bd167a67fd5c5b8e3ad79672fab9b62472aec59d6b4b08e75afea8f7732d47d3cfb51c47efe79a8c1eccbb7046e71a9ea5f7730d379e6b431c3575ae29ef9c6bb8ef41658bdebbd2ec5c0bd67883d7e071aec1e8c11a63693d989c144ca2e9fd5c337924ef7af036d5fbb7ede59c2fe77ff44a9f3c6fe41af22ee2b51f11e25e6da4a5debb100f792bf7ce7fbc711cf72ce2e6900e8e7d7a4fab913e2d477ebd5fc178cc89c3a17279f7a9e1bf2e2ef1d470faae8779353e54fe1cf747b5bc1a4fcbefdae719efa4da5d140a7fed8f1fe973e59d3c164ffc78e63840effb7939fe739f477b258af32e03da997d0f89b827aeadb9ad7aefd1fd3c6f1c81872c26933ec529ec33e645ba6844def589d34562d22bf1ce4fcc4fe5efcb3f3167710a9377f2c48bc2a43f2a3d72791a8d224ee17de2ca1b577ee4b23ef1e392a6bd1b1ef23efaafa43bf34cf47eaee115f1e110cf4bf9721a7dfd5c23e29e581475ae21bff1c46fbe7c99b3f560b105ee89a7f2274fbdd3b315cb7a17aead09cfbb9e2c12f1fa97e8bd1be9bd9bbdd744b7fbdcd77f382c2287872cf6de89f4de4d9ffbb62175d1c7fd4f028f45efc725f29f77421c4f168bc6e4d1ffbdbbbb33795ccea747bbe74e218e7b22be3cffdeddddddc921c38693c3a9e1dc70fe6f0fcf4e0f67b2980ff36fe4902159cccf68a3a7871ece33ff4612a79ada8996e34be5dddddd29ec9b4fb40cc9627edec8b333adcfa8f4c6e2b1b854a6e5c85b69dfc1dd9dfec491771179278bf9e9e7fbbcf3f3eeae2f2f2aefa2327987df378564315716f5289c3f5f268f377d67f42aee4404e92a73f4d71be6f9bfb7b6369ce96f57ff1ab9bc47e4f9cfc268f46ccbfa23ebf872bae3da1a8ebc8b38f2e77c7ff6129cd1f9ec5d889f68c4e279ee7db8d30b132c9dd6d686c334ffa29fcadbbe9167102b91e4b535bab8b696c473e59d828faef727bdf7183d78c7a5e34a612b44d3e0169fef944af9ee3eef329c25bd720fb95c5b93bbebbdaaf7bd8effbc6f86edbcee782b49f4def5ba7db7a0f75e0f393deabd38bc730eab20e9bde33752191cde181aefeece63d7d2bb5aefbfaf197bb46ef4de913d3883adcfd8e78d49bcd876fadefb32efbde3bd77650d197afab976d5bb5e0fca00d1fb4f1a3f71a8fcc2fad73885777ee2c5f3ce7befc9b30a13823188b852d8f7f386464fdf4e94c098c40a53619a66f45a0dc0822ffa7af0c5dd832fee7af0855c0fbe907bf045db832f2ef4e08b083df862ab075d44d0832e34f5a08b473d6897400fdabde941bb303d6877a507eda4f4a0dd911eb4dbd18376780fdae1f5a01d8bde3b56f02a410307bd83752e2fbbb507edce1eb4e3ea41bbab1eac13d583759a7ab06e811eacd3d383756d7ab08e4b0fd629e9c13a1e5bbd2f78d0bb185d971ea47bd283747c3d4867ec413a193d4877a207e9d27a90ee410fd255ddcaffa23626976d2a8879f2b7a9c89749a41b16174c70a5f0e6cb97f99f13d1bb0417183aae147ea87f325954e6f8da11f77b1df2227269b6bddbe8e3dbd35be6b8b246f2461ef368148978f6afe9d9bf70d182855d1ddd9cdc8a38b8146f284e982841426e631b2122865fb765573545d5846968a93668c87086e18205b30a1426a43a2594918d45100b8300f6952a55aade7b83bb1e648108570ad935ed2b6f3a2d899b7dfeed86ab3f91f65f2e2f1e8b6fb5f2dec3711f2722bfe188b98f8b3b2e711222e0169fa351fb1170fb713fa2f6233e9ec7f17f342eeb3b45efbd5845acc233557ce30d571b6f13c83ae4b7712b49e41fc745b0b1edddc63f42d96744aa40d6e1357249e2d35e3dbf8d226e4c2ef3d3dfcaffc2e7c6dfd686d7c6db441fd2a7b86fbadaffb6393c64b146fe249f8c74937b3373d42980d7b46fa3881f8d7e59e39f7fb651c4bfb2f76e7fe40da7024f51ff5bf95f206f38b636e44ddf746e371d5eff0f47ffe4dc3f7a38fa27e7802ee698a4c2774d4b33d2cd19bd77630fca5de9bd7be8c13908354e0ef8adfc36fc379e785e9c4fbb48c471a530a77df278d36a2a74856b1afdeb9b4eebcb8b4a753d4ffb3efbbc52e94fa488140f7af06d500fbe35e1a0a1f77e01acf7f8cd460fbeb13d8882540fa250d48328d0f4200a233d8822af0751d0f5208ab41e3c01aa074f14eabd5fad786366f5deed1e8cd3145c21872f6b7cfc4387bed95dd3d27e6efacf461c91defb79e6fe44debf1a7174c2defbaf07558c8a8bd0fb71893c3d78382e916b6b6bbd77be1e54c187ff258e17d5703522fdf3bebca8f449b5e34d0be725312fe2a9a9ade1c93c279eb94f9e1ceaaffc78784565fe954b63d1dbf6af4fe0070c3da802ee6d24e04c098bcabc0d4e4e7edf731de8f6de7f0fc2b5f5de51b8acde8535beb6862b85f527e29e885caaa54254f8ae6969c01e4c2197e243effd5cbbbb3b737ffedce7c9a55279b3f1a149ff896bc8bd1b9987ac53dec8e589f4776e3cf31bc996e34b0e45e189f427eeffec45e079f158349ec45c599c4fa43f917e26e6cbfbc48b5fb9cc97f69c01ffdfeef3c9f3ce3dd2edcc6f64ef2424f4dedf4e949dc8d27b477ee3f9e1ac8b475c29cc95379e47179735d472e58dab7dba68c495379de27f1239df8743de45bbb96f4c169574c8ff861b8d2244e0f5d72be6b447ba11716f220ef76f7b371caeae75375d8dd74811f82fe23e8ecdad76a3f1e2716d0d47febc3b5f5bc3d7d644d46e254af58ebff8cd97d7f9dcb7119325c8e0ea0b3b172e5ab0b0abababa35b3027a7fcc5defb8a4ea2eeff4c7b377b377b377bffb5e8bdfbe8419948cf3d5e51cf23bb55230fc3dcfec6616dbc819dcc7aafe2d4abce58f58ea596e3f5e9c1c399e10cf98d425a89abf99d49cf34dbf8f1d383879328fc78f57741e7c626224e04dbd9e1e4ab8b668ddefb8f1e6423d371a5b04f9923bf5ad21fbbf97bef3a7a908dace34ae1af6fa4daffca7c56c38dc69ba66fa3d1abf529bd722e1ad5727ca99c8bc61c5f2ad5e6a2510d59dc53fa3aed1b93499fc6ba445ae97dda37ce3ec7d58cf79dab259739be540ad1f3c389fcc673adfeca8fe3bef7ac1cf9f58c46cf161c711c313782c308b3115c23b44654f5de6fbe7c99871f4590e9f93279572722aef78fbcf3ba8823e99fe4fbc8e5894662ef4e0e7bef670f86882084a0deebafbc917845a3cfbd7d226f24daf9956d9d62f5c4b93c4fd31fc5cd97d7a5e8fdad77b3d7205af030c4a9c4a102f61228d57b07ba48ca8d59a02bd5a7de7b55982d03c43d88a3e7edbd9b209cc050c1a4c81539bd7773abcdac8c00b7a4b1f76e1ec9242183d2aac398defbef4d0641e9088623a27aef40af2581364999226750effd2a8028a3cc426ba842f4de7f934235c1614a8aa4b7f76e55e50e8b0a910f0d477def4e6af5de518148802b8573d1a8862cfa631a8b3b2eadeff86b4f8b50c3bbd570fa6edbbb93e7ffca4fa4130aefeeeefc3c6b64d13eeffc947187cfddc1a87faebc93c9255ed4bbcbfdf12b6f36618ecfcbb9b34fe9897745e1afefe3f9f58a4aa23fdd4ea15c4c8a301a3ddb9bf0ee7f1237ddddffb6f0ce68f46c77df46433b2a6f1b595c41ccf190df88fcc69c6f594c8af834f28613fe650de19d7d9fbf84f02fffb2c6a9fcb6f2e7f69df01b91c519af8fc57f54deb6f227718f1789b827de49fcee2ec791458fe74ffc23eda2f2eb9df7315fdeb33f7163d1e7bf3e914aff8de79d9fc6fb4e9ec8bb58dfc4dceee4cb897971efce857d79f2f84fbca8f437f2b4dd4e19776b6bca7f07a3a8fccb1a45afe795e7dddd892cea1571e427fe0c2ebcbeb4ad3c3beb8fa7fc474fc44f3c1bc5e39de34b3a4716cfaff4caa24f9e697d3fefcc50ff1cffc8b3cf7827cffc897fbca84c1e6f3ac3997d9ff8cffbe613bfbb3beb4fa497f869177334bcb8a7fcc45cc52974c3ef3ef286bbab8b77a7ed760aefea6211594ccb8dc5e58c7f65f22bebe217d61f5fdec8130daf8dbf882cfa1c79d34863dc29acbff2c48ba7f2562aff89f4271afe4fe57de6f4572aefdac6f365f2ac91de682c2a3ffeebfae37e4e9353889023717a4fbb9dc2bc889f7d483fdfc6f984533177e2f4777811ffc85fe244de388d62528430bf91c89bc51d777e628e8617cf7c993cbfb148dcbb73e47d24e645e58d67f4a7571697c933778b13c1f79167fef1943e179ecadbf679d12bf3b398f4e79df2d7c6e272049bf0ee537a3d9ffbba381412f122b248e214e637b2c68b27fe8f379d2f6fa4ef332693228a49112c54088b497f0acf3cdce7b63d77e27d1f85b098f473a7f027fb36ec79255e34feb6e1104f983ceb5fdf34f29ff29b08b6b9b3feb947fedcd3c89b3ebf72997fb95388872c2a73fcbc83ed7c7977faf3cfbf98178d1ea9fc39df3f7d51efac3f7e27f9fed9f7f38879714f58ff8f9f7d46a3bfcff3b46f7f9638ebfff11cbdf7aade7bd630477ebd9b2f5f0ef16487b5357cf88f5e69df7c79dd8713edf873bc6fae83f22661347ab66f9cbdd1e8d9d6d6b4d6d6d6d686c89b1ee2bf1e227f5d1789c362d20f93f8da9a6dfcf828e532f748bc227ed645a3d743ba9d21eafd56fe1767617a471a913f899f1139239ec1bdf74f238bf6afcfb27aaf3fbe24d27e410f62e8a4a00731202a9e7d79f2286340d33b314ffe9acfa7e8bd3be8410c53fade6db4955fefc6903cefeef0620a0c71bd2bcffce3dd70bdf7063d8801eefdeea6bbfbf4d293c090759747dfc6117767be9c8bca1c2fd667adf47b5faef7ced5831732f5dee95b993cf3e57daa68415777c14def49356d4de4c9a292c6f18ab8dbaa267264f1be3fe4cb24d22d5f2691c5146d355d34cecbb8b5350ba37aeff92722dd2c0cea5df8f1de3b580f5a10c0c2dd4ddc2bfa24dafff6791e6b9f2ce677f67da2dd2d73dadf9d2258fc6f0f8dbe982b7d12c7bd91ed1bffb787c3fafbffede1c7fdfce14387ff49b87540dec53ca9e27f7b88bc8bf8d248238bc962fe8f778ab535babd1b59a1810a892a00e9bdbff56005b8f7cea0072b6c98d08315b4da5098d31ea49052009b90678293091ebc7a70c259ef42e15dfef1a1f21b6ba427fe21f2be3bcf3c9fafadd5d5c5b63b7ce9e93fd3bfbee9b37379f45f79a6675a06dce8eff23f478754719723fff11b93c7e2d97997213d537177a6b19d152a08f17be9897cffa4f9bed2eff9f38f388578fef1cebc384c313cf1e289e3de480f3ff2861bcab8abefa2f2c71d97c722b298626d8ded0e46df8cbc4f7c7917f5909e989f4abce4d1e7f8f7390624ee8968e73fe922d227dd4e611e1d604238861ae5e920c4108ea1981a766422d7113d632661a1b16c9d0aabc3f0e78a03646472126b53b0d40d400955b720c79e1b60733208d263238c6c8818198db8482934739d8ad3202e55e2c4a04d69748cf5e9b1299bef485a324ab9b522c7a53d79cee6707aa02c0eb13d13339afa8c18f0c413d99740b6f492b42296c6468c2d54d39a5286204c9a41f6098dd70b3d6e605ed8895263e041039326d9f9d46622cb9a2613b21324044860a40559f5e628a2cf20a1280b938d3661395278ba72c7026fd581a58bd0263d4ebaea0f2f26a5e07a130a1525316c168e22827169a4380f619e884a553601d00a33562cac011a61a64268a2830a002b3a2ec50e74411a42a46b8f1f23abcaf5c5475329b3e01aa3b111f243d619a845f2dd490f26313825baa2e4401934a07392a5466c51d0cb0fd26b74ea00ad1a8d44645962e24c88ad080d12d05153d1022a8d9902c4d1458f30434796026b4b8a437a5431c327d259f7a29466d1a2470967d09f2f0bf7a5b36f01c1a0664d16187ac2746100880b213cfad895174d742b1e068ab4d457a1baf4fe95e7a6135b0c016adc581367d524aef72d4e785c00ca812289292621aaf210bd8f11600802087af824a5a9a192054eeffd2b14df9d4759eed81890a1841a3d322278c5c22a89e24317c7c8d27b27a33378422046173a630a08e5c17c0c0165e504994da19486355c7f0869f8d292a6ccc74c8409d81b3616c508353090221e5ca400f59d91da14f14823bc324f0a1f1b862cb95416a80a264438807c882a8580f0451205127bacdc9509f2e00d1b3656c82f3506544948c28948161a33b93d593eb888b320696051211ee9a3082a1d9a80430c064b6a12b87aa044c212d598840a886929445719506e54205bc0110d68673f2650c4f8d8fa125d5973a6fdf2403a01018f602740572916702236c950244e715e67c8f8d82009d162d25d130f11ea1cf1e0f4b02c8220cab28540dffb88c7585ea80bec979c3b654c502b94428841d96242ef125796e149e6e7831d02c215a89701e1d121d0e80f88740921c27aef5dbdf7de7befbdf7de7b0ff6de7befbdf7de7bef9d6bcc1712048c64e82468410a050b648a16b03a466aa04a1cdac4e7cc2b80e9c50005c836cc71f0e4c20f261d55ac82f87020c4c1c5a1cb4a0fd149c09253125ec32d4783af3d89ae0a293973a436301697a20aa31563385498289246cd572a2e74ed7f84fe969f3449ec1c38d834c453562647cb1d095f22c83a8d7142a801516ebc7cc953a0c51041d0371ada233269e96549f04a8e9d1a5bb3a3fa4a8b8d923d43fa6854b5a48678c591e2012bc9fcc08d0658dc09c2b6772982861c0bdc9271ce88492ac3e60b94ba48c10894602853699922f9e7ad0991313666bce2340d953bae2c7e4c476c305590142636440759aa37606e7d040b2e3599458e8250cc0ca243a841922c19f4f094694a90d75580a221779e4169d65a68ef0b180578c22eadc880a2003c734e84d8138549dc9f37c1542d0010dd980b47cc71ca86da63edf2b083c896a1025ba4df151c88e84ce011f6e668c4dc276397a21f6d8c1a6c6ac091842c605c973a9510db32fb7ac025a60b8b07771ae40902002d79a24d123e99c47c7103810dd75502a5dc209151a71f2a4589abcb22d911d9b3e1e5cee778509265ad4b8e0729f4bc4e9001f3c34040a2cfcceccb1f0827a100aeb01004e2c18a08ec9816c8475986ac1e6d65125082a8ff2133d1d7b6852b919738053455e92bd1790c4a8142814a604c1a743905c60e8b290768b97a24c01c2c6439179c872d021cd0d1698f8929788e575cc423c94a1b1c14baed72f819e2a83203fb994921810da13d47d0c842b88161953686808b47785c4cc471409419134a291ebead0820a085c0c36099c3d153b404c498822f3e01de38514c06096aa0abc9da405283b1af0412b0d02eb184d02ed8ec185445d096120e555e11453335a8206cdd92b4d05e9e14f061b585c0f1d12901bcf8302a222702d203052176ac9b0b0f56553e1022b361cbac52fb24d4a33287f054e881d586a28a1752829d519f5a244ae1868c77f39ad1436c0f18356e5035075a2c48e9abf2a20d85a0015981e4749015efb8d141c6849066812e078e54e19175b9d3529ac1c29cc1c009b1330712e041894128b6196c34d56913a551d005942ac92567059c8890aa21c54526a6eb2665e78d80072c59d182ea1465e7c52becc828d591a3335a7e28906380160dee85844d10809072a84a914973c81ef8d8f39d1e847261c9804a755c21042a5a6ae48a0be10134de4c961a3fe0a831c08d0707da7e48508b6143cc44924903dc99f90c8851ba3cc841a54fdcb18599061819539d79194320c8e8206a226614759923f2e181be3597caf2102a3c8851d424059106dc190814283cc80a930a31a22780407e448db4dbcb0e4c81411e2ea5d9a803a4ef09033e05148d219b23c4cf0c27aa41498aa840864e35b1e302200f21831e62494d47049184ccb06108acc3565c2ea7f8a8d48c02aa608020ec089902af2e4d320171b1e6124d4f9fb06ce2bae0809045abeae6ce6c9a2fcc16ea0b4d984b4d52a5fa6c6cf41011e48aee81b1188428b4d9910a048544139a542a8149b80507188a0007a9862cf3ac29a5a6e901195f67403e953d49559c8bb7c4a52e09414520e08b5a2538155b982c2d3d3622ada5d95201a6112749588cb8595dcd79f3539ff1e2d264813c46438c8b48983066e973144558a077020fa1014c7081291aa2a73bb0226869cf26396d6e7e14c05d82d2a84399f39a2087465e5d8c107014b6c0e90a51009e188d0d41ae34a889f3635010a9c459aa13f40163ada0080d9707050e260c073149d4b5c5532a4d82627cf54931a80137795a07617cccecb864a5666c872fd1c542013fb9a084140e3c0197780264a50f1e294fb4e45d18ce3907daf04d6c3f528df2c0574450187a8978290a93060ad5a92078334446969083c20f0a704299b9e900f1e9d10216760fccb44d42ad49e496d964699411ab0d0010a8d88100a7e000880b1a5a201892a00b87b203d6350e303df9770227f2b33e0c4e3c80cfb8220f5891f017c111a1b283081c84abb39acccd8601841c050d741cd198cbb008c871e8c8034f0e2e8861731f6a8b80eb0e20255fda68d21b804f439a5fe9c818981e50195783813267a89541e72e4d12d91c10b8493904f511f9d861a306c731b8e8d434707fb66482b4c3451a0f3f2a28fa6a00848c2d3e507c49e4082543224953a0312e4b5a05141860c2c4ce9459a7b14b555b95e21e1742f1117be1ca90f2c5b505fc1ae6819454e3e151270440995a044014b608a20a48d4e711031768a01ee8c085630dca968d4267e7822c1672c2c0fe91245dae78252aa29e39d03a8e9120e3c3a61a0cee4450914907015c7e12785962958861b082dddafaa4a686e2000b65d0f048a4c1845c1d2fbb3b82526568d4c2c6b438c815e1d51023a38054019562ac39a2f7ccc96d9929826386e0e85223d5858f00320a3d3891255097a1228c300ea318a00a12ca0d02995b95d802601a474620d8d2814159658659153958c2878a0d6d1229b00911182d6286202de872314782a00b130f6294082ae29150810bbbe3545993624d0a2f3548a60238d1d922818f181f5afc84bb173b30d861f2ce1879e0e844932e8cd6308297f065c9c096a20d8443646e8307911e905063a7678532c14cc282493f9a4c513405c21d9a8d107d198e0f880d06ada52282c54187087d88280a9804610497903d7468e021a480021d1f33c2c82893937286434de61be227d33d432097737d12a02fc5952379748fd458b892e85311303442c0b4546d22a10182234e5671c93c322b60ae142191e1d01a2c6098f074412284abc7253b4b3e8a2e0492847c40ce854385c028cc9f1e7c088426c8d889337968123d63984a9d41d40008a32fb40c18b2a9346b5c5c8d52584af020812554622e14ccd994c09714285aeef8b0e8e34f65e104578686de9887be3d6f50a5d1b19123c1060a2d1278b0f5c558f640004652c828b10027d4de0db4af20968529429ecc9192e64c06021670212a0294ac4da8c2c0644e0920064a821134cbad0e41a20c33543096f90884e8491b336e5e47be44d0e693b1c4850a411abce9e26291d8262605d4684ab4e044c696b3fd24e5820b88e10c6c429312850f9d4f3c42d8ab97960f1a1ac0cd9c1b1fce74ba8bdb7180d81ba9ba057416c8286a0043135f8d054d301961010c6ba420c932410ae7f341d29f2e241414a8a165cead05e30d6440032b76c2ce6cc8d1400b4d813e0f58dd71c009db0341063784677860a03a008cad4ad70d1a7b5dc144a40810f500aa2459578f4401c85e615e413e096c3819b0c0ccc596b86ee8858417740060e0925766495a526b92a9c0d38329792344782abcf5e1b0affef000b3074187132f385164244859b483888f53105d99006e005bd848c19063d090c69601ac06784021d2e9258d0e3e335c6e6cf1320017236099020803888c812f456f2f8ea8e85a6024abd463ee47a9ce0a1347358414123918c28526480812a0ba1e8a8e7c91b3409e01d880c5f0ca52c4a621d20a2113a382180a05b2550c459050a80028d9608734c022a5810b44272426207d3c0019ef0a11ef9482f3054893112f16a4400296e84be00382b501c67e582a03873c95a82d8c050a496af6cc6d0d4af6596135038c024b0c2d41c6c928f4556241aa4fa2cd8a396b9fd56dd2d22d02a240203e4ca12ba1f1a013624c86932a5b783e300c91f0e15e14688fc8169c1b5abceacc6988961a281874270a8daf0c624522a4716420700a52926709e74e15357e433095971815503e487518000a1c48716371bc3e28f2216a7071738410a906a874a980494c0913524c942cf082d433aaee0cd02605a9885589a0451e4bdf43950f3cb23a38e8a2e3478cda440ad28724bf06a7168a07619ce2276e34bc71a1041dd124cc82468782ed0f537236d4bca318c8502541961698ae11934ae185dd5989f25a63f239c1202e6c4e80b5108ede60e58b26fc3e8c31e922214c103d82c0be2490db6a60841f2e6bfc3cd83377c587993c09104291ee3940c88a0e214e1820925ef4b9314186aa030a865288324c4ebe8ca5102c8859c8c1a7832006983c90ab0246900067c05016482c57c00d6210308c6882e7ea052353c71324f2fc0805a92c7de0be433c41e140c40aa2befa930b2e06c89891d64060ca4b3b63a17004010218002c7e306636ce1f1f708a941962808cec86263b0facd5c164a74271838d248a17ae234eea505d805a80dd84382758a32160598146a5f0606907de1831192e91156a608c8f957b97c40f45000065cd6ce144852d549244986a1163111154639de6b080b3fbd26185eb0632e7caf3d0054d53990999c6cad8c0c44e6c815d316000634044c3de72d2c0a624f284195acf191b044b23787889ea42634191462e4cc151e71c4d787046582601b2840c1d9a1b970cb864a8011697b632f02913f159b329458dbd15425618f2e4851b5ac2e4c3960c8ffc2c60c152a5b7326281faac39dc89352ecc13b777e40851d0ce8e2c676836a17193e54f902b1b3259eafa248188da48430c4a457e18aaf42a411253b3440304941c5459a61168128092854a5046a72d7872f640783297c0cc0d1c93eeba96463ee6985233de60e8232616838c2fcc499e5376be2270ed94ce99e593992109a2fa4ea956de2090ca00e1a53d6a9b143c8880cc07105a3ed9d861a8d18a1c7340e581408a450a4046922e24f481e2a5515a0d5212de3213d88e0b6e3c3a0500a2e3fbb3f7c0471f5601330c096439546802143e3db420d03b44982a93ba49c0604f0652a87c8a321c43ae1b887498f159c121e7cb412acb030671f292e0c1194ac595c0191f3839556082349048d6a180c480437a4a5414f2acc812c8112df094a7b629099d833963acf070552962657d453a150a025d1143462459011bc1664281b12a7394338a64ded2acfc20e32a24668a8b1d327f20a8021bc6402e5c1bee306954c90519d3851d25557e6c21f1d5860d1baf61273013cdaa8ea88d201aab690a2fdc681ab3330602d5a05365946c193027141f019f9a905a0126151b0348fabe8447a5214768f4f6be6ca5ea32a42625029c2c4048a45881e2b504001d8a14c4c1b14527f770c3401d4649fa0c7060a2449dd06b00bb48160c29e7d0204a7b22e642435f8407640238f3d6e0d29506b0a8479c9660414d281e95595264c57c2629004d510650f3c2300311a24f795ee0a819eb0126ce031b6235dc250e50124b320c256dd91a00918ba0103b61451d68617d8b36c928b430c05d6194581068e4460222b9060c5de993e62a6cd092126b1630b3f407afcb9b0ca2518960052a480459bd41481dcf99312530bd75a1ede8644502c802612146c100206c92a3b0178ba6ab2917b4864d5ce58d2c33c02404196229eb831a12514b200ec4882caf3c509377fa171abd111b40592419c5cd07842c72683a92512e4c9803b4a10f9c2a92caf4d86e045800e71e208c1d08e8343062d1030f21543b7940055120419fa2d7d39e3d1016300181f77902d3e108a2b8043675e050e6608d8ab816c82d0566fed4a28a7c4e70ed0994c6c9dba60098142152896d91d0000c475b230812f03ab5e26cf201d2892f83c860d879e57a30707821b25142e54a9c102e175e7e887b48a559f235face9f1cdd17271821ec98daebf3b19f43c45fa506c6c6a8c14f71a2b02880888814238059b86c614a75624a9d073b42a1ce02b98d68b3bf3e1db20f34909021f2005e05c3c9023c22a4124e5262a576688c9a8304947b461c6dedc8018708010f951438555c8467a44d1f2f4731b62801c5e02e879c3b72228ef58e082c563e6a9ae09b2b1b42d982f4cc1160eb8bc78c5466c4e03387be3b3632bd1f5e314e3d3a01d405d71460f1666e522133313567506e1e98e8dc7038f085c84002b4e01952311240e3242fb3a98b88692401395d8b44a91135e6662b51918a18d381bd0d625ca1b2809234c9908a3bbdcb07b150a8208a4440a834b8ad3c29e2b140508f20625d330051a223a79507b9e20c5a41aa7417a6f7c391da85247d6e94885d582f86a324143233144127f490951976c212a0a220783049ca550c436542eac489557831208008203492930794822f674a0d585c960845bc91e0b58194a7064b0850b2a6081225a941171e1c39e07007080344055d40541e46155a4030610446dbdc1ddb8e1c0a960510421396bd20f3801711a61bc6809b3b2b212ae61a45062c85afc0c6a182e61329b4088080b539447616603431f1204345f1c516c8ba209944b494e7f74fb31cad5d09249710440dea3061e477b05f7f44d469f20276a684ab46a8077d8eccb11e82c6e0fd197b208d9406ca162decead05b487c89a8c305660655116bef756106e43c3f0d847d5d09c000a05b9d15308f97213c75e8e1986c1e81441043a2edcda237be1a72dead31e72465931379983e1571c0a784d7962faf06c896b457ae28a1c99b3300c2220511aad0f5276095092c6342ceca60d9f2b325a24c0218a44865e81a8412197fe49d5e4dfe97468a60b490036702509e2ef225b150748251e21e1066f28b8005246131071349a121434e8a8c39b2b34873a3ec04f07270aa0d14180f2c9849b8d825088cb2d89c290052410b7a086ab404121716cb2e98e768e4880218411534f43970d58100d0d5e44a9d5da61509e48582402cc1c34b9cb0365562c87cb9e0e27960860f1777803404b7ec601a63e950a40e2c6e6ced31ea71a3eb6bf56207c98f223e47170b2c40484ba2b008072821138088153a4ca04181c284111512663404b038409097468a18cd28132323e9c11533b71ea21f5862c2ec81332810990610828829a053c2654f14395319860039b455f6e54e490602dee2440026ceda80bdc0d0030ca65a28727087c21166815ec3919e2b304fa5eee013140f2c22a41542090b3858649b6c9c28f4a68c93933c7d02a571204c112e360b90773e3da88b23e7d1ef668bd881cd2a8ce8a921daa0810c04a00273cc18b23549c70771feb4a1589401fdd8f98ac2d5f6c70cadee0e5201764a3b7754e0cabe0c99655e1a05886120e340398a8e162f63477c400822e3dda591f240451b4e461a6c1d4a55cca1b8b3824465dc1a54d7c6edebed1497b33218012306607d91c854615184471e143c60010fa8e391c822445e340dda325ec0b0c7c24a8b3bf5b2081ede1aa0571eb53475693f90a17238c954478496aa0870a92b62f8269d208091a82f699c2490b78057461839a2c4cc1905c4f4084bc97cbcda803c49132a5fc090a3c5c61a1cb00f6251bcb81965a341a707c6ec41b487788541f0ca1027a5dedceca48c99812107a4f9aceb4e037b7024c020e30180368d0c1770080883a0c20261c0a852de4a2140b6064d86613036f48b107708c084ccc5034c36852dea32810255263b5884b06668ee364316b9b01733507d515302af4e1aa323bf3c0b4f021a080c88bb0b1391a66fae0c025b5a3c1efc09c07da083833d0d32157aa382e90b13087642dc31c3e7411cb92f7b8607fc38b6ec8140a114e540240643dc0d3768747411f180851d2a619480a1d1c2490ab93f2a2e0c00214d4d082e0256b46d6af3084c8f489de6cae23308368312001aea2982661864885c92d66835a8a22287221d8e7c34ea435107cc8a96054e465490b1a24c0a0de5900069c87eec51d1661019d68beda1830d064264702965081ac436268ba56125b98f093c02b006a148902804409109afa343205e30213536880029888ac8d9500c72c88f83b47db9806704b064e75565c2a72f8f32e8a8c3f605a48a102d1baa9898924ca6ac0cd4783266c10ed14daf879dbf608d01210c3118b525854a8f344c5b613b307482e052103d71bc4eed80d457471932e0c901760b98354c1170384a74680e1c3786cc107bf05991a0cb9650c1a50b86a0105029cd5c2181eb0b96579f92482892d811963722bcd8875410113bf4400072ce986031e48b5c83039254a011c4232a0b1b0792b86bf27c72835bb814ba46b1212289d8098827d529821024db18313752a63136342f36f88c1488090a01109c530cf23440294bc6236c517a5c9931d065035209335e61540290c1ba32d89303eb2e61543a76356d4db8ad6ac26dd5ba0b947ef461a59fe743295daa55a19a0ad1b4b4af57cc8bc7a232f9d9cc32c149a67afdcb3389c9241b935cf47e7ae8709e6b77cabb33c77d52aff6aa9d88d4eecb8581d574294942efbf8dc68b29fe27b17a22eeb66a5d5b1ff7eee4b036de44fc2b897491da9e168484a6e34a6131e9873ff77a4565723854f16e23a418777a7977b5b1a8fcc9decdaedecd07bd9b5cbd77f391a9130f59a495f799213feb9fc6879ec4fc9ecf4e1f7cb4e851a24781649c1cce1ebd09127cf4e4118e33f727dab9a6fc39edf93ef1c48b7c680cf70f6caa96c151ad9e1a369ce9a9f759219af66be5c7d38cc963f1b6916e24e8d6d64c158d3acde14a738e6d6d4d5d971f943f0e1f2a7f92cf1f713ff3f9e3870e7cfea8aecb0e7cfec8c8aef7ff952496b9cf6f1be9d6e7e31641585465f46bb85268f44145422186fc1b8d46cf626ded86c3bf0be5ad54ca0c0625aabb5e8f11051a2a7f5e1cd23f89abd15f0f511bbccfc7fd6f0ff13e445987e80e19c293a51b5a508881aaaaaa2a20f0f7334d060e80118006f0a84ac2a3eaed4ac3696285ea11fcc2c3ca6a01d605453daab4a455600bba8cb932c2a3ea2dc197d618841f3c12b8a87a012c53905f2dc82291055f6901397835e291f58647578c1e095ea0000f2480c4c32ad843cc108f05390503782480d0e087c5c14acd0a0a112f055f01f8a842c2c3c104071380695b6a5910b652f9b0da90055b7d003a0076c802c52355bbd2ba22c303a8e04aac0a4d410a34ab1654a16991b0da80e5e24aec4aeb8ac682ae055d092024f8c272013ce5e34a0c88c687951e1e1668541dcfa105b2aab5050eaeb6aa4c601a90ad2a6e01d8d50f8b0556042c382baf06e69502a055d5022010f8036201b38009b4c6aa805875585c0ee2b4b6b0aeb04c2056155ba55665668501c77a6449b01ac3a301991e5b575511b2da7c5439f2416178f654a82c25422428d01e3d4bbcb9264ce411203cbc3792d326350c41075958305ea8804bf5a7d020407f242c41a74809d103707408501e3a6ece8051135e0060992fc195a13c7562b440a104d8ecd03123c68b162ae04a90905006f625274e8a336674e418928ddd48090d1c3150e3c823152a5110c48001f6b575280f9e3a74dcb449b3444991e10c172c54c0b901fa83c7cf9c29261629029427013a067ce97224c80f4f9d0e2d40c700390400e1f16b37798b41274a931ced49200e9c35033449f2ebe18c183058b8c91cd6326c3100f467cf952a4d80fc7ac609371232874e6912a03f0ae08903674d9a019c280122e3849b070e6b2f9b66e0daaaeaa9284d6240813d7812880327cd004e9a28490224d250460c106a4253a5de503868d0688c0992232d58a05b921ce9e32b93201510d5ef9455a95f045963aac4fc06a80263aabfb40a35850ad2801b80e79784df9819014b0c186642a80233bf123ce0e20206ab1c2c68106420b6204cc198d65602acac2bacdfd5959515d0ec574022e08195e06a0c0bb6d202922da0ebf1e15785967576a59505572d7060562db81a56ed011900b7aa10fd0880c755831f56822a340664b0191e5a760bea2ab4063d7e6c04abba2af3aa831d1e1ededab67efcaab4aade3288e2f1a88759b5c1100f0d817a98566b5b1242f4f8558901d392e6840f561b16e0717525210e889783114180257a0ce1119680c582ae055d36487825b3702d087874c81394785bd3e32a021e774b825809800cacf2aa8a20e99155d5e08acc74b0f6b0b4452b83212059a3a434f829b00ab1851557a1f830f0f05843d3e381d5991609ad0b5731aa3460c53ef008592b2080123eacaa2cd1fa0aa24018d06f46eef050b0b4abfc60a03a30ebc8801cb0c2dc1e5a58f195565603e0eb560248a645e24aab0185363cb4b0dc18cc6599882093d04a6062c15cdda1001e605568635d575a576b0f185c69299029ccf8c2432bcb44d94cf6cb72a1c00a18b432af565c695971b8d2f061848265020c5926aeb4b0c218b42530ab824b00d6357641ec4b4316da0b0cca05e2f1cb22035eb8d2ca1262ad0cd6d72d0e6b41159698d51ad04db0a00ac319022b019656959a158a2a388469150138c1ea0b4d904503639903842cadaf046f8f052c104e019b7556655665762586878606556d561bacca1298558d394881643e7808d54ca00d4cab025adda030e309038d6ee41933810e4073464c17233b72f0e179f6a7ef66c478d1c2ae6e2eeeed848935783dbb60a1c259852781549c345902f1c10205b130ac2c7efa80f9b24206b146e6b540c1d51d3970ca8401d3858b962c57eace30a809ab04403797ca14a8f905a74d7486f796932545fb03072dac304d98bc0912211a20cc5aec827529d0cac21a8be0a64d0c437cf0dc41a04e9b25499018f9b50ab8136e24e43536cdc0b5d5804195004a8a0ce17ad4ce396346cc0e1676af0ba1ab4a50a04f761f3cb809b0aed2088143c016009e1cb98145000196a880fbc001c302b3545504bf51559dce4dbf4b55967e90ac1e998a7e877e86122cb0a0d04fd00fd04fce2f0df0cc2faf8a8669664ac822b31a6310f603fb79995d630facb87e5b66b0aac14f8195d62f4156d60f0bcbea5765024df3aa6b75313f4070a510595426afc6fa800af64173d6c8e56d9f69e79d0c773dd154187745e35a8e2c0ef98ab5570e95393e3cde4afba783cf1f7f2f501b5984f3701bd28a2651880ae7b078aef4493918500cf3f9e19481c2b097731c054a75e271d7b18e58fd87aaaa5779303b5616b3b6da32b1ba03d3eacb6c6066a9556f0742a92ac3fa65655d01ad3ad84fd87ffda7c05c5105c2ec581cac3a10b8a03bb832bb0906b4b2627f0a7edd344de0cf846962993fd3045ed9f8993f13ebf725679a572656ff990c84c0dfd5d599d66956fd7e554cccaa2a2d33d4cf4cd0adcc9ff5334d93c6cf347f5975bf083ff37755f53333fdccdf0a13cc3481bfacba5f03d30456014df3679a573f93cd0a88d5c02b0b685e317fe655d50f38347f5559a69980fd2d303f64995666400f26d6ef579502b57e3f338303d7bc51952a2051a5e2d7ad4454f59f17b30a785665f53381dd2a8a19c9ecbf1e0c06bbd9cd2af3676e32b37e1a4cf367f5fb014d7335d5cc2c73c1eff7fb5db19966e6eff7abfa992810cd341584655d30197089fda49856bf30b3ca049afd17f73bb5ccaafe2b5ef5f3ce4c02ec1310307b083c3fa079655661990c4ce094df2f0bb632e1ab5fd5f95b90e002b04a0bad4a25a0e64feb2aebb766fe7e8b805766825f1550cfa4f05b9a2630cd4ca0e067666199bf10bfb21f1970acaa03bbe9c0bcfafd4c06554160d52fecf7fb995766956d263033155805b04abfeaccdaff136577b57d0bbf6bbbfe9a66eb8f27d7b0fbfa5aa5bf9f3f1dfb6fcbb3faaa2ffae7d75e637a55ff976defe19a76e355fdb5bc7e77a5d9d74ee7d8bf755dd3f2faae71eb536faf6accbe703dcbe9eb5f7b6d53dfd2e8fbb6b597d9788e679f7af4a7ed57d9fa4e76513475e137456dfb6dd3991eca735dc3ec1cc3afbbdae967e919b2fb5798b6693b6ddf7576575a865cb3f4cb7a34b56d1fcfb64ac790633745ed798ed9f6dbee9bd230645bb553155dd3f9b32d1bdbf30b79453dacd6f54aabb51bbbf5ec42a66738f6b5eab26bdcce2d3db7903d5ab32abcc66f4cff5ffb99858cb2eef7ffa7efeaaa2edbce76b23dc3b06bbf9e4d5d0fd7ec5c27a3a97fe9954d6b77765f569de9e4989e55b54d55fbbbaaedd67e4eae539a76e754f5f6eaaaacebe564745ddd38fd73fcd9d4a559bf42a6ebdfd6e85cbb6bcbb63ff57172bdd22b8dda6f6ad36f6bd7b10af95d5b1a46dbdfd66c1cbf750c27ab68bdb2bf8655f6a7360dc729e499a5fddcb6746db7aeedbaf19b0cabe95cc7ae3bcf6c9cd66d8c424ed5d4ae55d5aed3754d3f1b9f90d518ae611bfdb11abfb6cbc66e321ab3eccbda2c4dd3739caeb189d4bba8fbd357ad6d182e21a3703cc3ff75e99886d5f68549c83f46ed1a9ebfedff9aa22b2ccbabcbcea8676bd5d7703aa3709bbcae1fa6674fa3ea4761db7ed964d745d5d99e57946dd314f6ef085975e11476d7da7dd3b7a5db5784fc6d7a9e5915763f4cbbb3ed8690db184dd9397ddb9a56eddabb2064b8feee8cd2bea55f745d61f7831cbf9f5d63dbff5faf30ddba1ee4b9fdeaaaa66c1aafec1aa36e079956df945551b5667fbbbabfe520b7286dff9fda1e46614fd7ed9abcda35aafaf5fb786e7deadb584e6958fd2fbab628eabeecdbc2f24bb3edfbaeb46bb7a9edd9f69567fbcff5ea7d8baeadcab2ad2bc329daa2a9afe1b8467f8ab6ad3cd3353cc773cdbe350ca768cbca6dfa7ab5b6e1cfce2afc6b76955bffd1b57e57dfaef5ff33abca36abbadff628ecb2b65f5b369559f7b3afdabaae1dbf6fcab2a8fc613a8d6bf8a7e9fcceaecaaac934eda229ccb66f0ddbf69bb242398dd93a76ed3676bdaa7e944d93e796a667f84d51afd229fc5734195e511786bf4dfb759e55bf6e9061177ee33a5ee7b89dd1d65d35c8efbcd6f4cbfad77d67d7af6b06798ddf9fbe1e66d199a53fac9ec96e8bd63f8dd7b9b667d776550c72eaaaaeddaaed77ddf97d5df582fcc2b64bb3e85cb7aa05798d6b98addfefc2ecfadbda4ca65f3a5dd3f4f5e87fd3b7826cdb2c8db6f487db36765d9a82fcae9eb6d9d785d7f8fbfa9d20b72f3abfad8baab6f72d8aa6a7dca6f1db7ed6566bcf7ed79620cf709a7ad47d6db4a5e3992e936738fe9fa6d9b6addfd87b32d9b56bd656e7d6db2cfbd5784cfef51bdb360bd3aff77e7e23c835fcb236fd5777fe360abb28f14d5f33ba126624cce8deccf0376d87680af762d8261636068175c9c0cabebc72be7f763d08e352fa1cc7b0858705d55bcc818606650cd2e1c70b5b90e2630ad2e2f178d3675a2a85045958576456e9f013c7aa3400d59f59a12f30a385259379c4fd9e104258ff478facd2ca2247414fe00923119d8867ff9a9e61bc70d182855d1ddd9cdc8a381570297a37519827dc20b529304729f87951b957fbaf9c5977a9ea0dd78649dcc49e89e296891619ceb513ed5c3b2b41a9c34bfadbe1c5a408bc98f4784863f25824812989d3eddd6c789f11a9e2d7770a8fd7b43c27cb464fdf6f48b7b9bebc685777c3296b3f0279176b3f824d0e27e6cae208fbbe9571b51ff18d3e9ffbca65be2461347ab6bebc3824e2de8489a377f346efa68dbede4dbedecd3dbd2babfc469e5ef9bd526edbb66ddb9665599665599665d7755dd7755dd75555555555555555d3344dd3344dd3145551155551155551155551155551358ee3388ee3388e61188661188661f87ddff77ddff77d5dd7755dd7755db76ddbb66ddbb66d59966559966559765dd7755dd7755d55555555555555354dd3344dd31445511445511445d3388ee3388ee33886611886611886e1f77ddff77ddff7755dd7755dd775ddb66ddbb66ddbb665599665599665d9755dd7755dd77555555555555555d5344dd3344dd3144d63f8755b7655d3a35b77b1b526f789b90aa3ff73ca3819f20bb7b9619bdca6820d4e1ecaa990939387f25b5d9b8a14c316225278bca6bf12af7feef17cf25626dff43e1ef2367ec0f37432f2e7dd74f0f2c3f1e76e1de86f87e3ddc6daed238b7848996d0bae90e1ac9bfdfc4a7fd7bb3934678479cffae6218efb24aca67ddadb39d2238bc7a292c68bf511f77be76da2775346efddf4b96fc38779f78713ad83cf7d6d8722e953fcafa41be186e149dce7bead4df66eaefd650d9f5461b28d608542e116bbb5723241981f4c0f260773ad76fbc93ebabe8f821e267175dd5a356cad67198442e1d9d97bafebfd37d765b9aead3452ef66bb856a52811af3e20cabe91077d5b4b4e4965aa4deebeacf5724315c5bab3f5fd13e95b76d0e9338dbbbb9aa3b20f5f91424939e2c3bc8dc90d0814cbeeed0d34349810a4c32ec18b1b602e923119c1d0c34449854b584898e437492c6022915e9d82246c589103022e938364221a63f01ea78277520d297567400c74ec55444a1c9f1078a9e181990bce598b27785668207ad1cb493bc03c4a470c8a11647c666e269140e520cecdee0a0f2e0b8a335060f021a601c4cb28ae401a28b00870b302348401802010eb3207f04b07135bcd1294f419a52f0db0d386d8e7e6c4842e2461060a55f110f836ec401cad4ae49597443ac923c41948b19362805a98a805662878d34af8ba382f1dbb871c4c81d5ce6b6412201071e692c90d8d8ca62ca364226d9c788cda3b5672345df1726583838d1e3a14fc9e04d2d4c96b4af43a4073bf2d5471f5684117d624060f20dc2d1264fccc0e3bbf284881a31a8173ebc01d632d07d7ac3a73aa06742d00ea93d546e21584b02c4d8d3b34605014d3ad0ec3d99bbaccc512fec0d817469a57e24f7ce00e91d51b3f242ef53a20d5b90e4f0d2a353c7110d1b3e8e5e113c4a9bf4c0a9e9d1cd95b5c8f20189de39424799375486969880a7227529e069b906102ab8bdac03963cbe7c054e8e78cb135c0a398a3ba360e9a5a2d10e9c4e871cd28234aa9d54743ea6440f4c82a608902f07fda9cb6d40c8452c6b3482404f57ae80d318002cbe08c10db59034a64fae0ad7f2a80d853c7920dc18c09c2a255d0fdc8d840682a1e707ffc125c1710c1528fd9cb8912982748c520a724f1128a08a28673a585ad82028a44c43a5ac82c5d35c0d51a8ec7c8525615403019565c0c621493594b48173aa898bbc1a2d9ca8a522baec6a540863a14e6fb495e484df5558280d240bc870c10b013174492067a6362b44d89271c93004e4f0d01363c73dc90a007e8e5f7d6e3439e41a665c1e6e1b73169bab1f506e39c29a863c2b7a773012944d7272a02117554dc811817784f462c59294523d76206b9c9073640a8f0a928398b2354db9047935218d1d2376161c05258f56e8bee2389154e9680f3066cf0815998eea04bbb52a7805e3a95f0526a3debcc63c788c4e98c00900ce23c828638d0c04942cf061c480800e57818736efd38fcf8cbbd69067401e91ba1da99a17276f6e6f0aa8333b348fc6a54c261c2489160d359cd8b4b74b168d1d944e132eae701a6e34ba8a6646e8b15b507c44778498a5cd5051cce988819f354fc5dc12844387e617c5106f1e91210377a6a85507cf46991369880be0052935678117442d12049851b59920e611db4c59680a4039443489106291b5f700af4f83324f60cc32e101508380179ac88ae079504ace543851080f0d4e0e4a566d426c084a49c144e30a6cdb991d6d8a8386949d8446aa49c31e4b6c1644fab421e0cf029b022143a39628f0f0374930e0850e3effdf847daf94d4a5ffa3049020a83c9a3e1c2242707478d787506689886d095b2d698ea847ee02b73e03800b5bce23bbba4fee9243d5f0d56d7510ad15958188854ef4c8aec58810a8e82e6af84854c153e9e49227796782d4a1d776c8c994b600a2add4302fa64b5ee64073150a65a928f542f35f43890a903ec09cfa527a088952c32ef078d6d8d096c430e49be869e780c8c1e76380f217ec14b2709b42e0ee81560f880b29bfbb397743e0c8088760487327e7c5ee0816395077640bb090f9b8716068a991a3bc04434f4335609438ada9c130d481840b041999944313491f7d93e4c018ce7064a2eecb128b1d3306b812c35700579f19b9555ddadd22433342cc4890e57815c973c928c48305cc466c29238b4d264d86993b326878786422caa4a30c96858cce27390805de174301476298b8e460c488b2c3441c118b70c4f06a96287fdcd0181b52c0800018e3529bd3038c3a564eccdda92405069234b60238682181610783c20b4d8a662b186902bc70e315e1c561a6e3850ff5458a17605b34dde9ca02c2452417665cf0b960abe3a241db02510b2e2dee16715e8baa146bf0550627168190b0a0f28845cd83056a17815d0227d01278a0a0b26b620783cbce421f541e5a440dea3c25f9d41b1e80a88b5327448e13a33b085bea562cfaf4a586c4a53aba4a8c202049818a4147805b190b5010c8419783ae04f1089bf8cd021d179c0432f224cbe61a41b09c11a9a1e7c0a898c317cc7d3083c4cc03becc5c96991c2132392c72453956aeafd8636305143d2bee8e2b34c030db58d5dd880b1577409c91615c5ddc042a2a32a968f3a5a2878a37157091e0c82c80dbf30037a2866390e2508a2d299029e0502980cae210db37790344b6f492b412e16dca1bfda68682148a3b0f50301900c50b1128ccfe9ce87402ce89202756446890808e3a80136e9470b73431dc70b891707b33c1a8cfc4176f4269c984072f26b04a0c2a214009a2a4122b095424f490780246624822032619947c805ce427d3b5f2794403dad9af491ba636366d3cda50b4b141621bc3a6c726826dc1084323b68c388a41d9d27b1ff19ad0bbd47b1ff1cb323c7bef22fcf8f922a41c022282e60a244208844788513442204024c49210215c843003d1a9c7582aed25329f97bd537fd403f5033a9a9e8549e7d193fdaec7f5101ded670ff6de1df4069d415fd01574ad043dab63f5ab6ed5ab3ab0ffbad9fb8ff84bf0039aa9cc08cc32ddf4d2cd2c5b1298f8affc39f829f8fd4a99a2b6ca18755c29341a97c8b23b656b7aef775b65507a99de5619b1affd645f5ed6b655b6a696a1f5de339c6b6868675b6509ca3af2b834def4797e6471497f25ee8fc79b2e7a65eef16ea572897fe46dcc60238b696a1b4ee57dc279b833bff1cece9f179145fbc47f7e2f6b9cbeefe7652091a2e832461a8aa2e832c6d969bc7fd2d3f8bfa3904306daddda1dfd69ccf789c4959e840a39cb011990df38dcfbc8b3a1d213e9215e14dac6ffe04a82d8015b6220cc14eddd54ebdd149a695c5b61343aae14de451b594cb3914578890a4f34e4ddaffa5658bfcbcab4056147fff59baabf56fee312f993fef8e99feccbf73eb2885c6e818dea5b608cfaddb90526e7eecc91c53b4beffdee547ebc9f238b5b604bb6c084dcddf9de4d0ca685b9144cb6be40295f6c7d2189b94faaf5e5b8dc79c4fbf849cc7dd2245b5bebdd1cf3aab7baec5450bec999d0adf46c752dd87ac0b7c505616beb4717a210d668c16962c321c7072945de75f9117c800007a59d157a99c603548b14714445120448e0c79c3c56444cfc993be0861a451084a110e4a6c6aa239602bd15800c374675750033234927a01163820d31f826a84510448350fae0c20a524e210a68eec490e809b3d441cba91869392270a02a85cd045288ae37a7e06ab739a866166e1739063d7af0c92944716ba87e04be513ff24301d86242e64f6a9a48c9da00ea804174483478f08255648891f311b29381d7404c823875901422072431b91b606b929c728296b94d840c30be604b66831f5798e25a40552cbce09c698b400eef0320380e3e03844b666bb610488f084d2a88bb28a126a59ad12942a00e3d4214fb1a48d539712ac4878fd8570814cf869367d30fc00512311db6dcd8eaf32948263d583c618204c903dd29b83d633724742093af63638066a938c249f9971e4a0a5460722649ce0fcf54143a641ab8d656207d2482a3624f1521b49854278890698830a96a09931d61461db262e0b73100a3933416489928159c3b325569305939c42546c58910302051f1953a01eb10c9d147d6088598fee4b704a8200c8b15065194804dea40a42fab78b19205e90dc72131881e8c9d8aa9883ae3060d961817295c9c1e9441d1132303923717615d4419cd3241900061ef0acd040f091e418a4ba013199147610f9ce41d20268583580a45efa713842ad9901047c666e2699486af0c9fca18907048431803bb3738283c44b6e29c51d2b1c3115d97d6183c0868808d8a4c9d6ea6d86f6cc1ac227980e848753a838aa1f5654aba61604690803004821494c210b011634ca5395d41fe0860e36a461737250045f9e2944981609e8234a560146d485d8110c34787d302626d8e7e6c48227b5292fc8d92a4aa44c10b58e957c48320250a92949d38942a135c1050a6764d8a2244093ca459a08f4a11056295e409a25cccb8b054f3c1e92c54182eaf205511d04ae808a2010991ce9ca802c26cbd2e8e0ac6ffd67938a93820e5e7221c31720797411ab0490f7b16b6e427e12b01071e692c8ef079204660ae84972a6f5b594cd946c8dc8660f8a20323101c1ec6d83c5a7b36de8c6c00d4604717569af08b09160e4ef478e06007e2439fa0d51c03b818bca985c9829a6a4bf5930b04d553c6223dd891af3d9e6899b2e50d920aac17601146f489018139c25219382e969446135c38dae4891978c4025828c70a38b3cb42f684881a31a8971c069db108ea28325bc10658cb40f7c90d13b78f464f95ae0610e07240cf84a01d5221d6dc1c90054730ceafcc2d046b490018544421c1c343b3d4e40a84352a0868d271c6cc904b104d1534e53a1ecc5d56e6a8172c84a910c0ee470526b504205d5aa91f490e300800a093a0413cb44000a47744cd8a8b3d5f677c0780591480d883441bb620c9d19585012179ba1037135e12ea38a261c3c309e054971a012497212884e151daa4074e18a9fea1c4ebc29d15ae6baeac45960f472ec5153fecc9b94b6a0447e828f386cad01c3ee4a3894800841231e0a9485d0a740a12c40bb28c9bf5d174014205b79775000d412b2cb098712cbb10fcf2153839da71148159c195a6d3a44c625c0a398a3ba38547831738202a2c1522e3a5a2d10e9c0e074171dc2881b88446765b0bd2a87652d10dd412000568c95b1aae08257a60123445801c611de05022a00bee87d7a03f75b90d0875171a0588123d2feed6b2462308f43cf8c1f662cb4534035393089cc60060f12588008332b0314b528bf1f1d542d2983eb9aa1d0d86dc21f38089c26feb511b0a79f240df4b5c44838aee923916c09c2a251d8f2d5a422d2d9da2fb52fc8a840682a1e707ce92a826426ab637745c7049701c432d2f428660046863e5891ed9891b992248c56c495259909aa5bd990386dc53040a28223d3e95e1f2e2070b3ca8b8e8606961838050950c2cd844fa91c19292a15256c1e249aec9223a458a571ea16a0386cace575892456022a5d2320185d89ff1406519b071289226365452ace9e04546a9ac0d9c534d5ce475d5d9f172006d13001c2038514b4574d50dc000cb000b1616da4c3d0863a14e6fb4459706014a5c64c802ed9180df5558289786f8209445f6486d8d5e58860b5e088899c35285d1958eb70720b8d375666ab3426444a52f3701f824ed0c8141b1ba40396240657c6b94ee24c4376018027278e889a143ca853b5bdebc703282baac00e0e7f8c5878c04209b0462ec740213cc21d730e3ea508480a20c2d75c4038488cd596cae7e4071f063d19e1f0511ac965784350d7956f494802461b197d80c5a8291a06c929363c392056cb0c810c264025c84aa093922f08e50942082ca94168fd6cdcb8a2529a57aecb88dc7297bb6740d5ab64ec839328547c5422716659011d6ba1411c494ad694a255cc42c44724ba06c93a4af0969ec18b1a3808d19206cb002513a72696b8d9296c39ffbce912b32b0285ad101ce18dd571c27922a61c97aa2f461d2230204be0618b367848a4c7155963d438acc2845ae09766b55700a50806a9e709930dbe8c87e15988c7af3cec51256b44954258b1030b68110784825c0288d003009d88854691017133801c07904e1f004a3001a7ad8045992ad91818092053ebc0f34180c30e0c4611318023a5c051e5ab13f452441506061cf91073f3e33ee5ac30d44481524ee15c80465341838b5e34accf000343a0e41f0e1160642dd8e54cd8bb3c38f8b545c36cc42421eec4d017566a746a546579f067a4cbd41122cd411f2a5d3dbd99a4d0f4e24aae2290e4226130e9224011c0d2d1cdc5d38ea3078c0894d7bbb60e999f068418b4668004909944e132eae948900f579a444b846035c1890304236f296747df1c0a386011010f9d0553433428fdd82201054fd45aa0d59d420dd1162963643f89529dd441f0a9594889d8e18f859ebf4c6d4055bd1a3f7d0892e4b100e1d9a5fa401104482170f34321c826f1e91210367c60803812889e9d3a9c81eb13a7836ca9c40c3400ad7a1ed86985e032fbc20a5e62cf002c58b2ea78051ccdc41b425418019559b890e267e9cb2b24707f828c257e03db5c6202d0421b53b3a53ae56af4c59680a4039c402cf810b31f55115045b4408b1c8dae32223a72c636649d89526630dca3c8131c35426ce0d8e133a96cc3ebe6a10f042131911235f48a11ca628d9b45ba0949ca97082d016096907a8953963226a0c4e0e4a566d4102a591fc8479315843e7ab94144c34aebc89eaf8f050464c0d199f6b76b4290e1a52374c169519911769cac868a49a34ecb164433b01802c8a34ac390546a44f1b02fe2ca0c0c4d2183590e220708a8b90a1514b1474b8846b2a12630d006e5d26c180173af83caea94c182874158cac4108fb5e29294b4b3a1971804dcf47a1520f4a000982caa309bfb080112b330005f79421220447873fc854a34ecc130526590a03a1cc1211db12360a75b6ead8b2dc4880f3608ea847ee82960d9e88addf71f8064502002e6c398fea3829a80247c3c4141b43c2e42e3954cdde03f7991a9bb2f495c2d2f5b2e59fece0818104090c0b298473a5205a2b2a035180335cb8e0203bd4424559d823bb1623429ca234080b9aa92307e890d2a5868f4415bc1448981d2cd0db8fca155cf224ef4c903aae032a990b740ec11821b6434ea6b4e58f0126563ca8a13eb0e18a971ae6c574c9cbbf0233e280504a8a9c08869a1b723a81c40d92400c6086022d59112894a5a2d409adf9f1730d285795105e6b285101d20790d1624280eed3082f3f5b3280d808d487e4b81307d05e06738c56043d8444a96115983a9242e16951cbc0ded71a1bda921886e82369866078dd49436a4b4f3b07440e3e155b8e6c45da0ba4e46e0c2f22e453ea130157c6a80844670d98f965a79085db949d502738e10cec0c644cae560f880b293f190b2089a1f566821d1e1905166b679eaecc9c4890127340cb4201181c19e1100c69223c8045486195e1a8039717bb2358e4407dc120e008dc121d6f28d9022c643e6e347572e2463eb103edb304d6c8515e8261a70396431a5a52b92825e10118254e6b6a3074199436594a7543edad0c0917083232d50840cd108a057c46a1280321e9a36f929c1790e830b025c9252d018b07495a611c0067c45251823bc08791a3230926eabe2cb1d0d1840a7212decb162955d89518be02b8f88029f3409c9c132b6ca67459d5a5dd2d3224c10018f872c497a832c1aa36b31438c6bc4d71cba0a18aecc4535896e35524cfd57561d13238ea5ed1a38b070b988d58ce2853a43b0c9e2011c1066d326932cc202089d3252b8706f0d0458979786422ca2423964a212278208caf62d6852ac5150371769556f889a2c401b1483f827c928350e07c6f44d46853b230c1c615732486894beec50144366b7147c010b1f3da61228e884537fc9c4c4ae15b341db9b6d42c51feb8a91d4a11624f0615158c2c23006129480af376c4cc9f0661746061dbf4058c71a9cde9a1c311440a0a40450990a72d2b27e6ee5492427379d0010a9f4c0bea8ca5b115c041ebc8200182a4c171c4800d405f46ac4051e3c0a501a597851e351066105c5939d85a98f2a18c23f5e02a5499087f4cd16c0523edca8f3575de28a060c6490730af082f0e331d3f51e65dd6a5236150ae3d13a450b2b4ca283f958e420c9d17c88e800915a647c510140e2e916ad8513904b645d39dae2c207640a0c0181b0c7c371e705d9a531413d6c71e667d8992c3a38751990835077a4bca24a72cf074c44d97fc0904d68297514a4f171e69bd3084f683c9f2410c4c99d2ce0ec8540979666b8ecb604359a92d3e132258325c26a15011a5828936087a14e1c9c26aa8d026ae0308313eb2bc0f084582796488a3228105a652c5a9a26628a18022a83e228137e40de11f45aa0c55989fc0a4b734b81c8962809b08ee284de94ab1065f656c6aa0c31e1f3cde52d983e0870ca1eca439e2c01e52b7204b9a2038083be580d3954b8e2231b2f3f66301994f6f5d0ae017c01cd871094d9524d150273b5c825a42bd796066cf1d80c385037c0754692366458e8b376b1ee4fc3c41c04b492755c1eb045a020f94538b0e0d406440c11a818fadac0b580605f97c919870a6d9b2a4549508213cf4f901b735c783e9a781aa30274ebcfaa0f2d0226a809eaaa2e00cd4b51cb195e4536f78f0218994331dc4420465fc8960690c21be32057058a08406419f4aa6727cc971627407418ba94c64739c78080280025b8b3e7da92161e914914952c2a4ef9805c69e9419795303571371a483f778800c912f461090a440c5b0e0c7d387c054d2e9c8e556c60214047064528001c89d3f0a3e19211b6166cb102cc23606bc68599344426e0f8c78844dfc66014869450a3d6c042d72c20527818c3c49322b6ef20f6b1b1ab88d20836039235233436951c0a90c0ce41801041b25e3529918708d1ee439150742cd027a9006e6008b1c0a26392094ce7d0d2090a8cc0c12330f783259c2565cbab28491710984235ce89cc1555053228703f6c5ad93f2c196067e0188c6961865783241b03e299190e72041061779503c8a52ecca5af066521805e5118e9938018fbd216c31973c645d11941820f49467cd0f9ab1cdd3069e14fc52c0a7451da39a56914e1bae36dcb50993e3684c9db66f52a30178b4191ae3a7539794303b56431e4c2736f597ab82020c413e485b08d419e3dc667d462d52d14182180cb38d559d8d0474682901ca09843bd5cb2b8051556df33ba5c7950c1165c2ea0419f07ae25e89302cc35a81e1cd31c38a99e2b4a253a919a96e08411e49a496e3f49262611106b51dea1eb8c5fde80105786cc96e2205a13325d4114f990b299664d911b6d009b4402a1814dc3c40321449077ee82b421f305b54bcd860d56bc65cfa19fab6ce18d2d4a06b4b06961f08c82900d31028636f471eb815c0669e3268509e258dbcc0f9e2b26559084a930865964b230ee6460fd7580f518dd8c0b8b168a261ce99233cf158044524516205619044d88bd2403564277911bf93bf4e97c006e4f9b75ea53dddb2ab8daaf17c49666b54f574eded97653f9dc296e4375dd5b6a5ed564de3f94dd34a32ebc62f4afbb9756dd5ae614af26cbf6cabc628eaebd59d5794f8a6c33e65fea6499fa21eb2ea0f0d7092fcc2734ba7ab0bc3331bbb764d7c53e40dab299b192a7f6372496716f766f60528498ed1f7ff768d59964de3f8d72930120cafa9eaae28bba628daaa6decbe705bc3ac8ac2b5da022145003e0a033a62a011a345404589862710d1a12104a0a1058613808586138084861b808304e12730500420a0e118f08f9f31601f3e5e4005f62c00ea916d38455fba9d69f7756796ade301807964b44d5197a6e37665dbb5855b3cf2afd7d955df1865d1341d2620bfab0baf73fcdaa99dc669bade91d93985dbf865fffff5ebff8ca64304e4794e6dda8d5bdb7d617b65fd9ada91bda7eb0fd7b0dac26cebe1e11a601df9fd281bb3764a7f7b4ee3b97edf000f9051f58ddd1a46eb597dd1394d492055a8b10af762f8e303a423bf711bab6f0cc7f6bbae369b1a20b7685ab3f36aab31ccaa3fade7c86bccb6f63ac7a8edaef367e161edc200ca9161f765fff72eabce6a3ddb9ff8a6ac0b601cd986fd1bafe9a75f3a85e1d755e1c870cb7e7ba5ed368ed318b655780ab00019fe701da3ab3bc3f00aa76dfabe91fdfbc6f3fa7adaff799dbd97037423fbfa9d6975f568bd7a7b9ded763d00d846aee714a66d549de75fcf2afd6b201b99ae51156ed9f77dd1cfb6e94a7cd3364e28dc025c8303a84666d9f9f5f38baa745c7f7a6e8104c436ddc26cfbcef447d3fa7bb817c31b9846b667fac7adcaaedfc3291dd76674255ab4702f8643201af9bfef57d7d7add51a6d6736fd368ab8dace009e91d3379ddd959debd5b55d3465ef7b3623d7e95bcf6eec7f4d7bf745816564b77e5d357553b55653cf7a380e908c4cfbd8a6e93665e9f6afafafdd00c7c8690cafbeb5d73465ff8aa24331b2aaaa74bbbe6eeaa2294cab339edfb46a0307906336ae5b974eebfabbb5eda66d1a46b659da55e3f97de1556d53b7351a3dadaa4e8060e4145dfddbdaab4da3ea5cab2cf14ddf24c02fb25da3ea6cbf2b8ada7ea5e799f8a6b78d2c7a595b15756d6fd72aedbfffc437ddf3ca16d8458e63bb653f5bd7f05f5f7856896f8aa66674255c571502e422d3ffade75fb7349aa62c5a7ff514708b5cc768dcfa9a46dd8fdab357e78442a1d04ded00b5c87efd7f8d3feb5df6c76fbac2648059e4f5db76fddaeb3acf76fc69144dc700b1c8705bafdf4ee774a5e71ab55da000f25bfbd94ed114a661d8b3714d7cd3373ec02b72bace71edaa280caf2babda30f14d5d2b358055e4d45d69157ee715666bd5865fb74de700039069186de3d45e6196ae69d5a53d314d3f8df4398e746bd3392015b565dd988563b56d635655df74756d155deb975dd7afd629fd02a7c8b4fbd670dda269dcaa29dbd2c4373dceb108b500a014398e5bfadbb047bfedfe755e896f3a2cd6b57fe51a0c1000d9c369bac6eecba6ef1aab2e3d4cdbd70c308a0cc7ebffad6fd3d666d7f7fd693a4c5b150f108a3cabea1bff16565196565bba1da668aa07f8444ed38fa6ac3aab36ece779b65b01804ee4d6f5718daa2e5c7b754dff8f87e9156013198e5d1446d5396659d7f6edec95399f6cc66666c666c66626824dd50099c8b1caa675fa61b4b5db5fd7f312397dd3348d5d167d7fea7ed62b91e7effad45dddd6a6ed74052671eb358eed76b6db3d201239555dd6d7ff7f3a56ebba858fc8a98f3fcab66c0dbfbe85632372eb6b775ee39a4ddf975e5b5706b088bcb671bdb23e4651b87561741ea6f9c7537a3aa1106ef179061291d139b567755dd53a66d737a6db1738449e69d4ae6b1875df977e53f613df94758142e476b669f4add9d86e5996ae7f10978ed11fa7df85dbb985896f4abba90b448ed797ad7f8bd268fbaef00aaf69db027fb436fdd2315abbed3adbb0ad07f491da710dffd8a3ac676b4fa451b8857b31e403f6a8d317fe289ad6efecb6765bb7702f8679401e724da32cccbe288dc2f18bda682a198ddbd4655fda453fec63d54525ff75a6dd1a56eb5fc7b48fdb53f247519476dfff6b777dd79826be691bff4cad331cafeffafa148de73836fe4ac9f6ec57d4bb713ac37e4557b88d405d591af628fad634fbbe69aab2ca3cf97fa4643aa6ed36a669f6b57d6ac7ea30fe7951c9a2cd8ff68afe46c92c9cd2a84bd33f8efd3b7f1ac44f94ecceeebcbe2e9aaeb4ebd2e94b7cd314c50f02b94e5d5a655f75ae53b445d154554ffc42c9e84fe39fce2e9bd26c3daf2cabf6f981925fdb665d3ab5e1f7d3be46eb4ff21bcfaa8bce6a9cda30ada2fe01778e5b14ad59746e634fb27fd9b57dd5768de17686d3b7938ca2ac5fdd96f52b6cc35ecd8b7b6cdf47f1a6b1891fa7b44655f6abb10ad32a1bcfeea6f655617aa6dfd6bbef1aa3b003323cb7714aa36f6bd770eceb56d38ada36ddfedafb9f49465f8fc671fcae36fad3d4a7985e1475d1975557967dd3974d5d157d59ffe7d6f5290ba7713c13df1459f4c7dc2e2a6b366d4046e76fdb68cda2aff72e8cc2f99fcb3fae5e92e3b44d67f7853decdaac675118cfcf92ecc6f4bbc26d3cafaaddc6ae4d7cd3b492ecba73cbb66ffb7ed5d36a8b2c1259954d29c9e8ecda30edba36fddf188edb25bf49f27f59749ddff4b553da9dd35b59b3667425cc92b7b24d284cdeca5a28c493771cff24c9ef9cce6eaadaab8aaeecfacec4378de9dedc95cc2f926cdb76edda2baab2a8dac2e8170a93fef842925dba65ddf5b557d7bdf9f2a5bade7cf992bdf37b24a3715dd3b09ddab347e9d5fb21caaa0bfc1cc92f8aba31eba2313dbfe83ab70cc8351dbbf05fe3575d558faeaa5098e3d7484659387d63f49ddf7a8669d425be699abe702f86c71f23796e55dbf5b19fd3148661ffd5157de15e0c8bbf45725bd7efcccefe5d6794465154286c5db817c3193f45f20bb7edfad6283dabaf3b7f3a91ecb6315bd7b1cb7eefff7f6144b25ac334fbbe6becfd8cceef7b48feb10dcf71ea3dccfaf7c32df14d8974ee9534ee95b9f2c687e9eae2674856d7d4abb08da6343dc3754c2f20b774dbae6eebbe68ed69ef63e29b0e8dbe38c7297e8564b7fd2e0cd3b45fe7759d5f42b20da329faa2b09fdbd9a65995f8a6433657deb89ac68364b84ddb9a855bba46d339feb620d946dff9f5739cc2b61abbee4a7c871fbf6f22adfe02cd6d4caf2b8bdaec57553fdb80d4f7755d967d63d49d7dbdfa3faffdbe685aa7a8b75db875fdc431fb616fd7b3bab634fd95c315e98bf53fa6697eeb15936d1f1fb76b1bb7e867e1d68edd9ae8b2347e7ce4747553746559fb7d5b9af631bc648f4be49a1f6d183f05e4b6a57f6db3769cc2706ac3f01e196561d66659d77de197a65d578f8cfe76a55b146d591445e735cd23a3280bd72a0ba73e7ddb7ac623a3a94f3ffad675add676cca22a9b801cd371cac6738cd6e89afe96be23cf2eedd7f58ddb79fd6ffb6104e4f7fd1e756b54fd7f46d5d98eacd66efba6afabbe29fca22a5b47ae6db7aed53456d5559d557f805c7fd4af5e6dd3d68edbb5457f74e4d555573ba6df7475ed165ee1113f03e415a65f1a55e9f9ad57dbb77e8e3cabaffd3fdc7ad8bb6d5bbf257e7264949e59b8f5a9a7d9daaee91495336333435798b199a171666c66a80a33363314ce8ccd0c4d61c66686be99b199a128cce2deccd0d4983c1687ca8f4416dd39bf38b2a77fbbbeed3aff344de33875336373d596cd0f8e5ca3ee0bb330ea57b665e9944d53571df32b404e55d5a3f4b7611b46dbffaa683c4c8ffcdec8688bd22a4ad7bf7d67dbb3ae919f1b19ae6db8f56dacd630bdd629dd464ed7d8756b15b5e9d5665b356623cf6becd62afcfa5aadd9d9bb6b641fbfb55bbbb4adaeedcad22b1dfa53a3ba6d9cc66b1bc3eefaae6d9bae6f4ab7b6cdbe6eecedd9d36acc778f100aebcf77cfb831792cb6567e04c86c8cb66dadaaf3dbfab9fd699be49746f6704ca7683dffda5d55daa368e4d7657f9dc63f7de9344d57575d972c92df19d96e63b86dd11fabdfab2fcdc26aaa0ef999916d989d5bd4765d36557f5bff32b26f5598566737a56114fd9e7597b44f51213f32f25fdf7576698fa25ea561a3d10f5fd58cae84d9d075e15e0cf97e63e4784559d67de9b4b563b48dd5017e6264566d55f5dbae4aa77e56d394f8a603b0f88591d3b5555b986e51d7c7a97f57e29bb25c7e6052d7ae5d9bad5bb5fe2a3c7ce9fcbec828cbba2b9b7eb5b5db3fc335f14deb616dbce9218cbb877e5e64f4d3b64bbfeef7e9fb69d713dfb4edf2eb22bbe9fa5fd8ad55dac7b05f57e29bba5e7e5c64ffc6eb0ac76b0cbb2eebe996f8a6eb96df967646e3d94661d466d99a6d896f9a77dfc4e137d6c521f25655b011f3220ba35184199b99199b59cef773e4cd66c66666c6666646f76626b368daa6707e5a647aa6513fb7ff753febda3fcfe76c875f1699555f96a5dfafd6de45699bc622a768ece19af6f4ea63556d6901647466eb157d51b66657d8ade72bf2f7318dc29e465db68dd1da5b91d198b63f4abba8cda2ff8ddd2a72ebdaab1bdbf67767efd3d40d407ed1d6c3708cba714b45f6f44bc3af3b7f34856bcfb253e4996d67d655d5ef59dbf6f12a4586edffaea9da7a785e5777550190e997add516b6e1776dd3d6a351dcd74e5514467f3ac768fdda4221eac2bd182a7f5050375e5b585d51b845d91765d1559d63359eebd846573a8653146f39ff36a1303fda4261ecc2bd18def83d91d5b665e3946dd70fb77fb5692732fbff9ab6ef6fbd5fdbd4db4d64bb5e55167d69f6a72c4ad32a871f13b9fe6e1dbf765dafa8773d5a2f91d73fa31f76e3356ee94fc74a643ba6d734465337f5ac7f93c8decf9e465bdb5d5fd7466124f2a7d59876bdedaa696cd3297d44b65dd7bb336ab7b41aa3703d1b91d79fbaeadbd62c5aa7f4878bc8aceb6bb6a5d7d8dbf5675b4f44ae57faf52d4afb19fdf39cc243e49fc6f13bc37e4d6314adbf1039855775a6e7d4b7ee67bd7783c82acba22a9ab2705da7ed4a0391d9d47bdad3abed6314b6df1fb25dfbcfd6ef9b7e14fea9dbfa90d91746bd5f3ffb531b4ded1eb28f5b1b4d53ffce6ababaffc743fee8bbdaedeabe350dc370fbf1569883994af66eeabe709aa2306cc729cda292630fdbb4adda2cfdce2bcbaea7648fa66b5cdb689bae2e5a7b53b21acf1e7e3dcdd63e86ddb694fcd6313dbbf09cfe765555558d407ed1d98ddb757653f47567352525bbae575b1656d5597d594fcc8b7b6e6af46baac21c25bbeefb6b9766e9afb668ddaaaa6ac71425d3ae6ac7bff5ad7761b7aedb341dc2312190e754b563ba7ed1d8bf6a8caa396e4642ce4ca8a6a88a86926d56ad63d785e15fcf2e3d839251f6b3f64cbf6a0c7f36466be36d0ffb94b99b50981773b73b47ba0985ca9f1787778e2c0a85f4d743d34ff2b7e99a4657358569b4fe694b7c53e2b046fae1f0ae53f5158144baa1ea0bf301b9fd1efd2b6abfb00bfff6fd9ee4effe184de7f58ded574d7d27199deb3465e9174dd935fd71cd494edb744dfdfcd17686e7587d37c9b64da728fcce360baff3fb5b076477f6dfaedf15a65d5aad5356933cfb35b56b96fdebfcb6eacf24c733ead6693bb3b53aaf33bc629255987e63f4b55916456b5b551b903fbca26c0d7bb87de3194ed14beafaba70daa6a89ac2e91bb7ecbb7e369efd87df588d5fd84e6de29beedd4abc21112f228b766a49865fd7d774adfaf9fd1ea6eb4a72bcd2f6fb59757ddd79f5b5a7247f97f6744c7f177ddf5665db4972edba316bd7706dd7af67ed94f8a6b19b2b6f9c6d479892e43945d3985ddb4fcfa9fb5b37921cb32b5bb72c3aabe8eceb9f429269d766edb86dd9b66e5d1b7e24a7705bbf70bddaedeadf584d1dc92ebcb61ef5749ad66c1da728f14dd9b44f992365a40a3336b31a594461c666c6662614be874c06e478b561d746e7d5557fda7abb91ccaef04bb3acaba233aba628cd4886eb54b5d3164569f46ddd3f2f92d1155d537bfedfa369bac2ab22d98d533b4dbd6dfb165de13625bee94f24d7fe6d535a7d555bb5e3d89d11c9f1aaae6babbab08daede5e5b2214f390aca669fd5dfbbbdf9e53df7e43b2add21f9ebd3aafbf66dd0f2f20a32cbaae74dc7ed4b369bdb685e4d94e67efb6f3cca6ebb7d994906ca728eadf3a5edf7786e37590ecd6706aab3ff6a867e7174597c912744ba3170a85c2f72f8d5eaf55deb98fdf26a620f9a7b13ac769fa6b1576dd19790ff76e251e6c4657c24c84199b19ddb7dbf37271fa06926d9585693b8659374de759fd80e41586d53a6ddd0fb331ebe3d48ccdac7633a37b33130a85693a4c69bc78645ddc5d5339e61fb98de79fc2ae9bbab15ba3df8fec631a6d57bfb6b3dac2bfaefbc8f55abfe887d7948ed9da4d633e725ccfee5ad3ab8bd22ccdaaa902726dc7b45bbb30eae9fadb34bd474e5bb5566156b5d399f6b13aeb91e31486517b8569fba3f3eb7d1ed94ee31766dbda7d6bafa6738c477ed1daa7ae1da72c9ab6734b2397abbac44c4086fdf7e99ac2691da7ab6bd3cb3bb2faebb89ed7977657344d631501d99e59b88ed537a5e1d76651637299bf76e415a55df88dd5f6fdab4fe93a726ddb31cdbafffd9fb5d903e4b445dbd97ee1ba8d6b16855d3af2fbd2aa9bbebf55d7f7cfdf13dfb41d621a20bbb0aa7eb5f6ff5d51fa8d5be2fbce9163f4af28edb6f14f571faf33f14dfb7e9edaf7f3d6a44fd1c39423c7f33ccfafbb7a56b5d33aaee3c82bdbce5e6d633865514fb3351cb9757d1dc7f44ab3760d7b142e404661355d61dbaed5da7687b827ba69fd3f3e7c5333ba1242e1afdbf78dfc57bfbeaf0babedfc63d44d896f6afc6a2aa2c69f8b7fadb6702f86b0e946feb13dc32fdad2b05f5b7aae896f5ae3e36d647b5d51d8a6e33a4d7ffddb97f8a6497f1cd6c8ffca261bd9bfe84f6d9a75d538b659b425be29f236def4708dbcfa79addb955de7189dd59825be69cb66aa61d5747d5db44d537685613665dd9886d9344de3f9b5d935a5e94f7cd361deffc9b7681220bba9ffaafa67dfc6aefbaa7f55edcc34b2f7a9fdc2acea559a8edb14c643de4678858946fef4eb553a66df389d6dda5dcfc8f5bcba6b1dbbefbbba6c1a7be29b0e55b5ce3423bff3bcbe36cbbef53ac7b167cbc82ceab2b3edd3759d595a6d3df14df15ce993ac6bb3294c3232ebd6ea3aaf71fdc6b0fa6b9bf8a6467f2cd2bf1e23bfed3ab3b6adceb377d5b7fdc43755519862649785dfd445d515555f584561e29bdaf71f2aef01e4f9ad574fc3b38763d86df9fefa668691e3d4c7eedab2f19f5f766d67e29b0e919ec6c1c82becbe74ede9fa85bf1dbf34f14d871f57fa649aa6ea09f38b1cab703bafebfad26a0ccfff13dfb4c5953e4e5d33bdc8f1fcb66ecbceb37767db7d6de29b0ee1d48cae845cbe3c9a919033837b31348d985d64b8855fdb8563b8866178ae57e29ba2e9af55d5e422cf343bcfefecd539865b3aaeb7c8aa1a7bdb7b4fb375bcce68ac45867dadcef5ea55f4a3bffd6d16199e698ffa7a7e6d369dd3af12df94882f93c33ce3728ecde84a2855d41fb9a7027e53d784c0c4227fb89d57954d69d5b775ebb2c437b543e1a63a3105906dfa7f9fd6b58f53afceae4b7c533ce4d04d3f5e2ddbfebfb199d999b199a1306333cb97298442e5cf53faa3fde57e7dc3098542e16d349a4053f5d737926dd3b4857b31fc5931afc8b5ed7feb637855539a5567f6ad625a915bff53f6db1e9dfffba6ca1c1fe645bca8179bd195c88b78d1ae36fe2289e15028fc42619b50f86ba170d8c8ac227ff6c72b8afe744e5fbba567e29bc66b0072bcc6715aab6f1ca76ecd7e368da3985464dafeeb9cbaac8fd1948ddff88939456edbb48e5dbf7effd268abdac437550e87ab8abb299fec73df26144a915b1a9e511645ed9af6e90c7ba2195d09a110cfbb6f229a0220b72bccb6b41db3349aba33fa95b7521945765195aee1d9aff69cae768be6c8af27b3b012138afc7d5cfb9745dff57f9856e3f82d623e91ebb84d7dead3954dd13a4ef6e5f16d2385c2154e623a91d1387ee9d4b7ee3cb734ead2c437ed9b87aa6a23eb84c21a4605309bc86dfa53bfd6f3daa2693c7f96f8a6356c9c3d0cf762b86732916df7a7f4675dd57b1fa7314a7c53a150287ce349e612ef5597fe6d1cafb64da7e9fc954bfc36d243583dde4a9b557ea3d1b31d6f2509a130577e3de44d0b855f79d36daac75422bf6cccceac6fd1d4b56dd87be29ba242a1195b6a574ceeddc921cdbe41cc24b2fde9788e59366dd119b56b94f8a6a8badad51f0fcfe7c5a437de775241151389dcd26c0bab6b3cfb5fcfb11b13dfb44d8542612e140a8542a1599c9c9959dc9b99199b599f50684657c2accf2e2abf9d19dd9b99505827140a856c66eaba34a37b333321142a7fed3f5128a48b42d74e79db4323fdeba150981cc6ec9ac2bd186a79328fb4b01ad374fcbf3bfbd8a3c4375516d3f475611a715d947eeb8fbaf55acf291d13dff4c633fa211eb2882c1e87f8d055efcc2232fcb2f17feb36b5551fcf704c44b6ddf7f5766bc7e9acb6ac7787c8b00baf293cc3e9ecae2bdab2c4371db6a9195d09b3b93936331666746f66357229142a3f2e14c2702f86260f53884c7b16a6eb154555f88dd73526bea92bc50c12fbd49d593b86bfadae2aeb896f4af76636441687c95b59afad324fde2610d865d5ffa62ebca6ebbba22af14dcdea7769762c1271a19ed9fc2ecd3e8dbc51f6d348154812aed2fcc1a22c1bcfe81ac36afa57787984f3650a248916c693f7fa9537cdc2bd18c6993e64b7a5d336b65ff845ebfa7b96f8a6f9d15ecde84a98c942e1af85c25f2b3f8ed3a52cdc8b2109b3079baa28bbc6eafbbe2b9ac62a9a0a8f7a46a350b6611875bdafdfd9ab6a4cabc4377559983ce4b64655dba6d3dadbb00bab9ff8a6776e4657c2cc68f442a1f2b68542a1d00c559766c6e4b16846f7663674e3611aa7702f8666003b641885e7f4cfb61bc36afcbea80e996dbf9fd99a9edf95b557fbcd21fbf97b3fbf769ca2f4bbda2e0ed9665d0fbb9fb5d7b48d591a25be693dc44316f1e59aca6e891b324adbb5eab6a84ffdb7e9d5b621a7b04dc7b61ac36bddd27f9d6fe470d827c3718bd2e857edd7f52e8cda7c725cb3eaafd3368dd7b8b5fd9e6cb3693bcf6bdad22a1ac7ebd793dbffc66deadab63bdba9edd24b594d69377dbfbac674ec5918ce657a76551a866d0f7f169ed71797d195fd6d8daeffa5db3a8e95b28f5ff87b755ded577d5596ad21db29fae3d86d571585515b45896f8afcc621fdf58671da0efbf2a2d227611249d9b65d14b667d6bb69ea55dbbe65ba5e67d6db2eaac6b00b7f1b297f745deb949e6bf46dd9f6db4799fe6b3ac7b3cdd2f51aa7df36caa8ff6fdda2686bd3715d7b3b4ff668cbb6a89dbab49fd318b669c82bfce99af5b5abce6eedae765166e3188eed98ada8442e4ac6537114e4308a840c21ce4c4502005000e312403038281c8ec6c211d1903e6b3014000365aa6e8838170944812c87711404410cc3401001041043080106198f6cae04e77e4d80811c7d1fe40f7cc85ff6c3f37782dc0047833a10746645300de89382d487f9cb7ca4dc11c66d5529cc7ae340f2a5a12c6f2ad7ba45fd533110985591b8d18e8901b21d0d193d6eba46cd82c91a6d6aa245dc6b655bcae59e419ccc6d50602061af2f81bfb98fdcde2cdbab6b526899a39a5fe69516540e8def993f178482799cc71cec79deb7218fd60217d409440a16a555bd93ae9bd101fdc59fa2b70bf7a8e8edee04a317a3fb793bb247dd75bba3cd5f34c718f510686c8cd07c913056f476257307c2e866471ec37a4857f4b63f20a68a91eb10f30c8bde8e2feee80545317d4d3d8f1db97d742770151a972f511bea4576c5c804da9c93ab0ea3436dab8f2a42d49e74a451e04e9667c5456f072393de525e5e515df456b4201d26e4e8ca8bdeae38fb61f03b694e8716b930cd333ea2c801f9b778b42def75fe9b8de2fef8a643848c93d667ed9259b7a6b0d3de41a078692f6474b07263e44bea1576deb8ac62d49d9eeccaed6c11ecdee9e1be1b6200a5a722fb9798fe39ea75bdfa6fbb20bb16f68e8393d4828107efbbbaf4899368a22486f65991cffc8389618f6f0e4bad0b46895b19301314108ec7d59aff24001eab1bf80dc7121e43fe4365db026bd04e198fc576776a00ffed60af29eda7972bb02ff114e41d3c81219a83412f0e084dc3d119f00fd71736281b0fe393b8e89b7b5f41bf9332eed765a358c99387f8181ef7f5e0b25c92563a9f143f30385add0004ff4d226c168ef8e5fec8666fe6e330a47931ba227f1f863a8fd273caefd4eadab8d03bcc8cf3bc4f52981737621e9a07853f7ab6f01addbfa840e96fa2660af8f44921bcb8cea30023ca19a9308870abbb0462d3fa32efbcc54c14f5ab4a78f75d4a3fc2a64d4d5f27d0c71024f726557538e9fd339541c9c8cdac83dac1baf5676022f10ddf86eb514094942d20df63eb74b3f6ea209d970ad278c37a8258f19929c1131f55ea920df13aec87b57a543f1b8cefa5374441b5b082e45e26d7d31ff68efaecd9e7285552e01ca27f3008d702098dbcb03264abdf0cc23b289d0004ba9c1d02d628564e4218673525b5bd47107c3862e3ad3a815feb067b53f585f3aecfd843e629e19234051c450123da2122cbdf2039b0d36e87c5fd8538994465324ea84e28bcab96f140add54522b82b8c14172ce191d0895c5484981efe6f71298f75ba2634c88a5207ca22603c1ffbc34719ef2de1ead2477892773506fec083bd6c355cfcf25eb308075c235acc3a7ab1a0652459c03071d82e36c68be7bbe9bfa496b3725cc07cc26c0e7ba1f76d4cd14a046626fcb1f87f8bddc8fe2c94e80b1ebc8e57ab5caf6b2aac77f688e3edad8811bf2a81336a69b3a4edeacb21831e923ed035029879933df0d7ff8546ef40dec44f4fc6bc8e61705ccf91b12a9f65df69db4df9d6a3995b635452dc18f3119755bc74c12b011a724dc0b16155c5de714399959773473c7818ec730e991c800af0375f6b03861431e31bf1af1b1f3bfb4ba72369f4beb1a59bc2779aa13910d1c5cba09ae2205e685c2cfad7ea3bda14c14f60f7ded465e6f0cfbe5e2eb2f5cb094c62d55efe802751b4f7c8b0d359051498a4e091dea776e46fbf5c35d20da22bea0a6ccb4ee2d3dd1f7646975fec60d71957009ecb06ea4d4b504468024e2b9cb2bfac935de803b9c83f7dba59ff72b05c29184d71b86e08880dd4a04051287b66257931109b218c640f6a69f0d05009d46a261833a2a573c486f383d0912c3879e3c675c09dc8dbe11b102d3c4d2a17baae5b76f7817f749bb48c445b61971cecb21a065ab9debb7117c66f3248c533eac480c0f05f77b90de4b5ea9a6913b060a10f1071f46223ccb2567a453e79456c13deccdbbeef7079ca41f6d3440280bb2b73f1e813453236b584c068a656a127dd467400e2aa542ae2a0c0841351b3c77354d4552cb92b9a5a34c29bafd6b6e56af98f64044d18b57cce482f2eae55a589573b9730894ccc98d3af10d14c0610b4eecb21ceae77c48561c9218b523073bbec061dfd56ee448c065ced9f97a2ad53431b612e320965fe00511dbcdb51b6ca256cc91207d347467810cc2a9e447c42c4f41f80794194ced4d2ef92c3d9d58308c8268dc42d696fe091642a26574a54ed390495dbc46bf71d2be3b2b761743c5bf1d965c76ae6134bf5fef932bca600c24612919e020b450d4053860d8f0b37e9a235503786f43f64ac621ec483cec9722b638687699adf91cf75c201c6b62e78e66bcaf375f5424f6439d8ced43e220233797cd74e15bb3942834dfc62345f7a162f69856b938779c27064e48c1a93c916a8d1866e668345464cec00a16168841b51e49a57d5621b9a2ef47c6b35e750ef0462bea938e725e9271a7c980c8edf2f7180b4be2dd4a4c533405f8af226b63f08480e4effe818258cc2a87fd71fb9508e2914bd82a7ccb4839502668f302ddced92bee47ff65fc4cab327dd1d78ca0cac143037c032bbd4fc0d2e57258177ec93ffc89faf7eec0579d5f733f712f024d6659fe98e4c4100330806d8daedfba56fab0344b9ce344c4261e6cec911ad2729bfe6d4e28d2ad3ba8c2bf974184fa58ca1aa03152f41ab2c3e00bb24848bd5a949852e32a5c04a251fa7166e7a813bbffc9e6b210ab0f0345805d719502bbfc62bac014b81089cb6912bba6aa67e9f2e4d017754041de527ed94a9bf4196f0cd457c24c537fdc2cbeb00ed2af2109626e0ba95897df7b9c80e94e06b666df6a0922af82aaa49ee8af65cd673004dcb7db0f6479988a3b280988e7205a69b988797f45e1d076fe38c8ab64c39495eb211e1981d257a0d6a0a48a23891c649602927e8d0e26820adc5d3402a5b08bbeeb5b60939ade00b202a108d645fd354398f629d273636d8b146f514dd6cc2a7f9241330a3081289bec6a00741460a2cc1c69f0008ad6f1d6b3637e246d2445c2b2bb801ad21c732bc1d124ec549330197d6d4a9352a4332ce30053957b03643706d1638597d2c43602b361ef4f33627a235d547675b63907c5991a0f1c15ed886b4a69206c47be3f6ce5c2d2e0aaeef815219965aaf7bdd34e317d1542323fe2d93dba2b03b61d10b42a017e0158d1850ce8a40608c402f64a88a024ef70bfd11c1b278ff17158bf59356eb5e542c8e0697bd012bd3481562a30ce527b946908b0a42b78e00bd43e0482f30cc742ef02ff31fcc7cf6e3dca8fb01d77672fcd00f3b4b3a039f504f3aaa81b71115268f90983b09275c45f54251e8d1b172d8e5f157c0640d498f4f3e16b3d5e430650c24e41ff440864ed58c182afd59b0d1b736e8fe754f28881390067595981df2c08a1f02a1043aa615eda24c05f3132b67ff118b9145fb118ac0b963f1407dd0796d59cd5a157a59955a7c0dd393a58d47b1e37d353928a99cdd80d2dd197beb9c6b6377714a159e7853e28a59263c2c946c293e6c101c5ff5ded3ed149eab75c1145be8235de4fdeabb554a2d7bd1b3d21f556f2b5aa26edaa704746647d45e1f146e1f68126776e0e8a92f8171bbc2808b08605040533182f8eedddf3435c6e5070dbb24778dfcc80d3cc04eb982548340961c5a52981cd585e3542841fb13adda66a228284d45b996e329704aa269d44e08bce6435814bba7329c1f256ccbf5a8d3701247f4ca2e587ca1f2f677a14aba35515e5f3843b85b73d1d384a8a7ec1856f8c7bca1cb81e23610af12651e5c69bc3725ca3bb8d678af94287bf0d78da551badc8372b5e174c54a4b27bca4c4f563a93d5f21e4d5036869503d25c41db4ca06ab5525a87ecb19834d4bb0193663c271a301c686a109dcd7c56a8241e8593a200053edb8fdfdca02173fd1cc020cd76bf3dd5efb8bb0f616d1e8de2cf4feec1b5055c05d2c1b17fd013f43e87d1150f9f2df938cd4fc28d0a923c416c632e05154460200088324ecd5a44ed3aae40b5020edb0d681360682d15792758536276f27c6115428ce23d2c5f6e858231ec96608b549898bf23d0429615ca23e490049a50749ecc580286ba91e348e6130de8198231043ad02f9a0b322e7326a1cc2e14261bc5ed7e8157ad191e4ee38cad815ccbe16caeb3e53ab6c32dd5aae039841036dddb5f8b03ac44b09e88ada6f3b6bcea1c309b9235e1ed7a5c44403a67712e43031468a01bd6e50bd33d0bbe9564dcfb0218a505068b2f20e36bf8a7bfbb88c8500de14807b0300bd26a0dc9000e69e0682313031e34cad0233345bed64b97aae10dfec53aa5782839c74712c99540d40afeca464250e5e7378cfb430272bb65a0dab4378bc7310c9f68aa179c772a133449cac61e72f7ec13c2b6f4eabbdb0b061ede78fdb938b533f1f069f045c2d4fdb2bc65bd0edbcb3ae4ec60d32afb41cc92e93496e2d8d3c841beae78a4bd557066e9991f157f46d3b7140376ee23fe32672bbb272985b2e4eaef2e24a11cb6d1684acf5a823408e98c670e6c141634ea91de815c8f53c0a60ea06a568a13495cb693bf48a57441396c2c2d3d544d9ec9cd58cae74e5e1c482e9805692f48a8b1a7b109ded25ec703588f81abf14c85eb58c46af5c405cdcd427c4fc143760664379b4c985c38b23e884ba85506a35bd217ffd4f774a56a29e5876356d0da86866bb379462e264410172f2126ad518277aeba34e2c5dc6d148184b120fb3f6b4ed6cced9b3b7abb9dcfbc322765039629192eec990e10056ad5d8596c9f28c62971479f0962ed00ef1d1f20ec2d56a8d1d4a3740817be1f2a2f8b438553cb50f5e28ade5e8a14db26b01f55474ecae4d6a14feb7a24c2acabc7565e81d50b95ffa9fe8531be4a4f911ef713397e5f0e6ffcbd51f1983bb5af13e5c679d58148cb19909dda076c462008bd3b85aae1d00be57138fe6745d469af577e9955e40b408e7b66a5326f88005cfd01b65d1966fb845f814f7f176cfdcd0965e16c3ee970ac1c77a0704cd4c1b0bb2ca8baf505574440969b34fb5f043ca346c29b8f47076a7a8b5cc11308a2f90d44d4f012d6457bdda0c87244b894e0c01fda53d4b9537ac898c24b3b9dc07185072c7b4434bb92fccfb0bca122ad413aa473022c741b10ab5d03c4293471730ad56495673ae17fe625d6ed3da000f598e7e823b1d8bf42b05c632ae256e702045b74ac1c7591fa6425851092844b951ff89e52dfc93f5c34fa7aa4c32aa014faa5b7a3176d2b43212ad93404509a918160b07af25ac6502ee608b38f7e7859bf8b26680e49957717089370322343420ef2cc9ec9a73f45abb101dd7e9313f6020c0d7e6d2c9515d797bc5753bc8838736c24145362b3c17d8335300630862e2e19029a18320031ff911c63e2efc58ae5aa94c081a4e7498681fccd833c8c1f11b2763afcefcb5ddc88d66b66cc4ba8da0926138ff51b92a5ad1c477c10c62bcbc74267b49e8b91cf765b18e7bc43aa903079a11628b0824c05ea5f4b25621adf888045eada5fa002ef107913e0f3c2952c7ea54be3d38645dca5cd970e863456ba91bfa031dff7295cf1a7bd368b867c46a2126a31fc84e5f4066578b35a7da462436e121289b914a9c6e25f4ad7c720ed521f9c979a6758f350280946bbb14b9a9d0986064e6b6b41f312df142c8519af87fa7a415b1efd54d7851511d659e11e535af7f2fc1c18f131dbb4a9ac45a5fdd51f8e2fa8eb5c61c0b8345222b7504e45a1b1956ee789e622fc4a121025163134ccb9501e0d45b443156c63d721e0821a20eca2a5eca0cf759bdeed0d66e01e48a388a6d1623da962969b59f6d456a2dbf9959b04b4c206d108dfe4ce0bce671508aa5f7261afc0ea8ac35ac87180dfd51caf581c60c5c0f470498b8533d7e30aea32c175f1048d08cedac230c04fed9f8d9d066dd5899749fb529d8c61877e34174d13536c96145e300f380457326c3b30f507ca6ea8a7ae12b2d5b9cbf8aa36d522d63ead258b4be370fa6ead2edace8f55161cb609e9a44e9696166ac0895816c5a641f71f87e48521a197b0cab46ab483b4bfe2d0eca82f1a2c81b1001fd8908b4ed9ffcc26a351133253683b2c338961ad8167394ed5b156973999e8e873c713cb4fa4d17c64929c85e2d7926aa5d2427964100b5d43051eda62796a22296249b136a90112d492602bb684e5c8340b4543211ec4273420d12d132c924b08bcc89358889162493825d3427ac41205a924c0676c99ca8069128960562b8749898b0f095822752ad326292c422508a86886b158849251641293444a8552226935802a5c810b156313141622928454384b50ac4248965a0940c11d52a12134b2c00ca52501c0347e465dc0b395d8f97aa7a4456cd9038855c2af05a335465452a11b3bdfafab0653e694a2a21079e5035063669d7afd8a46d25fc2e3c7d7dbe8d2bc1b3497576d17ba84dda612c34d7d926ed4c0b1597caf53669d7feb849d38d0270f4ac1b63c8ebf35a25ae2716f2bd49fbcca019f29bb4f9504cc2483baa615b2a5c464926a0e93a98fd381451e9842538c6ba7c018529ad3869174ee3a45527f83a899d8e8f93ea042427d5850d0adf3e73e334386937952e27ad702547dc01fa8706afe29cb41bb8e7a45df93b71d23ef02fad22e17417272a807556449332b041d5d8801736c670af0a098b047574d5649920907ad2b3c833a346436ae8f8a6d3a2823d0abb694e9fcc6910ce603da00cd87211c72c5bf68a7afa9f3c7d7dd35231b5cc23b5cacc946fe34f4ba05f25e003eaabb8e3e9d29ef14e9c8c95fa1461dbe8eb739c7e8ea42fd313a329b871eb1742d9ff2f9bfc892bbfa6d5a8ec47940bc0f7438d75bec4ab1ad2baf3e224f15bfc4963cf502b7151516bb3fd4deffbe10a956c15b2b16de6ea42c3b613e466e6a80d70e3d8a053b1ba3d59d6b5eda70a97100e52154c9301304d834165496007be8f7a70e9bc07ecd8a5d6d8c477cb14dfab58c00de63b98484819e88602b986c2fad9e1ba62212bc129990396265bff35d2f492b04ba647fa7c0918c8ab26001544da2ae7a3b0fe7f508074b77001cda582f7e35a6f54adeef62e8c0aae63598e45a8b0644153adae11f4b644a8ec46869cb05aabc2764b51e0498124b5394652d915a5b58d8d3a60375581da6bf89aed73059b3faf09a9426e808d9538a0ebd6aa55986e298a7d29101237c44829bba1b636b15087ed252b507a85a8566541a95ca85113f6836cacc4019d3655adc2ea4ad12eca035138a1454cd90ab5b51583ba6ea85b82d12a43b92a054ae58a8a9a5527b12ef1b6940c374f6e0baa6de36cc7c216e7dabead9daf5aa8d416ce3826e993260bdcbf228a94b11dcac6463cd0f186ba55485a25a8b7ca80d039228e90b71bc8ca463494cb96ba45c81ae568974a8190b9428992b719d8c25e2c90d396b255303ae528974b805339428a92b62b10a78da570454d20663f8239ef355e334c58440d2723d94e7ef6021186528f369b91f86bcc3febe8bd8b9e249f7c6cf95c518ef14a6dac3d171fec752f569095148706025b1a3596041077fa33f90d290263dc9dda44fb0ab5a8a016b28e75c2e40382f8f7417408afea8b9f8596b84923b3c327957e5fc3dd3aad48056ce2b2b4297b1a358352eb30de177c1d6743d8803cdeb5809054100849f841056d13321c6ef881604b2c1d0ff9ccebb70038cf2c0e9f43556962fd7db64cd9219b0edce61db78d625bd3d707f48747ed7f7fe596192be904b399fea6028f81882bd79bf507515832181f91ff5c4ac6561c8ea33daf6730ae3302f4879834801cd9ffb385c820c24b04e2abcd43d12e40e47ae96b9fcb86a056852d5536ea3fa45423f22590a4d67524fe0f22f1ecd6e18634e5bfd97b9c3f7331a31979e0d8d96ff164951c704ce3793ab0afe97c9a16fbf6563a04d5a14b875afb9d4371a9b18cc028e50644ba2ec7ec9fa459831fa52f5718b81774d159cb072de9d4a0655baa4433464f5bdc136a6e47934326eb9ad97c0fd59a096ad5d140874c88ea7af607bdd87dbca01d90694becc4da9fde2e3b6660ad8b895599f630055927758cf537b4ba3217396a3fd94f1e1808897b43b906b239967863a2cb390576d3e56cd92a9c5f530f03ff2909f67f72a2fcd7143d455961eb15a4c5e7afd1186cbfe88ed0c90f224d0522af0a19dfa71061fb1524ed0d8992fe7fcac4fe5f9e9c4b14486894d03285f4e91429a5b2885461af551a8b95c66ac51eb9725eafe0044b82150beb358b14d1b2a66a61902dd552b734542ebe972e0757bd209480493e350c453a46f4426687942159cb941133d5d58c9f9cf941cf60099af0150d35248d1ca2665cd5f02d6bba754d2f858d8bb2b94cdab0b54d2471c345dde8296fa6eb1be602a77385d34be258d73857450eadcac9fce9915fe988963a44b48e6cb1b35bed702d772ae99dc282c752c57359f2e04cf324a67ae8ca1ec1ba6756e143553e85913e2db58f9be2e781fa41973f99f50f19024855016d2a810869a0ea22a84f05f951067de9204242285b09312185546ba1e916437c72a8503d544310b929a26f920892264a218a585591b2b2685d17d11346657494517def50353403c0bc9433696ae0a954dfb84a3e5f63ca3bfbb42f81fb8c14deb197de0e532a7905a19dae48b78eff0e3a807f333ff928520e9c9d465a90bab10f33d211d11e3d0178245fc9f4741e14858c9e58dba0b74ce5874faf08eb6d6fefa44602c65b441b5cede74cb3e86430f3edb5f0e41c55d0bdf49a3797ad1a4c191407f1e18362f7fedfc8dbb7cd50d2aa8f136ef40be0d4e9583d5ba8e8cb4879d9cdde86ffa3ae3bfdaace15b721ed4afc168be9513bff3a43409f480ba2cbf9ea13eee905d84a0d6c7cb5d5d15372c1e9ed134b1425231f799e6daabc4ccac21ab1b5685608d3c249ed63193116c435896f62de0e2ee730f7bd3f4761320f0534382c9edccb390ea1f85536dece8144d116081ca8cd7e9a8c15bb26b8dc2216c77f83576a51b306d333f335ad609147b00a3453506206f2df65b91dcde919e16f35bb1e6eb19abdb11e84fb1fcc902c7849a19f0c629121001c9b6e8c31bf094a92af868d5fc172b2580fdacce96151776d199293724b9bf0f7c6e5c9b20a03b16d58521c7373e633240c24676eb6ae61cde57cb1bc0e342c0f2e9efa0099c76fb015912a872faaead311ec2f146e149fc9b9b25744f5da0f816d43585d72b0ed589fbc6ea9418d5d72826c278a51d73a9202df751faeecdb32fe933d822a7b75c3bfdf7cae26b41cc6b6961dc49fc98b763f6502988164b2ec20baec8223c264ccc42ee1021e40e531213bcf73f9c6fa96ae78d0e39efd7e65b74b8107ed42466ae1998dc2841d51af5d6c6df21675ce4397a42e92401a22120048141473125f8c47468bca9e0042d89f4f16e7e967e4f789948cf94171ba0558b184606f46a9fd5ac33d4f4353288153cc41de7d422033a99cf13b3c7c53d41d5414d42eafb1784939dfc411d13697641deb082e85ad456562d0b65b38ad38d7b8c829769caa30360520b24957d0f2e8db339262069dede6b4b59b7cd39cd5bbb9d88a60e02cd3a1f9688682e2d3813dfe2e528e5fff196e0239dc0c9b2e5d52aa75a9480d52c414b174d1091addc5f19dcb5aeef0fd255d2e12554adf24d0aad32f59225c1d2d1f923c5bb0e4c3aa70a495836f2ccbb650055854868792432e75bdda7c65bb8e8ec99ce3bdf5fe3f32fd5e6f75f7d8f067b14633fa9d2431cfa1a661973774dc013317ceead01824e6c759b8589a08cdc6fba0aa52203a07f9baabef270e4517eb728949b63d4ff5c5dd9cf851ec553a1ebb29f161bd3324e4f5b4b3d52985fc8362340f4af2d962481c87d142528cd6a2c11c198c8ebf5806bba3df2e4b536b77d05c1925adba4a00dc6468820b278860183488105007220ae78d8f790e9111cfcd0412b3148751f3d76d562cd43dc3639120982792c117d9aad19612492dadb32b4d0f4484ae4e8a4f6aba78a6a1ae41ed2bd1eb28df0eca57d8f9a8631b4cfa4ea0fc92911d2d9a5e8aca992a26a321e38354c503a14a7e9cf01a7f016ada3fb1f069b3cbf0ec935878c8272098180242303b4b0fda253b1e84ca4ec48d495da34fc3d067e9828ea5bbc42a4c73f9da75a22c872584150829844f6ff24f4cf4f1483bfdca0e240d8ebe934fe610e9e4c01626c22fcea12204e43b49a6e933fb291d1aeee43d9723b88517730cfd1524a7a318d79ecd2d45c78163834b08527163a57a332b21310c9f55ae1a7e945d8d4ea73f0e7a056efc86ad6847676d516062e7178116ad02e6ab8020cc5091cb9389ac910e17df882363c5da6245fdf21734fff00d2f3f3a94fa4262aeb607ed46701de141c0b903434b0d88f2095d27b6b8b2b0288ae6883f0b40cade38a90f5b382c6d6dd61198a2e498eb354c6fbddcbad1548137ad88765e3ce2e5b891614f6e04c204f0aa26be503416261c688c33c70ff4c54190314f3c60ab6c185f488afcfbe9e567d192783ac1d1ddd4736f6389bc2e164b4a5713ff01359d6878c6f46168a0658bdde89ede74ea4d75d532ab7e4cfeb8529df1b5fe495a186aee10c643f8283646f222a00365fa94a0daf2cda69fecf517f29e9af5943b6d019b6bdc4df96ec123f37bdd34e29e2e1f99d340c88072d4b5348a379cd55abf674f62ef099cbc2cd5be2f46c349fcc38f5cf4bc24f8ec38843c0192d9514def90f9734b5e22b4507186e1083b21208ed42d141455cd03ee424a887a1cd3da2ac1feee94fed322bf3cb490c62ecf09f0ae361ea70d063f2d8b304160d2a37ce9415f2c4ff71f3f58f83f608ccd4f6046de5a76d929e3bf93df393ea388f9d36916e5f19a0714d910d3c968dea18ef78786ef2721550728fa307cd69dfde4efb6e20a03728c288303fc8eea84153f94d9c4f7ab836e83931bade5e2fd21f06bb10fe2003716286bffe59fbfdac74bfd8a496a39b260f84fdbaafdf71d0ffacc19e912b5de95a28f1b666a105eb9d5ec40e011fa34710899c8fc3f1fe03efda1461f671b61d165a6e7095ab60ef667b7f3a27109a41eac8bb817c0409c52b914dc917b00710fb8bdd9cc7ea8c5a99e9e1e8d1e46fccb717018454b0119c0eb72895ccd75c5adf833b6b9223efadf5d7486a5c1d19ff6ee7151f0826d16fa10a221ade0d44ff66c77fc1a325a1a309e5db733d80c4bcb7606dc6b42ba8980d0bb40882a912b13c94016fc38c0da030ce351d6752bed4c3d220fe5cd9bcdffd1bcfa668ae6d2135f15fef3ffe065e8a7b897e2c0fbc1bdc5e79debb4228be30716e73a467d1b287b4c81673284b5611808b6b38352224ef74e069f8f7846f6b147c98ff1c6ad0ef6ad754ad012ec6fd51ed735ea1e104c9a6f7cd8911801c716f946a0ba2b81a44bb425fb5dd4a3a3f7fe2f0ec8587fcce06fefeca15b78ae1c21a6225896fdc7f514ef76fc71bece7ad40d3a696243865186b2cd39969ba247028ef512e71bc5991b23c2add8e7d5493a01858c311dac9b7ce1ec47efcf63e4cce111de30738bd9e17736a1bef361df1152475210969354448d88d1155905d4ba4484b5c4d9c806630eb4ddbbfaafd09a6d21acc8f0d69a8efe6ba83bbaf7c4cba0dd736b32a93bf13e9f059eb2951e0ff4bf09f4c3f86e77bccd728ca2c060bf2e3b11da074338960e8d7d7d0024e3c71cc1583777893d7ec546b9072162698d1f2de9a698b0682a97e5b2b2bdeea63bf7e405841fb8b93c4fa388337bc08b2725369bc1799c61c98844716f77a51a7c12fa1c908ede8954f3f919972f81464fbe5af54e87cdc6dacdd2f0d2be0eab956d9c7036a79ffcc970da7036837dc04cb3c5f31ef48aa71ee5b157dee885273ce3798f7bdd53bc81f6f664f0894fab789a236d5b1d73b61416da2a66caed4267abc7ce963750b7c878d8b2547d4bb0188aa51ac62f7acbb7dc463bb7d1ea56b6a6c5b66abd652d6ca31d6d6975eb5bdf425bb7d2f216b6d1ce36b5bab5d6b416e465e8211f72180879ec8f64bccde4bf10050e8fe2b24738965d90d2e4c4d5719edadb57e2e2cb8ba1e8fff84b7c345d7a3428dbce3e80719dcb4d398f9837124cb60156c72139e4d3c43e060b5d06cd3ff69e5e30dee69fcd23793075d27b8ebabb3abe16b4bcedb80d8d233437f5abb4cb86b13b04c625fd80a56959285749e0fe66641ba69b54443f8f124a75bf5b0d43d23eb47a91a8b1e7344045866c9fbe48867a0cf71c77d7fe0d56fe36e41880d5dfbd915aac34056608d3b76de4103ffdf9b997e605d7b27abbcfe1f745d344311dbd701fbdfda05676dbf93c0fe5d44e01da858ef409329660ea0c649fc01c3893397166034ed6df61de6626d731682b78fb1cf080f0b674ce3b182e479a3ff4bf08827e0d41ea38dad4e38bc80f21db41cba133140ef3c6d62f9c04ab0d5e3eeeac74ea48afb03b993af442ebaf9d1d539ac8a3c03881e1d51424b99866b0f392811db731a2b0a361819b43b13b678020ffc445696ac141a28ad740c781a7f8e616ef06e448115c81dc23d5ebe498d07e0f0f2c12886ce237e93c2bacf892272eba3d0d3434525602e8ff4a11ae042840ce952937885967c76a363840adddacb93521cb1761475e0ea27f691c9968e1147aacad0f878dfcc9914e542c5a2a6110267b0906017d7686f3c493eb0979dbe66a588ba9b0dca809f5c4fd50cc6e5b40cf4b5240056235aa9c84fe030421696dfd82c0f702fbe2248308b489b8043974606d39334d6cfd9fca9d9c0bf9e497f9c9bb24694bb1cd345e292d5063d30ea9692452f29edec32ed9f5bc1548d044365f7d5fbd19b12eed23d8fb1b94b34b6ad3e09523a0c518a7c790c55172af2138373f6c22fc1c695bd791676e44010ab91b14cc87a2a27e68ba812ca82e7c102ca45c7b859089a8ec8ed84a37ae88d025d40012433331c533e8afdcb86e9993efe5b6d2cfe28071d99b2f1e8c352925493c835e3908707b210cefcf760dfc28b1a0a39d5ec77e5a0e6c31be62c88fc296a0460aac05729c9cf2a5d7e5a7e299e14d3d58edb872bfc039a6c4a28cb89a6750e70746eb8127e60dc9d387a421beb4849ba58a098f7d451174179b786a5defd29978705324368dbc81e7a8a7729b0be8f492490a2920e141e337603effd18ee2636ad7370a8e42742d892c8c80f0809e30b60d1d98ac222fb807f9828f8e531a2b0632f8e6675b40c162bc743a83d621506610ee0053a82c645fa68c33881136b908f1cc82c61616ca375e13bba40ddc30e6291224d24496ef775a341b669b0b674a55029be828341d0670facb68b9984356a0c5fc7653095c225abb201fe2e48804209cb12cac8ef9e6ad7c4b5b99ae9be2a7dd47015850c156f81186b1576642a3f593c19d777c37c24049daadcd95ececc3df9915a7a7e84b86a386e568afb0f81cca7eee1a222ecebf73b640ffbdcc83e3b7e236904f93bef1c40f4742b0af6340906f6f4bbe12ceff05a473a4fe3dc1e945aad64411b2c6ca48a0cbca024760e9134eb04a5038baa2b9c44dc8078e5d2d2be1362a5f2fd4f31fac997c40a537348842e366a65091d364b0a00311906078a0872b50d5ed89ab37438811d1b238a603dd085fef79522af9c1082c6688fde3e21e7c1334387b02d5de9fca2539ff7ed6e0079b1120b360cd760444707fc2a20f53f009b04f1aa5558439de519f5c20fea5345708397c3d2201bfd3ec9b2d8e43f9af679675de6c37aa1289abf9451132525c698d97d8e1bd6d3fdab6ba8c6da526b50f1d005f5f4761d8b02782a5b1667c6b470db7cfe1547fe63eaab30fcabdeefcc76b8334421c2c785811398160a1561f0c9dce0ffeca023dd1c008bf72f4030181027d8f114691e7873e65fdc074ff8d0167cc3811051e75388ffd464cee81ebbef9f8e88dd5427d8accd1cce9c9ef5ac9b193a00d92ad1124da16ee30271ac3e7118a5da220edb95d70e51053d1f480cf4ee38f5ccdbce0c1e07e99722f48407e0a76eb671bb423c9163316cbc2ebc4c6702a5c63721a446263bf904cd5fbebb1e683f026e06cb198ac3c2cd1cca5f988ac1b1e725d188fe738b830d4231ab5202d5dec724afc48bbcb1732dbbf425fbf03e968e85199085dc99e6a4727528cea924c13fe5d6bbbf17acbd519aca91f879f9e7590808f003e90bf302fa06904749e3a2f1428fd5fa94eb32bb7e6aacf05683396f769470d9beb31d7bda913a8d8f24c8893ca0407dbb0c0dd0a84bb3bd2fb3cf500b0771d8b5d7ea8192110e6c1a17e70e4ce1a2222c74b34ab71a266bfa35971476ccb4111937639a3617b89697e107f9a554b6ef7beeeb8ff72fda871c9a54e2ade207f936909f411915cc6451920b854dd47c0bcb33509a4b2160d99a6d6e04a6d7f4ea00d4e249a68d6251a33b6fda1358e3e439e51e30f91cec3003fbf025e7b741a0229fe9938c2ce7d0a87fe3bd1592b6bc082db8c9b6f205b7108bf02f38290310e031418adb8f0054048ec5c180b7c49cb8f95bf61ac8700deb80a01bb5aa428e8cd7928488e11f787ce5ac7e631c5a2a78c1593c31c1973b3c742a3234c602dbc2b3b41623d236664848a589027788ce015c06b6fef22ce0f6e7a9782b37f2d7d0c523990d1550408f3143065d92f166070f24dc6422f570e59ad0fca122d8e49db50b42cc67d5a6e56a46562d8538aa654e34062a97152c2a35d63871846e5324c06a1c94f4877a850a0b19329cf95e6fd796c6e9896c2b0866120fe0e152ff4e8db3ee4e36b5c32555d978a595c91b370acd4234d326c38bbc141ecddc5499f51027fa4aea417d620f848df04569ebbcdfa841e93db7d1ef7fb1ebc8a1edcade78757fa55012638c014ccba0b6776fac4a9f4611b63f9e6efe3ed74ab65ccc37137a8a8bdf110befdd71783a26ec8366075b9bdde6b646193f27ac893f2b127bece9dd760186458c2b846fe40e68c884676fc0144572669d195e01e7cdd580c4daa36c087939b66da6e4e592a13fa49809a228259e92f0903618c92ae0b96f8f9475fe8a29d5363de33cbf802d044016278a7161d85c80253e400e1f162d78261df1f3111cc20a0fdd31b68d50bb990b7bbb33f0e200e73b83162a0e85d57f862ea720e5c9a355a16d6162976ba7e1a1a997a2f74025fb2a9d42417d4cacfd2d06a2bea7b349debd69622d885ede98f979cec5e27d744ff7d3f34c362f547bd898dcf645dc1215034b446ea7a2585915d4b110836b3e6e0a9dbc23938e3c0a3a0b0351ee02db3c2da74a57b518fb7557c4f29851f74a84dac0be3d51e916d10d4da460301749c6d89cd120f7ed9f3a04ffa4a839bc6a78dc7692b45b9707698a94572aa7582422ec1aa88fa63fb23d6aa8d590652dd8565954ca1d3cc4119922f876fd3f5507f04a81146563a7cb6bb1df7d2e85ccb7f19017ac71626b85986327e602192bf23c88e653d6a99f10d71e865d96a4c69966ebe9e6f2154214067865286a526bcc9186661d0ec02bf4a345c7db655a942d11e3696e4ad4f9bb0a943abe5c9effba2735303b096b0bceed0054bb174aac0754314d968f5a0ec4d1b9e3e6485d7d32850deac12a108ebe54b4a395417f3c33cb093795e69c74998b5b5403c8af03b90c1ee9bff53a3efcb13587c4b3d469f9e43e98260c9a31142c3eca90182f498dfcf19681212e1874e8c7dd94f304cd5703d415cec4ee0afe38b7ecf04533550f792eb16228ea936f2b1b78b76bf7980c4407c69f8a96c9b5272fc7839653b97600bf26e33269d80a0232de87896d01815ef40541c895064e8ff221029c88224b874ab03da6e74a1c5bc0c20b0c2816734803145ee6ce277b8de5a6df8797ba3ca44bc38b4bd10b6aa982836bd062ed2279bd34338d6b287e837c91c0f4a13b87c8a7ad5dbd162beb62ed54e9a935b0ccebb1a0334d802b0b1686e07d049b34d9f86b1bcda3af24fc18d4a9e97e7ecdba0ba1b206911c740b6e9085c2cebad0f1a6d3a70d613c667b96c8a2d127a61b7d0abece9e28b5a955bca7257bd446170256db7f2d79c7d2bc4af5bbff88b1bfbe47d715a87d9b95817364e9383c294956f2addca44d55a1a692dea7c5165f64527aa55cbfa20df797ba2308c96ef278ff5c71e9ca6b8f3807b5b66c8d05d3c91ece6ba44119d7ca9055ce9bcf9c7e5677a79c1645b550e1ffde7e5f5773beb5f9a6ee1f84c0852a1b22e8468f82dda2a2bbbcc32adc3732c0d7bc9ab798e05265680cc94bcbc3e3ab44ebf0209632211b671bc573d543f5fcc47b7612b31e830674858dd46c986a3d14b65e10deb71d1f85cd1e2daba4a4b8d9975be1db4788531eac58f20d9d595589ddfc566770142412f7496283c109b6fbd2e6a1636a8dd63772f0c0d9ef4aeb59b13b2443aa823e2b993a8fbf70bf3ed9d997c11643af9399a53bf6c78fccacca6694cd77cea6cbd3f98ade9cbaf6ff6c76a29d73fcd4bea0b7b13e27e478ad31774b04f7ba5ca922608ff73f0b3f42afe9bc56e549861aff406f9958cbbe6100b1e35e91f1a0aa4e6e43baba2edaaab82d714e05211a73424efb7f9f50c1dbc1d39637a511365d67ba4e682be7f1b9413b7c5c4a609d930a95f396d066545019376ddcfb35d2bbbfce865e60658cf5798c41c28d3a27bd7aec3ef506f6cdeb26f635dfa0e64d4f36fd59713c55694ad6bd37b49cd6f11228ed3b3426fc12e47bf388c712f990c34d18b3b1833bf5e3e1ecae4fd81e082a5c9f0fd767bbf31fca3952ced4edee0cc14fd232493d3004999b3872b0afc837aa0073fa2da9eca57e523d61843b55efbc07a6fda3614c73a08ac10c32fb9c0d0bf18d41f986e6775cb7d287282417902d50f65b48021d70e561c7e2894def3774f1e6dba73ad1a7be8c47e661d2e3875c94e457e6b6401740080cf0d894a1ba515f07c60d5b4fb25ba1c59aac55e33a4937172b91ae0c8ac7d99004b3daaff098b1cc97d8f8c3759a94a2cbbfeb5ca2b9bd9fd764383a882ad87d75c1150003477fdce79fdf5d00f140b12c55de60cf9acaed23ea58ad4bb1c5af3d4cf19e3c216d1aa176f7f50a5c1477afa82c08b5ea54c8530f78cbd3d487c6882230c482fc38ecb07624aa036ba5ba0d03474646dfceb4d03b280711548a60b54a73b24a151b7018be841b478409bbd728bc77b1186ebf2641c12669383f13553133d4326a3f700e911a8a582b47f65e2ad7c93e7ed23171cf1af8f805f56b3b88c66ed1accd0a1c84343b0fcd54e1ca9205f2748d9336093683d7adf3dc4877320c09e9db604f64a3df684d22d68a9d1ef36d4d2086972d39cb8ce97f88e3fd82bce03277545d18d3c91696d76e6f5f151ba740bf4f58afc375b0cdf12cd3a4ca71d771a392c09e01d31492cf43ba648ae56e18f02124ad9d301f1d6b6692f9388ab564c0bd913914ad044b80f3cece413921581ec5be89699e0ab56d2c1b1ac1f7dbc9cd6860739fb605d4fa535b6cd2680094ae72fdf7e7a5636b9426009ddb0c3a09717a257f9ca49e481fa075d2f8469a86a1bd33df4336fbe10a256689d2cf0b91db73ea8ea0db06e4c37eff09f559846183a5224c0f1ae800d100e51b03b15f76a9aadf1e9117209784c8037e24f29a2f12f1fc605df6d861e319c3470fb4c40436aaed428f682bc962a023f4e3fe6f516aa8f13bb8a10778f19aaa1092b87acdde7bec77581656db2dbe60d51c9cd1a8b4121306af0a7991bb2cfbc3cf4bba74edfe935a73fb3216dfba5103156f530174bdc48a83f448cb1834237f141f54cb52f40a800fa6de481d72780e92dc46deea408be02e4015f9fab245d1c7005d681b1f918493a8b02ce542a1f6b664f7542578c158948a6904155ebd3692304ddaca005129fb327c2a26071bcb9096642671062175d6b2dbeed119c23b0b638d515b9b2054dc404dd3d7d95048aaafb2ba8094d3f6c1e36b9a613359ee6b6d35ec052d2fa5a4698c4d13d9f04b6c0d906cc88c690f66c79108a98989ca781a4be5c700779c893f7274acedca3c20cdacd0c80155d9adc7c5c956addae7e05711f8c37754bcf888568786f7a52dc9bf6238e903f9086f0e84390990641c55afeaf57679acd3f9436692c5126b4d7adb548d01c13accdf7f0477e8d1b5552b6be38209c9943b805c6c3d58db70b8920e47563a684f93f37c9d09b5e268a2ae538a9fba472c024b8986aa102d8a209dad70d17daaafb0e672051b276114b441107abf2c0d693eaefdd63f183ebf9e084dfaeefec891ee0fbe172be1c2ec047ac2b7cc2a4bed2f9468c2bde7c096587f957addabc314206db04c5a12e6641f6c16ffb82b5a58cba57693353cf64299f40dbde9d2d7f38857b84c273975f0937a883e9fb60f4c4f389ef008b506af0b0fc2d304e244a975c6d5fc03d62d149ac12c92f899417c2e64d12e21793e51d74e6e455c6d5ed66e0605621ec7c4fc7dd74b4dc47023c78abc4216a1759cadd9005e9e739b9827b37e942ecde5bc95f8ff57cdaa819b09e7ff21c47e0368b5954c33e11642a2d7382795b93f80e55e386509890fe8769056f5489ffcaa6fc888ea5fdc6450a2d1db1dc75818101d123adf5caee99728c87c88d409a248f94e2ec541300aff7794bf49cdddeb18a481b4eed252b9576836cdf35d001eda8e77cf61b8cc3200e261bd8ed5e189748126a0c5fa59c5ff5e6ffc22d23515a18382ed6cfb6a4de8afdae7e9d28a5e0f1863c9e1f99cdedbdc212819f00d5cab6f6fbad087b1a7ee6cad5f71beba79d3103077770931e3c946d25a75d170e2a0880167bc6fc26d013dcf5c40fd13ad7c9065cbaf38a6333aa2be3d25f24307d01d10b02c6d1815556765644a483d1c8bf5b46ea6f70ea65c4546aeb162f978fb00f343cc4a61be57b4429cb254f0ea3c21b4a62d922c016244711deaed83845c8ed25ed69b64fa555cad09237f5757c786ec960f620ce3e37a8c7b9546f8ac3d3da26f9d487e8acee48ccd268874b186e4c2d05a687adecdae1cdd20e680825ffd6ca291fb1091a8718f2a2f5ae541c02627979aa646fd0f70a6c563587623cd3d5f55cc03756911de1f27fac26dc61ba7842fbc50c3509819cdb735d85f61f69b02350b89c4a39a846e3fb3a1880bd6365fede07809bce1205e60bcaf707543b1c71e2b40c159cc63894942ec44b481ccf07195b469939c86ed5b4d927ab7e479de7575cf30134e5dfdcd7f0d405adae4d0c90cb0f060fb2932cf05bebf0cd7a28b9b2911dec346c951d03f837fba520f87b8af38d30075e432c8498e79917af3243a96935a775704ae4c3055f89716cbb8d913066127590b5c674c3f8197c2d0457aee02c6302a03c50e734b1682a7186c4f170db293e4665e03a89b17c13d86cdc2b79f3da083282ea1e008339a784ab93c231ee8fb2644023a4f002d3d77f46284ccd9a015630e172e249ab4daa0a89bf6ee5b20c572f0f252039b1cc7834e5cb852295d4818d266749a424ad520ed490027e85d408c5a110f7b0a2eef17f74ab25c284eab9d4cb2a2537061dff55e5ae0fb17867646bf42b20f9cb0405f6306ee745881f4a83d558b68ac4fc2743f551877168693666e23600b21a6aa40dae111116ade4f74509bce47886bd3057dd23889a0e2fdb5183be9e2c9cf78409e5e166b790c743d742d529f266b384647ae924f3bbb21159c7152174fe07c4771b35ae4ac65e7b305440c0ef1fbc5383dfbf29ec4bab7bdebe001c57b119314aedcca2f7a32d3e71ff22cc4cd9771fda989354d5a9512f38d4576370975d09285a32c440febd1341d40a6cda51911766044c99823654712cf87c53fc6b320d36a74a2e9c1baf8234a6b6b6f56552497e94887636beddc855fc375617cb1b9a7d1470be5e6c02ce44f91994ed72c88b7e3f3f0f046eb32f5ca960b9681ba9b29808b374aec5aba3694b0b037e6a7d750b583bfa05783d714c329b85f27e1248aaa72518770ce1f8d1bedbf0196f894a2ee51b79e9abc20f743201165e7f4f01f37c41745f41f2db4bc706054fdf75733c05abbf6fd1316399ee76cecc3c39e17d26f2412b1f2e97f7deb847db5771bf36590c4c2d298a9ef60c8a44ad986b19c1e119a0b6641ff166c68a59ded4b8c7504be8500d9b45f0cc8257cc2d28794900c3cefbfa19f1b2e718ccdbf31efee3405ffd3052dfb7e8ffc4f726c9834df51211cc2ee21b75dd60ad15d6118247e928b7b61c9895992768fa6ac5ed8e43fb7588c1178b93d1e6d83ceadc40aa6a1af4028c3fbda70725c022d7f701a20108a36f7f2bf46402e07a93aefbad0896ec7a6023c3af3fddc1c0732a5ba95076a8d2a5e19fabf62bbe58fc2e5c2e2eb029e6b8441b82fa7c417f4418ada475af13dd60d8f73f16ae51d67808421f768360a3a5f3d480ef3d35cfc2c126607a6305d002c13c3229555b44cea885e08e93d0e57491f54d9073ca705f6d18378a0fee1608e5a84e908ee0fc4e70720f6c63038c348c181760410693174068e91e77a28369ad98eb185d15170a2ee18ddaad8aea14931625e79b5a0d44b57649224e030fd4f52c3c501bef8343242894712ad343300a6205593c8b3ed02084d9599535f8d967a72e0e11723b9c799f34aa2b2f29c6d0c218189763c67f03d5660f283d92c100b4401d2170365eecd3246c223bced650274a37c3f890f6a1081d4fd09a48fd311758ac35d7b15ce1e75f1d2c50676fa34b6535e0c014a8630bb34d518d45684b1540f60d7a48c3c0cab56a2cb0a0365c87459f780cf7d2fa5b18e4368181d6688881ffd7da0838ce760807e351a405ea177bd62f16d8413db17656cdb11c19fdadf140a75f9175d9d0451990b9a0964d5db7594877f3cbd61d2a63c908b5403b78bbca2918d4860b3ceed76b28ce90dbd038e9da66f5bc3aae57c8ea3beeab0560a4d7f9f5b30cfde6d599d9b6252d5118aac668f36258c034025b107863996dfd15b2528ea5a12072b40456f6f11dac6f68020a607fe3f253c95121be2b17a302d78201317cd17fdd80dd2b5372af870de3aa86dbe6030cbd265d6253a54537a6813ab206ea596790495cd18da085a9d3ff4a082a9fdb7edec9a71006d80a690f2286f47c3612062c12ca0f3896c723c35fc1e6281d7f52ceeb5e2876a0a596b456addc9421251ad0279449d143d3b0343207ae60888ad1c83001adc08e3487c3768e60bf740c3c207de456ade621e3ac5d79886863207d88d41b9d3ea509bf4064bac0f8cfe96cb4fbd85a838f537bc2286b5bc0148411ca1516e87513e52c39d0d6a87e6506add5df8fdcacabc94f5c009ff4a2b7af4510fe1562642e0b8346c5208277404a6108744d6646320e22def0b8490229da1b1cc579579276d9defd7de89468d56fcf0368c06297e9d1dc12705c73300358e728992e9526d2f326997b4c920cb598eaac3f02a778afc4f58680803dc1bbfff9a8f023063e60de1af393146e11a53cc2d5c123004e116137fcf0101173efc03c6b05e0d5f5d82e1bcbf7006bf9a9a1950087b324d124e5804eb3b944919a89b891da7617fdf1d0036554b599dbf410d1ecf4315606a802a0b34050d32dea543ba12a5d322f638d1090047f03c5814fd95ebd6d7717eb0e0be04079660d4d5a398a0c602b85a7f8749f2ed684757d82c8ffd07d487ed38902a8dbd3c3d416633892bfb97a2ecfd11b031ef06fe5f22d46906823a05786ffd432f010a012f5006ca7b8fef95b5c21f9d54206c0af687b267dd24cfc851f1e3ab843e3f398bac24051adbd337999c760eddf06fc5f779460925ca5df1e4f9914f38d2cf64ce269a7b5f36cf5c4516f8baa07bb1eb5e91109464eee4516a4ab6cdcbcd08de55dff247a8d14feb11606fe5608fe2c6153e0bda747a32005bff3a3004cc9d39b670b0acdc6440d8bcc44d0ce02b8ef2bc0edd45aee99382434d51e658963b80cd00626c6feb566b255c960ff74733ec9e3c9b3c8c6bb31630687b916d134542ea0e19b2f0f97ac896e65d8a2504d144643c73fd0d1c9b399aa601f42cc4ebb26a00197d363a722066848c52b74e767771af28279491380bcb7874c502db0d5bdabcd58e671e33146e9a265501debe10e033bed2bcd035017bd0a12dd61f8b5037a2528ff611bb6778b9c6e52c2136595c590cf6da47cd9657bc34afaa97db343e1348ff58e387f53a042e20e66540d764badb5716b8a2d0e2a9860afc4adf83e213f5c4016da19e0c4e1692b88b76965b988acfaa5abc7a15ece64bb23529c54515f2f64a31be00176e6e7d4b0bb015742f2065b1ebd0ce2f273a320d22ce2e0571a619100c9f56b1f791f57e52c54793d42f7eb7ab5006bac792eeb5a669626b4a8dde122e57646371777d712ae1cce6b0037b202e0e261cfffbac412b044460f401b960ecc4fed8947d971c7e4e601836f595f0cbdca7e40fe944891a584c3b29096b016f641280cf1d12cd9e6d23bccedb1cfa2bb8b0b1f8579043d96e5c43821d8d0e0913921dfcfe2e31b1df65859a2dfc39e0ff5a1b17c43fa0f7c7a758dd6162eb2bdcd15b0605a573505f15ea3d86ec79f03e6ce1ec57850d464719e6aafe9663dd4b88cc75c79fe9a02d92c2bbdaeff571c22cc86c74f5bc27289bb5aca93721b6c3afb02cecaa836371601c33666b2efd8b04062d9a71dae8168e68603b223f88ae218243294b3197927cfdf6b2e721071bce1506a6dd647367eff7a10a3f046262df0dbf8c8c6968406735fcdacb4b43a520144d2700d7df3ebde10c704664d26a70a55e1029e4a85d00d3540b026c3013c0c3c0c3c0c3c0c5c751e8d1a7db2e224414a29a5a2df0cb4e7324a29a594524a089ff8dfeff73b8e5ae7fc595b9b61e10dfa0db20d62808058198609347231796ff4aa4bb4831a155c4cdc4ee1c24573b80edf62927e51fe39cfde4a4511b61e3e7e1467010d5ba85fd7a6f46b648911dd40a31693dec7d46993efdd7d1161db511019243d4000020202726802a8020d5a4cda54d197931419a99a085ba3922ff941825d018d594ccc97534725694907dd89b08d948484f485a1020fe8781f2a28a4218bc42e44ab756c354cbfb425d088c52495d44f5e5f0cb3dbc262b2c864d2ae2eaf98ec3dd697315b909d6b2fd070c5a4f9b1be58b11ff53e1b684edd021aad98dc779be799e2d4aa67564cce74196ae2d28adc7488d95982c62a26a70a39bf1762348cd40472a0a18ac9977f2da64be6fee37f200c31c2f040186284d10131c2e08018dd041aa998a444c978dafc74a98b172a26bddc2599694c895ad129268fca86cb645af4d4668ac91de377a523c372be420a41032b5779d3332a448a494a65bcbed83d72b33b8a49316f4c49f8ea7ad05010344431c942f4e5df5428267fc6cd94b4d6998a15504c4a2989ae14b35ba770178e018310015482c6272675aa60dd223f2c8893272626cb70496c5062cce44e4cfc4faf529a4f6c7b754e4c2ed98e99be7278aa4c082a29630323256494e1430c1090ee316010c2031a9b98a4b4fff552e34951cbc70404e47d204d18c8a1918989a72a747f7edcecc95a00020202124203139798dca5b473d219a3c88f2c31596676ce2dd6eec67025265965f7109b726d1d8246831e3a6ce04a8312067233a03189c9a952feaf98feb772878624266657780aa13f07696624265d79a7d7f20bb723484cf6302b1b3f27fd79d32326693769b6ee1d634691232698d4d0acd1a7648e9f464c0c192f7758ae0b1f7e464cb0d89a73ccc1ca2def8b98943e8f873fef5c8db32226e71cf3aadfeeab3a9b8889d61d83c5dacab89e44c424d1a9c4c79c36b3987588895fb23ead7e47c310134f8405bb1425934a9e2068146262beca9553fc8ffbbe126282ac9494deab2c3d4a3988095f567bf137d8b886829898d3abe51272b37e6cb140231013ef366dbe8d97d4aa31a00188c939a7c2a578baa41affc3c40e42894bf5624956657e9858fab36e26911e3be5fb30c9afa25a099d829acee1c324e1419fb0ca231675dec34437f9bd4b49cf35b534f43039f4a73af579ea4e4579989832e6dedec77bd1c1c31d26a795d968ba62c16bb337d0b0837217ad73ecb8c13e11b6bb22d0a8c36131c868335f1068d0c1408ac61c2668ad8e416bc5f5d2f618300829a1218749b2c9c2c89261e4e558848d64840c341a714864cfa90b4db33b0a19396a75773ea0018789e222eeb631ada90d85d8f581c61b2658675c1a95413dfac70d93425aca2addb6b374db3029a6da4b0b9b9a7236d93041e8cdb1e4d3beb90727202099041a6b98d82533b37bef359b7d76a0a186c967ae791a642a1841184a42230d93323e8d698785a6ca4781061a265f255d51b5ceea65d138c304215b4c4d57d031af98a170afb12fd14cad3a1b71a6d4c96c3e5662743b060c424868946172baf9ebb5a0e2dfeb4e8609ea4ec959ecf3bc9b02020202d263c020040734c690031a622883461876d000c3e41c9a1fffa53fdd3d5f9864d7994574f0af4f96f2a0e18544a30b13e49546b92ad1d6cf120434b83039560e953a27ab1b3f6d61e2cdf5a88e59f8d6240d2da0c473da5c29c534751626a99ff59f1af7ae74c2c2a4f4a2296806933f9bbfc2a4cbdbdf9dba39d7ee5698a8d1379e4a96aec2e4d1dfcdac544a630e53a1b49311d5dd6c1b770a13bc2da6e8a8d8be47a5808a62b59effe45e10088841383073048d284c4edaa163cb29d3174b284cdcfe521637d66cad4f981c2bed7c4e973e6a874e98782652de936a8abf8c44074f8230c4280389200c31c2f0814448fe03aea0d184c9235a7f99d2690d3262c2844dfa64f6c5f286679630e145c6b3518da3f9311a4a981c54ca9c419d88ccd968246172aad71473f2fce3c6d040c2e4a4316851b3179f3399000c348e30316ed43f59da4b5ad68d30c1db2ae7d54be249661a459818948e87d433f5ae9408136f5449d5a46ea1f33f8409d27f33c758d13b8f2c8449a373ae59b6752e59348230c983300d0f9a6e4bcc54a00184895d6ea16407f9a5a3e51713b46cb8126b71637772862f267bb4eb549b5e4d8bc66098d18bc9a15436b1cfaedd55f3629206a1975963b3e4c744d8cab2306317c54e77cbd8f46139ab0b6e8318ffbed964f25c204bbabce7899323272e0ef1d0f5ca75ef4fb936d3d9dcfc4dc6db9591f13cb08c19b79868ae95dd64790ed39c76c40c5b4c3abfb79cfc5ff34d4e34c48c5a4cbad6e4a1d6ee77c773ce42ec2c0f336831f1947cabe49ea3893b8b097ad942c611ca42288b2c267859a6e89a7ec54d8ec544fb8e9f9ef7fb2b2f2c26df879ae7b691165a55bf62825e4a71199d514c75574cce2a7df5a4bbb3c56ac5c4cbbe7e9bfea33c848c1593b359c6759d4c8b414782305430823040400e31631513d784886cf114e4594515933f669f713f99544c0a3284b436619b93deba08335031d1c4849af55c7afa924e3139c7cba262b83ced9937c5c49017a33da8687d9b9762d2e9109aba9f3332a498f01b63ca9f53ae908b4731419eca4a2df2fee2b5a2986c39ab534e79e3ad77a198142be43ee5ebfb188162c279cea92e65f060b27d62828e1a93bae9b00ebd27269d8753dd3542bbaed59d98a055b3f62859bf22837e5c8f199c9868232cb75f7d8e952a9b98b89d5378fd1c3326796b625250bade5cc764b4d2332313136dd3c8cf2996b54146844d7b8cec10030404f518d961181393b77469ea53a6513665c625269adeb5b80a193c6c3dc312935ddf66eecc77640c89b0cda8c424d35db313f57d2f22a36307c9e9814a7480d8d60cc20176600625268dcea1edca365f681506332631a9e53a6452930b267f494cb2b4d4fdb17229c62e12135fe4c7d4696aa262161293f3a5b66b7cd89fdbbd30e31193c487f56728fd95bde28889d9fe35c724328755bb11136654deeeccff7e93996004613062724eb2a3d5eeb75785125e0956508230c408a30364fcd100da5174d0a0c78f0e8080e88c454cb4b04fcbb94222bc821e2538ebf123a4c7081a0f1d5e83198a981caa82a6ed1c2db596444cfa146c4fc90e2262f2c58b5f624a9fcce71944460a40400e31d162d48fd5d2a482c544d8748044ce43ca781f3e1e64862126dcc7f1d9f3709b3ba910935cd7630a329b3cb3122126c6fb55939b46ff47348889b295ad6ae79db27c0431713f6d9397efdec6261093b3c7a8416a0ef7b117404c0e0f16cce2a56ca3e47f9894cf65838ee3a6d2cb7e98f041a7bdef189ae2e53e4c8a1ae44b887d69062d1f26a70b573168103aedb37b987caa796fbbde355ed5c3a430cd4aca64f230498bdc87d3b942c69d789834aeb71653aec368f10e13eeb734578a1c592fda61522965a136dd43d5f87598685ebef6e9dd63262d0361061d26095ddf50717e3b4cfc31630e93643c699b2cfbad9545844d0e9384908b8d9f17b623e1384cd88bc9939d8f97103a3dd08e101f0306213f980187497396c32a09cd196df4864996d77226bdcd8a39e386492362438ef586186969c3a4203d778cb9ea92669c0d9366c66c64e9b398cfd730514f657f90391f2ab46a98f01e52c4e765ecbd9b8609a23456d67d3f1d648a8649a3e4fa3ea96b3113ea1967989841ce5f105a4353986698fc2642e78cf18eddc1324c3eabb64d1973f8fc906162a510232e75b45bca44d8caf051d20391f124b80ccc18431647b673ecc39ca533c430c1e4c83caf753f52c61e3a5a49ca8c304cf8a066dd325ffdb80d860942c8ec269d437e6bfa0b932a6c26d774756ec2f2c2c4516feac4ebc9fc761726a76dc6e54d7a93d09c0b93825992e964d2ff55da8c2d4cf66c6951338818ab2c1c66686152fa70315a327d39a7b76146162677921b2d29119e325bb030a9468fc5edd11bc5d531ccb8c2a4a42c636dd02654a9a408db977c7fc973e0ec665861b25c8a5a5a45e768aa7915265690617378326d3acc549894791a4fdf4aca299d30c408430523086324f5c02dcc98c224dbd34153735516a5224618933054308230426c86142608d58abf39c551766f14265690f2222753e7389d085b57610614266599509ded251ff624c2867c9071a685194f989c92eefdbfae94d35cce0e339c3071574ea7a77c71542867346182f88e391f5e5452a7313dcc60c2c4f55152e39fd4e0f14340cc58c2e4912f7b4a2977513f95303999eeec746de2bab9244c34d5de763aa76c1973f447186314fc11860ac228fa837d300309785da6be5abc9ce78ca595a8b13c5f1fc4bc1b08438c3034108609461046ee13661c61b2450dcf1fba4cc6934548fe036188b16c986184c941db3f6e8618b78b75000561288f19459814a672cec164e88cf30969f38148b00233883041f59cdc6c6a39655f4809a24109f2c08c21941942987499936cff505eda99118492ec20a7839062af081b83a0113380f08b89a32fc32fb5083399b730005f4cd2a647c9142f29a9a20e921e23cdab89778b01f462726592695feb27674b5e4ceaeb7062c673fad729c2e66503d8c5241d47ebdc3b65d4e5ba98a0920e7a97bf4da971b530805c4c3e8febd87c423b5e0717134353a9fa48594b1ee54b27f5b5ff17b40d8501d8626212ea3b87d0a2da3607ed4007492d267db2ce5729b773a5fb0b03a0c5c4d0a562cefe460f7a76c100663141994eef778f7d623b2dc100643149960ca6d34e25c2d63418402c26cd064d5f4153f0d660192367773000584c2e9d3934cba9150b721136927cc5e49493b66f557413a2523118802b26670eaf9fe2df843ed2e3ae1513be62b6facd3acf3e8bb091b062d25f5fbacd07cd503a3dde9ced18c02a262615378a755e69acac060350c54455cdc13fb788bf6b253d100e50489e2e25b48bc52dd6312f9eb2e966627a36e7d47136981a161363aca791b3255abbc221e6af98a4824c9a8330e53972bb62f2969818359fa7e43667a31513935613f24ac8a4339a6830b2a391157c388f11cd1d47df9174156a5d988cd7a5a7c1c80e54056a9b6916ba26aee9a9e5f1afee238f8c8006341819011923638080d0606447a66272c5f7acd325b7e65134021ba898f461545252c46d92293e525265a79814cd74348e4a62e456820d534c50ab15e743e5e87773889561a314933ea5a084ae50212284a498e81d5407d99a49dabea368d575e3e5446b66743cf3ca6abd7d9aaa38896262c89d0c32a6fe4abd7aa19864327aeb6792b53a0f28267e8e574751f9b6967e6272586b17ddb451d47a38061b9e98a8c9b299dbee8ae9533b31c173f2e4196f7f33a87062a228b93f99cd9f146c6c62b2c836f5f0a0cd2ac8c1604313137f4e4fac7583e65c666272aa9f7de75920214eb081898997c334dd7509997de303f92526a7ffd812a3f4cb3d5b4b4c5cad9227b795a27eaac4c4730b4a3e5b6e8312934da94ca773644ad9b39368cd36674aa3b1b327892badeae6f55b5eebad45785e511fcdfc6e292fd888c4a4586e9bb26853e5a56303129336f8d57b4ee972336ae31193638efdeb9c62ba6c77c4e4cca829983e1d5a4d3d748484ec0834b081128cc0036b42d61a31a9f2e39c7dd02d6d7a57c1062326a750af6019c39756915bc1c62226865fbde88648ca7813808034c1862278d7efaaad5313b7cb41fdb4621561a3811d0f1b89381b88b071880932bb745493a7de2463884949474ba6f8762126780c9d31da290931e1469c38355ff6db978d41b819a223e75af6b59bb1b2ae5fa162cc10521b829818cac3764e5644cf2810134f7f5d3e7c65396f01313964435444c7f6d3fa0f13dc722a55c26cd5edb4e1878951f635f4ff4ee9bd7d98d49a9487117363bda70d3e4cd04e3eeea929e6a42718d8d8432b23b69eb19d9a76af9e237e2ca87899ea7e1b7a98641f26c2649ef330d9479b28ed156b117294061b7898a8eb9d4daf2ac8cd66e30e93afaf479508ffddca4418052e031b769874fea6cec6d3e468490d36ea3041b78db50695af946c9a0e136efc82acbfff168bcf61725f66edda8c954f59351684c1861c2688bcaffa933e9faee37198d41fbf1baf979f628a2a1c26b867a9b47a59df3f3a7a6cbc61629261e27a964f4c8c6744a404914007191ad05638d870c3c4bbb652ad8ce1fe82011b6d981ccbf2be9b55c9186210109215830d364c9072eff13288cd7c695d43ea6153ce6fc212820d354c900dd2c225133a63f8692c68316ca461e269f2d7d0f9f5bb6d344c4e412be8f40b52337c6c9c6152f86d18d1e6e3f5296698a02e26e55ad2df64b836ca30e1a388b40aaded394d324ccccf9f964d34853c4d0c37d818c3841f5f8f1dd558779b1826aa9d07d3ad98a196db08032a36b35da1d7baff316f29265369ad0d304c0eea4644a898f3c55049c3411a0ef00b93773fe9d3d0f726cf9246051b5e98f0419e92a696a4ad076d7461c259a95a8ad2d464bd0d2e4cf014326557120dd69b1e36051b5b98bc99a67683c8a7c6181965a8c00420203e46c8682ed8d0c2c40ea582c7cad1b3e56601084848192567061b5998a07bff17df6e446a8e09ca28010129a3e4b660030b932ac714f71dec5684123fc1c615267cc99c8e5e9add632a9960c30a939469f5b18c6ea61e5485c929997d0c9d29e869850a933a63b66dd69655f9a630c15df478a794aced62529820b53a9932a52c79a6d20836a230296adbc58b6ed053591b509838da6fd3680cedd5a5274c3aadbf95b2ad369c305135e7f7bbe95226f61f4d406f079d7de7ebe3371326668ea7ccf3df9529ac6309ad9ea7c69cbec875ea67e92dedafd9e2aebe49060f1d684309934ce8b014e522d5dabb62230993f3ed52ee13a192c14307be0d244c38d335ffe8977310a1085ba7921f4ed23e4a48106d1c61a208f531eecae2a6648ab08590e8383302eb16aead1df6a61ff26f1d6db356d56ea30893649f8a499e1e4d514f84ad53c063c447077c9490ac880d224c9011e2b3bb6975eb48842d4d078f1f3d6c0c61820aa753989dc6d7f288b0d5ad0d214cd878315cb73a9fea13cf6d046182ba700b7263752a9742464ada061026968aebbfece19f627ca4447f31c1cb2d8d7ac857c5309b2f26bf8916b923e3315767074908193f6c3032b2c3ecf4403c90da19f76252c6cb964bcec91cd3891713be428d7cce116153dbc5e43069167bce749097f9ea62d2b8a76c16cc7f45e823c4b5462e26fc9ad0a4e48465381df3514282b898a083ce7fccd1e12928f92d26a550263b3473e6ce1d42628b49a1e91737bfe5a6364f0f1d39e8f163a4472d2686fb7cbe4e9ea4c69cd342abb8af7cb9aeda1811d395e25af486b39854b953d0c162aee84125c2a611a8218b496a43555099c2950c3fd588c5c4ee6c2fe3779e9303d4037d2011e3e3510a7c94a4c08c7d9490c022d32e2d1bad1717190bcf1964fa7861f459ff8a89e77731e3b7c7ac3929c276e88ac9f9fcb372923921968bb0f518e1c163c4848c9484f8692b26574e11974f08dd5f325a42a26304ce8ac95e9534968e9ed44b57ab98182b9eaccb1171997935eb121e491593bb72c51053c92ac957478d544c74af9842e8d3cf7bf3bc094040487ca0de31601042831aa89864bba6d5772f97aa94534c103336fa44c8302a42534cea984f2ae9959b2e25b42dc5041d47d57f475d322debe08080063d1e052020202024a498947745cf96997dd01611b6901d3f789459a0c62826e9b520ea528e5e8e1511b6cbc10819213b7ef0e84a1d1cd240c7067a79fce881a29894257a19ca736bd87dbc880909193969eaa384241413c7afa2893a7929936b74f478138080f018300849354031493d069349d9eb474d89b085147e62f27a9eb8a4f477ba213b762093353c31499fd2665236bdfac9ec18300889418d4e4c3e35b2d2d37ee56e6d0320203b7620c38909d2f3857fcfeae1ee31a2a3e4778ce8c041c8f13112d263e4aec62626dacee5efa83da733e203ed20a48c1282031d2704af84a48769627292cbbdaeadfb40c7c7c865a0462626a78c97f4ecec8fa5743950031313f653c4d25d6c44a745d87aa01d21a7070a4146c70e923cad718949a54efe9b6b7d5ca7c78f111f2165e40b6a5862923613b3bb794d8f0e9bd701da4a4c741bf9e0b631f55dc81809292141253e46444842dcb499c78f1e9498986262949fd61204352631e97d3ccd2e28158d9e2426f68dcafea9b1484cd039e7e52cd2b3dfa52131d13e4c63b60a5fa5648f98f41eb7156c2ea57dab84c4119366d367ce8ea7dae98f0183900fd468c464116f39641af51c743aa9c188893a32cffc74b02cf5d869a0c6222609353df2cc647ace7d50892b625257d660e9727f5b3611b6f36420488d444c52f3b0d5983cc6da5084ed6a20626210654a888e1ed6def3719e8c331fa8c40f3131c6f7f5f20ccf51b2089b96f0480da86188c9315e0a9fcaf54c7d4834e03a060c425c50a31093b2c924d4c42719d4b7226c253a402134f851d009597b1143c23e5ec4640a6a1002cfefb12c3b8f29c2d6673f424a78a41ec4a4b0e9e275ce66a3995341dc5a752d9b55fb5a7939bd2fcffd31468d404c0eef61ba729af4db527906d4004439c6e8a89ea2e978fd1ffa1cb425994d4f49a7fd60dad31aabcb7d7eefc3319c282f753a98fcf0a111dd294f5bd638ef1e26f5e53e9d4f5f50979e1e2695ae98332995c7fd2ae78c78d7c8c3842f1d3be820548ebd321e2696cf9c59d22eb3183a237798a4a14fcc8fd5a699e59c113b4cbaf479c406751fd4a5ce6bd461828aaf1b839fee986845b8e4078f90919290a6c3c4990df931447aca67cf6172f588d2ab205f41fb7715a821878939e5f28d5d1f952a2907231c87491beb61fbee6ecc54233c467c906147811a7040a7d5bde65423fe59086abc01a1e4aff397452b7fdc40478f1f21243ab60435dc3069fbd6c5e35fd65e4e1b26e5bcc982b9f6874da7088f94a0b1013bb578759d640a5b88d151f22524676b98983c78a732d589b0f5064850491945c78041c8d550c3a48b395c9fc5a072aa1e04a4e4c74819bf0304a4461a52d5d58b9bd58abdf67450030d933afd67fe54364f3953e30c1394d4db4d22e46c142511b6463e46c4f0f12c281b483b6483df51d60c3e5009c90f1f212109a8518609ba67f2f9da62fd77da946b9061e2a735755abd93d0a9c1a0c618d668c232060b35223722a82186c92d9bd26ec87c083ac31a6198745629c7f424776d54030cba555da7ed95cc5a6ddbe630ea7173cce14711b6103e418d2f84d4f0820c6a74610435b83029fc64ac990819fd926a6ca186167ed4c8c2c44a1f4ab54b4d5f6c45d842ceb68447da1a58e0313212b2e3f80809c151e30a35a861056cd434eb4bed2a2de6f27daafc246f999444eed4a8c2a4e8b549efe5b3f76e6b506192cfc9e6efbac61426e58a85f5bd065d421d86187e89a8218589a397da95a3a73639310f35a230495909996c3e4b782adda10614267c967eef9cd46a4c17421d30448d274c1215ce56c3e59cc457c309932e9f9b8587eff890f550a30993624a41a84e21136163c224a5d22995428fb80eb741516309934fb6851cd1d1c414c2aaa8a18449225d46889339c8dec614359230319a8a90dfe13d9dc7bb14359030e92ad9c8d7cfd2333a4798609d4d748c375beaf6166a186152d5fd657511f7589d6ba1461126875abefcd3b7db681261b2b88e9b98eead969ed3506308934aa3a96895f1196a214caa6c2d2a769a4d9de545438d204cb0cfb2a4c4b4652165a8018409a6d59684ca2957ee2c038d5f4caacf20facf6f93aa90fc382134e8a123a40b0d5f4ccc0e71236553fcd3ac1713b3c8f153a7ffa9a6e7c5a4d361445dd4cbe2fe70b4a33cda51feb44063179335e5e5d77b59d35517933227ed9f7f0d1b5e0c46f3bf3121bedf2f2689cbd61d946953d9cf1713b32a8bc69fc610f1f5628287c94baf2f2f26a5dc9fe7d1b9e3de5d4cf8645f555a429f6a4f1793cbca449412131aa3978b49fee935d987da28eae162b27b8fd267da693a79b7981ca39ee5080f9f3d79b6985c49ca66f711a6f7bc5a4c507a3475b2dfaa138f1693c7b3854e1ae5c452378b49b9721e1d4c96bc5f278bc959f1d4ea7ee6f9502c26c9ccba9693c72aa1038b4932b24a8a578a0c3aaf9818daf6afd4856ae6b862521255bf90316695a615eec6d7daebbcb162d2a68dab7fb6b5cbdb2a26be8ef61d9d53ff7a53c5a4a8b5d1f4ddffdeb6544c8c1e9f4b670b21621b2a266fd28c4184670a22db292676b0f98d29bf266dcd14937275b8fc167574572bc5c4cff59a326817254b23c5a48c226485176d14937392318de216a264268a091f3aeae70c323e6b168ac97ef5bd295812793aa098e46ad5b93f85d794f389c941d3a5a79745511b4f4cbed12973de54ce6be9c404d59c3ffc5ffe879c139334bd8ccc6fbce97d139392b21c6390cf3e62d7c4045d41fd7d4c9e3dde9998205e594a788e10d2c684a9ddba63947d894942580c4a69b6244cb6c444f9987477cca65450252686a8b5bdeb205410293131ac879d8ea5e47e6e129375e6fe6352297a563824312988caa1bd1d72feb42e1c9198746183a7c62fd3a79533c50189c915db4cae32091196537dc4a41dd3335762cad2b939081c8e9820727af5594e10f8d0114206491a8e464c4a31e6ce79d1d227a5c7c18809da1a2cbe2f874f1eb388c997a2e71caf9f7f55e350c404bd41c7a4ebd3dac850098e444c8aef23d573fc226c213d4674201af8184987768e884922a47c32f93afadd1e62529a4f8def3bb159321c869818d3780a5ebb29e7301261e3b18598f425da4bee6d9a8aa38f944e88495b6234ba8cefdacf3c88895639eb89854d9e16c4a4ea18dfd4dae2c72c8bb0ad5e2026775b8deadb77dbe8978990bc0809700022c40038fe80c30f38fa80830f38f6700aa6d2856605a51511de000e3d9cb66df2556e19bb326757599f6e53b08af330397736946e3cf5551d3c4cd89c493f6f89731ff91d26d85697b65f5a3b3bc9e0018232364042f2260001311c7698d841dc8d0aadd9d4421d3c0f17018e3a4caeec6bb9dcd483cc3e1d26a6501e455eff68904d0538e63069b3c9e5942b68c81549e43049fa677ebe3ad5351a19f1911dc011874969436f8b5e0787c9da59932795455d724dbf6152e7a07d2b7f2f9fd1090e374c8efb368fa73c9627751b267e7a940d4a835adc2bc0c18689b152f8937741e6aee86c0d934653e7509f9272918f473b8caa615278480d57973c698a49c3e94ec9a446c3643d9972fa6e7a8fb7e238c3445321a372dd63860927dda486bd4ced201c659818ce628aa894c4bd2745584b80830c93cb4c86caafcee86e978500c718266c769edcd01f4fe73ec490e8e0f1011c6298b4a6b46465dd7a1d0fe9f051922dc01186c92986fda93b0fbb72e106c3047129e61b3ceb83e40b93c3aad43ae6cf8d4945d8120f0e2f4cce7d277adce5e53492901292119110b437a223840c12edc2c40f25366d0a5a2b87100717266d540bfd5e119971d691521a083ad001903b1c5b6836064b2144838aea7168a1a03f89d9f3aa98c5038e2c14a76d5fea6e219faea3b4550e5f6943888f0c706061729f29954d46882a9946028e2b4cea154b9f84dc32d794152627ed7c2532da559898b6c1327ab638a830398e9cd2bfce62173f38a63069345ef49c826549704861f2d9979f850ce2fce238a23041e89f68cc65b5d0100e284ceaa45e2bee06cf24354f981c5b1eac4d63703861a2a98fd12e8511d9418ea30913f75c6348ebdad54f3361c25acea2dcfc726d8e630993edc63db7e90d87580e7028016780230913c5c4b3928e9b942c150e244ccc8d41ebb9df7d8ca3234c4eca57d64afca8a917871126ad66bca08416131f84701461b2e8974e2e426e8a31a903f40110101d20118383083ac03184c97a9dd25a6f354f0787106ebb38378d4dd554cf2c6dbde9e96e5387ce03471026a5df1863b6e2e779cae200c2e498ce736c7f99d022ff62b2bca55852d495903efa62c2a66c9ae654c66449d38bc9e927db4e65d3f0991362bc98b0fea9dc3a635eae2b0043b8b18b092b7b296544250fb1eb62c229d9d59e5bd397b79584a497c78041c8046ee4a22fbbb8ed3075b1719dc70d5c4cb4ef2f555dc1cb64d08d5b4c4e497f8c5b22b355f0d862526caf70b329c98ccdb5b054b6532e2b09db12328d4af9b1d06282a807a1eadff2582a89b0e140c7410e789fa11de5c7c8f19cc5e4bf329d155b1b7d39594c8edea35a834547082af990327c94a8dd8845315aa4854efaf7864532c6a5acd326b485f5156ceec876b57d587c5605a9a376c3b4a8a6b862d2e76f1b7db27c2d07b56272124a88eb66f80ba361c544cd5a22d7298fac6a5731b162f2b0cdbf30a63396851baa9894ed2ace85bd0faab420201d6268a93854dc290ce48629266c8652f1e6c44edc5c8a49d1b26d0eab8d1493f37b438cdf7ec8b24731d9ce345c5c955ce89ce41ba298a41d459e4ad53cb5b00e9088f9b8118a492a5999c8d4f4bb3d45d8ea3070031413d5b3ea8653aa3f4201c88d4f4cac3c115a1fa32a6f1432521242860e1b90b827baeb4e9b911bb3ca9a2dea22639e15614b23216ce7110a90d1b12305de89c936329ece1e8bcb41e3c4842d71dbae9e8305f17b8c9084e0d08d4d4c4e2a4d484fb93ecf7567e7862626eefc79dca4de3f8b6683e751968964b436c3e2d5e332dcbad4c7fc7a716a377e72700313933ebae9bc7b34bd25bec4243badbd6e52369f6e2c3131f45c582c994c8988e88c8851894959273b4476d753da44d84674dc0d4ad88d49d8df90c4e4ee0b96abb6dc333d9140c10d484cee381a5f62b9c36303f325c46f3c6282855bba18eebee188491e2b3f6e48eff86891c1430708c8888e1b8d98ac31f7b5eef79cae20464c4c8f95577a54ce56cf22eeaacacedc76ed76d750515ad3686b3a2584aa8849bd1a6bc55654eb06256252cc612e88f5274f9963861b889894c35cca318f675eff7d8c74c00623232320c38d434cfae06ef9b18225e97709508f12a8e08621268be5e8b41d552df3cd370a31612cbdb6cee3a950ea921e3a464cc00191121d2db841884921a4c6ccaa8a16d3786310133683f618fedb9478bc6e08625285b4fd18dd39540c076272eb6f6c9efdd6967a031013b4bb4b8a9a76fa70ff6162ba942dd59c96694c2ae1861f2665b9a439a3e2c8afa03e4caa1695f770dea569e4c3e4d67ceafa792bc65cddd88321466b55ae89f82225254fc60e6ee861928cc9f64dfce7fb5c3f76201f6470dfc8c344f9fccf996aad193e11b6901ca01e6b1bb8818789252d84698b11297913a448c9939165945cdeb8c324bdc92d3c83ced7f10df13112d2c30702019b0fd4638c1b769814d3cc28e9f122a6536ed4e15a97d735ed0e4f8b774f499adcf8bfe13f3c831b749874a65e627699395c90089b8380808090cc618287d5f2689bb229a59310077070430e1375c43afff8956efcf84068dd37e2304198dcb4392bc60a9b8829791e3c74f8286983c344517a3799e5a47931e564dc70e3a8d8ce12a5b96172d5e9bff9f8f04159da303955b4f22b95fb394d64c384f7ba98b2bf7e94bc2d6d70630d13a36877f7947354cb086b70430d1354f20a22d5db63328f6407193c74ecb89186893127a39f2a6dec73d03079548c07d3b7614bc98270e30c13dd2ade95ccdbcc6cea91f13c900537cc805e5a778697de75c73a9d4aa8a464744598878f910ef0f031929ccb3031ed28b154957baad7126e906192df5b57c8d2fe98496398a02d74d41453fbaefb6248c7ded6f4f3d435deeb3fa95132c970aa4f178649957b4525bd496edaf80618267b3e19fd2ddeda4b24c2a68344471bc90e1d253ff40b134f44d496100d1a4eef85492a4b4be9d7b8e3a2eec2e4a82f6ba71d979349b930c993d78e5cb8aaeef2c61626fabca94b21c3e2b6a38549faab7dfe63775bfe6f646192e8b134a394c509b1e10616265efcfc1d7e644ea2fb2b4c54d34fbeffb92abd5ac6b76024072ac80bdcb0c2e45c31e6fe6861c9d2d2f122628080f4d0f1bf49b8518549d253e5ac6493f0cda1c2a450552e27740eaf4c99c2c4ac1861aa54cc6041e68614269c88edad4b31dc84aab870230a934a881295cbb0d81a45d8722170030a93de7407a56b5d42674f42a2a3a4c7f3e8324a4a900f32f647193e700c188464e0c6132679e718dfc2fdc46cf2861326e8e916cfa21d316e34a1b356cd9337bbf7ac4d4deaa3568a656cd0cf0d264cd027b76a2a67b58ab98409e3f9f5ff35bbabf336dc50c2ba96d2ebd75cb98b4950537a5132e58c93f18284eb36e33c543e34eb44aec3d2c95a1a994157b8718449d23c8f38a5e6a22c7ba64698709a3ffa594ae95b471f28c2a4a815d46eba30b9eb032db84184496936cfda6dd48dedf8c1e3c61026590639cf327f1a9476f5560002c221e6831b429894a13dc7d7f0ffd6aa08db19e11182031d87576f05a937823049d6d6a9f174f97f2b3a401ff0817230328231601012821b409818ebebcf82aef86cab8d5f4c3eef4db7709731e515615b565f4c929bf4fe76ab67e38f7c24482f269fdfe5cabc1da47950848d0495945142f8487cfc1083049594b101e785a741d7586767f9243676616d8e8ac9a6b68e7a76d88f9ab3089d449c4c176723179362f7375e6a18519363c1062e269edeb9d9caefa764bdc5044b3bab9227b2be225b4c4cc992bc68139e63bab560a31613e3c99c637db61c9b3f8d820d5a4cb0b354be723ae5dd7ccf6292a7f14aa32d3ec52e8bc9e1729266050fd893809904f2ea1680b7af58ca1db08002c10631059812921f3e6804a08c220132720480c407c27101121d647c8e0044210005a0000048480ac80c017cc91f101a01f8923f233e406c00600008c0e10385d8c07c094948480100108003d8c091a30d3872b06152c533113a7c16e13efb71c603f908c1818e1372dc4a7ae838418e35942012354c3a31eadb314ce5f62ac2c69b230d93fd92da3c65ea73a52411b6e58178680e34dcc871068483111e3c100f1b39cc40068f324cdef1b4ae3b192647f3386697bcbc3a1721f990102f493a4448140339c63041ac5ec45d6c5c0b43427ac70f1e58811c6228830cc303f1a891230ca8a3c48708c98e90101c39c03049fe7fbef5eee5709a081bea28c1818ef32324c471a0e3fcb8408e2f4c76cbb12ee728f56fb71726c78a77f3c9c4c64a8748c8c88e921e20e04096f4d081243d7494ecd0f1a384f8e01c5d98d8f9630919511dbeb339b83071bc846b7dca31b32e97630b935b36e93ca295f3bf1262245a98789fdd4c48bd2c236ccf918549c9932eaf24fe1c589898e97286ac129a465639aef07a4a15a3db9ac30a78a7d6e6b866d7dd9c65a70a1fc35e5ba5534b0639aa30b94f87b2b51cfb6352a930f9f673327d39a3f79a7230220608480f21c714269dda85dd985cfec3490a93b7b34fdea9981c5198a8aaee39969272406152feec9ddb3dcb821c4f58c4e978c7bced4892c309bb5c5859c7975d7ece94b4be7fb5d89ba30993d7f2eda79c62d01921811a21071326a77c41e57ad6980bc21de458c2a4d3c92e07af51fbb1b3dc831c4a98d851ffcc36e48bced88e17428e244cb6d79c2f37689ff9377990030993ccc2544ccf252e57ef831c4798789ee1ad4653949dd2da90c30893b48bc91c45ec73438e224cb2ce7932c8ccdfaaa5d721071126e9f6934b5af392d2ef1026e81ba9d93125b1972308c81b720861b2aa8b7c05b97ae8283c46ccd9be2047102667926279ddbb4b4ca63980304956bafeca24bd1f60fc62b285f498533a1f4f3ae68b49e2f4d56834fd25966a1e80d18bc9b1f4e7b2ec7ad4b401831713ddc782b668ae3d15c1d8c524cf417ebc9710711d81a10bb5946b78ee051dfe008c5c4cd0a8a923c260e0c2115715113b33931bf1b7d624a2d5bdeb1d01080218b79874399e7ad217ca846744f89490849041a23801c31693a36c527ab4c824945ec0a8c5c4550d9683dccca8f905831693729a27b12a565be95d2b80318bc999bd545d28111a343f6e80fec70d26258bc9a92966f9c8b6bd9803462c2655f077d1fc2e5f3bc3000c584cb8d1592f4e379ba5d22bbab47aa6846200862b2606f9a6544e4237dc3760b4c2b194395b75cd8b4bd74ffa2f299d6263aac060c5a42a7191aefda664bc51e0ab98e431cf5b767bd1397b554cbaf93925cbf3de28cf3700462a269ed5bdc79a7d5f52a36252c8072575e3af86fc24609c6252c51fcb2aff76db9129269c86bda46b3ac3e94c29269ab9df5dfef3187c6d0318a498a4f252859754bf2ca3514c0c3f4a57cc38f3db922826ed79a8ca8ba70ffdc108c504b99ec4b3b9dac5e5c100c5a464236a5352fac4c418cbedb2625ab89127269c8cab8f59e7826d3a31e93e7da8784237c9144e4c32d5215c3f672b5c3631e1f256ca99d9529c8b26268ddb5b4ed92d5df69998e4773ae3da5bcaa5c6c4c4b4943777d0fcd7e94b4c529b7d3732c5302b5b62e2098f513fe6f49acf4a4cfe985bf99483bd9d9498586a5b57d5941a934d6272e526ad2965929818adbca2f87e529f484c4ea7f3578f6c1eb712242647d151754a74885ae9119377fb2dfe9a902326a7cb31efd26f12c2841a31b12f78a9c710232685c5cbb92e74d4f42c628232d5274633e68c8d22265dcabcc7cb9ed197444c4c974383eb4751b1206252f8701b3ffbeeb47e88c9e5267cff63c7ecda1093f3ef68cc9fb3869a0b31b1727c56513696944c8809961ae6f7e5fe843b88c92b3f67a61573f114c40411ebd4395a92ed652026a68c9733b2dbb33d04880933d2ee4c6ea8a037f487897a57ad7bc9d7fe427e9824b2c294e7cad677a13e4cf6ab18627359e48ef83061b3e8a052aca98da13d4c10eb24727ff35b85f43029284f2a4b2c4cf9270f93ec4fe4c5f3303b193c4c8abb389ae24a64de7798bc315e73b3ada9b7ed3049870d9541c347f1b90e132d9d4edd163c7498f09a93dae92725763c739860a55d2c6f3e990f8f1c26580abf2946e5204f3b7198b8512ff6e9ecc061f2e6532193481593a9f38689393affc9b0561fade38609da1f75ac4d3e46511b2669183fd5a2ceef446c989c5984a9d9144748cf1a267ebc606a339ee9a5d530e9d4068bd1392c9fd4a461c2dc07a52cc86455aa41c3a4dd145937b3ee5e9a334cca6d32055119e3a768cc30497df84a3907eddacb946192c5e0afaf5d757322c3a454a77d27437b4b670c9365749c6bcc9c23376298bc3dc2f24bf86756c230299c854ddee1eda20d86c9495c28a1b641ea69bf303184fe56f6991115f5c244ab8b3de2dfc3c660172698fed41cae64bf472e4cda949545bea40915b730494dc7183b3e669b2b5a98d477a593dc14198357b230e9a38fa52c9349cf56b030e12ed445ef346565e50a13bdd4da2613fafdaa62854942a6e85126ab5a4f5598245a2df662f01337a2c2a4f2f6cd1d2a77633485c96696f246e5aefd1c294cd41c7ee293a51cad446162508f1923bae2661e0a93d7af94a88eff22f5274cb418a12f84ed84096fb2bd2adb7e1a7113267c578cd0db2c7d3313267996d239b23955bf4b9898f97c7edf82b2e02a61925690a72c2609136374db93c9bb682b1226e5bfac9f43c7ab108f30f9747d49cdd42aea1961720c9e74a8247b308a30717449ad4b4184d0b107830813fb75dfcf76e497eac118c2844ddaeb84deb7f4ebc110c2a49f37d9ce77139d03461026095f3f8f7bdbba1c308030f992998d142b3be9f9c5e47b1df7ce29e2b3f1c5e4d818a4e7c5b7e0965e4cd0d8a0f205f9ba5ce1c504b1f1a93a263d6f71dfc5242146b95c7f8eedb7eb62f28d8cd8d4f531d3edb998ac723af5a9fd8f2b3b2e266915a52d6b7b8bc915c6d2b52b4dc91693baf42ad4d959b0d462825efadfcdeb9d645a4c1611b7d9369fd7d4594cb0d490212d4453306531713d7a5e3ab99c3cf4584c92d12d8ae851b9ba048b4977414ba8cbf7a939af98f8e29fd55c73d218574c188d1f1ef4646cd4b46252ea14fd6a2eac98b027b4e767cb2a26e5e93953131a33a6553161d39d12ef3946935331493ec8689d5da333544cd6a01b4e5bb89cad3dc544ad5232770ead6a32c5e4b8973bdbe5ed84a598a4fe92aa0be25f5e9262d245190defda79a1514cec2c9b3d7ac797184531497bcaab2473a79d178ac93e5f26d7e2658a5983626227afda94b24c531013e01313c38e909529e489892bba83066ddb39c67462f2dfcbaae6b8abbae1c4e40c2a07e126cc42359b9868d1b3375a5c4c3ac39a98204a655388c7fc7de14c4c0c99c52dc950bdb9c29898f431efd54afe2b7cbec4a4dc19530e25b6c48411b77d298d8c92722526a54f41cd534c9531ca94986cfbf9dfdea9bf294f62528a26eed736fc6bca9298706b29691139ed2d722426ff26a1f92d9dd5a5181213f6f286cb1c4b07393d62a2679bbe123aae7dc91113ef35553c6daa31083562d2982ee99936c9cc318c9834bec98447cb222686cb274e6c5bd29a57c4e457b98c7742058d3f11134eb66a3ce6f4b247c4a4906e1d2bc61c3cda8798b0fe6bfe6a1b6292dcd84967adf33571212656b96f0a67f93ab44b88c99fd252c59fcb15a33b8889c9daaab5475bf9b98298182f76ba9dcc4c991b88c93aba62fcba2c72840b88891b73c65c1edb3f4cde0c374f953286d7d60f9374f8d4a2f43255ccb60f13747ec372f68bc1abe5c3c4ea1cb6993fc5d4b38789df9e35b6a585cf317a9860e6a9632c95ca65c9c3a4d6ff8eee29a246c7c3e4929e57b6bcb46f7e8789b17599f2a7d50e136b533c345f554a5aadc30461993cc5c5ad3eab7498345761f229e95019d5394c4ee974e7a56ada56550e9344fbc5fbd77fac54e330d1bed5f45d985f4f2a1c26bf657ad80ab9d6a7be616289e6fb6eb89799ea86893e27548acfeaa14b6dc32431dabdaabfaf5d54364cb48b41dbf2829cdc740d932ac860f952a66a987c9552d6f4207ecfd2344c8a3bd72a4a8f8a3e42c34453bddfe14974d89c334ceadf1d69f163153466989cf5eec64def8367ca302957efc84ca6bed7428649ff2947d45fce1d2c6398b47a6a3acf736b55c430b9e3c3af09a5f3c2cf304c764f5f492d891cbf130c1373505bb2524dfc68f30b13537776b4e73ffb35bd303987b2641b45c8b331bb3031a57cb39663362531b93031a72d75496899095d6e61722cf97db247c6b7975a98243aef4793f935689659981c3276ce8db6d4b8120b93d2dde96cd1a7d397ae3041e50a97d496ac30b175464e438e27fda9c2c4312d8ba5c643e5870a13538afd0bbe9fff54a63049e9d4d1f598a1b2450a13531ee1397b6d66ce4761c25a655ef89de8f55098143ddda612a6465f7fc2a4cc185de9af652ded84c931a86ead92cd96e6264cda974b15c364c2a45399a62ae9281d2f61c2088dbddc0e09a084c9f741c5c9d196112a244012262993a17259c693498800489868f9f2ee8bd28b318800479828a2e4b252e7110d11c00893b42a645cd7df52320428c264ff14f54a67d3541b0210615295eef0ed63ba9a21c01026255dd284f60c5a2f4f00214c3a21dc4b4bb8a8dc1f018230793ff437b85d76de8f004098a483028d62a8b48e0523a2401c0c8402814018100a20ab670400a313000000101e10c6a2e188485c673d0014800348463050322c22301a128c0663b138181004428160280c0883c18050280804c2dc8c3ace015d6cefcd66e8ad4181d1da5306d43d8dfc5c104f75c9ee458db528b2ef2232f41deafe957a21f3f026d350b911c8028481e8557b1addf8588dce9ba26b257e5ceb4ffa1d712d00560d7f736e5e16d3ec1b5ea5e9a3ab71618ca02b411f1a23c53c432418987091143f54a38f93602ac6637221f49d0f09bd0dae49c4f61524200a5de12f2ad787c0d14917128d44ca24a325884e9c0229329f4aae91dc1e0af051d1c0aad17246d0a9cf02b12ac3b0b14c78247ac8514428a763905ca06f69731eb47159275b88092e6fb89fd427c7d4d0978b2e6a8f9dfb4a4d51d74a441914f1ea6a01ecc21f60fd76cb4a5fbb7d6b9ddb3ae564fb6fb96983063e4d238c2db2bae010b87af812b938c800578fd300cb58cee4b97362c2331598120b434a8f3dd54c5d80b994150366162be96ea0c76b2711dcd377002a3986a8a1392804712db69b829da6d4902ee089ce018482e803280ccd1cc52108512eab23628103efc0a8a923848e592a17003648225b0a164068f05c338bfaf94f54b6fc3fde37f38ee68ac2d4f0762d1ea2527dc34674d3e2fa50043c98e83526829b2fac2a74040c82357da1d5a2d94c3a633372c19133446eb68d5b41e7a1a38690eed5378620a53b56a62cc09dfa00f0822b4d9131ec4796cd6c36789c82234060c135c0e02f4cc274da4df366db50afe71c66283d74b68eda83a2623e812b4c14df42a2d79db9794b8120700a9711a5bd6b9206c15d246f8893fb179f1b2de84713a7eb7b5acc571b2ccd7d11a6c6e183e7a52aff2608da9a0e6f08a3e764d3514a83a8e0a2a481f056e25148730cff0283f7416074a22e7e1b9a9c5398e90fc0a359868a7db295ac6f46d547cdcd54ab6d94e09593e88ce8e16366906bf3368d7d4e21f718c75194ef6a9ad12e8e3d6ab4a1e26eec12c952a49624316590b9067a1300c79c40e8301d1e026bb2cea8f3479bb4a55dbe9141a27a8652f4d8ab13713853fcc4bb40f953ab818c3980f0085586f487703bbc2efe97142c3e7c1843165b68525a8ce33369764459b97ac38b614c9212e9297c143e4e82336570687057463e7fcee5858f7768537777ced4424f85407329c1a17948eed353e3609e89cbe1ea9f84237ffb9daad987d9514fabb143dc43644845b0281afba69a51ab025ac6c09c47c4f572520fc58d3c591c83337f1d2efb733722fa2219c4becc5edfcbf43939a2f7e36479b4f03e1a60eeec2062ca44c188e2024bcfe69c9ce940e9fb209fa20bb4cce44484f42159292667f47a5c96e7e208dcff93c1b13f73eba24ce42072fa51b23a4667e8fa5ea6cfc9b1a86606ce824cc41e8627e1d8df06bc8f23a72dfd5e5271312f149e3240110219cd13358c324041a9c245bab2a7cb68699e1411f92a889c002f1439ad8112c40f29fb633043d5e1b23707c979a6c0fb5e051b945d0db66d59f8398ecd1232cab3a6d70825955a88ccf25c8c03299c17e693220d141dec737c811684ec089276b820de89ce28e9f7df46129a842903b52d73c7edb63ab56a660e36fee3ebceddcc0ed6e9eae80954f3e43d47687c6882a41080d4ca2588e6dcaabc110b01d1a0abc6c5bc1297c389fe5d053960ae153aa71f928d18c9409d949d1c8888be4819418f6543a4110bb5ac5017d4553a4947f6767daa064fc6948b2a4942a4b483d4101c19aa70c09249b7aa99f4bdb802c7ff3638ed8fdc79bbac2e571769a825a13e0661a4727e7ae5633c490db1d281f4271852a090ca18d721a01f5236d31cb9e45ddb6b37110aa05a922012da472a0942862b1757e5a41e89db9e09badc9c0e148891cac987b0d123291027a91d5da55193622379a39015e055b8f867ee70bb5b27d6113a759a1925747988dc137624753db23885ee1346f87a19927ad0ae37e7f37db95f54bd9c6fbb1b893a18bb1a8b900a0df79208855a27ec72d3efc84dbc27c1fff99fdd440afef84afbd63b98906e2fdbbb29777440c3038442b153f86283c96856a97b3ed81ce59a0a00d725d4a8167b41b3c3b3828b36d41355d87dae8e87f3b7df46affe499e68ca420c61005865c33f8dff3fe4171881792bf91ed4d0d756768bea1266b0770547bc2c47e0b3e13e9abc6ac3ec908cb31d2a198fc93c3187d1c17f1920e99d0026265033ae103e76e310319b70b4391421590d6da7a45343bc46e2be6c77aaaf37c6dc798c150da70caf2a4a5d4089392360f6579542f8d1d07960b28d63443676ff38a6c99d00c71fe8a45d7a56f93b4d5411e93cd7967e940a0753098edf3dad41be21c5a730c024f6b6d60082461b6a345d8d92a8b4594756408fcc13ac0e0f9dc2a1a8e8a95df93a7505b3f6b6d0d2d9702c087d94e6f111c1a0ff7a44a3b9b0814ee3f0bcfd05ed249293fcc8a6351a79ffb1a6dc313fdd8ec7f4b0a132ec9264a090e1a880705d17ba25b40f849adbb93ce1a066c60bb45240b1787ddf04e87022c147cb124a290896c1a8167c1d576c0e2471e624f806a761cc931432313b9deac129ae9746eac4c1646d17705426abdcb441f4f1d767ae42ebd6e0ba04281ee21ac27280182c89843c7c933171b7c94459e023abcc84c8578a0f91b10d5073b6fe6368cfc2a273a17110dcb47db3f5d3ba2f706e392caeced9277ac93a82b81383c64fa512567f213088443eda2a59e3ebe7428949ca524e7298256c0c3aeb95390df69c73a066d512d404b2122514b7957e4148b1e6d00b84a80110d560dbd3e5f60fae4eca1b65d5304898bb4a8a31102b159d9086354234d69e5be0a9447341a269be00f128fb71c8bbf2a55b0438f98106fed019a7b5a505d5d5c7eb7f4c6e3b8cb88030704bb6b088273060845bedd40602a60aa87cc4ada05adb2aea397c4b805e3cd4a3e0ab681a5b0f283e582708f18ba4006d197b351bcd7531d2e5ff0a1589f4e3bc697c81ef097109ec9c4724d1f5bfb7c7effb3d9bbfe92abdac9e663c0c65d738b4af73001837a65471876c0065ab6b967153ad6b87b765465a356582070d7735d83a20f797ebe51b0c78bd515d751ccc196a092324ef9a804f742c496bc3e7dc6b2efa69c24b7a1c160b9216742436afe3329ef4722c54864694568698fd727837d2e75c07d296071b2b410dcb1c6a1c5649d53b85294926883b273d7c833901ae1faabf41170e47f4cea2a5868514a32cd50147f450140720c86a82e071a53ce1be308d9c5a10fd6dbc2f087283d971b2840bd3a0d49a20e06a598593e1a92170b11a1e9fa26015f81b24781d4876befa529c2358bd0a753c0ce0e6b77aadd833a0df3cc958d052433fc5bbe8681a684c43bd558a535596e2124fd160e3a461cb4555e70d4085477446fa230c4a4b48cfb791461c307038160ecdd7e12404efe8ae0f4b714388c14c7b2470eff826a22c18446654a8ea536f74009c742849cce32f2b58fa4ce272ae2c789997deb4edecf9910b7e5460f1c963a3d434fe0bfd19899c26aa02295607da39b88d9fbc9bd9c9568082238058721064bc073f7a62631116a796b68a3ca9e4480b3901d4a390d01df1e24f3ba6685e56adcdf57415836d764845b8ffb72f51cb3819478b90dd1c0ccb8e514c923381abd94e4aeb11a2d60a2a55bc5646ea596e848876bef7bb5e4b612e3d49c27e263c032b69423640def1c3a97f443158a4b30612a5daf0da4a14d807136ddf09abb97b3362a37f8792f5ff8dde651b2483d8a6837729078d24d4b4825f2c1241b8e9118004880594e529586a885ad4ff3cbe40a00ceea7da3faaf147c65756ea4f86422ab1fd32e78e0c80b2a151d2dcbbd9ba0e44a14e17589a1001ffb363d28ad92d0b0049970cf803680457f6e3bbf768379062024cd372b77ebb314d9bbc634607012aec177a79847e1d273137a1a60cc2eaf77cf0afb6a6c9aeeee34758c6e1ba89aa24450c04f18485f523c297f3a71a30329f51ef981bc94195980508b4a73fdea70ef240d950413c5a3ee0f6008958ed4e8fcf5f6cada2c76a839bfd77d7025d0234a63f84da93249ffa3f433f7884d681d5fcaa0ddb4ea79a234887fd8273f6aa7f2f3a88a50d8e02f0af895eb665e040621ead8836afc4227b6887d8a58e9d2d84330434028e100695119541596db44739059c964ec2ab6b4b0cf8a724fec3cc5110f0fd4eebe4804086853c5e66935bb72624d13cd267037091aa1d9794f738e25d1bca18ae81c0c4c9635e59b06e6afc30f3db9975fb3c47f0558ec28ea00e5b2acdce2201d6401e9ced523b5e643415722313e437870e75be2dbc8e3e015a7cfa44d896f008f859f0e1bd8e08efcc13fa7e663e95624d099a111d59dca9c00dad633153eca51d64d7807339c140ef1928f2ff90997a222b52c7f9fe0ac30fb8c014347076fe475010f1530d2e691d614380c37981250830a6aea24783bd245c553aa7fd2f4c0e5d8a035f6a999adb36e18db154c1092f04c7ef0181aa45e2824b8efb39d2527f202f530d17b02608d536a16c2535a507dc4de220efaec6e43c68d277bc5ba07d4912e251edd121401921ea74427108a0bfd3578392f7594236e1f12733ea3f94e6a2c264306c14d85e1f6cbd2f801ccf8d1dfdbed58f4028ff7038571b885f24855b911226d95b7be25c061effe52c0772b7b22f9ee3e4f61462f4beb807b51ed547dc294cf82a800829c0feaf851cfc2780ff3df6b23426a0a31b69f92f40083946ed16f1e99f71cb9e2e16cc381ce807159cfb5351ff017ddc137d4713c4410c07a36aa142846e11ecf26929bdc4dd3cdd02a03a5daf6aaa47c9d5813a02126073d5f27aa82a4b19e11d5b22c040b5f236611580a7d0065bcd2f430c8cdc98d1e548108d34943a9a80888800b3bdfc99652ada3aee38fb3c63c16348a83b79afe9e9264b0ba4fef9a1e444ca5f1de061cb18426a3db46018d0a203a8736d201ec76fc48ada0e4542477a391f50011a758268d557f38a708b67a5576c7727787e17a694158fbf2aca46620cb279983b1a5118d705fefb6079214c67abeb4874a52fef90680a09968397a01e23dc713043d07ca0a6c5b6a7c66a22197ade75c144af18212e18892451b05ccf90b2a564286befdb1d02cc7131ad641e6c166554054a0513d0b25c312e1b2acb2c2becf7b9f39ce6322a4b6bb9aab9b21e536295816892c3be2213818ae1a0339193acfa51df79a9c0aa499d9886b5243076fd2b06170425d6b1040fbf088a20d4051351355b2848294e63611435480c55439bb01a19bd5ecd0d1f0be0312e54cd883b2b02b1082ec9d2cb8b264490aa60b79c9601bd0b0af628e5ba9413d8a2875c6aa8a8c9c1490c1381996659a4518742418a6d8954d05075da07238390a73039cf15167b863d8392e80fd022171318d17cdff3d78dcc22a18832e81a4f4438926bb66ef96a7dcc2c396ba961108dee98fd05091c4d196a0405c7ef538083b399a6a96d8c7b3c73b0d514c28746ca64d0b3699a8529248ad1722b249573d047a9786cb5cc183b3272e13b2062705dba6252a6a2a3b33e417deaee51564c665a8856b4f6b1b6018e8332799b5071648946f12f457fc3498d56dd9dbc31131b9eea89dfaab6c6a8be340c8f25881b340e05de8212be80447d57352766c64ec5527a9983f7921fa8f74974813575fb8ada5c5229f4ec88976a42cfdd12852ecba179ce4a2bc77e8352d99ba64f8397d197a02aa1aeeb698c09e88bb5feaa58a791ee37739ec6a8bb3215d0b90593008280a451702130ff1a991dd129fec206459669f23eb17710a94a2abb132b7e6416ad46a57636ffa99b1bee6a202eeedbdd191845a177da18346d215ba5d700b1ea14ce26c174000054491a8002fb6b51524be2a7aca6a65644b0b21feb3fc58a99564213277be7fa8e0860c7812d9e1387990a960bc092ed210cbdee28391e41f8e4b32a68d45562b8aa6f18246079f58b76579106e98fe5be281c0093d49627b96249781dc6d9b2db024f427e7c077168a71727a2d3879fa176a3c79afb6e53ce485fd9210e51fbccacb62ecf411ddfa9ba14a0c9867964978aee510d811f079e673ecc440b21580f24299c9e1729e64e2c1fe474e041fc54f95a93808a2129e59e4f42492484bd386b359ad92c063bf9622ff2d0233f0d117a9e0e3f50d06b34fb3f634bfc33bd723bbebc21750d37139eba63d31524bae1160145340bcef3f243270d01b1ab3b646853ed9cf15b9f352860f3c3fb90cd2d2dec5ff2cc1c8c1639bf4be3cf5eb98a63b53190608a1b80f2eb7903f529cb07ce1230bd136c1a2d40a393ee91075847e8c98ffbebdc6063a4edd8be2553dfe943b559f04e3e921512f5705cf2f24f211080f9ce9a642bc193af5e02a47662797b0ed1686ffe173c42d137847c38f15ac3f5c7a2e082035bfa3499d4782642ea4fc44f1a11be1307dd835478b97cfcad231fae3ec655707bd39e61cf097061fb74c424aaac6f6ba206c75b07308880370d7b9a2aebf0ccd520c1c642d06d71e99d41e1b40cb830349f45b7bba3824ba545656d92482814a678e512e7c26b4745a2eaf66552cf31127b1d4882507a6b6f73c8dc725bb7e31b90b1b5ee9964df8f28ff0969c5bd67ed87a734e3478402c5ddc1ff1aa402291db31034e7f475a53892792d054084fcd913d890c6357755b74931173f09ace6475b937be8ffadabca6956ad02e6218be9a287c0e21d11da0e27010b82cf00206a111a31d0fc621e6d2234841595ff7d1c53c13b96e131c7a9bb256388a98decc3687e39e841556c79d2719a4d0d81b3a8965f3a529538b5b39a966ac374da3262dd5b868ce00326236ea10ce5482856813527db59f51e191a9273f24afc7b12dd847ed082907805b4ed2ade98922c0f7c66a62509d00067237676cf96b0813d89f920acb3f885274e6afeace4e893dc9e0a86a130a5d7004536043ae4c33a7b76ed62f3237598fd59a8898913a7a4ce5e4074b43f066f5a7c20875f7a097de408d6f09855d3c3cc24ec1edd83defc973f8ca376682191de86b8354d570e6edfcc7694651bbb94febaf056e25c72ecfac104fb412c48ade12d79058efeae386e71c6f0cfa0802f020c67bc4fcaabba10d9eda641c0c456dbf6e0e18ba1123641d31fa7cfdbbad0b0f1e0722417e9d4877fe0654ab1538d065030146ce1f3ca3b227460546485943c144e7b63c9b0875eea9cda66226ce4b1de6063a37f45a2327eafe5476f21472a64dd647f4bfb71e724a21de027b8096992850075091722c50ec23845b2ab390198b28ee64c906af530e12108b4656fd237629459f03da108c34e6222ed74f51b280992f622588a381bb4003efe1f899119f9b7dd202ef81dac419740b7599e2c9ee732822709977f69a4adb91c7abc3bff9cc686d0d7c8fe13548e6b01028ec04c3660c28db39946f493b89d7e5f681b8213aeaea89ae3e1def114c5580ba073f205b21e0e85b41402842ac91d89af616a09ca22edbae0812f60b2516eb053e400fa4dbe63fd34c98d478a4a1f434f8b30a665708d4c12d458605ac1b2babafd3899e5a048312c5ab9f3d7f43331f4bb25f198629702af2ea9b19206eeb6bc5a93f28b8128720c6c1f55a3e594d5cb33e196b418d46de3300c157c7f24a13ea13a7dc12d181c5e83c109acffbd232dc6a449730018b47edfee3850d0773339f41d2f50c06066a7c544834e8397febf22c1f644be9fd930faa93eaab9684d6e50aaa141951ec632ec254e72245cf9fa45c31cf1284bdabcf2acfdd04d1885918b6bcce50f5e599d993655ed433d841a9e31a44dd354c31c1f7805ad44079085f5e8a4f2a3a576cacd61f1609d01bdc7ecdab2a0f084719c37a4f6a6362fa6e311a943384ecb4cf93a5aa6009be40d83dd4dbfd9a02eba28c75480e32616b4ebb70ca2b219d3ba25eb3e72beb3e09120e3c1d8188bbef0d31a074cc672aa0a53fde59351df76571e389cb359e94f9f216547f82d204bcb8feb6c3de07c0fc9ed8a27b77df0684be2010a605ad0a27a6f5fe8ef23706bf9076b370fc3864f3ee053dab13e26fa44ad3049980a9ef58b0797e6623704a8a2eb6e217b00f05324a4ecc3f832319d15e1fe5f4f43cf0db54dd0a045ed3e70dbb0fb156f8727a60a187647844b25b981d05ec55a723104ec1c23ac5a62816bbcba99220e49cd114cd57258ba1fa71fa612517cc90fc2c0f2e8d87b84fe296625998e6aeaf864eb0bb10670d5cdbbbd9684538d5fcda1d9df41a1e12c570e4a774763e0e9d511ef0a20e71828476b03db2ef6db3c5c50d2e464c50e749f84aa4b2369cdbd315f675310a1c8202f511066e90d8bcea5a16b96ffc43a6d605439f8781b37819de677c96a01fb6957c2bc11273474695dac888ff6d09118efe125e950489e2be312da0bcd999726149f3cf15284f68063ec0bfe3a0b2cb7edf18a71f4b80bf733404ace30c92384a08dd8782226f91c219a7be5376afe76e793b4de4944f2942c225a55a35721be880b84e72253d309a10b4dd380c48e599cebfabb1c185aa63562ece4325558c1884ce4897041f47092b0df29129136e4a0285f830e385ad15d9710ffbc0c4256c0454487c5680f2853856caf2d822d81ec5b1b4c22cc18015861d8aa768e81a22489b9d17a060b95cb3d18167252125431932a80e5fd392798ce55750ffcc3964501919f813c6e1cebc2043709ea8570f04344a4fa2e69bcc64410400cbc5794efeab6215ec4f0e923376c021540467da5efb41daab987ec1ca1012c8e62d5c7b954f90e32e3acc99dc5f24322f5d93be462eb72cdade889c8b4e6bfaac5d66ebd547fa43af4c9121195572fba48556a6b7d6a4f0ddd10cf77d87d935482dbba4ec6ccc0b7f97a0521c83d6bf949621a2d32211b4b71a3c0c9c62814461bedc89038a34b500b4453b6c3ba7b6077882c5f850afdb189212a10a74a2815e44803949b1577510c064c5d110ca128aeca7a884bc6a12aa0c1e1de2d5eba1a913376de8dca58ac1b284c6315e9f4ebd3c5a7217ce849e34ad4a4d1bcc7809d5531c9d5f6d09f4752488e107a041c056e119728c1f450ba2f4d52d8af911f181735e57fe0dc45e8d8e7d091b2bc05c92025b967d46479319c3d9b6772e1c484b69e0ab5019a8f86c09091b5ae6bf85b72e728c1fc756d6c364d27704159021b9da665d1f53713eb9eb67ce8f165a3c6d04ebf8c6d28ea1f7bbdd508cdff1c8380303fb0be9281ccb77ad084a216242eabcb1b064456537405a7e330b1815353d544f6353e1b3acb869dc11989fe474c609c98fa08eb1c71d3b545e8837d4035e6316dc44d06c3fd717ee872e010e41b674c621b4a85a5ee504d0a83975c3453d28d8c0f0d7e0ca65a368d6cbdbf06da3aeaf9e70a268e7a010c8ce8a782f792982f00345e00e43ff74cf5ff77716bfec3d3e0ba0071e3cfc447f0651315191beb78c64a860bea6c207e283a127315cc2f238c52a80c928a41a81496d1e7c9bc5998f723a384cdd83a401b98766ba3fdb7c50c05a04da448f4bb5ca9055aadd6fd0cc6f08a73ef5562ce8cca20be347f5641b6843b04d7cd0bbb165f2130410b7bdc6902108dd9bd9c4e19813bf0cadb0a358702f87fadcac8ee904641ca67af9bd8a39c13b48ef31a2f014f1ef4fe7071cfa74298f9397f148f6567eb86b49c6e8f69ce06e72fd2a70b143e4d47ad9e5ca91807bf876d2007ca1efd6fbb4fd280b77a63b48a8dc6c40a19b2c5eb315d88ca50eb52ef870f0e3d5caba6a6c8e7b040d3418fb18df3bd546e002fe50a778bdd3ab164f4966f0e571c40d01a9ff490fa21ea481b3e45f0ff88b8fae7568dd196bd34edb64d938458bf3fec0d38cb182a85120bc41687a63e5768dbfe0041b1cababe1fe3da48241a6415b01c4b6e0f87624a0f5f767136ea4d84bdd4ed4e0d8dd6877e2890a18fe0d52fbdb99d82f2042ac5ad35378e426d6ca261d19fa4128a909de414bddc200f18c4bcd3545df7daac5bffabf4c2262b6d296f94906ef6a209c43861366270220bcb8d4ba2d9701f7264ecaa03aa8742a99306b4bf0aa38d1cb29a0a09f6b6ffbc29bfa0c882df5f521d6808b9088a23028542667700271b256f4787ff4b96b4fbfc4daefa17c3d0cc569dcdd414c5af3e40f23da66a8b5a9556cb0811338855510754672df0e1574c07028ace29e8dbc4eaeb1a1b02dbaba7006e985e14a9c0302e17907553064759146e2e32b8102ac652ff79073bad19ca780d7e7033b1459a0b90a4a7a8920872f02f89f4c68c4678e3dd6c72c9e2d0421a94b8d3027c08b79731e13f3db1512dfc4dcf92b6d67f169f8f0407f31225146753541dfea8013cbcc0158d3525e6e992ce95b7cb98ae28ea7de8d4af6745a89a02540f74792d3ee3e79a9a8e3d9713d595f2bb9d940a88362350a7a4937c4f91b1da21e12e6bc8e1707074720a043a07adc1b9bc05eddd9fd42efac6f2bea9c3280cc1dac049044312b76cf1ed20fd694b1940fe028a7a8466aad463b802c00377467c77baacd0c8a40ac9df750a698cbbd0e5bede8428c488b614cfed40c137398cba3b93a37ab1d2ece639eabc615d34786b688c8ff55f3f8f08c862c4d995e33f47a3d2bc962749030f700d7f193c4a8c24879bdea3c4b460b35e5df813c62a481c8612ec8e43d0d665fac3bcc6775e421241d5c6e7cdef7bb768ba69540d9346c5350bc5a02092a0d9a7ffa68452e2087fd2525322cfe6870495a5004c972941b6761efebc2d635413955373a522ddfce9bbb920160996d9d0b73ea64d6e08fb8ec6da0f4bd013096aa30d294e81f109aad163dde98a5237754eb74e32955e45d3cdb55bdd6eb4091b1d1f9dee6a59a2ff58d07fbb9cc9b39ef4dc2a0c4910b1abb0db93308c71566767d8295a5b46cbb19b3b5ebad1ad077ac5a320825beb8b98714b3df93c9e4acdefd8cbdb512e42b4d45a7c73c706f0639ec21e74550055295bd444abb87388c8b6b28f6fb4cbfd46a623dab2250596cfa7478369acf7ce5661f4817eaa41f4186cea3f85394b8a67b990be62aabae005c008692b236b09378ea313bd3f39b0271f1c0d8e00d9afa2e1cc176de734e0a144e41f5f047430ab2de4549a3e8bff69afb002b420460dbcf19340f62f18a8876c26819c68ef59909d20dcfe0d1ce5a56117048841e4ac794667380688a2e7e9a3836842838d8c11cb8466c7fc9e617993f46031e9c722ccb4fa7e31aff4d8cce6c133a733010da67fc792c8ddefb00f0e8d219963a152d34b7fda95eb2c6054204a42a4836a73b1bf4fbd8d6a1e8dec28035f4abcd435266a329cd99cfa50816a0611095b7895c93ec3337ee7f60e5ed42217a3962f719ad105ab96ad046af0e8dad3625f96df4f9bb199a627c6414b9960629521c72caf808349b6688767819431a13ed830caa883e8cf1f0c22d6b51bd712136b11f1fbf0de8b61c3c58d638dc36196ad061779596bfaf1bd016dc32c7d7c713378822eee0a25b0ba37844351ce6934c2d8a2c7d5c044ed246adf07eb6b8c8e937be9cb5eea6ff5cc4afe8ed208220e2e47ce70f33d1800cf433834a84634f3cb8915cc88e14aa7f449b92e177ee1ca90847da8d850a371f6accccb09dd95c671a121e5b5190b55f4aabc8ca3f6a4b97716ba3a9980bea418bd1422a010ccf2c4f95d8afe9dd9e776d7dd7577527ef5bbefd2e7e76f99d880963e6a60d77b2a075f86e80b26552e665b47c495dc62c72d20cf41593cff74854893a1f06c93828f5a726bc0bd93d1fb0c8a81bd6c4ff5bd7a816db0100cc7a149b54e7cc18543f3559d5e4ebe6cf7bf69fe39f3f68c8ba7168f94ea6666c5b8529b7a4d82d5cd43f92d8a49cb62ffe37bf6a4cd0c175ae909c99bcfabd96bc62b8bd79fa7dd83d05bbca7138fecec2d94772fda2f087cef80a2bdc10ebcb233fe410c05872a453379924a83dec583425ab799c23c9363d014c907ee6bd12964096a3c4b2f5cf234c3916355e578f99a50c8036337c510152225763bc1435fd74281c5902fc0b5b1c6c367b4f381d012d3bf7c81fa435a23939f7cc1f8c9a8d9292b719e08f18754d44a06ccd34640aad2d8a3d19a53da410cdcc0bd7fd2810da5a167bf0755cf40f86a0eb2480bd259ba2c3721636a219103b912058f0127fa60ef19420589b28260d9f8dae09c9ae9050fe6596e390f9a2b0104908d82f9ffce0fb8f1854c068f7ccd3c4f95dd21bd23e33a4ce7eebf8b3d5315623478a4b1d548b5c526a3ea7393ac0f4558d3da3808832312943ea7761c09a57725e57ebfb1cf628f3e300ef362cb3c69f5d29c512bcd46bb0b3499750ab85863c22b983327991920fd2075593092d3af384f006a42dc722a74d488636563b392f12b9419c4730b6883d8147f91162c125b49ce966d2db0064189ef4e94c8367a0f23a7cba39ebcda86e8564cd9bddc454beb9157d2c8984fda42aca9880658c860d8ecf20dd3fa6894642b86744d0ad259f8204646df50b08d904f85527c812078c7b9a0fe5b7c41f3c2d3081eb8f6b1774e0da71dcb5cd4b660295ea750258fb15db4b9a1779b17caba3f58af683e24c34ed131f99c1160c5eae5c66994ec38d0f6ebe5af524c4a20357eb61cea0d3538a5c78707a3d065d6164903632c831b6ec18d84f2d7109daa0bdc79e64e1fc1ef046556de2d27ebbf76f16ad73456d4245990fd208948254390ca88d5a01b5a2091cc6a7758c6b41a52ef0b7e87b17f97d4a1d69844de16c0583adcd11a327e7e2963990d711de0ffbbba94bd003a7d2d599438a121926bc517c411024092ef48c216493de957bc9d05d345bcf76265e22de95a759303d0915c2bbb5ae0f9ebe87a043d195bf1d6040d2ada553703c3b229142c16821ad50871a68a83438a02ff1d04af13c24e3a0378dc41835b206453dbcd576d2215784062ff6462ac3cf31e13f61e42085feeaa855ad60329bb73d6bd70108518dc46d9bc3e12a990210004267d8cf25d13a1bca0aedc603a356f58cde0d2ce2cb155d75d582d2057ceba20c699c0241739fc4866befbe56c17eba78e81c98c7aac44266013fc59367489514d58cc2237ef7a2194ef535a2bf0ad00cc6375cc01ccac1910c8abf353f92302fa3a7239c2f41a90aa2d26b05b6f466ea685594caf864c249f2e6eef29aa4d73854d12d4570a7fb5d6a7bfaaf9628c232b3beaafa99bf46a8e130c41515f73655cecb84db7732372ea37a1d43d15ad02",
+      "patch": {
+        "balances": {
+          "balances": [
+            [
+              "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
+              1125899906842624
+            ],
+            [
+              "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
+              1125899906842624
+            ],
+            [
+              "5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY",
+              1125899906842624
+            ],
+            [
+              "5HpG9w8EBLe5XCrbczpwq5TSXvedjrBGCwqxK1iQ7qUsSWFc",
+              1125899906842624
+            ]
+          ]
+        },
+        "keccakDifficultyAdjustment": {
+          "initialDifficulty": [
+            0,
+            9,
+            61,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0
+          ]
+        },
+        "md5DifficultyAdjustment": {
+          "initialDifficulty": [
+            0,
+            9,
+            61,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0
+          ]
+        },
+        "sha3DifficultyAdjustment": {
+          "initialDifficulty": [
+            0,
+            9,
+            61,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0
+          ]
+        },
+        "utxo": {
+          "genesisUtxos": [
+            [
+              1125899906842624,
+              "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"
+            ],
+            [
+              1125899906842624,
+              "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48"
+            ],
+            [
+              1125899906842624,
+              "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f"
+            ],
+            [
+              1125899906842624,
+              "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e"
+            ]
+          ]
+        }
+      }
+    }
+  }
+}

Rust Tooling

Some useful tools for Rust development

rustfmt

To keep your code clean and easy to read, we use a tool called rustfmt. To access all the latest features of rustfmt we specifically use the nightly toolchain.

To install rustfmt for nightly:

rustup component add rustfmt --toolchain nightly

To configure the behavior of rustfmt, we will create a rustfmt.toml file:

  1. Create a new file in your project's root directory called rustfmt.toml.

    touch rustfmt.toml
    
  2. Use the provided rustfmt.toml file to configure your formatting preferences.

  3. Run the code formatter using the following command:

    cargo +nightly fmt
    

You shouldn't see any changes this time around, but as you write more code, you will be able to see cargo +nightly fmt make everything look pretty, consistent, and easy to read.

We recommend you run cargo +nightly fmt after every step!

Rust Analyzer

Another popular tool in the Rust community is Rust Analyzer.

It provides many features like code completion and goto definition for code editors like VS Code.

However, to provide the full functionality that it does, Rust Analyzer needs to compile your code. For a small project like this one, this is not a problem, however working with a large project like Substrate / Polkadot-SDK, it is.

It is my personal recommendation that Rust Analyzer is not needed in this workshop, and generally you should not use it for Substrate development. However, this section might be updated in the future to include special configurations of Rust Analyzer which will work well with Polkadot SDK in the future.

For better search definition, you can follow the tutorial from Kianenigma. Simply use "one Regex to rule them all":

(macro_rules!|const|enum|struct|fn|trait|impl(<.*?>)?|type) <variable-name-here>

However, if you would like to use it anyway, now is the right time to set it up.

Issue after formatting code

You may got errors when building your project. This is because the code formatter changes the syntax of your code. To fix this, open lib.rs:334 and replace the following line:

-		Md5DifficultyAdjustment: difficulty<Instance1>,
-		Sha3DifficultyAdjustment: difficulty<Instance2>,
-		KeccakDifficultyAdjustment: difficulty<Instance3>,
+		Md5DifficultyAdjustment: difficulty::<Instance1>,
+		Sha3DifficultyAdjustment: difficulty::<Instance2>,
+		KeccakDifficultyAdjustment: difficulty::<Instance3>,
#![allow(unused)]
fn main() {
//! This crate represents a concrete Substrate PoW algorithm.
//!
//! It is multi-pow in the sense that there are multiple supported hashing algorithms.
//! A seal with any of the supported hashing algorithms will be accepted.
//!
//! The purpose of this design is to demonstrate hard and soft forks by adding and removing valid
//! hashing algorithms. While there is no precedent for changing hashing algorithms in the real
//! world yet, it is conceivable that a chain may want to upgrade to a new algorithm when the old
//! one is suspected weak. In any case, the point is that we want to demonstrate hard and soft forks
//! in an understandable way, the multiple hashing algorithms achieves that well.
//!
//! In the future, the hope is that there will be a dedicated difficulty threshold for each hashing
//! algorithm. But currently the Substrate PoW crates are not that flexible.
//! We could solve it by adding a pre-digest that includes information about what hashing algo is
//! being used for the runtime to use later in the difficulty adjustment.

#![cfg_attr(not(feature = "std"), no_std)]

use core::str::FromStr;
#[cfg(feature = "std")]
use std::sync::Arc;

use parity_scale_codec::{Decode, Encode};
#[cfg(feature = "std")]
use sc_consensus_pow::{Error, PowAlgorithm};
#[cfg(feature = "std")]
use sha3::{Digest, Keccak256, Sha3_256};
#[cfg(feature = "std")]
use sp_api::ProvideRuntimeApi;
#[cfg(feature = "std")]
use sp_consensus_pow::DifficultyApi;
#[cfg(feature = "std")]
use sp_consensus_pow::Seal as RawSeal;
use sp_consensus_pow::TotalDifficulty;
use sp_core::{H256, U256};
#[cfg(feature = "std")]
use sp_runtime::generic::BlockId;
#[cfg(feature = "std")]
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};

/// A struct that represents a difficulty threshold.
/// Unlike a normal PoW algorithm this struct has a separate threshold for each hash
#[derive(
	Clone,
	Copy,
	PartialEq,
	Eq,
	PartialOrd,
	Ord,
	Encode,
	Decode,
	Debug,
	Default,
	scale_info::TypeInfo,
)]
pub struct Threshold {
	pub md5: U256,
	pub sha3: U256,
	pub keccak: U256,
}

// This trait does not seem to be fully baked in the Substrate PoW code
// But we do need some kind of sinsible impl here so the node can import blocks.
// so I will not use it for now.
impl TotalDifficulty for Threshold {
	fn increment(&mut self, other: Threshold) {
		self.md5 += other.md5;
		self.sha3 += other.sha3;
		self.keccak += other.keccak;
	}
}

/// An enum that represents the supported hash types
#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, Debug)]
pub enum SupportedHashes {
	Md5,
	Sha3,
	Keccak,
}

impl Default for SupportedHashes {
	fn default() -> Self {
		Self::Sha3
	}
}

/// A struct that represents a concrete hash value tagged with what hashing
///  algorithm was used to compute it.
#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, Debug, Default)]
pub struct MultiHash {
	pub algo: SupportedHashes,
	pub value: H256,
}

/// Determine whether the given hash satisfies the given difficulty.
/// The test is done by multiplying the two together. If the product
/// overflows the bounds of U256, then the product (and thus the hash)
/// was too high.
pub fn simple_hash_meets_difficulty(hash: &H256, difficulty: U256) -> bool {
	let num_hash = U256::from_little_endian(&hash[..]);
	let (_, overflowed) = num_hash.overflowing_mul(difficulty);

	!overflowed
}

pub fn multi_hash_meets_difficulty(hash: &MultiHash, difficulty: Threshold) -> bool {
	match hash.algo {
		SupportedHashes::Md5 => simple_hash_meets_difficulty(&hash.value, difficulty.md5),
		SupportedHashes::Sha3 => simple_hash_meets_difficulty(&hash.value, difficulty.sha3),
		SupportedHashes::Keccak => simple_hash_meets_difficulty(&hash.value, difficulty.keccak),
	}
}

/// A Seal struct that will be encoded to a Vec<u8> as used as the
/// `RawSeal` type.
#[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)]
pub struct Seal {
	pub work: MultiHash,
	pub difficulty: Threshold,
	pub nonce: U256,
}

/// A not-yet-computed attempt to solve the proof of work. Calling the
/// compute method will compute the hash and return the seal.
#[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)]
pub struct Compute {
	pub difficulty: Threshold,
	pub pre_hash: H256,
	pub nonce: U256,
}

#[cfg(feature = "std")]
impl Compute {
	pub fn compute(self, algo: SupportedHashes) -> Seal {
		let value = match algo {
			SupportedHashes::Md5 => {
				// The md5 is only 16 byte output, so we just concatenate it twice to
				// get an H256
				let bytes = *md5::compute(&self.encode()[..]);
				let mut doubled = [0u8; 32];
				doubled[0..16].copy_from_slice(&bytes[0..16]);
				doubled[16..32].copy_from_slice(&bytes[0..16]);

				H256::from(doubled)
			},
			SupportedHashes::Sha3 =>
				H256::from_slice(Sha3_256::digest(&self.encode()[..]).as_slice()),
			SupportedHashes::Keccak =>
				H256::from_slice(Keccak256::digest(&self.encode()[..]).as_slice()),
		};

		Seal { nonce: self.nonce, difficulty: self.difficulty, work: MultiHash { algo, value } }
	}
}

#[cfg(feature = "std")]
/// A complete PoW Algorithm that uses multiple hashing algorithms.
/// Needs a reference to the client so it can grab the difficulty from the runtime.
pub struct MultiPow<C> {
	client: Arc<C>,
	fork_config: ForkingConfig,
}

#[cfg(feature = "std")]
impl<C> MultiPow<C> {
	pub fn new(client: Arc<C>, fork_config: ForkingConfig) -> Self {
		Self { client, fork_config }
	}
}

//TODO could maybe derive clone_no_bound
#[cfg(feature = "std")]
impl<C> Clone for MultiPow<C> {
	fn clone(&self) -> Self {
		Self::new(self.client.clone(), self.fork_config)
	}
}

// Here we implement the general PowAlgorithm trait for our concrete algorithm.
#[cfg(feature = "std")]
impl<B: BlockT<Hash = H256>, C> PowAlgorithm<B> for MultiPow<C>
where
	C: ProvideRuntimeApi<B>,
	C::Api: DifficultyApi<B, Threshold>,
	C: sc_client_api::HeaderBackend<B>,
{
	type Difficulty = Threshold;

	fn difficulty(&self, parent: B::Hash) -> Result<Self::Difficulty, Error<B>> {
		let difficulty = self.client.runtime_api().difficulty(parent).map_err(|err| {
			sc_consensus_pow::Error::Environment(format!(
				"Fetching difficulty from runtime failed: {:?}",
				err
			))
		})?;

		Ok(difficulty)
	}

	fn verify(
		&self,
		parent_id: &BlockId<B>,
		pre_hash: &H256,
		pre_digest: Option<&[u8]>,
		seal: &RawSeal,
		difficulty: Self::Difficulty,
	) -> Result<bool, Error<B>> {
		// Try to construct a seal object by decoding the raw seal given
		let seal = match Seal::decode(&mut &seal[..]) {
			Ok(seal) => seal,
			Err(_) => return Ok(false),
		};

		log::debug!("✅ Decode seal passed!");

		let Some(_encoded_pre_digest) = pre_digest else {
			return Ok(false);
		};

		log::debug!("✅ Checksum digest passed!");

		// // TODO idk why this always return md5 only
		// let algo_from_predigest = match SupportedHashes::decode(&mut &encoded_pre_digest[..]) {
		//     Ok(algo) => algo,
		//     Err(_) => return Ok(false),
		// };

		// log::debug!("✅ Get algorithm from digest passed!");

		// // Check that the pre-digest algo matches the seal algo
		// // TODO it shouldn't be necessary to have both.
		// if seal.work.algo != algo_from_predigest {
		//     return Ok(false);
		// }

		// log::debug!("✅ Checksum algorithm from seal passed!");

		// This is where we handle forks on the verification side.
		// We will still need to handle it in the mining algorithm somewhere.
		// Currently we make the miner configure what algo they mine manually with their cli.
		let parent_number: u32 = match parent_id {
			BlockId::Hash(h) => *self
				.client
				.header(*h)
				.expect("Database should perform lookup successfully")
				.expect("parent header should be present in the db")
				.number(),
			BlockId::Number(n) => *n,
		}
		.try_into()
		.map_err(|_| ())
		.expect("Block numbers can be converted to u32 (because they are u32)");

		log::debug!("✅ Checksum parent block number passed!");

		// Here we handle the forking logic according the the node operator's request.
		let valid_algorithm = match self.fork_config {
			ForkingConfig::Manual => manual_fork_validation(parent_number, seal.work.algo),
			ForkingConfig::Automatic(fork_heights, maxi_position) =>
				auto_fork_validation(parent_number, seal.work.algo, fork_heights, maxi_position),
		};

		if !valid_algorithm {
			return Ok(false);
		}

		log::debug!("✅ Valid algorithm!");

		// See whether the hash meets the difficulty requirement. If not, fail fast.
		if !multi_hash_meets_difficulty(&seal.work, difficulty) {
			return Ok(false);
		}

		log::debug!("✅ Checksum difficulty passed!");

		// Make sure the provided work actually comes from the correct pre_hash
		let compute = Compute { difficulty, pre_hash: *pre_hash, nonce: seal.nonce };

		if compute.compute(seal.work.algo) != seal {
			return Ok(false);
		}

		log::debug!("✅ Re-compute passed!");

		log::debug!("🛠️ All passed, append the block to the chain ...");

		Ok(true)
	}
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
///
pub struct ForkHeights {
	/// The block height to perform the soft fork that adds sha3 and keccak support.
	pub add_sha3_keccak: u32,
	/// The block height to perform the hard fork that removes md5 support.
	pub remove_md5: u32,
	/// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
	pub split_sha3_keccak: u32,
}

/// Various political positions a node could take when the network is forking into
/// keccak maxis and sha3 maxis
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum MaxiPosition {
	/// Allow all blocks, both sha3 and keccak
	NoMaxi,
	/// Only allow sha3 blocks
	Sha3Maxi,
	/// Only allow keccak blocks
	KeccakMaxi,
	/// Only allow a single type of blocks. Which type it is is determined by what algo the node is
	/// mining.
	FollowMining,
}

#[derive(Copy, Clone, Eq, PartialEq)]
/// The actual properly typed config after we're done working around all the BS.
pub enum ForkingConfig {
	///
	Manual,
	///
	Automatic(ForkHeights, MaxiPosition),
}

impl FromStr for MaxiPosition {
	type Err = ();

	fn from_str(s: &str) -> Result<Self, Self::Err> {
		Ok(match &s.to_lowercase()[..] {
			"allow-all" | "allowall" | "no-maxi" | "nomaxi" => Self::NoMaxi,
			"sha3-maxi" | "sha3maxi" => Self::Sha3Maxi,
			"keccak-maxi" | "keccakmaxi" => Self::KeccakMaxi,
			_ => Self::FollowMining,
		})
	}
}

/// Manual mode, the node operator manually specifies which hashing algorithms are valid through the
/// mining client. If you would like to do a fork, simply allow, un-allow some algorithms to check
/// it.
fn manual_fork_validation(_parent_number: u32, algo: SupportedHashes) -> bool {
	use SupportedHashes::*;

	// To begin with, allow all algorithms.
	// After the fork height this check is skipped so all the hashes become valid.
	match algo {
		Md5 => true,
		Sha3 => true,
		Keccak => true,
	}
}

/// In automatic mode, the `ForkHeights` and `MaxiPosition` structs define the forking schedule
/// and the node's behavior during the contentious fork
/// (where the network splits into two chains supporting different hashing algorithms).
/// The validation logic considers the parent block height,
/// forking configuration parameters, and the hashing algorithm used in the PoW solution to
/// determine its validity.
fn auto_fork_validation(
	parent_number: u32,
	algo: SupportedHashes,
	fork_heights: ForkHeights,
	maxi_position: MaxiPosition,
) -> bool {
	use MaxiPosition::*;
	use SupportedHashes::*;

	log::debug!("parent_number: {:?}", parent_number);
	log::debug!("fork_heights: {:?}", fork_heights);

	if parent_number < fork_heights.add_sha3_keccak {
		// To begin with we only allow md5 hashes for our pow.
		// After the fork height this check is skipped so all the hashes become valid.
		match algo {
			Md5 => true,
			Sha3 => false,
			Keccak => false,
		}
	} else if parent_number < fork_heights.remove_md5 {
		// After the first fork, all three algos become valid.
		match algo {
			Md5 => true,
			Sha3 => true,
			Keccak => true,
		}
	} else if parent_number < fork_heights.split_sha3_keccak {
		// After the second fork, md5 is no longer valid.
		match algo {
			Md5 => false,
			Sha3 => true,
			Keccak => true,
		}
	} else {
		// Finally we have the contentious fork.
		// Our behavior here depends which maxi position we have taken.
		#[allow(clippy::match_like_matches_macro)]
		match (algo, maxi_position) {
			(Sha3, Sha3Maxi) => true,
			(Sha3, NoMaxi) => true,
			(Keccak, KeccakMaxi) => true,
			(Keccak, NoMaxi) => true,
			_ => false,
		}
	}
}
}
fn main() {
	substrate_build_script_utils::generate_cargo_keys();
	substrate_build_script_utils::rerun_if_git_head_changed();
}
#![allow(unused)]
fn main() {
use std::str::FromStr;

use academy_pow_runtime::{
	AccountId, SS58Prefix, Signature, TOKEN_DECIMALS, TOKEN_SYMBOL, WASM_BINARY,
};
use multi_pow::{ForkHeights, ForkingConfig, MaxiPosition};
use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
use sc_service::ChainType;
use serde::{Deserialize, Serialize};
use sp_core::{sr25519, ByteArray, Pair, Public, H256};
use sp_runtime::traits::{IdentifyAccount, Verify};

/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
pub type ChainSpec = sc_service::GenericChainSpec<ForkingExtensions>;

/// PoW and Forking related chain spec extensions to configure the client side forking behavior.
///
/// The forks here are all related to adding and removing hash algorithms from the PoW.
/// The chain begins supporting only md5. Later is adds sha3 and keccak. Later it removes md5.
/// And finally there is a contentious fork where people become maxis.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]
#[serde(deny_unknown_fields)]
pub struct ForkingExtensions {
	/// Manual mode is intended for when we you are running a live workshop.
	/// No forking happens automatically. Rather, you have to hard-code the forks.
	///
	/// If manual mode is enabled, the rest of the parameters are ignored.
	/// This should really be an enum, but I have to work around the broken extension system.
	///
	/// Aww damn it! I can't even use bool in this broken system? Okay then I guess 0 means
	/// automatic mode and anything else means manual mode.
	pub manual_mode: u32,
	/// The block height to perform the soft fork that adds sha3 and keccak support.
	pub add_sha3_keccak: u32,
	/// The block height to perform the hard fork that removes md5 support.
	pub remove_md5: u32,
	/// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
	pub split_sha3_keccak: u32,
	// Damn extension thing is so fragile, I can't even use an enum here.
	// Let alone that time I tried to use the forked value feature.
	/// The political position that this node will take at the contentious fork.
	pub maxi_position: String,
}

impl From<&ForkingExtensions> for ForkingConfig {
	fn from(e: &ForkingExtensions) -> Self {
		if e.manual_mode > 0 {
			return Self::Manual;
		}

		let fork_heights = ForkHeights {
			add_sha3_keccak: e.add_sha3_keccak,
			remove_md5: e.remove_md5,
			split_sha3_keccak: e.split_sha3_keccak,
		};

		let maxi_position =
			MaxiPosition::from_str(&e.maxi_position).expect("Should have a valid maxi position...");

		Self::Automatic(fork_heights, maxi_position)
	}
}

impl ForkingExtensions {
	/// Try to get the extension from the given `ChainSpec`.
	pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {
		sc_chain_spec::get_extension(chain_spec.extensions())
	}
}

/// Generate a crypto pair from seed.
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
	TPublic::Pair::from_string(&format!("//{}", seed), None)
		.expect("static values are valid; qed")
		.public()
}

type AccountPublic = <Signature as Verify>::Signer;

/// Generate an account ID from seed.
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
where
	AccountPublic: From<<TPublic::Pair as Pair>::Public>,
{
	AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
}

pub fn development_config() -> Result<ChainSpec, String> {
	Ok(ChainSpec::builder(
		WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
		ForkingExtensions {
			manual_mode: 1, // change this to `0` if you want to try `auto_fork_validation`
			add_sha3_keccak: 10,
			remove_md5: 20,
			split_sha3_keccak: 30,
			maxi_position: String::from("follow-mining"),
		},
	)
	.with_name("Development")
	.with_id("dev")
	.with_chain_type(ChainType::Development)
	.with_genesis_config_patch(genesis(
		// Pre-funded accounts
		vec![
			get_account_id_from_seed::<sr25519::Public>("Alice"),
			get_account_id_from_seed::<sr25519::Public>("Bob"),
			get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
			get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
		],
		// Initial Difficulty
		4_000_000,
	))
	.with_properties(system_properties())
	.build())
}

pub fn testnet_config() -> Result<ChainSpec, String> {
	Ok(ChainSpec::builder(
		WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
		ForkingExtensions {
			manual_mode: 1,
			add_sha3_keccak: 0,
			remove_md5: 0,
			split_sha3_keccak: 0,
			maxi_position: String::new(),
		},
	)
	.with_name("Testnet")
	.with_id("testnet")
	.with_chain_type(ChainType::Local)
	.with_genesis_config_patch(genesis(
		vec![
			get_account_id_from_seed::<sr25519::Public>("Alice"),
			get_account_id_from_seed::<sr25519::Public>("Bob"),
			get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
			get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
		],
		4_000_000,
	))
	.with_properties(system_properties())
	.build())
}

fn genesis(endowed_accounts: Vec<AccountId>, initial_difficulty: u32) -> serde_json::Value {
	serde_json::json!({
		"balances": {
			// Configure endowed accounts with initial balance of 1 << 50.
			"balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 50)).collect::<Vec<_>>(),
		},
		"keccakDifficultyAdjustment": {
			"initialDifficulty": u32_to_u8_32(initial_difficulty),
		},
		"md5DifficultyAdjustment": {
			"initialDifficulty": u32_to_u8_32(initial_difficulty),
		},
		"sha3DifficultyAdjustment": {
			"initialDifficulty": u32_to_u8_32(initial_difficulty),
		},
	})
}

/// Convert u32 (default value) to [u8;32] (U256)
/// in little-endian format
pub fn u32_to_u8_32(num: u32) -> [u8; 32] {
	let mut result = [0u8; 32];
	let bytes = num.to_le_bytes();
	result[..4].copy_from_slice(&bytes);
	result
}

fn system_properties() -> sc_chain_spec::Properties {
	let mut properties = sc_chain_spec::Properties::new();

	properties.insert("ss58Format".into(), SS58Prefix::get().into());
	properties.insert("tokenSymbol".into(), TOKEN_SYMBOL.into());
	properties.insert("tokenDecimals".into(), TOKEN_DECIMALS.into());

	properties
}
}
#![allow(unused)]
fn main() {
use academy_pow_runtime::AccountId;
use multi_pow::SupportedHashes;
use sc_cli::{
	clap::{ArgGroup, Parser},
	RunCmd,
};
use sc_service::ChainType;
use sp_core::{crypto::Ss58Codec, sr25519};

#[derive(Debug, Parser)]
#[clap(subcommand_negates_reqs(true), version(env!("SUBSTRATE_CLI_IMPL_VERSION")))]
pub struct Cli {
	#[clap(subcommand)]
	pub subcommand: Option<Subcommand>,

	#[command(flatten)]
	pub pow: AcademyPowCli,

	#[clap(flatten)]
	pub run: RunCmd,
}

#[derive(Debug, Parser, Clone)]
#[clap(group(ArgGroup::new("backup")))]
pub struct AcademyPowCli {
	/// Miner's AccountId (base58 encoding of an SR25519 public key) for the block rewards
	#[clap(long,
           conflicts_with = "mining_public_key",
           value_parser = parse_account_id)]
	pub mining_account_id: Option<AccountId>,

	/// Miner's hex encoding of the SR25519 public key) for the block rewards
	#[clap(
        long,
        conflicts_with = "mining_account_id",
        value_parser = parse_sr25519_public_key
    )]
	pub mining_public_key: Option<sr25519::Public>,

	/// The mining algorithm to use
	#[clap(long, value_parser = parse_algo, default_value = "md5")]
	pub mining_algo: multi_pow::SupportedHashes,

	/// whether to use instant seal
	#[clap(long, default_value = "false")]
	pub instant_seal: bool,
}

impl AcademyPowCli {
	pub fn public_key_bytes(&self, keyring: Option<sp_keyring::Sr25519Keyring>) -> [u8; 32] {
		match &self.mining_account_id {
			Some(account_id) => *account_id.as_ref(),
			None => match self.mining_public_key {
				Some(public_key) => public_key.0,
				None => keyring.map(|k| k.to_raw_public()).unwrap_or([0u8; 32]),
			},
		}
	}
}

#[derive(Debug, Parser)]
pub struct BuildSpecCmd {
	#[clap(flatten)]
	pub base: sc_cli::BuildSpecCmd,

	/// Chain name.
	#[arg(long, default_value = "Academy PoW")]
	pub chain_name: String,

	/// Chain ID is a short identifier of the chain
	#[arg(long, value_name = "ID", default_value = "academy_pow")]
	pub chain_id: String,

	/// AccountIds of the optional rich accounts
	#[arg(long, value_delimiter = ',', value_parser = parse_account_id, num_args=1..)]
	pub endowed_accounts: Option<Vec<AccountId>>,

	/// The type of the chain. Possible values: "dev", "local", "live" (default)
	#[arg(long, value_name = "TYPE", value_parser = parse_chaintype, default_value = "live")]
	pub chain_type: ChainType,

	#[arg(long, default_value = "4000000")]
	pub initial_difficulty: u32,
}

fn parse_algo(s: &str) -> Result<SupportedHashes, String> {
	Ok(match s {
		"md" | "Md" | "md5" | "Md5" => SupportedHashes::Md5,
		"sha" | "sha3" | "Sha" | "Sha3" => SupportedHashes::Sha3,
		"keccak" | "Keccak" => SupportedHashes::Keccak,
		s => panic!("Wrong mining algo: {}. Possible values: md5, sha3, keccak", s),
	})
}

fn parse_chaintype(s: &str) -> Result<ChainType, String> {
	Ok(match s {
		"dev" => ChainType::Development,
		"local" => ChainType::Local,
		"live" => ChainType::Live,
		s => panic!("Wrong chain type {} Possible values: dev local live", s),
	})
}

/// Parse AccountId from a string argument passed on the command line.
fn parse_account_id(s: &str) -> Result<AccountId, String> {
	Ok(AccountId::from_string(s)
		.expect("Passed string is not a bas58 encoding of a sr25519 public key"))
}

/// Parse sr25519 pubkey from a string argument passed on the command line.
fn parse_sr25519_public_key(s: &str) -> Result<sr25519::Public, String> {
	Ok(sr25519::Public::from_string(s)
		.expect("Passed string is not a hex encoding of a sr25519 public key"))
}

#[derive(Debug, clap::Subcommand)]
pub enum Subcommand {
	/// Key management cli utilities
	#[command(subcommand)]
	Key(sc_cli::KeySubcommand),

	/// Build a chain specification.
	BuildSpec(BuildSpecCmd),

	/// Validate blocks.
	CheckBlock(sc_cli::CheckBlockCmd),

	/// Export blocks.
	ExportBlocks(sc_cli::ExportBlocksCmd),

	/// Export the state of a given block into a chain spec.
	ExportState(sc_cli::ExportStateCmd),

	/// Import blocks.
	ImportBlocks(sc_cli::ImportBlocksCmd),

	/// Remove the whole chain.
	PurgeChain(sc_cli::PurgeChainCmd),

	/// Revert the chain to a previous state.
	Revert(sc_cli::RevertCmd),

	/// Db meta columns information.
	ChainInfo(sc_cli::ChainInfoCmd),
}
}
#![allow(unused)]
fn main() {
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
// This file is part of Substrate.

// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Substrate.  If not, see <http://www.gnu.org/licenses/>.

use academy_pow_runtime::Block;
use multi_pow::{ForkingConfig, MaxiPosition};
use sc_cli::SubstrateCli;
use sc_service::PartialComponents;
use sp_core::sr25519;

use crate::{
	chain_spec::{self, ForkingExtensions},
	cli::{Cli, Subcommand},
	service,
};

impl SubstrateCli for Cli {
	fn impl_name() -> String {
		"Academy PoW Chain".into()
	}

	fn impl_version() -> String {
		env!("SUBSTRATE_CLI_IMPL_VERSION").into()
	}

	fn executable_name() -> String {
		env!("CARGO_PKG_NAME").into()
	}

	fn author() -> String {
		env!("CARGO_PKG_AUTHORS").into()
	}

	fn description() -> String {
		env!("CARGO_PKG_DESCRIPTION").into()
	}

	fn support_url() -> String {
		"https://github.com/danielbui12/substrate-bitcoin-like-blockchain/issues/new".into()
	}

	fn copyright_start_year() -> i32 {
		2025
	}

	fn load_spec(&self, id: &str) -> Result<Box<dyn sc_service::ChainSpec>, String> {
		Ok(match id {
			"" => Box::new(chain_spec::ChainSpec::from_json_bytes(
				&include_bytes!("../../spec.json")[..],
			)?),
			"dev" => Box::new(chain_spec::development_config()?),
			"local" => Box::new(chain_spec::testnet_config()?),
			path =>
				Box::new(chain_spec::ChainSpec::from_json_file(std::path::PathBuf::from(path))?),
		})
	}
}

/// Parse and run command line arguments
pub fn run() -> sc_cli::Result<()> {
	let cli = Cli::from_args();

	match &cli.subcommand {
		Some(Subcommand::Key(cmd)) => cmd.run(&cli),
		Some(Subcommand::BuildSpec(cmd)) => {
			let runner = cli.create_runner(&cmd.base)?;
			runner.sync_run(|config| cmd.base.run(config.chain_spec, config.network))
		},
		Some(Subcommand::CheckBlock(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.async_run(|config| {
				let PartialComponents { client, task_manager, import_queue, .. } =
					service::new_partial(&config, ForkingConfig::Manual)?;
				Ok((cmd.run(client, import_queue), task_manager))
			})
		},
		Some(Subcommand::ExportBlocks(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.async_run(|config| {
				let PartialComponents { client, task_manager, .. } =
					service::new_partial(&config, ForkingConfig::Manual)?;
				Ok((cmd.run(client, config.database), task_manager))
			})
		},
		Some(Subcommand::ExportState(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.async_run(|config| {
				let PartialComponents { client, task_manager, .. } =
					service::new_partial(&config, ForkingConfig::Manual)?;
				Ok((cmd.run(client, config.chain_spec), task_manager))
			})
		},
		Some(Subcommand::ImportBlocks(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.async_run(|config| {
				let PartialComponents { client, task_manager, import_queue, .. } =
					service::new_partial(&config, ForkingConfig::Manual)?;
				Ok((cmd.run(client, import_queue), task_manager))
			})
		},
		Some(Subcommand::PurgeChain(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.sync_run(|config| cmd.run(config.database))
		},
		Some(Subcommand::Revert(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.async_run(|config| {
				let PartialComponents { client, task_manager, backend, .. } =
					service::new_partial(&config, ForkingConfig::Manual)?;
				Ok((cmd.run(client, backend, None), task_manager))
			})
		},
		Some(Subcommand::ChainInfo(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.sync_run(|config| cmd.run::<Block>(&config))
		},
		None => {
			// Get the mining account from the cli
			let bytes: [u8; 32] = cli.pow.public_key_bytes(cli.run.get_keyring());
			let sr25519_public_key = sr25519::Public::from_raw(bytes);

			let runner = cli.create_runner(&cli.run)?;
			runner.run_node_until_exit(|config| async move {
				// Get the forking information from the chain spec extension.
				// Convert it to a strong type, and fill in the proper maxi position if they are
				// following mining.
				let forking_extension = ForkingExtensions::try_get(&*config.chain_spec)
					.expect("Should be able to get the fork config from the extension");
				let forking_config = match ForkingConfig::from(forking_extension) {
					ForkingConfig::Automatic(fork_heights, MaxiPosition::FollowMining) => {
						let maxi_position = match cli.pow.mining_algo {
							multi_pow::SupportedHashes::Md5 => MaxiPosition::NoMaxi,
							multi_pow::SupportedHashes::Sha3 => MaxiPosition::Sha3Maxi,
							multi_pow::SupportedHashes::Keccak => MaxiPosition::KeccakMaxi,
						};
						ForkingConfig::Automatic(fork_heights, maxi_position)
					},
					old_config => old_config,
				};

				service::new_full::<sc_network::Litep2pNetworkBackend>(
					config,
					forking_config,
					//TODO Combine the following three fields into a MiningConfig analogous to the
					// ForkingConfig
					sr25519_public_key,
					cli.pow.instant_seal,
					cli.pow.mining_algo,
				)
				.map_err(sc_cli::Error::Service)
			})
		},
	}
}
}
//! Substrate Node Template CLI library.
#![warn(missing_docs)]

mod chain_spec;
#[macro_use]
mod service;
mod cli;
mod command;
mod rpc;

fn main() -> sc_cli::Result<()> {
	command::run()
}
#![allow(unused)]
fn main() {
//! A collection of node-specific RPC methods.
//! Substrate provides the `sc-rpc` crate, which defines the core RPC layer
//! used by Substrate nodes. This file extends those RPC definitions with
//! capabilities that are specific to this project's runtime configuration.

#![warn(missing_docs)]

use std::sync::Arc;

use academy_pow_runtime::{opaque::Block, AccountId, Balance, Index};
use jsonrpsee::RpcModule;
pub use sc_rpc_api::DenyUnsafe;
use sc_transaction_pool_api::TransactionPool;
use sp_api::ProvideRuntimeApi;
use sp_block_builder::BlockBuilder;
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};

/// Full client dependencies.
pub struct FullDeps<C, P> {
	/// The client instance to use.
	pub client: Arc<C>,
	/// Transaction pool instance.
	pub pool: Arc<P>,
	/// Whether to deny unsafe calls
	pub deny_unsafe: DenyUnsafe,
}

/// Instantiate all full RPC extensions.
pub fn create_full<C, P>(
	deps: FullDeps<C, P>,
) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
where
	C: ProvideRuntimeApi<Block>,
	C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
	C: Send + Sync + 'static,
	C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
	C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
	C::Api: BlockBuilder<Block>,
	P: TransactionPool + 'static,
{
	use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
	use substrate_frame_rpc_system::{System, SystemApiServer};

	let mut module = RpcModule::new(());
	let FullDeps { client, pool, deny_unsafe } = deps;

	module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?;
	module.merge(TransactionPayment::new(client).into_rpc())?;

	Ok(module)
}
}
#![allow(unused)]
fn main() {
//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.

use core::clone::Clone;
use std::sync::Arc;

use academy_pow_runtime::{self, opaque::Block, PreDigest, RuntimeApi};
use multi_pow::{ForkingConfig, MultiPow, SupportedHashes};
use parity_scale_codec::Encode;
use sc_consensus::LongestChain;
use sc_service::{error::Error as ServiceError, Configuration, PartialComponents, TaskManager};
use sc_telemetry::{Telemetry, TelemetryWorker};
use sp_core::sr25519;

pub(crate) type FullClient = sc_service::TFullClient<
	Block,
	RuntimeApi,
	sc_executor::WasmExecutor<sp_io::SubstrateHostFunctions>,
>;
type FullBackend = sc_service::TFullBackend<Block>;
type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;

type BasicImportQueue = sc_consensus::DefaultImportQueue<Block>;
type BoxBlockImport = sc_consensus::BoxBlockImport<Block>;

pub type Service = PartialComponents<
	FullClient,
	FullBackend,
	FullSelectChain,
	BasicImportQueue,
	sc_transaction_pool::FullPool<Block, FullClient>,
	(BoxBlockImport, Option<Telemetry>),
>;

/// Returns most parts of a service. Not enough to run a full chain,
/// But enough to perform chain operations like purge-chain
#[allow(clippy::type_complexity)]
pub fn new_partial(
	config: &Configuration,
	fork_config: ForkingConfig,
) -> Result<Service, ServiceError> {
	let telemetry = config
		.telemetry_endpoints
		.clone()
		.filter(|x| !x.is_empty())
		.map(|endpoints| -> Result<_, sc_telemetry::Error> {
			let worker = TelemetryWorker::new(16)?;
			let telemetry = worker.handle().new_telemetry(endpoints);
			Ok((worker, telemetry))
		})
		.transpose()?;

	let executor = sc_service::new_wasm_executor::<sp_io::SubstrateHostFunctions>(config);
	let (client, backend, keystore_container, task_manager) =
		sc_service::new_full_parts::<Block, RuntimeApi, _>(
			config,
			telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
			executor,
		)?;
	let client = Arc::new(client);

	let telemetry = telemetry.map(|(worker, telemetry)| {
		task_manager.spawn_handle().spawn("telemetry", None, worker.run());
		telemetry
	});

	let select_chain = LongestChain::new(backend.clone());

	let transaction_pool = sc_transaction_pool::BasicPool::new_full(
		config.transaction_pool.clone(),
		config.role.is_authority().into(),
		config.prometheus_registry(),
		task_manager.spawn_essential_handle(),
		client.clone(),
	);

	let block_import = sc_consensus_pow::PowBlockImport::new(
		client.clone(),
		client.clone(),
		MultiPow::new(client.clone(), fork_config),
		0, // check inherents starting at block 0
		select_chain.clone(),
		move |_, ()| async move {
			let timestamp = sp_timestamp::InherentDataProvider::from_system_time();

			// We don't need the current mining key to check inherents, so we just use a default.
			// TODO, I don't think we need to do any checking here at all, right?
			// So can I just remove the author entirely?
			let author =
				academy_pow_runtime::block_author::InherentDataProvider(Default::default());

			Ok((timestamp, author))
		},
	);

	let import_queue = sc_consensus_pow::import_queue(
		Box::new(block_import.clone()),
		None,
		MultiPow::new(client.clone(), fork_config),
		&task_manager.spawn_essential_handle(),
		config.prometheus_registry(),
	)?;

	Ok(PartialComponents {
		client,
		backend,
		task_manager,
		import_queue,
		keystore_container,
		select_chain,
		transaction_pool,
		other: (Box::new(block_import), telemetry),
	})
}

/// Builds a new service for a full client.
pub fn new_full<
	N: sc_network::NetworkBackend<Block, <Block as sp_runtime::traits::Block>::Hash>,
>(
	config: Configuration,
	fork_config: ForkingConfig,
	sr25519_public_key: sr25519::Public,
	instant_seal: bool,
	mining_algo: SupportedHashes,
) -> Result<TaskManager, ServiceError> {
	let sc_service::PartialComponents {
		client,
		backend,
		mut task_manager,
		import_queue,
		keystore_container,
		select_chain,
		transaction_pool,
		other: (pow_block_import, mut telemetry),
	} = new_partial(&config, fork_config)?;

	let net_config = sc_network::config::FullNetworkConfiguration::<
		Block,
		<Block as sp_runtime::traits::Block>::Hash,
		N,
	>::new(&config.network);
	let metrics = sc_network::NotificationMetrics::new(None);

	let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =
		sc_service::build_network(sc_service::BuildNetworkParams {
			config: &config,
			net_config,
			client: client.clone(),
			transaction_pool: transaction_pool.clone(),
			spawn_handle: task_manager.spawn_handle(),
			import_queue,
			block_announce_validator_builder: None,
			warp_sync_params: None,
			block_relay: None,
			metrics,
		})?;

	let role = config.role.clone();
	let prometheus_registry = config.prometheus_registry().cloned();

	let rpc_extensions_builder = {
		let client = client.clone();
		let pool = transaction_pool.clone();

		Box::new(move |deny_unsafe, _| {
			let deps =
				crate::rpc::FullDeps { client: client.clone(), pool: pool.clone(), deny_unsafe };
			crate::rpc::create_full(deps).map_err(Into::into)
		})
	};

	sc_service::spawn_tasks(sc_service::SpawnTasksParams {
		network,
		client: client.clone(),
		keystore: keystore_container.keystore(),
		task_manager: &mut task_manager,
		transaction_pool: transaction_pool.clone(),
		rpc_builder: rpc_extensions_builder,
		backend,
		system_rpc_tx,
		tx_handler_controller,
		sync_service: sync_service.clone(),
		config,
		telemetry: telemetry.as_mut(),
	})?;

	if role.is_authority() {
		let proposer = sc_basic_authorship::ProposerFactory::new(
			task_manager.spawn_handle(),
			client.clone(),
			transaction_pool.clone(),
			prometheus_registry.as_ref(),
			telemetry.as_ref().map(|x| x.handle()),
		);

		// If instant seal is requested, we just start it. Otherwise, we do the full PoW setup.
		if instant_seal {
			let params = sc_consensus_manual_seal::InstantSealParams {
				block_import: client.clone(),
				env: proposer,
				client,
				pool: transaction_pool,
				select_chain,
				consensus_data_provider: None,
				create_inherent_data_providers: move |_, ()| async move {
					Ok(sp_timestamp::InherentDataProvider::from_system_time())
				},
			};

			let authorship_future = sc_consensus_manual_seal::run_instant_seal(params);

			task_manager.spawn_essential_handle().spawn_blocking(
				"instant-seal",
				None,
				authorship_future,
			);
		} else {
			let (mining_worker, mining_worker_task) = sc_consensus_pow::start_mining_worker(
				Box::new(pow_block_import),
				client.clone(),
				select_chain,
				MultiPow::new(client, fork_config),
				proposer,
				sync_service.clone(),
				sync_service,
				// Note the mining algorithm in the pre-runtime digest.
				// This allows us to know which algo it was in the runtime.
				// TODO This also makes it possible to remove the algo info from
				// the seal.
				Some(PreDigest::from((sr25519_public_key.into(), mining_algo)).encode()),
				// This code is copied from above. Would be better to not repeat it.
				move |_, ()| async move {
					let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
					// set default `author` following miner specified in CLI
					let author = academy_pow_runtime::block_author::InherentDataProvider(
						sr25519_public_key.encode(),
					);

					Ok((timestamp, author))
				},
				std::time::Duration::from_secs(10),
				std::time::Duration::from_secs(5),
			);

			task_manager.spawn_essential_handle().spawn_blocking(
				"pow-miner",
				Some("pow-mining"),
				mining_worker_task,
			);

			// Start Mining worker.
			//TODO Some of this should move into the multi_pow crate.
			use multi_pow::{multi_hash_meets_difficulty, Compute};
			use sp_core::U256;
			let mut nonce: U256 = U256::from(0);
			std::thread::spawn(move || loop {
				let worker = mining_worker.clone();
				let metadata = worker.metadata();
				if let Some(metadata) = metadata {
					let compute = Compute {
						difficulty: metadata.difficulty,
						pre_hash: metadata.pre_hash,
						nonce,
					};
					let seal = compute.compute(mining_algo);
					if multi_hash_meets_difficulty(&seal.work, seal.difficulty) {
						nonce = U256::from(0);
						let _ = futures::executor::block_on(worker.submit(seal.encode()));
					} else {
						nonce = nonce.saturating_add(U256::from(1));
						if nonce == U256::MAX {
							nonce = U256::from(0);
						}
					}
				} else {
					std::thread::sleep(std::time::Duration::from_secs(1));
				}
			});
		}
	}

	network_starter.start_network();
	Ok(task_manager)
}
}
fn main() {
	#[cfg(feature = "std")]
	substrate_wasm_builder::WasmBuilder::new()
		.with_current_project()
		.export_heap_base()
		.import_memory()
		.build()
}
#![allow(unused)]
fn main() {
//! This pallet allows block authors to self-identify by providing an sr25519 public key
//!
//! The included trait allows other pallets to fetch the author's account as long as the
//! runtime's AccountId type can be created from an sr25519 public key.

pub use pallet::*;
use parity_scale_codec::{Decode, Encode};
use sp_core::sr25519;
#[cfg(feature = "std")]
use sp_inherents::InherentData;
use sp_inherents::{InherentIdentifier, IsFatalError};
use sp_runtime::RuntimeString;
use sp_std::vec::Vec;

#[frame_support::pallet(dev_mode)]
pub mod pallet {
	use frame_support::pallet_prelude::*;
	use frame_system::pallet_prelude::*;

	use super::*;

	/// The BlockAuthor Inherent pallet.
	#[pallet::pallet]
	pub struct Pallet<T>(PhantomData<T>);
	/// The pallet's configuration trait. Nothing to configure.
	#[pallet::config]
	pub trait Config: frame_system::Config {
		fn on_author_set(_author_account: Self::AccountId) {}
	}

	#[pallet::error]
	pub enum Error<T> {
		/// Author already set in block.
		AuthorAlreadySet,
	}

	/// Author of current block.
	#[pallet::storage]
	pub type Author<T: Config> = StorageValue<_, sr25519::Public, OptionQuery>;

	#[pallet::call]
	impl<T: Config> Pallet<T>
	where
		<T as frame_system::Config>::AccountId: From<sp_core::sr25519::Public>,
	{
		/// Inherent to set the author of a block
		#[pallet::weight(1_000_000)]
		pub fn set_author(origin: OriginFor<T>, author: sr25519::Public) -> DispatchResult {
			ensure_none(origin)?;
			ensure!(Author::<T>::get().is_none(), Error::<T>::AuthorAlreadySet);

			// Store the author in case other pallets want to fetch it and to let
			// offchain tools inspect it
			Author::<T>::put(author);

			// Call the hook
			T::on_author_set(author.into());

			Ok(())
		}
	}

	#[pallet::hooks]
	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
		fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
			// Reset the author to None at the beginning of the block
			Author::<T>::kill();

			// Return zero weight because we are not using weight-based
			// transaction fees.
			Weight::zero()
		}
	}

	#[pallet::inherent]
	impl<T: Config> ProvideInherent for Pallet<T>
	where
		<T as frame_system::Config>::AccountId: From<sp_core::sr25519::Public>,
	{
		type Call = Call<T>;
		type Error = InherentError;
		const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;

		fn is_inherent_required(_: &InherentData) -> Result<Option<Self::Error>, Self::Error> {
			// Return Ok(Some(_)) unconditionally because this inherent is required in every block
			// If it is not found, throw an AuthorInherentRequired error.
			Ok(Some(InherentError::Other(sp_runtime::RuntimeString::Borrowed(
				"BlockAuthorInherentRequired",
			))))
		}

		fn create_inherent(data: &InherentData) -> Option<Self::Call> {
			// Grab the Vec<u8> labelled with "author_" from the map of all inherent data
			let author_raw = data
				.get_data::<InherentType>(&INHERENT_IDENTIFIER)
				.expect("Gets and decodes authorship inherent data")?;

			// Decode the Vec<u8> into an actual author
			let author = sr25519::Public::decode(&mut &author_raw[..])
				.expect("Decodes author raw inherent data");

			Some(Call::set_author { author })
		}

		fn is_inherent(call: &Self::Call) -> bool {
			matches!(call, Call::set_author { .. })
		}
	}
}

/// A trait to find the author (miner) of the block.
pub trait BlockAuthor {
	fn block_author() -> Option<sr25519::Public>;
}

impl BlockAuthor for () {
	fn block_author() -> Option<sr25519::Public> {
		None
	}
}

impl<T: Config> BlockAuthor for Pallet<T> {
	fn block_author() -> Option<sr25519::Public> {
		Author::<T>::get()
	}
}

pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"author__";

#[derive(Encode, Decode, Debug)]
pub enum InherentError {
	Other(RuntimeString),
}

impl IsFatalError for InherentError {
	fn is_fatal_error(&self) -> bool {
		match *self {
			InherentError::Other(_) => true,
		}
	}
}

impl InherentError {
	/// Try to create an instance ouf of the given identifier and data.
	#[cfg(feature = "std")]
	pub fn try_from(id: &InherentIdentifier, data: &[u8]) -> Option<Self> {
		if id == &INHERENT_IDENTIFIER {
			<InherentError as parity_scale_codec::Decode>::decode(&mut &data[..]).ok()
		} else {
			None
		}
	}
}

/// The type of data that the inherent will contain.
/// Just a byte array. It will be decoded to an actual pubkey later
pub type InherentType = Vec<u8>;

#[cfg(feature = "std")]
pub struct InherentDataProvider(pub InherentType);

#[cfg(feature = "std")]
#[async_trait::async_trait]
impl sp_inherents::InherentDataProvider for InherentDataProvider {
	async fn provide_inherent_data(
		&self,
		inherent_data: &mut InherentData,
	) -> Result<(), sp_inherents::Error> {
		inherent_data.put_data(INHERENT_IDENTIFIER, &self.0)
	}

	async fn try_handle_error(
		&self,
		identifier: &InherentIdentifier,
		_error: &[u8],
	) -> Option<Result<(), sp_inherents::Error>> {
		// Dont' process modules from other inherents
		if *identifier != INHERENT_IDENTIFIER {
			return None;
		}

		// All errors with the author inehrent are fatal
		Some(Err(sp_inherents::Error::Application(Box::from(String::from(
			"Error processing author inherent",
		)))))
	}
}
}
#![allow(unused)]
fn main() {
//! A difficulty adjustment algorithm (DAA) to keep the block time close to a particular goal
//! Cribbed from Kulupu https://github.com/kulupu/kulupu/blob/master/runtime/src/difficulty.rs
//!
//! It is possible to implement other DAAs such as that of BTC and BCH. This would be an interesting
//! and worth-while experiment. The DAAs should be abstracted away with a trait.
//! Some ideas: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3410460

use core::cmp::{max, min};

use frame_support::traits::Time;
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_core::U256;
use sp_runtime::traits::UniqueSaturatedInto;

#[derive(Encode, Decode, Clone, Copy, Eq, PartialEq, Debug, MaxEncodedLen, TypeInfo)]
pub struct DifficultyAndTimestamp<M> {
	pub difficulty: Difficulty,
	pub timestamp: M,
}

/// Move value linearly toward a goal
pub fn damp(actual: u128, goal: u128, damp_factor: u128) -> u128 {
	(actual + (damp_factor - 1) * goal) / damp_factor
}

/// Limit value to be within some factor from a goal
pub fn clamp(actual: u128, goal: u128, clamp_factor: u128) -> u128 {
	max(goal / clamp_factor, min(actual, goal * clamp_factor))
}

const DIFFICULTY_ADJUST_WINDOW: u128 = 60;
type Difficulty = U256;

pub use pallet::*;

#[frame_support::pallet(dev_mode)]
pub mod pallet {
	use frame_support::pallet_prelude::*;
	use frame_system::pallet_prelude::*;

	use super::*;

	/// Pallet's configuration trait.
	#[pallet::config]
	pub trait Config<I: 'static = ()>: frame_system::Config {
		/// A Source for timestamp data
		type TimeProvider: Time;
		/// The block time that the DAA will attempt to maintain
		type TargetBlockTime: Get<u128>;
		/// Dampening factor to use for difficulty adjustment
		type DampFactor: Get<u128>;
		/// Clamp factor to use for difficulty adjustment
		/// Limit value to within this factor of goal. Recommended value: 2
		type ClampFactor: Get<u128>;
		/// The maximum difficulty allowed. Recommended to use u128::max_value()
		type MaxDifficulty: Get<u128>;
		/// Minimum difficulty, enforced in difficulty retargetting
		/// avoids getting stuck when trying to increase difficulty subject to dampening
		/// Recommended to use same value as DampFactor
		type MinDifficulty: Get<u128>;

		/// Now that the pallet is instantiable, we need a way to decide which blocks are
		/// relevant to this instance. This function does just that.
		///
		/// The default implementation assumes that all blocks are relevant which is what
		/// you probably want when there is only a single instance.
		fn relevant_to_this_instance() -> bool {
			true
		}
	}

	#[pallet::pallet]
	pub struct Pallet<T, I = ()>(_);

	type DifficultyList<T, I> =
		[Option<DifficultyAndTimestamp<<<T as Config<I>>::TimeProvider as Time>::Moment>>; 60];

	/// Past difficulties and timestamps, from earliest to latest.
	#[pallet::storage]
	pub type PastDifficultiesAndTimestamps<T: Config<I>, I: 'static = ()> =
		StorageValue<_, DifficultyList<T, I>, ValueQuery, EmptyList<T, I>>;

	pub struct EmptyList<T: Config<I>, I: 'static = ()>(PhantomData<(T, I)>);
	impl<T: Config<I>, I> Get<DifficultyList<T, I>> for EmptyList<T, I> {
		fn get() -> DifficultyList<T, I> {
			[None; DIFFICULTY_ADJUST_WINDOW as usize]
		}
	}

	/// Current difficulty.
	#[pallet::storage]
	#[pallet::getter(fn difficulty)]
	pub type CurrentDifficulty<T: Config<I>, I: 'static = ()> =
		StorageValue<_, Difficulty, ValueQuery>;

	/// Initial difficulty.
	#[pallet::storage]
	pub type InitialDifficulty<T: Config<I>, I: 'static = ()> =
		StorageValue<_, Difficulty, ValueQuery>;

	#[pallet::genesis_config]
	pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
		pub _ph_data: Option<PhantomData<(T, I)>>,
		pub initial_difficulty: [u8; 32], // Difficulty = U256
	}

	#[pallet::genesis_build]
	impl<T: Config<I>, I: 'static> BuildGenesisConfig for GenesisConfig<T, I> {
		fn build(&self) {
			let initial_difficulty = U256::from_little_endian(&self.initial_difficulty);
			// Initialize the Current difficulty
			CurrentDifficulty::<T, I>::put(&initial_difficulty);

			// Store the initial difficulty in storage because we will need it
			// during the first DIFFICULTY_ADJUSTMENT_WINDOW blocks (see todo below).
			InitialDifficulty::<T, I>::put(&initial_difficulty);
		}
	}

	impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
		fn default() -> Self {
			GenesisConfig { _ph_data: Default::default(), initial_difficulty: [0u8; 32] }
		}
	}

	#[pallet::hooks]
	impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
		fn on_finalize(_n: BlockNumberFor<T>) {
			// First check if this is block is relevant to this instance of the difficulty
			// adjustment algorithm
			if !T::relevant_to_this_instance() {
				return;
			}

			let mut data = PastDifficultiesAndTimestamps::<T, I>::get();

			for i in 1..data.len() {
				data[i - 1] = data[i];
			}

			data[data.len() - 1] = Some(DifficultyAndTimestamp {
				timestamp: T::TimeProvider::now(),
				difficulty: Self::difficulty(),
			});

			let mut ts_delta = 0;
			for i in 1..(DIFFICULTY_ADJUST_WINDOW as usize) {
				let prev: Option<u128> = data[i - 1].map(|d| d.timestamp.unique_saturated_into());
				let cur: Option<u128> = data[i].map(|d| d.timestamp.unique_saturated_into());

				let delta = match (prev, cur) {
					(Some(prev), Some(cur)) => cur.saturating_sub(prev),
					_ => T::TargetBlockTime::get(),
				};
				ts_delta += delta;
			}

			if ts_delta == 0 {
				ts_delta = 1;
			}

			let mut diff_sum = U256::zero();
			//TODO Could we just initialize every array cell to the initial difficulty to not need
			// the separate storage item?
			for item in data.iter().take(DIFFICULTY_ADJUST_WINDOW as usize) {
				let diff = match item.map(|d| d.difficulty) {
					Some(diff) => diff,
					None => InitialDifficulty::<T, I>::get(),
				};
				diff_sum += diff;
			}

			if diff_sum < U256::from(T::MinDifficulty::get()) {
				diff_sum = U256::from(T::MinDifficulty::get());
			}

			// Calculate the average length of the adjustment window
			let adjustment_window = DIFFICULTY_ADJUST_WINDOW * T::TargetBlockTime::get();

			// adjust time delta toward goal subject to dampening and clamping
			let adj_ts = clamp(
				damp(ts_delta, adjustment_window, T::DampFactor::get()),
				adjustment_window,
				T::ClampFactor::get(),
			);

			// minimum difficulty avoids getting stuck due to dampening
			let difficulty = min(
				U256::from(T::MaxDifficulty::get()),
				max(
					U256::from(T::MinDifficulty::get()),
					diff_sum * U256::from(T::TargetBlockTime::get()) / U256::from(adj_ts),
				),
			);

			<PastDifficultiesAndTimestamps<T, I>>::put(data);
			<CurrentDifficulty<T, I>>::put(difficulty);
		}
	}
}
}
#![allow(unused)]
#![cfg_attr(not(feature = "std"), no_std)]

fn main() {
/// A trait for types that can provide the amount of issuance to award to the block
/// author for the given block number.
pub trait Issuance<BlockNumber, Balance> {
	fn issuance(block: BlockNumber) -> Balance;
}

// Minimal implementations for when you don't actually want any issuance
impl Issuance<u32, u128> for () {
	fn issuance(_block: u32) -> u128 {
		0
	}
}

impl Issuance<u64, u128> for () {
	fn issuance(_block: u64) -> u128 {
		0
	}
}

/// A type that provides block issuance according to bitcoin's rules
/// Initial issuance is 50 / block
/// Issuance is cut in half every 210,000 blocks
/// cribbed from
/// github.com/Bitcoin-ABC/bitcoin-abc/blob/9c7b12e6f128a59423f4de3d6d4b5231ebe9aac2/src/validation.
/// cpp#L1007

pub struct BitcoinHalving;

/// The number of blocks between each halving.
const HALVING_INTERVAL: u32 = 210_000;
/// The per-block issuance before any halving. Decimal places should be accounted for here.
const INITIAL_ISSUANCE: u32 = 50;

impl Issuance<u32, u128> for BitcoinHalving {
	fn issuance(block: u32) -> u128 {
		let halving = block / HALVING_INTERVAL;
		// Force block reward to zero when right shift is undefined.
		if halving >= 64 {
			return 0;
		}

		// Approximately, 600 seconds (or 10 minutes) for a block to be finalized.
		// Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
		// Divided by 2 using bitwise
		(INITIAL_ISSUANCE >> halving).into()
	}
}
}
#![allow(unused)]
fn main() {
//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.

#![cfg_attr(not(feature = "std"), no_std)]
// The construct runtime macro does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit = "256"]

// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

pub use frame_support::{
	construct_runtime, derive_impl, parameter_types,
	traits::{
		Currency, EstimateNextNewSession, Imbalance, IsSubType, KeyOwnerProofSystem,
		LockIdentifier, Nothing, OnUnbalanced, ValidatorSet, VariantCountOf,
	},
	weights::{
		constants::{
			BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND,
		},
		IdentityFee, Weight,
	},
	Callable, StorageValue,
};
use frame_support::{
	genesis_builder_helper::{build_state, get_preset},
	instances::{Instance1, Instance2, Instance3},
	sp_runtime::Perquintill,
	traits::{ConstU128, ConstU32, ConstU8},
};
use multi_pow::SupportedHashes;
pub use pallet_balances::Call as BalancesCall;
pub use pallet_timestamp::Call as TimestampCall;
use pallet_transaction_payment::{ConstFeeMultiplier, FungibleAdapter, Multiplier};
use parity_scale_codec::Decode;
use sp_api::impl_runtime_apis;
use sp_consensus_pow::POW_ENGINE_ID;
use sp_core::OpaqueMetadata;
// A few exports that help ease life for downstream crates.
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
use sp_runtime::{
	create_runtime_str, generic,
	traits::{
		AccountIdLookup, BlakeTwo256, Block as BlockT, Bounded, IdentifyAccount, One, Verify,
	},
	transaction_validity::{
		InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
	},
	ApplyExtrinsicResult, DigestItem, ExtrinsicInclusionMode, MultiSignature,
};
pub use sp_runtime::{FixedPointNumber, Perbill, Permill};
use sp_std::prelude::*;
#[cfg(feature = "std")]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
/// An index to a block.
pub type BlockNumber = u32;

/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
pub type Signature = MultiSignature;

/// Some way of identifying an account on the chain. We intentionally make it equivalent
/// to the public key of our transaction signing scheme.
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;

/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
/// never know...
pub type AccountIndex = u32;

/// Balance of an account.
pub type Balance = u128;

/// Index of a transaction in the chain.
pub type Nonce = u32;

/// Index of a transaction in the chain.
pub type Index = u32;

/// A hash of some data used by the chain.
pub type Hash = sp_core::H256;

/// Consensus digest containing block author and supported hash algorithm.
pub type PreDigest = (AccountId, SupportedHashes);

/// The BlockAuthor trait in `./block_author.rs`
pub mod block_author;

// /// The Difficulty Adjustment Algorithm in `./difficulty.rs`
pub mod difficulty;

/// The total issuance and halving time
pub mod issuance;

/// UTXOs serve as the digital equivalent of change you receive after making a cash purchase
pub mod utxo;

/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
/// to even the core data structures.
pub mod opaque {
	pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;

	use super::*;

	/// Opaque block header type.
	pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
	/// Opaque block type.
	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
	/// Opaque block identifier type.
	pub type BlockId = generic::BlockId<Block>;
}

/// This runtime version.
#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: create_runtime_str!("academy-pow"),
	impl_name: create_runtime_str!("academy-pow"),
	authoring_version: 1,
	spec_version: 1,
	impl_version: 1,
	apis: RUNTIME_API_VERSIONS,
	transaction_version: 1,
	state_version: 1,
};

/// The version information used to identify this runtime when compiled natively.
#[cfg(feature = "std")]
pub fn native_version() -> NativeVersion {
	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
}

const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
// native chain currency
pub const TOKEN_SYMBOL: &str = "Unit";
pub const TOKEN_DECIMALS: u32 = 12;
pub const TOKEN: u128 = 10u128.pow(TOKEN_DECIMALS);

parameter_types! {
	pub const BlockHashCount: BlockNumber = 2400;
	pub const Version: RuntimeVersion = VERSION;
	/// We allow for 2 seconds of compute with a 6 second average block time.
	pub BlockWeights: frame_system::limits::BlockWeights =
		frame_system::limits::BlockWeights::with_sensible_defaults(
			Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX),
			NORMAL_DISPATCH_RATIO,
		);
	pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
		::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
	pub const SS58Prefix: u8 = 42;
}

#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
impl frame_system::Config for Runtime {
	/// The basic call filter to use in dispatchable.
	type BaseCallFilter = frame_support::traits::Everything;
	/// Block & extrinsics weights: base values and limits.
	type BlockWeights = BlockWeights;
	/// The maximum length of a block (in bytes).
	type BlockLength = BlockLength;
	/// The identifier used to distinguish between accounts.
	type AccountId = AccountId;
	/// The aggregated dispatch type that is available for extrinsics.
	type RuntimeCall = RuntimeCall;
	/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
	type Lookup = AccountIdLookup<AccountId, ()>;
	/// The type for hashing blocks and tries.
	type Hash = Hash;
	/// The hashing algorithm used.
	type Hashing = BlakeTwo256;
	/// The ubiquitous event type.
	type RuntimeEvent = RuntimeEvent;
	/// The ubiquitous origin type.
	type RuntimeOrigin = RuntimeOrigin;
	/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
	type BlockHashCount = BlockHashCount;
	/// The weight of database operations that the runtime can invoke.
	type DbWeight = RocksDbWeight;
	/// Version of the runtime.
	type Version = Version;
	/// This type is being generated by the construct runtime macro.
	type PalletInfo = PalletInfo;
	/// What to do if a new account is created.
	type OnNewAccount = ();
	/// What to do if an account is fully reaped from the system.
	type OnKilledAccount = ();
	/// The data to be stored in an account.
	type AccountData = pallet_balances::AccountData<Balance>;
	/// Weight information for the extrinsics of this pallet.
	type SystemWeightInfo = ();
	/// This is used as an identifier of the chain. 42 is the generic substrate prefix.
	type SS58Prefix = SS58Prefix;
	/// The set code logic, just the default since we're not a parachain.
	type OnSetCode = ();
	type MaxConsumers = frame_support::traits::ConstU32<16>;
	type Nonce = Nonce;
	type Block = Block;
}

parameter_types! {
	pub const MinimumPeriod: u64 = 1000;
}

impl pallet_timestamp::Config for Runtime {
	/// A timestamp: milliseconds since the unix epoch.
	type Moment = u64;
	type OnTimestampSet = ();
	type MinimumPeriod = MinimumPeriod;
	type WeightInfo = ();
}

impl pallet_balances::Config for Runtime {
	type MaxLocks = ConstU32<50>;
	type MaxReserves = ();
	type ReserveIdentifier = [u8; 8];
	/// The type for recording an account's balance.
	type Balance = Balance;
	/// The ubiquitous event type.
	type RuntimeEvent = RuntimeEvent;
	type DustRemoval = ();
	type ExistentialDeposit = ConstU128<500>;
	type AccountStore = System;
	type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
	type FreezeIdentifier = RuntimeFreezeReason;
	type MaxFreezes = VariantCountOf<RuntimeFreezeReason>;
	type RuntimeHoldReason = RuntimeHoldReason;
	type RuntimeFreezeReason = RuntimeFreezeReason;
}

parameter_types! {
	pub const TargetBlockTime: u128 = 5_000;
	// Setting min difficulty to damp factor per recommendation
	pub const DampFactor: u128 = 3;
	pub const ClampFactor: u128 = 2;
	pub const MaxDifficulty: u128 = u128::max_value();
}

// Helper function to get the current blocks PoW algo from the predigest
fn current_blocks_mining_algo() -> SupportedHashes {
	System::digest()
		.logs
		.iter()
		.find_map(|digest_item| match digest_item {
			DigestItem::PreRuntime(POW_ENGINE_ID, pre_digest) =>
				PreDigest::decode(&mut &pre_digest[..]).map(|d| d.1).ok(),
			_ => None,
		})
		.expect("There should be exactly one pow pre-digest item")
}

impl difficulty::Config<Instance1> for Runtime {
	type TimeProvider = Timestamp;
	type TargetBlockTime = TargetBlockTime;
	type DampFactor = DampFactor;
	type ClampFactor = ClampFactor;
	type MaxDifficulty = MaxDifficulty;
	type MinDifficulty = DampFactor;

	fn relevant_to_this_instance() -> bool {
		current_blocks_mining_algo() == SupportedHashes::Md5
	}
}

impl difficulty::Config<Instance2> for Runtime {
	type TimeProvider = Timestamp;
	type TargetBlockTime = TargetBlockTime;
	type DampFactor = DampFactor;
	type ClampFactor = ClampFactor;
	type MaxDifficulty = MaxDifficulty;
	type MinDifficulty = DampFactor;

	fn relevant_to_this_instance() -> bool {
		current_blocks_mining_algo() == SupportedHashes::Sha3
	}
}

impl difficulty::Config<Instance3> for Runtime {
	type TimeProvider = Timestamp;
	type TargetBlockTime = TargetBlockTime;
	type DampFactor = DampFactor;
	type ClampFactor = ClampFactor;
	type MaxDifficulty = MaxDifficulty;
	type MinDifficulty = DampFactor;

	fn relevant_to_this_instance() -> bool {
		current_blocks_mining_algo() == SupportedHashes::Keccak
	}
}

impl block_author::Config for Runtime {
	// Each block mined issues 50 new tokens to the miner
	fn on_author_set(author_account: Self::AccountId) {
		let issuance = 50 * TOKEN;
		let _ = Balances::deposit_creating(&author_account, issuance);
	}
}

parameter_types! {
	// This value increases the priority of `Operational` transactions by adding
	// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
	// follows polkadot : https://github.com/paritytech/polkadot/blob/9ce5f7ef5abb1a4291454e8c9911b304d80679f9/runtime/polkadot/src/lib.rs#L369
	pub const OperationalFeeMultiplier: u8 = 5;
	// We expect that on average 25% of the normal capacity will be occupied with normal txs.
	pub const TargetSaturationLevel: Perquintill = Perquintill::from_percent(25);
	// During 20 blocks the fee may not change more than by 100%. This, together with the
	// `TargetSaturationLevel` value, results in variability ~0.067. For the corresponding
	// formulas please refer to Substrate code at `frame/transaction-payment/src/lib.rs`.
	pub FeeVariability: Multiplier = Multiplier::saturating_from_rational(67, 1000);
	// Fee should never be lower than the computational cost.
	pub MinimumMultiplier: Multiplier = Multiplier::one();
	pub MaximumMultiplier: Multiplier = Bounded::max_value();
}

parameter_types! {
	pub FeeMultiplier: Multiplier = Multiplier::one();
}

impl pallet_transaction_payment::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type OnChargeTransaction = FungibleAdapter<Balances, ()>;
	type OperationalFeeMultiplier = ConstU8<5>;
	type WeightToFee = IdentityFee<Balance>;
	type LengthToFee = IdentityFee<Balance>;
	type FeeMultiplierUpdate = ConstFeeMultiplier<FeeMultiplier>;
}

construct_runtime!(
	pub struct Runtime {
		System: frame_system,
		Timestamp: pallet_timestamp,
		Balances: pallet_balances,
		TransactionPayment: pallet_transaction_payment,
		Md5DifficultyAdjustment: difficulty::<Instance1>,
		Sha3DifficultyAdjustment: difficulty::<Instance2>,
		KeccakDifficultyAdjustment: difficulty::<Instance3>,
		BlockAuthor: block_author,
	}
);

/// The address format for describing accounts.
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// A Block signed with a Justification
pub type SignedBlock = generic::SignedBlock<Block>;
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
	frame_system::CheckNonZeroSender<Runtime>,
	frame_system::CheckSpecVersion<Runtime>,
	frame_system::CheckTxVersion<Runtime>,
	frame_system::CheckGenesis<Runtime>,
	frame_system::CheckEra<Runtime>,
	frame_system::CheckNonce<Runtime>,
	frame_system::CheckWeight<Runtime>,
	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
);
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
/// Executive: handles dispatch to the various modules.
pub type Executive = frame_executive::Executive<
	Runtime,
	Block,
	frame_system::ChainContext<Runtime>,
	Runtime,
	AllPalletsWithSystem,
>;

impl_runtime_apis! {
	impl sp_api::Core<Block> for Runtime {
		fn version() -> RuntimeVersion {
			VERSION
		}

		fn execute_block(block: Block) {
			Executive::execute_block(block)
		}

		fn initialize_block(header: &<Block as BlockT>::Header) -> ExtrinsicInclusionMode {
			Executive::initialize_block(header)
		}
	}

	impl sp_api::Metadata<Block> for Runtime {
		fn metadata() -> OpaqueMetadata {
			OpaqueMetadata::new(Runtime::metadata().into())
		}

		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
			Runtime::metadata_at_version(version)
		}

		fn metadata_versions() -> sp_std::vec::Vec<u32> {
			Runtime::metadata_versions()
		}
	}

	impl sp_block_builder::BlockBuilder<Block> for Runtime {
		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
			Executive::apply_extrinsic(extrinsic)
		}

		fn finalize_block() -> <Block as BlockT>::Header {
			Executive::finalize_block()
		}

		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
			data.create_extrinsics()
		}

		fn check_inherents(
			block: Block,
			data: sp_inherents::InherentData,
		) -> sp_inherents::CheckInherentsResult {
			data.check_extrinsics(&block)
		}
	}

	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
		fn validate_transaction(
			source: TransactionSource,
			tx: <Block as BlockT>::Extrinsic,
			block_hash: <Block as BlockT>::Hash,
		) -> TransactionValidity {
			Executive::validate_transaction(source, tx, block_hash)
		}
	}

	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
		fn offchain_worker(header: &<Block as BlockT>::Header) {
			Executive::offchain_worker(header)
		}
	}

	impl sp_session::SessionKeys<Block> for Runtime {
		fn generate_session_keys(_seed: Option<Vec<u8>>) -> Vec<u8> {
			Vec::new()
		}

		fn decode_session_keys(
			_encoded: Vec<u8>,
		) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
			None
		}
	}

	impl sp_consensus_pow::DifficultyApi<Block, multi_pow::Threshold> for Runtime {
		fn difficulty() -> multi_pow::Threshold {
			multi_pow::Threshold {
				md5: Md5DifficultyAdjustment::difficulty(),
				sha3: Sha3DifficultyAdjustment::difficulty(),
				keccak: KeccakDifficultyAdjustment::difficulty(),
			}
		}
	}

	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
		fn account_nonce(account: AccountId) -> Index {
			System::account_nonce(account)
		}
	}

	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime
	{
		fn query_info(
			uxt: <Block as BlockT>::Extrinsic,
			len: u32,
		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
			TransactionPayment::query_info(uxt, len)
		}
		fn query_fee_details(
			uxt: <Block as BlockT>::Extrinsic,
			len: u32,
		) -> pallet_transaction_payment::FeeDetails<Balance> {
			TransactionPayment::query_fee_details(uxt, len)
		}
		fn query_weight_to_fee(weight: Weight) -> Balance {
			TransactionPayment::weight_to_fee(weight)
		}
		fn query_length_to_fee(length: u32) -> Balance {
			TransactionPayment::length_to_fee(length)
		}
	}

	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
		for Runtime
	{
		fn query_call_info(
			call: RuntimeCall,
			len: u32,
		) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
			TransactionPayment::query_call_info(call, len)
		}
		fn query_call_fee_details(
			call: RuntimeCall,
			len: u32,
		) -> pallet_transaction_payment::FeeDetails<Balance> {
			TransactionPayment::query_call_fee_details(call, len)
		}
		fn query_weight_to_fee(weight: Weight) -> Balance {
			TransactionPayment::weight_to_fee(weight)
		}
		fn query_length_to_fee(length: u32) -> Balance {
			TransactionPayment::length_to_fee(length)
		}
	}

	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
			build_state::<RuntimeGenesisConfig>(config)
		}

		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
			get_preset::<RuntimeGenesisConfig>(id, |_| None)
		}

		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
			Default::default()
		}
	}
}
}
#![allow(unused)]
fn main() {
// We make sure this pallet uses `no_std` for compiling to Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_core::{
	sr25519::{Public, Signature},
	ByteArray, H256, H512,
};
use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

use super::{block_author::BlockAuthor, issuance::Issuance};

pub use pallet::*;

#[frame_support::pallet(dev_mode)]
pub mod pallet {
	use frame_support::pallet_prelude::*;
	use frame_system::pallet_prelude::*;

	use super::*;

	#[pallet::config]
	pub trait Config: frame_system::Config {}

	#[pallet::pallet]
	pub struct Pallet<T>(_);
}
}
# Basic
edition = "2021"
hard_tabs = true
max_width = 100
use_small_heuristics = "Max"
# Imports
imports_granularity = "Crate"
reorder_imports = true
# Consistency
newline_style = "Unix"
# Misc
chain_width = 80
spaces_around_ranges = false
binop_separator = "Back"
reorder_impl_items = false
match_arm_leading_pipes = "Preserve"
match_arm_blocks = false
match_block_trailing_comma = true
trailing_comma = "Vertical"
trailing_semicolon = false
use_field_init_shorthand = true
# Format comments
comment_width = 100
wrap_comments = true
diff --git a/multi-pow/src/lib.rs b/multi-pow/src/lib.rs
index 8c36e58..d3c0d24 100644
--- a/multi-pow/src/lib.rs
+++ b/multi-pow/src/lib.rs
@@ -3,16 +3,16 @@
 //! It is multi-pow in the sense that there are multiple supported hashing algorithms.
 //! A seal with any of the supported hashing algorithms will be accepted.
 //!
-//! The purpose of this design is to demonstrate hard and soft forks by adding and removing valid hashing algorithms.
-//! While there is no precedent for changing hashing algorithms in the real world yet, it is conceivable that
-//! a chain may want to upgrade to a new algorithm when the old one is suspected weak.
-//! In any case, the point is that we want to demonstrate hard and soft forks in an understandable way,
-//! the multiple hashing algorithms achieves that well.
+//! The purpose of this design is to demonstrate hard and soft forks by adding and removing valid
+//! hashing algorithms. While there is no precedent for changing hashing algorithms in the real
+//! world yet, it is conceivable that a chain may want to upgrade to a new algorithm when the old
+//! one is suspected weak. In any case, the point is that we want to demonstrate hard and soft forks
+//! in an understandable way, the multiple hashing algorithms achieves that well.
 //!
-//! In the future, the hope is that there will be a dedicated difficulty threshold for each hashing algorithm.
-//! But currently the Substrate PoW crates are not that flexible.
-//! We could solve it by adding a pre-digest that includes information about what hashing algo is being used
-//! for the runtime to use later in the difficulty adjustment.
+//! In the future, the hope is that there will be a dedicated difficulty threshold for each hashing
+//! algorithm. But currently the Substrate PoW crates are not that flexible.
+//! We could solve it by adding a pre-digest that includes information about what hashing algo is
+//! being used for the runtime to use later in the difficulty adjustment.
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
@@ -41,55 +41,55 @@ use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
 /// A struct that represents a difficulty threshold.
 /// Unlike a normal PoW algorithm this struct has a separate threshold for each hash
 #[derive(
-    Clone,
-    Copy,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Encode,
-    Decode,
-    Debug,
-    Default,
-    scale_info::TypeInfo,
+	Clone,
+	Copy,
+	PartialEq,
+	Eq,
+	PartialOrd,
+	Ord,
+	Encode,
+	Decode,
+	Debug,
+	Default,
+	scale_info::TypeInfo,
 )]
 pub struct Threshold {
-    pub md5: U256,
-    pub sha3: U256,
-    pub keccak: U256,
+	pub md5: U256,
+	pub sha3: U256,
+	pub keccak: U256,
 }
 
 // This trait does not seem to be fully baked in the Substrate PoW code
 // But we do need some kind of sinsible impl here so the node can import blocks.
 // so I will not use it for now.
 impl TotalDifficulty for Threshold {
-    fn increment(&mut self, other: Threshold) {
-        self.md5 += other.md5;
-        self.sha3 += other.sha3;
-        self.keccak += other.keccak;
-    }
+	fn increment(&mut self, other: Threshold) {
+		self.md5 += other.md5;
+		self.sha3 += other.sha3;
+		self.keccak += other.keccak;
+	}
 }
 
 /// An enum that represents the supported hash types
 #[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, Debug)]
 pub enum SupportedHashes {
-    Md5,
-    Sha3,
-    Keccak,
+	Md5,
+	Sha3,
+	Keccak,
 }
 
 impl Default for SupportedHashes {
-    fn default() -> Self {
-        Self::Sha3
-    }
+	fn default() -> Self {
+		Self::Sha3
+	}
 }
 
 /// A struct that represents a concrete hash value tagged with what hashing
 ///  algorithm was used to compute it.
 #[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, Debug, Default)]
 pub struct MultiHash {
-    pub algo: SupportedHashes,
-    pub value: H256,
+	pub algo: SupportedHashes,
+	pub value: H256,
 }
 
 /// Determine whether the given hash satisfies the given difficulty.
@@ -97,325 +97,310 @@ pub struct MultiHash {
 /// overflows the bounds of U256, then the product (and thus the hash)
 /// was too high.
 pub fn simple_hash_meets_difficulty(hash: &H256, difficulty: U256) -> bool {
-    let num_hash = U256::from_little_endian(&hash[..]);
-    let (_, overflowed) = num_hash.overflowing_mul(difficulty);
+	let num_hash = U256::from_little_endian(&hash[..]);
+	let (_, overflowed) = num_hash.overflowing_mul(difficulty);
 
-    !overflowed
+	!overflowed
 }
 
 pub fn multi_hash_meets_difficulty(hash: &MultiHash, difficulty: Threshold) -> bool {
-    match hash.algo {
-        SupportedHashes::Md5 => simple_hash_meets_difficulty(&hash.value, difficulty.md5),
-        SupportedHashes::Sha3 => simple_hash_meets_difficulty(&hash.value, difficulty.sha3),
-        SupportedHashes::Keccak => simple_hash_meets_difficulty(&hash.value, difficulty.keccak),
-    }
+	match hash.algo {
+		SupportedHashes::Md5 => simple_hash_meets_difficulty(&hash.value, difficulty.md5),
+		SupportedHashes::Sha3 => simple_hash_meets_difficulty(&hash.value, difficulty.sha3),
+		SupportedHashes::Keccak => simple_hash_meets_difficulty(&hash.value, difficulty.keccak),
+	}
 }
 
 /// A Seal struct that will be encoded to a Vec<u8> as used as the
 /// `RawSeal` type.
 #[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)]
 pub struct Seal {
-    pub work: MultiHash,
-    pub difficulty: Threshold,
-    pub nonce: U256,
+	pub work: MultiHash,
+	pub difficulty: Threshold,
+	pub nonce: U256,
 }
 
 /// A not-yet-computed attempt to solve the proof of work. Calling the
 /// compute method will compute the hash and return the seal.
 #[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)]
 pub struct Compute {
-    pub difficulty: Threshold,
-    pub pre_hash: H256,
-    pub nonce: U256,
+	pub difficulty: Threshold,
+	pub pre_hash: H256,
+	pub nonce: U256,
 }
 
 #[cfg(feature = "std")]
 impl Compute {
-    pub fn compute(self, algo: SupportedHashes) -> Seal {
-        let value = match algo {
-            SupportedHashes::Md5 => {
-                // The md5 is only 16 byte output, so we just concatenate it twice to
-                // get an H256
-                let bytes = *md5::compute(&self.encode()[..]);
-                let mut doubled = [0u8; 32];
-                doubled[0..16].copy_from_slice(&bytes[0..16]);
-                doubled[16..32].copy_from_slice(&bytes[0..16]);
-
-                H256::from(doubled)
-            }
-            SupportedHashes::Sha3 => {
-                H256::from_slice(Sha3_256::digest(&self.encode()[..]).as_slice())
-            }
-            SupportedHashes::Keccak => {
-                H256::from_slice(Keccak256::digest(&self.encode()[..]).as_slice())
-            }
-        };
-
-        Seal {
-            nonce: self.nonce,
-            difficulty: self.difficulty,
-            work: MultiHash { algo, value },
-        }
-    }
+	pub fn compute(self, algo: SupportedHashes) -> Seal {
+		let value = match algo {
+			SupportedHashes::Md5 => {
+				// The md5 is only 16 byte output, so we just concatenate it twice to
+				// get an H256
+				let bytes = *md5::compute(&self.encode()[..]);
+				let mut doubled = [0u8; 32];
+				doubled[0..16].copy_from_slice(&bytes[0..16]);
+				doubled[16..32].copy_from_slice(&bytes[0..16]);
+
+				H256::from(doubled)
+			},
+			SupportedHashes::Sha3 =>
+				H256::from_slice(Sha3_256::digest(&self.encode()[..]).as_slice()),
+			SupportedHashes::Keccak =>
+				H256::from_slice(Keccak256::digest(&self.encode()[..]).as_slice()),
+		};
+
+		Seal { nonce: self.nonce, difficulty: self.difficulty, work: MultiHash { algo, value } }
+	}
 }
 
 #[cfg(feature = "std")]
 /// A complete PoW Algorithm that uses multiple hashing algorithms.
 /// Needs a reference to the client so it can grab the difficulty from the runtime.
 pub struct MultiPow<C> {
-    client: Arc<C>,
-    fork_config: ForkingConfig,
+	client: Arc<C>,
+	fork_config: ForkingConfig,
 }
 
 #[cfg(feature = "std")]
 impl<C> MultiPow<C> {
-    pub fn new(client: Arc<C>, fork_config: ForkingConfig) -> Self {
-        Self {
-            client,
-            fork_config,
-        }
-    }
+	pub fn new(client: Arc<C>, fork_config: ForkingConfig) -> Self {
+		Self { client, fork_config }
+	}
 }
 
 //TODO could maybe derive clone_no_bound
 #[cfg(feature = "std")]
 impl<C> Clone for MultiPow<C> {
-    fn clone(&self) -> Self {
-        Self::new(self.client.clone(), self.fork_config)
-    }
+	fn clone(&self) -> Self {
+		Self::new(self.client.clone(), self.fork_config)
+	}
 }
 
 // Here we implement the general PowAlgorithm trait for our concrete algorithm.
 #[cfg(feature = "std")]
 impl<B: BlockT<Hash = H256>, C> PowAlgorithm<B> for MultiPow<C>
 where
-    C: ProvideRuntimeApi<B>,
-    C::Api: DifficultyApi<B, Threshold>,
-    C: sc_client_api::HeaderBackend<B>,
+	C: ProvideRuntimeApi<B>,
+	C::Api: DifficultyApi<B, Threshold>,
+	C: sc_client_api::HeaderBackend<B>,
 {
-    type Difficulty = Threshold;
-
-    fn difficulty(&self, parent: B::Hash) -> Result<Self::Difficulty, Error<B>> {
-        let difficulty = self
-            .client
-            .runtime_api()
-            .difficulty(parent)
-            .map_err(|err| {
-                sc_consensus_pow::Error::Environment(format!(
-                    "Fetching difficulty from runtime failed: {:?}",
-                    err
-                ))
-            })?;
-
-        Ok(difficulty)
-    }
-
-    fn verify(
-        &self,
-        parent_id: &BlockId<B>,
-        pre_hash: &H256,
-        pre_digest: Option<&[u8]>,
-        seal: &RawSeal,
-        difficulty: Self::Difficulty,
-    ) -> Result<bool, Error<B>> {
-        // Try to construct a seal object by decoding the raw seal given
-        let seal = match Seal::decode(&mut &seal[..]) {
-            Ok(seal) => seal,
-            Err(_) => return Ok(false),
-        };
-
-        log::debug!("✅ Decode seal passed!");
-
-        let Some(_encoded_pre_digest) = pre_digest else {
-            return Ok(false);
-        };
-
-        log::debug!("✅ Checksum digest passed!");
-
-        // // TODO idk why this always return md5 only
-        // let algo_from_predigest = match SupportedHashes::decode(&mut &encoded_pre_digest[..]) {
-        //     Ok(algo) => algo,
-        //     Err(_) => return Ok(false),
-        // };
-
-        // log::debug!("✅ Get algorithm from digest passed!");
-
-        // // Check that the pre-digest algo matches the seal algo
-        // // TODO it shouldn't be necessary to have both.
-        // if seal.work.algo != algo_from_predigest {
-        //     return Ok(false);
-        // }
-
-        // log::debug!("✅ Checksum algorithm from seal passed!");
-
-        // This is where we handle forks on the verification side.
-        // We will still need to handle it in the mining algorithm somewhere.
-        // Currently we make the miner configure what algo they mine manually with their cli.
-        let parent_number: u32 = match parent_id {
-            BlockId::Hash(h) => *self
-                .client
-                .header(*h)
-                .expect("Database should perform lookup successfully")
-                .expect("parent header should be present in the db")
-                .number(),
-            BlockId::Number(n) => *n,
-        }
-        .try_into()
-        .map_err(|_| ())
-        .expect("Block numbers can be converted to u32 (because they are u32)");
-
-        log::debug!("✅ Checksum parent block number passed!");
-
-        // Here we handle the forking logic according the the node operator's request.
-        let valid_algorithm = match self.fork_config {
-            ForkingConfig::Manual => manual_fork_validation(parent_number, seal.work.algo),
-            ForkingConfig::Automatic(fork_heights, maxi_position) => {
-                auto_fork_validation(parent_number, seal.work.algo, fork_heights, maxi_position)
-            }
-        };
-
-        if !valid_algorithm {
-            return Ok(false);
-        }
-
-        log::debug!("✅ Valid algorithm!");
-
-        // See whether the hash meets the difficulty requirement. If not, fail fast.
-        if !multi_hash_meets_difficulty(&seal.work, difficulty) {
-            return Ok(false);
-        }
-
-        log::debug!("✅ Checksum difficulty passed!");
-
-        // Make sure the provided work actually comes from the correct pre_hash
-        let compute = Compute {
-            difficulty,
-            pre_hash: *pre_hash,
-            nonce: seal.nonce,
-        };
-
-        if compute.compute(seal.work.algo) != seal {
-            return Ok(false);
-        }
-
-        log::debug!("✅ Re-compute passed!");
-
-        log::debug!("🛠️ All passed, append the block to the chain ...");
-
-        Ok(true)
-    }
+	type Difficulty = Threshold;
+
+	fn difficulty(&self, parent: B::Hash) -> Result<Self::Difficulty, Error<B>> {
+		let difficulty = self.client.runtime_api().difficulty(parent).map_err(|err| {
+			sc_consensus_pow::Error::Environment(format!(
+				"Fetching difficulty from runtime failed: {:?}",
+				err
+			))
+		})?;
+
+		Ok(difficulty)
+	}
+
+	fn verify(
+		&self,
+		parent_id: &BlockId<B>,
+		pre_hash: &H256,
+		pre_digest: Option<&[u8]>,
+		seal: &RawSeal,
+		difficulty: Self::Difficulty,
+	) -> Result<bool, Error<B>> {
+		// Try to construct a seal object by decoding the raw seal given
+		let seal = match Seal::decode(&mut &seal[..]) {
+			Ok(seal) => seal,
+			Err(_) => return Ok(false),
+		};
+
+		log::debug!("✅ Decode seal passed!");
+
+		let Some(_encoded_pre_digest) = pre_digest else {
+			return Ok(false);
+		};
+
+		log::debug!("✅ Checksum digest passed!");
+
+		// // TODO idk why this always return md5 only
+		// let algo_from_predigest = match SupportedHashes::decode(&mut &encoded_pre_digest[..]) {
+		//     Ok(algo) => algo,
+		//     Err(_) => return Ok(false),
+		// };
+
+		// log::debug!("✅ Get algorithm from digest passed!");
+
+		// // Check that the pre-digest algo matches the seal algo
+		// // TODO it shouldn't be necessary to have both.
+		// if seal.work.algo != algo_from_predigest {
+		//     return Ok(false);
+		// }
+
+		// log::debug!("✅ Checksum algorithm from seal passed!");
+
+		// This is where we handle forks on the verification side.
+		// We will still need to handle it in the mining algorithm somewhere.
+		// Currently we make the miner configure what algo they mine manually with their cli.
+		let parent_number: u32 = match parent_id {
+			BlockId::Hash(h) => *self
+				.client
+				.header(*h)
+				.expect("Database should perform lookup successfully")
+				.expect("parent header should be present in the db")
+				.number(),
+			BlockId::Number(n) => *n,
+		}
+		.try_into()
+		.map_err(|_| ())
+		.expect("Block numbers can be converted to u32 (because they are u32)");
+
+		log::debug!("✅ Checksum parent block number passed!");
+
+		// Here we handle the forking logic according the the node operator's request.
+		let valid_algorithm = match self.fork_config {
+			ForkingConfig::Manual => manual_fork_validation(parent_number, seal.work.algo),
+			ForkingConfig::Automatic(fork_heights, maxi_position) =>
+				auto_fork_validation(parent_number, seal.work.algo, fork_heights, maxi_position),
+		};
+
+		if !valid_algorithm {
+			return Ok(false);
+		}
+
+		log::debug!("✅ Valid algorithm!");
+
+		// See whether the hash meets the difficulty requirement. If not, fail fast.
+		if !multi_hash_meets_difficulty(&seal.work, difficulty) {
+			return Ok(false);
+		}
+
+		log::debug!("✅ Checksum difficulty passed!");
+
+		// Make sure the provided work actually comes from the correct pre_hash
+		let compute = Compute { difficulty, pre_hash: *pre_hash, nonce: seal.nonce };
+
+		if compute.compute(seal.work.algo) != seal {
+			return Ok(false);
+		}
+
+		log::debug!("✅ Re-compute passed!");
+
+		log::debug!("🛠️ All passed, append the block to the chain ...");
+
+		Ok(true)
+	}
 }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 ///
 pub struct ForkHeights {
-    /// The block height to perform the soft fork that adds sha3 and keccak support.
-    pub add_sha3_keccak: u32,
-    /// The block height to perform the hard fork that removes md5 support.
-    pub remove_md5: u32,
-    /// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
-    pub split_sha3_keccak: u32,
+	/// The block height to perform the soft fork that adds sha3 and keccak support.
+	pub add_sha3_keccak: u32,
+	/// The block height to perform the hard fork that removes md5 support.
+	pub remove_md5: u32,
+	/// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
+	pub split_sha3_keccak: u32,
 }
 
 /// Various political positions a node could take when the network is forking into
 /// keccak maxis and sha3 maxis
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 pub enum MaxiPosition {
-    /// Allow all blocks, both sha3 and keccak
-    NoMaxi,
-    /// Only allow sha3 blocks
-    Sha3Maxi,
-    /// Only allow keccak blocks
-    KeccakMaxi,
-    /// Only allow a single type of blocks. Which type it is is determined by what algo the node is mining.
-    FollowMining,
+	/// Allow all blocks, both sha3 and keccak
+	NoMaxi,
+	/// Only allow sha3 blocks
+	Sha3Maxi,
+	/// Only allow keccak blocks
+	KeccakMaxi,
+	/// Only allow a single type of blocks. Which type it is is determined by what algo the node is
+	/// mining.
+	FollowMining,
 }
 
 #[derive(Copy, Clone, Eq, PartialEq)]
 /// The actual properly typed config after we're done working around all the BS.
 pub enum ForkingConfig {
-    ///
-    Manual,
-    ///
-    Automatic(ForkHeights, MaxiPosition),
+	///
+	Manual,
+	///
+	Automatic(ForkHeights, MaxiPosition),
 }
 
 impl FromStr for MaxiPosition {
-    type Err = ();
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        Ok(match &s.to_lowercase()[..] {
-            "allow-all" | "allowall" | "no-maxi" | "nomaxi" => Self::NoMaxi,
-            "sha3-maxi" | "sha3maxi" => Self::Sha3Maxi,
-            "keccak-maxi" | "keccakmaxi" => Self::KeccakMaxi,
-            _ => Self::FollowMining,
-        })
-    }
+	type Err = ();
+
+	fn from_str(s: &str) -> Result<Self, Self::Err> {
+		Ok(match &s.to_lowercase()[..] {
+			"allow-all" | "allowall" | "no-maxi" | "nomaxi" => Self::NoMaxi,
+			"sha3-maxi" | "sha3maxi" => Self::Sha3Maxi,
+			"keccak-maxi" | "keccakmaxi" => Self::KeccakMaxi,
+			_ => Self::FollowMining,
+		})
+	}
 }
 
-/// Manual mode, the node operator manually specifies which hashing algorithms are valid through the mining client.
-/// If you would like to do a fork, simply allow, un-allow some algorithms to check it.
+/// Manual mode, the node operator manually specifies which hashing algorithms are valid through the
+/// mining client. If you would like to do a fork, simply allow, un-allow some algorithms to check
+/// it.
 fn manual_fork_validation(_parent_number: u32, algo: SupportedHashes) -> bool {
-    use SupportedHashes::*;
-
-    // To begin with, allow all algorithms.
-    // After the fork height this check is skipped so all the hashes become valid.
-    match algo {
-        Md5 => true,
-        Sha3 => true,
-        Keccak => true,
-    }
+	use SupportedHashes::*;
+
+	// To begin with, allow all algorithms.
+	// After the fork height this check is skipped so all the hashes become valid.
+	match algo {
+		Md5 => true,
+		Sha3 => true,
+		Keccak => true,
+	}
 }
 
 /// In automatic mode, the `ForkHeights` and `MaxiPosition` structs define the forking schedule
 /// and the node's behavior during the contentious fork
 /// (where the network splits into two chains supporting different hashing algorithms).
 /// The validation logic considers the parent block height,
-/// forking configuration parameters, and the hashing algorithm used in the PoW solution to determine its validity.
+/// forking configuration parameters, and the hashing algorithm used in the PoW solution to
+/// determine its validity.
 fn auto_fork_validation(
-    parent_number: u32,
-    algo: SupportedHashes,
-    fork_heights: ForkHeights,
-    maxi_position: MaxiPosition,
+	parent_number: u32,
+	algo: SupportedHashes,
+	fork_heights: ForkHeights,
+	maxi_position: MaxiPosition,
 ) -> bool {
-    use MaxiPosition::*;
-    use SupportedHashes::*;
-
-    log::debug!("parent_number: {:?}", parent_number);
-    log::debug!("fork_heights: {:?}", fork_heights);
-
-    if parent_number < fork_heights.add_sha3_keccak {
-        // To begin with we only allow md5 hashes for our pow.
-        // After the fork height this check is skipped so all the hashes become valid.
-        match algo {
-            Md5 => true,
-            Sha3 => false,
-            Keccak => false,
-        }
-    } else if parent_number < fork_heights.remove_md5 {
-        // After the first fork, all three algos become valid.
-        match algo {
-            Md5 => true,
-            Sha3 => true,
-            Keccak => true,
-        }
-    } else if parent_number < fork_heights.split_sha3_keccak {
-        // After the second fork, md5 is no longer valid.
-        match algo {
-            Md5 => false,
-            Sha3 => true,
-            Keccak => true,
-        }
-    } else {
-        // Finally we have the contentious fork.
-        // Our behavior here depends which maxi position we have taken.
-        #[allow(clippy::match_like_matches_macro)]
-        match (algo, maxi_position) {
-            (Sha3, Sha3Maxi) => true,
-            (Sha3, NoMaxi) => true,
-            (Keccak, KeccakMaxi) => true,
-            (Keccak, NoMaxi) => true,
-            _ => false,
-        }
-    }
+	use MaxiPosition::*;
+	use SupportedHashes::*;
+
+	log::debug!("parent_number: {:?}", parent_number);
+	log::debug!("fork_heights: {:?}", fork_heights);
+
+	if parent_number < fork_heights.add_sha3_keccak {
+		// To begin with we only allow md5 hashes for our pow.
+		// After the fork height this check is skipped so all the hashes become valid.
+		match algo {
+			Md5 => true,
+			Sha3 => false,
+			Keccak => false,
+		}
+	} else if parent_number < fork_heights.remove_md5 {
+		// After the first fork, all three algos become valid.
+		match algo {
+			Md5 => true,
+			Sha3 => true,
+			Keccak => true,
+		}
+	} else if parent_number < fork_heights.split_sha3_keccak {
+		// After the second fork, md5 is no longer valid.
+		match algo {
+			Md5 => false,
+			Sha3 => true,
+			Keccak => true,
+		}
+	} else {
+		// Finally we have the contentious fork.
+		// Our behavior here depends which maxi position we have taken.
+		#[allow(clippy::match_like_matches_macro)]
+		match (algo, maxi_position) {
+			(Sha3, Sha3Maxi) => true,
+			(Sha3, NoMaxi) => true,
+			(Keccak, KeccakMaxi) => true,
+			(Keccak, NoMaxi) => true,
+			_ => false,
+		}
+	}
 }
diff --git a/node/build.rs b/node/build.rs
index f97fd98..aa9206c 100644
--- a/node/build.rs
+++ b/node/build.rs
@@ -1,4 +1,4 @@
 fn main() {
-    substrate_build_script_utils::generate_cargo_keys();
-    substrate_build_script_utils::rerun_if_git_head_changed();
+	substrate_build_script_utils::generate_cargo_keys();
+	substrate_build_script_utils::rerun_if_git_head_changed();
 }
diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs
index a8e1732..091d0e8 100644
--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -1,19 +1,13 @@
 use std::str::FromStr;
 
 use academy_pow_runtime::{
-    AccountId,
-    SS58Prefix,
-    Signature,
-    TOKEN_DECIMALS,
-    TOKEN_SYMBOL,
-    WASM_BINARY,
+	AccountId, SS58Prefix, Signature, TOKEN_DECIMALS, TOKEN_SYMBOL, WASM_BINARY,
 };
 use multi_pow::{ForkHeights, ForkingConfig, MaxiPosition};
 use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
 use sc_service::ChainType;
 use serde::{Deserialize, Serialize};
-use sp_core::{sr25519, Pair, Public};
-use sp_core::{ByteArray, H256};
+use sp_core::{sr25519, ByteArray, Pair, Public, H256};
 use sp_runtime::traits::{IdentifyAccount, Verify};
 
 /// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
@@ -27,58 +21,58 @@ pub type ChainSpec = sc_service::GenericChainSpec<ForkingExtensions>;
 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]
 #[serde(deny_unknown_fields)]
 pub struct ForkingExtensions {
-    /// Manual mode is intended for when we you are running a live workshop.
-    /// No forking happens automatically. Rather, you have to hard-code the forks.
-    ///
-    /// If manual mode is enabled, the rest of the parameters are ignored.
-    /// This should really be an enum, but I have to work around the broken extension system.
-    ///
-    /// Aww damn it! I can't even use bool in this broken system? Okay then I guess 0 means automatic mode
-    /// and anything else means manual mode.
-    pub manual_mode: u32,
-    /// The block height to perform the soft fork that adds sha3 and keccak support.
-    pub add_sha3_keccak: u32,
-    /// The block height to perform the hard fork that removes md5 support.
-    pub remove_md5: u32,
-    /// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
-    pub split_sha3_keccak: u32,
-    // Damn extension thing is so fragile, I can't even use an enum here.
-    // Let alone that time I tried to use the forked value feature.
-    /// The political position that this node will take at the contentious fork.
-    pub maxi_position: String,
+	/// Manual mode is intended for when we you are running a live workshop.
+	/// No forking happens automatically. Rather, you have to hard-code the forks.
+	///
+	/// If manual mode is enabled, the rest of the parameters are ignored.
+	/// This should really be an enum, but I have to work around the broken extension system.
+	///
+	/// Aww damn it! I can't even use bool in this broken system? Okay then I guess 0 means
+	/// automatic mode and anything else means manual mode.
+	pub manual_mode: u32,
+	/// The block height to perform the soft fork that adds sha3 and keccak support.
+	pub add_sha3_keccak: u32,
+	/// The block height to perform the hard fork that removes md5 support.
+	pub remove_md5: u32,
+	/// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
+	pub split_sha3_keccak: u32,
+	// Damn extension thing is so fragile, I can't even use an enum here.
+	// Let alone that time I tried to use the forked value feature.
+	/// The political position that this node will take at the contentious fork.
+	pub maxi_position: String,
 }
 
 impl From<&ForkingExtensions> for ForkingConfig {
-    fn from(e: &ForkingExtensions) -> Self {
-        if e.manual_mode > 0 {
-            return Self::Manual;
-        }
-
-        let fork_heights = ForkHeights {
-            add_sha3_keccak: e.add_sha3_keccak,
-            remove_md5: e.remove_md5,
-            split_sha3_keccak: e.split_sha3_keccak,
-        };
-
-        let maxi_position =
-            MaxiPosition::from_str(&e.maxi_position).expect("Should have a valid maxi position...");
-
-        Self::Automatic(fork_heights, maxi_position)
-    }
+	fn from(e: &ForkingExtensions) -> Self {
+		if e.manual_mode > 0 {
+			return Self::Manual;
+		}
+
+		let fork_heights = ForkHeights {
+			add_sha3_keccak: e.add_sha3_keccak,
+			remove_md5: e.remove_md5,
+			split_sha3_keccak: e.split_sha3_keccak,
+		};
+
+		let maxi_position =
+			MaxiPosition::from_str(&e.maxi_position).expect("Should have a valid maxi position...");
+
+		Self::Automatic(fork_heights, maxi_position)
+	}
 }
 
 impl ForkingExtensions {
-    /// Try to get the extension from the given `ChainSpec`.
-    pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {
-        sc_chain_spec::get_extension(chain_spec.extensions())
-    }
+	/// Try to get the extension from the given `ChainSpec`.
+	pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {
+		sc_chain_spec::get_extension(chain_spec.extensions())
+	}
 }
 
 /// Generate a crypto pair from seed.
 pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
-    TPublic::Pair::from_string(&format!("//{}", seed), None)
-        .expect("static values are valid; qed")
-        .public()
+	TPublic::Pair::from_string(&format!("//{}", seed), None)
+		.expect("static values are valid; qed")
+		.public()
 }
 
 type AccountPublic = <Signature as Verify>::Signer;
@@ -86,103 +80,100 @@ type AccountPublic = <Signature as Verify>::Signer;
 /// Generate an account ID from seed.
 pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
 where
-    AccountPublic: From<<TPublic::Pair as Pair>::Public>,
+	AccountPublic: From<<TPublic::Pair as Pair>::Public>,
 {
-    AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
+	AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
 }
 
 pub fn development_config() -> Result<ChainSpec, String> {
-    Ok(ChainSpec::builder(
-        WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
-        ForkingExtensions {
-            manual_mode: 1, // change this to `0` if you want to try `auto_fork_validation`
-            add_sha3_keccak: 10,
-            remove_md5: 20,
-            split_sha3_keccak: 30,
-            maxi_position: String::from("follow-mining"),
-        },
-    )
-    .with_name("Development")
-    .with_id("dev")
-    .with_chain_type(ChainType::Development)
-    .with_genesis_config_patch(genesis(
-        // Pre-funded accounts
-        vec![
-            get_account_id_from_seed::<sr25519::Public>("Alice"),
-            get_account_id_from_seed::<sr25519::Public>("Bob"),
-            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
-            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
-        ],
-        // Initial Difficulty
-        4_000_000,
-    ))
-    .with_properties(system_properties())
-    .build())
+	Ok(ChainSpec::builder(
+		WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
+		ForkingExtensions {
+			manual_mode: 1, // change this to `0` if you want to try `auto_fork_validation`
+			add_sha3_keccak: 10,
+			remove_md5: 20,
+			split_sha3_keccak: 30,
+			maxi_position: String::from("follow-mining"),
+		},
+	)
+	.with_name("Development")
+	.with_id("dev")
+	.with_chain_type(ChainType::Development)
+	.with_genesis_config_patch(genesis(
+		// Pre-funded accounts
+		vec![
+			get_account_id_from_seed::<sr25519::Public>("Alice"),
+			get_account_id_from_seed::<sr25519::Public>("Bob"),
+			get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
+			get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
+		],
+		// Initial Difficulty
+		4_000_000,
+	))
+	.with_properties(system_properties())
+	.build())
 }
 
 pub fn testnet_config() -> Result<ChainSpec, String> {
-    Ok(ChainSpec::builder(
-        WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
-        ForkingExtensions {
-            manual_mode: 1,
-            add_sha3_keccak: 0,
-            remove_md5: 0,
-            split_sha3_keccak: 0,
-            maxi_position: String::new(),
-        },
-    )
-    .with_name("Testnet")
-    .with_id("testnet")
-    .with_chain_type(ChainType::Local)
-    .with_genesis_config_patch(genesis(
-        vec![
-            get_account_id_from_seed::<sr25519::Public>("Alice"),
-            get_account_id_from_seed::<sr25519::Public>("Bob"),
-            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
-            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
-        ],
-        4_000_000,
-    ))
-    .with_properties(system_properties())
-    .build())
+	Ok(ChainSpec::builder(
+		WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
+		ForkingExtensions {
+			manual_mode: 1,
+			add_sha3_keccak: 0,
+			remove_md5: 0,
+			split_sha3_keccak: 0,
+			maxi_position: String::new(),
+		},
+	)
+	.with_name("Testnet")
+	.with_id("testnet")
+	.with_chain_type(ChainType::Local)
+	.with_genesis_config_patch(genesis(
+		vec![
+			get_account_id_from_seed::<sr25519::Public>("Alice"),
+			get_account_id_from_seed::<sr25519::Public>("Bob"),
+			get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
+			get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
+		],
+		4_000_000,
+	))
+	.with_properties(system_properties())
+	.build())
 }
 
-fn genesis(
-    endowed_accounts: Vec<AccountId>,
-    initial_difficulty: u32,
-) -> serde_json::Value {
-    serde_json::json!({
-        "balances": {
-            // Configure endowed accounts with initial balance of 1 << 50.
-            "balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 50)).collect::<Vec<_>>(),
-        },
-        "keccakDifficultyAdjustment": {
-            "initialDifficulty": u32_to_u8_32(initial_difficulty),
-        },
-        "md5DifficultyAdjustment": {
-            "initialDifficulty": u32_to_u8_32(initial_difficulty),
-        },
-        "sha3DifficultyAdjustment": {
-            "initialDifficulty": u32_to_u8_32(initial_difficulty),
-        },
-    })
+fn genesis(endowed_accounts: Vec<AccountId>, initial_difficulty: u32) -> serde_json::Value {
+	serde_json::json!({
+		"balances": {
+			// Configure endowed accounts with initial balance of 1 << 50.
+			"balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 50)).collect::<Vec<_>>(),
+		},
+		"keccakDifficultyAdjustment": {
+			"initialDifficulty": u32_to_u8_32(initial_difficulty),
+		},
+		"md5DifficultyAdjustment": {
+			"initialDifficulty": u32_to_u8_32(initial_difficulty),
+		},
+		"sha3DifficultyAdjustment": {
+			"initialDifficulty": u32_to_u8_32(initial_difficulty),
+		},
+	})
 }
 
 /// Convert u32 (default value) to [u8;32] (U256)
 /// in little-endian format
 pub fn u32_to_u8_32(num: u32) -> [u8; 32] {
-    let mut result = [0u8; 32];
-    let bytes = num.to_le_bytes(); 
-    result[..4].copy_from_slice(&bytes);
-    result
+	let mut result = [0u8; 32];
+	let bytes = num.to_le_bytes();
+	result[..4].copy_from_slice(&bytes);
+	result
 }
 
 fn system_properties() -> sc_chain_spec::Properties {
-    let mut properties = sc_chain_spec::Properties::new();
+	let mut properties = sc_chain_spec::Properties::new();
 
-    properties.insert("ss58Format".into(), SS58Prefix::get().into());
-    properties.insert("tokenSymbol".into(), TOKEN_SYMBOL.into());
-    properties.insert("tokenDecimals".into(), TOKEN_DECIMALS.into());
+	properties.insert("ss58Format".into(), SS58Prefix::get().into());
+	properties.insert("tokenSymbol".into(), TOKEN_SYMBOL.into());
+	properties.insert("tokenDecimals".into(), TOKEN_DECIMALS.into());
 
-    properties
+	properties
 }
diff --git a/node/src/cli.rs b/node/src/cli.rs
index 4e1ac61..e7a62e5 100644
--- a/node/src/cli.rs
+++ b/node/src/cli.rs
@@ -1,8 +1,8 @@
 use academy_pow_runtime::AccountId;
 use multi_pow::SupportedHashes;
 use sc_cli::{
-    clap::{ArgGroup, Parser},
-    RunCmd,
+	clap::{ArgGroup, Parser},
+	RunCmd,
 };
 use sc_service::ChainType;
 use sp_core::{crypto::Ss58Codec, sr25519};
@@ -10,139 +10,136 @@ use sp_core::{crypto::Ss58Codec, sr25519};
 #[derive(Debug, Parser)]
 #[clap(subcommand_negates_reqs(true), version(env!("SUBSTRATE_CLI_IMPL_VERSION")))]
 pub struct Cli {
-    #[clap(subcommand)]
-    pub subcommand: Option<Subcommand>,
+	#[clap(subcommand)]
+	pub subcommand: Option<Subcommand>,
 
-    #[command(flatten)]
-    pub pow: AcademyPowCli,
+	#[command(flatten)]
+	pub pow: AcademyPowCli,
 
-    #[clap(flatten)]
-    pub run: RunCmd,
+	#[clap(flatten)]
+	pub run: RunCmd,
 }
 
 #[derive(Debug, Parser, Clone)]
 #[clap(group(ArgGroup::new("backup")))]
 pub struct AcademyPowCli {
-    /// Miner's AccountId (base58 encoding of an SR25519 public key) for the block rewards
-    #[clap(long,
+	/// Miner's AccountId (base58 encoding of an SR25519 public key) for the block rewards
+	#[clap(long,
            conflicts_with = "mining_public_key",
            value_parser = parse_account_id)]
-    pub mining_account_id: Option<AccountId>,
+	pub mining_account_id: Option<AccountId>,
 
-    /// Miner's hex encoding of the SR25519 public key) for the block rewards
-    #[clap(
+	/// Miner's hex encoding of the SR25519 public key) for the block rewards
+	#[clap(
         long,
         conflicts_with = "mining_account_id",
         value_parser = parse_sr25519_public_key
     )]
-    pub mining_public_key: Option<sr25519::Public>,
+	pub mining_public_key: Option<sr25519::Public>,
 
-    /// The mining algorithm to use
-    #[clap(long, value_parser = parse_algo, default_value = "md5")]
-    pub mining_algo: multi_pow::SupportedHashes,
+	/// The mining algorithm to use
+	#[clap(long, value_parser = parse_algo, default_value = "md5")]
+	pub mining_algo: multi_pow::SupportedHashes,
 
-    /// whether to use instant seal
-    #[clap(long, default_value = "false")]
-    pub instant_seal: bool,
+	/// whether to use instant seal
+	#[clap(long, default_value = "false")]
+	pub instant_seal: bool,
 }
 
 impl AcademyPowCli {
-    pub fn public_key_bytes(&self, keyring: Option<sp_keyring::Sr25519Keyring>) -> [u8; 32] {
-        match &self.mining_account_id {
-            Some(account_id) => *account_id.as_ref(),
-            None => match self.mining_public_key {
-                Some(public_key) => public_key.0,
-                None => keyring.map(|k| k.to_raw_public()).unwrap_or([0u8; 32]),
-            },
-        }
-    }
+	pub fn public_key_bytes(&self, keyring: Option<sp_keyring::Sr25519Keyring>) -> [u8; 32] {
+		match &self.mining_account_id {
+			Some(account_id) => *account_id.as_ref(),
+			None => match self.mining_public_key {
+				Some(public_key) => public_key.0,
+				None => keyring.map(|k| k.to_raw_public()).unwrap_or([0u8; 32]),
+			},
+		}
+	}
 }
 
 #[derive(Debug, Parser)]
 pub struct BuildSpecCmd {
-    #[clap(flatten)]
-    pub base: sc_cli::BuildSpecCmd,
+	#[clap(flatten)]
+	pub base: sc_cli::BuildSpecCmd,
 
-    /// Chain name.
-    #[arg(long, default_value = "Academy PoW")]
-    pub chain_name: String,
+	/// Chain name.
+	#[arg(long, default_value = "Academy PoW")]
+	pub chain_name: String,
 
-    /// Chain ID is a short identifier of the chain
-    #[arg(long, value_name = "ID", default_value = "academy_pow")]
-    pub chain_id: String,
+	/// Chain ID is a short identifier of the chain
+	#[arg(long, value_name = "ID", default_value = "academy_pow")]
+	pub chain_id: String,
 
-    /// AccountIds of the optional rich accounts
-    #[arg(long, value_delimiter = ',', value_parser = parse_account_id, num_args=1..)]
-    pub endowed_accounts: Option<Vec<AccountId>>,
+	/// AccountIds of the optional rich accounts
+	#[arg(long, value_delimiter = ',', value_parser = parse_account_id, num_args=1..)]
+	pub endowed_accounts: Option<Vec<AccountId>>,
 
-    /// The type of the chain. Possible values: "dev", "local", "live" (default)
-    #[arg(long, value_name = "TYPE", value_parser = parse_chaintype, default_value = "live")]
-    pub chain_type: ChainType,
+	/// The type of the chain. Possible values: "dev", "local", "live" (default)
+	#[arg(long, value_name = "TYPE", value_parser = parse_chaintype, default_value = "live")]
+	pub chain_type: ChainType,
 
-    #[arg(long, default_value = "4000000")]
-    pub initial_difficulty: u32,
+	#[arg(long, default_value = "4000000")]
+	pub initial_difficulty: u32,
 }
 
 fn parse_algo(s: &str) -> Result<SupportedHashes, String> {
-    Ok(match s {
-        "md" | "Md" | "md5" | "Md5" => SupportedHashes::Md5,
-        "sha" | "sha3" | "Sha" | "Sha3" => SupportedHashes::Sha3,
-        "keccak" | "Keccak" => SupportedHashes::Keccak,
-        s => panic!(
-            "Wrong mining algo: {}. Possible values: md5, sha3, keccak",
-            s
-        ),
-    })
+	Ok(match s {
+		"md" | "Md" | "md5" | "Md5" => SupportedHashes::Md5,
+		"sha" | "sha3" | "Sha" | "Sha3" => SupportedHashes::Sha3,
+		"keccak" | "Keccak" => SupportedHashes::Keccak,
+		s => panic!("Wrong mining algo: {}. Possible values: md5, sha3, keccak", s),
+	})
 }
 
 fn parse_chaintype(s: &str) -> Result<ChainType, String> {
-    Ok(match s {
-        "dev" => ChainType::Development,
-        "local" => ChainType::Local,
-        "live" => ChainType::Live,
-        s => panic!("Wrong chain type {} Possible values: dev local live", s),
-    })
+	Ok(match s {
+		"dev" => ChainType::Development,
+		"local" => ChainType::Local,
+		"live" => ChainType::Live,
+		s => panic!("Wrong chain type {} Possible values: dev local live", s),
+	})
 }
 
 /// Parse AccountId from a string argument passed on the command line.
 fn parse_account_id(s: &str) -> Result<AccountId, String> {
-    Ok(AccountId::from_string(s)
-        .expect("Passed string is not a bas58 encoding of a sr25519 public key"))
+	Ok(AccountId::from_string(s)
+		.expect("Passed string is not a bas58 encoding of a sr25519 public key"))
 }
 
 /// Parse sr25519 pubkey from a string argument passed on the command line.
 fn parse_sr25519_public_key(s: &str) -> Result<sr25519::Public, String> {
-    Ok(sr25519::Public::from_string(s)
-        .expect("Passed string is not a hex encoding of a sr25519 public key"))
+	Ok(sr25519::Public::from_string(s)
+		.expect("Passed string is not a hex encoding of a sr25519 public key"))
 }
 
 #[derive(Debug, clap::Subcommand)]
 pub enum Subcommand {
-    /// Key management cli utilities
-    #[command(subcommand)]
-    Key(sc_cli::KeySubcommand),
+	/// Key management cli utilities
+	#[command(subcommand)]
+	Key(sc_cli::KeySubcommand),
 
-    /// Build a chain specification.
-    BuildSpec(BuildSpecCmd),
+	/// Build a chain specification.
+	BuildSpec(BuildSpecCmd),
 
-    /// Validate blocks.
-    CheckBlock(sc_cli::CheckBlockCmd),
+	/// Validate blocks.
+	CheckBlock(sc_cli::CheckBlockCmd),
 
-    /// Export blocks.
-    ExportBlocks(sc_cli::ExportBlocksCmd),
+	/// Export blocks.
+	ExportBlocks(sc_cli::ExportBlocksCmd),
 
-    /// Export the state of a given block into a chain spec.
-    ExportState(sc_cli::ExportStateCmd),
+	/// Export the state of a given block into a chain spec.
+	ExportState(sc_cli::ExportStateCmd),
 
-    /// Import blocks.
-    ImportBlocks(sc_cli::ImportBlocksCmd),
+	/// Import blocks.
+	ImportBlocks(sc_cli::ImportBlocksCmd),
 
-    /// Remove the whole chain.
-    PurgeChain(sc_cli::PurgeChainCmd),
+	/// Remove the whole chain.
+	PurgeChain(sc_cli::PurgeChainCmd),
 
-    /// Revert the chain to a previous state.
-    Revert(sc_cli::RevertCmd),
+	/// Revert the chain to a previous state.
+	Revert(sc_cli::RevertCmd),
 
-    /// Db meta columns information.
-    ChainInfo(sc_cli::ChainInfoCmd),
+	/// Db meta columns information.
+	ChainInfo(sc_cli::ChainInfoCmd),
 }
diff --git a/node/src/command.rs b/node/src/command.rs
index b62bd98..18c5c54 100644
--- a/node/src/command.rs
+++ b/node/src/command.rs
@@ -21,163 +21,146 @@ use sc_service::PartialComponents;
 use sp_core::sr25519;
 
 use crate::{
-    chain_spec::{self, ForkingExtensions},
-    cli::{Cli, Subcommand},
-    service,
+	chain_spec::{self, ForkingExtensions},
+	cli::{Cli, Subcommand},
+	service,
 };
 
 impl SubstrateCli for Cli {
-    fn impl_name() -> String {
-        "Academy PoW Chain".into()
-    }
-
-    fn impl_version() -> String {
-        env!("SUBSTRATE_CLI_IMPL_VERSION").into()
-    }
-
-    fn executable_name() -> String {
-        env!("CARGO_PKG_NAME").into()
-    }
-
-    fn author() -> String {
-        env!("CARGO_PKG_AUTHORS").into()
-    }
-
-    fn description() -> String {
-        env!("CARGO_PKG_DESCRIPTION").into()
-    }
-
-    fn support_url() -> String {
-        "https://github.com/danielbui12/substrate-bitcoin-like-blockchain/issues/new".into()
-    }
-
-    fn copyright_start_year() -> i32 {
-        2025
-    }
-
-    fn load_spec(&self, id: &str) -> Result<Box<dyn sc_service::ChainSpec>, String> {
-        Ok(match id {
-            "" => Box::new(chain_spec::ChainSpec::from_json_bytes(
-                &include_bytes!("../../spec.json")[..],
-            )?),
-            "dev" => Box::new(chain_spec::development_config()?),
-            "local" => Box::new(chain_spec::testnet_config()?),
-            path => Box::new(chain_spec::ChainSpec::from_json_file(
-                std::path::PathBuf::from(path),
-            )?),
-        })
-    }
+	fn impl_name() -> String {
+		"Academy PoW Chain".into()
+	}
+
+	fn impl_version() -> String {
+		env!("SUBSTRATE_CLI_IMPL_VERSION").into()
+	}
+
+	fn executable_name() -> String {
+		env!("CARGO_PKG_NAME").into()
+	}
+
+	fn author() -> String {
+		env!("CARGO_PKG_AUTHORS").into()
+	}
+
+	fn description() -> String {
+		env!("CARGO_PKG_DESCRIPTION").into()
+	}
+
+	fn support_url() -> String {
+		"https://github.com/danielbui12/substrate-bitcoin-like-blockchain/issues/new".into()
+	}
+
+	fn copyright_start_year() -> i32 {
+		2025
+	}
+
+	fn load_spec(&self, id: &str) -> Result<Box<dyn sc_service::ChainSpec>, String> {
+		Ok(match id {
+			"" => Box::new(chain_spec::ChainSpec::from_json_bytes(
+				&include_bytes!("../../spec.json")[..],
+			)?),
+			"dev" => Box::new(chain_spec::development_config()?),
+			"local" => Box::new(chain_spec::testnet_config()?),
+			path =>
+				Box::new(chain_spec::ChainSpec::from_json_file(std::path::PathBuf::from(path))?),
+		})
+	}
 }
 
 /// Parse and run command line arguments
 pub fn run() -> sc_cli::Result<()> {
-    let cli = Cli::from_args();
-
-    match &cli.subcommand {
-        Some(Subcommand::Key(cmd)) => cmd.run(&cli),
-        Some(Subcommand::BuildSpec(cmd)) => {
-            let runner = cli.create_runner(&cmd.base)?;
-            runner.sync_run(|config| cmd.base.run(config.chain_spec, config.network))
-        }
-        Some(Subcommand::CheckBlock(cmd)) => {
-            let runner = cli.create_runner(cmd)?;
-            runner.async_run(|config| {
-                let PartialComponents {
-                    client,
-                    task_manager,
-                    import_queue,
-                    ..
-                } = service::new_partial(&config, ForkingConfig::Manual)?;
-                Ok((cmd.run(client, import_queue), task_manager))
-            })
-        }
-        Some(Subcommand::ExportBlocks(cmd)) => {
-            let runner = cli.create_runner(cmd)?;
-            runner.async_run(|config| {
-                let PartialComponents {
-                    client,
-                    task_manager,
-                    ..
-                } = service::new_partial(&config, ForkingConfig::Manual)?;
-                Ok((cmd.run(client, config.database), task_manager))
-            })
-        }
-        Some(Subcommand::ExportState(cmd)) => {
-            let runner = cli.create_runner(cmd)?;
-            runner.async_run(|config| {
-                let PartialComponents {
-                    client,
-                    task_manager,
-                    ..
-                } = service::new_partial(&config, ForkingConfig::Manual)?;
-                Ok((cmd.run(client, config.chain_spec), task_manager))
-            })
-        }
-        Some(Subcommand::ImportBlocks(cmd)) => {
-            let runner = cli.create_runner(cmd)?;
-            runner.async_run(|config| {
-                let PartialComponents {
-                    client,
-                    task_manager,
-                    import_queue,
-                    ..
-                } = service::new_partial(&config, ForkingConfig::Manual)?;
-                Ok((cmd.run(client, import_queue), task_manager))
-            })
-        }
-        Some(Subcommand::PurgeChain(cmd)) => {
-            let runner = cli.create_runner(cmd)?;
-            runner.sync_run(|config| cmd.run(config.database))
-        }
-        Some(Subcommand::Revert(cmd)) => {
-            let runner = cli.create_runner(cmd)?;
-            runner.async_run(|config| {
-                let PartialComponents {
-                    client,
-                    task_manager,
-                    backend,
-                    ..
-                } = service::new_partial(&config, ForkingConfig::Manual)?;
-                Ok((cmd.run(client, backend, None), task_manager))
-            })
-        }
-        Some(Subcommand::ChainInfo(cmd)) => {
-            let runner = cli.create_runner(cmd)?;
-            runner.sync_run(|config| cmd.run::<Block>(&config))
-        }
-        None => {
-            // Get the mining account from the cli
-            let bytes: [u8; 32] = cli.pow.public_key_bytes(cli.run.get_keyring());
-            let sr25519_public_key = sr25519::Public::from_raw(bytes);
-
-            let runner = cli.create_runner(&cli.run)?;
-            runner.run_node_until_exit(|config| async move {
-                // Get the forking information from the chain spec extension.
-                // Convert it to a strong type, and fill in the proper maxi position if they are following mining.
-                let forking_extension = ForkingExtensions::try_get(&*config.chain_spec)
-                    .expect("Should be able to get the fork config from the extension");
-                let forking_config = match ForkingConfig::from(forking_extension) {
-                    ForkingConfig::Automatic(fork_heights, MaxiPosition::FollowMining) => {
-                        let maxi_position = match cli.pow.mining_algo {
-                            multi_pow::SupportedHashes::Md5 => MaxiPosition::NoMaxi,
-                            multi_pow::SupportedHashes::Sha3 => MaxiPosition::Sha3Maxi,
-                            multi_pow::SupportedHashes::Keccak => MaxiPosition::KeccakMaxi,
-                        };
-                        ForkingConfig::Automatic(fork_heights, maxi_position)
-                    }
-                    old_config => old_config,
-                };
-
-                service::new_full::<sc_network::Litep2pNetworkBackend>(
-                    config,
-                    forking_config,
-                    //TODO Combine the following three fields into a MiningConfig analogous to the ForkingConfig
-                    sr25519_public_key,
-                    cli.pow.instant_seal,
-                    cli.pow.mining_algo,
-                )
-                .map_err(sc_cli::Error::Service)
-            })
-        }
-    }
+	let cli = Cli::from_args();
+
+	match &cli.subcommand {
+		Some(Subcommand::Key(cmd)) => cmd.run(&cli),
+		Some(Subcommand::BuildSpec(cmd)) => {
+			let runner = cli.create_runner(&cmd.base)?;
+			runner.sync_run(|config| cmd.base.run(config.chain_spec, config.network))
+		},
+		Some(Subcommand::CheckBlock(cmd)) => {
+			let runner = cli.create_runner(cmd)?;
+			runner.async_run(|config| {
+				let PartialComponents { client, task_manager, import_queue, .. } =
+					service::new_partial(&config, ForkingConfig::Manual)?;
+				Ok((cmd.run(client, import_queue), task_manager))
+			})
+		},
+		Some(Subcommand::ExportBlocks(cmd)) => {
+			let runner = cli.create_runner(cmd)?;
+			runner.async_run(|config| {
+				let PartialComponents { client, task_manager, .. } =
+					service::new_partial(&config, ForkingConfig::Manual)?;
+				Ok((cmd.run(client, config.database), task_manager))
+			})
+		},
+		Some(Subcommand::ExportState(cmd)) => {
+			let runner = cli.create_runner(cmd)?;
+			runner.async_run(|config| {
+				let PartialComponents { client, task_manager, .. } =
+					service::new_partial(&config, ForkingConfig::Manual)?;
+				Ok((cmd.run(client, config.chain_spec), task_manager))
+			})
+		},
+		Some(Subcommand::ImportBlocks(cmd)) => {
+			let runner = cli.create_runner(cmd)?;
+			runner.async_run(|config| {
+				let PartialComponents { client, task_manager, import_queue, .. } =
+					service::new_partial(&config, ForkingConfig::Manual)?;
+				Ok((cmd.run(client, import_queue), task_manager))
+			})
+		},
+		Some(Subcommand::PurgeChain(cmd)) => {
+			let runner = cli.create_runner(cmd)?;
+			runner.sync_run(|config| cmd.run(config.database))
+		},
+		Some(Subcommand::Revert(cmd)) => {
+			let runner = cli.create_runner(cmd)?;
+			runner.async_run(|config| {
+				let PartialComponents { client, task_manager, backend, .. } =
+					service::new_partial(&config, ForkingConfig::Manual)?;
+				Ok((cmd.run(client, backend, None), task_manager))
+			})
+		},
+		Some(Subcommand::ChainInfo(cmd)) => {
+			let runner = cli.create_runner(cmd)?;
+			runner.sync_run(|config| cmd.run::<Block>(&config))
+		},
+		None => {
+			// Get the mining account from the cli
+			let bytes: [u8; 32] = cli.pow.public_key_bytes(cli.run.get_keyring());
+			let sr25519_public_key = sr25519::Public::from_raw(bytes);
+
+			let runner = cli.create_runner(&cli.run)?;
+			runner.run_node_until_exit(|config| async move {
+				// Get the forking information from the chain spec extension.
+				// Convert it to a strong type, and fill in the proper maxi position if they are
+				// following mining.
+				let forking_extension = ForkingExtensions::try_get(&*config.chain_spec)
+					.expect("Should be able to get the fork config from the extension");
+				let forking_config = match ForkingConfig::from(forking_extension) {
+					ForkingConfig::Automatic(fork_heights, MaxiPosition::FollowMining) => {
+						let maxi_position = match cli.pow.mining_algo {
+							multi_pow::SupportedHashes::Md5 => MaxiPosition::NoMaxi,
+							multi_pow::SupportedHashes::Sha3 => MaxiPosition::Sha3Maxi,
+							multi_pow::SupportedHashes::Keccak => MaxiPosition::KeccakMaxi,
+						};
+						ForkingConfig::Automatic(fork_heights, maxi_position)
+					},
+					old_config => old_config,
+				};
+
+				service::new_full::<sc_network::Litep2pNetworkBackend>(
+					config,
+					forking_config,
+					//TODO Combine the following three fields into a MiningConfig analogous to the
+					// ForkingConfig
+					sr25519_public_key,
+					cli.pow.instant_seal,
+					cli.pow.mining_algo,
+				)
+				.map_err(sc_cli::Error::Service)
+			})
+		},
+	}
 }
diff --git a/node/src/main.rs b/node/src/main.rs
index a4182cd..4449d28 100644
--- a/node/src/main.rs
+++ b/node/src/main.rs
@@ -9,5 +9,5 @@ mod command;
 mod rpc;
 
 fn main() -> sc_cli::Result<()> {
-    command::run()
+	command::run()
 }
diff --git a/node/src/rpc.rs b/node/src/rpc.rs
index 875414c..c315565 100644
--- a/node/src/rpc.rs
+++ b/node/src/rpc.rs
@@ -17,39 +17,35 @@ use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
 
 /// Full client dependencies.
 pub struct FullDeps<C, P> {
-    /// The client instance to use.
-    pub client: Arc<C>,
-    /// Transaction pool instance.
-    pub pool: Arc<P>,
-    /// Whether to deny unsafe calls
-    pub deny_unsafe: DenyUnsafe,
+	/// The client instance to use.
+	pub client: Arc<C>,
+	/// Transaction pool instance.
+	pub pool: Arc<P>,
+	/// Whether to deny unsafe calls
+	pub deny_unsafe: DenyUnsafe,
 }
 
 /// Instantiate all full RPC extensions.
 pub fn create_full<C, P>(
-    deps: FullDeps<C, P>,
+	deps: FullDeps<C, P>,
 ) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
 where
-    C: ProvideRuntimeApi<Block>,
-    C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
-    C: Send + Sync + 'static,
-    C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
-    C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
-    C::Api: BlockBuilder<Block>,
-    P: TransactionPool + 'static,
+	C: ProvideRuntimeApi<Block>,
+	C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
+	C: Send + Sync + 'static,
+	C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
+	C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
+	C::Api: BlockBuilder<Block>,
+	P: TransactionPool + 'static,
 {
-    use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
-    use substrate_frame_rpc_system::{System, SystemApiServer};
+	use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
+	use substrate_frame_rpc_system::{System, SystemApiServer};
 
-    let mut module = RpcModule::new(());
-    let FullDeps {
-        client,
-        pool,
-        deny_unsafe,
-    } = deps;
+	let mut module = RpcModule::new(());
+	let FullDeps { client, pool, deny_unsafe } = deps;
 
-    module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?;
-    module.merge(TransactionPayment::new(client).into_rpc())?;
+	module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?;
+	module.merge(TransactionPayment::new(client).into_rpc())?;
 
-    Ok(module)
+	Ok(module)
 }
diff --git a/node/src/service.rs b/node/src/service.rs
index 4bf3935..abf64b5 100644
--- a/node/src/service.rs
+++ b/node/src/service.rs
@@ -23,266 +23,261 @@ type BasicImportQueue = sc_consensus::DefaultImportQueue<Block>;
 type BoxBlockImport = sc_consensus::BoxBlockImport<Block>;
 
 pub type Service = PartialComponents<
-    FullClient,
-    FullBackend,
-    FullSelectChain,
-    BasicImportQueue,
-    sc_transaction_pool::FullPool<Block, FullClient>,
-    (BoxBlockImport, Option<Telemetry>),
+	FullClient,
+	FullBackend,
+	FullSelectChain,
+	BasicImportQueue,
+	sc_transaction_pool::FullPool<Block, FullClient>,
+	(BoxBlockImport, Option<Telemetry>),
 >;
 
 /// Returns most parts of a service. Not enough to run a full chain,
 /// But enough to perform chain operations like purge-chain
 #[allow(clippy::type_complexity)]
 pub fn new_partial(
-    config: &Configuration,
-    fork_config: ForkingConfig,
+	config: &Configuration,
+	fork_config: ForkingConfig,
 ) -> Result<Service, ServiceError> {
-    let telemetry = config
-        .telemetry_endpoints
-        .clone()
-        .filter(|x| !x.is_empty())
-        .map(|endpoints| -> Result<_, sc_telemetry::Error> {
-            let worker = TelemetryWorker::new(16)?;
-            let telemetry = worker.handle().new_telemetry(endpoints);
-            Ok((worker, telemetry))
-        })
-        .transpose()?;
+	let telemetry = config
+		.telemetry_endpoints
+		.clone()
+		.filter(|x| !x.is_empty())
+		.map(|endpoints| -> Result<_, sc_telemetry::Error> {
+			let worker = TelemetryWorker::new(16)?;
+			let telemetry = worker.handle().new_telemetry(endpoints);
+			Ok((worker, telemetry))
+		})
+		.transpose()?;
 
-    let executor = sc_service::new_wasm_executor::<sp_io::SubstrateHostFunctions>(config);
-    let (client, backend, keystore_container, task_manager) =
-        sc_service::new_full_parts::<Block, RuntimeApi, _>(
-            config,
-            telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
-            executor,
-        )?;
-    let client = Arc::new(client);
+	let executor = sc_service::new_wasm_executor::<sp_io::SubstrateHostFunctions>(config);
+	let (client, backend, keystore_container, task_manager) =
+		sc_service::new_full_parts::<Block, RuntimeApi, _>(
+			config,
+			telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
+			executor,
+		)?;
+	let client = Arc::new(client);
 
-    let telemetry = telemetry.map(|(worker, telemetry)| {
-        task_manager
-            .spawn_handle()
-            .spawn("telemetry", None, worker.run());
-        telemetry
-    });
+	let telemetry = telemetry.map(|(worker, telemetry)| {
+		task_manager.spawn_handle().spawn("telemetry", None, worker.run());
+		telemetry
+	});
 
-    let select_chain = LongestChain::new(backend.clone());
+	let select_chain = LongestChain::new(backend.clone());
 
-    let transaction_pool = sc_transaction_pool::BasicPool::new_full(
-        config.transaction_pool.clone(),
-        config.role.is_authority().into(),
-        config.prometheus_registry(),
-        task_manager.spawn_essential_handle(),
-        client.clone(),
-    );
+	let transaction_pool = sc_transaction_pool::BasicPool::new_full(
+		config.transaction_pool.clone(),
+		config.role.is_authority().into(),
+		config.prometheus_registry(),
+		task_manager.spawn_essential_handle(),
+		client.clone(),
+	);
 
-    let block_import = sc_consensus_pow::PowBlockImport::new(
-        client.clone(),
-        client.clone(),
-        MultiPow::new(client.clone(), fork_config),
-        0, // check inherents starting at block 0
-        select_chain.clone(),
-        move |_, ()| async move {
-            let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
+	let block_import = sc_consensus_pow::PowBlockImport::new(
+		client.clone(),
+		client.clone(),
+		MultiPow::new(client.clone(), fork_config),
+		0, // check inherents starting at block 0
+		select_chain.clone(),
+		move |_, ()| async move {
+			let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
 
-            // We don't need the current mining key to check inherents, so we just use a default.
-            // TODO, I don't think we need to do any checking here at all, right?
-            // So can I just remove the author entirely?
-            let author =
-                academy_pow_runtime::block_author::InherentDataProvider(Default::default());
+			// We don't need the current mining key to check inherents, so we just use a default.
+			// TODO, I don't think we need to do any checking here at all, right?
+			// So can I just remove the author entirely?
+			let author =
+				academy_pow_runtime::block_author::InherentDataProvider(Default::default());
 
-            Ok((timestamp, author))
-        },
-    );
+			Ok((timestamp, author))
+		},
+	);
 
-    let import_queue = sc_consensus_pow::import_queue(
-        Box::new(block_import.clone()),
-        None,
-        MultiPow::new(client.clone(), fork_config),
-        &task_manager.spawn_essential_handle(),
-        config.prometheus_registry(),
-    )?;
+	let import_queue = sc_consensus_pow::import_queue(
+		Box::new(block_import.clone()),
+		None,
+		MultiPow::new(client.clone(), fork_config),
+		&task_manager.spawn_essential_handle(),
+		config.prometheus_registry(),
+	)?;
 
-    Ok(PartialComponents {
-        client,
-        backend,
-        task_manager,
-        import_queue,
-        keystore_container,
-        select_chain,
-        transaction_pool,
-        other: (Box::new(block_import), telemetry),
-    })
+	Ok(PartialComponents {
+		client,
+		backend,
+		task_manager,
+		import_queue,
+		keystore_container,
+		select_chain,
+		transaction_pool,
+		other: (Box::new(block_import), telemetry),
+	})
 }
 
 /// Builds a new service for a full client.
 pub fn new_full<
-    N: sc_network::NetworkBackend<Block, <Block as sp_runtime::traits::Block>::Hash>,
+	N: sc_network::NetworkBackend<Block, <Block as sp_runtime::traits::Block>::Hash>,
 >(
-    config: Configuration,
-    fork_config: ForkingConfig,
-    sr25519_public_key: sr25519::Public,
-    instant_seal: bool,
-    mining_algo: SupportedHashes,
+	config: Configuration,
+	fork_config: ForkingConfig,
+	sr25519_public_key: sr25519::Public,
+	instant_seal: bool,
+	mining_algo: SupportedHashes,
 ) -> Result<TaskManager, ServiceError> {
-    let sc_service::PartialComponents {
-        client,
-        backend,
-        mut task_manager,
-        import_queue,
-        keystore_container,
-        select_chain,
-        transaction_pool,
-        other: (pow_block_import, mut telemetry),
-    } = new_partial(&config, fork_config)?;
+	let sc_service::PartialComponents {
+		client,
+		backend,
+		mut task_manager,
+		import_queue,
+		keystore_container,
+		select_chain,
+		transaction_pool,
+		other: (pow_block_import, mut telemetry),
+	} = new_partial(&config, fork_config)?;
 
-    let net_config = sc_network::config::FullNetworkConfiguration::<
-        Block,
-        <Block as sp_runtime::traits::Block>::Hash,
-        N,
-    >::new(&config.network);
+	let net_config = sc_network::config::FullNetworkConfiguration::<
+		Block,
+		<Block as sp_runtime::traits::Block>::Hash,
+		N,
+	>::new(&config.network);
 	let metrics = sc_network::NotificationMetrics::new(None);
 
-    let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =
-        sc_service::build_network(sc_service::BuildNetworkParams {
-            config: &config,
-            net_config,
-            client: client.clone(),
-            transaction_pool: transaction_pool.clone(),
-            spawn_handle: task_manager.spawn_handle(),
-            import_queue,
-            block_announce_validator_builder: None,
-            warp_sync_params: None,
-            block_relay: None,
-            metrics: metrics,
-        })?;
+	let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =
+		sc_service::build_network(sc_service::BuildNetworkParams {
+			config: &config,
+			net_config,
+			client: client.clone(),
+			transaction_pool: transaction_pool.clone(),
+			spawn_handle: task_manager.spawn_handle(),
+			import_queue,
+			block_announce_validator_builder: None,
+			warp_sync_params: None,
+			block_relay: None,
+			metrics,
+		})?;
 
-    let role = config.role.clone();
-    let prometheus_registry = config.prometheus_registry().cloned();
+	let role = config.role.clone();
+	let prometheus_registry = config.prometheus_registry().cloned();
 
-    let rpc_extensions_builder = {
-        let client = client.clone();
-        let pool = transaction_pool.clone();
+	let rpc_extensions_builder = {
+		let client = client.clone();
+		let pool = transaction_pool.clone();
 
-        Box::new(move |deny_unsafe, _| {
-            let deps = crate::rpc::FullDeps {
-                client: client.clone(),
-                pool: pool.clone(),
-                deny_unsafe,
-            };
-            crate::rpc::create_full(deps).map_err(Into::into)
-        })
-    };
+		Box::new(move |deny_unsafe, _| {
+			let deps =
+				crate::rpc::FullDeps { client: client.clone(), pool: pool.clone(), deny_unsafe };
+			crate::rpc::create_full(deps).map_err(Into::into)
+		})
+	};
 
-    sc_service::spawn_tasks(sc_service::SpawnTasksParams {
-        network,
-        client: client.clone(),
-        keystore: keystore_container.keystore(),
-        task_manager: &mut task_manager,
-        transaction_pool: transaction_pool.clone(),
-        rpc_builder: rpc_extensions_builder,
-        backend,
-        system_rpc_tx,
-        tx_handler_controller,
-        sync_service: sync_service.clone(),
-        config,
-        telemetry: telemetry.as_mut(),
-    })?;
+	sc_service::spawn_tasks(sc_service::SpawnTasksParams {
+		network,
+		client: client.clone(),
+		keystore: keystore_container.keystore(),
+		task_manager: &mut task_manager,
+		transaction_pool: transaction_pool.clone(),
+		rpc_builder: rpc_extensions_builder,
+		backend,
+		system_rpc_tx,
+		tx_handler_controller,
+		sync_service: sync_service.clone(),
+		config,
+		telemetry: telemetry.as_mut(),
+	})?;
 
-    if role.is_authority() {
-        let proposer = sc_basic_authorship::ProposerFactory::new(
-            task_manager.spawn_handle(),
-            client.clone(),
-            transaction_pool.clone(),
-            prometheus_registry.as_ref(),
-            telemetry.as_ref().map(|x| x.handle()),
-        );
+	if role.is_authority() {
+		let proposer = sc_basic_authorship::ProposerFactory::new(
+			task_manager.spawn_handle(),
+			client.clone(),
+			transaction_pool.clone(),
+			prometheus_registry.as_ref(),
+			telemetry.as_ref().map(|x| x.handle()),
+		);
 
-        // If instant seal is requested, we just start it. Otherwise, we do the full PoW setup.
-        if instant_seal {
-            let params = sc_consensus_manual_seal::InstantSealParams {
-                block_import: client.clone(),
-                env: proposer,
-                client,
-                pool: transaction_pool,
-                select_chain,
-                consensus_data_provider: None,
-                create_inherent_data_providers: move |_, ()| async move {
-                    Ok(sp_timestamp::InherentDataProvider::from_system_time())
-                },
-            };
+		// If instant seal is requested, we just start it. Otherwise, we do the full PoW setup.
+		if instant_seal {
+			let params = sc_consensus_manual_seal::InstantSealParams {
+				block_import: client.clone(),
+				env: proposer,
+				client,
+				pool: transaction_pool,
+				select_chain,
+				consensus_data_provider: None,
+				create_inherent_data_providers: move |_, ()| async move {
+					Ok(sp_timestamp::InherentDataProvider::from_system_time())
+				},
+			};
 
-            let authorship_future = sc_consensus_manual_seal::run_instant_seal(params);
+			let authorship_future = sc_consensus_manual_seal::run_instant_seal(params);
 
-            task_manager.spawn_essential_handle().spawn_blocking(
-                "instant-seal",
-                None,
-                authorship_future,
-            );
-        } else {
-            let (mining_worker, mining_worker_task) = sc_consensus_pow::start_mining_worker(
-                Box::new(pow_block_import),
-                client.clone(),
-                select_chain,
-                MultiPow::new(client, fork_config),
-                proposer,
-                sync_service.clone(),
-                sync_service,
-                // Note the mining algorithm in the pre-runtime digest.
-                // This allows us to know which algo it was in the runtime.
-                // TODO This also makes it possible to remove the algo info from
-                // the seal.
-                Some(PreDigest::from((sr25519_public_key.into(), mining_algo)).encode()),
-                // This code is copied from above. Would be better to not repeat it.
-                move |_, ()| async move {
-                    let timestamp = sp_timestamp::InherentDataProvider::from_system_time();            
-                    // set default `author` following miner specified in CLI
-                    let author = academy_pow_runtime::block_author::InherentDataProvider(
-                        sr25519_public_key.encode(),
-                    );
+			task_manager.spawn_essential_handle().spawn_blocking(
+				"instant-seal",
+				None,
+				authorship_future,
+			);
+		} else {
+			let (mining_worker, mining_worker_task) = sc_consensus_pow::start_mining_worker(
+				Box::new(pow_block_import),
+				client.clone(),
+				select_chain,
+				MultiPow::new(client, fork_config),
+				proposer,
+				sync_service.clone(),
+				sync_service,
+				// Note the mining algorithm in the pre-runtime digest.
+				// This allows us to know which algo it was in the runtime.
+				// TODO This also makes it possible to remove the algo info from
+				// the seal.
+				Some(PreDigest::from((sr25519_public_key.into(), mining_algo)).encode()),
+				// This code is copied from above. Would be better to not repeat it.
+				move |_, ()| async move {
+					let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
+					// set default `author` following miner specified in CLI
+					let author = academy_pow_runtime::block_author::InherentDataProvider(
+						sr25519_public_key.encode(),
+					);
 
-                    Ok((timestamp, author))
-                },
-                std::time::Duration::from_secs(10),
-                std::time::Duration::from_secs(5),
-            );
+					Ok((timestamp, author))
+				},
+				std::time::Duration::from_secs(10),
+				std::time::Duration::from_secs(5),
+			);
 
-            task_manager.spawn_essential_handle().spawn_blocking(
-                "pow-miner",
-                Some("pow-mining"),
-                mining_worker_task,
-            );
+			task_manager.spawn_essential_handle().spawn_blocking(
+				"pow-miner",
+				Some("pow-mining"),
+				mining_worker_task,
+			);
 
-            // Start Mining worker.
-            //TODO Some of this should move into the multi_pow crate.
-            use multi_pow::{multi_hash_meets_difficulty, Compute};
-            use sp_core::U256;
-            let mut nonce: U256 = U256::from(0);
-            std::thread::spawn(move || loop {
-                let worker = mining_worker.clone();
-                let metadata = worker.metadata();
-                if let Some(metadata) = metadata {
-                    let compute = Compute {
-                        difficulty: metadata.difficulty,
-                        pre_hash: metadata.pre_hash,
-                        nonce,
-                    };
-                    let seal = compute.compute(mining_algo);
-                    if multi_hash_meets_difficulty(&seal.work, seal.difficulty) {
-                        nonce = U256::from(0);
-                        let _ = futures::executor::block_on(worker.submit(seal.encode()));
-                    } else {
-                        nonce = nonce.saturating_add(U256::from(1));
-                        if nonce == U256::MAX {
-                            nonce = U256::from(0);
-                        }
-                    }
-                } else {
-                    std::thread::sleep(std::time::Duration::from_secs(1));
-                }
-            });
-        }
-    }
+			// Start Mining worker.
+			//TODO Some of this should move into the multi_pow crate.
+			use multi_pow::{multi_hash_meets_difficulty, Compute};
+			use sp_core::U256;
+			let mut nonce: U256 = U256::from(0);
+			std::thread::spawn(move || loop {
+				let worker = mining_worker.clone();
+				let metadata = worker.metadata();
+				if let Some(metadata) = metadata {
+					let compute = Compute {
+						difficulty: metadata.difficulty,
+						pre_hash: metadata.pre_hash,
+						nonce,
+					};
+					let seal = compute.compute(mining_algo);
+					if multi_hash_meets_difficulty(&seal.work, seal.difficulty) {
+						nonce = U256::from(0);
+						let _ = futures::executor::block_on(worker.submit(seal.encode()));
+					} else {
+						nonce = nonce.saturating_add(U256::from(1));
+						if nonce == U256::MAX {
+							nonce = U256::from(0);
+						}
+					}
+				} else {
+					std::thread::sleep(std::time::Duration::from_secs(1));
+				}
+			});
+		}
+	}
 
-    network_starter.start_network();
-    Ok(task_manager)
+	network_starter.start_network();
+	Ok(task_manager)
 }
diff --git a/runtime/build.rs b/runtime/build.rs
index 6db3d90..9029164 100644
--- a/runtime/build.rs
+++ b/runtime/build.rs
@@ -1,8 +1,8 @@
 fn main() {
-    #[cfg(feature = "std")]
-    substrate_wasm_builder::WasmBuilder::new()
-        .with_current_project()
-        .export_heap_base()
-        .import_memory()
-        .build()
+	#[cfg(feature = "std")]
+	substrate_wasm_builder::WasmBuilder::new()
+		.with_current_project()
+		.export_heap_base()
+		.import_memory()
+		.build()
 }
diff --git a/runtime/src/block_author.rs b/runtime/src/block_author.rs
index b147eeb..156e630 100644
--- a/runtime/src/block_author.rs
+++ b/runtime/src/block_author.rs
@@ -14,142 +14,142 @@ use sp_std::vec::Vec;
 
 #[frame_support::pallet(dev_mode)]
 pub mod pallet {
-    use frame_support::pallet_prelude::*;
-    use frame_system::pallet_prelude::*;
-
-    use super::*;
-
-    /// The BlockAuthor Inherent pallet.
-    #[pallet::pallet]
-    pub struct Pallet<T>(PhantomData<T>);
-    /// The pallet's configuration trait. Nothing to configure.
-    #[pallet::config]
-    pub trait Config: frame_system::Config {
-        fn on_author_set(_author_account: Self::AccountId) {}
-    }
-
-    #[pallet::error]
-    pub enum Error<T> {
-        /// Author already set in block.
-        AuthorAlreadySet,
-    }
-
-    /// Author of current block.
-    #[pallet::storage]
-    pub type Author<T: Config> = StorageValue<_, sr25519::Public, OptionQuery>;
-
-    #[pallet::call]
-    impl<T: Config> Pallet<T>
-    where
-        <T as frame_system::Config>::AccountId: From<sp_core::sr25519::Public>,
-    {
-        /// Inherent to set the author of a block
-        #[pallet::weight(1_000_000)]
-        pub fn set_author(origin: OriginFor<T>, author: sr25519::Public) -> DispatchResult {
-            ensure_none(origin)?;
-            ensure!(Author::<T>::get().is_none(), Error::<T>::AuthorAlreadySet);
-
-            // Store the author in case other pallets want to fetch it and to let
-            // offchain tools inspect it
-            Author::<T>::put(author);
-
-            // Call the hook
-            T::on_author_set(author.into());
-
-            Ok(())
-        }
-    }
-
-    #[pallet::hooks]
-    impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
-        fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
-            // Reset the author to None at the beginning of the block
-            Author::<T>::kill();
-
-            // Return zero weight because we are not using weight-based
-            // transaction fees.
-            Weight::zero()
-        }
-    }
-
-    #[pallet::inherent]
-    impl<T: Config> ProvideInherent for Pallet<T>
-    where
-        <T as frame_system::Config>::AccountId: From<sp_core::sr25519::Public>,
-    {
-        type Call = Call<T>;
-        type Error = InherentError;
-        const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
-
-        fn is_inherent_required(_: &InherentData) -> Result<Option<Self::Error>, Self::Error> {
-            // Return Ok(Some(_)) unconditionally because this inherent is required in every block
-            // If it is not found, throw an AuthorInherentRequired error.
-            Ok(Some(InherentError::Other(
-                sp_runtime::RuntimeString::Borrowed("BlockAuthorInherentRequired"),
-            )))
-        }
-
-        fn create_inherent(data: &InherentData) -> Option<Self::Call> {
-            // Grab the Vec<u8> labelled with "author_" from the map of all inherent data
-            let author_raw = data
-                .get_data::<InherentType>(&INHERENT_IDENTIFIER)
-                .expect("Gets and decodes authorship inherent data")?;
-
-            // Decode the Vec<u8> into an actual author
-            let author = sr25519::Public::decode(&mut &author_raw[..])
-                .expect("Decodes author raw inherent data");
-
-            Some(Call::set_author { author })
-        }
-
-        fn is_inherent(call: &Self::Call) -> bool {
-            matches!(call, Call::set_author { .. })
-        }
-    }
+	use frame_support::pallet_prelude::*;
+	use frame_system::pallet_prelude::*;
+
+	use super::*;
+
+	/// The BlockAuthor Inherent pallet.
+	#[pallet::pallet]
+	pub struct Pallet<T>(PhantomData<T>);
+	/// The pallet's configuration trait. Nothing to configure.
+	#[pallet::config]
+	pub trait Config: frame_system::Config {
+		fn on_author_set(_author_account: Self::AccountId) {}
+	}
+
+	#[pallet::error]
+	pub enum Error<T> {
+		/// Author already set in block.
+		AuthorAlreadySet,
+	}
+
+	/// Author of current block.
+	#[pallet::storage]
+	pub type Author<T: Config> = StorageValue<_, sr25519::Public, OptionQuery>;
+
+	#[pallet::call]
+	impl<T: Config> Pallet<T>
+	where
+		<T as frame_system::Config>::AccountId: From<sp_core::sr25519::Public>,
+	{
+		/// Inherent to set the author of a block
+		#[pallet::weight(1_000_000)]
+		pub fn set_author(origin: OriginFor<T>, author: sr25519::Public) -> DispatchResult {
+			ensure_none(origin)?;
+			ensure!(Author::<T>::get().is_none(), Error::<T>::AuthorAlreadySet);
+
+			// Store the author in case other pallets want to fetch it and to let
+			// offchain tools inspect it
+			Author::<T>::put(author);
+
+			// Call the hook
+			T::on_author_set(author.into());
+
+			Ok(())
+		}
+	}
+
+	#[pallet::hooks]
+	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
+		fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
+			// Reset the author to None at the beginning of the block
+			Author::<T>::kill();
+
+			// Return zero weight because we are not using weight-based
+			// transaction fees.
+			Weight::zero()
+		}
+	}
+
+	#[pallet::inherent]
+	impl<T: Config> ProvideInherent for Pallet<T>
+	where
+		<T as frame_system::Config>::AccountId: From<sp_core::sr25519::Public>,
+	{
+		type Call = Call<T>;
+		type Error = InherentError;
+		const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
+
+		fn is_inherent_required(_: &InherentData) -> Result<Option<Self::Error>, Self::Error> {
+			// Return Ok(Some(_)) unconditionally because this inherent is required in every block
+			// If it is not found, throw an AuthorInherentRequired error.
+			Ok(Some(InherentError::Other(sp_runtime::RuntimeString::Borrowed(
+				"BlockAuthorInherentRequired",
+			))))
+		}
+
+		fn create_inherent(data: &InherentData) -> Option<Self::Call> {
+			// Grab the Vec<u8> labelled with "author_" from the map of all inherent data
+			let author_raw = data
+				.get_data::<InherentType>(&INHERENT_IDENTIFIER)
+				.expect("Gets and decodes authorship inherent data")?;
+
+			// Decode the Vec<u8> into an actual author
+			let author = sr25519::Public::decode(&mut &author_raw[..])
+				.expect("Decodes author raw inherent data");
+
+			Some(Call::set_author { author })
+		}
+
+		fn is_inherent(call: &Self::Call) -> bool {
+			matches!(call, Call::set_author { .. })
+		}
+	}
 }
 
 /// A trait to find the author (miner) of the block.
 pub trait BlockAuthor {
-    fn block_author() -> Option<sr25519::Public>;
+	fn block_author() -> Option<sr25519::Public>;
 }
 
 impl BlockAuthor for () {
-    fn block_author() -> Option<sr25519::Public> {
-        None
-    }
+	fn block_author() -> Option<sr25519::Public> {
+		None
+	}
 }
 
 impl<T: Config> BlockAuthor for Pallet<T> {
-    fn block_author() -> Option<sr25519::Public> {
-        Author::<T>::get()
-    }
+	fn block_author() -> Option<sr25519::Public> {
+		Author::<T>::get()
+	}
 }
 
 pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"author__";
 
 #[derive(Encode, Decode, Debug)]
 pub enum InherentError {
-    Other(RuntimeString),
+	Other(RuntimeString),
 }
 
 impl IsFatalError for InherentError {
-    fn is_fatal_error(&self) -> bool {
-        match *self {
-            InherentError::Other(_) => true,
-        }
-    }
+	fn is_fatal_error(&self) -> bool {
+		match *self {
+			InherentError::Other(_) => true,
+		}
+	}
 }
 
 impl InherentError {
-    /// Try to create an instance ouf of the given identifier and data.
-    #[cfg(feature = "std")]
-    pub fn try_from(id: &InherentIdentifier, data: &[u8]) -> Option<Self> {
-        if id == &INHERENT_IDENTIFIER {
-            <InherentError as parity_scale_codec::Decode>::decode(&mut &data[..]).ok()
-        } else {
-            None
-        }
-    }
+	/// Try to create an instance ouf of the given identifier and data.
+	#[cfg(feature = "std")]
+	pub fn try_from(id: &InherentIdentifier, data: &[u8]) -> Option<Self> {
+		if id == &INHERENT_IDENTIFIER {
+			<InherentError as parity_scale_codec::Decode>::decode(&mut &data[..]).ok()
+		} else {
+			None
+		}
+	}
 }
 
 /// The type of data that the inherent will contain.
@@ -162,26 +162,26 @@ pub struct InherentDataProvider(pub InherentType);
 #[cfg(feature = "std")]
 #[async_trait::async_trait]
 impl sp_inherents::InherentDataProvider for InherentDataProvider {
-    async fn provide_inherent_data(
-        &self,
-        inherent_data: &mut InherentData,
-    ) -> Result<(), sp_inherents::Error> {
-        inherent_data.put_data(INHERENT_IDENTIFIER, &self.0)
-    }
-
-    async fn try_handle_error(
-        &self,
-        identifier: &InherentIdentifier,
-        _error: &[u8],
-    ) -> Option<Result<(), sp_inherents::Error>> {
-        // Dont' process modules from other inherents
-        if *identifier != INHERENT_IDENTIFIER {
-            return None;
-        }
-
-        // All errors with the author inehrent are fatal
-        Some(Err(sp_inherents::Error::Application(Box::from(
-            String::from("Error processing author inherent"),
-        ))))
-    }
+	async fn provide_inherent_data(
+		&self,
+		inherent_data: &mut InherentData,
+	) -> Result<(), sp_inherents::Error> {
+		inherent_data.put_data(INHERENT_IDENTIFIER, &self.0)
+	}
+
+	async fn try_handle_error(
+		&self,
+		identifier: &InherentIdentifier,
+		_error: &[u8],
+	) -> Option<Result<(), sp_inherents::Error>> {
+		// Dont' process modules from other inherents
+		if *identifier != INHERENT_IDENTIFIER {
+			return None;
+		}
+
+		// All errors with the author inehrent are fatal
+		Some(Err(sp_inherents::Error::Application(Box::from(String::from(
+			"Error processing author inherent",
+		)))))
+	}
 }
diff --git a/runtime/src/difficulty.rs b/runtime/src/difficulty.rs
index babfeab..650d77a 100644
--- a/runtime/src/difficulty.rs
+++ b/runtime/src/difficulty.rs
@@ -15,18 +15,18 @@ use sp_runtime::traits::UniqueSaturatedInto;
 
 #[derive(Encode, Decode, Clone, Copy, Eq, PartialEq, Debug, MaxEncodedLen, TypeInfo)]
 pub struct DifficultyAndTimestamp<M> {
-    pub difficulty: Difficulty,
-    pub timestamp: M,
+	pub difficulty: Difficulty,
+	pub timestamp: M,
 }
 
 /// Move value linearly toward a goal
 pub fn damp(actual: u128, goal: u128, damp_factor: u128) -> u128 {
-    (actual + (damp_factor - 1) * goal) / damp_factor
+	(actual + (damp_factor - 1) * goal) / damp_factor
 }
 
 /// Limit value to be within some factor from a goal
 pub fn clamp(actual: u128, goal: u128, clamp_factor: u128) -> u128 {
-    max(goal / clamp_factor, min(actual, goal * clamp_factor))
+	max(goal / clamp_factor, min(actual, goal * clamp_factor))
 }
 
 const DIFFICULTY_ADJUST_WINDOW: u128 = 60;
@@ -36,168 +36,166 @@ pub use pallet::*;
 
 #[frame_support::pallet(dev_mode)]
 pub mod pallet {
-    use frame_support::pallet_prelude::*;
-    use frame_system::pallet_prelude::*;
-
-    use super::*;
-
-    /// Pallet's configuration trait.
-    #[pallet::config]
-    pub trait Config<I: 'static = ()>: frame_system::Config {
-        /// A Source for timestamp data
-        type TimeProvider: Time;
-        /// The block time that the DAA will attempt to maintain
-        type TargetBlockTime: Get<u128>;
-        /// Dampening factor to use for difficulty adjustment
-        type DampFactor: Get<u128>;
-        /// Clamp factor to use for difficulty adjustment
-        /// Limit value to within this factor of goal. Recommended value: 2
-        type ClampFactor: Get<u128>;
-        /// The maximum difficulty allowed. Recommended to use u128::max_value()
-        type MaxDifficulty: Get<u128>;
-        /// Minimum difficulty, enforced in difficulty retargetting
-        /// avoids getting stuck when trying to increase difficulty subject to dampening
-        /// Recommended to use same value as DampFactor
-        type MinDifficulty: Get<u128>;
-
-        /// Now that the pallet is instantiable, we need a way to decide which blocks are
-        /// relevant to this instance. This function does just that.
-        ///
-        /// The default implementation assumes that all blocks are relevant which is what
-        /// you probably want when there is only a single instance.
-        fn relevant_to_this_instance() -> bool {
-            true
-        }
-    }
-
-    #[pallet::pallet]
-    pub struct Pallet<T, I = ()>(_);
-
-    type DifficultyList<T, I> =
-        [Option<DifficultyAndTimestamp<<<T as Config<I>>::TimeProvider as Time>::Moment>>; 60];
-
-    /// Past difficulties and timestamps, from earliest to latest.
-    #[pallet::storage]
-    pub type PastDifficultiesAndTimestamps<T: Config<I>, I: 'static = ()> =
-        StorageValue<_, DifficultyList<T, I>, ValueQuery, EmptyList<T, I>>;
-
-    pub struct EmptyList<T: Config<I>, I: 'static = ()>(PhantomData<(T, I)>);
-    impl<T: Config<I>, I> Get<DifficultyList<T, I>> for EmptyList<T, I> {
-        fn get() -> DifficultyList<T, I> {
-            [None; DIFFICULTY_ADJUST_WINDOW as usize]
-        }
-    }
-
-    /// Current difficulty.
-    #[pallet::storage]
-    #[pallet::getter(fn difficulty)]
-    pub type CurrentDifficulty<T: Config<I>, I: 'static = ()> =
-        StorageValue<_, Difficulty, ValueQuery>;
-
-    /// Initial difficulty.
-    #[pallet::storage]
-    pub type InitialDifficulty<T: Config<I>, I: 'static = ()> =
-        StorageValue<_, Difficulty, ValueQuery>;
-
-    #[pallet::genesis_config]
-    pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
-        pub _ph_data: Option<PhantomData<(T, I)>>,
-        pub initial_difficulty: [u8; 32], // Difficulty = U256
-    }
-
-    #[pallet::genesis_build]
-    impl<T: Config<I>, I: 'static> BuildGenesisConfig for GenesisConfig<T, I> {
-        fn build(&self) {
-            let initial_difficulty = U256::from_little_endian(&self.initial_difficulty);
-            // Initialize the Current difficulty
-            CurrentDifficulty::<T, I>::put(&initial_difficulty);
-
-            // Store the initial difficulty in storage because we will need it
-            // during the first DIFFICULTY_ADJUSTMENT_WINDOW blocks (see todo below).
-            InitialDifficulty::<T, I>::put(&initial_difficulty);
-        }
-    }
-
-    impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
-        fn default() -> Self {
-            GenesisConfig {
-                _ph_data: Default::default(),
-                initial_difficulty: [0u8; 32],
-            }
-        }
-    }
-
-    #[pallet::hooks]
-    impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
-        fn on_finalize(_n: BlockNumberFor<T>) {
-            // First check if this is block is relevant to this instance of the difficulty adjustment algorithm
-            if !T::relevant_to_this_instance() {
-                return;
-            }
-
-            let mut data = PastDifficultiesAndTimestamps::<T, I>::get();
-
-            for i in 1..data.len() {
-                data[i - 1] = data[i];
-            }
-
-            data[data.len() - 1] = Some(DifficultyAndTimestamp {
-                timestamp: T::TimeProvider::now(),
-                difficulty: Self::difficulty(),
-            });
-
-            let mut ts_delta = 0;
-            for i in 1..(DIFFICULTY_ADJUST_WINDOW as usize) {
-                let prev: Option<u128> = data[i - 1].map(|d| d.timestamp.unique_saturated_into());
-                let cur: Option<u128> = data[i].map(|d| d.timestamp.unique_saturated_into());
-
-                let delta = match (prev, cur) {
-                    (Some(prev), Some(cur)) => cur.saturating_sub(prev),
-                    _ => T::TargetBlockTime::get(),
-                };
-                ts_delta += delta;
-            }
-
-            if ts_delta == 0 {
-                ts_delta = 1;
-            }
-
-            let mut diff_sum = U256::zero();
-            //TODO Could we just initialize every array cell to the initial difficulty to not need the
-            // separate storage item?
-            for item in data.iter().take(DIFFICULTY_ADJUST_WINDOW as usize) {
-                let diff = match item.map(|d| d.difficulty) {
-                    Some(diff) => diff,
-                    None => InitialDifficulty::<T, I>::get(),
-                };
-                diff_sum += diff;
-            }
-
-            if diff_sum < U256::from(T::MinDifficulty::get()) {
-                diff_sum = U256::from(T::MinDifficulty::get());
-            }
-
-            // Calculate the average length of the adjustment window
-            let adjustment_window = DIFFICULTY_ADJUST_WINDOW * T::TargetBlockTime::get();
-
-            // adjust time delta toward goal subject to dampening and clamping
-            let adj_ts = clamp(
-                damp(ts_delta, adjustment_window, T::DampFactor::get()),
-                adjustment_window,
-                T::ClampFactor::get(),
-            );
-
-            // minimum difficulty avoids getting stuck due to dampening
-            let difficulty = min(
-                U256::from(T::MaxDifficulty::get()),
-                max(
-                    U256::from(T::MinDifficulty::get()),
-                    diff_sum * U256::from(T::TargetBlockTime::get()) / U256::from(adj_ts),
-                ),
-            );
-
-            <PastDifficultiesAndTimestamps<T, I>>::put(data);
-            <CurrentDifficulty<T, I>>::put(difficulty);
-        }
-    }
+	use frame_support::pallet_prelude::*;
+	use frame_system::pallet_prelude::*;
+
+	use super::*;
+
+	/// Pallet's configuration trait.
+	#[pallet::config]
+	pub trait Config<I: 'static = ()>: frame_system::Config {
+		/// A Source for timestamp data
+		type TimeProvider: Time;
+		/// The block time that the DAA will attempt to maintain
+		type TargetBlockTime: Get<u128>;
+		/// Dampening factor to use for difficulty adjustment
+		type DampFactor: Get<u128>;
+		/// Clamp factor to use for difficulty adjustment
+		/// Limit value to within this factor of goal. Recommended value: 2
+		type ClampFactor: Get<u128>;
+		/// The maximum difficulty allowed. Recommended to use u128::max_value()
+		type MaxDifficulty: Get<u128>;
+		/// Minimum difficulty, enforced in difficulty retargetting
+		/// avoids getting stuck when trying to increase difficulty subject to dampening
+		/// Recommended to use same value as DampFactor
+		type MinDifficulty: Get<u128>;
+
+		/// Now that the pallet is instantiable, we need a way to decide which blocks are
+		/// relevant to this instance. This function does just that.
+		///
+		/// The default implementation assumes that all blocks are relevant which is what
+		/// you probably want when there is only a single instance.
+		fn relevant_to_this_instance() -> bool {
+			true
+		}
+	}
+
+	#[pallet::pallet]
+	pub struct Pallet<T, I = ()>(_);
+
+	type DifficultyList<T, I> =
+		[Option<DifficultyAndTimestamp<<<T as Config<I>>::TimeProvider as Time>::Moment>>; 60];
+
+	/// Past difficulties and timestamps, from earliest to latest.
+	#[pallet::storage]
+	pub type PastDifficultiesAndTimestamps<T: Config<I>, I: 'static = ()> =
+		StorageValue<_, DifficultyList<T, I>, ValueQuery, EmptyList<T, I>>;
+
+	pub struct EmptyList<T: Config<I>, I: 'static = ()>(PhantomData<(T, I)>);
+	impl<T: Config<I>, I> Get<DifficultyList<T, I>> for EmptyList<T, I> {
+		fn get() -> DifficultyList<T, I> {
+			[None; DIFFICULTY_ADJUST_WINDOW as usize]
+		}
+	}
+
+	/// Current difficulty.
+	#[pallet::storage]
+	#[pallet::getter(fn difficulty)]
+	pub type CurrentDifficulty<T: Config<I>, I: 'static = ()> =
+		StorageValue<_, Difficulty, ValueQuery>;
+
+	/// Initial difficulty.
+	#[pallet::storage]
+	pub type InitialDifficulty<T: Config<I>, I: 'static = ()> =
+		StorageValue<_, Difficulty, ValueQuery>;
+
+	#[pallet::genesis_config]
+	pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
+		pub _ph_data: Option<PhantomData<(T, I)>>,
+		pub initial_difficulty: [u8; 32], // Difficulty = U256
+	}
+
+	#[pallet::genesis_build]
+	impl<T: Config<I>, I: 'static> BuildGenesisConfig for GenesisConfig<T, I> {
+		fn build(&self) {
+			let initial_difficulty = U256::from_little_endian(&self.initial_difficulty);
+			// Initialize the Current difficulty
+			CurrentDifficulty::<T, I>::put(&initial_difficulty);
+
+			// Store the initial difficulty in storage because we will need it
+			// during the first DIFFICULTY_ADJUSTMENT_WINDOW blocks (see todo below).
+			InitialDifficulty::<T, I>::put(&initial_difficulty);
+		}
+	}
+
+	impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
+		fn default() -> Self {
+			GenesisConfig { _ph_data: Default::default(), initial_difficulty: [0u8; 32] }
+		}
+	}
+
+	#[pallet::hooks]
+	impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
+		fn on_finalize(_n: BlockNumberFor<T>) {
+			// First check if this is block is relevant to this instance of the difficulty
+			// adjustment algorithm
+			if !T::relevant_to_this_instance() {
+				return;
+			}
+
+			let mut data = PastDifficultiesAndTimestamps::<T, I>::get();
+
+			for i in 1..data.len() {
+				data[i - 1] = data[i];
+			}
+
+			data[data.len() - 1] = Some(DifficultyAndTimestamp {
+				timestamp: T::TimeProvider::now(),
+				difficulty: Self::difficulty(),
+			});
+
+			let mut ts_delta = 0;
+			for i in 1..(DIFFICULTY_ADJUST_WINDOW as usize) {
+				let prev: Option<u128> = data[i - 1].map(|d| d.timestamp.unique_saturated_into());
+				let cur: Option<u128> = data[i].map(|d| d.timestamp.unique_saturated_into());
+
+				let delta = match (prev, cur) {
+					(Some(prev), Some(cur)) => cur.saturating_sub(prev),
+					_ => T::TargetBlockTime::get(),
+				};
+				ts_delta += delta;
+			}
+
+			if ts_delta == 0 {
+				ts_delta = 1;
+			}
+
+			let mut diff_sum = U256::zero();
+			//TODO Could we just initialize every array cell to the initial difficulty to not need
+			// the separate storage item?
+			for item in data.iter().take(DIFFICULTY_ADJUST_WINDOW as usize) {
+				let diff = match item.map(|d| d.difficulty) {
+					Some(diff) => diff,
+					None => InitialDifficulty::<T, I>::get(),
+				};
+				diff_sum += diff;
+			}
+
+			if diff_sum < U256::from(T::MinDifficulty::get()) {
+				diff_sum = U256::from(T::MinDifficulty::get());
+			}
+
+			// Calculate the average length of the adjustment window
+			let adjustment_window = DIFFICULTY_ADJUST_WINDOW * T::TargetBlockTime::get();
+
+			// adjust time delta toward goal subject to dampening and clamping
+			let adj_ts = clamp(
+				damp(ts_delta, adjustment_window, T::DampFactor::get()),
+				adjustment_window,
+				T::ClampFactor::get(),
+			);
+
+			// minimum difficulty avoids getting stuck due to dampening
+			let difficulty = min(
+				U256::from(T::MaxDifficulty::get()),
+				max(
+					U256::from(T::MinDifficulty::get()),
+					diff_sum * U256::from(T::TargetBlockTime::get()) / U256::from(adj_ts),
+				),
+			);
+
+			<PastDifficultiesAndTimestamps<T, I>>::put(data);
+			<CurrentDifficulty<T, I>>::put(difficulty);
+		}
+	}
 }
diff --git a/runtime/src/issuance.rs b/runtime/src/issuance.rs
index 9a11f9d..a8146c1 100644
--- a/runtime/src/issuance.rs
+++ b/runtime/src/issuance.rs
@@ -3,26 +3,28 @@
 /// A trait for types that can provide the amount of issuance to award to the block
 /// author for the given block number.
 pub trait Issuance<BlockNumber, Balance> {
-    fn issuance(block: BlockNumber) -> Balance;
+	fn issuance(block: BlockNumber) -> Balance;
 }
 
 // Minimal implementations for when you don't actually want any issuance
 impl Issuance<u32, u128> for () {
-    fn issuance(_block: u32) -> u128 {
-        0
-    }
+	fn issuance(_block: u32) -> u128 {
+		0
+	}
 }
 
 impl Issuance<u64, u128> for () {
-    fn issuance(_block: u64) -> u128 {
-        0
-    }
+	fn issuance(_block: u64) -> u128 {
+		0
+	}
 }
 
 /// A type that provides block issuance according to bitcoin's rules
 /// Initial issuance is 50 / block
 /// Issuance is cut in half every 210,000 blocks
-/// cribbed from github.com/Bitcoin-ABC/bitcoin-abc/blob/9c7b12e6f128a59423f4de3d6d4b5231ebe9aac2/src/validation.cpp#L1007
+/// cribbed from
+/// github.com/Bitcoin-ABC/bitcoin-abc/blob/9c7b12e6f128a59423f4de3d6d4b5231ebe9aac2/src/validation.
+/// cpp#L1007
 
 pub struct BitcoinHalving;
 
@@ -32,16 +34,16 @@ const HALVING_INTERVAL: u32 = 210_000;
 const INITIAL_ISSUANCE: u32 = 50;
 
 impl Issuance<u32, u128> for BitcoinHalving {
-    fn issuance(block: u32) -> u128 {
-        let halving = block / HALVING_INTERVAL;
-        // Force block reward to zero when right shift is undefined.
-        if halving >= 64 {
-            return 0;
-        }
-
-        // Approximately, 600 seconds (or 10 minutes) for a block to be finalized.
-        // Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
-        // Divided by 2 using bitwise
-        (INITIAL_ISSUANCE >> halving).into()
-    }
+	fn issuance(block: u32) -> u128 {
+		let halving = block / HALVING_INTERVAL;
+		// Force block reward to zero when right shift is undefined.
+		if halving >= 64 {
+			return 0;
+		}
+
+		// Approximately, 600 seconds (or 10 minutes) for a block to be finalized.
+		// Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
+		// Divided by 2 using bitwise
+		(INITIAL_ISSUANCE >> halving).into()
+	}
 }
diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs
index 5b09407..b724b7e 100644
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -9,24 +9,24 @@
 include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
 
 pub use frame_support::{
-    construct_runtime, parameter_types, derive_impl,
-    traits::{
-        Currency, EstimateNextNewSession, Imbalance, IsSubType, KeyOwnerProofSystem,
-        LockIdentifier, Nothing, OnUnbalanced, ValidatorSet, VariantCountOf,
-    },
-    weights::{
-        constants::{
-            BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND,
-        },
-        IdentityFee, Weight,
-    },
-    Callable, StorageValue,
+	construct_runtime, derive_impl, parameter_types,
+	traits::{
+		Currency, EstimateNextNewSession, Imbalance, IsSubType, KeyOwnerProofSystem,
+		LockIdentifier, Nothing, OnUnbalanced, ValidatorSet, VariantCountOf,
+	},
+	weights::{
+		constants::{
+			BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND,
+		},
+		IdentityFee, Weight,
+	},
+	Callable, StorageValue,
 };
 use frame_support::{
-    genesis_builder_helper::{build_state, get_preset},
-    instances::{Instance1, Instance2, Instance3},
-    sp_runtime::Perquintill,
-    traits::{ConstU128, ConstU32, ConstU8},
+	genesis_builder_helper::{build_state, get_preset},
+	instances::{Instance1, Instance2, Instance3},
+	sp_runtime::Perquintill,
+	traits::{ConstU128, ConstU32, ConstU8},
 };
 use multi_pow::SupportedHashes;
 pub use pallet_balances::Call as BalancesCall;
@@ -40,15 +40,14 @@ use sp_core::OpaqueMetadata;
 #[cfg(any(feature = "std", test))]
 pub use sp_runtime::BuildStorage;
 use sp_runtime::{
-    create_runtime_str, generic,
-    traits::{
-        AccountIdLookup, BlakeTwo256, Block as BlockT, Bounded, IdentifyAccount, One, Verify,
-    },
-    transaction_validity::{
-        InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
-    },
-    ApplyExtrinsicResult, DigestItem, MultiSignature,
-    ExtrinsicInclusionMode,
+	create_runtime_str, generic,
+	traits::{
+		AccountIdLookup, BlakeTwo256, Block as BlockT, Bounded, IdentifyAccount, One, Verify,
+	},
+	transaction_validity::{
+		InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
+	},
+	ApplyExtrinsicResult, DigestItem, ExtrinsicInclusionMode, MultiSignature,
 };
 pub use sp_runtime::{FixedPointNumber, Perbill, Permill};
 use sp_std::prelude::*;
@@ -101,38 +100,35 @@ pub mod utxo;
 /// of data like extrinsics, allowing for them to continue syncing the network through upgrades
 /// to even the core data structures.
 pub mod opaque {
-    pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
+	pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
 
-    use super::*;
+	use super::*;
 
-    /// Opaque block header type.
-    pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
-    /// Opaque block type.
-    pub type Block = generic::Block<Header, UncheckedExtrinsic>;
-    /// Opaque block identifier type.
-    pub type BlockId = generic::BlockId<Block>;
+	/// Opaque block header type.
+	pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
+	/// Opaque block type.
+	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+	/// Opaque block identifier type.
+	pub type BlockId = generic::BlockId<Block>;
 }
 
 /// This runtime version.
 #[sp_version::runtime_version]
 pub const VERSION: RuntimeVersion = RuntimeVersion {
-    spec_name: create_runtime_str!("academy-pow"),
-    impl_name: create_runtime_str!("academy-pow"),
-    authoring_version: 1,
-    spec_version: 1,
-    impl_version: 1,
-    apis: RUNTIME_API_VERSIONS,
-    transaction_version: 1,
-    state_version: 1,
+	spec_name: create_runtime_str!("academy-pow"),
+	impl_name: create_runtime_str!("academy-pow"),
+	authoring_version: 1,
+	spec_version: 1,
+	impl_version: 1,
+	apis: RUNTIME_API_VERSIONS,
+	transaction_version: 1,
+	state_version: 1,
 };
 
 /// The version information used to identify this runtime when compiled natively.
 #[cfg(feature = "std")]
 pub fn native_version() -> NativeVersion {
-    NativeVersion {
-        runtime_version: VERSION,
-        can_author_with: Default::default(),
-    }
+	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
 }
 
 const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
@@ -142,205 +138,204 @@ pub const TOKEN_DECIMALS: u32 = 12;
 pub const TOKEN: u128 = 10u128.pow(TOKEN_DECIMALS);
 
 parameter_types! {
-    pub const BlockHashCount: BlockNumber = 2400;
-    pub const Version: RuntimeVersion = VERSION;
-    /// We allow for 2 seconds of compute with a 6 second average block time.
-    pub BlockWeights: frame_system::limits::BlockWeights =
-        frame_system::limits::BlockWeights::with_sensible_defaults(
-            Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX),
-            NORMAL_DISPATCH_RATIO,
-        );
-    pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
-        ::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
-    pub const SS58Prefix: u8 = 42;
+	pub const BlockHashCount: BlockNumber = 2400;
+	pub const Version: RuntimeVersion = VERSION;
+	/// We allow for 2 seconds of compute with a 6 second average block time.
+	pub BlockWeights: frame_system::limits::BlockWeights =
+		frame_system::limits::BlockWeights::with_sensible_defaults(
+			Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX),
+			NORMAL_DISPATCH_RATIO,
+		);
+	pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
+		::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
+	pub const SS58Prefix: u8 = 42;
 }
 
 #[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
 impl frame_system::Config for Runtime {
-    /// The basic call filter to use in dispatchable.
-    type BaseCallFilter = frame_support::traits::Everything;
-    /// Block & extrinsics weights: base values and limits.
-    type BlockWeights = BlockWeights;
-    /// The maximum length of a block (in bytes).
-    type BlockLength = BlockLength;
-    /// The identifier used to distinguish between accounts.
-    type AccountId = AccountId;
-    /// The aggregated dispatch type that is available for extrinsics.
-    type RuntimeCall = RuntimeCall;
-    /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
-    type Lookup = AccountIdLookup<AccountId, ()>;
-    /// The type for hashing blocks and tries.
-    type Hash = Hash;
-    /// The hashing algorithm used.
-    type Hashing = BlakeTwo256;
-    /// The ubiquitous event type.
-    type RuntimeEvent = RuntimeEvent;
-    /// The ubiquitous origin type.
-    type RuntimeOrigin = RuntimeOrigin;
-    /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
-    type BlockHashCount = BlockHashCount;
-    /// The weight of database operations that the runtime can invoke.
-    type DbWeight = RocksDbWeight;
-    /// Version of the runtime.
-    type Version = Version;
-    /// This type is being generated by the construct runtime macro.
-    type PalletInfo = PalletInfo;
-    /// What to do if a new account is created.
-    type OnNewAccount = ();
-    /// What to do if an account is fully reaped from the system.
-    type OnKilledAccount = ();
-    /// The data to be stored in an account.
-    type AccountData = pallet_balances::AccountData<Balance>;
-    /// Weight information for the extrinsics of this pallet.
-    type SystemWeightInfo = ();
-    /// This is used as an identifier of the chain. 42 is the generic substrate prefix.
-    type SS58Prefix = SS58Prefix;
-    /// The set code logic, just the default since we're not a parachain.
-    type OnSetCode = ();
-    type MaxConsumers = frame_support::traits::ConstU32<16>;
-    type Nonce = Nonce;
-    type Block = Block;
+	/// The basic call filter to use in dispatchable.
+	type BaseCallFilter = frame_support::traits::Everything;
+	/// Block & extrinsics weights: base values and limits.
+	type BlockWeights = BlockWeights;
+	/// The maximum length of a block (in bytes).
+	type BlockLength = BlockLength;
+	/// The identifier used to distinguish between accounts.
+	type AccountId = AccountId;
+	/// The aggregated dispatch type that is available for extrinsics.
+	type RuntimeCall = RuntimeCall;
+	/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
+	type Lookup = AccountIdLookup<AccountId, ()>;
+	/// The type for hashing blocks and tries.
+	type Hash = Hash;
+	/// The hashing algorithm used.
+	type Hashing = BlakeTwo256;
+	/// The ubiquitous event type.
+	type RuntimeEvent = RuntimeEvent;
+	/// The ubiquitous origin type.
+	type RuntimeOrigin = RuntimeOrigin;
+	/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
+	type BlockHashCount = BlockHashCount;
+	/// The weight of database operations that the runtime can invoke.
+	type DbWeight = RocksDbWeight;
+	/// Version of the runtime.
+	type Version = Version;
+	/// This type is being generated by the construct runtime macro.
+	type PalletInfo = PalletInfo;
+	/// What to do if a new account is created.
+	type OnNewAccount = ();
+	/// What to do if an account is fully reaped from the system.
+	type OnKilledAccount = ();
+	/// The data to be stored in an account.
+	type AccountData = pallet_balances::AccountData<Balance>;
+	/// Weight information for the extrinsics of this pallet.
+	type SystemWeightInfo = ();
+	/// This is used as an identifier of the chain. 42 is the generic substrate prefix.
+	type SS58Prefix = SS58Prefix;
+	/// The set code logic, just the default since we're not a parachain.
+	type OnSetCode = ();
+	type MaxConsumers = frame_support::traits::ConstU32<16>;
+	type Nonce = Nonce;
+	type Block = Block;
 }
 
 parameter_types! {
-    pub const MinimumPeriod: u64 = 1000;
+	pub const MinimumPeriod: u64 = 1000;
 }
 
 impl pallet_timestamp::Config for Runtime {
-    /// A timestamp: milliseconds since the unix epoch.
-    type Moment = u64;
-    type OnTimestampSet = ();
-    type MinimumPeriod = MinimumPeriod;
-    type WeightInfo = ();
+	/// A timestamp: milliseconds since the unix epoch.
+	type Moment = u64;
+	type OnTimestampSet = ();
+	type MinimumPeriod = MinimumPeriod;
+	type WeightInfo = ();
 }
 
 impl pallet_balances::Config for Runtime {
-    type MaxLocks = ConstU32<50>;
-    type MaxReserves = ();
-    type ReserveIdentifier = [u8; 8];
-    /// The type for recording an account's balance.
-    type Balance = Balance;
-    /// The ubiquitous event type.
-    type RuntimeEvent = RuntimeEvent;
-    type DustRemoval = ();
-    type ExistentialDeposit = ConstU128<500>;
-    type AccountStore = System;
-    type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
-    type FreezeIdentifier = RuntimeFreezeReason;
-    type MaxFreezes = VariantCountOf<RuntimeFreezeReason>;
-    type RuntimeHoldReason = RuntimeHoldReason;
-    type RuntimeFreezeReason = RuntimeFreezeReason;
+	type MaxLocks = ConstU32<50>;
+	type MaxReserves = ();
+	type ReserveIdentifier = [u8; 8];
+	/// The type for recording an account's balance.
+	type Balance = Balance;
+	/// The ubiquitous event type.
+	type RuntimeEvent = RuntimeEvent;
+	type DustRemoval = ();
+	type ExistentialDeposit = ConstU128<500>;
+	type AccountStore = System;
+	type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
+	type FreezeIdentifier = RuntimeFreezeReason;
+	type MaxFreezes = VariantCountOf<RuntimeFreezeReason>;
+	type RuntimeHoldReason = RuntimeHoldReason;
+	type RuntimeFreezeReason = RuntimeFreezeReason;
 }
 
 parameter_types! {
-    pub const TargetBlockTime: u128 = 5_000;
-    // Setting min difficulty to damp factor per recommendation
-    pub const DampFactor: u128 = 3;
-    pub const ClampFactor: u128 = 2;
-    pub const MaxDifficulty: u128 = u128::max_value();
+	pub const TargetBlockTime: u128 = 5_000;
+	// Setting min difficulty to damp factor per recommendation
+	pub const DampFactor: u128 = 3;
+	pub const ClampFactor: u128 = 2;
+	pub const MaxDifficulty: u128 = u128::max_value();
 }
 
 // Helper function to get the current blocks PoW algo from the predigest
 fn current_blocks_mining_algo() -> SupportedHashes {
-    System::digest()
-        .logs
-        .iter()
-        .find_map(|digest_item| match digest_item {
-            DigestItem::PreRuntime(POW_ENGINE_ID, pre_digest) => {
-                PreDigest::decode(&mut &pre_digest[..]).map(|d| d.1).ok()
-            }
-            _ => None,
-        })
-        .expect("There should be exactly one pow pre-digest item")
+	System::digest()
+		.logs
+		.iter()
+		.find_map(|digest_item| match digest_item {
+			DigestItem::PreRuntime(POW_ENGINE_ID, pre_digest) =>
+				PreDigest::decode(&mut &pre_digest[..]).map(|d| d.1).ok(),
+			_ => None,
+		})
+		.expect("There should be exactly one pow pre-digest item")
 }
 
 impl difficulty::Config<Instance1> for Runtime {
-    type TimeProvider = Timestamp;
-    type TargetBlockTime = TargetBlockTime;
-    type DampFactor = DampFactor;
-    type ClampFactor = ClampFactor;
-    type MaxDifficulty = MaxDifficulty;
-    type MinDifficulty = DampFactor;
-
-    fn relevant_to_this_instance() -> bool {
-        current_blocks_mining_algo() == SupportedHashes::Md5
-    }
+	type TimeProvider = Timestamp;
+	type TargetBlockTime = TargetBlockTime;
+	type DampFactor = DampFactor;
+	type ClampFactor = ClampFactor;
+	type MaxDifficulty = MaxDifficulty;
+	type MinDifficulty = DampFactor;
+
+	fn relevant_to_this_instance() -> bool {
+		current_blocks_mining_algo() == SupportedHashes::Md5
+	}
 }
 
 impl difficulty::Config<Instance2> for Runtime {
-    type TimeProvider = Timestamp;
-    type TargetBlockTime = TargetBlockTime;
-    type DampFactor = DampFactor;
-    type ClampFactor = ClampFactor;
-    type MaxDifficulty = MaxDifficulty;
-    type MinDifficulty = DampFactor;
-
-    fn relevant_to_this_instance() -> bool {
-        current_blocks_mining_algo() == SupportedHashes::Sha3
-    }
+	type TimeProvider = Timestamp;
+	type TargetBlockTime = TargetBlockTime;
+	type DampFactor = DampFactor;
+	type ClampFactor = ClampFactor;
+	type MaxDifficulty = MaxDifficulty;
+	type MinDifficulty = DampFactor;
+
+	fn relevant_to_this_instance() -> bool {
+		current_blocks_mining_algo() == SupportedHashes::Sha3
+	}
 }
 
 impl difficulty::Config<Instance3> for Runtime {
-    type TimeProvider = Timestamp;
-    type TargetBlockTime = TargetBlockTime;
-    type DampFactor = DampFactor;
-    type ClampFactor = ClampFactor;
-    type MaxDifficulty = MaxDifficulty;
-    type MinDifficulty = DampFactor;
-
-    fn relevant_to_this_instance() -> bool {
-        current_blocks_mining_algo() == SupportedHashes::Keccak
-    }
+	type TimeProvider = Timestamp;
+	type TargetBlockTime = TargetBlockTime;
+	type DampFactor = DampFactor;
+	type ClampFactor = ClampFactor;
+	type MaxDifficulty = MaxDifficulty;
+	type MinDifficulty = DampFactor;
+
+	fn relevant_to_this_instance() -> bool {
+		current_blocks_mining_algo() == SupportedHashes::Keccak
+	}
 }
 
 impl block_author::Config for Runtime {
-    // Each block mined issues 50 new tokens to the miner
-    fn on_author_set(author_account: Self::AccountId) {
-        let issuance = 50 * TOKEN;
-        let _ = Balances::deposit_creating(&author_account, issuance);
-    }
+	// Each block mined issues 50 new tokens to the miner
+	fn on_author_set(author_account: Self::AccountId) {
+		let issuance = 50 * TOKEN;
+		let _ = Balances::deposit_creating(&author_account, issuance);
+	}
 }
 
 parameter_types! {
-    // This value increases the priority of `Operational` transactions by adding
-    // a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
-    // follows polkadot : https://github.com/paritytech/polkadot/blob/9ce5f7ef5abb1a4291454e8c9911b304d80679f9/runtime/polkadot/src/lib.rs#L369
-    pub const OperationalFeeMultiplier: u8 = 5;
-    // We expect that on average 25% of the normal capacity will be occupied with normal txs.
-    pub const TargetSaturationLevel: Perquintill = Perquintill::from_percent(25);
-    // During 20 blocks the fee may not change more than by 100%. This, together with the
-    // `TargetSaturationLevel` value, results in variability ~0.067. For the corresponding
-    // formulas please refer to Substrate code at `frame/transaction-payment/src/lib.rs`.
-    pub FeeVariability: Multiplier = Multiplier::saturating_from_rational(67, 1000);
-    // Fee should never be lower than the computational cost.
-    pub MinimumMultiplier: Multiplier = Multiplier::one();
-    pub MaximumMultiplier: Multiplier = Bounded::max_value();
+	// This value increases the priority of `Operational` transactions by adding
+	// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
+	// follows polkadot : https://github.com/paritytech/polkadot/blob/9ce5f7ef5abb1a4291454e8c9911b304d80679f9/runtime/polkadot/src/lib.rs#L369
+	pub const OperationalFeeMultiplier: u8 = 5;
+	// We expect that on average 25% of the normal capacity will be occupied with normal txs.
+	pub const TargetSaturationLevel: Perquintill = Perquintill::from_percent(25);
+	// During 20 blocks the fee may not change more than by 100%. This, together with the
+	// `TargetSaturationLevel` value, results in variability ~0.067. For the corresponding
+	// formulas please refer to Substrate code at `frame/transaction-payment/src/lib.rs`.
+	pub FeeVariability: Multiplier = Multiplier::saturating_from_rational(67, 1000);
+	// Fee should never be lower than the computational cost.
+	pub MinimumMultiplier: Multiplier = Multiplier::one();
+	pub MaximumMultiplier: Multiplier = Bounded::max_value();
 }
 
 parameter_types! {
-    pub FeeMultiplier: Multiplier = Multiplier::one();
+	pub FeeMultiplier: Multiplier = Multiplier::one();
 }
 
 impl pallet_transaction_payment::Config for Runtime {
-    type RuntimeEvent = RuntimeEvent;
-    type OnChargeTransaction = FungibleAdapter<Balances, ()>;
-    type OperationalFeeMultiplier = ConstU8<5>;
-    type WeightToFee = IdentityFee<Balance>;
-    type LengthToFee = IdentityFee<Balance>;
-    type FeeMultiplierUpdate = ConstFeeMultiplier<FeeMultiplier>;
+	type RuntimeEvent = RuntimeEvent;
+	type OnChargeTransaction = FungibleAdapter<Balances, ()>;
+	type OperationalFeeMultiplier = ConstU8<5>;
+	type WeightToFee = IdentityFee<Balance>;
+	type LengthToFee = IdentityFee<Balance>;
+	type FeeMultiplierUpdate = ConstFeeMultiplier<FeeMultiplier>;
 }
 
 construct_runtime!(
-    pub struct Runtime {
-        System: frame_system,
-        Timestamp: pallet_timestamp,
-        Balances: pallet_balances,
-        TransactionPayment: pallet_transaction_payment,
-        Md5DifficultyAdjustment: difficulty::<Instance1>,
-        Sha3DifficultyAdjustment: difficulty::<Instance2>,
-        KeccakDifficultyAdjustment: difficulty::<Instance3>,
-        BlockAuthor: block_author,
-    }
+	pub struct Runtime {
+		System: frame_system,
+		Timestamp: pallet_timestamp,
+		Balances: pallet_balances,
+		TransactionPayment: pallet_transaction_payment,
+		Md5DifficultyAdjustment: difficulty::<Instance1>,
+		Sha3DifficultyAdjustment: difficulty::<Instance2>,
+		KeccakDifficultyAdjustment: difficulty::<Instance3>,
+		BlockAuthor: block_author,
+	}
 );
 
 /// The address format for describing accounts.
@@ -353,177 +348,177 @@ pub type Block = generic::Block<Header, UncheckedExtrinsic>;
 pub type SignedBlock = generic::SignedBlock<Block>;
 /// The SignedExtension to the basic transaction logic.
 pub type SignedExtra = (
-    frame_system::CheckNonZeroSender<Runtime>,
-    frame_system::CheckSpecVersion<Runtime>,
-    frame_system::CheckTxVersion<Runtime>,
-    frame_system::CheckGenesis<Runtime>,
-    frame_system::CheckEra<Runtime>,
-    frame_system::CheckNonce<Runtime>,
-    frame_system::CheckWeight<Runtime>,
-    pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
+	frame_system::CheckNonZeroSender<Runtime>,
+	frame_system::CheckSpecVersion<Runtime>,
+	frame_system::CheckTxVersion<Runtime>,
+	frame_system::CheckGenesis<Runtime>,
+	frame_system::CheckEra<Runtime>,
+	frame_system::CheckNonce<Runtime>,
+	frame_system::CheckWeight<Runtime>,
+	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
 );
 /// Unchecked extrinsic type as expected by this runtime.
 pub type UncheckedExtrinsic =
-    generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
+	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
 /// Executive: handles dispatch to the various modules.
 pub type Executive = frame_executive::Executive<
-    Runtime,
-    Block,
-    frame_system::ChainContext<Runtime>,
-    Runtime,
-    AllPalletsWithSystem,
+	Runtime,
+	Block,
+	frame_system::ChainContext<Runtime>,
+	Runtime,
+	AllPalletsWithSystem,
 >;
 
 impl_runtime_apis! {
-    impl sp_api::Core<Block> for Runtime {
-        fn version() -> RuntimeVersion {
-            VERSION
-        }
-
-        fn execute_block(block: Block) {
-            Executive::execute_block(block)
-        }
-
-        fn initialize_block(header: &<Block as BlockT>::Header) -> ExtrinsicInclusionMode {
-            Executive::initialize_block(header)
-        }
-    }
-
-    impl sp_api::Metadata<Block> for Runtime {
-        fn metadata() -> OpaqueMetadata {
-            OpaqueMetadata::new(Runtime::metadata().into())
-        }
-
-        fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
-            Runtime::metadata_at_version(version)
-        }
-
-        fn metadata_versions() -> sp_std::vec::Vec<u32> {
-            Runtime::metadata_versions()
-        }
-    }
-
-    impl sp_block_builder::BlockBuilder<Block> for Runtime {
-        fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
-            Executive::apply_extrinsic(extrinsic)
-        }
-
-        fn finalize_block() -> <Block as BlockT>::Header {
-            Executive::finalize_block()
-        }
-
-        fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
-            data.create_extrinsics()
-        }
-
-        fn check_inherents(
-            block: Block,
-            data: sp_inherents::InherentData,
-        ) -> sp_inherents::CheckInherentsResult {
-            data.check_extrinsics(&block)
-        }
-    }
-
-    impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
-        fn validate_transaction(
-            source: TransactionSource,
-            tx: <Block as BlockT>::Extrinsic,
-            block_hash: <Block as BlockT>::Hash,
-        ) -> TransactionValidity {
-            Executive::validate_transaction(source, tx, block_hash)
-        }
-    }
-
-    impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
-        fn offchain_worker(header: &<Block as BlockT>::Header) {
-            Executive::offchain_worker(header)
-        }
-    }
-
-    impl sp_session::SessionKeys<Block> for Runtime {
-        fn generate_session_keys(_seed: Option<Vec<u8>>) -> Vec<u8> {
-            Vec::new()
-        }
-
-        fn decode_session_keys(
-            _encoded: Vec<u8>,
-        ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
-            None
-        }
-    }
-
-    impl sp_consensus_pow::DifficultyApi<Block, multi_pow::Threshold> for Runtime {
-        fn difficulty() -> multi_pow::Threshold {
-            multi_pow::Threshold {
-                md5: Md5DifficultyAdjustment::difficulty(),
-                sha3: Sha3DifficultyAdjustment::difficulty(),
-                keccak: KeccakDifficultyAdjustment::difficulty(),
-            }
-        }
-    }
-
-    impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
-        fn account_nonce(account: AccountId) -> Index {
-            System::account_nonce(account)
-        }
-    }
-
-    impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime
-    {
-        fn query_info(
-            uxt: <Block as BlockT>::Extrinsic,
-            len: u32,
-        ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
-            TransactionPayment::query_info(uxt, len)
-        }
-        fn query_fee_details(
-            uxt: <Block as BlockT>::Extrinsic,
-            len: u32,
-        ) -> pallet_transaction_payment::FeeDetails<Balance> {
-            TransactionPayment::query_fee_details(uxt, len)
-        }
-        fn query_weight_to_fee(weight: Weight) -> Balance {
-            TransactionPayment::weight_to_fee(weight)
-        }
-        fn query_length_to_fee(length: u32) -> Balance {
-            TransactionPayment::length_to_fee(length)
-        }
-    }
-
-    impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
-        for Runtime
-    {
-        fn query_call_info(
-            call: RuntimeCall,
-            len: u32,
-        ) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
-            TransactionPayment::query_call_info(call, len)
-        }
-        fn query_call_fee_details(
-            call: RuntimeCall,
-            len: u32,
-        ) -> pallet_transaction_payment::FeeDetails<Balance> {
-            TransactionPayment::query_call_fee_details(call, len)
-        }
-        fn query_weight_to_fee(weight: Weight) -> Balance {
-            TransactionPayment::weight_to_fee(weight)
-        }
-        fn query_length_to_fee(length: u32) -> Balance {
-            TransactionPayment::length_to_fee(length)
-        }
-    }
-
-    impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
-        fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
-            build_state::<RuntimeGenesisConfig>(config)
-        }
-
-        fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
-            get_preset::<RuntimeGenesisConfig>(id, |_| None)
-        }
-
-        fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
-            Default::default()
-        }
-    }
+	impl sp_api::Core<Block> for Runtime {
+		fn version() -> RuntimeVersion {
+			VERSION
+		}
+
+		fn execute_block(block: Block) {
+			Executive::execute_block(block)
+		}
+
+		fn initialize_block(header: &<Block as BlockT>::Header) -> ExtrinsicInclusionMode {
+			Executive::initialize_block(header)
+		}
+	}
+
+	impl sp_api::Metadata<Block> for Runtime {
+		fn metadata() -> OpaqueMetadata {
+			OpaqueMetadata::new(Runtime::metadata().into())
+		}
+
+		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
+			Runtime::metadata_at_version(version)
+		}
+
+		fn metadata_versions() -> sp_std::vec::Vec<u32> {
+			Runtime::metadata_versions()
+		}
+	}
+
+	impl sp_block_builder::BlockBuilder<Block> for Runtime {
+		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
+			Executive::apply_extrinsic(extrinsic)
+		}
+
+		fn finalize_block() -> <Block as BlockT>::Header {
+			Executive::finalize_block()
+		}
+
+		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
+			data.create_extrinsics()
+		}
+
+		fn check_inherents(
+			block: Block,
+			data: sp_inherents::InherentData,
+		) -> sp_inherents::CheckInherentsResult {
+			data.check_extrinsics(&block)
+		}
+	}
+
+	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
+		fn validate_transaction(
+			source: TransactionSource,
+			tx: <Block as BlockT>::Extrinsic,
+			block_hash: <Block as BlockT>::Hash,
+		) -> TransactionValidity {
+			Executive::validate_transaction(source, tx, block_hash)
+		}
+	}
+
+	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
+		fn offchain_worker(header: &<Block as BlockT>::Header) {
+			Executive::offchain_worker(header)
+		}
+	}
+
+	impl sp_session::SessionKeys<Block> for Runtime {
+		fn generate_session_keys(_seed: Option<Vec<u8>>) -> Vec<u8> {
+			Vec::new()
+		}
+
+		fn decode_session_keys(
+			_encoded: Vec<u8>,
+		) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
+			None
+		}
+	}
+
+	impl sp_consensus_pow::DifficultyApi<Block, multi_pow::Threshold> for Runtime {
+		fn difficulty() -> multi_pow::Threshold {
+			multi_pow::Threshold {
+				md5: Md5DifficultyAdjustment::difficulty(),
+				sha3: Sha3DifficultyAdjustment::difficulty(),
+				keccak: KeccakDifficultyAdjustment::difficulty(),
+			}
+		}
+	}
+
+	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
+		fn account_nonce(account: AccountId) -> Index {
+			System::account_nonce(account)
+		}
+	}
+
+	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime
+	{
+		fn query_info(
+			uxt: <Block as BlockT>::Extrinsic,
+			len: u32,
+		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
+			TransactionPayment::query_info(uxt, len)
+		}
+		fn query_fee_details(
+			uxt: <Block as BlockT>::Extrinsic,
+			len: u32,
+		) -> pallet_transaction_payment::FeeDetails<Balance> {
+			TransactionPayment::query_fee_details(uxt, len)
+		}
+		fn query_weight_to_fee(weight: Weight) -> Balance {
+			TransactionPayment::weight_to_fee(weight)
+		}
+		fn query_length_to_fee(length: u32) -> Balance {
+			TransactionPayment::length_to_fee(length)
+		}
+	}
+
+	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
+		for Runtime
+	{
+		fn query_call_info(
+			call: RuntimeCall,
+			len: u32,
+		) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
+			TransactionPayment::query_call_info(call, len)
+		}
+		fn query_call_fee_details(
+			call: RuntimeCall,
+			len: u32,
+		) -> pallet_transaction_payment::FeeDetails<Balance> {
+			TransactionPayment::query_call_fee_details(call, len)
+		}
+		fn query_weight_to_fee(weight: Weight) -> Balance {
+			TransactionPayment::weight_to_fee(weight)
+		}
+		fn query_length_to_fee(length: u32) -> Balance {
+			TransactionPayment::length_to_fee(length)
+		}
+	}
+
+	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
+		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
+			build_state::<RuntimeGenesisConfig>(config)
+		}
+
+		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
+			get_preset::<RuntimeGenesisConfig>(id, |_| None)
+		}
+
+		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
+			Default::default()
+		}
+	}
 }
diff --git a/runtime/src/utxo.rs b/runtime/src/utxo.rs
index d51c203..d387d16 100644
--- a/runtime/src/utxo.rs
+++ b/runtime/src/utxo.rs
@@ -6,8 +6,8 @@ use scale_info::TypeInfo;
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
 use sp_core::{
-    sr25519::{Public, Signature},
-    ByteArray, H256, H512,
+	sr25519::{Public, Signature},
+	ByteArray, H256, H512,
 };
 use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
 use sp_std::{collections::btree_map::BTreeMap, vec::Vec};
@@ -18,14 +18,14 @@ pub use pallet::*;
 
 #[frame_support::pallet(dev_mode)]
 pub mod pallet {
-    use frame_support::pallet_prelude::*;
-    use frame_system::pallet_prelude::*;
+	use frame_support::pallet_prelude::*;
+	use frame_system::pallet_prelude::*;
 
-    use super::*;
+	use super::*;
 
-    #[pallet::config]
-    pub trait Config: frame_system::Config { }
+	#[pallet::config]
+	pub trait Config: frame_system::Config {}
 
-    #[pallet::pallet]
-    pub struct Pallet<T>(_);
+	#[pallet::pallet]
+	pub struct Pallet<T>(_);
 }
diff --git a/rustfmt.toml b/rustfmt.toml
index af85000..c342153 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,7 +1,24 @@
+# Basic
 edition = "2021"
-use_field_init_shorthand = true
-reorder_modules = true
-
+hard_tabs = true
+max_width = 100
+use_small_heuristics = "Max"
+# Imports
 imports_granularity = "Crate"
-group_imports = "StdExternalCrate"
 reorder_imports = true
+# Consistency
+newline_style = "Unix"
+# Misc
+chain_width = 80
+spaces_around_ranges = false
+binop_separator = "Back"
+reorder_impl_items = false
+match_arm_leading_pipes = "Preserve"
+match_arm_blocks = false
+match_block_trailing_comma = true
+trailing_comma = "Vertical"
+trailing_semicolon = false
+use_field_init_shorthand = true
+# Format comments
+comment_width = 100
+wrap_comments = true

The UTXO Pallet

In this section, we will build the UTXO Pallet and apply it to the PoW Runtime & Node

This Pallet will manage the balances of users and allow them to transfer tokens to one another instead of Account-based model.

Reading materials:

Creating UTXO Pallet

[!Note] Resolve all "/// TODO" in runtime/src/utxo.rs to complete this step.

Reading Materials

I would recommend you to read these materials below first before looking at the code implmentation of the data structures. These materials below cover very well the concepts of FRAME storage in Substrate development.

Data structures to work with Storage API

The FRAME Storage module simplifies access to these layered storage abstractions. You can use the FRAME storage data structures to read or write any value that can be encoded by the SCALE codec. The storage module provides the following types of storage structures:

  • StorageValue: to store any single value, such as a u64.
  • StorageMap: to store a single key to value mapping, such as a specific account key to a specific balance value.
  • StorageDoubleMap: to store values in a storage map with two keys as an optimization to efficiently remove all entries that have a common first key.
  • StorageNMap: to store values in a map with any arbitrary number of keys.

Struct data for UTXO

Simple type for storing balance of UTXO

#![allow(unused)]
fn main() {
pub type Value = u128;
}

Struct for representing a transaction in a UTXO-based model. The struct includes macros for serialization, deserialization, and various traits that enable efficient use in a blockchain context. Let’s break down the purpose of each macro:

#![allow(unused)]
fn main() {
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct Transaction {
    /// UTXOs to be used as inputs for current transaction
    pub inputs: Vec<TransactionInput>,
    /// UTXOs to be created as a result of current transaction dispatch
    pub outputs: Vec<TransactionOutput>,
}


#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionInput {
    /// Reference to an UTXO to be spent
    pub outpoint: H256,
    /// Proof that transaction owner is authorized to spend referred UTXO &
    /// that the entire transaction is untampered
    pub sigscript: H512,
}


#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionOutput {
    /// Value associated with this output
    pub value: Value,
    /// Public key associated with this output. In order to spend this output
    /// owner must provide a proof by hashing the whole `Transaction` and
    /// signing it with a corresponding private key.
    pub pubkey: H256,
}
}
  • cfg_attr(feature = "std", derive(Serialize, Deserialize)): This macro conditionally derives the Serialize and Deserialize traits when the std feature is enabled. This feature is useful for converting the Transaction struct to and from formats like JSON or other text-based formats. This functionality is often used in scenarios like data exchange between systems, debugging, or interacting with APIs or frontends.

  • Encode, Decode: These macros from the parity-scale-codec crate allow the struct to be serialized to and deserialized from the SCALE binary format, ensuring efficient storage and transmission on the blockchain. Read more SCALE.

  • TypeInfo: Generates metadata for the struct, allowing its type information to be included in the blockchain's runtime metadata. This is valuable for interoperability with tools like Substrate frontends.


Configure your pallet's types, events and errors

#![allow(unused)]
fn main() {
#[pallet::config]
pub trait Config: frame_system::Config {
    /// Because this pallet emits events, it depends on the runtime's definition of an event.
    /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
    type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

    /// A source to determine the block author
    /// Read more: `runtime/src/block_author.rs`
    /// Pallet loosely coupling
    /// https://polkadot-blockchain-academy.github.io/pba-book/frame/coupling/page.html#loosely-coupled-pallets
    type BlockAuthor: BlockAuthor;

    /// A source to determine the issuance portion of the block reward
    /// Read more: `runtime/src/issuance.rs`
    type Issuance: Issuance<BlockNumberFor<Self>, Value>;
}
}

This storage item represents the total reward value to be redistributed among authorities during block finalization.

#![allow(unused)]
fn main() {
/// Total reward value to be redistributed among authorities.
/// It is accumulated from transactions during block execution
/// and then dispersed to validators on block finalization.
#[pallet::storage]
#[pallet::getter(fn total_reward)]
pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;
}

This storage item represents a mapping of UTXOs to their respective keys, allowing efficient lookup and management of UTXOs in a UTXO-based blockchain model.

#![allow(unused)]
fn main() {
/// All valid unspent transaction outputs are stored in this map.
/// Initial set of UTXO is populated from the list stored in genesis.
/// We use the identity hasher here because the cryptographic hashing is
/// done explicitly.
/// Mapping from `BlakeTwo256::hash_of(transaction, index)` to `TransactionOutput`
#[pallet::storage]
#[pallet::getter(fn utxo_store)]
pub type UtxoStore<T: Config> = StorageMap<
    Hasher = Identity,
    Key = H256,
    Value = TransactionOutput,
    QueryKind = OptionQuery,
>;
}

Events & Errors

Events and errors are used to notify about specific activity. Please use this for debugging purpose only. Events and Errors should not be used as a communication method between functionalities. In our codebase, we will declare these errors and events.

To declare error, simply use macro #[pallet::error]

#![allow(unused)]
fn main() {
/// Errors inform users that something went wrong.
#[pallet::error]
pub enum Error<T> {
    /// Missing `Transaction` Input
    MissingInput,
    /// Reward overflow
    RewardOverflow,
    /// Maximum transaction depth
    MaximumTransactionDepth,
    /// Empty input
    EmptyInput,
    /// Empty output
    EmptyOutput,
    /// Each input must only be used once
    DuplicatedInput,
    /// Each output must be defined only once
    DuplicatedOutput,
    /// Input value is overflow
    InputOverflow,
    /// Output value is overflow
    OutputOverflow,
    /// Output spent must lte than Input spent
    OutputOverInput,
    /// Zero amount spent
    ZeroAmount,
    /// Invalid signature
    InvalidSignature,
}
}

To declare event, use #[pallet::event]. Moreover with #[pallet::generate_deposit(pub(super) fn deposit_event)], it automatically generate a function deposit_event for emitting events.

#![allow(unused)]
fn main() {
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
    /// Dispatch transaction successful
    TransactionSuccess(Transaction),
    /// UTXO out processed
    TransactionOutputProcessed(H256),
    /// Reward distributed to `BlockAuthor`
    RewardDistributed(Value, H256),
    /// Faucet to `To`
    Faucet(Value, H256),
    /// No one get reward
    RewardWasted,
}
}

Build the code

cargo build --release

Great job! 🎉 You're making fantastic progress. Let's keep the momentum going and dive into next step

#![allow(unused)]
fn main() {
// We make sure this pallet uses `no_std` for compiling to Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_core::{
    sr25519::{Public, Signature},
    ByteArray, H256, H512,
};
use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

use super::{block_author::BlockAuthor, issuance::Issuance};

pub use pallet::*;

/// TODO [2-data-structure]
// pub type Value = u128;

/// TODO [2-data-structure]
/// Single transaction to be dispatched
// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
// #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
// pub struct Transaction {
//     /// UTXOs to be used as inputs for current transaction
//     pub inputs: Vec<TransactionInput>,
//     /// UTXOs to be created as a result of current transaction dispatch
//     pub outputs: Vec<TransactionOutput>,
// }

/// TODO [2-data-structure]
/// Single transaction input that refers to one UTXO
// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
// #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
// pub struct TransactionInput {
//     /// Reference to an UTXO to be spent
//     pub outpoint: H256,

//     /// Proof that transaction owner is authorized to spend referred UTXO &
//     /// that the entire transaction is untampered
//     pub sigscript: H512,
// }

/// TODO [2-data-structure]
/// Single transaction output to create upon transaction dispatch
// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
// #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
// pub struct TransactionOutput {
//     /// Value associated with this output
//     pub value: Value,

//     /// Public key associated with this output. In order to spend this output
//     /// owner must provide a proof by hashing the whole `Transaction` and
//     /// signing it with a corresponding private key.
//     pub pubkey: H256,
// }

#[frame_support::pallet(dev_mode)]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    use super::*;

    /// TODO [2-data-structure]
    #[pallet::config]
    pub trait Config: frame_system::Config {
        // /// Because this pallet emits events, it depends on the runtime's definition of an event.
        // /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
        // type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

        // /// A source to determine the block author
        // /// Read more: `runtime/src/block_author.rs`
        // /// Pallet loosely coupling
        // /// https://polkadot-blockchain-academy.github.io/pba-book/frame/coupling/page.html#loosely-coupled-pallets
        // type BlockAuthor: BlockAuthor;

        // /// A source to determine the issuance portion of the block reward
        // type Issuance: Issuance<BlockNumberFor<Self>, Value>;
    }

    #[pallet::pallet]
    pub struct Pallet<T>(_);


    /// TODO [2-data-structure]
    /// Total reward value to be redistributed among authorities.
    /// It is accumulated from transactions during block execution
    /// and then dispersed to validators on block finalization.
    // #[pallet::storage]
    // #[pallet::getter(fn total_reward)]
    // pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;

    /// TODO [2-data-structure]
    /// All valid unspent transaction outputs are stored in this map.
    /// Initial set of UTXO is populated from the list stored in genesis.
    /// We use the identity hasher here because the cryptographic hashing is
    /// done explicitly.
    /// Mapping from `BlakeTwo256::hash_of(transaction, index)` to `TransactionOutput`
    // #[pallet::storage]
    // #[pallet::getter(fn utxo_store)]
    // pub type UtxoStore<T: Config> = StorageMap<
    //     Hasher = Identity,
    //     Key = H256,
    //     Value = TransactionOutput,
    //     QueryKind = OptionQuery,
    // >;


    /// TODO [2-data-structure]
    /// Pallets use events to inform users when important changes are made.
    // #[pallet::event]
    // #[pallet::generate_deposit(pub(super) fn deposit_event)]
    // pub enum Event<T: Config> {
    //     /// Dispatch transaction successful
    //     TransactionSuccess(Transaction),
    //     /// UTXO out processed
    //     TransactionOutputProcessed(H256),
    //     /// Reward distributed to `BlockAuthor`
    //     RewardDistributed(Value, H256),
    //     /// Faucet to `To`
    //     Faucet(Value, H256),
    //     /// No one get reward
    //     RewardWasted,
    // }


    /// TODO [2-data-structure]
    /// Errors inform users that something went wrong.
    // #[pallet::error]
    // pub enum Error<T> {
    //     /// Missing `Transaction` Input
    //     MissingInput,
    //     /// Reward overflow
    //     RewardOverflow,
    //     /// Maximum transaction depth
    //     MaximumTransactionDepth,
    //     /// Empty input
    //     EmptyInput,
    //     /// Empty output
    //     EmptyOutput,
    //     /// Each input must only be used once
    //     DuplicatedInput,
    //     /// Each output must be defined only once
    //     DuplicatedOutput,
    //     /// Input value is overflow
    //     InputOverflow,
    //     /// Output value is overflow
    //     OutputOverflow,
    //     /// Output spent must lte than Input spent
    //     OutputOverInput,
    //     /// Zero amount spent
    //     ZeroAmount,
    //     /// Invalid signature
    //     InvalidSignature,
    // }


    /// TODO [2-data-structure]
    /// Define extrinsics / dispatchable function
    // #[pallet::call]
    // impl<T: Config> Pallet<T> {
    //     pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
    //         todo!();
    //     }

    // }

    /// TODO [2-data-structure]
    /// Define intrinsics
    // impl<T: Config> Pallet<T> {
    //     /// Implement spend logic, update storage to reflect changes made by transaction
    //     /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
    //     fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
    //         todo!();
    //     }

    //     /// Redistribute combined reward value to block Author
    //     fn disperse_reward(author: &Public) {
    //         todo!();
    //     }

    //     /// Mutate storage, insert / update new UTXOs
    //     fn store_utxo(utxo: &TransactionOutput, hash: H256) {
    //         todo!();
    //     }

    //     /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
    //     fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
    //         todo!();
    //     }

    //     /// Check transaction for validity, errors, & race conditions
    //     /// Called by both transaction pool and runtime execution
    //     pub fn validate_transaction(
    //         transaction: &Transaction,
    //     ) -> Result<ValidTransaction, &'static str> {
    //         todo!();
    //     }
    // }
}
}
#![allow(unused)]
fn main() {
// We make sure this pallet uses `no_std` for compiling to Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_core::{
    sr25519::{Public, Signature},
    ByteArray, H256, H512,
};
use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

use super::{block_author::BlockAuthor, issuance::Issuance};

pub use pallet::*;

///  [2-data-structure]
pub type Value = u128;

///  [2-data-structure]
/// Single transaction to be dispatched
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct Transaction {
    /// UTXOs to be used as inputs for current transaction
    pub inputs: Vec<TransactionInput>,
    /// UTXOs to be created as a result of current transaction dispatch
    pub outputs: Vec<TransactionOutput>,
}

///  [2-data-structure]
/// Single transaction input that refers to one UTXO
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionInput {
    /// Reference to an UTXO to be spent
    pub outpoint: H256,

    /// Proof that transaction owner is authorized to spend referred UTXO &
    /// that the entire transaction is untampered
    pub sigscript: H512,
}

///  [2-data-structure]
/// Single transaction output to create upon transaction dispatch
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionOutput {
    /// Value associated with this output
    pub value: Value,

    /// Public key associated with this output. In order to spend this output
    /// owner must provide a proof by hashing the whole `Transaction` and
    /// signing it with a corresponding private key.
    pub pubkey: H256,
}

#[frame_support::pallet(dev_mode)]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    use super::*;

    ///  [2-data-structure]
    #[pallet::config]
    pub trait Config: frame_system::Config {
        /// Because this pallet emits events, it depends on the runtime's definition of an event.
        /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
        type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

        /// A source to determine the block author
        /// Read more: `runtime/src/block_author.rs`
        /// Pallet loosely coupling
        /// https://polkadot-blockchain-academy.github.io/pba-book/frame/coupling/page.html#loosely-coupled-pallets
        type BlockAuthor: BlockAuthor;

        /// A source to determine the issuance portion of the block reward
        type Issuance: Issuance<BlockNumberFor<Self>, Value>;
    }

    #[pallet::pallet]
    pub struct Pallet<T>(_);


    ///  [2-data-structure]
    /// Total reward value to be redistributed among authorities.
    /// It is accumulated from transactions during block execution
    /// and then dispersed to validators on block finalization.
    #[pallet::storage]
    #[pallet::getter(fn total_reward)]
    pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;

    ///  [2-data-structure]
    /// All valid unspent transaction outputs are stored in this map.
    /// Initial set of UTXO is populated from the list stored in genesis.
    /// We use the identity hasher here because the cryptographic hashing is
    /// done explicitly.
    /// Mapping from `BlakeTwo256::hash_of(transaction, index)` to `TransactionOutput`
    #[pallet::storage]
    #[pallet::getter(fn utxo_store)]
    pub type UtxoStore<T: Config> = StorageMap<
        Hasher = Identity,
        Key = H256,
        Value = TransactionOutput,
        QueryKind = OptionQuery,
    >;


    ///  [2-data-structure]
    /// Pallets use events to inform users when important changes are made.
    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        /// Dispatch transaction successful
        TransactionSuccess(Transaction),
        /// UTXO out processed
        TransactionOutputProcessed(H256),
        /// Reward distributed to `BlockAuthor`
        RewardDistributed(Value, H256),
        /// Faucet to `To`
        Faucet(Value, H256),
        /// No one get reward
        RewardWasted,
    }


    ///  [2-data-structure]
    /// Errors inform users that something went wrong.
    #[pallet::error]
    pub enum Error<T> {
        /// Missing `Transaction` Input
        MissingInput,
        /// Reward overflow
        RewardOverflow,
        /// Maximum transaction depth
        MaximumTransactionDepth,
        /// Empty input
        EmptyInput,
        /// Empty output
        EmptyOutput,
        /// Each input must only be used once
        DuplicatedInput,
        /// Each output must be defined only once
        DuplicatedOutput,
        /// Input value is overflow
        InputOverflow,
        /// Output value is overflow
        OutputOverflow,
        /// Output spent must lte than Input spent
        OutputOverInput,
        /// Zero amount spent
        ZeroAmount,
        /// Invalid signature
        InvalidSignature,
    }


    ///  [2-data-structure]
    /// Define extrinsics / dispatchable function
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
            todo!();
        }

    }

    ///  [2-data-structure]
    /// Define intrinsics
    impl<T: Config> Pallet<T> {
        /// Implement spend logic, update storage to reflect changes made by transaction
        /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
        fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
            todo!();
        }

        /// Redistribute combined reward value to block Author
        fn disperse_reward(author: &Public) {
            todo!();
        }

        /// Mutate storage, insert / update new UTXOs
        fn store_utxo(utxo: &TransactionOutput, hash: H256) {
            todo!();
        }

        /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
        fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
            todo!();
        }

        /// Check transaction for validity, errors, & race conditions
        /// Called by both transaction pool and runtime execution
        pub fn validate_transaction(
            transaction: &Transaction,
        ) -> Result<ValidTransaction, &'static str> {
            todo!();
        }
    }
}
}
diff --git a/runtime/src/utxo.rs b/runtime/src/utxo.rs
index d387d16..47950e4 100644
--- a/runtime/src/utxo.rs
+++ b/runtime/src/utxo.rs
@@ -6,8 +6,8 @@ use scale_info::TypeInfo;
 #[cfg(feature = "std")]
 use serde::{Deserialize, Serialize};
 use sp_core::{
-	sr25519::{Public, Signature},
-	ByteArray, H256, H512,
+    sr25519::{Public, Signature},
+    ByteArray, H256, H512,
 };
 use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
 use sp_std::{collections::btree_map::BTreeMap, vec::Vec};
@@ -16,16 +16,188 @@ use super::{block_author::BlockAuthor, issuance::Issuance};
 
 pub use pallet::*;
 
+/// TODO [2-data-structure]
+// pub type Value = u128;
+
+/// TODO [2-data-structure]
+/// Single transaction to be dispatched
+// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+// #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
+// pub struct Transaction {
+//     /// UTXOs to be used as inputs for current transaction
+//     pub inputs: Vec<TransactionInput>,
+//     /// UTXOs to be created as a result of current transaction dispatch
+//     pub outputs: Vec<TransactionOutput>,
+// }
+
+/// TODO [2-data-structure]
+/// Single transaction input that refers to one UTXO
+// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+// #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
+// pub struct TransactionInput {
+//     /// Reference to an UTXO to be spent
+//     pub outpoint: H256,
+
+//     /// Proof that transaction owner is authorized to spend referred UTXO &
+//     /// that the entire transaction is untampered
+//     pub sigscript: H512,
+// }
+
+/// TODO [2-data-structure]
+/// Single transaction output to create upon transaction dispatch
+// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+// #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
+// pub struct TransactionOutput {
+//     /// Value associated with this output
+//     pub value: Value,
+
+//     /// Public key associated with this output. In order to spend this output
+//     /// owner must provide a proof by hashing the whole `Transaction` and
+//     /// signing it with a corresponding private key.
+//     pub pubkey: H256,
+// }
+
 #[frame_support::pallet(dev_mode)]
 pub mod pallet {
-	use frame_support::pallet_prelude::*;
-	use frame_system::pallet_prelude::*;
+    use frame_support::pallet_prelude::*;
+    use frame_system::pallet_prelude::*;
+
+    use super::*;
+
+    /// TODO [2-data-structure]
+    #[pallet::config]
+    pub trait Config: frame_system::Config {
+        // /// Because this pallet emits events, it depends on the runtime's definition of an event.
+        // /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
+        // type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
+
+        // /// A source to determine the block author
+        // /// Read more: `runtime/src/block_author.rs`
+        // /// Pallet loosely coupling
+        // /// https://polkadot-blockchain-academy.github.io/pba-book/frame/coupling/page.html#loosely-coupled-pallets
+        // type BlockAuthor: BlockAuthor;
+
+        // /// A source to determine the issuance portion of the block reward
+        // type Issuance: Issuance<BlockNumberFor<Self>, Value>;
+    }
+
+    #[pallet::pallet]
+    pub struct Pallet<T>(_);
+
+
+    /// TODO [2-data-structure]
+    /// Total reward value to be redistributed among authorities.
+    /// It is accumulated from transactions during block execution
+    /// and then dispersed to validators on block finalization.
+    // #[pallet::storage]
+    // #[pallet::getter(fn total_reward)]
+    // pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;
+
+    /// TODO [2-data-structure]
+    /// All valid unspent transaction outputs are stored in this map.
+    /// Initial set of UTXO is populated from the list stored in genesis.
+    /// We use the identity hasher here because the cryptographic hashing is
+    /// done explicitly.
+    /// Mapping from `BlakeTwo256::hash_of(transaction, index)` to `TransactionOutput`
+    // #[pallet::storage]
+    // #[pallet::getter(fn utxo_store)]
+    // pub type UtxoStore<T: Config> = StorageMap<
+    //     Hasher = Identity,
+    //     Key = H256,
+    //     Value = TransactionOutput,
+    //     QueryKind = OptionQuery,
+    // >;
+
+
+    /// TODO [2-data-structure]
+    /// Pallets use events to inform users when important changes are made.
+    // #[pallet::event]
+    // #[pallet::generate_deposit(pub(super) fn deposit_event)]
+    // pub enum Event<T: Config> {
+    //     /// Dispatch transaction successful
+    //     TransactionSuccess(Transaction),
+    //     /// UTXO out processed
+    //     TransactionOutputProcessed(H256),
+    //     /// Reward distributed to `BlockAuthor`
+    //     RewardDistributed(Value, H256),
+    //     /// Faucet to `To`
+    //     Faucet(Value, H256),
+    //     /// No one get reward
+    //     RewardWasted,
+    // }
+
+
+    /// TODO [2-data-structure]
+    /// Errors inform users that something went wrong.
+    // #[pallet::error]
+    // pub enum Error<T> {
+    //     /// Missing `Transaction` Input
+    //     MissingInput,
+    //     /// Reward overflow
+    //     RewardOverflow,
+    //     /// Maximum transaction depth
+    //     MaximumTransactionDepth,
+    //     /// Empty input
+    //     EmptyInput,
+    //     /// Empty output
+    //     EmptyOutput,
+    //     /// Each input must only be used once
+    //     DuplicatedInput,
+    //     /// Each output must be defined only once
+    //     DuplicatedOutput,
+    //     /// Input value is overflow
+    //     InputOverflow,
+    //     /// Output value is overflow
+    //     OutputOverflow,
+    //     /// Output spent must lte than Input spent
+    //     OutputOverInput,
+    //     /// Zero amount spent
+    //     ZeroAmount,
+    //     /// Invalid signature
+    //     InvalidSignature,
+    // }
+
+
+    /// TODO [2-data-structure]
+    /// Define extrinsics / dispatchable function
+    // #[pallet::call]
+    // impl<T: Config> Pallet<T> {
+    //     pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
+    //         todo!();
+    //     }
+
+    // }
+
+    /// TODO [2-data-structure]
+    /// Define intrinsics
+    // impl<T: Config> Pallet<T> {
+    //     /// Implement spend logic, update storage to reflect changes made by transaction
+    //     /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
+    //     fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
+    //         todo!();
+    //     }
+
+    //     /// Redistribute combined reward value to block Author
+    //     fn disperse_reward(author: &Public) {
+    //         todo!();
+    //     }
 
-	use super::*;
+    //     /// Mutate storage, insert / update new UTXOs
+    //     fn store_utxo(utxo: &TransactionOutput, hash: H256) {
+    //         todo!();
+    //     }
 
-	#[pallet::config]
-	pub trait Config: frame_system::Config {}
+    //     /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
+    //     fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
+    //         todo!();
+    //     }
 
-	#[pallet::pallet]
-	pub struct Pallet<T>(_);
-}
+    //     /// Check transaction for validity, errors, & race conditions
+    //     /// Called by both transaction pool and runtime execution
+    //     pub fn validate_transaction(
+    //         transaction: &Transaction,
+    //     ) -> Result<ValidTransaction, &'static str> {
+    //         todo!();
+    //     }
+    // }
+}
\ No newline at end of file
diff --git a/runtime/src/utxo.rs b/runtime/src/utxo.rs
index 47950e4..69a9535 100644
--- a/runtime/src/utxo.rs
+++ b/runtime/src/utxo.rs
@@ -16,46 +16,46 @@ use super::{block_author::BlockAuthor, issuance::Issuance};
 
 pub use pallet::*;
 
-/// TODO [2-data-structure]
-// pub type Value = u128;
+///  [2-data-structure]
+pub type Value = u128;
 
-/// TODO [2-data-structure]
+///  [2-data-structure]
 /// Single transaction to be dispatched
-// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-// #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
-// pub struct Transaction {
-//     /// UTXOs to be used as inputs for current transaction
-//     pub inputs: Vec<TransactionInput>,
-//     /// UTXOs to be created as a result of current transaction dispatch
-//     pub outputs: Vec<TransactionOutput>,
-// }
-
-/// TODO [2-data-structure]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
+pub struct Transaction {
+    /// UTXOs to be used as inputs for current transaction
+    pub inputs: Vec<TransactionInput>,
+    /// UTXOs to be created as a result of current transaction dispatch
+    pub outputs: Vec<TransactionOutput>,
+}
+
+///  [2-data-structure]
 /// Single transaction input that refers to one UTXO
-// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-// #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
-// pub struct TransactionInput {
-//     /// Reference to an UTXO to be spent
-//     pub outpoint: H256,
-
-//     /// Proof that transaction owner is authorized to spend referred UTXO &
-//     /// that the entire transaction is untampered
-//     pub sigscript: H512,
-// }
-
-/// TODO [2-data-structure]
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
+pub struct TransactionInput {
+    /// Reference to an UTXO to be spent
+    pub outpoint: H256,
+
+    /// Proof that transaction owner is authorized to spend referred UTXO &
+    /// that the entire transaction is untampered
+    pub sigscript: H512,
+}
+
+///  [2-data-structure]
 /// Single transaction output to create upon transaction dispatch
-// #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
-// #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
-// pub struct TransactionOutput {
-//     /// Value associated with this output
-//     pub value: Value,
-
-//     /// Public key associated with this output. In order to spend this output
-//     /// owner must provide a proof by hashing the whole `Transaction` and
-//     /// signing it with a corresponding private key.
-//     pub pubkey: H256,
-// }
+#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
+#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
+pub struct TransactionOutput {
+    /// Value associated with this output
+    pub value: Value,
+
+    /// Public key associated with this output. In order to spend this output
+    /// owner must provide a proof by hashing the whole `Transaction` and
+    /// signing it with a corresponding private key.
+    pub pubkey: H256,
+}
 
 #[frame_support::pallet(dev_mode)]
 pub mod pallet {
@@ -64,140 +64,140 @@ pub mod pallet {
 
     use super::*;
 
-    /// TODO [2-data-structure]
+    ///  [2-data-structure]
     #[pallet::config]
     pub trait Config: frame_system::Config {
-        // /// Because this pallet emits events, it depends on the runtime's definition of an event.
-        // /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
-        // type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
-
-        // /// A source to determine the block author
-        // /// Read more: `runtime/src/block_author.rs`
-        // /// Pallet loosely coupling
-        // /// https://polkadot-blockchain-academy.github.io/pba-book/frame/coupling/page.html#loosely-coupled-pallets
-        // type BlockAuthor: BlockAuthor;
-
-        // /// A source to determine the issuance portion of the block reward
-        // type Issuance: Issuance<BlockNumberFor<Self>, Value>;
+        /// Because this pallet emits events, it depends on the runtime's definition of an event.
+        /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
+        type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
+
+        /// A source to determine the block author
+        /// Read more: `runtime/src/block_author.rs`
+        /// Pallet loosely coupling
+        /// https://polkadot-blockchain-academy.github.io/pba-book/frame/coupling/page.html#loosely-coupled-pallets
+        type BlockAuthor: BlockAuthor;
+
+        /// A source to determine the issuance portion of the block reward
+        type Issuance: Issuance<BlockNumberFor<Self>, Value>;
     }
 
     #[pallet::pallet]
     pub struct Pallet<T>(_);
 
 
-    /// TODO [2-data-structure]
+    ///  [2-data-structure]
     /// Total reward value to be redistributed among authorities.
     /// It is accumulated from transactions during block execution
     /// and then dispersed to validators on block finalization.
-    // #[pallet::storage]
-    // #[pallet::getter(fn total_reward)]
-    // pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;
+    #[pallet::storage]
+    #[pallet::getter(fn total_reward)]
+    pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;
 
-    /// TODO [2-data-structure]
+    ///  [2-data-structure]
     /// All valid unspent transaction outputs are stored in this map.
     /// Initial set of UTXO is populated from the list stored in genesis.
     /// We use the identity hasher here because the cryptographic hashing is
     /// done explicitly.
     /// Mapping from `BlakeTwo256::hash_of(transaction, index)` to `TransactionOutput`
-    // #[pallet::storage]
-    // #[pallet::getter(fn utxo_store)]
-    // pub type UtxoStore<T: Config> = StorageMap<
-    //     Hasher = Identity,
-    //     Key = H256,
-    //     Value = TransactionOutput,
-    //     QueryKind = OptionQuery,
-    // >;
+    #[pallet::storage]
+    #[pallet::getter(fn utxo_store)]
+    pub type UtxoStore<T: Config> = StorageMap<
+        Hasher = Identity,
+        Key = H256,
+        Value = TransactionOutput,
+        QueryKind = OptionQuery,
+    >;
 
 
-    /// TODO [2-data-structure]
+    ///  [2-data-structure]
     /// Pallets use events to inform users when important changes are made.
-    // #[pallet::event]
-    // #[pallet::generate_deposit(pub(super) fn deposit_event)]
-    // pub enum Event<T: Config> {
-    //     /// Dispatch transaction successful
-    //     TransactionSuccess(Transaction),
-    //     /// UTXO out processed
-    //     TransactionOutputProcessed(H256),
-    //     /// Reward distributed to `BlockAuthor`
-    //     RewardDistributed(Value, H256),
-    //     /// Faucet to `To`
-    //     Faucet(Value, H256),
-    //     /// No one get reward
-    //     RewardWasted,
-    // }
-
-
-    /// TODO [2-data-structure]
+    #[pallet::event]
+    #[pallet::generate_deposit(pub(super) fn deposit_event)]
+    pub enum Event<T: Config> {
+        /// Dispatch transaction successful
+        TransactionSuccess(Transaction),
+        /// UTXO out processed
+        TransactionOutputProcessed(H256),
+        /// Reward distributed to `BlockAuthor`
+        RewardDistributed(Value, H256),
+        /// Faucet to `To`
+        Faucet(Value, H256),
+        /// No one get reward
+        RewardWasted,
+    }
+
+
+    ///  [2-data-structure]
     /// Errors inform users that something went wrong.
-    // #[pallet::error]
-    // pub enum Error<T> {
-    //     /// Missing `Transaction` Input
-    //     MissingInput,
-    //     /// Reward overflow
-    //     RewardOverflow,
-    //     /// Maximum transaction depth
-    //     MaximumTransactionDepth,
-    //     /// Empty input
-    //     EmptyInput,
-    //     /// Empty output
-    //     EmptyOutput,
-    //     /// Each input must only be used once
-    //     DuplicatedInput,
-    //     /// Each output must be defined only once
-    //     DuplicatedOutput,
-    //     /// Input value is overflow
-    //     InputOverflow,
-    //     /// Output value is overflow
-    //     OutputOverflow,
-    //     /// Output spent must lte than Input spent
-    //     OutputOverInput,
-    //     /// Zero amount spent
-    //     ZeroAmount,
-    //     /// Invalid signature
-    //     InvalidSignature,
-    // }
-
-
-    /// TODO [2-data-structure]
+    #[pallet::error]
+    pub enum Error<T> {
+        /// Missing `Transaction` Input
+        MissingInput,
+        /// Reward overflow
+        RewardOverflow,
+        /// Maximum transaction depth
+        MaximumTransactionDepth,
+        /// Empty input
+        EmptyInput,
+        /// Empty output
+        EmptyOutput,
+        /// Each input must only be used once
+        DuplicatedInput,
+        /// Each output must be defined only once
+        DuplicatedOutput,
+        /// Input value is overflow
+        InputOverflow,
+        /// Output value is overflow
+        OutputOverflow,
+        /// Output spent must lte than Input spent
+        OutputOverInput,
+        /// Zero amount spent
+        ZeroAmount,
+        /// Invalid signature
+        InvalidSignature,
+    }
+
+
+    ///  [2-data-structure]
     /// Define extrinsics / dispatchable function
-    // #[pallet::call]
-    // impl<T: Config> Pallet<T> {
-    //     pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
-    //         todo!();
-    //     }
+    #[pallet::call]
+    impl<T: Config> Pallet<T> {
+        pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
+            todo!();
+        }
 
-    // }
+    }
 
-    /// TODO [2-data-structure]
+    ///  [2-data-structure]
     /// Define intrinsics
-    // impl<T: Config> Pallet<T> {
-    //     /// Implement spend logic, update storage to reflect changes made by transaction
-    //     /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
-    //     fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
-    //         todo!();
-    //     }
-
-    //     /// Redistribute combined reward value to block Author
-    //     fn disperse_reward(author: &Public) {
-    //         todo!();
-    //     }
-
-    //     /// Mutate storage, insert / update new UTXOs
-    //     fn store_utxo(utxo: &TransactionOutput, hash: H256) {
-    //         todo!();
-    //     }
-
-    //     /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
-    //     fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
-    //         todo!();
-    //     }
-
-    //     /// Check transaction for validity, errors, & race conditions
-    //     /// Called by both transaction pool and runtime execution
-    //     pub fn validate_transaction(
-    //         transaction: &Transaction,
-    //     ) -> Result<ValidTransaction, &'static str> {
-    //         todo!();
-    //     }
-    // }
+    impl<T: Config> Pallet<T> {
+        /// Implement spend logic, update storage to reflect changes made by transaction
+        /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
+        fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
+            todo!();
+        }
+
+        /// Redistribute combined reward value to block Author
+        fn disperse_reward(author: &Public) {
+            todo!();
+        }
+
+        /// Mutate storage, insert / update new UTXOs
+        fn store_utxo(utxo: &TransactionOutput, hash: H256) {
+            todo!();
+        }
+
+        /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
+        fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
+            todo!();
+        }
+
+        /// Check transaction for validity, errors, & race conditions
+        /// Called by both transaction pool and runtime execution
+        pub fn validate_transaction(
+            transaction: &Transaction,
+        ) -> Result<ValidTransaction, &'static str> {
+            todo!();
+        }
+    }
 }
\ No newline at end of file

Interacting with UTXO

[!Note] Resolve all TODO in runtime/src/utxo.rs to complete this step.

Now that we have established the basics of our UTXO module, let's add ways to interact with it.

Reading Materials

Dispatchable / Call / Extrinsic functions:

[!Note] Note that we'll implement UTXO pallet in dev_mode, it is not necessary to specify weight and call_index. However, feel free to do it if you want.

Implement for Pallet UTXO

Implement spend extrinsic. Highly recommend that keep the function simple and move all logics to intrinsics named with prefix do_..., execute_... (or whatever prefix you want 👀).

#![allow(unused)]
fn main() {
pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
    // validate transaction
    let transaction_validity = Self::validate_transaction(&transaction)?;
    ensure!(
        transaction_validity.requires.is_empty(),
        Error::<T>::MissingInput
    );

    // implement logic
    Self::do_spend(&transaction, transaction_validity.priority as Value)?;

    // emit event
    Self::deposit_event(Event::<T>::TransactionSuccess(transaction));

    Ok(())
}
}

Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.

Just is for demo usage, feel free to add logic of using additional salt yourself 😉.

#![allow(unused)]
fn main() {
fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
    let mut trx = transaction.clone();
    for input in trx.inputs.iter_mut() {
        input.sigscript = H512::zero();
    }

    trx.encode()
}
}

Implement validate_transaction intrinsic with criteria:

  • Inputs and outputs are not empty
  • Each input is used exactly once
  • All inputs match to existing, unspent and unlocked outputs
  • Sum of input values does not overflow
  • Each output is defined exactly once and has nonzero value
  • Sum of output values does not overflow
  • Total output value must not exceed total input value
#![allow(unused)]
fn main() {
/// Check transaction for validity, errors, & race conditions
/// Called by both transaction pool and runtime execution
pub fn validate_transaction(
    transaction: &Transaction,
) -> Result<ValidTransaction, &'static str> {
    // Check inputs and outputs are not empty
    ensure!(!transaction.inputs.is_empty(), Error::<T>::EmptyInput);
    ensure!(!transaction.outputs.is_empty(), Error::<T>::EmptyOutput);

    // Check each input is used exactly once
    {
        let input_set: BTreeMap<_, ()> =
            transaction.inputs.iter().map(|input| (input, ())).collect();
        ensure!(
            input_set.len() == transaction.inputs.len(),
            Error::<T>::DuplicatedInput
        );
    }
    {
        let output_set: BTreeMap<_, ()> = transaction
            .outputs
            .iter()
            .map(|output| (output, ()))
            .collect();
        ensure!(
            output_set.len() == transaction.outputs.len(),
            Error::<T>::DuplicatedOutput
        );
    }

    let mut total_input: Value = 0;
    let mut total_output: Value = 0;
    let mut output_index: u64 = 0;
    let simple_transaction = Self::get_simple_transaction(transaction);

    // Variables sent to transaction pool
    let mut missing_utxos = Vec::new();
    let mut new_utxos = Vec::new();
    let mut reward = 0;

    for input in transaction.inputs.iter() {
        // Check all inputs match to existing, unspent and unlocked outputs
        if let Some(input_utxo) = UtxoStore::<T>::get(&input.outpoint) {
            // Check provided signatures are valid
            let is_valid_sig = sp_io::crypto::sr25519_verify(
                &Signature::from_raw(*input.sigscript.as_fixed_bytes()),
                &simple_transaction,
                &Public::from_h256(input_utxo.pubkey),
            );
            ensure!(is_valid_sig, Error::<T>::InvalidSignature);
            // Check sum of input values does not overflow
            total_input = total_input
                .checked_add(input_utxo.value)
                .ok_or(Error::<T>::InputOverflow)?;
        } else {
            missing_utxos.push(input.outpoint.clone().as_fixed_bytes().to_vec());
        }
    }

    // Check each output is defined exactly once and has nonzero value
    for output in transaction.outputs.iter() {
        ensure!(output.value > 0, Error::<T>::ZeroAmount);
        let hash = BlakeTwo256::hash_of(&(&transaction.encode(), output_index));
        output_index = output_index
            .checked_add(1)
            .ok_or(Error::<T>::MaximumTransactionDepth)?;
        // Check new outputs do not collide with existing ones
        ensure!(
            !UtxoStore::<T>::contains_key(hash),
            Error::<T>::DuplicatedOutput
        );
        // Check sum of output values does not overflow
        total_output = total_output
            .checked_add(output.value)
            .ok_or(Error::<T>::OutputOverflow)?;
        new_utxos.push(hash.as_fixed_bytes().to_vec());
    }

    // If no race condition, check the math
    if missing_utxos.is_empty() {
        // Check total output value must not exceed total input value
        ensure!(total_input >= total_output, Error::<T>::OutputOverInput);
        reward = total_input
            .checked_sub(total_output)
            .ok_or(Error::<T>::RewardOverflow)?;
    }

    // Returns transaction details
    Ok(ValidTransaction {
        requires: missing_utxos,
        provides: new_utxos,
        priority: reward as u64,
        longevity: TransactionLongevity::max_value(),
        propagate: true,
    })
}
}

Implement do_spend intrinsic for spend extrinsic

#![allow(unused)]
fn main() {
/// Implement spend logic, update storage to reflect changes made by transaction
/// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
    // Calculate new reward total. The rest of `total_input - total_output` will be used for block reward.
    let new_total = TotalReward::<T>::get()
        .checked_add(reward)
        .ok_or(Error::<T>::RewardOverflow)?;
    TotalReward::<T>::put(new_total);

    // Removing spent UTXOs
    for input in &transaction.inputs {
        UtxoStore::<T>::remove(input.outpoint);
    }

    let mut index: u64 = 0;
    for output in &transaction.outputs {
        let hash = BlakeTwo256::hash_of(&(&transaction.encode(), index));
        // validated before, this is safe
        index = index
            .checked_add(1)
            .ok_or(Error::<T>::MaximumTransactionDepth)
            .unwrap();
        Self::store_utxo(output, hash);
        // Optional, this event I used for log 
        Self::deposit_event(Event::TransactionOutputProcessed(hash));
    }

    Ok(())
}
}

Implement store_utxo for storage mutation

#![allow(unused)]
fn main() {
 fn store_utxo(utxo: &TransactionOutput, hash: H256) {
    // TODO [3-spend-utxo]
    UtxoStore::<T>::insert(hash, utxo);
    
    // further update 😉
}
}

Build the code

cargo build --release

Awesome work completing this step! 🚀 You're doing great. Now, let's advance to next step.

#![allow(unused)]
fn main() {
// We make sure this pallet uses `no_std` for compiling to Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_core::{
    sr25519::{Public, Signature},
    ByteArray, H256, H512,
};
use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

use super::{block_author::BlockAuthor, issuance::Issuance};

pub use pallet::*;

/// [2-data-structure]
pub type Value = u128;

/// [2-data-structure]
/// Single transaction to be dispatched
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct Transaction {
    /// UTXOs to be used as inputs for current transaction
    pub inputs: Vec<TransactionInput>,
    /// UTXOs to be created as a result of current transaction dispatch
    pub outputs: Vec<TransactionOutput>,
}

/// [2-data-structure]
/// Single transaction input that refers to one UTXO
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionInput {
    /// Reference to an UTXO to be spent
    pub outpoint: H256,

    /// Proof that transaction owner is authorized to spend referred UTXO &
    /// that the entire transaction is untampered
    pub sigscript: H512,
}

/// [2-data-structure]
/// Single transaction output to create upon transaction dispatch
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionOutput {
    /// Value associated with this output
    pub value: Value,

    /// Public key associated with this output. In order to spend this output
    /// owner must provide a proof by hashing the whole `Transaction` and
    /// signing it with a corresponding private key.
    pub pubkey: H256,
}

#[frame_support::pallet(dev_mode)]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    use super::*;

    /// [2-data-structure]
    #[pallet::config]
    pub trait Config: frame_system::Config {
        /// Because this pallet emits events, it depends on the runtime's definition of an event.
        /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
        type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

        /// A source to determine the block author
        type BlockAuthor: BlockAuthor;

        /// A source to determine the issuance portion of the block reward
        type Issuance: Issuance<BlockNumberFor<Self>, Value>;
    }

    #[pallet::pallet]
    pub struct Pallet<T>(_);


    /// [2-data-structure]
    /// Total reward value to be redistributed among authorities.
    /// It is accumulated from transactions during block execution
    /// and then dispersed to validators on block finalization.
    #[pallet::storage]
    #[pallet::getter(fn total_reward)]
    pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;

    /// [2-data-structure]
    /// All valid unspent transaction outputs are stored in this map.
    /// Initial set of UTXO is populated from the list stored in genesis.
    /// We use the identity hasher here because the cryptographic hashing is
    /// done explicitly.
    /// Mapping from `BlakeTwo256::hash_of(transaction, index)` to `TransactionOutput`
    #[pallet::storage]
    #[pallet::getter(fn utxo_store)]
    pub type UtxoStore<T: Config> = StorageMap<
        Hasher = Identity,
        Key = H256,
        Value = TransactionOutput,
        QueryKind = OptionQuery,
    >;


    /// [2-data-structure]
    /// Pallets use events to inform users when important changes are made.
    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        /// Dispatch transaction successful
        TransactionSuccess(Transaction),
        /// UTXO out processed
        TransactionOutputProcessed(H256),
        /// Reward distributed to `BlockAuthor`
        RewardDistributed(Value, H256),
        /// Faucet to `To`
        Faucet(Value, H256),
        /// No one get reward
        RewardWasted,
    }


    /// [2-data-structure]
    /// Errors inform users that something went wrong.
    #[pallet::error]
    pub enum Error<T> {
        /// Missing `Transaction` Input
        MissingInput,
        /// Reward overflow
        RewardOverflow,
        /// Maximum transaction depth
        MaximumTransactionDepth,
        /// Empty input
        EmptyInput,
        /// Empty output
        EmptyOutput,
        /// Each input must only be used once
        DuplicatedInput,
        /// Each output must be defined only once
        DuplicatedOutput,
        /// Input value is overflow
        InputOverflow,
        /// Output value is overflow
        OutputOverflow,
        /// Output spent must lte than Input spent
        OutputOverInput,
        /// Zero amount spent
        ZeroAmount,
        /// Invalid signature
        InvalidSignature,
    }


    /// [2-data-structure]
    /// Define extrinsics / dispatchable function
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
            // TODO remove this
            todo!()

            // TODO [3-spend-utxo]
            // validate transaction
            // let transaction_validity = Self::validate_transaction(&transaction)?;
            // ensure!(
            //     transaction_validity.requires.is_empty(),
            //     Error::<T>::MissingInput
            // );

            // // implement logic
            // Self::do_spend(&transaction, transaction_validity.priority as Value)?;
            // // emit event
            // Self::deposit_event(Event::<T>::TransactionSuccess(transaction));

            // Ok(())
        }
    }

    /// [2-data-structure]
    /// Define intrinsics
    impl<T: Config> Pallet<T> {
        /// Implement spend logic, update storage to reflect changes made by transaction
        /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
        fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
            // TODO remove this
            todo!();

            // TODO [3-spend-utxo]
            // Calculate new reward total. The rest of `total_input - total_output` will be used for block reward.
            // let new_total = TotalReward::<T>::get()
            //     .checked_add(reward)
            //     .ok_or(Error::<T>::RewardOverflow)?;
            // TotalReward::<T>::put(new_total);

            // // Removing spent UTXOs
            // for input in &transaction.inputs {
            //     UtxoStore::<T>::remove(input.outpoint);
            // }

            // let mut index: u64 = 0;
            // for output in &transaction.outputs {
            //     let hash = BlakeTwo256::hash_of(&(&transaction.encode(), index));
            //     // validated before, this is safe
            //     index = index
            //         .checked_add(1)
            //         .ok_or(Error::<T>::MaximumTransactionDepth)
            //         .unwrap();
            //     Self::store_utxo(output, hash);
            //     Self::deposit_event(Event::TransactionOutputProcessed(hash));
            // }

            // Ok(())
        }

        /// Redistribute combined reward value to block Author
        fn disperse_reward(author: &Public) {
            todo!();
        }

        /// Mutate storage, insert / update new UTXOs
        fn store_utxo(utxo: &TransactionOutput, hash: H256) {
            // TODO remove this
            todo!();

            // // TODO [3-spend-utxo]
            // UtxoStore::<T>::insert(hash, utxo);
            
            // // further update 😉
        }

        /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
        fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
            // TODO remove this
            todo!();

            // // TODO [3-spend-utxo]
            // let mut trx = transaction.clone();
            // for input in trx.inputs.iter_mut() {
            //     input.sigscript = H512::zero();
            // }

            // trx.encode()
        }

        /// Check transaction for validity, errors, & race conditions
        /// Called by both transaction pool and runtime execution
        pub fn validate_transaction(
            transaction: &Transaction,
        ) -> Result<ValidTransaction, &'static str> {
            // TODO remove this
            todo!();
            
            // TODO [3-spend-utxo]
            // // Check inputs and outputs are not empty
            // ensure!(!transaction.inputs.is_empty(), Error::<T>::EmptyInput);
            // ensure!(!transaction.outputs.is_empty(), Error::<T>::EmptyOutput);

            // // Check each input is used exactly once
            // {
            //     let input_set: BTreeMap<_, ()> =
            //         transaction.inputs.iter().map(|input| (input, ())).collect();
            //     ensure!(
            //         input_set.len() == transaction.inputs.len(),
            //         Error::<T>::DuplicatedInput
            //     );
            // }
            // {
            //     let output_set: BTreeMap<_, ()> = transaction
            //         .outputs
            //         .iter()
            //         .map(|output| (output, ()))
            //         .collect();
            //     ensure!(
            //         output_set.len() == transaction.outputs.len(),
            //         Error::<T>::DuplicatedOutput
            //     );
            // }

            // let mut total_input: Value = 0;
            // let mut total_output: Value = 0;
            // let mut output_index: u64 = 0;
            // let simple_transaction = Self::get_simple_transaction(transaction);

            // // Variables sent to transaction pool
            // let mut missing_utxos = Vec::new();
            // let mut new_utxos = Vec::new();
            // let mut reward = 0;

            // for input in transaction.inputs.iter() {
            //     // Check all inputs match to existing, unspent and unlocked outputs
            //     if let Some(input_utxo) = UtxoStore::<T>::get(&input.outpoint) {
            //         // Check provided signatures are valid
            //         let is_valid_sig = sp_io::crypto::sr25519_verify(
            //             &Signature::from_raw(*input.sigscript.as_fixed_bytes()),
            //             &simple_transaction,
            //             &Public::from_h256(input_utxo.pubkey),
            //         );
            //         ensure!(is_valid_sig, Error::<T>::InvalidSignature);
            //         // Check sum of input values does not overflow
            //         total_input = total_input
            //             .checked_add(input_utxo.value)
            //             .ok_or(Error::<T>::InputOverflow)?;
            //     } else {
            //         missing_utxos.push(input.outpoint.clone().as_fixed_bytes().to_vec());
            //     }
            // }

            // // Check each output is defined exactly once and has nonzero value
            // for output in transaction.outputs.iter() {
            //     ensure!(output.value > 0, Error::<T>::ZeroAmount);
            //     let hash = BlakeTwo256::hash_of(&(&transaction.encode(), output_index));
            //     output_index = output_index
            //         .checked_add(1)
            //         .ok_or(Error::<T>::MaximumTransactionDepth)?;
            //     // Check new outputs do not collide with existing ones
            //     ensure!(
            //         !UtxoStore::<T>::contains_key(hash),
            //         Error::<T>::DuplicatedOutput
            //     );
            //     // Check sum of output values does not overflow
            //     total_output = total_output
            //         .checked_add(output.value)
            //         .ok_or(Error::<T>::OutputOverflow)?;
            //     new_utxos.push(hash.as_fixed_bytes().to_vec());
            // }

            // // If no race condition, check the math
            // if missing_utxos.is_empty() {
            //     // Check total output value must not exceed total input value
            //     ensure!(total_input >= total_output, Error::<T>::OutputOverInput);
            //     reward = total_input
            //         .checked_sub(total_output)
            //         .ok_or(Error::<T>::RewardOverflow)?;
            // }

            // // Returns transaction details
            // Ok(ValidTransaction {
            //     requires: missing_utxos,
            //     provides: new_utxos,
            //     priority: reward as u64,
            //     longevity: TransactionLongevity::max_value(),
            //     propagate: true,
            // })
        }
    }
}
}
#![allow(unused)]
fn main() {
// We make sure this pallet uses `no_std` for compiling to Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_core::{
    sr25519::{Public, Signature},
    ByteArray, H256, H512,
};
use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

use super::{block_author::BlockAuthor, issuance::Issuance};

pub use pallet::*;

/// [2-data-structure]
pub type Value = u128;

/// [2-data-structure]
/// Single transaction to be dispatched
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct Transaction {
    /// UTXOs to be used as inputs for current transaction
    pub inputs: Vec<TransactionInput>,
    /// UTXOs to be created as a result of current transaction dispatch
    pub outputs: Vec<TransactionOutput>,
}

/// [2-data-structure]
/// Single transaction input that refers to one UTXO
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionInput {
    /// Reference to an UTXO to be spent
    pub outpoint: H256,

    /// Proof that transaction owner is authorized to spend referred UTXO &
    /// that the entire transaction is untampered
    pub sigscript: H512,
}

/// [2-data-structure]
/// Single transaction output to create upon transaction dispatch
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionOutput {
    /// Value associated with this output
    pub value: Value,

    /// Public key associated with this output. In order to spend this output
    /// owner must provide a proof by hashing the whole `Transaction` and
    /// signing it with a corresponding private key.
    pub pubkey: H256,
}

#[frame_support::pallet(dev_mode)]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    use super::*;

    /// [2-data-structure]
    #[pallet::config]
    pub trait Config: frame_system::Config {
        /// Because this pallet emits events, it depends on the runtime's definition of an event.
        /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
        type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

        /// A source to determine the block author
        type BlockAuthor: BlockAuthor;

        /// A source to determine the issuance portion of the block reward
        type Issuance: Issuance<BlockNumberFor<Self>, Value>;
    }

    #[pallet::pallet]
    pub struct Pallet<T>(_);


    /// [2-data-structure]
    /// Total reward value to be redistributed among authorities.
    /// It is accumulated from transactions during block execution
    /// and then dispersed to validators on block finalization.
    #[pallet::storage]
    #[pallet::getter(fn total_reward)]
    pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;

    /// [2-data-structure]
    /// All valid unspent transaction outputs are stored in this map.
    /// Initial set of UTXO is populated from the list stored in genesis.
    /// We use the identity hasher here because the cryptographic hashing is
    /// done explicitly.
    /// Mapping from `BlakeTwo256::hash_of(transaction, index)` to `TransactionOutput`
    #[pallet::storage]
    #[pallet::getter(fn utxo_store)]
    pub type UtxoStore<T: Config> = StorageMap<
        Hasher = Identity,
        Key = H256,
        Value = TransactionOutput,
        QueryKind = OptionQuery,
    >;


    /// [2-data-structure]
    /// Pallets use events to inform users when important changes are made.
    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        /// Dispatch transaction successful
        TransactionSuccess(Transaction),
        /// UTXO out processed
        TransactionOutputProcessed(H256),
        /// Reward distributed to `BlockAuthor`
        RewardDistributed(Value, H256),
        /// Faucet to `To`
        Faucet(Value, H256),
        /// No one get reward
        RewardWasted,
    }


    /// [2-data-structure]
    /// Errors inform users that something went wrong.
    #[pallet::error]
    pub enum Error<T> {
        /// Missing `Transaction` Input
        MissingInput,
        /// Reward overflow
        RewardOverflow,
        /// Maximum transaction depth
        MaximumTransactionDepth,
        /// Empty input
        EmptyInput,
        /// Empty output
        EmptyOutput,
        /// Each input must only be used once
        DuplicatedInput,
        /// Each output must be defined only once
        DuplicatedOutput,
        /// Input value is overflow
        InputOverflow,
        /// Output value is overflow
        OutputOverflow,
        /// Output spent must lte than Input spent
        OutputOverInput,
        /// Zero amount spent
        ZeroAmount,
        /// Invalid signature
        InvalidSignature,
    }


    /// [2-data-structure]
    /// Define extrinsics / dispatchable function
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
            // [3-spend-utxo]
            // validate transaction
            let transaction_validity = Self::validate_transaction(&transaction)?;
            ensure!(
                transaction_validity.requires.is_empty(),
                Error::<T>::MissingInput
            );

            // implement logic
            Self::do_spend(&transaction, transaction_validity.priority as Value)?;
            // emit event
            Self::deposit_event(Event::<T>::TransactionSuccess(transaction));

            Ok(())
        }
    }

    /// [2-data-structure]
    /// Define intrinsics
    impl<T: Config> Pallet<T> {
        /// Implement spend logic, update storage to reflect changes made by transaction
        /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
        fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
            // [3-spend-utxo]
            // Calculate new reward total. The rest of `total_input - total_output` will be used for block reward.
            let new_total = TotalReward::<T>::get()
                .checked_add(reward)
                .ok_or(Error::<T>::RewardOverflow)?;
            TotalReward::<T>::put(new_total);

            // Removing spent UTXOs
            for input in &transaction.inputs {
                UtxoStore::<T>::remove(input.outpoint);
            }

            let mut index: u64 = 0;
            for output in &transaction.outputs {
                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), index));
                // validated before, this is safe
                index = index
                    .checked_add(1)
                    .ok_or(Error::<T>::MaximumTransactionDepth)
                    .unwrap();
                Self::store_utxo(output, hash);
                Self::deposit_event(Event::TransactionOutputProcessed(hash));
            }

            Ok(())
        }

        /// Redistribute combined reward value to block Author
        fn disperse_reward(author: &Public) {
            todo!();
        }

        /// Mutate storage, insert / update new UTXOs
        fn store_utxo(utxo: &TransactionOutput, hash: H256) {
            // [3-spend-utxo]
            UtxoStore::<T>::insert(hash, utxo);
            
            // // further update 😉
        }

        /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
        fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
            // [3-spend-utxo]
            let mut trx = transaction.clone();
            for input in trx.inputs.iter_mut() {
                input.sigscript = H512::zero();
            }

            trx.encode()
        }

        /// Check transaction for validity, errors, & race conditions
        /// Called by both transaction pool and runtime execution
        pub fn validate_transaction(
            transaction: &Transaction,
        ) -> Result<ValidTransaction, &'static str> {
            // [3-spend-utxo]
            // Check inputs and outputs are not empty
            ensure!(!transaction.inputs.is_empty(), Error::<T>::EmptyInput);
            ensure!(!transaction.outputs.is_empty(), Error::<T>::EmptyOutput);

            // Check each input is used exactly once
            {
                let input_set: BTreeMap<_, ()> =
                    transaction.inputs.iter().map(|input| (input, ())).collect();
                ensure!(
                    input_set.len() == transaction.inputs.len(),
                    Error::<T>::DuplicatedInput
                );
            }
            {
                let output_set: BTreeMap<_, ()> = transaction
                    .outputs
                    .iter()
                    .map(|output| (output, ()))
                    .collect();
                ensure!(
                    output_set.len() == transaction.outputs.len(),
                    Error::<T>::DuplicatedOutput
                );
            }

            let mut total_input: Value = 0;
            let mut total_output: Value = 0;
            let mut output_index: u64 = 0;
            let simple_transaction = Self::get_simple_transaction(transaction);

            // Variables sent to transaction pool
            let mut missing_utxos = Vec::new();
            let mut new_utxos = Vec::new();
            let mut reward = 0;

            for input in transaction.inputs.iter() {
                // Check all inputs match to existing, unspent and unlocked outputs
                if let Some(input_utxo) = UtxoStore::<T>::get(&input.outpoint) {
                    // Check provided signatures are valid
                    let is_valid_sig = sp_io::crypto::sr25519_verify(
                        &Signature::from_raw(*input.sigscript.as_fixed_bytes()),
                        &simple_transaction,
                        &Public::from_h256(input_utxo.pubkey),
                    );
                    ensure!(is_valid_sig, Error::<T>::InvalidSignature);
                    // Check sum of input values does not overflow
                    total_input = total_input
                        .checked_add(input_utxo.value)
                        .ok_or(Error::<T>::InputOverflow)?;
                } else {
                    missing_utxos.push(input.outpoint.clone().as_fixed_bytes().to_vec());
                }
            }

            // Check each output is defined exactly once and has nonzero value
            for output in transaction.outputs.iter() {
                ensure!(output.value > 0, Error::<T>::ZeroAmount);
                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), output_index));
                output_index = output_index
                    .checked_add(1)
                    .ok_or(Error::<T>::MaximumTransactionDepth)?;
                // Check new outputs do not collide with existing ones
                ensure!(
                    !UtxoStore::<T>::contains_key(hash),
                    Error::<T>::DuplicatedOutput
                );
                // Check sum of output values does not overflow
                total_output = total_output
                    .checked_add(output.value)
                    .ok_or(Error::<T>::OutputOverflow)?;
                new_utxos.push(hash.as_fixed_bytes().to_vec());
            }

            // If no race condition, check the math
            if missing_utxos.is_empty() {
                // Check total output value must not exceed total input value
                ensure!(total_input >= total_output, Error::<T>::OutputOverInput);
                reward = total_input
                    .checked_sub(total_output)
                    .ok_or(Error::<T>::RewardOverflow)?;
            }

            // Returns transaction details
            Ok(ValidTransaction {
                requires: missing_utxos,
                provides: new_utxos,
                priority: reward as u64,
                longevity: TransactionLongevity::max_value(),
                propagate: true,
            })
        }
    }
}
}
diff --git a/runtime/src/utxo.rs b/runtime/src/utxo.rs
index 69a9535..a36637d 100644
--- a/runtime/src/utxo.rs
+++ b/runtime/src/utxo.rs
@@ -16,10 +16,10 @@ use super::{block_author::BlockAuthor, issuance::Issuance};
 
 pub use pallet::*;
 
-///  [2-data-structure]
+/// [2-data-structure]
 pub type Value = u128;
 
-///  [2-data-structure]
+/// [2-data-structure]
 /// Single transaction to be dispatched
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
@@ -30,7 +30,7 @@ pub struct Transaction {
     pub outputs: Vec<TransactionOutput>,
 }
 
-///  [2-data-structure]
+/// [2-data-structure]
 /// Single transaction input that refers to one UTXO
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
@@ -43,7 +43,7 @@ pub struct TransactionInput {
     pub sigscript: H512,
 }
 
-///  [2-data-structure]
+/// [2-data-structure]
 /// Single transaction output to create upon transaction dispatch
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 #[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
@@ -64,7 +64,7 @@ pub mod pallet {
 
     use super::*;
 
-    ///  [2-data-structure]
+    /// [2-data-structure]
     #[pallet::config]
     pub trait Config: frame_system::Config {
         /// Because this pallet emits events, it depends on the runtime's definition of an event.
@@ -72,9 +72,6 @@ pub mod pallet {
         type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
 
         /// A source to determine the block author
-        /// Read more: `runtime/src/block_author.rs`
-        /// Pallet loosely coupling
-        /// https://polkadot-blockchain-academy.github.io/pba-book/frame/coupling/page.html#loosely-coupled-pallets
         type BlockAuthor: BlockAuthor;
 
         /// A source to determine the issuance portion of the block reward
@@ -85,7 +82,7 @@ pub mod pallet {
     pub struct Pallet<T>(_);
 
 
-    ///  [2-data-structure]
+    /// [2-data-structure]
     /// Total reward value to be redistributed among authorities.
     /// It is accumulated from transactions during block execution
     /// and then dispersed to validators on block finalization.
@@ -93,7 +90,7 @@ pub mod pallet {
     #[pallet::getter(fn total_reward)]
     pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;
 
-    ///  [2-data-structure]
+    /// [2-data-structure]
     /// All valid unspent transaction outputs are stored in this map.
     /// Initial set of UTXO is populated from the list stored in genesis.
     /// We use the identity hasher here because the cryptographic hashing is
@@ -109,7 +106,7 @@ pub mod pallet {
     >;
 
 
-    ///  [2-data-structure]
+    /// [2-data-structure]
     /// Pallets use events to inform users when important changes are made.
     #[pallet::event]
     #[pallet::generate_deposit(pub(super) fn deposit_event)]
@@ -127,7 +124,7 @@ pub mod pallet {
     }
 
 
-    ///  [2-data-structure]
+    /// [2-data-structure]
     /// Errors inform users that something went wrong.
     #[pallet::error]
     pub enum Error<T> {
@@ -158,23 +155,65 @@ pub mod pallet {
     }
 
 
-    ///  [2-data-structure]
+    /// [2-data-structure]
     /// Define extrinsics / dispatchable function
     #[pallet::call]
     impl<T: Config> Pallet<T> {
         pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
-            todo!();
-        }
+            // TODO remove this
+            todo!()
+
+            // TODO [3-spend-utxo]
+            // validate transaction
+            // let transaction_validity = Self::validate_transaction(&transaction)?;
+            // ensure!(
+            //     transaction_validity.requires.is_empty(),
+            //     Error::<T>::MissingInput
+            // );
 
+            // // implement logic
+            // Self::do_spend(&transaction, transaction_validity.priority as Value)?;
+            // // emit event
+            // Self::deposit_event(Event::<T>::TransactionSuccess(transaction));
+
+            // Ok(())
+        }
     }
 
-    ///  [2-data-structure]
+    /// [2-data-structure]
     /// Define intrinsics
     impl<T: Config> Pallet<T> {
         /// Implement spend logic, update storage to reflect changes made by transaction
         /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
         fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
+            // TODO remove this
             todo!();
+
+            // TODO [3-spend-utxo]
+            // Calculate new reward total. The rest of `total_input - total_output` will be used for block reward.
+            // let new_total = TotalReward::<T>::get()
+            //     .checked_add(reward)
+            //     .ok_or(Error::<T>::RewardOverflow)?;
+            // TotalReward::<T>::put(new_total);
+
+            // // Removing spent UTXOs
+            // for input in &transaction.inputs {
+            //     UtxoStore::<T>::remove(input.outpoint);
+            // }
+
+            // let mut index: u64 = 0;
+            // for output in &transaction.outputs {
+            //     let hash = BlakeTwo256::hash_of(&(&transaction.encode(), index));
+            //     // validated before, this is safe
+            //     index = index
+            //         .checked_add(1)
+            //         .ok_or(Error::<T>::MaximumTransactionDepth)
+            //         .unwrap();
+            //     Self::store_utxo(output, hash);
+            //     Self::deposit_event(Event::TransactionOutputProcessed(hash));
+            // }
+
+            // Ok(())
         }
 
         /// Redistribute combined reward value to block Author
@@ -184,12 +223,27 @@ pub mod pallet {
 
         /// Mutate storage, insert / update new UTXOs
         fn store_utxo(utxo: &TransactionOutput, hash: H256) {
+            // TODO remove this
             todo!();
+
+            // // TODO [3-spend-utxo]
+            // UtxoStore::<T>::insert(hash, utxo);
+            
+            // // further update 😉
         }
 
         /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
         fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
+            // TODO remove this
             todo!();
+
+            // // TODO [3-spend-utxo]
+            // let mut trx = transaction.clone();
+            // for input in trx.inputs.iter_mut() {
+            //     input.sigscript = H512::zero();
+            // }
+
+            // trx.encode()
         }
 
         /// Check transaction for validity, errors, & race conditions
@@ -197,7 +251,100 @@ pub mod pallet {
         pub fn validate_transaction(
             transaction: &Transaction,
         ) -> Result<ValidTransaction, &'static str> {
+            // TODO remove this
             todo!();
+            
+            // TODO [3-spend-utxo]
+            // // Check inputs and outputs are not empty
+            // ensure!(!transaction.inputs.is_empty(), Error::<T>::EmptyInput);
+            // ensure!(!transaction.outputs.is_empty(), Error::<T>::EmptyOutput);
+
+            // // Check each input is used exactly once
+            // {
+            //     let input_set: BTreeMap<_, ()> =
+            //         transaction.inputs.iter().map(|input| (input, ())).collect();
+            //     ensure!(
+            //         input_set.len() == transaction.inputs.len(),
+            //         Error::<T>::DuplicatedInput
+            //     );
+            // }
+            // {
+            //     let output_set: BTreeMap<_, ()> = transaction
+            //         .outputs
+            //         .iter()
+            //         .map(|output| (output, ()))
+            //         .collect();
+            //     ensure!(
+            //         output_set.len() == transaction.outputs.len(),
+            //         Error::<T>::DuplicatedOutput
+            //     );
+            // }
+
+            // let mut total_input: Value = 0;
+            // let mut total_output: Value = 0;
+            // let mut output_index: u64 = 0;
+            // let simple_transaction = Self::get_simple_transaction(transaction);
+
+            // // Variables sent to transaction pool
+            // let mut missing_utxos = Vec::new();
+            // let mut new_utxos = Vec::new();
+            // let mut reward = 0;
+
+            // for input in transaction.inputs.iter() {
+            //     // Check all inputs match to existing, unspent and unlocked outputs
+            //     if let Some(input_utxo) = UtxoStore::<T>::get(&input.outpoint) {
+            //         // Check provided signatures are valid
+            //         let is_valid_sig = sp_io::crypto::sr25519_verify(
+            //             &Signature::from_raw(*input.sigscript.as_fixed_bytes()),
+            //             &simple_transaction,
+            //             &Public::from_h256(input_utxo.pubkey),
+            //         );
+            //         ensure!(is_valid_sig, Error::<T>::InvalidSignature);
+            //         // Check sum of input values does not overflow
+            //         total_input = total_input
+            //             .checked_add(input_utxo.value)
+            //             .ok_or(Error::<T>::InputOverflow)?;
+            //     } else {
+            //         missing_utxos.push(input.outpoint.clone().as_fixed_bytes().to_vec());
+            //     }
+            // }
+
+            // // Check each output is defined exactly once and has nonzero value
+            // for output in transaction.outputs.iter() {
+            //     ensure!(output.value > 0, Error::<T>::ZeroAmount);
+            //     let hash = BlakeTwo256::hash_of(&(&transaction.encode(), output_index));
+            //     output_index = output_index
+            //         .checked_add(1)
+            //         .ok_or(Error::<T>::MaximumTransactionDepth)?;
+            //     // Check new outputs do not collide with existing ones
+            //     ensure!(
+            //         !UtxoStore::<T>::contains_key(hash),
+            //         Error::<T>::DuplicatedOutput
+            //     );
+            //     // Check sum of output values does not overflow
+            //     total_output = total_output
+            //         .checked_add(output.value)
+            //         .ok_or(Error::<T>::OutputOverflow)?;
+            //     new_utxos.push(hash.as_fixed_bytes().to_vec());
+            // }
+
+            // // If no race condition, check the math
+            // if missing_utxos.is_empty() {
+            //     // Check total output value must not exceed total input value
+            //     ensure!(total_input >= total_output, Error::<T>::OutputOverInput);
+            //     reward = total_input
+            //         .checked_sub(total_output)
+            //         .ok_or(Error::<T>::RewardOverflow)?;
+            // }
+
+            // // Returns transaction details
+            // Ok(ValidTransaction {
+            //     requires: missing_utxos,
+            //     provides: new_utxos,
+            //     priority: reward as u64,
+            //     longevity: TransactionLongevity::max_value(),
+            //     propagate: true,
+            // })
         }
     }
 }
\ No newline at end of file
diff --git a/runtime/src/utxo.rs b/runtime/src/utxo.rs
index a36637d..00433df 100644
--- a/runtime/src/utxo.rs
+++ b/runtime/src/utxo.rs
@@ -160,23 +160,20 @@ pub mod pallet {
     #[pallet::call]
     impl<T: Config> Pallet<T> {
         pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
-            // TODO remove this
-            todo!()
-
-            // TODO [3-spend-utxo]
+            // [3-spend-utxo]
             // validate transaction
-            // let transaction_validity = Self::validate_transaction(&transaction)?;
-            // ensure!(
-            //     transaction_validity.requires.is_empty(),
-            //     Error::<T>::MissingInput
-            // );
-
-            // // implement logic
-            // Self::do_spend(&transaction, transaction_validity.priority as Value)?;
-            // // emit event
-            // Self::deposit_event(Event::<T>::TransactionSuccess(transaction));
-
-            // Ok(())
+            let transaction_validity = Self::validate_transaction(&transaction)?;
+            ensure!(
+                transaction_validity.requires.is_empty(),
+                Error::<T>::MissingInput
+            );
+
+            // implement logic
+            Self::do_spend(&transaction, transaction_validity.priority as Value)?;
+            // emit event
+            Self::deposit_event(Event::<T>::TransactionSuccess(transaction));
+
+            Ok(())
         }
     }
 
@@ -186,34 +183,31 @@ pub mod pallet {
         /// Implement spend logic, update storage to reflect changes made by transaction
         /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
         fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
-            // TODO remove this
-            todo!();
-
-            // TODO [3-spend-utxo]
+            // [3-spend-utxo]
             // Calculate new reward total. The rest of `total_input - total_output` will be used for block reward.
-            // let new_total = TotalReward::<T>::get()
-            //     .checked_add(reward)
-            //     .ok_or(Error::<T>::RewardOverflow)?;
-            // TotalReward::<T>::put(new_total);
-
-            // // Removing spent UTXOs
-            // for input in &transaction.inputs {
-            //     UtxoStore::<T>::remove(input.outpoint);
-            // }
-
-            // let mut index: u64 = 0;
-            // for output in &transaction.outputs {
-            //     let hash = BlakeTwo256::hash_of(&(&transaction.encode(), index));
-            //     // validated before, this is safe
-            //     index = index
-            //         .checked_add(1)
-            //         .ok_or(Error::<T>::MaximumTransactionDepth)
-            //         .unwrap();
-            //     Self::store_utxo(output, hash);
-            //     Self::deposit_event(Event::TransactionOutputProcessed(hash));
-            // }
-
-            // Ok(())
+            let new_total = TotalReward::<T>::get()
+                .checked_add(reward)
+                .ok_or(Error::<T>::RewardOverflow)?;
+            TotalReward::<T>::put(new_total);
+
+            // Removing spent UTXOs
+            for input in &transaction.inputs {
+                UtxoStore::<T>::remove(input.outpoint);
+            }
+
+            let mut index: u64 = 0;
+            for output in &transaction.outputs {
+                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), index));
+                // validated before, this is safe
+                index = index
+                    .checked_add(1)
+                    .ok_or(Error::<T>::MaximumTransactionDepth)
+                    .unwrap();
+                Self::store_utxo(output, hash);
+                Self::deposit_event(Event::TransactionOutputProcessed(hash));
+            }
+
+            Ok(())
         }
 
         /// Redistribute combined reward value to block Author
@@ -223,27 +217,21 @@ pub mod pallet {
 
         /// Mutate storage, insert / update new UTXOs
         fn store_utxo(utxo: &TransactionOutput, hash: H256) {
-            // TODO remove this
-            todo!();
-
-            // // TODO [3-spend-utxo]
-            // UtxoStore::<T>::insert(hash, utxo);
+            // [3-spend-utxo]
+            UtxoStore::<T>::insert(hash, utxo);
             
             // // further update 😉
         }
 
         /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
         fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
-            // TODO remove this
-            todo!();
-
-            // // TODO [3-spend-utxo]
-            // let mut trx = transaction.clone();
-            // for input in trx.inputs.iter_mut() {
-            //     input.sigscript = H512::zero();
-            // }
+            // [3-spend-utxo]
+            let mut trx = transaction.clone();
+            for input in trx.inputs.iter_mut() {
+                input.sigscript = H512::zero();
+            }
 
-            // trx.encode()
+            trx.encode()
         }
 
         /// Check transaction for validity, errors, & race conditions
@@ -251,100 +239,97 @@ pub mod pallet {
         pub fn validate_transaction(
             transaction: &Transaction,
         ) -> Result<ValidTransaction, &'static str> {
-            // TODO remove this
-            todo!();
-            
-            // TODO [3-spend-utxo]
-            // // Check inputs and outputs are not empty
-            // ensure!(!transaction.inputs.is_empty(), Error::<T>::EmptyInput);
-            // ensure!(!transaction.outputs.is_empty(), Error::<T>::EmptyOutput);
-
-            // // Check each input is used exactly once
-            // {
-            //     let input_set: BTreeMap<_, ()> =
-            //         transaction.inputs.iter().map(|input| (input, ())).collect();
-            //     ensure!(
-            //         input_set.len() == transaction.inputs.len(),
-            //         Error::<T>::DuplicatedInput
-            //     );
-            // }
-            // {
-            //     let output_set: BTreeMap<_, ()> = transaction
-            //         .outputs
-            //         .iter()
-            //         .map(|output| (output, ()))
-            //         .collect();
-            //     ensure!(
-            //         output_set.len() == transaction.outputs.len(),
-            //         Error::<T>::DuplicatedOutput
-            //     );
-            // }
-
-            // let mut total_input: Value = 0;
-            // let mut total_output: Value = 0;
-            // let mut output_index: u64 = 0;
-            // let simple_transaction = Self::get_simple_transaction(transaction);
-
-            // // Variables sent to transaction pool
-            // let mut missing_utxos = Vec::new();
-            // let mut new_utxos = Vec::new();
-            // let mut reward = 0;
-
-            // for input in transaction.inputs.iter() {
-            //     // Check all inputs match to existing, unspent and unlocked outputs
-            //     if let Some(input_utxo) = UtxoStore::<T>::get(&input.outpoint) {
-            //         // Check provided signatures are valid
-            //         let is_valid_sig = sp_io::crypto::sr25519_verify(
-            //             &Signature::from_raw(*input.sigscript.as_fixed_bytes()),
-            //             &simple_transaction,
-            //             &Public::from_h256(input_utxo.pubkey),
-            //         );
-            //         ensure!(is_valid_sig, Error::<T>::InvalidSignature);
-            //         // Check sum of input values does not overflow
-            //         total_input = total_input
-            //             .checked_add(input_utxo.value)
-            //             .ok_or(Error::<T>::InputOverflow)?;
-            //     } else {
-            //         missing_utxos.push(input.outpoint.clone().as_fixed_bytes().to_vec());
-            //     }
-            // }
-
-            // // Check each output is defined exactly once and has nonzero value
-            // for output in transaction.outputs.iter() {
-            //     ensure!(output.value > 0, Error::<T>::ZeroAmount);
-            //     let hash = BlakeTwo256::hash_of(&(&transaction.encode(), output_index));
-            //     output_index = output_index
-            //         .checked_add(1)
-            //         .ok_or(Error::<T>::MaximumTransactionDepth)?;
-            //     // Check new outputs do not collide with existing ones
-            //     ensure!(
-            //         !UtxoStore::<T>::contains_key(hash),
-            //         Error::<T>::DuplicatedOutput
-            //     );
-            //     // Check sum of output values does not overflow
-            //     total_output = total_output
-            //         .checked_add(output.value)
-            //         .ok_or(Error::<T>::OutputOverflow)?;
-            //     new_utxos.push(hash.as_fixed_bytes().to_vec());
-            // }
-
-            // // If no race condition, check the math
-            // if missing_utxos.is_empty() {
-            //     // Check total output value must not exceed total input value
-            //     ensure!(total_input >= total_output, Error::<T>::OutputOverInput);
-            //     reward = total_input
-            //         .checked_sub(total_output)
-            //         .ok_or(Error::<T>::RewardOverflow)?;
-            // }
-
-            // // Returns transaction details
-            // Ok(ValidTransaction {
-            //     requires: missing_utxos,
-            //     provides: new_utxos,
-            //     priority: reward as u64,
-            //     longevity: TransactionLongevity::max_value(),
-            //     propagate: true,
-            // })
+            // [3-spend-utxo]
+            // Check inputs and outputs are not empty
+            ensure!(!transaction.inputs.is_empty(), Error::<T>::EmptyInput);
+            ensure!(!transaction.outputs.is_empty(), Error::<T>::EmptyOutput);
+
+            // Check each input is used exactly once
+            {
+                let input_set: BTreeMap<_, ()> =
+                    transaction.inputs.iter().map(|input| (input, ())).collect();
+                ensure!(
+                    input_set.len() == transaction.inputs.len(),
+                    Error::<T>::DuplicatedInput
+                );
+            }
+            {
+                let output_set: BTreeMap<_, ()> = transaction
+                    .outputs
+                    .iter()
+                    .map(|output| (output, ()))
+                    .collect();
+                ensure!(
+                    output_set.len() == transaction.outputs.len(),
+                    Error::<T>::DuplicatedOutput
+                );
+            }
+
+            let mut total_input: Value = 0;
+            let mut total_output: Value = 0;
+            let mut output_index: u64 = 0;
+            let simple_transaction = Self::get_simple_transaction(transaction);
+
+            // Variables sent to transaction pool
+            let mut missing_utxos = Vec::new();
+            let mut new_utxos = Vec::new();
+            let mut reward = 0;
+
+            for input in transaction.inputs.iter() {
+                // Check all inputs match to existing, unspent and unlocked outputs
+                if let Some(input_utxo) = UtxoStore::<T>::get(&input.outpoint) {
+                    // Check provided signatures are valid
+                    let is_valid_sig = sp_io::crypto::sr25519_verify(
+                        &Signature::from_raw(*input.sigscript.as_fixed_bytes()),
+                        &simple_transaction,
+                        &Public::from_h256(input_utxo.pubkey),
+                    );
+                    ensure!(is_valid_sig, Error::<T>::InvalidSignature);
+                    // Check sum of input values does not overflow
+                    total_input = total_input
+                        .checked_add(input_utxo.value)
+                        .ok_or(Error::<T>::InputOverflow)?;
+                } else {
+                    missing_utxos.push(input.outpoint.clone().as_fixed_bytes().to_vec());
+                }
+            }
+
+            // Check each output is defined exactly once and has nonzero value
+            for output in transaction.outputs.iter() {
+                ensure!(output.value > 0, Error::<T>::ZeroAmount);
+                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), output_index));
+                output_index = output_index
+                    .checked_add(1)
+                    .ok_or(Error::<T>::MaximumTransactionDepth)?;
+                // Check new outputs do not collide with existing ones
+                ensure!(
+                    !UtxoStore::<T>::contains_key(hash),
+                    Error::<T>::DuplicatedOutput
+                );
+                // Check sum of output values does not overflow
+                total_output = total_output
+                    .checked_add(output.value)
+                    .ok_or(Error::<T>::OutputOverflow)?;
+                new_utxos.push(hash.as_fixed_bytes().to_vec());
+            }
+
+            // If no race condition, check the math
+            if missing_utxos.is_empty() {
+                // Check total output value must not exceed total input value
+                ensure!(total_input >= total_output, Error::<T>::OutputOverInput);
+                reward = total_input
+                    .checked_sub(total_output)
+                    .ok_or(Error::<T>::RewardOverflow)?;
+            }
+
+            // Returns transaction details
+            Ok(ValidTransaction {
+                requires: missing_utxos,
+                provides: new_utxos,
+                priority: reward as u64,
+                longevity: TransactionLongevity::max_value(),
+                propagate: true,
+            })
         }
     }
 }
\ No newline at end of file

Disperse Reward

[!Note] Resolve all TODO in runtime/src/utxo.rs to complete this step.

Reading Materials

The block reward is a combination of the block subsidy and all transaction fees paid by transactions in a specific block. When miners mine a block, they receive a block subsidy in the form of newly minted bitcoin. All transactions also include a fee, which miners collect. The block reward is the sum of these two amounts. As block subsidies are cut in half every four years, fees will slowly become a greater portion of the block reward. The term block reward and block subsidy are occasionally used interchangeably.

The block reward is paid out in the blockchain transaction of each block. This special transaction is the first transaction in every block, and it has no inputs.

So the problem in this step is that we've to distribute the block reward to the miners who successfully solve the puzzle to mine new blocks.

Before go to this tutorial, please read these documents to understand transaction lifecycle in Substrate:

graph LR
    subgraph AfterTransactions
    direction LR
        OnIdle --> OnFinalize
    end

    subgraph OnChain
    direction LR
        Optional --> BeforeExtrinsics
        BeforeExtrinsics --> Inherents
        Inherents --> Poll
        Poll --> Transactions
        Transactions --> AfterTransactions
    end

    subgraph Optional
        OnRuntimeUpgrade
    end


    subgraph BeforeExtrinsics
        OnInitialize
    end

    subgraph Transactions
        Transaction1 --> UnsignedTransaction2 --> Transaction3
    end

    subgraph Inherents
        Inherent1 --> Inherent2
    end

Implement

To disperse block reward to block author, we'll use on_finalize hook.

To implement the Hooks trait provides logic that is executed at the end of each block.

  • Start with #[pallet::hooks] macro.
  • Implements the Hooks trait for the pallet. This trait is generic over the BlockNumberFor<T>, which represents the type of block number defined in the runtime configuration.
  • fn on_finalize(_n: BlockNumberFor<T>): This function is triggered automatically at the end of each block.
#![allow(unused)]
fn main() {
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
    fn on_finalize(_n: BlockNumberFor<T>) {
        match T::BlockAuthor::block_author() {
            // Block author did not provide key to claim reward
            None => Self::deposit_event(Event::RewardWasted),
            // Block author did provide key, so issue thir reward
            Some(author) => Self::disperse_reward(&author),
        }
    }
}
}

Implement logic of function disperse_reward

#![allow(unused)]
fn main() {
/// Redistribute combined reward value to block Author
fn disperse_reward(author: &Public) {
    // take the cumulative reward in storage
    // plus issuance of blocknumber
    let reward = TotalReward::<T>::take()
        + T::Issuance::issuance(frame_system::Pallet::<T>::block_number());

    // create new UTXO
    let utxo = TransactionOutput {
        value: reward,
        pubkey: H256::from_slice(author.as_slice()),
    };

    // hash UTXO to get the key
    let hash = BlakeTwo256::hash_of(&(
        &utxo,
        frame_system::Pallet::<T>::block_number().saturated_into::<u64>(),
    ));

    // mutate storage
    Self::store_utxo(&utxo, hash);
    
    // emit event `RewardDistributed`
    Self::deposit_event(Event::RewardDistributed(reward, hash));
}
}

Build the code

cargo build --release

Fantastic job completing a new step! 🌟 You're almost there. Let's move forward to next step.

#![allow(unused)]
fn main() {
// We make sure this pallet uses `no_std` for compiling to Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_core::{
    sr25519::{Public, Signature},
    ByteArray, H256, H512,
};
use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

use super::{block_author::BlockAuthor, issuance::Issuance};

pub use pallet::*;

/// [2-data-structure]
pub type Value = u128;

/// [2-data-structure]
/// Single transaction to be dispatched
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct Transaction {
    /// UTXOs to be used as inputs for current transaction
    pub inputs: Vec<TransactionInput>,
    /// UTXOs to be created as a result of current transaction dispatch
    pub outputs: Vec<TransactionOutput>,
}

/// [2-data-structure]
/// Single transaction input that refers to one UTXO
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionInput {
    /// Reference to an UTXO to be spent
    pub outpoint: H256,

    /// Proof that transaction owner is authorized to spend referred UTXO &
    /// that the entire transaction is untampered
    pub sigscript: H512,
}

/// [2-data-structure]
/// Single transaction output to create upon transaction dispatch
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionOutput {
    /// Value associated with this output
    pub value: Value,

    /// Public key associated with this output. In order to spend this output
    /// owner must provide a proof by hashing the whole `Transaction` and
    /// signing it with a corresponding private key.
    pub pubkey: H256,
}

#[frame_support::pallet(dev_mode)]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    use super::*;

    /// [2-data-structure]
    #[pallet::config]
    pub trait Config: frame_system::Config {
        /// Because this pallet emits events, it depends on the runtime's definition of an event.
        /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
        type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

        /// A source to determine the block author
        type BlockAuthor: BlockAuthor;

        /// A source to determine the issuance portion of the block reward
        type Issuance: Issuance<BlockNumberFor<Self>, Value>;
    }

    #[pallet::pallet]
    pub struct Pallet<T>(_);


    /// [2-data-structure]
    /// Total reward value to be redistributed among authorities.
    /// It is accumulated from transactions during block execution
    /// and then dispersed to validators on block finalization.
    #[pallet::storage]
    #[pallet::getter(fn total_reward)]
    pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;

    /// [2-data-structure]
    /// All valid unspent transaction outputs are stored in this map.
    /// Initial set of UTXO is populated from the list stored in genesis.
    /// We use the identity hasher here because the cryptographic hashing is
    /// done explicitly.
    /// Mapping from `BlakeTwo256::hash_of(transaction, index)` to `TransactionOutput`
    #[pallet::storage]
    #[pallet::getter(fn utxo_store)]
    pub type UtxoStore<T: Config> = StorageMap<
        Hasher = Identity,
        Key = H256,
        Value = TransactionOutput,
        QueryKind = OptionQuery,
    >;


    /// [2-data-structure]
    /// Pallets use events to inform users when important changes are made.
    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        /// Dispatch transaction successful
        TransactionSuccess(Transaction),
        /// UTXO out processed
        TransactionOutputProcessed(H256),
        /// Reward distributed to `BlockAuthor`
        RewardDistributed(Value, H256),
        /// Faucet to `To`
        Faucet(Value, H256),
        /// No one get reward
        RewardWasted,
    }


    /// [2-data-structure]
    /// Errors inform users that something went wrong.
    #[pallet::error]
    pub enum Error<T> {
        /// Missing `Transaction` Input
        MissingInput,
        /// Reward overflow
        RewardOverflow,
        /// Maximum transaction depth
        MaximumTransactionDepth,
        /// Empty input
        EmptyInput,
        /// Empty output
        EmptyOutput,
        /// Each input must only be used once
        DuplicatedInput,
        /// Each output must be defined only once
        DuplicatedOutput,
        /// Input value is overflow
        InputOverflow,
        /// Output value is overflow
        OutputOverflow,
        /// Output spent must lte than Input spent
        OutputOverInput,
        /// Zero amount spent
        ZeroAmount,
        /// Invalid signature
        InvalidSignature,
    }

    /// TODO [4-dispersed-reward]
    // #[pallet::hooks]
    // impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
    //     fn on_finalize(_n: BlockNumberFor<T>) {
    //         match T::BlockAuthor::block_author() {
    //             // Block author did not provide key to claim reward
    //             None => Self::deposit_event(Event::RewardWasted),
    //             // Block author did provide key, so issue thir reward
    //             Some(author) => Self::disperse_reward(&author),
    //         }
    //     }
    // }

    /// [2-data-structure]
    /// Define extrinsics / dispatchable function
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
            // [3-spend-utxo]
            // validate transaction
            let transaction_validity = Self::validate_transaction(&transaction)?;
            ensure!(
                transaction_validity.requires.is_empty(),
                Error::<T>::MissingInput
            );

            // implement logic
            Self::do_spend(&transaction, transaction_validity.priority as Value)?;
            // emit event
            Self::deposit_event(Event::<T>::TransactionSuccess(transaction));

            Ok(())
        }
    }

    /// [2-data-structure]
    /// Define intrinsics
    impl<T: Config> Pallet<T> {
        /// Implement spend logic, update storage to reflect changes made by transaction
        /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
        fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
            // [3-spend-utxo]
            // Calculate new reward total. The rest of `total_input - total_output` will be used for block reward.
            let new_total = TotalReward::<T>::get()
                .checked_add(reward)
                .ok_or(Error::<T>::RewardOverflow)?;
            TotalReward::<T>::put(new_total);

            // Removing spent UTXOs
            for input in &transaction.inputs {
                UtxoStore::<T>::remove(input.outpoint);
            }

            let mut index: u64 = 0;
            for output in &transaction.outputs {
                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), index));
                // validated before, this is safe
                index = index
                    .checked_add(1)
                    .ok_or(Error::<T>::MaximumTransactionDepth)
                    .unwrap();
                Self::store_utxo(output, hash);
                Self::deposit_event(Event::TransactionOutputProcessed(hash));
            }

            Ok(())
        }

        /// Redistribute combined reward value to block Author
        fn disperse_reward(author: &Public) {
            // TODO remove this
            todo!();

            // TODO [4-dispersed-reward]

            // take the rest of reward
            // plus issuance reward of current block number
            // let reward = TotalReward::<T>::take()
            // + T::Issuance::issuance(frame_system::Pallet::<T>::block_number());

            // let utxo = TransactionOutput {
            //     value: reward,
            //     pubkey: H256::from_slice(author.as_slice()),
            // };

            // let hash = BlakeTwo256::hash_of(&(
            //     &utxo,
            //     frame_system::Pallet::<T>::block_number().saturated_into::<u64>(),
            // ));

            // Self::store_utxo(&utxo, hash);
            // Self::deposit_event(Event::RewardDistributed(reward, hash));  
        }

        /// Mutate storage, insert / update new UTXOs
        fn store_utxo(utxo: &TransactionOutput, hash: H256) {
            // [3-spend-utxo]
            UtxoStore::<T>::insert(hash, utxo);
            
            // // further update 😉
        }

        /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
        fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
            // [3-spend-utxo]
            let mut trx = transaction.clone();
            for input in trx.inputs.iter_mut() {
                input.sigscript = H512::zero();
            }

            trx.encode()
        }

        /// Check transaction for validity, errors, & race conditions
        /// Called by both transaction pool and runtime execution
        pub fn validate_transaction(
            transaction: &Transaction,
        ) -> Result<ValidTransaction, &'static str> {
            // [3-spend-utxo]
            // Check inputs and outputs are not empty
            ensure!(!transaction.inputs.is_empty(), Error::<T>::EmptyInput);
            ensure!(!transaction.outputs.is_empty(), Error::<T>::EmptyOutput);

            // Check each input is used exactly once
            {
                let input_set: BTreeMap<_, ()> =
                    transaction.inputs.iter().map(|input| (input, ())).collect();
                ensure!(
                    input_set.len() == transaction.inputs.len(),
                    Error::<T>::DuplicatedInput
                );
            }
            {
                let output_set: BTreeMap<_, ()> = transaction
                    .outputs
                    .iter()
                    .map(|output| (output, ()))
                    .collect();
                ensure!(
                    output_set.len() == transaction.outputs.len(),
                    Error::<T>::DuplicatedOutput
                );
            }

            let mut total_input: Value = 0;
            let mut total_output: Value = 0;
            let mut output_index: u64 = 0;
            let simple_transaction = Self::get_simple_transaction(transaction);

            // Variables sent to transaction pool
            let mut missing_utxos = Vec::new();
            let mut new_utxos = Vec::new();
            let mut reward = 0;

            for input in transaction.inputs.iter() {
                // Check all inputs match to existing, unspent and unlocked outputs
                if let Some(input_utxo) = UtxoStore::<T>::get(&input.outpoint) {
                    // Check provided signatures are valid
                    let is_valid_sig = sp_io::crypto::sr25519_verify(
                        &Signature::from_raw(*input.sigscript.as_fixed_bytes()),
                        &simple_transaction,
                        &Public::from_h256(input_utxo.pubkey),
                    );
                    ensure!(is_valid_sig, Error::<T>::InvalidSignature);
                    // Check sum of input values does not overflow
                    total_input = total_input
                        .checked_add(input_utxo.value)
                        .ok_or(Error::<T>::InputOverflow)?;
                } else {
                    missing_utxos.push(input.outpoint.clone().as_fixed_bytes().to_vec());
                }
            }

            // Check each output is defined exactly once and has nonzero value
            for output in transaction.outputs.iter() {
                ensure!(output.value > 0, Error::<T>::ZeroAmount);
                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), output_index));
                output_index = output_index
                    .checked_add(1)
                    .ok_or(Error::<T>::MaximumTransactionDepth)?;
                // Check new outputs do not collide with existing ones
                ensure!(
                    !UtxoStore::<T>::contains_key(hash),
                    Error::<T>::DuplicatedOutput
                );
                // Check sum of output values does not overflow
                total_output = total_output
                    .checked_add(output.value)
                    .ok_or(Error::<T>::OutputOverflow)?;
                new_utxos.push(hash.as_fixed_bytes().to_vec());
            }

            // If no race condition, check the math
            if missing_utxos.is_empty() {
                // Check total output value must not exceed total input value
                ensure!(total_input >= total_output, Error::<T>::OutputOverInput);
                reward = total_input
                    .checked_sub(total_output)
                    .ok_or(Error::<T>::RewardOverflow)?;
            }

            // Returns transaction details
            Ok(ValidTransaction {
                requires: missing_utxos,
                provides: new_utxos,
                priority: reward as u64,
                longevity: TransactionLongevity::max_value(),
                propagate: true,
            })
        }
    }
}
}
#![allow(unused)]
fn main() {
// We make sure this pallet uses `no_std` for compiling to Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_core::{
    sr25519::{Public, Signature},
    ByteArray, H256, H512,
};
use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

use super::{block_author::BlockAuthor, issuance::Issuance};

pub use pallet::*;

/// [2-data-structure]
pub type Value = u128;

/// [2-data-structure]
/// Single transaction to be dispatched
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct Transaction {
    /// UTXOs to be used as inputs for current transaction
    pub inputs: Vec<TransactionInput>,
    /// UTXOs to be created as a result of current transaction dispatch
    pub outputs: Vec<TransactionOutput>,
}

/// [2-data-structure]
/// Single transaction input that refers to one UTXO
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionInput {
    /// Reference to an UTXO to be spent
    pub outpoint: H256,

    /// Proof that transaction owner is authorized to spend referred UTXO &
    /// that the entire transaction is untampered
    pub sigscript: H512,
}

/// [2-data-structure]
/// Single transaction output to create upon transaction dispatch
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionOutput {
    /// Value associated with this output
    pub value: Value,

    /// Public key associated with this output. In order to spend this output
    /// owner must provide a proof by hashing the whole `Transaction` and
    /// signing it with a corresponding private key.
    pub pubkey: H256,
}

#[frame_support::pallet(dev_mode)]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    use super::*;

    /// [2-data-structure]
    #[pallet::config]
    pub trait Config: frame_system::Config {
        /// Because this pallet emits events, it depends on the runtime's definition of an event.
        /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
        type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

        /// A source to determine the block author
        type BlockAuthor: BlockAuthor;

        /// A source to determine the issuance portion of the block reward
        type Issuance: Issuance<BlockNumberFor<Self>, Value>;
    }

    #[pallet::pallet]
    pub struct Pallet<T>(_);


    /// [2-data-structure]
    /// Total reward value to be redistributed among authorities.
    /// It is accumulated from transactions during block execution
    /// and then dispersed to validators on block finalization.
    #[pallet::storage]
    #[pallet::getter(fn total_reward)]
    pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;

    /// [2-data-structure]
    /// All valid unspent transaction outputs are stored in this map.
    /// Initial set of UTXO is populated from the list stored in genesis.
    /// We use the identity hasher here because the cryptographic hashing is
    /// done explicitly.
    /// Mapping from `BlakeTwo256::hash_of(transaction, index)` to `TransactionOutput`
    #[pallet::storage]
    #[pallet::getter(fn utxo_store)]
    pub type UtxoStore<T: Config> = StorageMap<
        Hasher = Identity,
        Key = H256,
        Value = TransactionOutput,
        QueryKind = OptionQuery,
    >;


    /// [2-data-structure]
    /// Pallets use events to inform users when important changes are made.
    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        /// Dispatch transaction successful
        TransactionSuccess(Transaction),
        /// UTXO out processed
        TransactionOutputProcessed(H256),
        /// Reward distributed to `BlockAuthor`
        RewardDistributed(Value, H256),
        /// Faucet to `To`
        Faucet(Value, H256),
        /// No one get reward
        RewardWasted,
    }


    /// [2-data-structure]
    /// Errors inform users that something went wrong.
    #[pallet::error]
    pub enum Error<T> {
        /// Missing `Transaction` Input
        MissingInput,
        /// Reward overflow
        RewardOverflow,
        /// Maximum transaction depth
        MaximumTransactionDepth,
        /// Empty input
        EmptyInput,
        /// Empty output
        EmptyOutput,
        /// Each input must only be used once
        DuplicatedInput,
        /// Each output must be defined only once
        DuplicatedOutput,
        /// Input value is overflow
        InputOverflow,
        /// Output value is overflow
        OutputOverflow,
        /// Output spent must lte than Input spent
        OutputOverInput,
        /// Zero amount spent
        ZeroAmount,
        /// Invalid signature
        InvalidSignature,
    }

    /// [4-dispersed-reward]
    #[pallet::hooks]
    impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
        fn on_finalize(_n: BlockNumberFor<T>) {
            match T::BlockAuthor::block_author() {
                // Block author did not provide key to claim reward
                None => Self::deposit_event(Event::RewardWasted),
                // Block author did provide key, so issue thir reward
                Some(author) => Self::disperse_reward(&author),
            }
        }
    }

    /// [2-data-structure]
    /// Define extrinsics / dispatchable function
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
            // [3-spend-utxo]
            // validate transaction
            let transaction_validity = Self::validate_transaction(&transaction)?;
            ensure!(
                transaction_validity.requires.is_empty(),
                Error::<T>::MissingInput
            );

            // implement logic
            Self::do_spend(&transaction, transaction_validity.priority as Value)?;
            // emit event
            Self::deposit_event(Event::<T>::TransactionSuccess(transaction));

            Ok(())
        }
    }

    /// [2-data-structure]
    /// Define intrinsics
    impl<T: Config> Pallet<T> {
        /// Implement spend logic, update storage to reflect changes made by transaction
        /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
        fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
            // [3-spend-utxo]
            // Calculate new reward total. The rest of `total_input - total_output` will be used for block reward.
            let new_total = TotalReward::<T>::get()
                .checked_add(reward)
                .ok_or(Error::<T>::RewardOverflow)?;
            TotalReward::<T>::put(new_total);

            // Removing spent UTXOs
            for input in &transaction.inputs {
                UtxoStore::<T>::remove(input.outpoint);
            }

            let mut index: u64 = 0;
            for output in &transaction.outputs {
                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), index));
                // validated before, this is safe
                index = index
                    .checked_add(1)
                    .ok_or(Error::<T>::MaximumTransactionDepth)
                    .unwrap();
                Self::store_utxo(output, hash);
                Self::deposit_event(Event::TransactionOutputProcessed(hash));
            }

            Ok(())
        }

        /// Redistribute combined reward value to block Author
        fn disperse_reward(author: &Public) {
            // [4-dispersed-reward]

            // take the rest of reward
            // plus issuance reward of current block number
            let reward = TotalReward::<T>::take()
            + T::Issuance::issuance(frame_system::Pallet::<T>::block_number());

            let utxo = TransactionOutput {
                value: reward,
                pubkey: H256::from_slice(author.as_slice()),
            };

            let hash = BlakeTwo256::hash_of(&(
                &utxo,
                frame_system::Pallet::<T>::block_number().saturated_into::<u64>(),
            ));

            Self::store_utxo(&utxo, hash);
            Self::deposit_event(Event::RewardDistributed(reward, hash));  
        }

        /// Mutate storage, insert / update new UTXOs
        fn store_utxo(utxo: &TransactionOutput, hash: H256) {
            // [3-spend-utxo]
            UtxoStore::<T>::insert(hash, utxo);
            
            // // further update 😉
        }

        /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
        fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
            // [3-spend-utxo]
            let mut trx = transaction.clone();
            for input in trx.inputs.iter_mut() {
                input.sigscript = H512::zero();
            }

            trx.encode()
        }

        /// Check transaction for validity, errors, & race conditions
        /// Called by both transaction pool and runtime execution
        pub fn validate_transaction(
            transaction: &Transaction,
        ) -> Result<ValidTransaction, &'static str> {
            // [3-spend-utxo]
            // Check inputs and outputs are not empty
            ensure!(!transaction.inputs.is_empty(), Error::<T>::EmptyInput);
            ensure!(!transaction.outputs.is_empty(), Error::<T>::EmptyOutput);

            // Check each input is used exactly once
            {
                let input_set: BTreeMap<_, ()> =
                    transaction.inputs.iter().map(|input| (input, ())).collect();
                ensure!(
                    input_set.len() == transaction.inputs.len(),
                    Error::<T>::DuplicatedInput
                );
            }
            {
                let output_set: BTreeMap<_, ()> = transaction
                    .outputs
                    .iter()
                    .map(|output| (output, ()))
                    .collect();
                ensure!(
                    output_set.len() == transaction.outputs.len(),
                    Error::<T>::DuplicatedOutput
                );
            }

            let mut total_input: Value = 0;
            let mut total_output: Value = 0;
            let mut output_index: u64 = 0;
            let simple_transaction = Self::get_simple_transaction(transaction);

            // Variables sent to transaction pool
            let mut missing_utxos = Vec::new();
            let mut new_utxos = Vec::new();
            let mut reward = 0;

            for input in transaction.inputs.iter() {
                // Check all inputs match to existing, unspent and unlocked outputs
                if let Some(input_utxo) = UtxoStore::<T>::get(&input.outpoint) {
                    // Check provided signatures are valid
                    let is_valid_sig = sp_io::crypto::sr25519_verify(
                        &Signature::from_raw(*input.sigscript.as_fixed_bytes()),
                        &simple_transaction,
                        &Public::from_h256(input_utxo.pubkey),
                    );
                    ensure!(is_valid_sig, Error::<T>::InvalidSignature);
                    // Check sum of input values does not overflow
                    total_input = total_input
                        .checked_add(input_utxo.value)
                        .ok_or(Error::<T>::InputOverflow)?;
                } else {
                    missing_utxos.push(input.outpoint.clone().as_fixed_bytes().to_vec());
                }
            }

            // Check each output is defined exactly once and has nonzero value
            for output in transaction.outputs.iter() {
                ensure!(output.value > 0, Error::<T>::ZeroAmount);
                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), output_index));
                output_index = output_index
                    .checked_add(1)
                    .ok_or(Error::<T>::MaximumTransactionDepth)?;
                // Check new outputs do not collide with existing ones
                ensure!(
                    !UtxoStore::<T>::contains_key(hash),
                    Error::<T>::DuplicatedOutput
                );
                // Check sum of output values does not overflow
                total_output = total_output
                    .checked_add(output.value)
                    .ok_or(Error::<T>::OutputOverflow)?;
                new_utxos.push(hash.as_fixed_bytes().to_vec());
            }

            // If no race condition, check the math
            if missing_utxos.is_empty() {
                // Check total output value must not exceed total input value
                ensure!(total_input >= total_output, Error::<T>::OutputOverInput);
                reward = total_input
                    .checked_sub(total_output)
                    .ok_or(Error::<T>::RewardOverflow)?;
            }

            // Returns transaction details
            Ok(ValidTransaction {
                requires: missing_utxos,
                provides: new_utxos,
                priority: reward as u64,
                longevity: TransactionLongevity::max_value(),
                propagate: true,
            })
        }
    }
}
}
diff --git a/runtime/src/utxo.rs b/runtime/src/utxo.rs
index 00433df..1c51039 100644
--- a/runtime/src/utxo.rs
+++ b/runtime/src/utxo.rs
@@ -154,6 +154,18 @@ pub mod pallet {
         InvalidSignature,
     }
 
+    /// TODO [4-dispersed-reward]
+    // #[pallet::hooks]
+    // impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
+    //     fn on_finalize(_n: BlockNumberFor<T>) {
+    //         match T::BlockAuthor::block_author() {
+    //             // Block author did not provide key to claim reward
+    //             None => Self::deposit_event(Event::RewardWasted),
+    //             // Block author did provide key, so issue thir reward
+    //             Some(author) => Self::disperse_reward(&author),
+    //         }
+    //     }
+    // }
 
     /// [2-data-structure]
     /// Define extrinsics / dispatchable function
@@ -212,7 +224,28 @@ pub mod pallet {
 
         /// Redistribute combined reward value to block Author
         fn disperse_reward(author: &Public) {
+            // TODO remove this
             todo!();
+
+            // TODO [4-dispersed-reward]
+
+            // take the rest of reward
+            // plus issuance reward of current block number
+            // let reward = TotalReward::<T>::take()
+            // + T::Issuance::issuance(frame_system::Pallet::<T>::block_number());
+
+            // let utxo = TransactionOutput {
+            //     value: reward,
+            //     pubkey: H256::from_slice(author.as_slice()),
+            // };
+
+            // let hash = BlakeTwo256::hash_of(&(
+            //     &utxo,
+            //     frame_system::Pallet::<T>::block_number().saturated_into::<u64>(),
+            // ));
+
+            // Self::store_utxo(&utxo, hash);
+            // Self::deposit_event(Event::RewardDistributed(reward, hash));  
         }
 
         /// Mutate storage, insert / update new UTXOs
diff --git a/runtime/src/utxo.rs b/runtime/src/utxo.rs
index 1c51039..ed8ec6a 100644
--- a/runtime/src/utxo.rs
+++ b/runtime/src/utxo.rs
@@ -154,18 +154,18 @@ pub mod pallet {
         InvalidSignature,
     }
 
-    /// TODO [4-dispersed-reward]
-    // #[pallet::hooks]
-    // impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
-    //     fn on_finalize(_n: BlockNumberFor<T>) {
-    //         match T::BlockAuthor::block_author() {
-    //             // Block author did not provide key to claim reward
-    //             None => Self::deposit_event(Event::RewardWasted),
-    //             // Block author did provide key, so issue thir reward
-    //             Some(author) => Self::disperse_reward(&author),
-    //         }
-    //     }
-    // }
+    /// [4-dispersed-reward]
+    #[pallet::hooks]
+    impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
+        fn on_finalize(_n: BlockNumberFor<T>) {
+            match T::BlockAuthor::block_author() {
+                // Block author did not provide key to claim reward
+                None => Self::deposit_event(Event::RewardWasted),
+                // Block author did provide key, so issue thir reward
+                Some(author) => Self::disperse_reward(&author),
+            }
+        }
+    }
 
     /// [2-data-structure]
     /// Define extrinsics / dispatchable function
@@ -224,28 +224,25 @@ pub mod pallet {
 
         /// Redistribute combined reward value to block Author
         fn disperse_reward(author: &Public) {
-            // TODO remove this
-            todo!();
-
-            // TODO [4-dispersed-reward]
+            // [4-dispersed-reward]
 
             // take the rest of reward
             // plus issuance reward of current block number
-            // let reward = TotalReward::<T>::take()
-            // + T::Issuance::issuance(frame_system::Pallet::<T>::block_number());
+            let reward = TotalReward::<T>::take()
+            + T::Issuance::issuance(frame_system::Pallet::<T>::block_number());
 
-            // let utxo = TransactionOutput {
-            //     value: reward,
-            //     pubkey: H256::from_slice(author.as_slice()),
-            // };
+            let utxo = TransactionOutput {
+                value: reward,
+                pubkey: H256::from_slice(author.as_slice()),
+            };
 
-            // let hash = BlakeTwo256::hash_of(&(
-            //     &utxo,
-            //     frame_system::Pallet::<T>::block_number().saturated_into::<u64>(),
-            // ));
+            let hash = BlakeTwo256::hash_of(&(
+                &utxo,
+                frame_system::Pallet::<T>::block_number().saturated_into::<u64>(),
+            ));
 
-            // Self::store_utxo(&utxo, hash);
-            // Self::deposit_event(Event::RewardDistributed(reward, hash));  
+            Self::store_utxo(&utxo, hash);
+            Self::deposit_event(Event::RewardDistributed(reward, hash));  
         }
 
         /// Mutate storage, insert / update new UTXOs

Runtime

[!Note] Resolve all TODO in runtime/src/lib.rs to complete this step.

Reading Materials

Implement

From the first step of building environment, I've already import pallet into the runtime for ya

#![allow(unused)]
fn main() {
/// UTXOs serve as the digital equivalent of change you receive after making a cash purchase
pub mod utxo;
}

Now, you just have to add the pallet UTXO to the runtime

+ impl utxo::Config for Runtime {
+    type RuntimeEvent = RuntimeEvent;
+    type BlockAuthor = BlockAuthor;
+    type Issuance = issuance::BitcoinHalving;
+ }

... 

construct_runtime!(
    pub struct Runtime {
        System: frame_system,
        Timestamp: pallet_timestamp,
        Balances: pallet_balances,
        TransactionPayment: pallet_transaction_payment,
        Md5DifficultyAdjustment: difficulty::<Instance1>,
        Sha3DifficultyAdjustment: difficulty::<Instance2>,
        KeccakDifficultyAdjustment: difficulty::<Instance3>,
        BlockAuthor: block_author,
+        Utxo: utxo,
    }
);

...



impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
    fn validate_transaction(
        source: TransactionSource,
        tx: <Block as BlockT>::Extrinsic,
        block_hash: <Block as BlockT>::Hash,
    ) -> TransactionValidity {
+        // Extrinsics representing UTXO transaction need some special handling
+        if let Some(&utxo::Call::spend{ ref transaction }) = IsSubType::<<Utxo as Callable<Runtime>>::RuntimeCall>::is_sub_type(&tx.function)
+        {
+            match Utxo::validate_transaction(&transaction) {
+                // Transaction verification failed
+                Err(e) => {
+                    sp_runtime::print(e);
+                    return Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(1)));
+                }
+                // Race condition, or Transaction is good to go
+                Ok(tv) => { return Ok(tv); }
+            }
+        }

        // Fall back to default logic for non UTXO-spending extrinsics
        Executive::validate_transaction(source, tx, block_hash)
    }
}



Build the code

cargo build --release
# start temporary local node in development environment
./target/release/academy-pow --dev --tmp

Direct to https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/explorer, and see block production. If you see after every a new block, there's also an event RewardDistributed, your work are perfect!

result


Well done on completing! 🎉 You're on fire! Now, let's tackle next step.

#![allow(unused)]
fn main() {
//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.

#![cfg_attr(not(feature = "std"), no_std)]
// The construct runtime macro does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit = "256"]

// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

pub use frame_support::{
	construct_runtime, derive_impl, parameter_types,
	traits::{
		Currency, EstimateNextNewSession, Imbalance, IsSubType, KeyOwnerProofSystem,
		LockIdentifier, Nothing, OnUnbalanced, ValidatorSet, VariantCountOf,
	},
	weights::{
		constants::{
			BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND,
		},
		IdentityFee, Weight,
	},
	Callable, StorageValue,
};
use frame_support::{
	genesis_builder_helper::{build_state, get_preset},
	instances::{Instance1, Instance2, Instance3},
	sp_runtime::Perquintill,
	traits::{ConstU128, ConstU32, ConstU8},
};
use multi_pow::SupportedHashes;
pub use pallet_balances::Call as BalancesCall;
pub use pallet_timestamp::Call as TimestampCall;
use pallet_transaction_payment::{ConstFeeMultiplier, FungibleAdapter, Multiplier};
use parity_scale_codec::Decode;
use sp_api::impl_runtime_apis;
use sp_consensus_pow::POW_ENGINE_ID;
use sp_core::OpaqueMetadata;
// A few exports that help ease life for downstream crates.
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
use sp_runtime::{
	create_runtime_str, generic,
	traits::{
		AccountIdLookup, BlakeTwo256, Block as BlockT, Bounded, IdentifyAccount, One, Verify,
	},
	transaction_validity::{
		InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
	},
	ApplyExtrinsicResult, DigestItem, ExtrinsicInclusionMode, MultiSignature,
};
pub use sp_runtime::{FixedPointNumber, Perbill, Permill};
use sp_std::prelude::*;
#[cfg(feature = "std")]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
/// An index to a block.
pub type BlockNumber = u32;

/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
pub type Signature = MultiSignature;

/// Some way of identifying an account on the chain. We intentionally make it equivalent
/// to the public key of our transaction signing scheme.
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;

/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
/// never know...
pub type AccountIndex = u32;

/// Balance of an account.
pub type Balance = u128;

/// Index of a transaction in the chain.
pub type Nonce = u32;

/// Index of a transaction in the chain.
pub type Index = u32;

/// A hash of some data used by the chain.
pub type Hash = sp_core::H256;

/// Consensus digest containing block author and supported hash algorithm.
pub type PreDigest = (AccountId, SupportedHashes);

/// The BlockAuthor trait in `./block_author.rs`
pub mod block_author;

// /// The Difficulty Adjustment Algorithm in `./difficulty.rs`
pub mod difficulty;

/// The total issuance and halving time
pub mod issuance;

/// UTXOs serve as the digital equivalent of change you receive after making a cash purchase
pub mod utxo;

/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
/// to even the core data structures.
pub mod opaque {
	pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;

	use super::*;

	/// Opaque block header type.
	pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
	/// Opaque block type.
	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
	/// Opaque block identifier type.
	pub type BlockId = generic::BlockId<Block>;
}

/// This runtime version.
#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: create_runtime_str!("academy-pow"),
	impl_name: create_runtime_str!("academy-pow"),
	authoring_version: 1,
	spec_version: 1,
	impl_version: 1,
	apis: RUNTIME_API_VERSIONS,
	transaction_version: 1,
	state_version: 1,
};

/// The version information used to identify this runtime when compiled natively.
#[cfg(feature = "std")]
pub fn native_version() -> NativeVersion {
	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
}

const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
// native chain currency
pub const TOKEN_SYMBOL: &str = "Unit";
pub const TOKEN_DECIMALS: u32 = 12;
pub const TOKEN: u128 = 10u128.pow(TOKEN_DECIMALS);

parameter_types! {
	pub const BlockHashCount: BlockNumber = 2400;
	pub const Version: RuntimeVersion = VERSION;
	/// We allow for 2 seconds of compute with a 6 second average block time.
	pub BlockWeights: frame_system::limits::BlockWeights =
		frame_system::limits::BlockWeights::with_sensible_defaults(
			Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX),
			NORMAL_DISPATCH_RATIO,
		);
	pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
		::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
	pub const SS58Prefix: u8 = 42;
}

#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
impl frame_system::Config for Runtime {
	/// The basic call filter to use in dispatchable.
	type BaseCallFilter = frame_support::traits::Everything;
	/// Block & extrinsics weights: base values and limits.
	type BlockWeights = BlockWeights;
	/// The maximum length of a block (in bytes).
	type BlockLength = BlockLength;
	/// The identifier used to distinguish between accounts.
	type AccountId = AccountId;
	/// The aggregated dispatch type that is available for extrinsics.
	type RuntimeCall = RuntimeCall;
	/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
	type Lookup = AccountIdLookup<AccountId, ()>;
	/// The type for hashing blocks and tries.
	type Hash = Hash;
	/// The hashing algorithm used.
	type Hashing = BlakeTwo256;
	/// The ubiquitous event type.
	type RuntimeEvent = RuntimeEvent;
	/// The ubiquitous origin type.
	type RuntimeOrigin = RuntimeOrigin;
	/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
	type BlockHashCount = BlockHashCount;
	/// The weight of database operations that the runtime can invoke.
	type DbWeight = RocksDbWeight;
	/// Version of the runtime.
	type Version = Version;
	/// This type is being generated by the construct runtime macro.
	type PalletInfo = PalletInfo;
	/// What to do if a new account is created.
	type OnNewAccount = ();
	/// What to do if an account is fully reaped from the system.
	type OnKilledAccount = ();
	/// The data to be stored in an account.
	type AccountData = pallet_balances::AccountData<Balance>;
	/// Weight information for the extrinsics of this pallet.
	type SystemWeightInfo = ();
	/// This is used as an identifier of the chain. 42 is the generic substrate prefix.
	type SS58Prefix = SS58Prefix;
	/// The set code logic, just the default since we're not a parachain.
	type OnSetCode = ();
	type MaxConsumers = frame_support::traits::ConstU32<16>;
	type Nonce = Nonce;
	type Block = Block;
}

parameter_types! {
	pub const MinimumPeriod: u64 = 1000;
}

impl pallet_timestamp::Config for Runtime {
	/// A timestamp: milliseconds since the unix epoch.
	type Moment = u64;
	type OnTimestampSet = ();
	type MinimumPeriod = MinimumPeriod;
	type WeightInfo = ();
}

impl pallet_balances::Config for Runtime {
	type MaxLocks = ConstU32<50>;
	type MaxReserves = ();
	type ReserveIdentifier = [u8; 8];
	/// The type for recording an account's balance.
	type Balance = Balance;
	/// The ubiquitous event type.
	type RuntimeEvent = RuntimeEvent;
	type DustRemoval = ();
	type ExistentialDeposit = ConstU128<500>;
	type AccountStore = System;
	type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
	type FreezeIdentifier = RuntimeFreezeReason;
	type MaxFreezes = VariantCountOf<RuntimeFreezeReason>;
	type RuntimeHoldReason = RuntimeHoldReason;
	type RuntimeFreezeReason = RuntimeFreezeReason;
}

parameter_types! {
	pub const TargetBlockTime: u128 = 5_000;
	// Setting min difficulty to damp factor per recommendation
	pub const DampFactor: u128 = 3;
	pub const ClampFactor: u128 = 2;
	pub const MaxDifficulty: u128 = u128::max_value();
}

// Helper function to get the current blocks PoW algo from the predigest
fn current_blocks_mining_algo() -> SupportedHashes {
	System::digest()
		.logs
		.iter()
		.find_map(|digest_item| match digest_item {
			DigestItem::PreRuntime(POW_ENGINE_ID, pre_digest) =>
				PreDigest::decode(&mut &pre_digest[..]).map(|d| d.1).ok(),
			_ => None,
		})
		.expect("There should be exactly one pow pre-digest item")
}

impl difficulty::Config<Instance1> for Runtime {
	type TimeProvider = Timestamp;
	type TargetBlockTime = TargetBlockTime;
	type DampFactor = DampFactor;
	type ClampFactor = ClampFactor;
	type MaxDifficulty = MaxDifficulty;
	type MinDifficulty = DampFactor;

	fn relevant_to_this_instance() -> bool {
		current_blocks_mining_algo() == SupportedHashes::Md5
	}
}

impl difficulty::Config<Instance2> for Runtime {
	type TimeProvider = Timestamp;
	type TargetBlockTime = TargetBlockTime;
	type DampFactor = DampFactor;
	type ClampFactor = ClampFactor;
	type MaxDifficulty = MaxDifficulty;
	type MinDifficulty = DampFactor;

	fn relevant_to_this_instance() -> bool {
		current_blocks_mining_algo() == SupportedHashes::Sha3
	}
}

impl difficulty::Config<Instance3> for Runtime {
	type TimeProvider = Timestamp;
	type TargetBlockTime = TargetBlockTime;
	type DampFactor = DampFactor;
	type ClampFactor = ClampFactor;
	type MaxDifficulty = MaxDifficulty;
	type MinDifficulty = DampFactor;

	fn relevant_to_this_instance() -> bool {
		current_blocks_mining_algo() == SupportedHashes::Keccak
	}
}

impl block_author::Config for Runtime {
	// Each block mined issues 50 new tokens to the miner
	fn on_author_set(author_account: Self::AccountId) {
		let issuance = 50 * TOKEN;
		let _ = Balances::deposit_creating(&author_account, issuance);
	}
}

parameter_types! {
	// This value increases the priority of `Operational` transactions by adding
	// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
	// follows polkadot : https://github.com/paritytech/polkadot/blob/9ce5f7ef5abb1a4291454e8c9911b304d80679f9/runtime/polkadot/src/lib.rs#L369
	pub const OperationalFeeMultiplier: u8 = 5;
	// We expect that on average 25% of the normal capacity will be occupied with normal txs.
	pub const TargetSaturationLevel: Perquintill = Perquintill::from_percent(25);
	// During 20 blocks the fee may not change more than by 100%. This, together with the
	// `TargetSaturationLevel` value, results in variability ~0.067. For the corresponding
	// formulas please refer to Substrate code at `frame/transaction-payment/src/lib.rs`.
	pub FeeVariability: Multiplier = Multiplier::saturating_from_rational(67, 1000);
	// Fee should never be lower than the computational cost.
	pub MinimumMultiplier: Multiplier = Multiplier::one();
	pub MaximumMultiplier: Multiplier = Bounded::max_value();
}

parameter_types! {
	pub FeeMultiplier: Multiplier = Multiplier::one();
}

impl pallet_transaction_payment::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type OnChargeTransaction = FungibleAdapter<Balances, ()>;
	type OperationalFeeMultiplier = ConstU8<5>;
	type WeightToFee = IdentityFee<Balance>;
	type LengthToFee = IdentityFee<Balance>;
	type FeeMultiplierUpdate = ConstFeeMultiplier<FeeMultiplier>;
}


// TODO [5-runtime]
// impl utxo::Config for Runtime {
//     type RuntimeEvent = RuntimeEvent;
//     type BlockAuthor = BlockAuthor;
//     type Issuance = issuance::BitcoinHalving;
// }


construct_runtime!(
	pub struct Runtime {
		System: frame_system,
		Timestamp: pallet_timestamp,
		Balances: pallet_balances,
		TransactionPayment: pallet_transaction_payment,
		Md5DifficultyAdjustment: difficulty::<Instance1>,
		Sha3DifficultyAdjustment: difficulty::<Instance2>,
		KeccakDifficultyAdjustment: difficulty::<Instance3>,
		BlockAuthor: block_author,
        // TODO [5-runtime]
        // Utxo: utxo,
	}
);

/// The address format for describing accounts.
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// A Block signed with a Justification
pub type SignedBlock = generic::SignedBlock<Block>;
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
	frame_system::CheckNonZeroSender<Runtime>,
	frame_system::CheckSpecVersion<Runtime>,
	frame_system::CheckTxVersion<Runtime>,
	frame_system::CheckGenesis<Runtime>,
	frame_system::CheckEra<Runtime>,
	frame_system::CheckNonce<Runtime>,
	frame_system::CheckWeight<Runtime>,
	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
);
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
/// Executive: handles dispatch to the various modules.
pub type Executive = frame_executive::Executive<
	Runtime,
	Block,
	frame_system::ChainContext<Runtime>,
	Runtime,
	AllPalletsWithSystem,
>;

impl_runtime_apis! {
	impl sp_api::Core<Block> for Runtime {
		fn version() -> RuntimeVersion {
			VERSION
		}

		fn execute_block(block: Block) {
			Executive::execute_block(block)
		}

		fn initialize_block(header: &<Block as BlockT>::Header) -> ExtrinsicInclusionMode {
			Executive::initialize_block(header)
		}
	}

	impl sp_api::Metadata<Block> for Runtime {
		fn metadata() -> OpaqueMetadata {
			OpaqueMetadata::new(Runtime::metadata().into())
		}

		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
			Runtime::metadata_at_version(version)
		}

		fn metadata_versions() -> sp_std::vec::Vec<u32> {
			Runtime::metadata_versions()
		}
	}

	impl sp_block_builder::BlockBuilder<Block> for Runtime {
		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
			Executive::apply_extrinsic(extrinsic)
		}

		fn finalize_block() -> <Block as BlockT>::Header {
			Executive::finalize_block()
		}

		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
			data.create_extrinsics()
		}

		fn check_inherents(
			block: Block,
			data: sp_inherents::InherentData,
		) -> sp_inherents::CheckInherentsResult {
			data.check_extrinsics(&block)
		}
	}

	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
		fn validate_transaction(
			source: TransactionSource,
			tx: <Block as BlockT>::Extrinsic,
			block_hash: <Block as BlockT>::Hash,
		) -> TransactionValidity {
            // TODO [5-runtime]

            // // Extrinsics representing UTXO transaction need some special handling
            // if let Some(&utxo::Call::spend{ ref transaction }) = IsSubType::<<Utxo as Callable<Runtime>>::RuntimeCall>::is_sub_type(&tx.function)
            // {
            //     match Utxo::validate_transaction(&transaction) {
            //         // Transaction verification failed
            //         Err(e) => {
            //             sp_runtime::print(e);
            //             return Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(1)));
            //         }
            //         // Race condition, or Transaction is good to go
            //         Ok(tv) => { return Ok(tv); }
            //     }
            // }

            // Fall back to default logic for non UTXO-spending extrinsics
			Executive::validate_transaction(source, tx, block_hash)
		}
	}

	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
		fn offchain_worker(header: &<Block as BlockT>::Header) {
			Executive::offchain_worker(header)
		}
	}

	impl sp_session::SessionKeys<Block> for Runtime {
		fn generate_session_keys(_seed: Option<Vec<u8>>) -> Vec<u8> {
			Vec::new()
		}

		fn decode_session_keys(
			_encoded: Vec<u8>,
		) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
			None
		}
	}

	impl sp_consensus_pow::DifficultyApi<Block, multi_pow::Threshold> for Runtime {
		fn difficulty() -> multi_pow::Threshold {
			multi_pow::Threshold {
				md5: Md5DifficultyAdjustment::difficulty(),
				sha3: Sha3DifficultyAdjustment::difficulty(),
				keccak: KeccakDifficultyAdjustment::difficulty(),
			}
		}
	}

	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
		fn account_nonce(account: AccountId) -> Index {
			System::account_nonce(account)
		}
	}

	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime
	{
		fn query_info(
			uxt: <Block as BlockT>::Extrinsic,
			len: u32,
		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
			TransactionPayment::query_info(uxt, len)
		}
		fn query_fee_details(
			uxt: <Block as BlockT>::Extrinsic,
			len: u32,
		) -> pallet_transaction_payment::FeeDetails<Balance> {
			TransactionPayment::query_fee_details(uxt, len)
		}
		fn query_weight_to_fee(weight: Weight) -> Balance {
			TransactionPayment::weight_to_fee(weight)
		}
		fn query_length_to_fee(length: u32) -> Balance {
			TransactionPayment::length_to_fee(length)
		}
	}

	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
		for Runtime
	{
		fn query_call_info(
			call: RuntimeCall,
			len: u32,
		) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
			TransactionPayment::query_call_info(call, len)
		}
		fn query_call_fee_details(
			call: RuntimeCall,
			len: u32,
		) -> pallet_transaction_payment::FeeDetails<Balance> {
			TransactionPayment::query_call_fee_details(call, len)
		}
		fn query_weight_to_fee(weight: Weight) -> Balance {
			TransactionPayment::weight_to_fee(weight)
		}
		fn query_length_to_fee(length: u32) -> Balance {
			TransactionPayment::length_to_fee(length)
		}
	}

	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
			build_state::<RuntimeGenesisConfig>(config)
		}

		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
			get_preset::<RuntimeGenesisConfig>(id, |_| None)
		}

		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
			Default::default()
		}
	}
}
}
#![allow(unused)]
fn main() {
//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.

#![cfg_attr(not(feature = "std"), no_std)]
// The construct runtime macro does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit = "256"]

// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

pub use frame_support::{
	construct_runtime, derive_impl, parameter_types,
	traits::{
		Currency, EstimateNextNewSession, Imbalance, IsSubType, KeyOwnerProofSystem,
		LockIdentifier, Nothing, OnUnbalanced, ValidatorSet, VariantCountOf,
	},
	weights::{
		constants::{
			BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND,
		},
		IdentityFee, Weight,
	},
	Callable, StorageValue,
};
use frame_support::{
	genesis_builder_helper::{build_state, get_preset},
	instances::{Instance1, Instance2, Instance3},
	sp_runtime::Perquintill,
	traits::{ConstU128, ConstU32, ConstU8},
};
use multi_pow::SupportedHashes;
pub use pallet_balances::Call as BalancesCall;
pub use pallet_timestamp::Call as TimestampCall;
use pallet_transaction_payment::{ConstFeeMultiplier, FungibleAdapter, Multiplier};
use parity_scale_codec::Decode;
use sp_api::impl_runtime_apis;
use sp_consensus_pow::POW_ENGINE_ID;
use sp_core::OpaqueMetadata;
// A few exports that help ease life for downstream crates.
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
use sp_runtime::{
	create_runtime_str, generic,
	traits::{
		AccountIdLookup, BlakeTwo256, Block as BlockT, Bounded, IdentifyAccount, One, Verify,
	},
	transaction_validity::{
		InvalidTransaction, TransactionSource, TransactionValidity, TransactionValidityError,
	},
	ApplyExtrinsicResult, DigestItem, ExtrinsicInclusionMode, MultiSignature,
};
pub use sp_runtime::{FixedPointNumber, Perbill, Permill};
use sp_std::prelude::*;
#[cfg(feature = "std")]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
/// An index to a block.
pub type BlockNumber = u32;

/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
pub type Signature = MultiSignature;

/// Some way of identifying an account on the chain. We intentionally make it equivalent
/// to the public key of our transaction signing scheme.
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;

/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
/// never know...
pub type AccountIndex = u32;

/// Balance of an account.
pub type Balance = u128;

/// Index of a transaction in the chain.
pub type Nonce = u32;

/// Index of a transaction in the chain.
pub type Index = u32;

/// A hash of some data used by the chain.
pub type Hash = sp_core::H256;

/// Consensus digest containing block author and supported hash algorithm.
pub type PreDigest = (AccountId, SupportedHashes);

/// The BlockAuthor trait in `./block_author.rs`
pub mod block_author;

// /// The Difficulty Adjustment Algorithm in `./difficulty.rs`
pub mod difficulty;

/// The total issuance and halving time
pub mod issuance;

/// UTXOs serve as the digital equivalent of change you receive after making a cash purchase
pub mod utxo;

/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
/// to even the core data structures.
pub mod opaque {
	pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;

	use super::*;

	/// Opaque block header type.
	pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
	/// Opaque block type.
	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
	/// Opaque block identifier type.
	pub type BlockId = generic::BlockId<Block>;
}

/// This runtime version.
#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: create_runtime_str!("academy-pow"),
	impl_name: create_runtime_str!("academy-pow"),
	authoring_version: 1,
	spec_version: 1,
	impl_version: 1,
	apis: RUNTIME_API_VERSIONS,
	transaction_version: 1,
	state_version: 1,
};

/// The version information used to identify this runtime when compiled natively.
#[cfg(feature = "std")]
pub fn native_version() -> NativeVersion {
	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
}

const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
// native chain currency
pub const TOKEN_SYMBOL: &str = "Unit";
pub const TOKEN_DECIMALS: u32 = 12;
pub const TOKEN: u128 = 10u128.pow(TOKEN_DECIMALS);

parameter_types! {
	pub const BlockHashCount: BlockNumber = 2400;
	pub const Version: RuntimeVersion = VERSION;
	/// We allow for 2 seconds of compute with a 6 second average block time.
	pub BlockWeights: frame_system::limits::BlockWeights =
		frame_system::limits::BlockWeights::with_sensible_defaults(
			Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX),
			NORMAL_DISPATCH_RATIO,
		);
	pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
		::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
	pub const SS58Prefix: u8 = 42;
}

#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig)]
impl frame_system::Config for Runtime {
	/// The basic call filter to use in dispatchable.
	type BaseCallFilter = frame_support::traits::Everything;
	/// Block & extrinsics weights: base values and limits.
	type BlockWeights = BlockWeights;
	/// The maximum length of a block (in bytes).
	type BlockLength = BlockLength;
	/// The identifier used to distinguish between accounts.
	type AccountId = AccountId;
	/// The aggregated dispatch type that is available for extrinsics.
	type RuntimeCall = RuntimeCall;
	/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
	type Lookup = AccountIdLookup<AccountId, ()>;
	/// The type for hashing blocks and tries.
	type Hash = Hash;
	/// The hashing algorithm used.
	type Hashing = BlakeTwo256;
	/// The ubiquitous event type.
	type RuntimeEvent = RuntimeEvent;
	/// The ubiquitous origin type.
	type RuntimeOrigin = RuntimeOrigin;
	/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
	type BlockHashCount = BlockHashCount;
	/// The weight of database operations that the runtime can invoke.
	type DbWeight = RocksDbWeight;
	/// Version of the runtime.
	type Version = Version;
	/// This type is being generated by the construct runtime macro.
	type PalletInfo = PalletInfo;
	/// What to do if a new account is created.
	type OnNewAccount = ();
	/// What to do if an account is fully reaped from the system.
	type OnKilledAccount = ();
	/// The data to be stored in an account.
	type AccountData = pallet_balances::AccountData<Balance>;
	/// Weight information for the extrinsics of this pallet.
	type SystemWeightInfo = ();
	/// This is used as an identifier of the chain. 42 is the generic substrate prefix.
	type SS58Prefix = SS58Prefix;
	/// The set code logic, just the default since we're not a parachain.
	type OnSetCode = ();
	type MaxConsumers = frame_support::traits::ConstU32<16>;
	type Nonce = Nonce;
	type Block = Block;
}

parameter_types! {
	pub const MinimumPeriod: u64 = 1000;
}

impl pallet_timestamp::Config for Runtime {
	/// A timestamp: milliseconds since the unix epoch.
	type Moment = u64;
	type OnTimestampSet = ();
	type MinimumPeriod = MinimumPeriod;
	type WeightInfo = ();
}

impl pallet_balances::Config for Runtime {
	type MaxLocks = ConstU32<50>;
	type MaxReserves = ();
	type ReserveIdentifier = [u8; 8];
	/// The type for recording an account's balance.
	type Balance = Balance;
	/// The ubiquitous event type.
	type RuntimeEvent = RuntimeEvent;
	type DustRemoval = ();
	type ExistentialDeposit = ConstU128<500>;
	type AccountStore = System;
	type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
	type FreezeIdentifier = RuntimeFreezeReason;
	type MaxFreezes = VariantCountOf<RuntimeFreezeReason>;
	type RuntimeHoldReason = RuntimeHoldReason;
	type RuntimeFreezeReason = RuntimeFreezeReason;
}

parameter_types! {
	pub const TargetBlockTime: u128 = 5_000;
	// Setting min difficulty to damp factor per recommendation
	pub const DampFactor: u128 = 3;
	pub const ClampFactor: u128 = 2;
	pub const MaxDifficulty: u128 = u128::max_value();
}

// Helper function to get the current blocks PoW algo from the predigest
fn current_blocks_mining_algo() -> SupportedHashes {
	System::digest()
		.logs
		.iter()
		.find_map(|digest_item| match digest_item {
			DigestItem::PreRuntime(POW_ENGINE_ID, pre_digest) =>
				PreDigest::decode(&mut &pre_digest[..]).map(|d| d.1).ok(),
			_ => None,
		})
		.expect("There should be exactly one pow pre-digest item")
}

impl difficulty::Config<Instance1> for Runtime {
	type TimeProvider = Timestamp;
	type TargetBlockTime = TargetBlockTime;
	type DampFactor = DampFactor;
	type ClampFactor = ClampFactor;
	type MaxDifficulty = MaxDifficulty;
	type MinDifficulty = DampFactor;

	fn relevant_to_this_instance() -> bool {
		current_blocks_mining_algo() == SupportedHashes::Md5
	}
}

impl difficulty::Config<Instance2> for Runtime {
	type TimeProvider = Timestamp;
	type TargetBlockTime = TargetBlockTime;
	type DampFactor = DampFactor;
	type ClampFactor = ClampFactor;
	type MaxDifficulty = MaxDifficulty;
	type MinDifficulty = DampFactor;

	fn relevant_to_this_instance() -> bool {
		current_blocks_mining_algo() == SupportedHashes::Sha3
	}
}

impl difficulty::Config<Instance3> for Runtime {
	type TimeProvider = Timestamp;
	type TargetBlockTime = TargetBlockTime;
	type DampFactor = DampFactor;
	type ClampFactor = ClampFactor;
	type MaxDifficulty = MaxDifficulty;
	type MinDifficulty = DampFactor;

	fn relevant_to_this_instance() -> bool {
		current_blocks_mining_algo() == SupportedHashes::Keccak
	}
}

impl block_author::Config for Runtime {
	// Each block mined issues 50 new tokens to the miner
	fn on_author_set(author_account: Self::AccountId) {
		let issuance = 50 * TOKEN;
		let _ = Balances::deposit_creating(&author_account, issuance);
	}
}

parameter_types! {
	// This value increases the priority of `Operational` transactions by adding
	// a "virtual tip" that's equal to the `OperationalFeeMultiplier * final_fee`.
	// follows polkadot : https://github.com/paritytech/polkadot/blob/9ce5f7ef5abb1a4291454e8c9911b304d80679f9/runtime/polkadot/src/lib.rs#L369
	pub const OperationalFeeMultiplier: u8 = 5;
	// We expect that on average 25% of the normal capacity will be occupied with normal txs.
	pub const TargetSaturationLevel: Perquintill = Perquintill::from_percent(25);
	// During 20 blocks the fee may not change more than by 100%. This, together with the
	// `TargetSaturationLevel` value, results in variability ~0.067. For the corresponding
	// formulas please refer to Substrate code at `frame/transaction-payment/src/lib.rs`.
	pub FeeVariability: Multiplier = Multiplier::saturating_from_rational(67, 1000);
	// Fee should never be lower than the computational cost.
	pub MinimumMultiplier: Multiplier = Multiplier::one();
	pub MaximumMultiplier: Multiplier = Bounded::max_value();
}

parameter_types! {
	pub FeeMultiplier: Multiplier = Multiplier::one();
}

impl pallet_transaction_payment::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type OnChargeTransaction = FungibleAdapter<Balances, ()>;
	type OperationalFeeMultiplier = ConstU8<5>;
	type WeightToFee = IdentityFee<Balance>;
	type LengthToFee = IdentityFee<Balance>;
	type FeeMultiplierUpdate = ConstFeeMultiplier<FeeMultiplier>;
}


// [5-runtime]
impl utxo::Config for Runtime {
    type RuntimeEvent = RuntimeEvent;
    type BlockAuthor = BlockAuthor;
    type Issuance = issuance::BitcoinHalving;
}


construct_runtime!(
	pub struct Runtime {
		System: frame_system,
		Timestamp: pallet_timestamp,
		Balances: pallet_balances,
		TransactionPayment: pallet_transaction_payment,
		Md5DifficultyAdjustment: difficulty::<Instance1>,
		Sha3DifficultyAdjustment: difficulty::<Instance2>,
		KeccakDifficultyAdjustment: difficulty::<Instance3>,
		BlockAuthor: block_author,
        // [5-runtime]
        Utxo: utxo,
	}
);

/// The address format for describing accounts.
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// A Block signed with a Justification
pub type SignedBlock = generic::SignedBlock<Block>;
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
	frame_system::CheckNonZeroSender<Runtime>,
	frame_system::CheckSpecVersion<Runtime>,
	frame_system::CheckTxVersion<Runtime>,
	frame_system::CheckGenesis<Runtime>,
	frame_system::CheckEra<Runtime>,
	frame_system::CheckNonce<Runtime>,
	frame_system::CheckWeight<Runtime>,
	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
);
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
/// Executive: handles dispatch to the various modules.
pub type Executive = frame_executive::Executive<
	Runtime,
	Block,
	frame_system::ChainContext<Runtime>,
	Runtime,
	AllPalletsWithSystem,
>;

impl_runtime_apis! {
	impl sp_api::Core<Block> for Runtime {
		fn version() -> RuntimeVersion {
			VERSION
		}

		fn execute_block(block: Block) {
			Executive::execute_block(block)
		}

		fn initialize_block(header: &<Block as BlockT>::Header) -> ExtrinsicInclusionMode {
			Executive::initialize_block(header)
		}
	}

	impl sp_api::Metadata<Block> for Runtime {
		fn metadata() -> OpaqueMetadata {
			OpaqueMetadata::new(Runtime::metadata().into())
		}

		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
			Runtime::metadata_at_version(version)
		}

		fn metadata_versions() -> sp_std::vec::Vec<u32> {
			Runtime::metadata_versions()
		}
	}

	impl sp_block_builder::BlockBuilder<Block> for Runtime {
		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
			Executive::apply_extrinsic(extrinsic)
		}

		fn finalize_block() -> <Block as BlockT>::Header {
			Executive::finalize_block()
		}

		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
			data.create_extrinsics()
		}

		fn check_inherents(
			block: Block,
			data: sp_inherents::InherentData,
		) -> sp_inherents::CheckInherentsResult {
			data.check_extrinsics(&block)
		}
	}

	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
		fn validate_transaction(
			source: TransactionSource,
			tx: <Block as BlockT>::Extrinsic,
			block_hash: <Block as BlockT>::Hash,
		) -> TransactionValidity {
            // [5-runtime]

            // Extrinsics representing UTXO transaction need some special handling
            if let Some(&utxo::Call::spend{ ref transaction }) = IsSubType::<<Utxo as Callable<Runtime>>::RuntimeCall>::is_sub_type(&tx.function)
            {
                match Utxo::validate_transaction(&transaction) {
                    // Transaction verification failed
                    Err(e) => {
                        sp_runtime::print(e);
                        return Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(1)));
                    }
                    // Race condition, or Transaction is good to go
                    Ok(tv) => { return Ok(tv); }
                }
            }

            // Fall back to default logic for non UTXO-spending extrinsics
			Executive::validate_transaction(source, tx, block_hash)
		}
	}

	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
		fn offchain_worker(header: &<Block as BlockT>::Header) {
			Executive::offchain_worker(header)
		}
	}

	impl sp_session::SessionKeys<Block> for Runtime {
		fn generate_session_keys(_seed: Option<Vec<u8>>) -> Vec<u8> {
			Vec::new()
		}

		fn decode_session_keys(
			_encoded: Vec<u8>,
		) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
			None
		}
	}

	impl sp_consensus_pow::DifficultyApi<Block, multi_pow::Threshold> for Runtime {
		fn difficulty() -> multi_pow::Threshold {
			multi_pow::Threshold {
				md5: Md5DifficultyAdjustment::difficulty(),
				sha3: Sha3DifficultyAdjustment::difficulty(),
				keccak: KeccakDifficultyAdjustment::difficulty(),
			}
		}
	}

	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
		fn account_nonce(account: AccountId) -> Index {
			System::account_nonce(account)
		}
	}

	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime
	{
		fn query_info(
			uxt: <Block as BlockT>::Extrinsic,
			len: u32,
		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
			TransactionPayment::query_info(uxt, len)
		}
		fn query_fee_details(
			uxt: <Block as BlockT>::Extrinsic,
			len: u32,
		) -> pallet_transaction_payment::FeeDetails<Balance> {
			TransactionPayment::query_fee_details(uxt, len)
		}
		fn query_weight_to_fee(weight: Weight) -> Balance {
			TransactionPayment::weight_to_fee(weight)
		}
		fn query_length_to_fee(length: u32) -> Balance {
			TransactionPayment::length_to_fee(length)
		}
	}

	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall>
		for Runtime
	{
		fn query_call_info(
			call: RuntimeCall,
			len: u32,
		) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
			TransactionPayment::query_call_info(call, len)
		}
		fn query_call_fee_details(
			call: RuntimeCall,
			len: u32,
		) -> pallet_transaction_payment::FeeDetails<Balance> {
			TransactionPayment::query_call_fee_details(call, len)
		}
		fn query_weight_to_fee(weight: Weight) -> Balance {
			TransactionPayment::weight_to_fee(weight)
		}
		fn query_length_to_fee(length: u32) -> Balance {
			TransactionPayment::length_to_fee(length)
		}
	}

	impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
		fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
			build_state::<RuntimeGenesisConfig>(config)
		}

		fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
			get_preset::<RuntimeGenesisConfig>(id, |_| None)
		}

		fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
			Default::default()
		}
	}
}
}
diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs
index b724b7e..258420d 100644
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -325,6 +325,15 @@ impl pallet_transaction_payment::Config for Runtime {
 	type FeeMultiplierUpdate = ConstFeeMultiplier<FeeMultiplier>;
 }
 
+
+// TODO [5-runtime]
+// impl utxo::Config for Runtime {
+//     type RuntimeEvent = RuntimeEvent;
+//     type BlockAuthor = BlockAuthor;
+//     type Issuance = issuance::BitcoinHalving;
+// }
+
+
 construct_runtime!(
 	pub struct Runtime {
 		System: frame_system,
@@ -335,6 +344,8 @@ construct_runtime!(
 		Sha3DifficultyAdjustment: difficulty::<Instance2>,
 		KeccakDifficultyAdjustment: difficulty::<Instance3>,
 		BlockAuthor: block_author,
+        // TODO [5-runtime]
+        // Utxo: utxo,
 	}
 );
 
@@ -425,6 +436,23 @@ impl_runtime_apis! {
 			tx: <Block as BlockT>::Extrinsic,
 			block_hash: <Block as BlockT>::Hash,
 		) -> TransactionValidity {
+            // TODO [5-runtime]
+
+            // // Extrinsics representing UTXO transaction need some special handling
+            // if let Some(&utxo::Call::spend{ ref transaction }) = IsSubType::<<Utxo as Callable<Runtime>>::RuntimeCall>::is_sub_type(&tx.function)
+            // {
+            //     match Utxo::validate_transaction(&transaction) {
+            //         // Transaction verification failed
+            //         Err(e) => {
+            //             sp_runtime::print(e);
+            //             return Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(1)));
+            //         }
+            //         // Race condition, or Transaction is good to go
+            //         Ok(tv) => { return Ok(tv); }
+            //     }
+            // }
+
+            // Fall back to default logic for non UTXO-spending extrinsics
 			Executive::validate_transaction(source, tx, block_hash)
 		}
 	}
diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs
index 258420d..75498bf 100644
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -326,12 +326,12 @@ impl pallet_transaction_payment::Config for Runtime {
 }
 
 
-// TODO [5-runtime]
-// impl utxo::Config for Runtime {
-//     type RuntimeEvent = RuntimeEvent;
-//     type BlockAuthor = BlockAuthor;
-//     type Issuance = issuance::BitcoinHalving;
-// }
+// [5-runtime]
+impl utxo::Config for Runtime {
+    type RuntimeEvent = RuntimeEvent;
+    type BlockAuthor = BlockAuthor;
+    type Issuance = issuance::BitcoinHalving;
+}
 
 
 construct_runtime!(
@@ -344,8 +344,8 @@ construct_runtime!(
 		Sha3DifficultyAdjustment: difficulty::<Instance2>,
 		KeccakDifficultyAdjustment: difficulty::<Instance3>,
 		BlockAuthor: block_author,
-        // TODO [5-runtime]
-        // Utxo: utxo,
+        // [5-runtime]
+        Utxo: utxo,
 	}
 );
 
@@ -436,21 +436,21 @@ impl_runtime_apis! {
 			tx: <Block as BlockT>::Extrinsic,
 			block_hash: <Block as BlockT>::Hash,
 		) -> TransactionValidity {
-            // TODO [5-runtime]
-
-            // // Extrinsics representing UTXO transaction need some special handling
-            // if let Some(&utxo::Call::spend{ ref transaction }) = IsSubType::<<Utxo as Callable<Runtime>>::RuntimeCall>::is_sub_type(&tx.function)
-            // {
-            //     match Utxo::validate_transaction(&transaction) {
-            //         // Transaction verification failed
-            //         Err(e) => {
-            //             sp_runtime::print(e);
-            //             return Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(1)));
-            //         }
-            //         // Race condition, or Transaction is good to go
-            //         Ok(tv) => { return Ok(tv); }
-            //     }
-            // }
+            // [5-runtime]
+
+            // Extrinsics representing UTXO transaction need some special handling
+            if let Some(&utxo::Call::spend{ ref transaction }) = IsSubType::<<Utxo as Callable<Runtime>>::RuntimeCall>::is_sub_type(&tx.function)
+            {
+                match Utxo::validate_transaction(&transaction) {
+                    // Transaction verification failed
+                    Err(e) => {
+                        sp_runtime::print(e);
+                        return Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(1)));
+                    }
+                    // Race condition, or Transaction is good to go
+                    Ok(tv) => { return Ok(tv); }
+                }
+            }
 
             // Fall back to default logic for non UTXO-spending extrinsics
 			Executive::validate_transaction(source, tx, block_hash)

Genesis Builder

[!Note] Resolve all TODO in runtime/src/utxo.rs and runtime/src/chain_spec.rs to complete this step.

Reading Materials

We've almost complete the UTXO pallet. However we have no balance to test it, that's quite ridiculous 🫤.

In this tutorial, I'll show you how to add gensis data for pallet, have initial UTXO balances, and something to easier to test.

Moreover, you can add faucet extrinsic to pallet, that's work too. I let this is challenge for you. Feel free to complete it. The solution is on main branch.

Implement

Firstly, we've to declare genesis data type.

[!Important] Because code is built on no-std feature. If we keep using the TransactionOutput struct, we'll get error

... "the trait Serialize is not implemented for TransactionOutput" ...

... "the trait Deserialize<'_> is not implemented for TransactionOutput" ...

Hence, we need to simplify data type to make it work in both std and no-std feature.

#![allow(unused)]
fn main() {
...
/// Genesis Utxo Type
pub type GenesisUtxoType = (Value, H256);

...
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
    pub _ph_data: Option<PhantomData<T>>,
    pub genesis_utxos: Vec<GenesisUtxoType>,
}
}

Implement Default trait for GenesisConfig:

#![allow(unused)]
fn main() {
impl<T: Config> Default for GenesisConfig<T> {
    fn default() -> Self {
        Self {
            _ph_data: Default::default(),
            genesis_utxos: Vec::<GenesisUtxoType>::new(),
        }
    }
}
}

Implement logic to build genesis data

#![allow(unused)]
fn main() {
#[pallet::genesis_build]
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
    fn build(&self) {
        for utxo in self.genesis_utxos.iter() {
            let utxo = TransactionOutput { value: utxo.0, pubkey: utxo.1 };
            let hash = BlakeTwo256::hash_of(&utxo);
            Pallet::<T>::store_utxo(&utxo, hash);
        }
    }
}
}

Additionally, I've put some codes to make it easier for testing as mentioned above

#![allow(unused)]
fn main() {
...

/// Keep track of latest UTXO hash of account
/// Mapping from `sr25519::Pubkey` to `BlakeTwo256::hash_of(transaction, index)`
/// Just for testing 🫤
/// Because 1 account may have multiple UTXOs
#[pallet::storage]
#[pallet::getter(fn utxo_of)]
pub type UtxoOf<T: Config> =
    StorageMap<Hasher = Identity, Key = Public, Value = H256, QueryKind = OptionQuery>;

...

fn store_utxo(utxo: &TransactionOutput, hash: H256) {
    ...    
    // Convert H256 back to sr25519::Public
    let pubkey = Public::from_h256(utxo.pubkey);
    UtxoOf::<T>::insert(pubkey, hash);
}

...
}

Move on the node/src/chain_spec.rs, add some genesis data for pallet UTXO:


...

use academy_pow_runtime::{
    AccountId,
    SS58Prefix,
    Signature,
    TOKEN_DECIMALS,
    TOKEN_SYMBOL,
    WASM_BINARY,
+   utxo::{GenesisUtxoType, Value},
};

...

pub fn development_config() -> Result<ChainSpec, String> {
    Ok(ChainSpec::builder(
        WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
        ForkingExtensions {
            manual_mode: 1, // change this to `0` if you want to try `auto_fork_validation`
            add_sha3_keccak: 10,
            remove_md5: 20,
            split_sha3_keccak: 30,
            maxi_position: String::from("follow-mining"),
        },
    )
    .with_name("Development")
    .with_id("dev")
    .with_chain_type(ChainType::Development)
    .with_genesis_config_patch(genesis(
        // Pre-funded accounts
        vec![
            get_account_id_from_seed::<sr25519::Public>("Alice"),
            get_account_id_from_seed::<sr25519::Public>("Bob"),
            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
        ],
        // Initial Difficulty
        4_000_000,
+       vec![
+           get_account_id_from_seed::<sr25519::Public>("Alice"),
+           get_account_id_from_seed::<sr25519::Public>("Bob"),
+           get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
+           get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
+       ],
    ))
    .with_properties(system_properties())
    .build())
}

...


pub fn testnet_config() -> Result<ChainSpec, String> {
    Ok(ChainSpec::builder(
        WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
        ForkingExtensions {
            manual_mode: 1,
            add_sha3_keccak: 0,
            remove_md5: 0,
            split_sha3_keccak: 0,
            maxi_position: String::new(),
        },
    )
    .with_name("Testnet")
    .with_id("testnet")
    .with_chain_type(ChainType::Local)
    .with_genesis_config_patch(genesis(
        vec![
            get_account_id_from_seed::<sr25519::Public>("Alice"),
            get_account_id_from_seed::<sr25519::Public>("Bob"),
            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
        ],
        4_000_000,
+        vec![
+            get_account_id_from_seed::<sr25519::Public>("Alice"),
+            get_account_id_from_seed::<sr25519::Public>("Bob"),
+            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
+            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
+        ],
    ))
    .with_properties(system_properties())
    .build())
}

...



fn genesis(
    endowed_accounts: Vec<AccountId>,
    initial_difficulty: u32,
+   utxo_genesis_accounts: Vec<AccountId>,
) -> serde_json::Value {
    serde_json::json!({
        "balances": {
            // Configure endowed accounts with initial balance of 1 << 50.
            "balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 50)).collect::<Vec<_>>(),
        },
        "keccakDifficultyAdjustment": {
            "initialDifficulty": u32_to_u8_32(initial_difficulty),
        },
        "md5DifficultyAdjustment": {
            "initialDifficulty": u32_to_u8_32(initial_difficulty),
        },
        "sha3DifficultyAdjustment": {
            "initialDifficulty": u32_to_u8_32(initial_difficulty),
        },
+         "utxo": {
+             "genesisUtxos": utxo_genesis_accounts
+                 .iter().cloned()
+                 .map(|k| {
+                     let hash = H256::from_slice(&k.as_slice()); 
+                     let value: Value = (1u64 << 50).into();
+                     let genesis_utxo: GenesisUtxoType = (value, hash);
+                     genesis_utxo
+                 }).collect::<Vec<GenesisUtxoType>>(),
+         },
    })
}

...

We've add some balances for Alice, Bob, also hard-derive account of Alice and Bob. Let's testing.


Build the code

cargo build --release
# start temporary local node in development environment
./target/release/academy-pow --dev --tmp

[!Note] Because Substrate default account is in SS58 format, so we've to map that address to sr25519 format. Powerful tool to convert SS58 account to sr25519::Pubkey: https://polkadot.subscan.io/tools/format_transform

  • Alice: from 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY to 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
  • Bob: from 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty to 0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48

Direct to https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/chainstate.

Select pallet UTXO > utxoOf:

  • Input: 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d, press + button.
  • Output:
utxo.utxoOf: Option<H256>
0xc670c5f69081da78af400552edcafa3f0f31e84db1b50dd70776e0f87477b3dc`

Select pallet UTXO > utxoStore:

  • Input: 0xc670c5f69081da78af400552edcafa3f0f31e84db1b50dd70776e0f87477b3dc, press + button.
  • Output:
utxo.utxoStore: Option<AcademyPowRuntimeUtxoTransactionOutput>
{
  value: 1,125,899,906,842,624
  pubkey: 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
}

Great work completing a new step! 💪 You're almost at the finish line. Now, let's dive into last step. Run this command to continue:

#![allow(unused)]
fn main() {
use std::str::FromStr;

use academy_pow_runtime::{
	AccountId, SS58Prefix, Signature, TOKEN_DECIMALS, TOKEN_SYMBOL, WASM_BINARY,
    // TODO [6-genesis-builder]
    utxo::{GenesisUtxoType, Value},
};
use multi_pow::{ForkHeights, ForkingConfig, MaxiPosition};
use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
use sc_service::ChainType;
use serde::{Deserialize, Serialize};
use sp_core::{sr25519, ByteArray, Pair, Public, H256};
use sp_runtime::traits::{IdentifyAccount, Verify};

/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
pub type ChainSpec = sc_service::GenericChainSpec<ForkingExtensions>;

/// PoW and Forking related chain spec extensions to configure the client side forking behavior.
///
/// The forks here are all related to adding and removing hash algorithms from the PoW.
/// The chain begins supporting only md5. Later is adds sha3 and keccak. Later it removes md5.
/// And finally there is a contentious fork where people become maxis.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]
#[serde(deny_unknown_fields)]
pub struct ForkingExtensions {
	/// Manual mode is intended for when we you are running a live workshop.
	/// No forking happens automatically. Rather, you have to hard-code the forks.
	///
	/// If manual mode is enabled, the rest of the parameters are ignored.
	/// This should really be an enum, but I have to work around the broken extension system.
	///
	/// Aww damn it! I can't even use bool in this broken system? Okay then I guess 0 means
	/// automatic mode and anything else means manual mode.
	pub manual_mode: u32,
	/// The block height to perform the soft fork that adds sha3 and keccak support.
	pub add_sha3_keccak: u32,
	/// The block height to perform the hard fork that removes md5 support.
	pub remove_md5: u32,
	/// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
	pub split_sha3_keccak: u32,
	// Damn extension thing is so fragile, I can't even use an enum here.
	// Let alone that time I tried to use the forked value feature.
	/// The political position that this node will take at the contentious fork.
	pub maxi_position: String,
}

impl From<&ForkingExtensions> for ForkingConfig {
	fn from(e: &ForkingExtensions) -> Self {
		if e.manual_mode > 0 {
			return Self::Manual;
		}

		let fork_heights = ForkHeights {
			add_sha3_keccak: e.add_sha3_keccak,
			remove_md5: e.remove_md5,
			split_sha3_keccak: e.split_sha3_keccak,
		};

		let maxi_position =
			MaxiPosition::from_str(&e.maxi_position).expect("Should have a valid maxi position...");

		Self::Automatic(fork_heights, maxi_position)
	}
}

impl ForkingExtensions {
	/// Try to get the extension from the given `ChainSpec`.
	pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {
		sc_chain_spec::get_extension(chain_spec.extensions())
	}
}

/// Generate a crypto pair from seed.
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
	TPublic::Pair::from_string(&format!("//{}", seed), None)
		.expect("static values are valid; qed")
		.public()
}

type AccountPublic = <Signature as Verify>::Signer;

/// Generate an account ID from seed.
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
where
	AccountPublic: From<<TPublic::Pair as Pair>::Public>,
{
	AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
}

pub fn development_config() -> Result<ChainSpec, String> {
	Ok(ChainSpec::builder(
		WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
		ForkingExtensions {
			manual_mode: 1, // change this to `0` if you want to try `auto_fork_validation`
			add_sha3_keccak: 10,
			remove_md5: 20,
			split_sha3_keccak: 30,
			maxi_position: String::from("follow-mining"),
		},
	)
	.with_name("Development")
	.with_id("dev")
	.with_chain_type(ChainType::Development)
	.with_genesis_config_patch(genesis(
		// Pre-funded accounts
		vec![
			get_account_id_from_seed::<sr25519::Public>("Alice"),
			get_account_id_from_seed::<sr25519::Public>("Bob"),
			get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
			get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
		],
		// Initial Difficulty
		4_000_000,
        // TODO [6-genesis-builder]
        // vec![
        //     get_account_id_from_seed::<sr25519::Public>("Alice"),
        //     get_account_id_from_seed::<sr25519::Public>("Bob"),
        //     get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
        //     get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
        // ],
	))
	.with_properties(system_properties())
	.build())
}

pub fn testnet_config() -> Result<ChainSpec, String> {
	Ok(ChainSpec::builder(
		WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
		ForkingExtensions {
			manual_mode: 1,
			add_sha3_keccak: 0,
			remove_md5: 0,
			split_sha3_keccak: 0,
			maxi_position: String::new(),
		},
	)
	.with_name("Testnet")
	.with_id("testnet")
	.with_chain_type(ChainType::Local)
	.with_genesis_config_patch(genesis(
		vec![
			get_account_id_from_seed::<sr25519::Public>("Alice"),
			get_account_id_from_seed::<sr25519::Public>("Bob"),
			get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
			get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
		],
		4_000_000,
        // TODO [6-genesis-builder]
        // vec![
        //     get_account_id_from_seed::<sr25519::Public>("Alice"),
        //     get_account_id_from_seed::<sr25519::Public>("Bob"),
        //     get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
        //     get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
        // ],
	))
	.with_properties(system_properties())
	.build())
}

fn genesis(
    endowed_accounts: Vec<AccountId>,
    initial_difficulty: u32,
    // TODO [6-genesis-builder]
    // utxo_genesis_accounts: Vec<AccountId>,
) -> serde_json::Value {
	serde_json::json!({
		"balances": {
			// Configure endowed accounts with initial balance of 1 << 50.
			"balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 50)).collect::<Vec<_>>(),
		},
		"keccakDifficultyAdjustment": {
			"initialDifficulty": u32_to_u8_32(initial_difficulty),
		},
		"md5DifficultyAdjustment": {
			"initialDifficulty": u32_to_u8_32(initial_difficulty),
		},
		"sha3DifficultyAdjustment": {
			"initialDifficulty": u32_to_u8_32(initial_difficulty),
		},
        // TODO [6-genesis-builder]
        // "utxo": {
        //     "genesisUtxos": utxo_genesis_accounts
        //         .iter().cloned()
        //         .map(|k| {
        //             let hash = H256::from_slice(&k.as_slice()); 
        //             let value: Value = (1u64 << 50).into();
        //             let genesis_utxo: GenesisUtxoType = (value, hash);

        //             genesis_utxo
        //         }).collect::<Vec<GenesisUtxoType>>(),
        // },
	})
}

/// Convert u32 (default value) to [u8;32] (U256)
/// in little-endian format
pub fn u32_to_u8_32(num: u32) -> [u8; 32] {
	let mut result = [0u8; 32];
	let bytes = num.to_le_bytes();
	result[..4].copy_from_slice(&bytes);
	result
}

fn system_properties() -> sc_chain_spec::Properties {
	let mut properties = sc_chain_spec::Properties::new();

	properties.insert("ss58Format".into(), SS58Prefix::get().into());
	properties.insert("tokenSymbol".into(), TOKEN_SYMBOL.into());
	properties.insert("tokenDecimals".into(), TOKEN_DECIMALS.into());

	properties
}
}
#![allow(unused)]
fn main() {
// We make sure this pallet uses `no_std` for compiling to Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_core::{
    sr25519::{Public, Signature},
    ByteArray, H256, H512,
};
use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

use super::{block_author::BlockAuthor, issuance::Issuance};

pub use pallet::*;

/// [2-data-structure]
pub type Value = u128;

/// [2-data-structure]
/// Single transaction to be dispatched
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct Transaction {
    /// UTXOs to be used as inputs for current transaction
    pub inputs: Vec<TransactionInput>,
    /// UTXOs to be created as a result of current transaction dispatch
    pub outputs: Vec<TransactionOutput>,
}

/// [2-data-structure]
/// Single transaction input that refers to one UTXO
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionInput {
    /// Reference to an UTXO to be spent
    pub outpoint: H256,

    /// Proof that transaction owner is authorized to spend referred UTXO &
    /// that the entire transaction is untampered
    pub sigscript: H512,
}

/// [2-data-structure]
/// Single transaction output to create upon transaction dispatch
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionOutput {
    /// Value associated with this output
    pub value: Value,

    /// Public key associated with this output. In order to spend this output
    /// owner must provide a proof by hashing the whole `Transaction` and
    /// signing it with a corresponding private key.
    pub pubkey: H256,
}


/// TODO [6-genesis-builder]
/// Because code is built on `no-std` feature.
/// And we got error:
/// ```
/// ...
/// the trait `Serialize` is not implemented for `TransactionOutput`
/// the trait `Deserialize<'_>` is not implemented for `TransactionOutput`
/// ...
/// ```
///
/// Hence, we need to simplify data type to make it work in both `std` and `no-std` feature.
/// Genesis Utxo Type
// pub type GenesisUtxoType = (Value, H256);

#[frame_support::pallet(dev_mode)]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    use super::*;

    /// [2-data-structure]
    #[pallet::config]
    pub trait Config: frame_system::Config {
        /// Because this pallet emits events, it depends on the runtime's definition of an event.
        /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
        type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

        /// A source to determine the block author
        type BlockAuthor: BlockAuthor;

        /// A source to determine the issuance portion of the block reward
        type Issuance: Issuance<BlockNumberFor<Self>, Value>;
    }

    #[pallet::pallet]
    pub struct Pallet<T>(_);


    /// [2-data-structure]
    /// Total reward value to be redistributed among authorities.
    /// It is accumulated from transactions during block execution
    /// and then dispersed to validators on block finalization.
    #[pallet::storage]
    #[pallet::getter(fn total_reward)]
    pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;

    /// [2-data-structure]
    /// All valid unspent transaction outputs are stored in this map.
    /// Initial set of UTXO is populated from the list stored in genesis.
    /// We use the identity hasher here because the cryptographic hashing is
    /// done explicitly.
    /// Mapping from `BlakeTwo256::hash_of(transaction, index)` to `TransactionOutput`
    #[pallet::storage]
    #[pallet::getter(fn utxo_store)]
    pub type UtxoStore<T: Config> = StorageMap<
        Hasher = Identity,
        Key = H256,
        Value = TransactionOutput,
        QueryKind = OptionQuery,
    >;

    /// TODO [6-genesis-builder]
    /// Keep track of latest UTXO hash of account
    /// Mapping from `sr25519::Pubkey` to `BlakeTwo256::hash_of(transaction, index)`
    /// Just for testing 🫤
    /// Because 1 account may have multiple UTXOs
    // #[pallet::storage]
    // #[pallet::getter(fn utxo_of)]
    // pub type UtxoOf<T: Config> =
    //     StorageMap<Hasher = Identity, Key = Public, Value = H256, QueryKind = OptionQuery>;

    /// TODO [6-genesis-builder]
    // #[pallet::genesis_config]
    // pub struct GenesisConfig<T: Config> {
    //     pub _ph_data: Option<PhantomData<T>>,
    //     pub genesis_utxos: Vec<GenesisUtxoType>,
    // }

    /// TODO [6-genesis-builder]
    // impl<T: Config> Default for GenesisConfig<T> {
    //     fn default() -> Self {
    //         Self {
    //             _ph_data: Default::default(),
    //             genesis_utxos: Vec::<GenesisUtxoType>::new(),
    //         }
    //     }
    // }

    /// TODO [6-genesis-builder]
    // #[pallet::genesis_build]
    // impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
    //     fn build(&self) {
    //         for utxo in self.genesis_utxos.iter() {
    //             let utxo = TransactionOutput { value: utxo.0, pubkey: utxo.1 };
    //             let hash = BlakeTwo256::hash_of(&utxo);
    //             Pallet::<T>::store_utxo(&utxo, hash);
    //         }
    //     }
    // }

    /// [2-data-structure]
    /// Pallets use events to inform users when important changes are made.
    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        /// Dispatch transaction successful
        TransactionSuccess(Transaction),
        /// UTXO out processed
        TransactionOutputProcessed(H256),
        /// Reward distributed to `BlockAuthor`
        RewardDistributed(Value, H256),
        /// Faucet to `To`
        Faucet(Value, H256),
        /// No one get reward
        RewardWasted,
    }


    /// [2-data-structure]
    /// Errors inform users that something went wrong.
    #[pallet::error]
    pub enum Error<T> {
        /// Missing `Transaction` Input
        MissingInput,
        /// Reward overflow
        RewardOverflow,
        /// Maximum transaction depth
        MaximumTransactionDepth,
        /// Empty input
        EmptyInput,
        /// Empty output
        EmptyOutput,
        /// Each input must only be used once
        DuplicatedInput,
        /// Each output must be defined only once
        DuplicatedOutput,
        /// Input value is overflow
        InputOverflow,
        /// Output value is overflow
        OutputOverflow,
        /// Output spent must lte than Input spent
        OutputOverInput,
        /// Zero amount spent
        ZeroAmount,
        /// Invalid signature
        InvalidSignature,
    }

    /// [4-dispersed-reward]
    #[pallet::hooks]
    impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
        fn on_finalize(_n: BlockNumberFor<T>) {
            match T::BlockAuthor::block_author() {
                // Block author did not provide key to claim reward
                None => Self::deposit_event(Event::RewardWasted),
                // Block author did provide key, so issue thir reward
                Some(author) => Self::disperse_reward(&author),
            }
        }
    }

    /// [2-data-structure]
    /// Define extrinsics / dispatchable function
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
            // [3-spend-utxo]
            // validate transaction
            let transaction_validity = Self::validate_transaction(&transaction)?;
            ensure!(
                transaction_validity.requires.is_empty(),
                Error::<T>::MissingInput
            );

            // implement logic
            Self::do_spend(&transaction, transaction_validity.priority as Value)?;
            // emit event
            Self::deposit_event(Event::<T>::TransactionSuccess(transaction));

            Ok(())
        }
    }

    /// [2-data-structure]
    /// Define intrinsics
    impl<T: Config> Pallet<T> {
        /// Implement spend logic, update storage to reflect changes made by transaction
        /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
        fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
            // [3-spend-utxo]
            // Calculate new reward total. The rest of `total_input - total_output` will be used for block reward.
            let new_total = TotalReward::<T>::get()
                .checked_add(reward)
                .ok_or(Error::<T>::RewardOverflow)?;
            TotalReward::<T>::put(new_total);

            // Removing spent UTXOs
            for input in &transaction.inputs {
                UtxoStore::<T>::remove(input.outpoint);
            }

            let mut index: u64 = 0;
            for output in &transaction.outputs {
                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), index));
                // validated before, this is safe
                index = index
                    .checked_add(1)
                    .ok_or(Error::<T>::MaximumTransactionDepth)
                    .unwrap();
                Self::store_utxo(output, hash);
                Self::deposit_event(Event::TransactionOutputProcessed(hash));
            }

            Ok(())
        }

        /// Redistribute combined reward value to block Author
        fn disperse_reward(author: &Public) {
            // [4-dispersed-reward]

            // take the rest of reward
            // plus issuance reward of current block number
            let reward = TotalReward::<T>::take()
            + T::Issuance::issuance(frame_system::Pallet::<T>::block_number());

            let utxo = TransactionOutput {
                value: reward,
                pubkey: H256::from_slice(author.as_slice()),
            };

            let hash = BlakeTwo256::hash_of(&(
                &utxo,
                frame_system::Pallet::<T>::block_number().saturated_into::<u64>(),
            ));

            Self::store_utxo(&utxo, hash);
            Self::deposit_event(Event::RewardDistributed(reward, hash));  
        }

        /// Mutate storage, insert / update new UTXOs
        fn store_utxo(utxo: &TransactionOutput, hash: H256) {
            // [3-spend-utxo]
            UtxoStore::<T>::insert(hash, utxo);
            
            // TODO [6-genesis-builder]
            // Convert H256 back to sr25519::Public
            // let pubkey = Public::from_h256(utxo.pubkey);
            // UtxoOf::<T>::insert(pubkey, hash);
        }

        /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
        fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
            // [3-spend-utxo]
            let mut trx = transaction.clone();
            for input in trx.inputs.iter_mut() {
                input.sigscript = H512::zero();
            }

            trx.encode()
        }

        /// Check transaction for validity, errors, & race conditions
        /// Called by both transaction pool and runtime execution
        pub fn validate_transaction(
            transaction: &Transaction,
        ) -> Result<ValidTransaction, &'static str> {
            // [3-spend-utxo]
            // Check inputs and outputs are not empty
            ensure!(!transaction.inputs.is_empty(), Error::<T>::EmptyInput);
            ensure!(!transaction.outputs.is_empty(), Error::<T>::EmptyOutput);

            // Check each input is used exactly once
            {
                let input_set: BTreeMap<_, ()> =
                    transaction.inputs.iter().map(|input| (input, ())).collect();
                ensure!(
                    input_set.len() == transaction.inputs.len(),
                    Error::<T>::DuplicatedInput
                );
            }
            {
                let output_set: BTreeMap<_, ()> = transaction
                    .outputs
                    .iter()
                    .map(|output| (output, ()))
                    .collect();
                ensure!(
                    output_set.len() == transaction.outputs.len(),
                    Error::<T>::DuplicatedOutput
                );
            }

            let mut total_input: Value = 0;
            let mut total_output: Value = 0;
            let mut output_index: u64 = 0;
            let simple_transaction = Self::get_simple_transaction(transaction);

            // Variables sent to transaction pool
            let mut missing_utxos = Vec::new();
            let mut new_utxos = Vec::new();
            let mut reward = 0;

            for input in transaction.inputs.iter() {
                // Check all inputs match to existing, unspent and unlocked outputs
                if let Some(input_utxo) = UtxoStore::<T>::get(&input.outpoint) {
                    // Check provided signatures are valid
                    let is_valid_sig = sp_io::crypto::sr25519_verify(
                        &Signature::from_raw(*input.sigscript.as_fixed_bytes()),
                        &simple_transaction,
                        &Public::from_h256(input_utxo.pubkey),
                    );
                    ensure!(is_valid_sig, Error::<T>::InvalidSignature);
                    // Check sum of input values does not overflow
                    total_input = total_input
                        .checked_add(input_utxo.value)
                        .ok_or(Error::<T>::InputOverflow)?;
                } else {
                    missing_utxos.push(input.outpoint.clone().as_fixed_bytes().to_vec());
                }
            }

            // Check each output is defined exactly once and has nonzero value
            for output in transaction.outputs.iter() {
                ensure!(output.value > 0, Error::<T>::ZeroAmount);
                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), output_index));
                output_index = output_index
                    .checked_add(1)
                    .ok_or(Error::<T>::MaximumTransactionDepth)?;
                // Check new outputs do not collide with existing ones
                ensure!(
                    !UtxoStore::<T>::contains_key(hash),
                    Error::<T>::DuplicatedOutput
                );
                // Check sum of output values does not overflow
                total_output = total_output
                    .checked_add(output.value)
                    .ok_or(Error::<T>::OutputOverflow)?;
                new_utxos.push(hash.as_fixed_bytes().to_vec());
            }

            // If no race condition, check the math
            if missing_utxos.is_empty() {
                // Check total output value must not exceed total input value
                ensure!(total_input >= total_output, Error::<T>::OutputOverInput);
                reward = total_input
                    .checked_sub(total_output)
                    .ok_or(Error::<T>::RewardOverflow)?;
            }

            // Returns transaction details
            Ok(ValidTransaction {
                requires: missing_utxos,
                provides: new_utxos,
                priority: reward as u64,
                longevity: TransactionLongevity::max_value(),
                propagate: true,
            })
        }
    }
}
}
#![allow(unused)]
fn main() {
use std::str::FromStr;

use academy_pow_runtime::{
	AccountId, SS58Prefix, Signature, TOKEN_DECIMALS, TOKEN_SYMBOL, WASM_BINARY,
    // [6-genesis-builder]
    utxo::{GenesisUtxoType, Value},
};
use multi_pow::{ForkHeights, ForkingConfig, MaxiPosition};
use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
use sc_service::ChainType;
use serde::{Deserialize, Serialize};
use sp_core::{sr25519, ByteArray, Pair, Public, H256};
use sp_runtime::traits::{IdentifyAccount, Verify};

/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
pub type ChainSpec = sc_service::GenericChainSpec<ForkingExtensions>;

/// PoW and Forking related chain spec extensions to configure the client side forking behavior.
///
/// The forks here are all related to adding and removing hash algorithms from the PoW.
/// The chain begins supporting only md5. Later is adds sha3 and keccak. Later it removes md5.
/// And finally there is a contentious fork where people become maxis.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]
#[serde(deny_unknown_fields)]
pub struct ForkingExtensions {
	/// Manual mode is intended for when we you are running a live workshop.
	/// No forking happens automatically. Rather, you have to hard-code the forks.
	///
	/// If manual mode is enabled, the rest of the parameters are ignored.
	/// This should really be an enum, but I have to work around the broken extension system.
	///
	/// Aww damn it! I can't even use bool in this broken system? Okay then I guess 0 means
	/// automatic mode and anything else means manual mode.
	pub manual_mode: u32,
	/// The block height to perform the soft fork that adds sha3 and keccak support.
	pub add_sha3_keccak: u32,
	/// The block height to perform the hard fork that removes md5 support.
	pub remove_md5: u32,
	/// The block height to perform the contentious fork where some become sha3- or keccak-maxis.
	pub split_sha3_keccak: u32,
	// Damn extension thing is so fragile, I can't even use an enum here.
	// Let alone that time I tried to use the forked value feature.
	/// The political position that this node will take at the contentious fork.
	pub maxi_position: String,
}

impl From<&ForkingExtensions> for ForkingConfig {
	fn from(e: &ForkingExtensions) -> Self {
		if e.manual_mode > 0 {
			return Self::Manual;
		}

		let fork_heights = ForkHeights {
			add_sha3_keccak: e.add_sha3_keccak,
			remove_md5: e.remove_md5,
			split_sha3_keccak: e.split_sha3_keccak,
		};

		let maxi_position =
			MaxiPosition::from_str(&e.maxi_position).expect("Should have a valid maxi position...");

		Self::Automatic(fork_heights, maxi_position)
	}
}

impl ForkingExtensions {
	/// Try to get the extension from the given `ChainSpec`.
	pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {
		sc_chain_spec::get_extension(chain_spec.extensions())
	}
}

/// Generate a crypto pair from seed.
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
	TPublic::Pair::from_string(&format!("//{}", seed), None)
		.expect("static values are valid; qed")
		.public()
}

type AccountPublic = <Signature as Verify>::Signer;

/// Generate an account ID from seed.
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
where
	AccountPublic: From<<TPublic::Pair as Pair>::Public>,
{
	AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
}

pub fn development_config() -> Result<ChainSpec, String> {
	Ok(ChainSpec::builder(
		WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
		ForkingExtensions {
			manual_mode: 1, // change this to `0` if you want to try `auto_fork_validation`
			add_sha3_keccak: 10,
			remove_md5: 20,
			split_sha3_keccak: 30,
			maxi_position: String::from("follow-mining"),
		},
	)
	.with_name("Development")
	.with_id("dev")
	.with_chain_type(ChainType::Development)
	.with_genesis_config_patch(genesis(
		// Pre-funded accounts
		vec![
			get_account_id_from_seed::<sr25519::Public>("Alice"),
			get_account_id_from_seed::<sr25519::Public>("Bob"),
			get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
			get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
		],
		// Initial Difficulty
		4_000_000,
        // [6-genesis-builder]
        vec![
            get_account_id_from_seed::<sr25519::Public>("Alice"),
            get_account_id_from_seed::<sr25519::Public>("Bob"),
            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
        ],
	))
	.with_properties(system_properties())
	.build())
}

pub fn testnet_config() -> Result<ChainSpec, String> {
	Ok(ChainSpec::builder(
		WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?,
		ForkingExtensions {
			manual_mode: 1,
			add_sha3_keccak: 0,
			remove_md5: 0,
			split_sha3_keccak: 0,
			maxi_position: String::new(),
		},
	)
	.with_name("Testnet")
	.with_id("testnet")
	.with_chain_type(ChainType::Local)
	.with_genesis_config_patch(genesis(
		vec![
			get_account_id_from_seed::<sr25519::Public>("Alice"),
			get_account_id_from_seed::<sr25519::Public>("Bob"),
			get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
			get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
		],
		4_000_000,
        // [6-genesis-builder]
        vec![
            get_account_id_from_seed::<sr25519::Public>("Alice"),
            get_account_id_from_seed::<sr25519::Public>("Bob"),
            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
        ],
	))
	.with_properties(system_properties())
	.build())
}

fn genesis(
    endowed_accounts: Vec<AccountId>,
    initial_difficulty: u32,
    // [6-genesis-builder]
    utxo_genesis_accounts: Vec<AccountId>,
) -> serde_json::Value {
	serde_json::json!({
		"balances": {
			// Configure endowed accounts with initial balance of 1 << 50.
			"balances": endowed_accounts.iter().cloned().map(|k| (k, 1u64 << 50)).collect::<Vec<_>>(),
		},
		"keccakDifficultyAdjustment": {
			"initialDifficulty": u32_to_u8_32(initial_difficulty),
		},
		"md5DifficultyAdjustment": {
			"initialDifficulty": u32_to_u8_32(initial_difficulty),
		},
		"sha3DifficultyAdjustment": {
			"initialDifficulty": u32_to_u8_32(initial_difficulty),
		},
        // [6-genesis-builder]
        "utxo": {
            "genesisUtxos": utxo_genesis_accounts
                .iter().cloned()
                .map(|k| {
                    let hash = H256::from_slice(&k.as_slice()); 
                    let value: Value = (1u64 << 50).into();
                    let genesis_utxo: GenesisUtxoType = (value, hash);

                    genesis_utxo
                }).collect::<Vec<GenesisUtxoType>>(),
        },
	})
}

/// Convert u32 (default value) to [u8;32] (U256)
/// in little-endian format
pub fn u32_to_u8_32(num: u32) -> [u8; 32] {
	let mut result = [0u8; 32];
	let bytes = num.to_le_bytes();
	result[..4].copy_from_slice(&bytes);
	result
}

fn system_properties() -> sc_chain_spec::Properties {
	let mut properties = sc_chain_spec::Properties::new();

	properties.insert("ss58Format".into(), SS58Prefix::get().into());
	properties.insert("tokenSymbol".into(), TOKEN_SYMBOL.into());
	properties.insert("tokenDecimals".into(), TOKEN_DECIMALS.into());

	properties
}
}
#![allow(unused)]
fn main() {
// We make sure this pallet uses `no_std` for compiling to Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_core::{
    sr25519::{Public, Signature},
    ByteArray, H256, H512,
};
use sp_runtime::traits::{BlakeTwo256, Hash, SaturatedConversion};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

use super::{block_author::BlockAuthor, issuance::Issuance};

pub use pallet::*;

/// [2-data-structure]
pub type Value = u128;

/// [2-data-structure]
/// Single transaction to be dispatched
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct Transaction {
    /// UTXOs to be used as inputs for current transaction
    pub inputs: Vec<TransactionInput>,
    /// UTXOs to be created as a result of current transaction dispatch
    pub outputs: Vec<TransactionOutput>,
}

/// [2-data-structure]
/// Single transaction input that refers to one UTXO
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionInput {
    /// Reference to an UTXO to be spent
    pub outpoint: H256,

    /// Proof that transaction owner is authorized to spend referred UTXO &
    /// that the entire transaction is untampered
    pub sigscript: H512,
}

/// [2-data-structure]
/// Single transaction output to create upon transaction dispatch
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[derive(PartialEq, Eq, PartialOrd, Ord, Default, Clone, Encode, Decode, Hash, Debug, TypeInfo)]
pub struct TransactionOutput {
    /// Value associated with this output
    pub value: Value,

    /// Public key associated with this output. In order to spend this output
    /// owner must provide a proof by hashing the whole `Transaction` and
    /// signing it with a corresponding private key.
    pub pubkey: H256,
}


/// [6-genesis-builder]
/// Because code is built on `no-std` feature.
/// And we got error:
/// ```
/// ...
/// the trait `Serialize` is not implemented for `TransactionOutput`
/// the trait `Deserialize<'_>` is not implemented for `TransactionOutput`
/// ...
/// ```
///
/// Hence, we need to simplify data type to make it work in both `std` and `no-std` feature.
/// Genesis Utxo Type
pub type GenesisUtxoType = (Value, H256);

#[frame_support::pallet(dev_mode)]
pub mod pallet {
    use frame_support::pallet_prelude::*;
    use frame_system::pallet_prelude::*;

    use super::*;

    /// [2-data-structure]
    #[pallet::config]
    pub trait Config: frame_system::Config {
        /// Because this pallet emits events, it depends on the runtime's definition of an event.
        /// Read more: https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/frame_runtime_types/index.html
        type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

        /// A source to determine the block author
        type BlockAuthor: BlockAuthor;

        /// A source to determine the issuance portion of the block reward
        type Issuance: Issuance<BlockNumberFor<Self>, Value>;
    }

    #[pallet::pallet]
    pub struct Pallet<T>(_);


    /// [2-data-structure]
    /// Total reward value to be redistributed among authorities.
    /// It is accumulated from transactions during block execution
    /// and then dispersed to validators on block finalization.
    #[pallet::storage]
    #[pallet::getter(fn total_reward)]
    pub type TotalReward<T: Config> = StorageValue<_, Value, ValueQuery>;

    /// [2-data-structure]
    /// All valid unspent transaction outputs are stored in this map.
    /// Initial set of UTXO is populated from the list stored in genesis.
    /// We use the identity hasher here because the cryptographic hashing is
    /// done explicitly.
    /// Mapping from `BlakeTwo256::hash_of(transaction, index)` to `TransactionOutput`
    #[pallet::storage]
    #[pallet::getter(fn utxo_store)]
    pub type UtxoStore<T: Config> = StorageMap<
        Hasher = Identity,
        Key = H256,
        Value = TransactionOutput,
        QueryKind = OptionQuery,
    >;

    /// [6-genesis-builder]
    /// Keep track of latest UTXO hash of account
    /// Mapping from `sr25519::Pubkey` to `BlakeTwo256::hash_of(transaction, index)`
    /// Just for testing 🫤
    /// Because 1 account may have multiple UTXOs
    #[pallet::storage]
    #[pallet::getter(fn utxo_of)]
    pub type UtxoOf<T: Config> =
        StorageMap<Hasher = Identity, Key = Public, Value = H256, QueryKind = OptionQuery>;

    /// [6-genesis-builder]
    #[pallet::genesis_config]
    pub struct GenesisConfig<T: Config> {
        pub _ph_data: Option<PhantomData<T>>,
        pub genesis_utxos: Vec<GenesisUtxoType>,
    }

    /// [6-genesis-builder]
    impl<T: Config> Default for GenesisConfig<T> {
        fn default() -> Self {
            Self {
                _ph_data: Default::default(),
                genesis_utxos: Vec::<GenesisUtxoType>::new(),
            }
        }
    }

    /// [6-genesis-builder]
    #[pallet::genesis_build]
    impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
        fn build(&self) {
            for utxo in self.genesis_utxos.iter() {
                let utxo = TransactionOutput { value: utxo.0, pubkey: utxo.1 };
                let hash = BlakeTwo256::hash_of(&utxo);
                Pallet::<T>::store_utxo(&utxo, hash);
            }
        }
    }

    /// [2-data-structure]
    /// Pallets use events to inform users when important changes are made.
    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        /// Dispatch transaction successful
        TransactionSuccess(Transaction),
        /// UTXO out processed
        TransactionOutputProcessed(H256),
        /// Reward distributed to `BlockAuthor`
        RewardDistributed(Value, H256),
        /// Faucet to `To`
        Faucet(Value, H256),
        /// No one get reward
        RewardWasted,
    }


    /// [2-data-structure]
    /// Errors inform users that something went wrong.
    #[pallet::error]
    pub enum Error<T> {
        /// Missing `Transaction` Input
        MissingInput,
        /// Reward overflow
        RewardOverflow,
        /// Maximum transaction depth
        MaximumTransactionDepth,
        /// Empty input
        EmptyInput,
        /// Empty output
        EmptyOutput,
        /// Each input must only be used once
        DuplicatedInput,
        /// Each output must be defined only once
        DuplicatedOutput,
        /// Input value is overflow
        InputOverflow,
        /// Output value is overflow
        OutputOverflow,
        /// Output spent must lte than Input spent
        OutputOverInput,
        /// Zero amount spent
        ZeroAmount,
        /// Invalid signature
        InvalidSignature,
    }

    /// [4-dispersed-reward]
    #[pallet::hooks]
    impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
        fn on_finalize(_n: BlockNumberFor<T>) {
            match T::BlockAuthor::block_author() {
                // Block author did not provide key to claim reward
                None => Self::deposit_event(Event::RewardWasted),
                // Block author did provide key, so issue thir reward
                Some(author) => Self::disperse_reward(&author),
            }
        }
    }

    /// [2-data-structure]
    /// Define extrinsics / dispatchable function
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn spend(_origin: OriginFor<T>, transaction: Transaction) -> DispatchResult {
            // [3-spend-utxo]
            // validate transaction
            let transaction_validity = Self::validate_transaction(&transaction)?;
            ensure!(
                transaction_validity.requires.is_empty(),
                Error::<T>::MissingInput
            );

            // implement logic
            Self::do_spend(&transaction, transaction_validity.priority as Value)?;
            // emit event
            Self::deposit_event(Event::<T>::TransactionSuccess(transaction));

            Ok(())
        }
    }

    /// [2-data-structure]
    /// Define intrinsics
    impl<T: Config> Pallet<T> {
        /// Implement spend logic, update storage to reflect changes made by transaction
        /// Where each UTXO key is a hash of the entire transaction and its order in the `TransactionOutputs` vector
        fn do_spend(transaction: &Transaction, reward: Value) -> DispatchResult {
            // [3-spend-utxo]
            // Calculate new reward total. The rest of `total_input - total_output` will be used for block reward.
            let new_total = TotalReward::<T>::get()
                .checked_add(reward)
                .ok_or(Error::<T>::RewardOverflow)?;
            TotalReward::<T>::put(new_total);

            // Removing spent UTXOs
            for input in &transaction.inputs {
                UtxoStore::<T>::remove(input.outpoint);
            }

            let mut index: u64 = 0;
            for output in &transaction.outputs {
                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), index));
                // validated before, this is safe
                index = index
                    .checked_add(1)
                    .ok_or(Error::<T>::MaximumTransactionDepth)
                    .unwrap();
                Self::store_utxo(output, hash);
                Self::deposit_event(Event::TransactionOutputProcessed(hash));
            }

            Ok(())
        }

        /// Redistribute combined reward value to block Author
        fn disperse_reward(author: &Public) {
            // [4-dispersed-reward]

            // take the rest of reward
            // plus issuance reward of current block number
            let reward = TotalReward::<T>::take()
            + T::Issuance::issuance(frame_system::Pallet::<T>::block_number());

            let utxo = TransactionOutput {
                value: reward,
                pubkey: H256::from_slice(author.as_slice()),
            };

            let hash = BlakeTwo256::hash_of(&(
                &utxo,
                frame_system::Pallet::<T>::block_number().saturated_into::<u64>(),
            ));

            Self::store_utxo(&utxo, hash);
            Self::deposit_event(Event::RewardDistributed(reward, hash));  
        }

        /// Mutate storage, insert / update new UTXOs
        fn store_utxo(utxo: &TransactionOutput, hash: H256) {
            // [3-spend-utxo]
            UtxoStore::<T>::insert(hash, utxo);
            
            // [6-genesis-builder]
            // Convert H256 back to sr25519::Public
            let pubkey = Public::from_h256(utxo.pubkey);
            UtxoOf::<T>::insert(pubkey, hash);
        }

        /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
        fn get_simple_transaction(transaction: &Transaction) -> Vec<u8> {
            // [3-spend-utxo]
            let mut trx = transaction.clone();
            for input in trx.inputs.iter_mut() {
                input.sigscript = H512::zero();
            }

            trx.encode()
        }

        /// Check transaction for validity, errors, & race conditions
        /// Called by both transaction pool and runtime execution
        pub fn validate_transaction(
            transaction: &Transaction,
        ) -> Result<ValidTransaction, &'static str> {
            // [3-spend-utxo]
            // Check inputs and outputs are not empty
            ensure!(!transaction.inputs.is_empty(), Error::<T>::EmptyInput);
            ensure!(!transaction.outputs.is_empty(), Error::<T>::EmptyOutput);

            // Check each input is used exactly once
            {
                let input_set: BTreeMap<_, ()> =
                    transaction.inputs.iter().map(|input| (input, ())).collect();
                ensure!(
                    input_set.len() == transaction.inputs.len(),
                    Error::<T>::DuplicatedInput
                );
            }
            {
                let output_set: BTreeMap<_, ()> = transaction
                    .outputs
                    .iter()
                    .map(|output| (output, ()))
                    .collect();
                ensure!(
                    output_set.len() == transaction.outputs.len(),
                    Error::<T>::DuplicatedOutput
                );
            }

            let mut total_input: Value = 0;
            let mut total_output: Value = 0;
            let mut output_index: u64 = 0;
            let simple_transaction = Self::get_simple_transaction(transaction);

            // Variables sent to transaction pool
            let mut missing_utxos = Vec::new();
            let mut new_utxos = Vec::new();
            let mut reward = 0;

            for input in transaction.inputs.iter() {
                // Check all inputs match to existing, unspent and unlocked outputs
                if let Some(input_utxo) = UtxoStore::<T>::get(&input.outpoint) {
                    // Check provided signatures are valid
                    let is_valid_sig = sp_io::crypto::sr25519_verify(
                        &Signature::from_raw(*input.sigscript.as_fixed_bytes()),
                        &simple_transaction,
                        &Public::from_h256(input_utxo.pubkey),
                    );
                    ensure!(is_valid_sig, Error::<T>::InvalidSignature);
                    // Check sum of input values does not overflow
                    total_input = total_input
                        .checked_add(input_utxo.value)
                        .ok_or(Error::<T>::InputOverflow)?;
                } else {
                    missing_utxos.push(input.outpoint.clone().as_fixed_bytes().to_vec());
                }
            }

            // Check each output is defined exactly once and has nonzero value
            for output in transaction.outputs.iter() {
                ensure!(output.value > 0, Error::<T>::ZeroAmount);
                let hash = BlakeTwo256::hash_of(&(&transaction.encode(), output_index));
                output_index = output_index
                    .checked_add(1)
                    .ok_or(Error::<T>::MaximumTransactionDepth)?;
                // Check new outputs do not collide with existing ones
                ensure!(
                    !UtxoStore::<T>::contains_key(hash),
                    Error::<T>::DuplicatedOutput
                );
                // Check sum of output values does not overflow
                total_output = total_output
                    .checked_add(output.value)
                    .ok_or(Error::<T>::OutputOverflow)?;
                new_utxos.push(hash.as_fixed_bytes().to_vec());
            }

            // If no race condition, check the math
            if missing_utxos.is_empty() {
                // Check total output value must not exceed total input value
                ensure!(total_input >= total_output, Error::<T>::OutputOverInput);
                reward = total_input
                    .checked_sub(total_output)
                    .ok_or(Error::<T>::RewardOverflow)?;
            }

            // Returns transaction details
            Ok(ValidTransaction {
                requires: missing_utxos,
                provides: new_utxos,
                priority: reward as u64,
                longevity: TransactionLongevity::max_value(),
                propagate: true,
            })
        }
    }
}
}
diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs
index 091d0e8..90e5e84 100644
--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -2,6 +2,8 @@ use std::str::FromStr;
 
 use academy_pow_runtime::{
 	AccountId, SS58Prefix, Signature, TOKEN_DECIMALS, TOKEN_SYMBOL, WASM_BINARY,
+    // TODO [6-genesis-builder]
+    utxo::{GenesisUtxoType, Value},
 };
 use multi_pow::{ForkHeights, ForkingConfig, MaxiPosition};
 use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
@@ -109,6 +111,13 @@ pub fn development_config() -> Result<ChainSpec, String> {
 		],
 		// Initial Difficulty
 		4_000_000,
+        // TODO [6-genesis-builder]
+        // vec![
+        //     get_account_id_from_seed::<sr25519::Public>("Alice"),
+        //     get_account_id_from_seed::<sr25519::Public>("Bob"),
+        //     get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
+        //     get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
+        // ],
 	))
 	.with_properties(system_properties())
 	.build())
@@ -136,12 +145,24 @@ pub fn testnet_config() -> Result<ChainSpec, String> {
 			get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
 		],
 		4_000_000,
+        // TODO [6-genesis-builder]
+        // vec![
+        //     get_account_id_from_seed::<sr25519::Public>("Alice"),
+        //     get_account_id_from_seed::<sr25519::Public>("Bob"),
+        //     get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
+        //     get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
+        // ],
 	))
 	.with_properties(system_properties())
 	.build())
 }
 
-fn genesis(endowed_accounts: Vec<AccountId>, initial_difficulty: u32) -> serde_json::Value {
+fn genesis(
+    endowed_accounts: Vec<AccountId>,
+    initial_difficulty: u32,
+    // TODO [6-genesis-builder]
+    // utxo_genesis_accounts: Vec<AccountId>,
+) -> serde_json::Value {
 	serde_json::json!({
 		"balances": {
 			// Configure endowed accounts with initial balance of 1 << 50.
@@ -156,6 +177,18 @@ fn genesis(endowed_accounts: Vec<AccountId>, initial_difficulty: u32) -> serde_j
 		"sha3DifficultyAdjustment": {
 			"initialDifficulty": u32_to_u8_32(initial_difficulty),
 		},
+        // TODO [6-genesis-builder]
+        // "utxo": {
+        //     "genesisUtxos": utxo_genesis_accounts
+        //         .iter().cloned()
+        //         .map(|k| {
+        //             let hash = H256::from_slice(&k.as_slice()); 
+        //             let value: Value = (1u64 << 50).into();
+        //             let genesis_utxo: GenesisUtxoType = (value, hash);
+
+        //             genesis_utxo
+        //         }).collect::<Vec<GenesisUtxoType>>(),
+        // },
 	})
 }
 
diff --git a/runtime/src/utxo.rs b/runtime/src/utxo.rs
index ed8ec6a..0632046 100644
--- a/runtime/src/utxo.rs
+++ b/runtime/src/utxo.rs
@@ -57,6 +57,21 @@ pub struct TransactionOutput {
     pub pubkey: H256,
 }
 
+
+/// TODO [6-genesis-builder]
+/// Because code is built on `no-std` feature.
+/// And we got error:
+/// ```
+/// ...
+/// the trait `Serialize` is not implemented for `TransactionOutput`
+/// the trait `Deserialize<'_>` is not implemented for `TransactionOutput`
+/// ...
+/// ```
+///
+/// Hence, we need to simplify data type to make it work in both `std` and `no-std` feature.
+/// Genesis Utxo Type
+// pub type GenesisUtxoType = (Value, H256);
+
 #[frame_support::pallet(dev_mode)]
 pub mod pallet {
     use frame_support::pallet_prelude::*;
@@ -105,6 +120,44 @@ pub mod pallet {
         QueryKind = OptionQuery,
     >;
 
+    /// TODO [6-genesis-builder]
+    /// Keep track of latest UTXO hash of account
+    /// Mapping from `sr25519::Pubkey` to `BlakeTwo256::hash_of(transaction, index)`
+    /// Just for testing 🫤
+    /// Because 1 account may have multiple UTXOs
+    // #[pallet::storage]
+    // #[pallet::getter(fn utxo_of)]
+    // pub type UtxoOf<T: Config> =
+    //     StorageMap<Hasher = Identity, Key = Public, Value = H256, QueryKind = OptionQuery>;
+
+    /// TODO [6-genesis-builder]
+    // #[pallet::genesis_config]
+    // pub struct GenesisConfig<T: Config> {
+    //     pub _ph_data: Option<PhantomData<T>>,
+    //     pub genesis_utxos: Vec<GenesisUtxoType>,
+    // }
+
+    /// TODO [6-genesis-builder]
+    // impl<T: Config> Default for GenesisConfig<T> {
+    //     fn default() -> Self {
+    //         Self {
+    //             _ph_data: Default::default(),
+    //             genesis_utxos: Vec::<GenesisUtxoType>::new(),
+    //         }
+    //     }
+    // }
+
+    /// TODO [6-genesis-builder]
+    // #[pallet::genesis_build]
+    // impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
+    //     fn build(&self) {
+    //         for utxo in self.genesis_utxos.iter() {
+    //             let utxo = TransactionOutput { value: utxo.0, pubkey: utxo.1 };
+    //             let hash = BlakeTwo256::hash_of(&utxo);
+    //             Pallet::<T>::store_utxo(&utxo, hash);
+    //         }
+    //     }
+    // }
 
     /// [2-data-structure]
     /// Pallets use events to inform users when important changes are made.
@@ -250,7 +303,10 @@ pub mod pallet {
             // [3-spend-utxo]
             UtxoStore::<T>::insert(hash, utxo);
             
-            // // further update 😉
+            // TODO [6-genesis-builder]
+            // Convert H256 back to sr25519::Public
+            // let pubkey = Public::from_h256(utxo.pubkey);
+            // UtxoOf::<T>::insert(pubkey, hash);
         }
 
         /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.
diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs
index 90e5e84..71fc6c7 100644
--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -2,7 +2,7 @@ use std::str::FromStr;
 
 use academy_pow_runtime::{
 	AccountId, SS58Prefix, Signature, TOKEN_DECIMALS, TOKEN_SYMBOL, WASM_BINARY,
-    // TODO [6-genesis-builder]
+    // [6-genesis-builder]
     utxo::{GenesisUtxoType, Value},
 };
 use multi_pow::{ForkHeights, ForkingConfig, MaxiPosition};
@@ -111,13 +111,13 @@ pub fn development_config() -> Result<ChainSpec, String> {
 		],
 		// Initial Difficulty
 		4_000_000,
-        // TODO [6-genesis-builder]
-        // vec![
-        //     get_account_id_from_seed::<sr25519::Public>("Alice"),
-        //     get_account_id_from_seed::<sr25519::Public>("Bob"),
-        //     get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
-        //     get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
-        // ],
+        // [6-genesis-builder]
+        vec![
+            get_account_id_from_seed::<sr25519::Public>("Alice"),
+            get_account_id_from_seed::<sr25519::Public>("Bob"),
+            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
+            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
+        ],
 	))
 	.with_properties(system_properties())
 	.build())
@@ -145,13 +145,13 @@ pub fn testnet_config() -> Result<ChainSpec, String> {
 			get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
 		],
 		4_000_000,
-        // TODO [6-genesis-builder]
-        // vec![
-        //     get_account_id_from_seed::<sr25519::Public>("Alice"),
-        //     get_account_id_from_seed::<sr25519::Public>("Bob"),
-        //     get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
-        //     get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
-        // ],
+        // [6-genesis-builder]
+        vec![
+            get_account_id_from_seed::<sr25519::Public>("Alice"),
+            get_account_id_from_seed::<sr25519::Public>("Bob"),
+            get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
+            get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
+        ],
 	))
 	.with_properties(system_properties())
 	.build())
@@ -160,8 +160,8 @@ pub fn testnet_config() -> Result<ChainSpec, String> {
 fn genesis(
     endowed_accounts: Vec<AccountId>,
     initial_difficulty: u32,
-    // TODO [6-genesis-builder]
-    // utxo_genesis_accounts: Vec<AccountId>,
+    // [6-genesis-builder]
+    utxo_genesis_accounts: Vec<AccountId>,
 ) -> serde_json::Value {
 	serde_json::json!({
 		"balances": {
@@ -177,18 +177,18 @@ fn genesis(
 		"sha3DifficultyAdjustment": {
 			"initialDifficulty": u32_to_u8_32(initial_difficulty),
 		},
-        // TODO [6-genesis-builder]
-        // "utxo": {
-        //     "genesisUtxos": utxo_genesis_accounts
-        //         .iter().cloned()
-        //         .map(|k| {
-        //             let hash = H256::from_slice(&k.as_slice()); 
-        //             let value: Value = (1u64 << 50).into();
-        //             let genesis_utxo: GenesisUtxoType = (value, hash);
-
-        //             genesis_utxo
-        //         }).collect::<Vec<GenesisUtxoType>>(),
-        // },
+        // [6-genesis-builder]
+        "utxo": {
+            "genesisUtxos": utxo_genesis_accounts
+                .iter().cloned()
+                .map(|k| {
+                    let hash = H256::from_slice(&k.as_slice()); 
+                    let value: Value = (1u64 << 50).into();
+                    let genesis_utxo: GenesisUtxoType = (value, hash);
+
+                    genesis_utxo
+                }).collect::<Vec<GenesisUtxoType>>(),
+        },
 	})
 }
 
diff --git a/runtime/src/utxo.rs b/runtime/src/utxo.rs
index 0632046..5f0bda0 100644
--- a/runtime/src/utxo.rs
+++ b/runtime/src/utxo.rs
@@ -58,7 +58,7 @@ pub struct TransactionOutput {
 }
 
 
-/// TODO [6-genesis-builder]
+/// [6-genesis-builder]
 /// Because code is built on `no-std` feature.
 /// And we got error:
 /// ```
@@ -70,7 +70,7 @@ pub struct TransactionOutput {
 ///
 /// Hence, we need to simplify data type to make it work in both `std` and `no-std` feature.
 /// Genesis Utxo Type
-// pub type GenesisUtxoType = (Value, H256);
+pub type GenesisUtxoType = (Value, H256);
 
 #[frame_support::pallet(dev_mode)]
 pub mod pallet {
@@ -120,44 +120,44 @@ pub mod pallet {
         QueryKind = OptionQuery,
     >;
 
-    /// TODO [6-genesis-builder]
+    /// [6-genesis-builder]
     /// Keep track of latest UTXO hash of account
     /// Mapping from `sr25519::Pubkey` to `BlakeTwo256::hash_of(transaction, index)`
     /// Just for testing 🫤
     /// Because 1 account may have multiple UTXOs
-    // #[pallet::storage]
-    // #[pallet::getter(fn utxo_of)]
-    // pub type UtxoOf<T: Config> =
-    //     StorageMap<Hasher = Identity, Key = Public, Value = H256, QueryKind = OptionQuery>;
-
-    /// TODO [6-genesis-builder]
-    // #[pallet::genesis_config]
-    // pub struct GenesisConfig<T: Config> {
-    //     pub _ph_data: Option<PhantomData<T>>,
-    //     pub genesis_utxos: Vec<GenesisUtxoType>,
-    // }
-
-    /// TODO [6-genesis-builder]
-    // impl<T: Config> Default for GenesisConfig<T> {
-    //     fn default() -> Self {
-    //         Self {
-    //             _ph_data: Default::default(),
-    //             genesis_utxos: Vec::<GenesisUtxoType>::new(),
-    //         }
-    //     }
-    // }
-
-    /// TODO [6-genesis-builder]
-    // #[pallet::genesis_build]
-    // impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
-    //     fn build(&self) {
-    //         for utxo in self.genesis_utxos.iter() {
-    //             let utxo = TransactionOutput { value: utxo.0, pubkey: utxo.1 };
-    //             let hash = BlakeTwo256::hash_of(&utxo);
-    //             Pallet::<T>::store_utxo(&utxo, hash);
-    //         }
-    //     }
-    // }
+    #[pallet::storage]
+    #[pallet::getter(fn utxo_of)]
+    pub type UtxoOf<T: Config> =
+        StorageMap<Hasher = Identity, Key = Public, Value = H256, QueryKind = OptionQuery>;
+
+    /// [6-genesis-builder]
+    #[pallet::genesis_config]
+    pub struct GenesisConfig<T: Config> {
+        pub _ph_data: Option<PhantomData<T>>,
+        pub genesis_utxos: Vec<GenesisUtxoType>,
+    }
+
+    /// [6-genesis-builder]
+    impl<T: Config> Default for GenesisConfig<T> {
+        fn default() -> Self {
+            Self {
+                _ph_data: Default::default(),
+                genesis_utxos: Vec::<GenesisUtxoType>::new(),
+            }
+        }
+    }
+
+    /// [6-genesis-builder]
+    #[pallet::genesis_build]
+    impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
+        fn build(&self) {
+            for utxo in self.genesis_utxos.iter() {
+                let utxo = TransactionOutput { value: utxo.0, pubkey: utxo.1 };
+                let hash = BlakeTwo256::hash_of(&utxo);
+                Pallet::<T>::store_utxo(&utxo, hash);
+            }
+        }
+    }
 
     /// [2-data-structure]
     /// Pallets use events to inform users when important changes are made.
@@ -303,10 +303,10 @@ pub mod pallet {
             // [3-spend-utxo]
             UtxoStore::<T>::insert(hash, utxo);
             
-            // TODO [6-genesis-builder]
+            // [6-genesis-builder]
             // Convert H256 back to sr25519::Public
-            // let pubkey = Public::from_h256(utxo.pubkey);
-            // UtxoOf::<T>::insert(pubkey, hash);
+            let pubkey = Public::from_h256(utxo.pubkey);
+            UtxoOf::<T>::insert(pubkey, hash);
         }
 
         /// Strips a transaction of its Signature fields by replacing value with ZERO-initialized fixed hash.

Client script

In this section, we will write a client script to generate sigscript for UTXO transaction using Javascript and @polkadot/api.

Initialize Working Environment

In this step, we will initialize a basic Javascript project, where we can start building our simple client script.

Make sure you have installed Node.js in your machine.

NPM init

  1. Create a new directory for your project:
mkdir scripts/generate-signature
cd scripts/generate-signature
  1. In that folder, run the following command to initialize a new Node.js project:
npm init -y

You'll see the package.json file created in your project directory. This file contains metadata about your project, such as its name, version, description, author, and dependencies.

  1. Install necessary dependencies
npm install @polkadot/api @polkadot/keyring @polkadot/types @polkadot/util @polkadot/wasm-crypto
{
  "name": "generate-signature",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "generate-signature",
      "version": "1.0.0",
      "license": "ISC",
      "dependencies": {
        "@polkadot/api": "^15.5.2",
        "@polkadot/keyring": "^13.3.1",
        "@polkadot/types": "^15.5.2",
        "@polkadot/util": "^13.3.1",
        "@polkadot/wasm-crypto": "^7.4.1"
      }
    },
    "node_modules/@noble/curves": {
      "version": "1.8.1",
      "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz",
      "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==",
      "license": "MIT",
      "dependencies": {
        "@noble/hashes": "1.7.1"
      },
      "engines": {
        "node": "^14.21.3 || >=16"
      },
      "funding": {
        "url": "https://paulmillr.com/funding/"
      }
    },
    "node_modules/@noble/hashes": {
      "version": "1.7.1",
      "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz",
      "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==",
      "license": "MIT",
      "engines": {
        "node": "^14.21.3 || >=16"
      },
      "funding": {
        "url": "https://paulmillr.com/funding/"
      }
    },
    "node_modules/@polkadot-api/json-rpc-provider": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider/-/json-rpc-provider-0.0.1.tgz",
      "integrity": "sha512-/SMC/l7foRjpykLTUTacIH05H3mr9ip8b5xxfwXlVezXrNVLp3Cv0GX6uItkKd+ZjzVPf3PFrDF2B2/HLSNESA==",
      "license": "MIT",
      "optional": true
    },
    "node_modules/@polkadot-api/json-rpc-provider-proxy": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider-proxy/-/json-rpc-provider-proxy-0.1.0.tgz",
      "integrity": "sha512-8GSFE5+EF73MCuLQm8tjrbCqlgclcHBSRaswvXziJ0ZW7iw3UEMsKkkKvELayWyBuOPa2T5i1nj6gFOeIsqvrg==",
      "license": "MIT",
      "optional": true
    },
    "node_modules/@polkadot-api/metadata-builders": {
      "version": "0.3.2",
      "resolved": "https://registry.npmjs.org/@polkadot-api/metadata-builders/-/metadata-builders-0.3.2.tgz",
      "integrity": "sha512-TKpfoT6vTb+513KDzMBTfCb/ORdgRnsS3TDFpOhAhZ08ikvK+hjHMt5plPiAX/OWkm1Wc9I3+K6W0hX5Ab7MVg==",
      "license": "MIT",
      "optional": true,
      "dependencies": {
        "@polkadot-api/substrate-bindings": "0.6.0",
        "@polkadot-api/utils": "0.1.0"
      }
    },
    "node_modules/@polkadot-api/observable-client": {
      "version": "0.3.2",
      "resolved": "https://registry.npmjs.org/@polkadot-api/observable-client/-/observable-client-0.3.2.tgz",
      "integrity": "sha512-HGgqWgEutVyOBXoGOPp4+IAq6CNdK/3MfQJmhCJb8YaJiaK4W6aRGrdQuQSTPHfERHCARt9BrOmEvTXAT257Ug==",
      "license": "MIT",
      "optional": true,
      "dependencies": {
        "@polkadot-api/metadata-builders": "0.3.2",
        "@polkadot-api/substrate-bindings": "0.6.0",
        "@polkadot-api/utils": "0.1.0"
      },
      "peerDependencies": {
        "@polkadot-api/substrate-client": "0.1.4",
        "rxjs": ">=7.8.0"
      }
    },
    "node_modules/@polkadot-api/substrate-bindings": {
      "version": "0.6.0",
      "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-bindings/-/substrate-bindings-0.6.0.tgz",
      "integrity": "sha512-lGuhE74NA1/PqdN7fKFdE5C1gNYX357j1tWzdlPXI0kQ7h3kN0zfxNOpPUN7dIrPcOFZ6C0tRRVrBylXkI6xPw==",
      "license": "MIT",
      "optional": true,
      "dependencies": {
        "@noble/hashes": "^1.3.1",
        "@polkadot-api/utils": "0.1.0",
        "@scure/base": "^1.1.1",
        "scale-ts": "^1.6.0"
      }
    },
    "node_modules/@polkadot-api/substrate-client": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-client/-/substrate-client-0.1.4.tgz",
      "integrity": "sha512-MljrPobN0ZWTpn++da9vOvt+Ex+NlqTlr/XT7zi9sqPtDJiQcYl+d29hFAgpaeTqbeQKZwz3WDE9xcEfLE8c5A==",
      "license": "MIT",
      "optional": true,
      "dependencies": {
        "@polkadot-api/json-rpc-provider": "0.0.1",
        "@polkadot-api/utils": "0.1.0"
      }
    },
    "node_modules/@polkadot-api/utils": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/@polkadot-api/utils/-/utils-0.1.0.tgz",
      "integrity": "sha512-MXzWZeuGxKizPx2Xf/47wx9sr/uxKw39bVJUptTJdsaQn/TGq+z310mHzf1RCGvC1diHM8f593KrnDgc9oNbJA==",
      "license": "MIT",
      "optional": true
    },
    "node_modules/@polkadot/api": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-15.5.2.tgz",
      "integrity": "sha512-TZPJlnoYr5kAfINooSmbvUcUCQnKDmTdLKNJmMh7CvCOYqQSJjFnMyfxhjM1bBTIcqnP9nFIGkldy19ErZHtcQ==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/api-augment": "15.5.2",
        "@polkadot/api-base": "15.5.2",
        "@polkadot/api-derive": "15.5.2",
        "@polkadot/keyring": "^13.3.1",
        "@polkadot/rpc-augment": "15.5.2",
        "@polkadot/rpc-core": "15.5.2",
        "@polkadot/rpc-provider": "15.5.2",
        "@polkadot/types": "15.5.2",
        "@polkadot/types-augment": "15.5.2",
        "@polkadot/types-codec": "15.5.2",
        "@polkadot/types-create": "15.5.2",
        "@polkadot/types-known": "15.5.2",
        "@polkadot/util": "^13.3.1",
        "@polkadot/util-crypto": "^13.3.1",
        "eventemitter3": "^5.0.1",
        "rxjs": "^7.8.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/api-augment": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-15.5.2.tgz",
      "integrity": "sha512-EuE13KeifPj6PBfR3qMtqCq+Clbly/VX5adh53ljw7XTtHt8MKTlvhTK9pO9WHnixL6hUVH1f/Ekuzt8ROhpAg==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/api-base": "15.5.2",
        "@polkadot/rpc-augment": "15.5.2",
        "@polkadot/types": "15.5.2",
        "@polkadot/types-augment": "15.5.2",
        "@polkadot/types-codec": "15.5.2",
        "@polkadot/util": "^13.3.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/api-base": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/api-base/-/api-base-15.5.2.tgz",
      "integrity": "sha512-e8W2KRwn6pkI/JIOrOCT2RsVil072vxQ95X2HCqu5eMmn5vwyOHB2OaMWezXikMegnCF3XEDeIzSP/VxGWW+zA==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/rpc-core": "15.5.2",
        "@polkadot/types": "15.5.2",
        "@polkadot/util": "^13.3.1",
        "rxjs": "^7.8.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/api-derive": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-15.5.2.tgz",
      "integrity": "sha512-eSSPE0O9LE9jsRJIBqrPfHa7vCjE3NR+3ATdwAKBwK9LUfeCEEWud7c53njW8wLMSOiczxcX3JS2J9Rb0q7HCA==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/api": "15.5.2",
        "@polkadot/api-augment": "15.5.2",
        "@polkadot/api-base": "15.5.2",
        "@polkadot/rpc-core": "15.5.2",
        "@polkadot/types": "15.5.2",
        "@polkadot/types-codec": "15.5.2",
        "@polkadot/util": "^13.3.1",
        "@polkadot/util-crypto": "^13.3.1",
        "rxjs": "^7.8.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/keyring": {
      "version": "13.3.1",
      "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-13.3.1.tgz",
      "integrity": "sha512-PT3uG9MqciPyoEz/f23RRMSlht77fo1hZaA1Vbcs1Rz7h7qFC0+7jFI9Ak30EJh9V0I2YugfzqAe3NjjyDxlvw==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/util": "13.3.1",
        "@polkadot/util-crypto": "13.3.1",
        "tslib": "^2.8.0"
      },
      "engines": {
        "node": ">=18"
      },
      "peerDependencies": {
        "@polkadot/util": "13.3.1",
        "@polkadot/util-crypto": "13.3.1"
      }
    },
    "node_modules/@polkadot/networks": {
      "version": "13.3.1",
      "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-13.3.1.tgz",
      "integrity": "sha512-g/0OmCMUrbbW4RQ/xajTYd2SMJvFKY4kmMvpxtNN57hWQpY7c5oDXSz57jGH2uwvcBWeDfaNokcS+9hJL1RBcA==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/util": "13.3.1",
        "@substrate/ss58-registry": "^1.51.0",
        "tslib": "^2.8.0"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/rpc-augment": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-15.5.2.tgz",
      "integrity": "sha512-eDCcmgrb/csOcav/RRBPFkOdPRvRXVYlksCGlQuzobYkPZfPz5tIKmgenip/5qnviR6gag6tK9ara+8kZ/7tpw==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/rpc-core": "15.5.2",
        "@polkadot/types": "15.5.2",
        "@polkadot/types-codec": "15.5.2",
        "@polkadot/util": "^13.3.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/rpc-core": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-15.5.2.tgz",
      "integrity": "sha512-a4Xq3iEJvRA9gHE+QxMaIEOkgjuZUfW+uI3XLDtPgtxu2yF3hceyRl/K1m6E4AXR383VaxQ45wvDS1odPbmwaw==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/rpc-augment": "15.5.2",
        "@polkadot/rpc-provider": "15.5.2",
        "@polkadot/types": "15.5.2",
        "@polkadot/util": "^13.3.1",
        "rxjs": "^7.8.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/rpc-provider": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-15.5.2.tgz",
      "integrity": "sha512-LHDG4mY5moFdVyUuEyuF9hMVWgA+DoLeNYZjtOL88gSALpfjhBLt1Hjbm3R6VwvcxeVNTkteVGvCo0AlH123JQ==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/keyring": "^13.3.1",
        "@polkadot/types": "15.5.2",
        "@polkadot/types-support": "15.5.2",
        "@polkadot/util": "^13.3.1",
        "@polkadot/util-crypto": "^13.3.1",
        "@polkadot/x-fetch": "^13.3.1",
        "@polkadot/x-global": "^13.3.1",
        "@polkadot/x-ws": "^13.3.1",
        "eventemitter3": "^5.0.1",
        "mock-socket": "^9.3.1",
        "nock": "^13.5.5",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      },
      "optionalDependencies": {
        "@substrate/connect": "0.8.11"
      }
    },
    "node_modules/@polkadot/types": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-15.5.2.tgz",
      "integrity": "sha512-TANrhfovLgbG00ldFvZbOuwyzqibOOMAU9egGqnoFwz4x4vTNTBgNJRvQGF5w4+FhjcEepdxlLU/3yqFM98yzA==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/keyring": "^13.3.1",
        "@polkadot/types-augment": "15.5.2",
        "@polkadot/types-codec": "15.5.2",
        "@polkadot/types-create": "15.5.2",
        "@polkadot/util": "^13.3.1",
        "@polkadot/util-crypto": "^13.3.1",
        "rxjs": "^7.8.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/types-augment": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-15.5.2.tgz",
      "integrity": "sha512-Za5ifsiu2gSQkOBjwcCtCr5nz+PojsBoptdHKjMm0JHLgilNn0kNqriqRRrCiPkUO1656UXRQNCHpP6Vs8tncg==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/types": "15.5.2",
        "@polkadot/types-codec": "15.5.2",
        "@polkadot/util": "^13.3.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/types-codec": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-15.5.2.tgz",
      "integrity": "sha512-caQNGQ+QHVZV4hGSolYN9L9pMRZeo9rJzYoybT5LMIxX8QVdW3RM5HDesj1SKGSrgIJmooN4/5JzPjrFZ4C7Vw==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/util": "^13.3.1",
        "@polkadot/x-bigint": "^13.3.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/types-create": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-15.5.2.tgz",
      "integrity": "sha512-PbrT2mP5x7VTpwCZa/BCl8jl3y/s6UOwrjBL+pq8TErLEbkackn5a3cR4GaH9toeP5qlEaLbSWRFm24YcW8FOg==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/types-codec": "15.5.2",
        "@polkadot/util": "^13.3.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/types-known": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-15.5.2.tgz",
      "integrity": "sha512-4yk1DnIeAy4uImFf4yDyRRdgkf5nAagQzPZWO61uxhEA+Q2MxLHLDeLbUwFiLxLLvpM09Xke8rGbem/vPRg9nA==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/networks": "^13.3.1",
        "@polkadot/types": "15.5.2",
        "@polkadot/types-codec": "15.5.2",
        "@polkadot/types-create": "15.5.2",
        "@polkadot/util": "^13.3.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/types-support": {
      "version": "15.5.2",
      "resolved": "https://registry.npmjs.org/@polkadot/types-support/-/types-support-15.5.2.tgz",
      "integrity": "sha512-PT3MTSy69euAPtRQ3c2I7vM0OfAIQXU1yIWpYTcEkG+spTn4d0fcYeJjfxvAmcROJlpJoXf10YMsXKwx+gvOig==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/util": "^13.3.1",
        "tslib": "^2.8.1"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/util": {
      "version": "13.3.1",
      "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-13.3.1.tgz",
      "integrity": "sha512-5crLP/rUZOJzuo/W8t73J8PxpibJ5vrxY57rR6V+mIpCZd1ORiw0wxeHcV5F9Adpn7yJyuGBwxPbueNR5Rr1Zw==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/x-bigint": "13.3.1",
        "@polkadot/x-global": "13.3.1",
        "@polkadot/x-textdecoder": "13.3.1",
        "@polkadot/x-textencoder": "13.3.1",
        "@types/bn.js": "^5.1.6",
        "bn.js": "^5.2.1",
        "tslib": "^2.8.0"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/util-crypto": {
      "version": "13.3.1",
      "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-13.3.1.tgz",
      "integrity": "sha512-FU6yf3IY++DKlf0eqO9/obe2y1zuZ5rbqRs75fyOME/5VXio1fA3GIpW7aFphyneFRd78G8QLh8kn0oIwBGMNg==",
      "license": "Apache-2.0",
      "dependencies": {
        "@noble/curves": "^1.3.0",
        "@noble/hashes": "^1.3.3",
        "@polkadot/networks": "13.3.1",
        "@polkadot/util": "13.3.1",
        "@polkadot/wasm-crypto": "^7.4.1",
        "@polkadot/wasm-util": "^7.4.1",
        "@polkadot/x-bigint": "13.3.1",
        "@polkadot/x-randomvalues": "13.3.1",
        "@scure/base": "^1.1.7",
        "tslib": "^2.8.0"
      },
      "engines": {
        "node": ">=18"
      },
      "peerDependencies": {
        "@polkadot/util": "13.3.1"
      }
    },
    "node_modules/@polkadot/wasm-bridge": {
      "version": "7.4.1",
      "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.4.1.tgz",
      "integrity": "sha512-tdkJaV453tezBxhF39r4oeG0A39sPKGDJmN81LYLf+Fihb7astzwju+u75BRmDrHZjZIv00un3razJEWCxze6g==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/wasm-util": "7.4.1",
        "tslib": "^2.7.0"
      },
      "engines": {
        "node": ">=18"
      },
      "peerDependencies": {
        "@polkadot/util": "*",
        "@polkadot/x-randomvalues": "*"
      }
    },
    "node_modules/@polkadot/wasm-crypto": {
      "version": "7.4.1",
      "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.4.1.tgz",
      "integrity": "sha512-kHN/kF7hYxm1y0WeFLWeWir6oTzvcFmR4N8fJJokR+ajYbdmrafPN+6iLgQVbhZnDdxyv9jWDuRRsDnBx8tPMQ==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/wasm-bridge": "7.4.1",
        "@polkadot/wasm-crypto-asmjs": "7.4.1",
        "@polkadot/wasm-crypto-init": "7.4.1",
        "@polkadot/wasm-crypto-wasm": "7.4.1",
        "@polkadot/wasm-util": "7.4.1",
        "tslib": "^2.7.0"
      },
      "engines": {
        "node": ">=18"
      },
      "peerDependencies": {
        "@polkadot/util": "*",
        "@polkadot/x-randomvalues": "*"
      }
    },
    "node_modules/@polkadot/wasm-crypto-asmjs": {
      "version": "7.4.1",
      "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.4.1.tgz",
      "integrity": "sha512-pwU8QXhUW7IberyHJIQr37IhbB6DPkCG5FhozCiNTq4vFBsFPjm9q8aZh7oX1QHQaiAZa2m2/VjIVE+FHGbvHQ==",
      "license": "Apache-2.0",
      "dependencies": {
        "tslib": "^2.7.0"
      },
      "engines": {
        "node": ">=18"
      },
      "peerDependencies": {
        "@polkadot/util": "*"
      }
    },
    "node_modules/@polkadot/wasm-crypto-init": {
      "version": "7.4.1",
      "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.4.1.tgz",
      "integrity": "sha512-AVka33+f7MvXEEIGq5U0dhaA2SaXMXnxVCQyhJTaCnJ5bRDj0Xlm3ijwDEQUiaDql7EikbkkRtmlvs95eSUWYQ==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/wasm-bridge": "7.4.1",
        "@polkadot/wasm-crypto-asmjs": "7.4.1",
        "@polkadot/wasm-crypto-wasm": "7.4.1",
        "@polkadot/wasm-util": "7.4.1",
        "tslib": "^2.7.0"
      },
      "engines": {
        "node": ">=18"
      },
      "peerDependencies": {
        "@polkadot/util": "*",
        "@polkadot/x-randomvalues": "*"
      }
    },
    "node_modules/@polkadot/wasm-crypto-wasm": {
      "version": "7.4.1",
      "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.4.1.tgz",
      "integrity": "sha512-PE1OAoupFR0ZOV2O8tr7D1FEUAwaggzxtfs3Aa5gr+yxlSOaWUKeqsOYe1KdrcjmZVV3iINEAXxgrbzCmiuONg==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/wasm-util": "7.4.1",
        "tslib": "^2.7.0"
      },
      "engines": {
        "node": ">=18"
      },
      "peerDependencies": {
        "@polkadot/util": "*"
      }
    },
    "node_modules/@polkadot/wasm-util": {
      "version": "7.4.1",
      "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.4.1.tgz",
      "integrity": "sha512-RAcxNFf3zzpkr+LX/ItAsvj+QyM56TomJ0xjUMo4wKkHjwsxkz4dWJtx5knIgQz/OthqSDMR59VNEycQeNuXzA==",
      "license": "Apache-2.0",
      "dependencies": {
        "tslib": "^2.7.0"
      },
      "engines": {
        "node": ">=18"
      },
      "peerDependencies": {
        "@polkadot/util": "*"
      }
    },
    "node_modules/@polkadot/x-bigint": {
      "version": "13.3.1",
      "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-13.3.1.tgz",
      "integrity": "sha512-ewc708a7LUdrT92v9DsSAIbcJQBn3aR9/LavF/iyMOq5lZJyPXDSjAnskfMs818R3RLCrKVKfs+aKkxt2eqo8g==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/x-global": "13.3.1",
        "tslib": "^2.8.0"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/x-fetch": {
      "version": "13.3.1",
      "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-13.3.1.tgz",
      "integrity": "sha512-J+HM42j0KGqdC/eo7vmsdLPz74MR7+0My4km6TG9HGjKqqztwygtenpopPod2SbRnL4nHiEG0wZzpVOW6HN2gw==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/x-global": "13.3.1",
        "node-fetch": "^3.3.2",
        "tslib": "^2.8.0"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/x-global": {
      "version": "13.3.1",
      "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-13.3.1.tgz",
      "integrity": "sha512-861TeIw49a3JvkwlUWrddfG+JaUqtFZDsemYxxZIjjcRJLrKOsoKNqHbiHi2OPrwlX8PwAA/wc5I9Q4XRQ7KEg==",
      "license": "Apache-2.0",
      "dependencies": {
        "tslib": "^2.8.0"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/x-randomvalues": {
      "version": "13.3.1",
      "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-13.3.1.tgz",
      "integrity": "sha512-GIb0au3vIX2U/DRH0PRckM+1I4EIbU8PLX1roGJgN1MAYKWiylJTKPVoBMafMM87o8qauOevJ46uYB/qlfbiWg==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/x-global": "13.3.1",
        "tslib": "^2.8.0"
      },
      "engines": {
        "node": ">=18"
      },
      "peerDependencies": {
        "@polkadot/util": "13.3.1",
        "@polkadot/wasm-util": "*"
      }
    },
    "node_modules/@polkadot/x-textdecoder": {
      "version": "13.3.1",
      "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-13.3.1.tgz",
      "integrity": "sha512-g2R9O1p0ZsNDhZ3uEBZh6fQaVLlo3yFr0YNqt15v7e9lBI4APvTJ202EINlo2jB5lz/R438/BdjEA3AL+0zUtQ==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/x-global": "13.3.1",
        "tslib": "^2.8.0"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/x-textencoder": {
      "version": "13.3.1",
      "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-13.3.1.tgz",
      "integrity": "sha512-DnHLUdoKDYxekfxopuUuPB+j5Mu7Jemejcduu5gz3/89GP/sYPAu0CAVbq9B+hK1yGjBBj31eA4wkAV1oktYmg==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/x-global": "13.3.1",
        "tslib": "^2.8.0"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@polkadot/x-ws": {
      "version": "13.3.1",
      "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-13.3.1.tgz",
      "integrity": "sha512-ytqkC7FwVs4BlzNFAmPMFp+xD1KIdMMP/mvCSOrnxjlsyM5DVGop4x4c2ZgDUBmrFqmIiVkWDfMIZeOxui2OLQ==",
      "license": "Apache-2.0",
      "dependencies": {
        "@polkadot/x-global": "13.3.1",
        "tslib": "^2.8.0",
        "ws": "^8.18.0"
      },
      "engines": {
        "node": ">=18"
      }
    },
    "node_modules/@scure/base": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.4.tgz",
      "integrity": "sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==",
      "license": "MIT",
      "funding": {
        "url": "https://paulmillr.com/funding/"
      }
    },
    "node_modules/@substrate/connect": {
      "version": "0.8.11",
      "resolved": "https://registry.npmjs.org/@substrate/connect/-/connect-0.8.11.tgz",
      "integrity": "sha512-ofLs1PAO9AtDdPbdyTYj217Pe+lBfTLltdHDs3ds8no0BseoLeAGxpz1mHfi7zB4IxI3YyAiLjH6U8cw4pj4Nw==",
      "deprecated": "versions below 1.x are no longer maintained",
      "license": "GPL-3.0-only",
      "optional": true,
      "dependencies": {
        "@substrate/connect-extension-protocol": "^2.0.0",
        "@substrate/connect-known-chains": "^1.1.5",
        "@substrate/light-client-extension-helpers": "^1.0.0",
        "smoldot": "2.0.26"
      }
    },
    "node_modules/@substrate/connect-extension-protocol": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-2.2.1.tgz",
      "integrity": "sha512-GoafTgm/Jey9E4Xlj4Z5ZBt/H4drH2CNq8VrAro80rtoznrXnFDNVivLQzZN0Xaj2g8YXSn9pC9Oc9IovYZJXw==",
      "license": "GPL-3.0-only",
      "optional": true
    },
    "node_modules/@substrate/connect-known-chains": {
      "version": "1.9.1",
      "resolved": "https://registry.npmjs.org/@substrate/connect-known-chains/-/connect-known-chains-1.9.1.tgz",
      "integrity": "sha512-dWNf5x3hjrY4s+WEovPKL0jH58pyIaIiAM918aAdnp/VKkAMqOfhKzRWL7BqJDKCm95bL4fqnOfaXZ3SQpVoYw==",
      "license": "GPL-3.0-only",
      "optional": true
    },
    "node_modules/@substrate/light-client-extension-helpers": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/@substrate/light-client-extension-helpers/-/light-client-extension-helpers-1.0.0.tgz",
      "integrity": "sha512-TdKlni1mBBZptOaeVrKnusMg/UBpWUORNDv5fdCaJklP4RJiFOzBCrzC+CyVI5kQzsXBisZ+2pXm+rIjS38kHg==",
      "license": "MIT",
      "optional": true,
      "dependencies": {
        "@polkadot-api/json-rpc-provider": "^0.0.1",
        "@polkadot-api/json-rpc-provider-proxy": "^0.1.0",
        "@polkadot-api/observable-client": "^0.3.0",
        "@polkadot-api/substrate-client": "^0.1.2",
        "@substrate/connect-extension-protocol": "^2.0.0",
        "@substrate/connect-known-chains": "^1.1.5",
        "rxjs": "^7.8.1"
      },
      "peerDependencies": {
        "smoldot": "2.x"
      }
    },
    "node_modules/@substrate/ss58-registry": {
      "version": "1.51.0",
      "resolved": "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.51.0.tgz",
      "integrity": "sha512-TWDurLiPxndFgKjVavCniytBIw+t4ViOi7TYp9h/D0NMmkEc9klFTo+827eyEJ0lELpqO207Ey7uGxUa+BS1jQ==",
      "license": "Apache-2.0"
    },
    "node_modules/@types/bn.js": {
      "version": "5.1.6",
      "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.6.tgz",
      "integrity": "sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==",
      "license": "MIT",
      "dependencies": {
        "@types/node": "*"
      }
    },
    "node_modules/@types/node": {
      "version": "22.13.1",
      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
      "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
      "license": "MIT",
      "dependencies": {
        "undici-types": "~6.20.0"
      }
    },
    "node_modules/bn.js": {
      "version": "5.2.1",
      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
      "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
      "license": "MIT"
    },
    "node_modules/data-uri-to-buffer": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
      "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
      "license": "MIT",
      "engines": {
        "node": ">= 12"
      }
    },
    "node_modules/debug": {
      "version": "4.4.0",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
      "license": "MIT",
      "dependencies": {
        "ms": "^2.1.3"
      },
      "engines": {
        "node": ">=6.0"
      },
      "peerDependenciesMeta": {
        "supports-color": {
          "optional": true
        }
      }
    },
    "node_modules/eventemitter3": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
      "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
      "license": "MIT"
    },
    "node_modules/fetch-blob": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
      "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/jimmywarting"
        },
        {
          "type": "paypal",
          "url": "https://paypal.me/jimmywarting"
        }
      ],
      "license": "MIT",
      "dependencies": {
        "node-domexception": "^1.0.0",
        "web-streams-polyfill": "^3.0.3"
      },
      "engines": {
        "node": "^12.20 || >= 14.13"
      }
    },
    "node_modules/formdata-polyfill": {
      "version": "4.0.10",
      "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
      "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
      "license": "MIT",
      "dependencies": {
        "fetch-blob": "^3.1.2"
      },
      "engines": {
        "node": ">=12.20.0"
      }
    },
    "node_modules/json-stringify-safe": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
      "license": "ISC"
    },
    "node_modules/mock-socket": {
      "version": "9.3.1",
      "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.3.1.tgz",
      "integrity": "sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==",
      "license": "MIT",
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/ms": {
      "version": "2.1.3",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
      "license": "MIT"
    },
    "node_modules/nock": {
      "version": "13.5.6",
      "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.6.tgz",
      "integrity": "sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==",
      "license": "MIT",
      "dependencies": {
        "debug": "^4.1.0",
        "json-stringify-safe": "^5.0.1",
        "propagate": "^2.0.0"
      },
      "engines": {
        "node": ">= 10.13"
      }
    },
    "node_modules/node-domexception": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
      "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/jimmywarting"
        },
        {
          "type": "github",
          "url": "https://paypal.me/jimmywarting"
        }
      ],
      "license": "MIT",
      "engines": {
        "node": ">=10.5.0"
      }
    },
    "node_modules/node-fetch": {
      "version": "3.3.2",
      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
      "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
      "license": "MIT",
      "dependencies": {
        "data-uri-to-buffer": "^4.0.0",
        "fetch-blob": "^3.1.4",
        "formdata-polyfill": "^4.0.10"
      },
      "engines": {
        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/node-fetch"
      }
    },
    "node_modules/propagate": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
      "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
      "license": "MIT",
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/rxjs": {
      "version": "7.8.1",
      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
      "license": "Apache-2.0",
      "dependencies": {
        "tslib": "^2.1.0"
      }
    },
    "node_modules/scale-ts": {
      "version": "1.6.1",
      "resolved": "https://registry.npmjs.org/scale-ts/-/scale-ts-1.6.1.tgz",
      "integrity": "sha512-PBMc2AWc6wSEqJYBDPcyCLUj9/tMKnLX70jLOSndMtcUoLQucP/DM0vnQo1wJAYjTrQiq8iG9rD0q6wFzgjH7g==",
      "license": "MIT",
      "optional": true
    },
    "node_modules/smoldot": {
      "version": "2.0.26",
      "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-2.0.26.tgz",
      "integrity": "sha512-F+qYmH4z2s2FK+CxGj8moYcd1ekSIKH8ywkdqlOz88Dat35iB1DIYL11aILN46YSGMzQW/lbJNS307zBSDN5Ig==",
      "license": "GPL-3.0-or-later WITH Classpath-exception-2.0",
      "optional": true,
      "dependencies": {
        "ws": "^8.8.1"
      }
    },
    "node_modules/tslib": {
      "version": "2.8.1",
      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
      "license": "0BSD"
    },
    "node_modules/undici-types": {
      "version": "6.20.0",
      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
      "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
      "license": "MIT"
    },
    "node_modules/web-streams-polyfill": {
      "version": "3.3.3",
      "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
      "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
      "license": "MIT",
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/ws": {
      "version": "8.18.0",
      "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
      "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
      "license": "MIT",
      "engines": {
        "node": ">=10.0.0"
      },
      "peerDependencies": {
        "bufferutil": "^4.0.1",
        "utf-8-validate": ">=5.0.2"
      },
      "peerDependenciesMeta": {
        "bufferutil": {
          "optional": true
        },
        "utf-8-validate": {
          "optional": true
        }
      }
    }
  }
}
{
  "name": "generate-signature",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "@polkadot/api": "^15.5.2",
    "@polkadot/keyring": "^13.3.1",
    "@polkadot/types": "^15.5.2",
    "@polkadot/util": "^13.3.1",
    "@polkadot/wasm-crypto": "^7.4.1"
  }
}
diff --git a/scripts/generate-signature/package-lock.json b/scripts/generate-signature/package-lock.json
new file mode 100644
index 0000000..86de335
--- /dev/null
+++ b/scripts/generate-signature/package-lock.json
@@ -0,0 +1,929 @@
+{
+  "name": "generate-signature",
+  "version": "1.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "generate-signature",
+      "version": "1.0.0",
+      "license": "ISC",
+      "dependencies": {
+        "@polkadot/api": "^15.5.2",
+        "@polkadot/keyring": "^13.3.1",
+        "@polkadot/types": "^15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "@polkadot/wasm-crypto": "^7.4.1"
+      }
+    },
+    "node_modules/@noble/curves": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz",
+      "integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@noble/hashes": "1.7.1"
+      },
+      "engines": {
+        "node": "^14.21.3 || >=16"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@noble/hashes": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz",
+      "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==",
+      "license": "MIT",
+      "engines": {
+        "node": "^14.21.3 || >=16"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@polkadot-api/json-rpc-provider": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider/-/json-rpc-provider-0.0.1.tgz",
+      "integrity": "sha512-/SMC/l7foRjpykLTUTacIH05H3mr9ip8b5xxfwXlVezXrNVLp3Cv0GX6uItkKd+ZjzVPf3PFrDF2B2/HLSNESA==",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@polkadot-api/json-rpc-provider-proxy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/@polkadot-api/json-rpc-provider-proxy/-/json-rpc-provider-proxy-0.1.0.tgz",
+      "integrity": "sha512-8GSFE5+EF73MCuLQm8tjrbCqlgclcHBSRaswvXziJ0ZW7iw3UEMsKkkKvELayWyBuOPa2T5i1nj6gFOeIsqvrg==",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@polkadot-api/metadata-builders": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/@polkadot-api/metadata-builders/-/metadata-builders-0.3.2.tgz",
+      "integrity": "sha512-TKpfoT6vTb+513KDzMBTfCb/ORdgRnsS3TDFpOhAhZ08ikvK+hjHMt5plPiAX/OWkm1Wc9I3+K6W0hX5Ab7MVg==",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@polkadot-api/substrate-bindings": "0.6.0",
+        "@polkadot-api/utils": "0.1.0"
+      }
+    },
+    "node_modules/@polkadot-api/observable-client": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/@polkadot-api/observable-client/-/observable-client-0.3.2.tgz",
+      "integrity": "sha512-HGgqWgEutVyOBXoGOPp4+IAq6CNdK/3MfQJmhCJb8YaJiaK4W6aRGrdQuQSTPHfERHCARt9BrOmEvTXAT257Ug==",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@polkadot-api/metadata-builders": "0.3.2",
+        "@polkadot-api/substrate-bindings": "0.6.0",
+        "@polkadot-api/utils": "0.1.0"
+      },
+      "peerDependencies": {
+        "@polkadot-api/substrate-client": "0.1.4",
+        "rxjs": ">=7.8.0"
+      }
+    },
+    "node_modules/@polkadot-api/substrate-bindings": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-bindings/-/substrate-bindings-0.6.0.tgz",
+      "integrity": "sha512-lGuhE74NA1/PqdN7fKFdE5C1gNYX357j1tWzdlPXI0kQ7h3kN0zfxNOpPUN7dIrPcOFZ6C0tRRVrBylXkI6xPw==",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@noble/hashes": "^1.3.1",
+        "@polkadot-api/utils": "0.1.0",
+        "@scure/base": "^1.1.1",
+        "scale-ts": "^1.6.0"
+      }
+    },
+    "node_modules/@polkadot-api/substrate-client": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/@polkadot-api/substrate-client/-/substrate-client-0.1.4.tgz",
+      "integrity": "sha512-MljrPobN0ZWTpn++da9vOvt+Ex+NlqTlr/XT7zi9sqPtDJiQcYl+d29hFAgpaeTqbeQKZwz3WDE9xcEfLE8c5A==",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@polkadot-api/json-rpc-provider": "0.0.1",
+        "@polkadot-api/utils": "0.1.0"
+      }
+    },
+    "node_modules/@polkadot-api/utils": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/@polkadot-api/utils/-/utils-0.1.0.tgz",
+      "integrity": "sha512-MXzWZeuGxKizPx2Xf/47wx9sr/uxKw39bVJUptTJdsaQn/TGq+z310mHzf1RCGvC1diHM8f593KrnDgc9oNbJA==",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/@polkadot/api": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-15.5.2.tgz",
+      "integrity": "sha512-TZPJlnoYr5kAfINooSmbvUcUCQnKDmTdLKNJmMh7CvCOYqQSJjFnMyfxhjM1bBTIcqnP9nFIGkldy19ErZHtcQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/api-augment": "15.5.2",
+        "@polkadot/api-base": "15.5.2",
+        "@polkadot/api-derive": "15.5.2",
+        "@polkadot/keyring": "^13.3.1",
+        "@polkadot/rpc-augment": "15.5.2",
+        "@polkadot/rpc-core": "15.5.2",
+        "@polkadot/rpc-provider": "15.5.2",
+        "@polkadot/types": "15.5.2",
+        "@polkadot/types-augment": "15.5.2",
+        "@polkadot/types-codec": "15.5.2",
+        "@polkadot/types-create": "15.5.2",
+        "@polkadot/types-known": "15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "@polkadot/util-crypto": "^13.3.1",
+        "eventemitter3": "^5.0.1",
+        "rxjs": "^7.8.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/api-augment": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-15.5.2.tgz",
+      "integrity": "sha512-EuE13KeifPj6PBfR3qMtqCq+Clbly/VX5adh53ljw7XTtHt8MKTlvhTK9pO9WHnixL6hUVH1f/Ekuzt8ROhpAg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/api-base": "15.5.2",
+        "@polkadot/rpc-augment": "15.5.2",
+        "@polkadot/types": "15.5.2",
+        "@polkadot/types-augment": "15.5.2",
+        "@polkadot/types-codec": "15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/api-base": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/api-base/-/api-base-15.5.2.tgz",
+      "integrity": "sha512-e8W2KRwn6pkI/JIOrOCT2RsVil072vxQ95X2HCqu5eMmn5vwyOHB2OaMWezXikMegnCF3XEDeIzSP/VxGWW+zA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/rpc-core": "15.5.2",
+        "@polkadot/types": "15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "rxjs": "^7.8.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/api-derive": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-15.5.2.tgz",
+      "integrity": "sha512-eSSPE0O9LE9jsRJIBqrPfHa7vCjE3NR+3ATdwAKBwK9LUfeCEEWud7c53njW8wLMSOiczxcX3JS2J9Rb0q7HCA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/api": "15.5.2",
+        "@polkadot/api-augment": "15.5.2",
+        "@polkadot/api-base": "15.5.2",
+        "@polkadot/rpc-core": "15.5.2",
+        "@polkadot/types": "15.5.2",
+        "@polkadot/types-codec": "15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "@polkadot/util-crypto": "^13.3.1",
+        "rxjs": "^7.8.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/keyring": {
+      "version": "13.3.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-13.3.1.tgz",
+      "integrity": "sha512-PT3uG9MqciPyoEz/f23RRMSlht77fo1hZaA1Vbcs1Rz7h7qFC0+7jFI9Ak30EJh9V0I2YugfzqAe3NjjyDxlvw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/util": "13.3.1",
+        "@polkadot/util-crypto": "13.3.1",
+        "tslib": "^2.8.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@polkadot/util": "13.3.1",
+        "@polkadot/util-crypto": "13.3.1"
+      }
+    },
+    "node_modules/@polkadot/networks": {
+      "version": "13.3.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-13.3.1.tgz",
+      "integrity": "sha512-g/0OmCMUrbbW4RQ/xajTYd2SMJvFKY4kmMvpxtNN57hWQpY7c5oDXSz57jGH2uwvcBWeDfaNokcS+9hJL1RBcA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/util": "13.3.1",
+        "@substrate/ss58-registry": "^1.51.0",
+        "tslib": "^2.8.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/rpc-augment": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-15.5.2.tgz",
+      "integrity": "sha512-eDCcmgrb/csOcav/RRBPFkOdPRvRXVYlksCGlQuzobYkPZfPz5tIKmgenip/5qnviR6gag6tK9ara+8kZ/7tpw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/rpc-core": "15.5.2",
+        "@polkadot/types": "15.5.2",
+        "@polkadot/types-codec": "15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/rpc-core": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-15.5.2.tgz",
+      "integrity": "sha512-a4Xq3iEJvRA9gHE+QxMaIEOkgjuZUfW+uI3XLDtPgtxu2yF3hceyRl/K1m6E4AXR383VaxQ45wvDS1odPbmwaw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/rpc-augment": "15.5.2",
+        "@polkadot/rpc-provider": "15.5.2",
+        "@polkadot/types": "15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "rxjs": "^7.8.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/rpc-provider": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-15.5.2.tgz",
+      "integrity": "sha512-LHDG4mY5moFdVyUuEyuF9hMVWgA+DoLeNYZjtOL88gSALpfjhBLt1Hjbm3R6VwvcxeVNTkteVGvCo0AlH123JQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/keyring": "^13.3.1",
+        "@polkadot/types": "15.5.2",
+        "@polkadot/types-support": "15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "@polkadot/util-crypto": "^13.3.1",
+        "@polkadot/x-fetch": "^13.3.1",
+        "@polkadot/x-global": "^13.3.1",
+        "@polkadot/x-ws": "^13.3.1",
+        "eventemitter3": "^5.0.1",
+        "mock-socket": "^9.3.1",
+        "nock": "^13.5.5",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "optionalDependencies": {
+        "@substrate/connect": "0.8.11"
+      }
+    },
+    "node_modules/@polkadot/types": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-15.5.2.tgz",
+      "integrity": "sha512-TANrhfovLgbG00ldFvZbOuwyzqibOOMAU9egGqnoFwz4x4vTNTBgNJRvQGF5w4+FhjcEepdxlLU/3yqFM98yzA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/keyring": "^13.3.1",
+        "@polkadot/types-augment": "15.5.2",
+        "@polkadot/types-codec": "15.5.2",
+        "@polkadot/types-create": "15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "@polkadot/util-crypto": "^13.3.1",
+        "rxjs": "^7.8.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/types-augment": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-15.5.2.tgz",
+      "integrity": "sha512-Za5ifsiu2gSQkOBjwcCtCr5nz+PojsBoptdHKjMm0JHLgilNn0kNqriqRRrCiPkUO1656UXRQNCHpP6Vs8tncg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/types": "15.5.2",
+        "@polkadot/types-codec": "15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/types-codec": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-15.5.2.tgz",
+      "integrity": "sha512-caQNGQ+QHVZV4hGSolYN9L9pMRZeo9rJzYoybT5LMIxX8QVdW3RM5HDesj1SKGSrgIJmooN4/5JzPjrFZ4C7Vw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/util": "^13.3.1",
+        "@polkadot/x-bigint": "^13.3.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/types-create": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/types-create/-/types-create-15.5.2.tgz",
+      "integrity": "sha512-PbrT2mP5x7VTpwCZa/BCl8jl3y/s6UOwrjBL+pq8TErLEbkackn5a3cR4GaH9toeP5qlEaLbSWRFm24YcW8FOg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/types-codec": "15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/types-known": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-15.5.2.tgz",
+      "integrity": "sha512-4yk1DnIeAy4uImFf4yDyRRdgkf5nAagQzPZWO61uxhEA+Q2MxLHLDeLbUwFiLxLLvpM09Xke8rGbem/vPRg9nA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/networks": "^13.3.1",
+        "@polkadot/types": "15.5.2",
+        "@polkadot/types-codec": "15.5.2",
+        "@polkadot/types-create": "15.5.2",
+        "@polkadot/util": "^13.3.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/types-support": {
+      "version": "15.5.2",
+      "resolved": "https://registry.npmjs.org/@polkadot/types-support/-/types-support-15.5.2.tgz",
+      "integrity": "sha512-PT3MTSy69euAPtRQ3c2I7vM0OfAIQXU1yIWpYTcEkG+spTn4d0fcYeJjfxvAmcROJlpJoXf10YMsXKwx+gvOig==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/util": "^13.3.1",
+        "tslib": "^2.8.1"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/util": {
+      "version": "13.3.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-13.3.1.tgz",
+      "integrity": "sha512-5crLP/rUZOJzuo/W8t73J8PxpibJ5vrxY57rR6V+mIpCZd1ORiw0wxeHcV5F9Adpn7yJyuGBwxPbueNR5Rr1Zw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/x-bigint": "13.3.1",
+        "@polkadot/x-global": "13.3.1",
+        "@polkadot/x-textdecoder": "13.3.1",
+        "@polkadot/x-textencoder": "13.3.1",
+        "@types/bn.js": "^5.1.6",
+        "bn.js": "^5.2.1",
+        "tslib": "^2.8.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/util-crypto": {
+      "version": "13.3.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-13.3.1.tgz",
+      "integrity": "sha512-FU6yf3IY++DKlf0eqO9/obe2y1zuZ5rbqRs75fyOME/5VXio1fA3GIpW7aFphyneFRd78G8QLh8kn0oIwBGMNg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@noble/curves": "^1.3.0",
+        "@noble/hashes": "^1.3.3",
+        "@polkadot/networks": "13.3.1",
+        "@polkadot/util": "13.3.1",
+        "@polkadot/wasm-crypto": "^7.4.1",
+        "@polkadot/wasm-util": "^7.4.1",
+        "@polkadot/x-bigint": "13.3.1",
+        "@polkadot/x-randomvalues": "13.3.1",
+        "@scure/base": "^1.1.7",
+        "tslib": "^2.8.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@polkadot/util": "13.3.1"
+      }
+    },
+    "node_modules/@polkadot/wasm-bridge": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.4.1.tgz",
+      "integrity": "sha512-tdkJaV453tezBxhF39r4oeG0A39sPKGDJmN81LYLf+Fihb7astzwju+u75BRmDrHZjZIv00un3razJEWCxze6g==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/wasm-util": "7.4.1",
+        "tslib": "^2.7.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@polkadot/util": "*",
+        "@polkadot/x-randomvalues": "*"
+      }
+    },
+    "node_modules/@polkadot/wasm-crypto": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.4.1.tgz",
+      "integrity": "sha512-kHN/kF7hYxm1y0WeFLWeWir6oTzvcFmR4N8fJJokR+ajYbdmrafPN+6iLgQVbhZnDdxyv9jWDuRRsDnBx8tPMQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/wasm-bridge": "7.4.1",
+        "@polkadot/wasm-crypto-asmjs": "7.4.1",
+        "@polkadot/wasm-crypto-init": "7.4.1",
+        "@polkadot/wasm-crypto-wasm": "7.4.1",
+        "@polkadot/wasm-util": "7.4.1",
+        "tslib": "^2.7.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@polkadot/util": "*",
+        "@polkadot/x-randomvalues": "*"
+      }
+    },
+    "node_modules/@polkadot/wasm-crypto-asmjs": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.4.1.tgz",
+      "integrity": "sha512-pwU8QXhUW7IberyHJIQr37IhbB6DPkCG5FhozCiNTq4vFBsFPjm9q8aZh7oX1QHQaiAZa2m2/VjIVE+FHGbvHQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.7.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@polkadot/util": "*"
+      }
+    },
+    "node_modules/@polkadot/wasm-crypto-init": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.4.1.tgz",
+      "integrity": "sha512-AVka33+f7MvXEEIGq5U0dhaA2SaXMXnxVCQyhJTaCnJ5bRDj0Xlm3ijwDEQUiaDql7EikbkkRtmlvs95eSUWYQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/wasm-bridge": "7.4.1",
+        "@polkadot/wasm-crypto-asmjs": "7.4.1",
+        "@polkadot/wasm-crypto-wasm": "7.4.1",
+        "@polkadot/wasm-util": "7.4.1",
+        "tslib": "^2.7.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@polkadot/util": "*",
+        "@polkadot/x-randomvalues": "*"
+      }
+    },
+    "node_modules/@polkadot/wasm-crypto-wasm": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.4.1.tgz",
+      "integrity": "sha512-PE1OAoupFR0ZOV2O8tr7D1FEUAwaggzxtfs3Aa5gr+yxlSOaWUKeqsOYe1KdrcjmZVV3iINEAXxgrbzCmiuONg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/wasm-util": "7.4.1",
+        "tslib": "^2.7.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@polkadot/util": "*"
+      }
+    },
+    "node_modules/@polkadot/wasm-util": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.4.1.tgz",
+      "integrity": "sha512-RAcxNFf3zzpkr+LX/ItAsvj+QyM56TomJ0xjUMo4wKkHjwsxkz4dWJtx5knIgQz/OthqSDMR59VNEycQeNuXzA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.7.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@polkadot/util": "*"
+      }
+    },
+    "node_modules/@polkadot/x-bigint": {
+      "version": "13.3.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-13.3.1.tgz",
+      "integrity": "sha512-ewc708a7LUdrT92v9DsSAIbcJQBn3aR9/LavF/iyMOq5lZJyPXDSjAnskfMs818R3RLCrKVKfs+aKkxt2eqo8g==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/x-global": "13.3.1",
+        "tslib": "^2.8.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/x-fetch": {
+      "version": "13.3.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-13.3.1.tgz",
+      "integrity": "sha512-J+HM42j0KGqdC/eo7vmsdLPz74MR7+0My4km6TG9HGjKqqztwygtenpopPod2SbRnL4nHiEG0wZzpVOW6HN2gw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/x-global": "13.3.1",
+        "node-fetch": "^3.3.2",
+        "tslib": "^2.8.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/x-global": {
+      "version": "13.3.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-13.3.1.tgz",
+      "integrity": "sha512-861TeIw49a3JvkwlUWrddfG+JaUqtFZDsemYxxZIjjcRJLrKOsoKNqHbiHi2OPrwlX8PwAA/wc5I9Q4XRQ7KEg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.8.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/x-randomvalues": {
+      "version": "13.3.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-13.3.1.tgz",
+      "integrity": "sha512-GIb0au3vIX2U/DRH0PRckM+1I4EIbU8PLX1roGJgN1MAYKWiylJTKPVoBMafMM87o8qauOevJ46uYB/qlfbiWg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/x-global": "13.3.1",
+        "tslib": "^2.8.0"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "peerDependencies": {
+        "@polkadot/util": "13.3.1",
+        "@polkadot/wasm-util": "*"
+      }
+    },
+    "node_modules/@polkadot/x-textdecoder": {
+      "version": "13.3.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-13.3.1.tgz",
+      "integrity": "sha512-g2R9O1p0ZsNDhZ3uEBZh6fQaVLlo3yFr0YNqt15v7e9lBI4APvTJ202EINlo2jB5lz/R438/BdjEA3AL+0zUtQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/x-global": "13.3.1",
+        "tslib": "^2.8.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/x-textencoder": {
+      "version": "13.3.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-13.3.1.tgz",
+      "integrity": "sha512-DnHLUdoKDYxekfxopuUuPB+j5Mu7Jemejcduu5gz3/89GP/sYPAu0CAVbq9B+hK1yGjBBj31eA4wkAV1oktYmg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/x-global": "13.3.1",
+        "tslib": "^2.8.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@polkadot/x-ws": {
+      "version": "13.3.1",
+      "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-13.3.1.tgz",
+      "integrity": "sha512-ytqkC7FwVs4BlzNFAmPMFp+xD1KIdMMP/mvCSOrnxjlsyM5DVGop4x4c2ZgDUBmrFqmIiVkWDfMIZeOxui2OLQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@polkadot/x-global": "13.3.1",
+        "tslib": "^2.8.0",
+        "ws": "^8.18.0"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@scure/base": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.4.tgz",
+      "integrity": "sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@substrate/connect": {
+      "version": "0.8.11",
+      "resolved": "https://registry.npmjs.org/@substrate/connect/-/connect-0.8.11.tgz",
+      "integrity": "sha512-ofLs1PAO9AtDdPbdyTYj217Pe+lBfTLltdHDs3ds8no0BseoLeAGxpz1mHfi7zB4IxI3YyAiLjH6U8cw4pj4Nw==",
+      "deprecated": "versions below 1.x are no longer maintained",
+      "license": "GPL-3.0-only",
+      "optional": true,
+      "dependencies": {
+        "@substrate/connect-extension-protocol": "^2.0.0",
+        "@substrate/connect-known-chains": "^1.1.5",
+        "@substrate/light-client-extension-helpers": "^1.0.0",
+        "smoldot": "2.0.26"
+      }
+    },
+    "node_modules/@substrate/connect-extension-protocol": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-2.2.1.tgz",
+      "integrity": "sha512-GoafTgm/Jey9E4Xlj4Z5ZBt/H4drH2CNq8VrAro80rtoznrXnFDNVivLQzZN0Xaj2g8YXSn9pC9Oc9IovYZJXw==",
+      "license": "GPL-3.0-only",
+      "optional": true
+    },
+    "node_modules/@substrate/connect-known-chains": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/@substrate/connect-known-chains/-/connect-known-chains-1.9.1.tgz",
+      "integrity": "sha512-dWNf5x3hjrY4s+WEovPKL0jH58pyIaIiAM918aAdnp/VKkAMqOfhKzRWL7BqJDKCm95bL4fqnOfaXZ3SQpVoYw==",
+      "license": "GPL-3.0-only",
+      "optional": true
+    },
+    "node_modules/@substrate/light-client-extension-helpers": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@substrate/light-client-extension-helpers/-/light-client-extension-helpers-1.0.0.tgz",
+      "integrity": "sha512-TdKlni1mBBZptOaeVrKnusMg/UBpWUORNDv5fdCaJklP4RJiFOzBCrzC+CyVI5kQzsXBisZ+2pXm+rIjS38kHg==",
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@polkadot-api/json-rpc-provider": "^0.0.1",
+        "@polkadot-api/json-rpc-provider-proxy": "^0.1.0",
+        "@polkadot-api/observable-client": "^0.3.0",
+        "@polkadot-api/substrate-client": "^0.1.2",
+        "@substrate/connect-extension-protocol": "^2.0.0",
+        "@substrate/connect-known-chains": "^1.1.5",
+        "rxjs": "^7.8.1"
+      },
+      "peerDependencies": {
+        "smoldot": "2.x"
+      }
+    },
+    "node_modules/@substrate/ss58-registry": {
+      "version": "1.51.0",
+      "resolved": "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.51.0.tgz",
+      "integrity": "sha512-TWDurLiPxndFgKjVavCniytBIw+t4ViOi7TYp9h/D0NMmkEc9klFTo+827eyEJ0lELpqO207Ey7uGxUa+BS1jQ==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@types/bn.js": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.6.tgz",
+      "integrity": "sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/node": {
+      "version": "22.13.1",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
+      "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
+      "license": "MIT",
+      "dependencies": {
+        "undici-types": "~6.20.0"
+      }
+    },
+    "node_modules/bn.js": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
+      "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
+      "license": "MIT"
+    },
+    "node_modules/data-uri-to-buffer": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
+      "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 12"
+      }
+    },
+    "node_modules/debug": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/eventemitter3": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+      "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
+      "license": "MIT"
+    },
+    "node_modules/fetch-blob": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
+      "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/jimmywarting"
+        },
+        {
+          "type": "paypal",
+          "url": "https://paypal.me/jimmywarting"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "node-domexception": "^1.0.0",
+        "web-streams-polyfill": "^3.0.3"
+      },
+      "engines": {
+        "node": "^12.20 || >= 14.13"
+      }
+    },
+    "node_modules/formdata-polyfill": {
+      "version": "4.0.10",
+      "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
+      "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
+      "license": "MIT",
+      "dependencies": {
+        "fetch-blob": "^3.1.2"
+      },
+      "engines": {
+        "node": ">=12.20.0"
+      }
+    },
+    "node_modules/json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+      "license": "ISC"
+    },
+    "node_modules/mock-socket": {
+      "version": "9.3.1",
+      "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.3.1.tgz",
+      "integrity": "sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "license": "MIT"
+    },
+    "node_modules/nock": {
+      "version": "13.5.6",
+      "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.6.tgz",
+      "integrity": "sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==",
+      "license": "MIT",
+      "dependencies": {
+        "debug": "^4.1.0",
+        "json-stringify-safe": "^5.0.1",
+        "propagate": "^2.0.0"
+      },
+      "engines": {
+        "node": ">= 10.13"
+      }
+    },
+    "node_modules/node-domexception": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
+      "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/jimmywarting"
+        },
+        {
+          "type": "github",
+          "url": "https://paypal.me/jimmywarting"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.5.0"
+      }
+    },
+    "node_modules/node-fetch": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
+      "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
+      "license": "MIT",
+      "dependencies": {
+        "data-uri-to-buffer": "^4.0.0",
+        "fetch-blob": "^3.1.4",
+        "formdata-polyfill": "^4.0.10"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/node-fetch"
+      }
+    },
+    "node_modules/propagate": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
+      "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/rxjs": {
+      "version": "7.8.1",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "tslib": "^2.1.0"
+      }
+    },
+    "node_modules/scale-ts": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/scale-ts/-/scale-ts-1.6.1.tgz",
+      "integrity": "sha512-PBMc2AWc6wSEqJYBDPcyCLUj9/tMKnLX70jLOSndMtcUoLQucP/DM0vnQo1wJAYjTrQiq8iG9rD0q6wFzgjH7g==",
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/smoldot": {
+      "version": "2.0.26",
+      "resolved": "https://registry.npmjs.org/smoldot/-/smoldot-2.0.26.tgz",
+      "integrity": "sha512-F+qYmH4z2s2FK+CxGj8moYcd1ekSIKH8ywkdqlOz88Dat35iB1DIYL11aILN46YSGMzQW/lbJNS307zBSDN5Ig==",
+      "license": "GPL-3.0-or-later WITH Classpath-exception-2.0",
+      "optional": true,
+      "dependencies": {
+        "ws": "^8.8.1"
+      }
+    },
+    "node_modules/tslib": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+      "license": "0BSD"
+    },
+    "node_modules/undici-types": {
+      "version": "6.20.0",
+      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+      "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+      "license": "MIT"
+    },
+    "node_modules/web-streams-polyfill": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
+      "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/ws": {
+      "version": "8.18.0",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
+      "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": ">=5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    }
+  }
+}
diff --git a/scripts/generate-signature/package.json b/scripts/generate-signature/package.json
new file mode 100644
index 0000000..93be3ba
--- /dev/null
+++ b/scripts/generate-signature/package.json
@@ -0,0 +1,19 @@
+{
+  "name": "generate-signature",
+  "version": "1.0.0",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [],
+  "author": "",
+  "license": "ISC",
+  "description": "",
+  "dependencies": {
+    "@polkadot/api": "^15.5.2",
+    "@polkadot/keyring": "^13.3.1",
+    "@polkadot/types": "^15.5.2",
+    "@polkadot/util": "^13.3.1",
+    "@polkadot/wasm-crypto": "^7.4.1"
+  }
+}

Creating script

We'll create a light weight client for the Polkadot network. This script will allow us to interact with the Polkadot network using the Polkadot API.

Start local node:

At the root of the project, run the following command to start a local node:

./target/release/academy-pow --dev --tmp

Implement script

  1. Create scripts/generate-signature/index.js file.
cd scripts/generate-signature
touch index.js
  1. Create client
const { WsProvider } = require('@polkadot/api');

const wsProvider = new WsProvider('ws://127.0.0.1:9944'); // Replace with your endpoint

async function main() {
}

main().then(() => process.exit(0)).catch(error => {
    console.error(error);
    process.exit(1);
});
  1. Define keyring and data structure
const { WsProvider } = require('@polkadot/api');
+const Keyring = require('@polkadot/keyring').default;
+const { ApiPromise } = require('@polkadot/api');

const wsProvider = new WsProvider('ws://127.0.0.1:9944'); // Replace with your endpoint

async function main() {
+    // because our account address is in `sr25519` format
+    const keyring = new Keyring({ type: 'sr25519', ss58Format: 2 });
+    // Register types
+    const api = await ApiPromise.create({
+        types: {
+            TransactionInput: {
+                outpoint: 'H256',      // Fixed 32 bytes
+                sigscript: 'H512'     // Fixed 64 bytes
+            },
+            TransactionOutput: {
+                value: 'u128',        // 16 bytes
+                pubkey: 'H256'        // Fixed 32 bytes
+            },
+            Transaction: {
+                inputs: 'Vec<TransactionInput>',  // Vec type
+                outputs: 'Vec<TransactionOutput>' // Vec type
+            }
+        },
+        provider: wsProvider, // Add the provider here
    });
}

main().then(() => process.exit(0)).catch(error => {
    console.error(error);
    process.exit(1);
});
  1. Define signer
async function main() {
    // ...

    // create Alice based on the development seed. You can change to any other signer if you want
    const alice = keyring.addFromUri('//Alice');
}
  1. Define transaction data

Scenarios:

  • Alice address in sr25519 format: 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d.
  • Bob address in sr25519 format: 0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48.
  • Alice has an UTXO 0xc670c5f69081da78af400552edcafa3f0f31e84db1b50dd70776e0f87477b3dc worth 100.
  • Alice wants to send 50 to Bob.
  • Alice gets back 50.
async function main() {
    // ...

    const inputs = [{
        // the latest UTXO hash of the account want to spent
        outpoint: "0xc670c5f69081da78af400552edcafa3f0f31e84db1b50dd70776e0f87477b3dc",
        // default simple sigscript
        sigscript: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    }]
    const outputs = [
        {
            // Value to spend
            value: "50",
            // Bob pubkey
            pubkey: "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48",
        },
        {
            // Value to spend
            value: "50",
            // Alice pubkey
            pubkey: "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d",
        },
    ]
}
  1. Encode data then sign the data
// ...
const { u8aToHex } = require('@polkadot/util');

async function main() {
    // ...

    // Encode full transaction
    const encodedTx = api.createType('Transaction', {
        inputs: inputs,
        outputs: outputs
    }).toU8a();

    // the encoded transaction in u8 array
    const signature = alice.sign(encodedTx);
    const isValid = alice.verify(encodedTx, signature, alice.publicKey);

    if (isValid) {
        console.log(`✅ Signature: ${u8aToHex(signature)}`);
    } else {
        console.log(`❌ Something went wrong! Please report to 👉 https://github.com/danielbui12/substrate-bitcoin-like-blockchain/issues/new`);
    }
}
  1. Run the script
node index.js

2025-02-10 15:08:18        API/INIT: RPC methods not decorated: chainHead_v1_body, chainHead_v1_call, chainHead_v1_continue, chainHead_v1_follow, chainHead_v1_header, chainHead_v1_stopOperation, chainHead_v1_storage, chainHead_v1_unfollow, chainHead_v1_unpin, transactionWatch_v1_submitAndWatch, transactionWatch_v1_unwatch, transaction_v1_broadcast, transaction_v1_stop
✅ Signature: 0xe6d4b51e3a892a074eff4e1d7358b76c70c36f7956fb1c203d7c8e8504a51f469c7ce771646f7dd751cee91051b46b52508edfba7b318004a429ee7b255bbe8d

const { WsProvider } = require('@polkadot/api');
const Keyring = require('@polkadot/keyring').default;
const { ApiPromise } = require('@polkadot/api');
const { u8aToHex } = require('@polkadot/util');

const wsProvider = new WsProvider('ws://127.0.0.1:9944'); // Replace with your endpoint

async function main() {
    // because our account address is in `sr25519` format
    const keyring = new Keyring({ type: 'sr25519', ss58Format: 2 });
    // Register types
    const api = await ApiPromise.create({
        types: {
            TransactionInput: {
                outpoint: 'H256',      // Fixed 32 bytes
                sigscript: 'H512'     // Fixed 64 bytes
            },
            TransactionOutput: {
                value: 'u128',        // 16 bytes
                pubkey: 'H256'        // Fixed 32 bytes
            },
            Transaction: {
                inputs: 'Vec<TransactionInput>',  // Vec type
                outputs: 'Vec<TransactionOutput>' // Vec type
            }
        },
        provider: wsProvider, // Add the provider here
    });

    // create Alice based on the development seed. You can change to any other signer if you want
    const alice = keyring.addFromUri('//Alice');

    const inputs = [{
        // the latest UTXO hash of the account want to spent
        outpoint: "0xc670c5f69081da78af400552edcafa3f0f31e84db1b50dd70776e0f87477b3dc",
        // default simple sigscript
        sigscript: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    }]
    const outputs = [
        {
            // Value to spend
            value: "50",
            // Bob pubkey
            pubkey: "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48",
        },
        {
            // Value to spend
            value: "50",
            // Alice pubkey
            pubkey: "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d",
        },
    ]
    // Encode full transaction
    const encodedTx = api.createType('Transaction', {
        inputs: inputs,
        outputs: outputs
    }).toU8a();
     
    // the encoded transaction in u8 array
    const signature = alice.sign(encodedTx);
    const isValid = alice.verify(encodedTx, signature, alice.publicKey);
     
    if (isValid) {
        console.log(`✅ Signature: ${u8aToHex(signature)}`);
    } else {
        console.log(`❌ Something went wrong! Please report to 👉 https://github.com/danielbui12/substrate-bitcoin-like-blockchain/issues/new`);
    }
}

main().then(() => process.exit(0)).catch(error => {
    console.error(error);
    process.exit(1);
});
diff --git a/scripts/generate-signature/index.js b/scripts/generate-signature/index.js
new file mode 100644
index 0000000..30c4d75
--- /dev/null
+++ b/scripts/generate-signature/index.js
@@ -0,0 +1,73 @@
+const { WsProvider } = require('@polkadot/api');
+const Keyring = require('@polkadot/keyring').default;
+const { ApiPromise } = require('@polkadot/api');
+const { u8aToHex } = require('@polkadot/util');
+
+const wsProvider = new WsProvider('ws://127.0.0.1:9944'); // Replace with your endpoint
+
+async function main() {
+    // because our account address is in `sr25519` format
+    const keyring = new Keyring({ type: 'sr25519', ss58Format: 2 });
+    // Register types
+    const api = await ApiPromise.create({
+        types: {
+            TransactionInput: {
+                outpoint: 'H256',      // Fixed 32 bytes
+                sigscript: 'H512'     // Fixed 64 bytes
+            },
+            TransactionOutput: {
+                value: 'u128',        // 16 bytes
+                pubkey: 'H256'        // Fixed 32 bytes
+            },
+            Transaction: {
+                inputs: 'Vec<TransactionInput>',  // Vec type
+                outputs: 'Vec<TransactionOutput>' // Vec type
+            }
+        },
+        provider: wsProvider, // Add the provider here
+    });
+
+    // create Alice based on the development seed. You can change to any other signer if you want
+    const alice = keyring.addFromUri('//Alice');
+
+    const inputs = [{
+        // the latest UTXO hash of the account want to spent
+        outpoint: "0xc670c5f69081da78af400552edcafa3f0f31e84db1b50dd70776e0f87477b3dc",
+        // default simple sigscript
+        sigscript: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+    }]
+    const outputs = [
+        {
+            // Value to spend
+            value: "50",
+            // Bob pubkey
+            pubkey: "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48",
+        },
+        {
+            // Value to spend
+            value: "50",
+            // Alice pubkey
+            pubkey: "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d",
+        },
+    ]
+    // Encode full transaction
+    const encodedTx = api.createType('Transaction', {
+        inputs: inputs,
+        outputs: outputs
+    }).toU8a();
+     
+    // the encoded transaction in u8 array
+    const signature = alice.sign(encodedTx);
+    const isValid = alice.verify(encodedTx, signature, alice.publicKey);
+     
+    if (isValid) {
+        console.log(`✅ Signature: ${u8aToHex(signature)}`);
+    } else {
+        console.log(`❌ Something went wrong! Please report to 👉 https://github.com/danielbui12/substrate-bitcoin-like-blockchain/issues/new`);
+    }
+}
+
+main().then(() => process.exit(0)).catch(error => {
+    console.error(error);
+    process.exit(1);
+});
\ No newline at end of file

Wrap up

Wow, you've made it all the way to the end!

Congratulations on completing all steps! 🎉 You've done an amazing job and you're all done! 🙌

Start hacking by following demo usage tutorial!

Demo usage

[!IMPORTANT] Please follow up strictly these value to have best experience 😉.

Address

  • Powerful tool to convert SS58 account to sr25519::Pubkey: https://polkadot.subscan.io/tools/format_transform
  • Alice: from 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY to 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
  • Bob: from 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty to 0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48

Scenario

  1. Initially, Alice has a UTXO 1,125,899,906,842,624.
  2. She transfers to BOB a UTXO 842,624; but she doesn't have a UTXO $842,624. So she has to use her 1,125,899,906,842,624.
  3. TransactionInput contains outpoint is UTXO 1,125,899,906,842,624; sigscript is signed data of "simple transaction" (refer to runtime/src/utxo.rs:354).
  4. There will be 2 TransactionOutputs:
    • TransactionOutput contains value is UTXO 842,624; pubkey is Bob address
    • TransactionOutput contains value is UTXO 1,125,899,906,000,000; pubkey is Alice address
flowchart LR
    AliceBefore[Alice <br/> UTXO 1,125,899,906,842,624] --> T{Transaction}
    T -->|Change| AliceAfter[Alice <br/> UTXO 842,624]
    T -->|Receive| Bob[Bob <br/> UTXO 1,125,899,906,000,000]

Steps

  • Navigate to: https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/extrinsics

Check balance

  • Switch to Chain State, select utxo, utxoOf
  • Input: 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
  • Press + button
  • Verify Alice has a UTXO hash
utxo.utxoOf: Option<H256>
0xc670c5f69081da78af400552edcafa3f0f31e84db1b50dd70776e0f87477b3dc
  • Then select utxo, utxoStore
  • Input: 0xc670c5f69081da78af400552edcafa3f0f31e84db1b50dd70776e0f87477b3dc
  • Press + button
  • Verify Alice has a UTXO value
utxo.utxoStore: Option<AcademyPowRuntimeUtxoTransactionOutput>
{
  value: 1,125,899,906,842,624
  pubkey: 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
}

1_check_balance

Alice transfers UTXO 842,624 to Bob, get back UXTO 1,125,899,906,000,000

Input

  • inputs[0].outpoint: 0xc670c5f69081da78af400552edcafa3f0f31e84db1b50dd70776e0f87477b3dc

  • inputs[0].sigscript: 0xa23674686467cf6a3d755987276e1dbb71b4800ff99f2721e7d4fd52774fe43086ed5a385b5cde80a346be5eb7afd3e95ef1dd9b9069deee889cd432891ba481

  • outputs[0].value: 842624

  • outputs[0].pubkey: 0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48

  • outputs[1].value: 1125899906000000

  • outputs[1].pubkey: 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d

Then submit unsigned transaction

2_submit_spend_extrinsic

Events

  • New UTXO hash of Bob: 0x60bfe689ea5d2f0e2380a146289067465a3608b9ef20ef9e152cf501c0040dba
  • New UTXO hash of Alice: 0x426e4f172479a674b4c044c34a77453bdf4ddbdf8b3993d586a05d9cffe57bd3

2_event

Check balance

Alice:

  • Input: 0x426e4f172479a674b4c044c34a77453bdf4ddbdf8b3993d586a05d9cffe57bd3
  • Press + button
  • Verify Alice has a UTXO 1,125,899,906,000,000

Bob:

  • Input: 0x60bfe689ea5d2f0e2380a146289067465a3608b9ef20ef9e152cf501c0040dba
  • Press + button
  • Verify Bob has a UTXO 842,624

2_check_balance

Custom your own

[!NOTE] If you would love to play in your own way, refer to scripts/generate-signature/index.js to generate your own custom signed data!

Run multiple nodes

# Start the first local blockchain node using Ferdie account,
# using md5 algorithm 
./target/release/academy-pow  \
    --mining-algo md5 \
    --base-path ./validators/ferdie \
    --dev \
    --ferdie \
    --port 30333 \
    --rpc-port 9944 \
    --node-key 0000000000000000000000000000000000000000000000000000000000000001 \
    --no-prometheus \
    --validator

# Start the second local blockchain node using Eve account,
# using sha3 algorithm
./target/release/academy-pow  \
    --mining-algo sha3 \
    --base-path ./validators/eve \
    --dev \
    --eve \
    --port 30334 \
    --rpc-port 9945 \
    --no-prometheus \
    --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp \
    --validator

Then you can see Ferdie and Eve are continuously producing blocks.

multinode-1 multinode-2

Purge chain

./target/release/academy-pow purge-chain --base-path ./validators/ferdie --dev
./target/release/academy-pow purge-chain --base-path ./validators/eve --dev

More Help

academy-pow --help